# DF-4966 VERDICT

**Status: reproduced (the wrong-bit translation is deterministic and was
executed on the DF guest against the real DCE11 register field constants).
No memory-safety consequence — functional MMIO misprogramming only.**

## The defect

`id_to_offset` in `sys/dev/drm/amd/display/dc/gpio/dce110/hw_translate_dce110.c`
assigns the *shared* DDC data mask to **every** `GPIO_ID_DDC_DATA` line:

- hw_translate_dce110.c:189-190: `info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;`
- hw_translate_dce110.c:213-215: `case GPIO_DDC_LINE_I2C_PAD: info->offset = mmDC_GPIO_I2CPAD_A;`
  — the offset changes but the mask stays 0x100.

On DCE11, the real `DC_GPIO_I2CPAD_A` (0x4899) field layout is
(dce_11_0_sh_mask.h:4203-4206):

- `DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK = 0x1` (bit 0)
- `DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK = 0x2` (bit 1)

unlike the DDCx_A/DDCVGA_A registers where CLK=bit0 / DATA=bit8 (0x100), which
is why the shared mask is correct for DDC1..6 and VGA (verified controls:
DDC1DATA=0x100, DDC6DATA=0x100, VGADATA=0x100).

So `id_to_offset(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_I2C_PAD)` returns
offset=0x4899 with **mask=0x100 — a bit that does not exist in that register**
(SDA is bit 1). The DDC_CLOCK twin is correct only by coincidence
(DDC CLK bit0 == pad SCL bit0).

## Manifestation (run.log, guest)

- `id_to_offset(DDC_DATA, I2C_PAD)  mask = 0x100 -> WRONG: selects bit 8`
- `id_to_offset(DDC_CLOCK, I2C_PAD) mask = 0x1  -> correct (by coincidence)`
- control `id_to_offset(DDC_DATA, DDC1) = 0x100 == DDC1DATA_A_MASK -> correct`

## Consequence / impact ceiling

The hw_gpio/hw_ddc code then does `REG_UPDATE`/`REG_GET` on 0x4899 with
mask 0x100: read-modify-write **sets/reads an undefined bit** while never
touching the real SDA bit (0x2). Effects: the I2C-pad GPIO DDC line cannot
work (reads always 0; writes hit a reserved bit) — a functional defect; on
hardware where bit 8 of that register aliases something else, unintended
MMIO state change. No kernel memory-safety impact; upstream-shared code
(AMD DAL dce110 hw_translate is verbatim from the amdgpu display-core).

Reached from `dal_gpio_create_ddc` when the VBIOS I2C record points the DDC
data line at the I2C pad (`dc_link_ddc.c:272-276`, offset/mask from
`get_gpio_i2c_info`), i.e. crafted-VBIOS or real boards that wire the pad that
way. Severity: Info (hardening / correctness; no demonstrated security impact).

## Fix

`fix.diff`: override the mask in the DDC_DATA I2C_PAD case with the real SDA
bit (`DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK`). Validated at harness level — the
wrong-bit is structurally eliminated; all other lines keep the shared mask.

## Guest

DragonFly 6.5-DEVELOPMENT #0 (X86_64_GENERIC, 2026-07-02), gcc 8.3.
No AMD hardware (`amdgpu` modules: 0, vendor-0x1002 PCI devices: 0), so the
register constants were verified against the tree's generated headers and the
translation executed at unit level — the defect itself is pure constant
arithmetic, deterministic on any host.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
