id_to_offset GPIO_ID_DDC_DATA hardwires the DDC6DATA bit-8 mask (0x100) for every line including the I2C pad, whose SDA field is bit 1 (0x2) β translate and factory tables disagree; the pin would be driven on the wrong GPIO bit
Summary
The mask is assigned once outside the per-line switch: correct for DDC1-6/VGA but wrong for I2C_PAD (SDA at bit 1; the factory's own ddc_i2c_data_regs uses the SDA mask). Latent (the consumer is dead API). Harness-proven exactly one WRONG-BIT line; per-line-mask fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4947 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.0 KB | β raw | |
| VERDICT.md | β | 2.7 KB | β raw | |
| harness_mask.c | β | 5.8 KB | view raw | |
| build.log | β | 703 B | view raw | |
| run.log | β | 703 B | view raw | |
| fix.diff | β | 1.7 KB | view raw | |
| manifest.json | β | 758 B | view raw | |
| verdict.json | β | 3.2 KB | view raw |
DF-4947 β DCN10 id_to_offset hands the I2C pad the DDC6DATA mask (wrong GPIO bit)
File: sys/dev/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c:211-212,235-237
Family: DF-4944 (dce80 mask-vs-index) β this is the DCN10 twin.
Severity: Info Β· CWE-697 (plus latent CWE-1298 wrong-bit programming)
Build
gcc -O2 -Wall -Wextra -o harness_mask harness_mask.c
Run
./harness_mask
Expected
id_to_offset(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_I2C_PAD) pairs
offset = REG(DC_GPIO_I2CPAD_A) (0x5dc1) with mask = 0x100 (the DDC6DATA
bit-8 layout), but DC_GPIO_I2CPAD_A's SDA field is bit 1 (0x2)
(dcn_1_0_sh_mask.h:41219) and the factory's own ddc_i2c_data_regs entry for
this pin uses that SDA_A_MASK (ddc_regs.h:69-71). Exactly 1 WRONG BIT line;
DDC1-6/VGA (identical bit-8/bit-0 layout to DDC6) and the SCL clock mask are
coincidentally correct. The sole in-tree consumer (dal_gpio_get_pin_info,
gpio_base.c:140-147) currently has no callers, so the defect is latent.
DF-4947 VERDICT β reproduced (deterministic unit-level; latent β no in-tree consumer)
Defect
id_to_offset's GPIO_ID_DDC_DATA branch (hw_translate_dcn10.c:211-212) sets
info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK (0x100) before the
per-line switch and never changes it, so every DDC line β including
GPIO_DDC_LINE_I2C_PAD (hw_translate_dcn10.c:235-237) β receives the DDC6
bit-8 layout mask. For DDC1..6 and VGA that is correct by coincidence:
DC_GPIO_DDC{1..6,VGA}DATA_A_MASK are all 0x100 and the CLK masks all 0x1
(dcn_1_0_sh_mask.h:40628,40817-40818,40853-40854).
The I2C pad is different silicon: DC_GPIO_I2CPAD_A exposes
DC_GPIO_SCL_A at bit 0 (0x1) and DC_GPIO_SDA_A at bit 1 (0x2)
(dcn_1_0_sh_mask.h:41216-41219). The factory's own table for the same pin β
ddc_i2c_data_regs via DDC_GPIO_I2C_REG_LIST_ENTRY(A, SDA) (ddc_regs.h:66-71)
β uses DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK. The two tables disagree:
id_to_offset would drive/read bit 8 of the I2C pad register instead of the
SDA line. (DDC_CLOCK + I2C_PAD gets 0x1 == SCL_A β correct by coincidence.)
Result (run.log)
harness_mask (verbatim copies of hw_translate_dcn10.c:210-274, real DCN10
constants): id_to_offset(DDC_DATA, I2C_PAD) = true offset=0x5dc1 mask=0x100
real field mask=0x2 WRONG BIT (DF-4947) β exactly 1 wrong-mask line; the
DDC1/VGA/SCL lines report OK. Deterministic.
Reachability (why Info)
The only in-tree consumer of id_to_offset is dal_gpio_get_pin_info
(gpio_base.c:140-147); rg dal_gpio_get_pin_info across sys/dev/drm returns
no callers. The mask defect is therefore latent today (the factory path β
define_ddc_registers β is what actually programs the pins, and it uses the
correct per-pin tables). If dal_gpio_get_pin_info is ever wired up (it is
part of the exported gpio interface), the I2C pad would be driven on the
wrong bit. Info severity, matching the DF-4944 family precedent.
Fix validation
fix.diff moves the mask assignment into the per-line switch and selects
DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK for the I2C pad data line (the same
edit modeled in DF-4946's harness_fixed.c, which reports
mask=0x2 (SDA_A_MASK=0x2: CORRECT) and 0 residual violations). Kernel
rebuild is meaningless for a userland unit harness; structural validation
matches family precedent (DF-4944 fix validated the same way).
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.
Fix verification
not_testablefix.diff moves the mask selection into the per-line switch and selects DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK (0x2) for the I2C pad data line; the identical edit is modeled in DF-4946's harness_fixed.c which reports mask=0x2 CORRECT with 0 residual violations. No in-tree consumer exists today, so the patched-behavior demonstration is the unit model (family precedent DF-4944).
fix.diff (per-line mask hunks for hw_translate_dcn10.c); DF-4946/run.log 'FIXED T3: I2C_PAD data mask is now the real SDA field ... CORRECT'.
Confirmed kernel references
Detail
Evidence (decisive lines)
run.log line 'id_to_offset(DDC_DATA, I2C_PAD) = true offset=0x5dc1 mask=0x100 real field mask=0x2 WRONG BIT (DF-4947)' plus the three OK lines proving the DDC6 layout masks are correct for DDC1-6/VGA/SCL; DF-4946/run.log 'FIXED T3' shows the fixed model selecting mask=0x2 CORRECT.
PoC changes
n/a β fresh self-contained harness (verbatim DDC branches of the dcn10 id_to_offset, real DCN10 constants).
Verified recommended fix
Select the mask per DDC line in id_to_offset; use DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK for GPIO_DDC_LINE_I2C_PAD under GPIO_ID_DDC_DATA.
Verdict
id_to_offset's GPIO_ID_DDC_DATA branch (hw_translate_dcn10.c:211-212) hardwires info->mask to the DDC6DATA bit-8 layout (0x100) for every DDC line, including GPIO_DDC_LINE_I2C_PAD (235-237). The I2C pad register DC_GPIO_I2CPAD_A exposes its data line (SDA) at bit 1 (0x2, dcn_1_0_sh_mask.h:41216-41219), and the factory's own ddc_i2c_data_regs entry for this pin uses that SDA_A_MASK (ddc_regs.h:66-71) β the translate and factory tables disagree, so the translate path would drive/read the wrong GPIO bit. Demonstrated deterministically on the DF guest with verbatim function copies and real DCN10 constants: run.log shows exactly one WRONG BIT line (mask=0x100 vs real 0x2); DDC1-6/VGA (identical layout) and the SCL clock mask are coincidentally correct. The sole in-tree consumer, dal_gpio_get_pin_info (gpio_base.c:140-147), has no callers today, so the defect is latent β Info severity, matching the DF-4944 family precedent.
No comments yet.