From 7455fa3d2d299d6123db3e80014779260846281a Mon Sep 17 00:00:00 2001 From: Jess Sullivan Date: Sun, 10 May 2026 01:42:24 -0400 Subject: [PATCH] xr: add amdgpu DSC PPS debugfs carry --- .github/workflows/build-kernel.yml | 5 ++ xr/patches/README.md | 4 + xr/patches/amdgpu-dsc-pps-debugfs.patch | 98 +++++++++++++++++++++++++ xr/patches/series | 1 + xr/scripts/build-rpm.sh | 7 ++ xr/scripts/check-kernel-carry.sh | 7 ++ xr/scripts/check-rpm-patch-wiring.sh | 91 +++++++++++++++++++++++ xr/source-sync.md | 3 + xr/specs/kernel-xr.spec | 5 ++ 9 files changed, 221 insertions(+) create mode 100644 xr/patches/amdgpu-dsc-pps-debugfs.patch create mode 100755 xr/scripts/check-rpm-patch-wiring.sh diff --git a/.github/workflows/build-kernel.yml b/.github/workflows/build-kernel.yml index 154e1533772aa7..2df74508757395 100644 --- a/.github/workflows/build-kernel.yml +++ b/.github/workflows/build-kernel.yml @@ -116,6 +116,10 @@ jobs: .github xr + - name: Check XR patch wiring + if: steps.filter.outputs.skip != 'true' + run: bash xr/scripts/check-rpm-patch-wiring.sh + - name: Restore ccache if: steps.filter.outputs.skip != 'true' && (github.event_name != 'workflow_dispatch' || inputs.use_ccache == 'true') uses: actions/cache/restore@v4 @@ -268,6 +272,7 @@ jobs: ### Patches applied - `0007-vesa-dsc-bpp.patch` — VESA DisplayID DSC BPP parser + QP/RC fixes - `bigscreen-beyond-edid.patch` — EDID non-desktop quirk (BIG/0x1234 + 0x5095) + - `amdgpu-dsc-pps-debugfs.patch` — read-only DSC PPS debugfs observability for Honey lab proof work - `cve-2026-31431-algif-aead.patch` — applied automatically for vulnerable 6.19.x bases - `dirtyfrag-esp-shared-frag.patch` — applied automatically for CVE-2026-43284 Dirty Frag ESP-affected bases - `dirtyfrag-rxrpc-linearize.patch` — applied automatically for reserved CVE-2026-43500 Dirty Frag RxRPC-affected bases diff --git a/xr/patches/README.md b/xr/patches/README.md index ccef51918b4320..8d9cfc1b011169 100644 --- a/xr/patches/README.md +++ b/xr/patches/README.md @@ -8,6 +8,7 @@ Current carry classification: - `0007-vesa-dsc-bpp.patch`: carry with partial upstream overlap; upstream has AMD DSC passthrough plumbing, but this tree still carries the DisplayID/VESA DSC fixed-BPP parser and DRM connector/mode propagation path. Split that parser/connector path from local QP/RC offset adjustments before submission. - `bigscreen-beyond-edid.patch`: upstream candidate for the Bigscreen Beyond non-desktop quirk. Keep the release carry separate from the upstream submission route; the current carry is GNU-patch usable but must be regenerated before v1 submission. +- `amdgpu-dsc-pps-debugfs.patch`: local Honey lab diagnostic carry. It adds a read-only connector debugfs file for the packed DSC PPS cached by AMD DC; treat this as observability for black-screen proof work, not as a product fix or upstream-ready behavior change. Detailed split map: @@ -15,3 +16,6 @@ Detailed split map: - [`bigscreen-beyond-edid.route.md`](bigscreen-beyond-edid.route.md) The build and release workflows should source patches from here rather than another repo. +Run `xr/scripts/check-rpm-patch-wiring.sh` after changing `series` or +`xr/specs/kernel-xr.spec`; it verifies that each carry patch is declared and +applied by the RPM prep path. diff --git a/xr/patches/amdgpu-dsc-pps-debugfs.patch b/xr/patches/amdgpu-dsc-pps-debugfs.patch new file mode 100644 index 00000000000000..da9b1c32bad213 --- /dev/null +++ b/xr/patches/amdgpu-dsc-pps-debugfs.patch @@ -0,0 +1,98 @@ +From: Jess Sullivan +Subject: [PATCH] drm/amd/display: expose packed DSC PPS in connector debugfs + +Bigscreen Beyond black-screen diagnosis needs byte-level proof of the DSC +Picture Parameter Set sent to the sink. AMD DC already caches the packed +128-byte PPS in dc_stream_state.dsc_packed_pps when DSC is programmed. +amdgpu connector debugfs currently exposes only scalar DSC state such as +BPP, slice geometry, and chunk size. + +Add dsc_pic_parameter_set as a read-only connector debugfs file. It dumps +the cached packed PPS as hex bytes. This does not retrain the link, +reprogram DSC, or mutate stream state; it only exposes the exact PPS +payload already generated by the driver. + +Signed-off-by: Jess Sullivan +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 61 ++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +index 000000000000..111111111111 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +@@ -2268,6 +2268,66 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu + return size; + } + ++/* Read the packed 128-byte DSC PPS payload cached on the current stream. */ ++static ssize_t dp_dsc_pic_parameter_set_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; ++ struct dc_state *current_state; ++ struct pipe_ctx *pipe_ctx = NULL; ++ const u8 *pps; ++ size_t pps_size; ++ size_t rd_buf_size; ++ char *rd_buf; ++ ssize_t result; ++ size_t i; ++ int pipe_idx; ++ int len = 0; ++ ++ if (!aconnector->dc_link || ++ !aconnector->dc_link->dc || ++ !aconnector->dc_link->dc->current_state) ++ return -ENODEV; ++ ++ current_state = aconnector->dc_link->dc->current_state; ++ ++ for (pipe_idx = 0; pipe_idx < MAX_PIPES; pipe_idx++) { ++ pipe_ctx = ¤t_state->res_ctx.pipe_ctx[pipe_idx]; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; ++ } ++ ++ if (pipe_idx == MAX_PIPES || !pipe_ctx || !pipe_ctx->stream) ++ return -ENODEV; ++ ++ pps = pipe_ctx->stream->dsc_packed_pps; ++ pps_size = sizeof(pipe_ctx->stream->dsc_packed_pps); ++ rd_buf_size = pps_size * 3 + 1; ++ ++ rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); ++ if (!rd_buf) ++ return -ENOMEM; ++ ++ for (i = 0; i < pps_size; i++) { ++ len += scnprintf(rd_buf + len, rd_buf_size - len, ++ "%02x%c", pps[i], ++ i + 1 == pps_size ? '\n' : ' '); ++ } ++ ++ result = simple_read_from_buffer(buf, size, pos, rd_buf, len); ++ kfree(rd_buf); ++ return result; ++} ++ ++static const struct file_operations dp_dsc_pic_parameter_set_debugfs_fops = { ++ .owner = THIS_MODULE, ++ .read = dp_dsc_pic_parameter_set_read, ++ .llseek = default_llseek ++}; ++ + /* function: read DSC picture width parameter on the connector + * + * The read function: dp_dsc_pic_width_read +@@ -3107,6 +3167,7 @@ static const struct { + {"dsc_slice_width", &dp_dsc_slice_width_debugfs_fops}, + {"dsc_slice_height", &dp_dsc_slice_height_debugfs_fops}, + {"dsc_bits_per_pixel", &dp_dsc_bits_per_pixel_debugfs_fops}, ++ {"dsc_pic_parameter_set", &dp_dsc_pic_parameter_set_debugfs_fops}, + {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops}, + {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops}, + {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops}, diff --git a/xr/patches/series b/xr/patches/series index f579b157b5f10a..72ed3fad36709c 100644 --- a/xr/patches/series +++ b/xr/patches/series @@ -1,2 +1,3 @@ 0007-vesa-dsc-bpp.patch bigscreen-beyond-edid.patch +amdgpu-dsc-pps-debugfs.patch diff --git a/xr/scripts/build-rpm.sh b/xr/scripts/build-rpm.sh index 87351745180238..9037d45925a08a 100755 --- a/xr/scripts/build-rpm.sh +++ b/xr/scripts/build-rpm.sh @@ -17,6 +17,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" XR_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" PATCH_DIR="${XR_DIR}/patches" SERIES_FILE="${PATCH_DIR}/series" +PATCH_WIRING_CHECK="${XR_DIR}/scripts/check-rpm-patch-wiring.sh" SECURITY_DIR="${XR_DIR}/security" SECURITY_CONFIG_CHECK="${XR_DIR}/scripts/check-security-config.sh" CVE_2026_31431_PATCH="cve-2026-31431-algif-aead.patch" @@ -590,6 +591,12 @@ if [[ ! -f "${SERIES_FILE}" ]]; then exit 1 fi +if [[ ! -x "${PATCH_WIRING_CHECK}" ]]; then + echo "ERROR: ${PATCH_WIRING_CHECK} not found or not executable." + exit 1 +fi +"${PATCH_WIRING_CHECK}" + mapfile -t PATCHES < <(grep -vE '^[[:space:]]*(#|$)' "${SERIES_FILE}") if [[ "${#PATCHES[@]}" -eq 0 ]]; then diff --git a/xr/scripts/check-kernel-carry.sh b/xr/scripts/check-kernel-carry.sh index 9a28611800ef75..2d32b042f17907 100755 --- a/xr/scripts/check-kernel-carry.sh +++ b/xr/scripts/check-kernel-carry.sh @@ -12,6 +12,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" XR_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" PATCH_DIR="${XR_DIR}/patches" SERIES_FILE="${PATCH_DIR}/series" +PATCH_WIRING_CHECK="${XR_DIR}/scripts/check-rpm-patch-wiring.sh" usage() { cat <<'EOF' @@ -81,6 +82,12 @@ require_command curl require_command patch require_command tar +if [[ ! -x "${PATCH_WIRING_CHECK}" ]]; then + echo "ERROR: ${PATCH_WIRING_CHECK} not found or not executable." >&2 + exit 1 +fi +"${PATCH_WIRING_CHECK}" + if [[ -z "${WORK_DIR}" ]]; then WORK_DIR="${TMPDIR:-/tmp}/linux-xr-carry-${KERNEL_VERSION}${RT_VERSION:+-${RT_VERSION}}" fi diff --git a/xr/scripts/check-rpm-patch-wiring.sh b/xr/scripts/check-rpm-patch-wiring.sh new file mode 100755 index 00000000000000..7a638c25a1335c --- /dev/null +++ b/xr/scripts/check-rpm-patch-wiring.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# Verify that every XR carry patch listed in series is wired into kernel-xr.spec. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +XR_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +PATCH_DIR="${XR_DIR}/patches" +SERIES_FILE="${PATCH_DIR}/series" +SPEC_FILE="${XR_DIR}/specs/kernel-xr.spec" + +usage() { + cat <<'EOF' +Usage: check-rpm-patch-wiring.sh + +Checks that every non-comment entry in xr/patches/series: + 1. exists in xr/patches/ + 2. has a PatchN declaration in xr/specs/kernel-xr.spec + 3. is applied in %prep by either %patch -PN or an explicit patch command + +This is a static guard only; use check-kernel-carry.sh for kernel tarball +application checks. +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --help|-h) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" >&2 + usage >&2 + exit 1 + ;; + esac +done + +if [[ ! -f "${SERIES_FILE}" ]]; then + echo "ERROR: ${SERIES_FILE} not found." >&2 + exit 1 +fi + +if [[ ! -f "${SPEC_FILE}" ]]; then + echo "ERROR: ${SPEC_FILE} not found." >&2 + exit 1 +fi + +status=0 + +while IFS= read -r patch_file; do + case "${patch_file}" in + ""|\#*) + continue + ;; + esac + + if [[ ! -f "${PATCH_DIR}/${patch_file}" ]]; then + echo "ERROR: missing carry patch ${PATCH_DIR}/${patch_file}" >&2 + status=1 + continue + fi + + patch_number="$( + awk -v patch="${patch_file}" ' + $1 ~ /^Patch[0-9]+:/ && $2 == patch { + sub(/^Patch/, "", $1) + sub(/:$/, "", $1) + print $1 + exit + } + ' "${SPEC_FILE}" + )" + + if [[ -z "${patch_number}" ]]; then + echo "ERROR: ${patch_file} is in series but has no PatchN declaration in ${SPEC_FILE}." >&2 + status=1 + continue + fi + + if grep -Eq "%patch[[:space:]]+-P${patch_number}([[:space:]]|$)" "${SPEC_FILE}" || + grep -Fq "_sourcedir}/${patch_file}" "${SPEC_FILE}"; then + echo "OK: ${patch_file} -> Patch${patch_number}" + else + echo "ERROR: ${patch_file} is Patch${patch_number} but is not applied in %prep." >&2 + status=1 + fi +done < "${SERIES_FILE}" + +exit "${status}" diff --git a/xr/source-sync.md b/xr/source-sync.md index 2c7ea796410415..cbbedd05fbb34d 100644 --- a/xr/source-sync.md +++ b/xr/source-sync.md @@ -51,6 +51,9 @@ macOS case-insensitive checkouts for Linux source truth. Required checks before moving build defaults or release tags: ```bash +# Fast static guard after changing xr/patches/series or kernel-xr.spec: +./xr/scripts/check-rpm-patch-wiring.sh + # Discover current maintained candidates and optionally run bounded preflights: ./xr/scripts/triage-upstream-targets.sh ./xr/scripts/triage-upstream-targets.sh --run-preflight diff --git a/xr/specs/kernel-xr.spec b/xr/specs/kernel-xr.spec index 63e1bf90c42254..ebc13f4d7ffcc9 100644 --- a/xr/specs/kernel-xr.spec +++ b/xr/specs/kernel-xr.spec @@ -42,6 +42,7 @@ Source2: check-security-config.sh # XR patches (fetched by build-rpm.sh into SOURCES/) Patch0: 0007-vesa-dsc-bpp.patch Patch1: bigscreen-beyond-edid.patch +Patch20: amdgpu-dsc-pps-debugfs.patch %if 0%{?apply_cve_2026_31431_patch} Patch2: cve-2026-31431-algif-aead.patch %endif @@ -85,6 +86,7 @@ on AMD GPUs (RDNA2+). Includes: - EDID non-desktop quirk for Beyond (BIG/0x1234) - DSC QP table corrections for 8bpc 4:4:4 at 8 BPP - RC offset fix for ofs[11] in get_ofs_set() CM_444/CM_RGB +- Read-only DSC PPS debugfs observability for Honey lab proof work %if 0%{?apply_cve_2026_31431_patch} - CVE-2026-31431 algif_aead backport %endif @@ -144,6 +146,9 @@ patch -p1 < %{_sourcedir}/patch-%{rt_version}.patch # EDID non-desktop quirk for Beyond (fuzz needed: context shifted by DSC patch) patch -p1 --fuzz=3 < %{_sourcedir}/bigscreen-beyond-edid.patch +# Honey lab diagnostic: expose packed DSC PPS through connector debugfs. +%patch -P20 -p1 + # Apply base config from honey server cp %{SOURCE1} .config