Hi,
This patch series changes the way SeaBIOS figures whenever it runs on qemu or not. Instead of using different ways for each configuration (CONFIG_QEMU / CONFIG_CSM / CONFIG_COREBOOT) we'll have a generic function which checks the PCI Subsystem ID of the northbridge.
v2: - Force PF_QEMU on CONFIG_QEMU, even when no northbridge was found. Needed for isapc and very old qemu versions. - Rebased, applies on top of kevin's include cleanup series.
Gerd Hoffmann (3): Add generic qemu detection Drop coreboot qemu detection Add qemu detection to csm
src/fw/coreboot.c | 4 ---- src/fw/csm.c | 3 +++ src/fw/paravirt.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 9 deletions(-)
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/fw/paravirt.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-)
diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 2524b7b..357de56 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -12,6 +12,7 @@ #include "config.h" // CONFIG_QEMU #include "hw/cmos.h" // CMOS_* #include "hw/pci.h" // create_pirtable +#include "hw/pci_regs.h" // PCI_DEVICE_ID #include "ioport.h" // outw #include "malloc.h" // malloc_tmp #include "memmap.h" // add_e820 @@ -35,10 +36,8 @@ int PlatformRunningOn VARFSEG; */ #define KVM_CPUID_SIGNATURE 0x40000000
-static void kvm_preinit(void) +static void kvm_detect(void) { - if (!CONFIG_QEMU) - return; unsigned int eax, ebx, ecx, edx; char signature[13];
@@ -54,9 +53,43 @@ static void kvm_preinit(void) } }
+static void qemu_detect(void) +{ + if (!CONFIG_QEMU_HARDWARE) + return; + + // check northbridge @ 00:00.0 + u16 v = pci_config_readw(0, PCI_VENDOR_ID); + if (v == 0x0000 || v == 0xffff) + return; + u16 d = pci_config_readw(0, PCI_DEVICE_ID); + u16 sv = pci_config_readw(0, PCI_SUBSYSTEM_VENDOR_ID); + u16 sd = pci_config_readw(0, PCI_SUBSYSTEM_ID); + + if (sv != 0x1af4 || /* Red Hat, Inc */ + sd != 0x1100) /* Qemu virtual machine */ + return; + + PlatformRunningOn |= PF_QEMU; + switch (d) { + case 0x1237: + dprintf(1, "Running on QEMU (i440fx)\n"); + break; + case 0x29c0: + dprintf(1, "Running on QEMU (q35)\n"); + break; + default: + dprintf(1, "Running on QEMU (unknown nb: %04x:%04x)\n", v, d); + break; + } + kvm_detect(); +} + void qemu_preinit(void) { + qemu_detect(); + if (!CONFIG_QEMU) return;
@@ -65,8 +98,11 @@ qemu_preinit(void) return; }
- PlatformRunningOn = PF_QEMU; - kvm_preinit(); + if (!runningOnQEMU()) { + dprintf(1, "Warning: No QEMU Northbridge found (isapc?)\n"); + PlatformRunningOn |= PF_QEMU; + kvm_detect(); + }
// On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16)
On Mon, Sep 16, 2013 at 12:36:28PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
What if other userspace will want to write enough support to run Seabios as a guest? Why kvm detection depends on QEMU?
Signed-off-by: Gerd Hoffmann kraxel@redhat.com
src/fw/paravirt.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-)
diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 2524b7b..357de56 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -12,6 +12,7 @@ #include "config.h" // CONFIG_QEMU #include "hw/cmos.h" // CMOS_* #include "hw/pci.h" // create_pirtable +#include "hw/pci_regs.h" // PCI_DEVICE_ID #include "ioport.h" // outw #include "malloc.h" // malloc_tmp #include "memmap.h" // add_e820 @@ -35,10 +36,8 @@ int PlatformRunningOn VARFSEG; */ #define KVM_CPUID_SIGNATURE 0x40000000
-static void kvm_preinit(void) +static void kvm_detect(void) {
- if (!CONFIG_QEMU)
unsigned int eax, ebx, ecx, edx; char signature[13];return;
@@ -54,9 +53,43 @@ static void kvm_preinit(void) } }
+static void qemu_detect(void) +{
- if (!CONFIG_QEMU_HARDWARE)
return;
- // check northbridge @ 00:00.0
- u16 v = pci_config_readw(0, PCI_VENDOR_ID);
- if (v == 0x0000 || v == 0xffff)
return;
- u16 d = pci_config_readw(0, PCI_DEVICE_ID);
- u16 sv = pci_config_readw(0, PCI_SUBSYSTEM_VENDOR_ID);
- u16 sd = pci_config_readw(0, PCI_SUBSYSTEM_ID);
- if (sv != 0x1af4 || /* Red Hat, Inc */
sd != 0x1100) /* Qemu virtual machine */
return;
- PlatformRunningOn |= PF_QEMU;
- switch (d) {
- case 0x1237:
dprintf(1, "Running on QEMU (i440fx)\n");
break;
- case 0x29c0:
dprintf(1, "Running on QEMU (q35)\n");
break;
- default:
dprintf(1, "Running on QEMU (unknown nb: %04x:%04x)\n", v, d);
break;
- }
- kvm_detect();
+}
void qemu_preinit(void) {
- qemu_detect();
- if (!CONFIG_QEMU) return;
@@ -65,8 +98,11 @@ qemu_preinit(void) return; }
- PlatformRunningOn = PF_QEMU;
- kvm_preinit();
if (!runningOnQEMU()) {
dprintf(1, "Warning: No QEMU Northbridge found (isapc?)\n");
PlatformRunningOn |= PF_QEMU;
kvm_detect();
}
// On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16)
-- 1.8.3.1
SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
-- Gleb.
On Mo, 2013-09-16 at 14:10 +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 12:36:28PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
What if other userspace will want to write enough support to run Seabios as a guest? Why kvm detection depends on QEMU?
What other userspace? There is none today. And if that changes some day we'll just call kvm_detect() in the init code for $otheruserspace.
cheers, gerd
On Mon, Sep 16, 2013 at 02:27:37PM +0200, Gerd Hoffmann wrote:
On Mo, 2013-09-16 at 14:10 +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 12:36:28PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
What if other userspace will want to write enough support to run Seabios as a guest? Why kvm detection depends on QEMU?
What other userspace? There is none today. And if that changes some day we'll just call kvm_detect() in the init code for $otheruserspace.
Why seabios code has to be changed at all to support other device model emulator (assuming it will emulate same chipset)?
-- Gleb.
On Mo, 2013-09-16 at 15:34 +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 02:27:37PM +0200, Gerd Hoffmann wrote:
On Mo, 2013-09-16 at 14:10 +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 12:36:28PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
What if other userspace will want to write enough support to run Seabios as a guest? Why kvm detection depends on QEMU?
What other userspace? There is none today. And if that changes some day we'll just call kvm_detect() in the init code for $otheruserspace.
Why seabios code has to be changed at all to support other device model emulator (assuming it will emulate same chipset)?
That is a purely theoretical thing. In practice seabios mist likely has to be changed for one or another reason.
Note that the detection behavior isn't new, current seabios code does kvm detection for CONFIG_QEMU builds only.
Also note that in theory seabios should not need to care at all whenever it runs on kvm or tcg. In practice qemu has slightly different behavior with kvm enabled and seabios needs adapt to that. That alone is reason enougth that supporting other kvm userspace very likely needs adaptions in seabios, unless your theoretical[1] other userspace is bug compatible with qemu here.
cheers, Gerd
[1] Or do you know something you don't wanna tell me?
On Mon, Sep 16, 2013 at 03:14:45PM +0200, Gerd Hoffmann wrote:
On Mo, 2013-09-16 at 15:34 +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 02:27:37PM +0200, Gerd Hoffmann wrote:
On Mo, 2013-09-16 at 14:10 +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 12:36:28PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
What if other userspace will want to write enough support to run Seabios as a guest? Why kvm detection depends on QEMU?
What other userspace? There is none today. And if that changes some day we'll just call kvm_detect() in the init code for $otheruserspace.
Why seabios code has to be changed at all to support other device model emulator (assuming it will emulate same chipset)?
That is a purely theoretical thing. In practice seabios mist likely has to be changed for one or another reason.
It's not have to be this way if Seabios would check for specific HW features instead of checking for QEMU. For instance if discovery of fw_cfg will not depend on QEMU detection other userspace can emulate and it will be detected without changing Seabios.
kvm detection for CONFIG_QEMU builds only.
Indeed the current logic is the same.
Also note that in theory seabios should not need to care at all whenever it runs on kvm or tcg. In practice qemu has slightly different behavior with kvm enabled and seabios needs adapt to that. That alone is reason enougth that supporting other kvm userspace very likely needs adaptions in seabios, unless your theoretical[1] other userspace is bug compatible with qemu here.
I see only one thing that is done based on KVM detection and the logic would be correct for other userspaces that do not provide e820 map.
cheers, Gerd
[1] Or do you know something you don't wanna tell me?
No, all I know is that kvmtool wanted to add seabios support, but I guess nobody works on that these days.
-- Gleb.
On Mon, Sep 16, 2013 at 07:58:42PM +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 03:14:45PM +0200, Gerd Hoffmann wrote:
That is a purely theoretical thing. In practice seabios mist likely has to be changed for one or another reason.
It's not have to be this way if Seabios would check for specific HW features instead of checking for QEMU. For instance if discovery of fw_cfg will not depend on QEMU detection other userspace can emulate and it will be detected without changing Seabios.
For the most part, this is what SeaBIOS does today. There are very few places in the code that check CONFIG_QEMU.
In particular, Gerd has already changed the fw_cfg support to not depend on CONFIG_QEMU.
Also note that in theory seabios should not need to care at all whenever it runs on kvm or tcg. In practice qemu has slightly different behavior with kvm enabled and seabios needs adapt to that. That alone is reason enougth that supporting other kvm userspace very likely needs adaptions in seabios, unless your theoretical[1] other userspace is bug compatible with qemu here.
I see only one thing that is done based on KVM detection and the logic would be correct for other userspaces that do not provide e820 map.
One of the places where CONFIG_QEMU is used is in determining how to get the memory map. Any new emulator that uses SeaBIOS is going to have to define the mechanism for passing the memory map and that's going to be a SeaBIOS code change anyway. (It's different on qemu, xen, coreboot, and csm.) It's theoretically possible to use the QEMU memory map passing (magic cmos variables), but if that path is taken one might as well just enable CONFIG_QEMU then..
-Kevin
On Mon, Sep 16, 2013 at 08:03:01PM -0400, Kevin O'Connor wrote:
On Mon, Sep 16, 2013 at 07:58:42PM +0300, Gleb Natapov wrote:
On Mon, Sep 16, 2013 at 03:14:45PM +0200, Gerd Hoffmann wrote:
That is a purely theoretical thing. In practice seabios mist likely has to be changed for one or another reason.
It's not have to be this way if Seabios would check for specific HW features instead of checking for QEMU. For instance if discovery of fw_cfg will not depend on QEMU detection other userspace can emulate and it will be detected without changing Seabios.
For the most part, this is what SeaBIOS does today. There are very few places in the code that check CONFIG_QEMU.
In particular, Gerd has already changed the fw_cfg support to not depend on CONFIG_QEMU.
Cool. That's definitely an improvement.
Also note that in theory seabios should not need to care at all whenever it runs on kvm or tcg. In practice qemu has slightly different behavior with kvm enabled and seabios needs adapt to that. That alone is reason enougth that supporting other kvm userspace very likely needs adaptions in seabios, unless your theoretical[1] other userspace is bug compatible with qemu here.
I see only one thing that is done based on KVM detection and the logic would be correct for other userspaces that do not provide e820 map.
One of the places where CONFIG_QEMU is used is in determining how to get the memory map. Any new emulator that uses SeaBIOS is going to have to define the mechanism for passing the memory map and that's going to be a SeaBIOS code change anyway. (It's different on qemu, xen, coreboot, and csm.) It's theoretically possible to use the QEMU memory map passing (magic cmos variables), but if that path is taken one might as well just enable CONFIG_QEMU then..
As far as I see the memory map is passed through fw_cfg, so it is enough to implement it.
-- Gleb.
Not needed any more, the new qemu_detect() function does the job instead.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/fw/coreboot.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c index a234e97..70a99a0 100644 --- a/src/fw/coreboot.c +++ b/src/fw/coreboot.c @@ -190,10 +190,6 @@ coreboot_preinit(void) if (cbmb) { CBvendor = &cbmb->strings[cbmb->vendor_idx]; CBpart = &cbmb->strings[cbmb->part_idx]; - if (strcmp(CBvendor, "Emulation") == 0 && - memcmp(CBpart, "QEMU", 4) == 0) { - PlatformRunningOn |= PF_QEMU; - } dprintf(1, "Found mainboard %s %s\n", CBvendor, CBpart); }
Add a qemu_preinit() call to csm initialization, so PF_QEMU gets set when running on qemu.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/fw/csm.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/fw/csm.c b/src/fw/csm.c index cd16641..dfb0d12 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -17,6 +17,7 @@ #include "std/bda.h" // struct bios_data_area_s #include "std/optionrom.h" // struct rom_header #include "util.h" // copy_smbios +#include "paravirt.h" // qemu_preinit
#define UINT8 u8 #define UINT16 u16 @@ -69,6 +70,8 @@ csm_maininit(struct bregs *regs) static void handle_csm_0000(struct bregs *regs) { + qemu_preinit(); + dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es, regs->bx);
On Mo, 2013-09-16 at 12:36 +0200, Gerd Hoffmann wrote:
This patch series changes the way SeaBIOS figures whenever it runs on qemu or not. Instead of using different ways for each configuration (CONFIG_QEMU / CONFIG_CSM / CONFIG_COREBOOT) we'll have a generic function which checks the PCI Subsystem ID of the northbridge.
Commited now.
cheers, Gerd