⬢ DragonFlyBSD Kernel Audit
DF-3572 / run.log
← back to finding ↓ download raw
primary  src 8192x8192 -> dst 2731x2731  ds=8.9979 (<3/axis OK)  data_rate = 2415353856  (0x8ff76000, fits u32: True)
sprite0  src 4096x8192 -> dst 1366x2731  ds=8.9946 (<3/axis OK)  data_rate = 1207234560  (0x47f4f000, fits u32: True)
sprite1  src 4096x8192 -> dst 1366x2731  ds=8.9946 (<3/axis OK)  data_rate = 1207234560  (0x47f4f000, fits u32: True)

true 32-bit sum          = 4829822976
kernel total_data_rate   = 534855680  (0x1fe14000)  WRAPPED by 4294967296

ddb_size=892 alloc_size=860
primary  PLANE_BUF_CFG ddb entry [    0, 3891]  -> +2999 blocks vs ddb_size 892
sprite0  PLANE_BUF_CFG ddb entry [ 3891, 5840]  -> +4948 blocks vs ddb_size 892
sprite1  PLANE_BUF_CFG ddb entry [ 5840, 7789]  -> +6897 blocks vs ddb_size 892

RESULT: the u32 wrap in total_data_rate shrinks the denominator ~9x, each
plane's proportional share is multiplied accordingly, and the three DDB
entries run far past the pipe's DDB end (hardware field is 10 bits
[SKL_DDB_ENTRY_MASK=0x3FF, i915_reg.h:6667], so the programmed values alias
to yet different wrong ranges).  Nothing downstream bounds an entry against
ddb_size (skl_ddb_allocation_overlaps, intel_display.c:12696, only orders
cross-PIPE updates), so skl_ddb_entry_write() programs out-of-range
PLANE_BUF_CFG start/end -> overlapping display buffer allocations ->
display FIFO underrun / pipe wedge (modeset or GPU reset to recover).
Local DoS by any DRM master.

Linux computes these rates in u64 (v5.2 rework of
skl_plane_relative_data_rate/skl_get_total_relative_data_rate); this
DragonFly tree retains the pre-v5.2 u32 arithmetic.