qemu-kvm: extboot: Keep variables in RAM
PATCH 1/2 qemu-kvm: extboot: Keep variables in RAM
Instead of saving the old INT 0x13 and 0x19 handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT 0x80 and 0x81.
---
Don't forget to update extboot.bin after merging both patches.
pc-bios/optionrom/extboot.S | 41 ++++++++++++++++++++++++++++++----------- 1 files changed, 30 insertions(+), 11 deletions(-)
pc-bios/optionrom/extboot.S +30 -11
@@ -19,6 +19,9 @@ * Authors: Anthony Liguori <[email protected]> */ +#define OLD_INT19 (0x80 * 4) /* re-use INT 0x80 BASIC vector */ +#define OLD_INT13 (0x81 * 4) /* re-use INT 0x81 BASIC vector */ + .code16 .text .global _start
@@ -37,7 +40,7 @@ _start: /* save old int 19 */ mov (0x19*4), %eax - mov %eax, %cs:old_int19 + mov %eax, (OLD_INT19) /* install out int 19 handler */ movw $int19_handler, (0x19*4)
@@ -48,6 +51,7 @@ _start: lret int19_handler: + push %eax /* reserve space for lret */ push %eax push %bx push %cx
@@ -69,7 +73,7 @@ int19_handler: 1: /* hook int13: intb(0x404) == 1 */ /* save old int 13 to int 2c */ mov (0x13*4), %eax - mov %eax, %cs:old_int13 + mov %eax, (OLD_INT13) /* install our int 13 handler */ movw $int13_handler, (0x13*4)
@@ -90,15 +94,21 @@ int19_handler: 3: /* fall through: inb(0x404) == 0 */ /* restore previous int $0x19 handler */ - mov %cs:old_int19,%eax + mov (OLD_INT19),%eax mov %eax,(0x19*4) - + + /* write old handler as return address onto stack */ + push %bp + mov %sp, %bp + mov %eax, 14(%bp) + pop %bp + pop %ds pop %dx pop %cx pop %bx pop %eax - ljmpw *%cs:old_int19 + lret #define FLAGS_CF 0x01
@@ -626,7 +636,21 @@ terminate_disk_emulation: int13_handler: cmp $0x80, %dl je 1f - ljmpw *%cs:old_int13 + + /* write old handler as return address onto stack */ + push %eax + push %eax + push %ds + push %bp + mov %sp, %bp + xor %ax, %ax + mov %ax, %ds + mov (OLD_INT13), %eax + mov %eax, 8(%bp) + pop %bp + pop %ds + pop %eax + lret 1: cmp $0x0, %ah jne 1f
@@ -686,10 +710,5 @@ int13_handler: int $0x18 /* boot failed */ iret -/* Variables */ -.align 4, 0 -old_int13: .long 0 -old_int19: .long 0 - .align 512, 0 _end:
Quoted 6 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.Signed-off-by Jan Kiszka<[email protected]>
commit a4492b03932ea3c9762372f3e15e8c6526ee56c6
Author: H. Peter Anvin <[email protected]> Date: Fri Jul 18 11:22:59 2008 -0700
kvm: extboot: don't use interrupt vectors $0x2b and $0x2c
extboot's use of interrupt vectors $0x2b and $0x2c is unsafe, as these interrupt vectors fall in the OS-use range (0x20-0x3f). Furthermore, it's unnecessary: we can keep a local pointer instead of hooking another interrupt as long as we can write to our own segment.
Make the extboot segment writable, and use local variables to hold the old link pointers.
If this turns out to cause problems, we should probably switch to using vectors in the 0xc0-0xef range, and/or other BIOS-reserved memory.
Sounds like 0x80/0x81 is probably not the best choice. hpa: any suggestions?
Regards,
Anthony Liguori
Quoted 111 lines
---
Don't forget to update extboot.bin after merging both patches.
pc-bios/optionrom/extboot.S | 41 ++++++++++++++++++++++++++++++----------- 1 files changed, 30 insertions(+), 11 deletions(-)pc-bios/optionrom/extboot.S +30
-12@@ -19,6 +19,9 @@ * Authors: Anthony Liguori<[email protected]> */ +#define OLD_INT19 (0x80 * 4) /* re-use INT 0x80 BASIC vector */ +#define OLD_INT13 (0x81 * 4) /* re-use INT 0x81 BASIC vector */ + .code16 .text .global _start@@ -37,7 +40,7 @@ _start: /* save old int 19 */ mov (0x19*4), %eax - mov %eax, %cs:old_int19 + mov %eax, (OLD_INT19) /* install out int 19 handler */ movw $int19_handler, (0x19*4)@@ -48,6 +51,7 @@ _start: lret int19_handler: + push %eax /* reserve space for lret */ push %eax push %bx push %cx@@ -69,7 +73,7 @@ int19_handler: 1: /* hook int13: intb(0x404) == 1 */ /* save old int 13 to int 2c */ mov (0x13*4), %eax - mov %eax, %cs:old_int13 + mov %eax, (OLD_INT13) /* install our int 13 handler */ movw $int13_handler, (0x13*4)@@ -90,15 +94,21 @@ int19_handler: 3: /* fall through: inb(0x404) == 0 */ /* restore previous int $0x19 handler */ - mov %cs:old_int19,%eax + mov (OLD_INT19),%eax mov %eax,(0x19*4) - + + /* write old handler as return address onto stack */ + push %bp + mov %sp, %bp + mov %eax, 14(%bp) + pop %bp + pop %ds pop %dx pop %cx pop %bx pop %eax - ljmpw *%cs:old_int19 + lret #define FLAGS_CF 0x01@@ -626,7 +636,21 @@ terminate_disk_emulation: int13_handler: cmp $0x80, %dl je 1f - ljmpw *%cs:old_int13 + + /* write old handler as return address onto stack */ + push %eax + push %eax + push %ds + push %bp + mov %sp, %bp + xor %ax, %ax + mov %ax, %ds + mov (OLD_INT13), %eax + mov %eax, 8(%bp) + pop %bp + pop %ds + pop %eax + lret 1: cmp $0x0, %ah jne 1f@@ -686,10 +710,5 @@ int13_handler: int $0x18 /* boot failed */ iret -/* Variables */ -.align 4, 0 -old_int13: .long 0 -old_int19: .long 0 - .align 512, 0 _end: --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 26 lines · Anthony Liguori
Quoted 6 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.Signed-off-by Jan Kiszka<[email protected]>commit
a4492b03932ea3c9762372f3e15e8c6526ee56c6Author: H. Peter Anvin <[email protected]> Date: Fri Jul 18 11:22:59 2008 -0700kvm: extboot: don't use interrupt vectors $0x2b and $0x2c
extboot's use of interrupt vectors $0x2b and $0x2c is unsafe, as these interrupt vectors fall in the OS-use range (0x20-0x3f). Furthermore, it's unnecessary: we can keep a local pointer instead of hooking another interrupt as long as we can write to our own segment.
Make the extboot segment writable, and use local variables to hold the old link pointers.
If this turns out to cause problems, we should probably switch to using vectors in the 0xc0-0xef range, and/or other BIOS-reserved memory.
Quoted 5 lines
Signed-off-by H. Peter Anvin <[email protected]>Signed-off-by Avi Kivity <[email protected]>Sounds like 0x80/0x81 is probably not the best choice. hpa: any suggestions?
There aren't really any free memory that you can just use -- there are no free interrupt vectors which are safe to use. Furthermore, this implies that there is a bug in the Qemu BIOS in this respect: the PCI spec requires that the "ROM region" (upper memory area) that contains shadow ROM contents be writable until INT 19h is executed -- at *that* point it gets write protected.
However, as I did point out in the original comment, there are some BIOSes in the field which uses vectors 0xc0-0xdf as a scratch memory pool -- usually to have somewhere to stash a small stack -- so if you absolutely have to go down this route that range those probably be the safest. An alternative would be to use memory in the BDA in the range 0x4ac-0x4ff (absolute), which appears to be available for BIOS-specific uses.
Quoted 1 line
Quoted 1 line
NEITHER OF THESE OPTIONS ARE SAFE ON REAL HARDWARE <<
These are both BIOS-specific use areas.
-hpa
Quoted 32 lines · H. Peter Anvin
Quoted 25 lines · Anthony Liguori
Quoted 6 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.Signed-off-by Jan Kiszka<[email protected]>commit
a4492b03932ea3c9762372f3e15e8c6526ee56c6Author: H. Peter Anvin <[email protected]> Date: Fri Jul 18 11:22:59 2008 -0700kvm: extboot: don't use interrupt vectors $0x2b and $0x2c
extboot's use of interrupt vectors $0x2b and $0x2c is unsafe, as these interrupt vectors fall in the OS-use range (0x20-0x3f). Furthermore, it's unnecessary: we can keep a local pointer instead of hooking another interrupt as long as we can write to our own segment.
Make the extboot segment writable, and use local variables to hold the old link pointers.
If this turns out to cause problems, we should probably switch to using vectors in the 0xc0-0xef range, and/or other BIOS-reserved memory.
Quoted 5 lines
Signed-off-by H. Peter Anvin <[email protected]>Signed-off-by Avi Kivity <[email protected]>Sounds like 0x80/0x81 is probably not the best choice. hpa: any suggestions?
Quoted 6 lines
There aren't really any free memory that you can just use -- there are no free interrupt vectors which are safe to use. Furthermore, this implies that there is a bug in the Qemu BIOS in this respect: the PCI spec requires that the "ROM region" (upper memory area) that contains shadow ROM contents be writable until INT 19h is executed -- at *that* point it gets write protected.
Shall the protection start _before_ INT 19 or somewhere _while_ it is processed? I'm asking as extboot redirect the handler and writes to some variable in its own handler. If the protection is already active at this point, we must move at least one of the variables out of the shadow ROM.
Quoted 8 lines
However, as I did point out in the original comment, there are some BIOSes in the field which uses vectors 0xc0-0xdf as a scratch memory pool -- usually to have somewhere to stash a small stack -- so if you absolutely have to go down this route that range those probably be the safest. An alternative would be to use memory in the BDA in the range 0x4ac-0x4ff (absolute), which appears to be available for BIOS-specific uses.
No problem moving to 0xc0 vectors if we have to (though my PC interrupt vector docs all state that already 0x80 is BIOS/BASIC domain).
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
NEITHER OF THESE OPTIONS ARE SAFE ON REAL HARDWARE <<
These are both BIOS-specific use areas.
Extboot is not targeting real hardware. It is built for a paravirtual interface to QEMU.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 6 lines · Jan Kiszka
Shall the protection start _before_ INT 19 or somewhere _while_ it is processed? I'm asking as extboot redirect the handler and writes to some variable in its own handler. If the protection is already active at this point, we must move at least one of the variables out of the shadow ROM.
The protection kicks in as the PMM system is torn down, which is done immediately before INT 19h. So
Quoted 11 lines
Quoted 7 lines
However, as I did point out in the original comment, there are some BIOSes in the field which uses vectors 0xc0-0xdf as a scratch memory pool -- usually to have somewhere to stash a small stack -- so if you absolutely have to go down this route that range those probably be the safest. An alternative would be to use memory in the BDA in the range 0x4ac-0x4ff (absolute), which appears to be available for BIOS-specific uses.
No problem moving to
0xc0vectors if we have to (though my PC interrupt vector docs all state that already0x80is BIOS/BASIC domain).
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
NEITHER OF THESE OPTIONS ARE SAFE ON REAL HARDWARE <<
These are both BIOS-specific use areas.
Extboot is not targeting real hardware. It is built for a paravirtual interface to QEMU.
Actually, extboot, or at least one variant of it, is used on real hardware in the gPXE stack. Nothing that says it has to be identical code, of course.
For the Qemu case it sounds like the easiest thing is to just reserve two dwords in the BIOS Data Area that your BIOS doesn't use.
-hpa
Quoted 27 lines · H. Peter Anvin
Quoted 5 lines · Jan Kiszka
Shall the protection start _before_ INT 19 or somewhere _while_ it is processed? I'm asking as extboot redirect the handler and writes to some variable in its own handler. If the protection is already active at this point, we must move at least one of the variables out of the shadow ROM.
The protection kicks in as the PMM system is torn down, which is done immediately before INT 19h. So
Quoted 7 lines
Quoted 7 lines
However, as I did point out in the original comment, there are some BIOSes in the field which uses vectors 0xc0-0xdf as a scratch memory pool -- usually to have somewhere to stash a small stack -- so if you absolutely have to go down this route that range those probably be the safest. An alternative would be to use memory in the BDA in the range 0x4ac-0x4ff (absolute), which appears to be available for BIOS-specific uses.
Quoted 9 lines
No problem moving to
0xc0vectors if we have to (though my PC interrupt vector docs all state that already0x80is BIOS/BASIC domain).Quoted 3 lines
Quoted 1 line
Quoted 1 line
NEITHER OF THESE OPTIONS ARE SAFE ON REAL HARDWARE <<
These are both BIOS-specific use areas.
Extboot is not targeting real hardware. It is built for a paravirtual interface to QEMU.
Quoted 6 lines
Actually, extboot, or at least one variant of it, is used on real hardware in the gPXE stack. Nothing that says it has to be identical code, of course.
For the Qemu case it sounds like the easiest thing is to just reserve two dwords in the BIOS Data Area that your BIOS doesn't use.
Actually, I'm still in favor of proper (Sea)BIOS support for virtio and scsi, either via the paravirt port 0x405 and its qemu backend or via minimalistic support of the hardware directly in the BIOS. That would free us from all those hooking and unhooking dances at least.
Kevin, Anthony, and all others: what is now the merge road map for the bootable scsi/virtio feature?
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 6 lines · Jan Kiszka
Actually, I'm still in favor of proper (Sea)BIOS support for virtio and scsi, either via the paravirt port
0x405and its qemu backend or via minimalistic support of the hardware directly in the BIOS. That would free us from all those hooking and unhooking dances at least.
The *proper* thing is to support BBS in SeaBIOS - that way your device drivers just hook in through the standard BEV/BCV mechanism (which should be used by *all* the device drivers, including the internal ones.)
-hpa
Quoted 10 lines · H. Peter Anvin
Quoted 5 lines · Jan Kiszka
Actually, I'm still in favor of proper (Sea)BIOS support for virtio and scsi, either via the paravirt port
0x405and its qemu backend or via minimalistic support of the hardware directly in the BIOS. That would free us from all those hooking and unhooking dances at least.The *proper* thing is to support BBS in SeaBIOS - that way your device drivers just hook in through the standard BEV/BCV mechanism (which should be used by *all* the device drivers, including the internal ones.)
If there is standard for this, even better. On first glance, it doesn't look like a specification monster. Still some work to do. Or are there already activities in this direction?
If not let us fix the issue ad-hoc until we have full BBS.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 8 lines · Jan Kiszka
Actually, I'm still in favor of proper (Sea)BIOS support for virtio and scsi, either via the paravirt port
0x405and its qemu backend or via minimalistic support of the hardware directly in the BIOS. That would free us from all those hooking and unhooking dances at least.Kevin, Anthony, and all others: what is now the merge road map for the bootable scsi/virtio feature?
Stefan posted a virtio-blk driver for gPXE. I like this approach because it's generally useful (gPXE can be used with any BIOS).
For the LSI SCSI adapter, I'm not really sure the best way forward. Honestly, it's so broken currently, I'm not sure booting really matters.
Regards,
Anthony Liguori
Quoted 3 lines
Jan
Quoted 6 lines · Anthony Liguori
Quoted 5 lines · Jan Kiszka
Actually, I'm still in favor of proper (Sea)BIOS support for virtio and scsi, either via the paravirt port
0x405and its qemu backend or via minimalistic support of the hardware directly in the BIOS. That would free us from all those hooking and unhooking dances at least.
Quoted 6 lines
Quoted 3 lines
Kevin, Anthony, and all others: what is now the merge road map for the bootable scsi/virtio feature?
Stefan posted a virtio-blk driver for gPXE. I like this approach because it's generally useful (gPXE can be used with any BIOS).
Does it allow a unified boot device selection, one menu for them all, no more "boot=on" workarounds?
Quoted 3 lines
For the LSI SCSI adapter, I'm not really sure the best way forward. Honestly, it's so broken currently, I'm not sure booting really matters.
Well, we are successfully using this "broken" adapter. What is not working?
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 7 lines · Jan Kiszka
Quoted 3 lines
Stefan posted a virtio-blk driver for gPXE. I like this approach because it's generally useful (gPXE can be used with any BIOS).
Does it allow a unified boot device selection, one menu for them all, no more "boot=on" workarounds?
Well, it hooks into BBS if the underlying BIOS supports it. Without BBS there is no ability to have a unified boot device selection.
-hpa
Quoted 11 lines · H. Peter Anvin
Quoted 7 lines · Jan Kiszka
Quoted 3 lines
Stefan posted a virtio-blk driver for gPXE. I like this approach because it's generally useful (gPXE can be used with any BIOS).
Does it allow a unified boot device selection, one menu for them all, no more "boot=on" workarounds?
Well, it hooks into BBS if the underlying BIOS supports it. Without BBS there is no ability to have a unified boot device selection.
SeaBIOS does support BBS (both BEVs and BCVs). Also, under qemu, SeaBIOS will run option roms with memory writable and then lock the memory after the POST phase (as is required by the spec).
SeaBIOS also support PMM (both temporary allocations and the PCIv3 extensions for permanent memory).
Finally, I plan to commit a series of patches to SeaBIOS which add support for booting from USB drives. I imagine adding virtio support to SeaBIOS would not be difficult if someone wishes to take that on.
-Kevin
Current status of gPXE virtio support:
Virtio-net support has been in mainline gPXE since August 2008. Virtio-blk patches exist and I'd like to get them merged so both types of devices are supported.
These are PCI option ROMs and they have a BEV entry point to hook into the boot menu. With SeaBIOS BBS and PMM support the gPXE ROMs can provide your virtio support.
Stefan
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 1 line · H. Peter Anvin
Typically a disk device would use a BCV, not a BEV.
Laurent Vivier's virtio-blk patchset has BCV support. It is not yet merged into gPXE:
http://markmail.org/message/oq2et3t3kzjzts7i
Stefan
Avi Kivity
AppliedQuoted 5 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.
Applied both, thanks.
Quoted 2 lines
Don't forget to update extboot.bin after merging both patches.
We don't carry a precompiled binary (well, we have qemu/pc-bios/extboot.bin, but that's bogus and I've removed it).
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 7 lines · Avi Kivity
Quoted 5 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.
Quoted 7 lines
Applied both, thanks.
Quoted 2 lines
Don't forget to update extboot.bin after merging both patches.
We don't carry a precompiled binary (well, we have qemu/pc-bios/extboot.bin, but that's bogus and I've removed it).
You do:
qemu-kvm/pc-bios/optionrom/extboot.bin qemu-kvm/qemu/pc-bios/extboot.bin (what is that for?)
And as I had to copy the built extboot.bin around to let it be recognized when starting qemu-kvm from an out-of-tree build directory, I guess that concept needs some cleanup/fixing.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 9 lines · Jan Kiszka
Quoted 8 lines · Avi Kivity
Quoted 5 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.Applied both, thanks.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Don't forget to update extboot.bin after merging both patches.
We don't carry a precompiled binary (well, we have qemu/pc-bios/extboot.bin, but that's bogus and I've removed it).
You do:
qemu-kvm/pc-bios/optionrom/extboot.bin
That one doesn't exist in git in fact.
Quoted 6 lines
qemu-kvm/qemu/pc-bios/extboot.bin (what is that for?)
And as I had to copy the built extboot.bin around to let it be recognized when starting qemu-kvm from an out-of-tree build directory, I guess that concept needs some cleanup/fixing.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 7 lines · Jan Kiszka
Quoted 3 lines
We don't carry a precompiled binary (well, we have qemu/pc-bios/extboot.bin, but that's bogus and I've removed it).
You do:
qemu-kvm/qemu/pc-bios/extboot.bin (what is that for?)
Artifact, removed.
Quoted 4 lines
And as I had to copy the built extboot.bin around to let it be recognized when starting qemu-kvm from an out-of-tree build directory, I guess that concept needs some cleanup/fixing.
Yes.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 8 lines · Avi Kivity
Quoted 5 lines · Jan Kiszka
Instead of saving the old INT
0x13and0x19handlers in ROM which fails under QEMU as it enforces protection, keep them in spare vectors of the interrupt table, namely INT0x80and0x81.Applied both, thanks.
Forgot to tag it: Please consider the first one ("Keep variables in RAM", 2dcbbec) for stable as well.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux