DF-5135 / i915_probe.c
/* * i915_probe.c -- kmod PoC helper for DF-5135 * (TUNABLE_bool() in sys/dev/drm/include/linux/moduleparam.h casts a 1-byte * _Bool param to (int *) and kgetenv_int() stores 4 bytes, corrupting the * following params in struct i915_params). * * Reads the real i915_modparams symbol out of i915.ko at the offsets of the * trailing bool block (identical ABI to the struct in i915_params.h). * * Must be kldload'ed AFTER i915.ko. */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/module.h> #include <sys/sysctl.h> #include <sys/types.h> #include <sys/stdint.h> /* exact replica of struct i915_params member order (i915_params.h) */ struct probe_params { char *vbt_firmware; int modeset, lvds_channel_mode, panel_use_ssc, vbt_sdvo_panel_type; int enable_dc, enable_fbc, enable_ppgtt, enable_psr, disable_power_well; int enable_ips, invert_brightness, enable_guc, guc_log_level; char *guc_firmware_path, *huc_firmware_path, *dmc_firmware_path; int mmio_debug, edp_vswing, reset; unsigned int inject_load_failure; _Bool alpha_support, enable_hangcheck, fastboot, prefault_disable, load_detect_test, force_reset_modeset_test, error_capture, disable_display, verbose_state_checks, nuclear_pageflip, enable_dp_mst, enable_dpcd_backlight, enable_gvt; }; extern unsigned char i915_modparams[]; /* the real thing, from i915.ko */ #define POFF(m) ((int)(unsigned long)&((struct probe_params *)0)->m) static int probe_show(SYSCTL_HANDLER_ARGS) { unsigned char *p = i915_modparams; int out = p[POFF(verbose_state_checks)]; kprintf("dmabug: i915_modparams @ %p (sizeof=%zu)\n", i915_modparams, sizeof(struct probe_params)); kprintf("dmabug: error_capture=%d disable_display=%d " "verbose_state_checks=%d nuclear_pageflip=%d\n" "dmabug: (defaults were: 1 0" " 1 0)\n", p[POFF(error_capture)], p[POFF(disable_display)], p[POFF(verbose_state_checks)], p[POFF(nuclear_pageflip)]); kprintf("dmabug: enable_dp_mst=%d enable_dpcd_backlight=%d " "enable_gvt=%d (last member; 4-byte store ends in padding)\n", p[POFF(enable_dp_mst)], p[POFF(enable_dpcd_backlight)], p[POFF(enable_gvt)]); kprintf("dmabug: enable_hangcheck=%d fastboot=%d " "prefault_disable=%d load_detect_test=%d\n", p[POFF(enable_hangcheck)], p[POFF(fastboot)], p[POFF(prefault_disable)], p[POFF(load_detect_test)]); return sysctl_handle_int(oidp, &out, 0, req); } SYSCTL_NODE(_hw, OID_AUTO, i915probe, CTLFLAG_RW, 0, "i915 param probe"); SYSCTL_PROC(_hw_i915probe, OID_AUTO, params, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_ANYBODY, NULL, 0, probe_show, "I", "dump trailing bool block of i915_modparams"); static int probe_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: kprintf("dmabug: i915 probe loaded; i915_modparams=%p " "(error_capture@%d verbose_state_checks@%d " "enable_gvt@%d)\n", i915_modparams, POFF(error_capture), POFF(verbose_state_checks), POFF(enable_gvt)); return 0; case MOD_UNLOAD: return 0; } return 0; } static moduledata_t probe_mod = { "i915probe", probe_modevent, NULL }; DECLARE_MODULE(i915probe, probe_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); |