watchthelight labs

Probe reports wanted from other Intel Xe machines (stage 2, read-only) #3

openhelp wantedtesting
watchthelight 2026-10-21

Stage 2 only reads registers. Reports from Tiger Lake, Alder Lake, Raptor Lake, Meteor Lake, Lunar Lake and Arc machines tell us what the shim sees elsewhere (BAR sizes, GMD_ID, stolen memory base, the firmware's pipe and GGTT state, PCH watchdog). How to run it and what to post: CONTRIBUTING.md, section Testing on your machine. Please do not run stage 4 yet.

TrDiTu 2026-10-30

Hi @watchthelight , I saw the issue that you left on my repository about my hackintosh project and I wanna provide my info that I got when try to run your project:

I actually tried to run Stage 4 (sysctl debug.xegfx_stage=4), a kernel panic occurs due to a page fault (Type 14, CR2: 0x0000000000000000) inside _xg_vsnprintf + 0x45.
Stages 1, 2, and 3 all passed cleanly on this Alder Lake-P platform. The panic trace indicates that _intel_detect_pch() invokes LinuxKPI's _lkpi_pci_get_class() to probe the LPC/ISA bridge (PCI_CLASS_BRIDGE_ISA), which attempts to register a kobject with a NULL format string, causing an unguarded dereference in string formatting / xg_has_pext.

System Environment

  • Target OS: macOS 26 Tahoe (Darwin 25.6.0, Build 25G241, x86_64)
  • XeGfx Version: v0.0.38 (Commit 78db6fceab4a6d50c3072c12e5ea89688f281d26)
  • Device Model: HP Victus 15-fa0xxx (Motherboard: HP 8A4F)
  • CPU: Intel Core i7-12650H (Alder Lake-H/P, 6P + 4E, 16 threads, Family 6 Model 154 Stepping 3)
  • Host Bridge: 8086:4649
  • iGPU: Intel UHD / Iris Xe Graphics Alder Lake-P GT1 (8086:46A3, Rev 0x0C, 64 EUs)
  • PCH Chipset: Intel Alder Lake PCH-P LPC/ISA Bridge (8086:5182)
  • Discrete GPU: NVIDIA GeForce RTX 3050 Ti Mobile (Completely powered down via ACPI _OFF())
  • Boot Arguments: -v debug=0x100 keepsyms=1 -lilubetaall amfi_get_out_of_my_way=0x1 -vi2c-force-polling -wegnoegpu alcid=11
  • SIP / Security: SIP disabled (csr-active-config = 0x0FEF), SecureBootModel = Disabled, XeGfx loaded dynamically into AuxKC (not injected via OpenCore).

Preceding Stage Results (All Passed)

  1. Stage 1 (Shim state & Vmap test):
    • Result: debug.xegfx_results = 0x00000001 (PASS)
    • xegfx: vm: vmap selftest 0 succeeded without -12 error.
  2. Stage 2 (Read-only GPU Probe):
    • Result: debug.xegfx_results = [Stage 1: 1, Stage 2: 1] (PASS)
    • XeGfxProbe dictionary successfully populated in IORegistry:
      • device-id = 0x9A49 (Tiger Lake spoof) / Physical hardware 8086:46A3
      • revision = 0x0C, bar0 = 16 MiB, bar2 = 256 MiB
      • pipe-a-lit = 1, boot-fb-size = 8294400 (1080p 32-bit eDP).
  3. Stage 3 (Newbus & DMA layer):
    • Result: debug.xegfx_results = [Stage 1: 1, Stage 2: 1, Stage 3: 1] (PASS)
    • Device tree resolved: hostb0 (8086:4649) -> vgapci0 (8086:9a49) -> drmn0
    • Stolen memory: base = 0x7c800000, size = 60 MiB, DMA physical mapping active.

Steps to Reproduce

  1. Install and load XeGfx.kext into AuxKC via sudo kmutil load -b org.watchthelight.XeGfx.
  2. Successfully execute Stages 1, 2, and 3:
    sudo sysctl debug.xegfx_stage=1
    sudo sysctl debug.xegfx_stage=2
    sudo sysctl debug.xegfx_stage=3
  3. Trigger Stage 4:
    sudo sysctl debug.xegfx_stage=4

Actual Behavior (Kernel Panic)

The system immediately panics with a page fault at CR2: 0x0000000000000000.

Panic Header & Registers:

panic(cpu 0 caller 0xffffff80184d528a): Kernel trap at 0xffffff7faeffcad5, type = 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x0000000000000000, CR3: 0x0000000560b2e105, CR4: 0x00000000003626e0
RAX: 0xffffffb984b78910, RBX: 0x0000000000000000, RCX: 0xffffffb984b788b0, RDX: 0x0000000000000000
RSP: 0xffffffb984b78870, RBP: 0xffffffb984b78890, RSI: 0x0000000000000000, RDI: 0xffffffb984b788af
R8: 0xffffffb984b78a00, R9: 0xffffff9e4d4aea60, R10: 0x0000000000000000, R11: 0x0000000000000200
R12: 0xffffffb984b789c0, R13: 0xffffff7faf1405b8, R14: 0x0000000000000000, R15: 0xffffffa98102cf10
RFL: 0x0000000000010282, RIP: 0xffffff7faeffcad5, CS: 0x0000000000000008, SS: 0x0000000000000010
Fault CR2: 0x0000000000000000, Error code: 0x0000000000000000, Fault CPU: 0x0
Panicked task: pid 863: sysctl

Backtrace:

org.watchthelight.XeGfx : _xg_vsnprintf + 0x45
org.watchthelight.XeGfx : _kobject_set_name_vargs + 0x8a
org.watchthelight.XeGfx : _kobject_init_and_add + 0xc7
org.watchthelight.XeGfx : _lkpi_pci_dev_init_common + 0x3f
org.watchthelight.XeGfx : _lkpi_pci_get_class + 0x5f
org.watchthelight.XeGfx : _intel_detect_pch + 0x63
org.watchthelight.XeGfx : _i915_driver_probe + 0x56d
org.watchthelight.XeGfx : _linux_pci_attach_device + 0x50b
org.watchthelight.XeGfx : _device_attach + 0x5a
org.watchthelight.XeGfx : _bus_generic_driver_added + 0x3d
org.watchthelight.XeGfx : _xg_pci_driver_added + 0x35
org.watchthelight.XeGfx : _devclass_add_driver + 0xa9
org.watchthelight.XeGfx : _lkpi_pci_register_driver + 0xc5
org.watchthelight.XeGfx : _i915kms_evh + 0x2dc
org.watchthelight.XeGfx : _module_register_init + 0xa9
org.watchthelight.XeGfx : _xg_run_set + 0x22a
org.watchthelight.XeGfx : _xg_start_stage + 0x46
org.watchthelight.XeGfx : __ZL18xegfx_stage_sysctlP10sysctl_oidPviP10sysctl_req + 0x4f7


Root Cause Analysis

  1. During _i915_driver_probe, the driver executes intel_detect_pch() to identify the platform's PCH (8086:5182 Alder Lake PCH-P) via pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, ...).
  2. LinuxKPI finds the device and calls _lkpi_pci_dev_init_common(), which calls kobject_init_and_add() -> kobject_set_name_vargs().
  3. The format string pointer passed into _xg_vsnprintf is NULL (RDX = 0x0000000000000000).
  4. In shim/src/xnu/xg_kext.cpp (or corresponding string helper), xg_has_pext(fmt) iterates through characters via for (; *f; f++) without an initial guard if (!f) return false; (or checking for nullptr), causing an immediate NULL pointer dereference.
zsct648gn6-dev 2026-10-31

Stage 2 report: Lenovo Legion Y9000P 2022 / i7-12700H / 8086:46A6

Hi @watchthelight, I ran the stage 2 probe on my machine.

  • Laptop: Lenovo Legion Y9000P 2022 (IAH7H / 82RF)
  • CPU: Intel Core i7-12700H
  • iGPU: Alder Lake-P GT2 / Iris Xe Graphics, 8086:46A6, revision 0C
  • dGPU: RTX 3070 Laptop GPU, 10DE:24DD
  • macOS: 26.7.1 (25G241)
  • XeGfx: Prebuilt v0.0.46
  • BIOS graphics mode: Hybrid enabled for this test. I normally use discrete-only mode.
  • OpenCore / iGPU visibility: macOS enumerates the iGPU as IGPU@2, with device-id = <a6460000>. Ubuntu also detects it at 00:02.0.

The load command returned without an error:

sudo kmutil load -b org.watchthelight.XeGfx
sudo sysctl debug.xegfx_stage=2
debug.xegfx_stage: 0 -> 2

Registry output:

+-o XeGfxResident <class XeGfxResident, id 0x100000935, registered, matched, active, busy 0 (0 ms), retain 5>
    {
      "IOProbeScore" = 0
      "CFBundleIdentifier" = "org.watchthelight.XeGfx"
      "IOMatchCategory" = "XeGfxArmed"
      "IOClass" = "XeGfxResident"
      "IOPersonalityPublisher" = "org.watchthelight.XeGfx"
      "IOProviderClass" = "IOResources"
      "CFBundleIdentifierKernel" = "org.watchthelight.XeGfx"
      "XeGfxProbe" = {"plane-surf-1-a"=0,"pipe-a-lit"=1,"pipe-frmcount-a"=22717,"tco-ctl"=257,"tco2-sts"=0,"bar2-size"=268435456,"tco1-cnt"=6144,"gmd-id-graphics"=0,"tco2-cnt"=8,"revision"=12,"subsystem"=988616618,"bar0-base"=275146342400,"boot-fb-size"=16384000,"transconf-a"=18446744072635809792,"bar2-base"=274877906944,"dsm-base-lo"=1283457025,"device-id"=18086,"plane-size-1-a"=104794623,"ggtt-pte-surf"=1283457025,"tco-base"=1024,"tco-rld"=4,"dsm-base-hi"=0,"tco-tmr"=4,"command"=7,"ggc"=65217,"gmd-id-display"=0,"pcode-stolen-access"=0,"plane-stride-1-a"=160,"tco1-sts"=0,"result"=1,"plane-ctl-1-a"=18446744071897612296,"bar0-size"=16777216}
      "IOResourceMatch" = "XeGfxArm"
      "XeGfxStage" = 2
    }

Complete output of sysctl -b debug.xegfx_log:

xegfx: vm: vmap selftest 0

Only stages up to 2 were requested; I have not run stage 4 or higher. Let me know if any additional information would help.

watchthelight 2026-10-31

Thanks a lot for running this and for the full panic, it's a clear report.

Stages 1 to 3 passing on 46A3 is good news. The panic is in my code. At stage 4, i915 asks for the PCH's ISA bridge, the LinuxKPI shim builds a device for it without a name, and the formatter then reads a NULL format string. My Arrow Lake machines never take that path, which is why I hadn't seen it. Nothing between 0.0.38 and 0.0.46 changes it.

Please stay at stage 3 or below for now. I'll post here when a build has the fix. Even then, stage 4 on Alder Lake will still need its own GuC firmware (adlp_guc_70.bin), which isn't linked yet. You'll be in the README credits either way.

watchthelight 2026-10-31

@zsct648gn6-dev thank you, this is the first stage 2 run on Alder Lake, and it's clean. The registry dump matches what I'd expect for a 46A6 with the panel lit on pipe A. You're in the README's Testers section.

Please stop at stage 2 on this machine for now. Alder Lake needs its own GuC firmware for stage 4 and later, and another Alder Lake tester hit a panic at stage 4 (above), which 0.0.47 fixes.

watchthelight 2026-10-31

@TrDiTu 0.0.47 has the fix for your stage 4 panic: https://github.com/watchthelight-labs/XeGfx/releases/tag/v0.0.47

The formatter now prints "(fmt null)" for a NULL format string, the same way FreeBSD's kvprintf does, so the ISA bridge lookup no longer takes the kernel down. Stage 4 on 46A3 will most likely still stop early, because Alder Lake-P needs adlp_guc firmware and XeGfx only links the Meteor Lake GuC so far. I haven't run stage 4 on Alder Lake myself, so I can't promise what it does next. If you do try it, the output would help me. Stages 1 to 3 are safe either way.

Reply on GitHub