DCC/PTE read-bandwidth overhead factors (1 + 1/256)/(1 + 1/64)/(1 + 1/512) are C integer constant divisions that compile to *1 β the DCN1 DCC/PTE bandwidth overhead accounting is dead code
Summary
mode_support_and_system_configuration transcribes the DCN1 spreadsheet overhead factors as integer constant expressions: each 1/N is an int division evaluating to 0, so every factor compiles to exactly 1 and the DCC-compression and PTE-row overhead on read_bandwidth is never applied. total_read_bandwidth under-counts by up to ~1.5%/plane and bandwidth_support can validate a configuration the hardware model would reject - marginal modes pass validation and can hit DRAM/DCFCLK underruns (flicker/underflow) on Raven APUs. No kernel memory-safety impact (all consumers are float comparisons that fail safe). Reproduced by compiling the REAL kernel source on the guest: two planes differing only in dcc_enable yield byte-identical read_bandwidth (ratio 1.000000000); fix flips it to exactly 1.00390625. The identical transcription bug exists upstream. Float-constant fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4199 Β· 15 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.7 KB | β raw | |
| VERDICT.md | β | 5.1 KB | β raw | |
| dcnauto_harness.c | β | 12.6 KB | view raw | |
| dm_services.h | β | 1.9 KB | view raw | |
| display_clock.h | β | 452 B | view raw | |
| build.sh | β | 163 B | view raw | |
| run.sh | β | 89 B | view raw | |
| build.log | β | 1.6 KB | view raw | |
| run.log | β | 1.8 KB | view raw | |
| run.2.log | β | 1.8 KB | view raw | |
| run.3.log | β | 243 B | view raw | |
| env.txt | β | 244 B | view raw | |
| fix.diff | β | 1.9 KB | view raw | |
| manifest.json | β | 1.3 KB | view raw | |
| verdict.json | β | 3.9 KB | view raw |
DF-4199 β dead DCC/PTE bandwidth-overhead factors in dcn_calc_auto.c (integer-constant division transcription bug)
File: sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c (pass 2)
Severity: Info (correctness; no kernel memory-safety impact)
Status: reproduced at source level on the audit guest by compiling the
REAL kernel source (DF-4198 pattern).
What
mode_support_and_system_configuration() applies DCC-compression and PTE-row
read-bandwidth overhead factors that were transcribed from the DCN1
spreadsheet ("HW gospel", REVISION#250) as C integer constant expressions:
v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 256); /* :178 DCC */
v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 64); /* :181 PTE */
v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 256); /* :184 PTE */
v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 512); /* :187 PTE */
In C, 1 / 256, 1 / 64, 1 / 512 are int divisions that evaluate to
0, so every factor compiles to exactly 1 and the entire DCC/PTE
overhead accounting is dead code. The spreadsheet intends 1.00390625,
1.015625, 1.00390625, 1.001953125 respectively.
Impact
total_read_bandwidth_consumed_gbyte_per_second (dcn_calc_auto.c:189) is
under-estimated by up to ~1.5% per DCC+PTE plane, and bandwidth_support[i]
(:231) can therefore say yes for a configuration the hardware model would
reject β a marginal mode passes DCN1 validation and can hit DRAM/DCFCLK
underruns (visual corruption / flicker on Raven APUs). No kernel memory
corruption: every consumer in the file is an IEEE-754 float comparison;
the only float->int conversions (voltage_level, dispclk_dppclk_ratio)
are provably in-range (see VERDICT.md "killed candidates").
Reproduce
./build.sh # pulls REAL dcn_calc_auto.c + dcn_calc_math.c + real DCN
# headers from guest /usr/src; only dm_services.h and
# display_clock.h are stubs; builds baseline + fixed
./run.sh # dcc / pte / degen / log0 tests
Expected (see run.log / run.2.log):
baseline: read_bw[dcc]=518.400024 read_bw[nodcc]=518.400024 ratio=1.000000000
DEFECT PRESENT: factor (1 + 1/256) evaluated to exactly 1
fixed: read_bw[dcc]=522.457947 read_bw[nodcc]=520.425049 ratio=1.003906250
FIXED: factor is (1.0 + 1.0/256.0) = 1.00390625
The same binary also documents the pass-2 negative results: degenerate
crafted inputs (pixel_clock=0, htotal=0, all-zero socBB clocks,
viewport_width=0 feeding dcn_bw_log(0) = -127) produce no SIGFPE/#DE
β every division in this file is float β validation fails safe, and
voltage_level stays within [0,5].
Fix
fix.diff (4 lines, applied and validated in this pack).
DF-4199 VERDICT β dead (1 + 1/N) overhead factors in dcn_calc_auto.c
Verdict: reproduced (source-level, on-guest, real-source harness), impact = none (Info-class correctness defect: DCC/PTE bandwidth overhead accounting is dead code on DCN1). Confidence: certain.
How reproduced
The REAL sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c and
calcs/dcn_calc_math.c were compiled unmodified on the audit guest
(DragonFly 6.5-DEVELOPMENT, cc 8.3) together with the REAL header chain
(inc/dcn_calcs.h, inc/bw_fixed.h, dml/*.h); only dm_services.h
(non-fatal ASSERT / log sinks β matches release os_types.h WARN_ON
semantics) and display_clock.h (opaque struct dc_clocks only) are stubs.
The harness (dcnauto_harness.c) fills struct dcn_bw_internal_vars
exactly the way the kernel does β memset(v,0,sizeof(*v))
(dcn_calcs.c:716) + DCN1 socbb/ip defaults transcribed verbatim from
dcn_calcs.c:57-157 + the same per-state tables (dcn_calcs.c:796-831) and
per-plane fill (dcn_calcs.c:845-984) β then runs the kernel's full call
sequence scaler_settings_calculation β mode_support_and_system_configuration
β display_pipe_configuration β dispclkdppclkdcfclk_β¦ (dcn_calcs.c:987-1035).
Decisive output (run.log, deterministic 2/2):
baseline read_bw[dcc] = 518.400024 baseline read_bw[nodcc]= 518.400024 ratio=1.000000000 -> DEFECT PRESENT fixed ratio = 1.003906250 -> FIXED
Two byte-identical planes differing only in dcc_enable produce
byte-identical read_bandwidth[], proving the * (1 + 1 / 256) factor at
dcn_calc_auto.c:178 compiles to * 1. The PTE factors at :181/:184/:187 are
dead the same way (pte test: 4KB_S-vert vs var_d-vert read_bw equal). With
fix.diff applied to the real source and recompiled, the DCC plane reads
exactly 1.00390625Γ the non-DCC plane.
Why it matters (and why only Info)
total_read_bandwidth_consumed_gbyte_per_second (:189) under-counts by up
to ~1.5%/plane; bandwidth_support[i] (:231) can pass a configuration the
DCN1 hardware model would reject β marginal mode validated β DRAM/DCFCLK
underrun (flicker/underflow) on Raven. Every consumer of these values in
the file is a float comparison; no kernel memory safety is affected.
Upstream Linux carries the identical transcription bug (same REVISION#250
file), so the defect is not DFly-specific.
Pass-2 killed candidates (evidence in run.log "degen"/"log0" sections)
- Integer #DE family (DF-3869/3870, DF-4198 class): there are NO
runtime integer divisions and NO explicit floatβint casts in this file;
every division is IEEE-754 float. Degenerate crafted inputs
(pixel_clock=0, htotal=0, all-zero socBB clocks incl. dcfclk/dram/phy)
run all four functions with no SIGFPE; NaN/inf make every support
comparison false β validation fails safe (
mode_support= no,voltage_level=5). - Index safety (output writes vs declared sizes, checklist c): k is
bounded by
number_of_active_planes= streams-with-pipes β€pool->pipe_count=res_cap->num_timing_generatorβ€ 6 =number_of_planes_minus_one + 1arrays (dcn10_resource.c:1212); i β€ 5 into[number_of_states_plus_one + 1]= 6; j β {0,1} into[1+1];voltage_levelβ [0,5] becausevoltage_override_levelis memset-0 and never set elsewhere, so the loops at :963/:968 always assign at i=5 first (verified in all degen runs: voltage_level=5). - dcn_bw_log(0)/negative (checklist b):
dcn_bw_log(0.0f,2.0f)returns exactly -127.0 (dml_log2 twin) anddcn_bw_pow(2,-127)= 5.877e-39 subnormal β garbage floats only, no trap; with a degenerate viewport_width=0 plane the dpte row math produces garbage but the mode is rejected. All four call sites (:665, :726, :1491, :1550) take strictly positive arguments for validated planes (viewport β₯ 1 px, no_of_dpp β {1,2}), so this is unreachable from UABI-legal input and fails safe even when forced. - byte-per-element zero (checklist e, DF-4198 class): the
byte_per_pixel_in_dety/detcswitch (:153-172, :1016-1035, :1233-1252) has an else-branch (4/3, 8/3) covering every unhandled enum β no 0-divisor family here. - Do/while prefetch loops (:1608-1755): terminate β once
v_startup_linesexceeds everymax_vstartup_lines[k]the threeplanes_with_roomβ¦flags keep their re-initialized values (yes/no/no) and the inner loop exits; outer loop exits atprefetch_mode == 2.0; NaN comparisons are false, which also exits.
Fix validation
fix.diff (4 one-line changes, int constants β float constants) applied to
the real source and rebuilt on the guest: baseline defect 2/2 runs, fixed
0/2 (ratio exactly 1.00390625) β fix_status fixed (harness-level; kernel
build validation not possible on this guest, no AMD GPU β env.txt).
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
fixedfix.diff applied to the REAL dcn_calc_auto.c and recompiled on the guest: baseline defect 2/2 runs (ratio exactly 1.000000000), patched 0/2 with DCC plane exactly 1.00390625x the non-DCC plane. Harness-level validation complete; kernel-build validation not possible (guest has no AMD GPU).
run.log + run.2.log baseline 'DEFECT PRESENT'; run.3.log fixed 'FIXED: factor is (1.0 + 1.0/256.0) = 1.00390625'; fix.diff
Confirmed kernel references
- sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c:178
- sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c:181
- sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c:184
- sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c:187
- sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c:189
- sys/dev/drm/amd/display/dc/calcs/dcn_calc_auto.c:231
- sys/dev/drm/amd/display/dc/calcs/dcn_calcs.c:716
- sys/dev/drm/amd/display/dc/calcs/dcn_calcs.c:57
Detail
Evidence (decisive lines)
run.log/run.2.log baseline 'DEFECT PRESENT ... ratio=1.000000000' vs fixed 'FIXED ... ratio=1.003906250'; degen sections show no SIGFPE for zero clocks and safe voltage_level=5; log0 section documents dcn_bw_log(0)=-127 no-trap twin; build.log real-source compile; env.txt guest uname + no AMD GPU
PoC changes
harness written fresh (no seed): kernel-faithful fill of struct dcn_bw_internal_vars (memset-0 + dcn10_soc/ip_defaults transcribed from dcn_calcs.c:57-157 + per-state tables dcn_calcs.c:796-831); dm_services.h stub extended with u64/BUILD_BUG_ON/div64_u64_rem for the real bw_fixed.h inlines; display_clock.h stub = opaque struct dc_clocks
Verified recommended fix
Replace the four integer-constant factors with float constants: (1.0 + 1.0/256.0), (1.0 + 1.0/64.0), (1.0 + 1.0/256.0), (1.0 + 1.0/512.0) β see fix.diff.
Verdict
REAL dcn_calc_auto.c + dcn_calc_math.c compiled unmodified on the audit guest and driven exactly like the kernel (memset-0 vars + DCN1 socbb/ip defaults + kernel call sequence): two byte-identical planes differing only in dcc_enable produce byte-identical read_bandwidth, proving the four overhead factors (1 + 1/256)/:(1 + 1/64)/:(1 + 1/512) at dcn_calc_auto.c:178/181/184/187 are C integer constant divisions that compile to *1 β the DCC/PTE bandwidth overhead accounting is dead code. Same harness proves the pass-2 negative results: no integer #DE sites exist (all-float arithmetic; zero clocks/pixel_clock/htotal/viewport yield inf/NaN that fail validation safe, voltage_level stays in [0,5]). Info severity: worst realistic impact is marginal DCN1 modes passing validation and hitting display underruns; identical transcription bug exists upstream.
No comments yet.