[SeaBIOS] varlow/extrastack vs code

Kevin O'Connor kevin at koconnor.net
Tue Feb 14 20:14:46 CET 2017


On Tue, Feb 14, 2017 at 07:52:01PM +0100, Laszlo Ersek wrote:
> On 02/14/17 19:43, Kevin O'Connor wrote:
> > On Tue, Feb 14, 2017 at 07:04:05PM +0100, Laszlo Ersek wrote:
> >> On 02/14/17 18:16, Kevin O'Connor wrote:
> >>> Also, the PAM registers on real hardware support a mode where reads to
> >>> 0xf0000 return the pristine copy of the bios while writes update
> >>> memory.  I didn't think there was any interest in implementing that on
> >>> QEMU (nor do I think it would be particularly helpful to have).
> >>
> >> Hmmm, I thought this was implemented with the four modes visible in
> >> init_pam() and switched by pam_update(), in "hw/pci-host/pam.c".
> >>
> >> Based on the remaining "XXX" comments though, and the wording of commit
> >> 175f099b30d47 ("pam: partly fix write-only mode"), it seems that the
> >> emulation is not complete just yet?...
> >>
> >> Perhaps this helps Dave identify what should be fixed in QEMU...
> > 
> > I don't think anything in QEMU needs to be "fixed" - the bug is
> > definitely in SeaBIOS.  The QEMU pam stuff is definitely quirky, but
> > even if we updated qemu we'd still have to fix seabios for old
> > versions of qemu.
> > 
> > Just for historical perspective - the reason I think qemu didn't
> > implement the pam "read from rom and write to memory" mode is that I
> > don't think there's a good way to emulate that with page tables (and
> > the range needs to be executable so just making it all device memory
> > isn't practical).  Even if it were implemented, though, I doubt it
> > would help much.
> 
> There are two questions here, AIUI:
> (1) resetting the PAM config on qemu system reset,
> (2) implementing all four PAM modes in QEMU, faithfully to phys hw.
> 
> I agree that item (2) is not important.
> 
> However, in order to fix SeaBIOS, item (1) should be fixed in QEMU,
> shouldn't it? You wrote,
> 
> > The root of the problem is that QEMU does not reset the f-segment on a
> > reboot signal and so SeaBIOS must manually reset that memory. [...]

Sorry, I didn't word that paragraph well.  I was trying to give
context for why the seabios code was memcpy'ing over itself.

> If item (1) is fixed in QEMU, then the above "root cause" goes away, and
> the workaround in SeaBIOS can be conditionalized. Am I wrong?

I'm not sure.  If I recall correctly, there are different resets on
the x86 - some only reset the cpu and some do a "full machine reset".
SeaBIOS attempts a variety of different reset mechanisms to reboot and
I'm not sure which are supposed to do the full reset.  If seabios does
a "reset cpu" mechanism before a "reset machine" mechanism, then qemu
resetting the pam may not help.

Thinking about this further, I think the real problem is that after
seabios copies over itself it goes back into its generic reboot
handling code.  The udelay() is actually fine on real hardware - it's
just not okay after seabios has memcpy'd itself.  So, I think if
seabios immediately did a reboot after the memcpy this problem would
go away.  Something like the patch below.

What's the best way to force a reboot on QEMU?  The mechanism really
should reset all cpus in a multi-cpu machine, ideally it would work on
different machine types (piix4, q35, isapc, etc.), and ideally it
would reset the hardware as well.

-Kevin


--- a/src/fw/shadow.c
+++ b/src/fw/shadow.c
@@ -187,4 +187,8 @@ qemu_prep_reset(void)
     memcpy(hrp + 4, hrp + 4 + BIOS_SRC_OFFSET, cend - (hrp + 4));
     barrier();
     HaveRunPost = 0;
+    barrier();
+
+    // Force QEMU reboot
+    asm volatile("int3");
 }



More information about the SeaBIOS mailing list