apply_below_the_range: BTR min-frame-duration clamp uses wrong constant (dead clamp) and computed min_frame_duration_in_ns is never used
Summary
The clamp compares inserted_frame_duration_in_us against 1000000/max_refresh_in_uHz, which is 0 for every real refresh in uHz, so the clamp never fires; the correctly-computed min_frame_duration_in_ns (1e15/max) is never used. Upstream uses ns/1000 - a porting divergence. Effect: BTR can program below-minimum-refresh frame durations (flicker/stutter); no memory-safety impact (downstream v_total stays clamped), and the whole function is dead code in this port (zero callers of handle_preflight). Match-upstream fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4489 Β· 2 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | β | 2.3 KB | β raw | |
| verdict.json | β | 1.8 KB | view raw |
DF-4489 β BTR minimum-frame-duration clamp uses the wrong constant (dead clamp) + dead min_frame_duration_in_ns
File: sys/dev/drm/amd/display/modules/freesync/freesync.c
Root cause (code-certain; AMD-GPU-gated, no AMD hardware on the audit guest):
- :250-252 apply_below_the_range() computes
min_frame_duration_in_ns = div64_u64((1000000000ULL * 1000000),
in_out_vrr->max_refresh_in_uhz); and then NEVER USES the variable (dead).
- :357-360 the clamp is written as
if (inserted_frame_duration_in_us < (1000000 /
in_out_vrr->max_refresh_in_uhz)) inserted_frame_duration_in_us = (1000000 /
in_out_vrr->max_refresh_in_uhz);
With refresh in Β΅Hz (e.g. 144 Hz = 144000000 Β΅Hz) the divisor yields
1000000/144000000 == 0 β the clamp NEVER fires for any refresh above 1 Β΅Hz
encoded value > 1 MHz equivalent; i.e. it is dead for every real panel.
- Correct arithmetic (matches upstream Linux amd display, which this port
diverges from): duration_in_us = 1e12 / refresh_in_uhz, i.e. the clamp
should compare against min_frame_duration_in_ns / 1000.
Impact: functional only β BTR frame insertion can program frame durations
below the panel's minimum refresh, i.e. flicker/stutter in below-the-range
operation. No memory-safety consequence: the resulting v_total computed via
calc_v_total_from_duration() :146-160 is clamped into
[min_duration_in_us, max_duration_in_us] and floor-clamped to the nominal
v_total, so nothing out-of-range reaches hardware programming. Severity Info
(hardening / correctness divergence from upstream).
Not runtime-verifiable on this audit guest (no AMD GPU β QEMU virtio-gpu
only; pciconf -l shows no AMD vendor 0x1002 device), and the AMD DC freesync
module is not reachable without amdgpu hardware. Static analysis only.
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.
(No fix.diff for this item: documented recommendation only - see Fix above.)
Fix verification
not_testableNo AMD hardware on the audit guest; static arithmetic proof only.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md (arithmetic proof: 1000000/144000000 == 0)
Verified recommended fix
Use min_frame_duration_in_ns/1000 (i.e. div64_u64(1000000000000ULL, max_refresh_in_uhz)) for the inserted_frame_duration_in_us clamp
Verdict
Porting divergence in apply_below_the_range (freesync.c:250-252,357-360): min_frame_duration_in_ns is computed then never used, and the clamp compares inserted_frame_duration_in_us against (1000000 / max_refresh_in_uhz) which is 0 for every real refresh in uHz (correct arithmetic is 1e12/refresh_uHz, cf. upstream Linux amd display 'min_frame_duration_in_ns / 1000'). The clamp is dead -> BTR may insert frames below the panel minimum refresh (flicker); no memory-safety impact (v_total is re-clamped to [min,max] duration and nominal v_total in calc_v_total_from_duration :146-160). AMD-GPU-gated: audit guest has no AMD device (virtio-gpu only), so not runtime-testable. Info severity.
No comments yet.