[SeaBIOS] varlow/extrastack vs code

Laszlo Ersek lersek at redhat.com
Tue Feb 14 19:04:05 CET 2017


On 02/14/17 18:16, Kevin O'Connor wrote:
> On Tue, Feb 14, 2017 at 05:36:34PM +0100, Laszlo Ersek wrote:
>> On 02/14/17 17:22, Kevin O'Connor wrote:
>>> On Tue, Feb 14, 2017 at 02:50:23PM +0000, Dr. David Alan Gilbert wrote:
>>>> I've been sporadically carrying on debugging this and I
>>>> think I have a bit more understanding, but not quite all the way.
>>>>
>>>> I'm pretty sure we are trying to run code that's been over written
>>>> by variable data - which I believe to be TimerLast, and I'm also
>>>> fairly sure the problem is not a delayed reset from multiple reboot signals.
>>>>
>>>> Some detail:
>>>> a) I added some debug to qemu to print what triggered the reboot by
>>>>   always passing qemu_system_reset_request a string; the kernel
>>>>   is always rebooting via KBD_CCMD_RESET, I see that enter the BIOS
>>>>   and then see SeaBIOS then does KBD_CCMD_RESET again - which I think
>>>>   is the one coming from handle_resume32.
>>>>   But then I noticed that every so often we got a reboot from a KVM_SHUTDOWN
>>>>   which is apparently a triple-fault or the like.
>>>>
>>>> b) With a KVM trace I got the addresses the fault was happening at,
>>>>   and it was always an address in the copy fo the bios around bffbcf..
>>>>   although the actual failure jumped about a bit, taking the:
>>>>     Relocating init from 0x000e4810 to 0xbffb2050 (size 57120)
>>>>   I worked the fault address back to 'ef799' and from the objdump
>>>>   found that was an address in maininit but also corresponded to
>>>>   TimerLast:
>>>
>>> I can confirm there is a defect with TimerLast and reboot handling.
>>> I'm not sure what the best fix is - suggestions welcome.
>>>
>>> The root of the problem is that QEMU does not reset the f-segment on a
>>> reboot signal
>>
>> Are you sure this applies to recent QEMU too, not just ancient QEMU?
>>
>>> and so SeaBIOS must manually reset that memory.
>>
>> Do you mean a workaround for the (historically lacking) emulation of the
>> PAM chipset registers? PAM emulation has been correct for quite a while
>> now in QEMU, as far as I can tell.
> 
> My understanding was that a write to the PCI reboot register (0x0cf9)
> would cause a hard reboot - which would reset the PAM registers to
> their default (a RO view of the pristine bios at 0xf0000).  I just did
> some tests with qemu v2.8 and it does not appear to do that.

Sigh, you are right, and I'm wrong again. :/

In "hw/pci-host/q35.c", we have

  mch_reset()
    mch_update()
      mch_update_pam()
        pam_update() [hw/pci-host/pam.c]

but the config space registers that underlie the PAM configuration
(MCH_HOST_BRIDGE_PAM0 etc) are not re-set.

Same for i440fx ("hw/pci-host/piix.c"):

  i440fx_update_memory_mappings()
    pam_update() [hw/pci-host/pam.c]

Although i440fx_update_memory_mappings() is called from a good number of
places (i440fx_write_config(), i440fx_load_old(), i440fx_post_load(),
i440fx_init()), it doesn't seem to be called from any system reset handler.

Knowing this, it likely doesn't even matter that the PAM registers
(I440FX_PAM etc) are not re-set in piix3_reset().

> 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...

Thanks
Laszlo



More information about the SeaBIOS mailing list