[SeaBIOS] [RFC PATCH v3 3/3] fw/pci: Allocate IGD stolen memory

Alex Williamson alex.williamson at redhat.com
Sat Feb 13 19:51:51 CET 2016

On Sat, 13 Feb 2016 13:18:39 -0500
"Kevin O'Connor" <kevin at koconnor.net> wrote:

> On Sat, Feb 13, 2016 at 08:12:09AM -0700, Alex Williamson wrote:
> > On Fri, 12 Feb 2016 21:49:04 -0500
> > "Kevin O'Connor" <kevin at koconnor.net> wrote:  
> > > On Fri, Feb 12, 2016 at 05:23:18PM -0700, Alex Williamson wrote:  
> > > > Intel IGD makes use of memory allocated and marked reserved by the
> > > > BIOS as a stolen memory range.  For the most part, guest drivers don't
> > > > make use of this, but our achilles heel is the vBIOS.  The vBIOS
> > > > programs the device to use the host stolen memory range and it's used
> > > > in the pre-boot environment.  Generally the guest won't have access to
> > > > the host stolen memory area, so these accesses either land in VM
> > > > memory or unassigned space and generate IOMMU faults.  By allocating
> > > > this range in SeaBIOS and programming it into the device, QEMU (via
> > > > vfio) can make sure this guest allocated stolen memory range is used
> > > > instead.    
> > > 
> > > What does "vBIOS" mean in this context?  Is it the video device option
> > > rom or something else?  
> > 
> > vBIOS = video BIOS, you're correct, it's just the video device option
> > ROM.  
> Is the problem from when the host runs the video option rom, or is the
> problem from the guest (via SeaBIOS) running the video option rom?  If
> the guest is running the option rom, is it the first time the option
> rom has been run for the machine (ie, was the option rom not executed
> on the host when the host machine first booted)?
> FWIW, many of the chromebooks use coreboot with Intel graphics and a
> number of users have installed SeaBIOS (running natively) on their
> machines.  Running the intel video option rom more than once has been
> known to cause issues.

The issue is in the VM and it occurs every time the option ROM is
executed.  Standard VGA text mode displays fine (ex. SeaBIOS version
string and boot menu), but any sort of extended graphics mode (ex. live
CD boot menu) tries to make use of the host memory area which
corresponds to the stolen memory area of the physical device.  We're
not really sure how the ROM execution arrives at these addresses (not
from the device according to access traces), but we can see when the
ROM is writing these addresses to the device and modify they addresses
to point at a VM memory range which we've allocated.  That's what this
code attempts to do, allocate a buffer and tell QEMU about it via the
BDSM (Base Data of Stolen Memory) register.
> [...]
> > The write to 0x5C is used by QEMU code that traps writes to the
> > device I/O port BAR and replaces the host stolen memory address
> > with the new guest address generated here.  0x5C is initialized to
> > 0x0 by kernel vfio code, so we can detect whether it has been
> > written.  If not written, QEMU has no place to redirect to for
> > stolen memory and it will either overlap VM memory or an unassigned
> > area.  The former may corrupt VM memory, the latter throws host
> > errors.  We could in QEMU halt with a hardware error if 0x5C hasn't
> > been programmed.  
> So, if I understand correctly, 0x5C is not a "real" register on the
> hardware, but is instead just a mechanism to give QEMU the address of
> some guest visible ram?

It is a real register, BDSM that is virtualized by vfio turning it
effectively into a scratch register.  On physical hardware the
register is read-only.
> BTW, is 0xFC a "real" register in the hardware?  How does the guest
> find the location of the "OpRegion" if SeaBIOS allocates it?

0xFC is the ASL Storage register, the guest finds the location of the
OpRegion using this register.  This is another register that is
read-only on real hardware but virtualized through vfio so we can
relocate the OpRegion into the VM address space.

I've found that allocating a dummy MMIO BAR does work as an alternative
for mapping space for this stolen memory into the VM address space.
For a Linux guest it works to allocate BAR5 on the IGD device.
Windows10 is not so happy with this, but does work if I allocate the
BAR on something like the ISA bridge device.  My guess is that the IGD
driver in Windows freaks out at finding this strange new BAR on its
device.  So I'll need to come up with an algorithm for either creating
a dummy PCI device to host this BAR or trying to add it to other
existing devices.  It's certainly a more self-contained solution this
way, so I expect we'll only need patch 1/3 from this series.  Thanks,


More information about the SeaBIOS mailing list