On 2026-09-15 09:30, Junjie Cao wrote:
> On Mon, 14 Sep 2026 16:41:58 +0800, Tomita Moeko wrote:
>> Just curious, on host side, does the value of 0x1080C0 equals (BAR2 + 8M)
>> on Meteor and Arrow Lake?
>
> No. Measured on Meteor Lake-P (8086:7d55, host i915):
>
> BAR2 (LMEMBAR) 0x4000000000, 256MB
> MMIO 0x108100 GSMBASE 0x70000000
> MMIO 0x1080C0 DSMBASE 0x70800000 (GSMBASE + 8MB)
> MMIO 0x108040 GGC 0x4c0 (GGMS=3, GMS=4 -> 128MB)
> config 0x50 GGC 0x4c0
> config 0x5C 0
> config 0xC0-0xC3 MSI Pending Bits (MSI cap at 0xac, 64-bit + PVM)
> config 0xC4-0xC7 0
> MMIO 0x138914 1
> /proc/iomem 64000000-787fffff : Reserved
>
> DSMBASE is a system physical address inside the BIOS reserved range, and
> DSMBASE + 128MB is exactly the end of that range. BAR2 + 8M is the
> aperture onto the same memory: i915_gem_stolen.c and xe_ttm_stolen_mgr.c
> use either DSMBASE or LMEMBAR + 8M as the io base of the same stolen
> region.
>
> So with igd_gen() == -1, where no BAR0 quirk is installed, a guest reads
> the host physical DSMBASE from 0x1080C0. Given Yuan's point that the
> GOP reads this register for its stolen base, that is a host address
> handed to guest firmware, and something QEMU should fix.
>
>> My concern is that if guest driver still uses (BAR2 + 8M) as DSM base, while
>> 0x1080C0 pointing to the mocked region, will this bring any inconsistency?
>
> The drivers map stolen on MTL+ with DM-flagged PTEs as offsets from
> GSMBASE (xe_ttm_stolen_mgr.c; i915 sets PTE_LM for stolen-local), which
> a region in guest RAM cannot satisfy. Whether the GOP maps its frame
> buffer the same way I cannot check from here. Yuan, if the display has
> come up for you with v2 and the stock GOP, that answers it; the variant
> below does not depend on the answer.
>
So on MTL+ BAR2 is mapped to the physical memory at GSMBASE, with first 8M
for GTT. PTE addresses are relative addresses so that accessing indirectly
from BAR or directly works. That makes sense.
Meteor and later IGDs are supposed to access DSM from BAR2 instead of directly
from DSMBASE, but there is some hardware issues in Meteor Lake and Arrow Lake's
BAR2, software workarounds it to by falling back to DSMBASE. i915 won't read
DSMBASE register if the WA is not enabled (and it's always disabled when
virtualization enabled), while it's possible for GOP driver (and maybe windows
driver) to read it. Is my understanding correct?
>> Having the register pointing to guest's (BAR2 + 8M) sounds more reasonable,
>> but it would require more efforts, monitoring config space writes to BAR2 and
>> changing the emulated value in QEMU.
>
> Agree with the direction, and it is cheaper than that: a read-only BAR0
> quirk can take pci_get_bar_addr(pdev, 2) at read time, returning BAR2 at
> 0x108100 and BAR2 + 8M at 0x1080C0. Then the CPU-side address resolves
> to real stolen memory through the aperture instead of guest RAM,
> bdsm-size stays 0 as documented, and nothing in config space is
> invented.
Yes hooking on 0x1080C0 register read is easier and more straightforward.
>> Possibly an easier way is emulating MTL_PCODE_STOLEN_ACCESS(0x138914) to
>> disallowed in QEMU, if the GOP driver code checks it, to enforce the access
>> via BAR2 in guest.
>
> 0x138914 reads 1 on the host and is not quirked, so a guest sees 1 too.
> Returning 0 there is a small addition and covers a GOP that checks it;
> the DSMBASE quirk covers one that does not. On the Wa itself: i915
> already takes the BAR path in guests (i915_run_as_guest() short-circuits
> i915_direct_stolen_access()), so that path has upstream precedent; we
> have not measured whether the hang reproduces there.
>
Quirking 0x138914 prevents driver applying that WA, but we are not sure
if driver checks it before WA. While hooking read to 0x1080C0 fakes the
DSMBASE to (BAR2 + 8M) in guest address space. Both tries to enforce
guest accesses to DSM via BAR2. I personally prefers hooking 0x1080C0
as it's driver-independent.
Btw, this quirk seems only necessary for Meteor and Arrow lake. That WA
is not applied in Xe driver. I'm not sure if it still presents in GOP or
windows driver for later generations.
> The firmware still has to program ASLS. The IgdAssignmentDxe build the
> v2 commit message describes aborts on bdsm-size=0 before doing so;
> VfioIgdPkg has no such check and programs ASLS for MTL+ as is.
>
> I'll write the quirk. It can go into Yuan's v3 or on top of it as a
> separate patch -- Yuan, your call. Either way it needs a run with the
> stock GOP build on your setup.
>
> Junjie
Yes OpRegion is needed for display to work. In the "hooking 0x1080C0 read"
approach above, allocating DSM in guest is not needed. It sounds better to
make your IgdAssignmentDxe not aborting if bdsm-size=0.
Best Regards,
Moeko