src/fw/paravirt.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
From 405de6e571a2bf332452a17ae98f7b3a0613365e Mon Sep 17 00:00:00 2001
From: Petr Berky <petr.berky@email.cz>
Date: Tue, 14 Mar 2017 20:30:52 +0100
Subject: [PATCH] config: Add function to check if fw_cfg exists
It was found qemu_get_present_cpus_count may return impossible
number of cpus because of not checking if fw_cfg exists before
using it. That may lead to undefined behavior of emulator,
in particular Bochs that freezes.
Signed-off-by: Petr Berky <petr.berky@email.cz>
---
src/fw/paravirt.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c
index 707502d..b2cfc23 100644
--- a/src/fw/paravirt.c
+++ b/src/fw/paravirt.c
@@ -220,6 +220,21 @@ qemu_cfg_select(u16 f)
outw(f, PORT_QEMU_CFG_CTL);
}
+static int
+qemu_cfg_check_signature(void)
+{
+ int i;
+ char *sig = "QEMU";
+
+ qemu_cfg_select(QEMU_CFG_SIGNATURE);
+ for (i = 0; i < 4; i++) {
+ if (inb(PORT_QEMU_CFG_DATA) != sig[i]) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
static void
qemu_cfg_dma_transfer(void *address, u32 length, u32 control)
{
@@ -392,7 +407,9 @@ u16
qemu_get_present_cpus_count(void)
{
u16 smp_count = 0;
- qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count));
+ if (qemu_cfg_check_signature() == 0) {
+ qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count));
+ }
u16 cmos_cpu_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1;
if (smp_count < cmos_cpu_count) {
smp_count = cmos_cpu_count;
@@ -563,12 +580,9 @@ void qemu_cfg_init(void)
return;
// Detect fw_cfg interface.
- qemu_cfg_select(QEMU_CFG_SIGNATURE);
- char *sig = "QEMU";
- int i;
- for (i = 0; i < 4; i++)
- if (inb(PORT_QEMU_CFG_DATA) != sig[i])
- return;
+ if (qemu_cfg_check_signature() != 0) {
+ return;
+ }
dprintf(1, "Found QEMU fw_cfg\n");
--
2.11.0
_______________________________________________
SeaBIOS mailing list
SeaBIOS@seabios.org
https://www.coreboot.org/mailman/listinfo/seabios
On 03/14/17 21:33, petr.berky@email.cz wrote: > From 405de6e571a2bf332452a17ae98f7b3a0613365e Mon Sep 17 00:00:00 2001 > From: Petr Berky <petr.berky@email.cz> > Date: Tue, 14 Mar 2017 20:30:52 +0100 > Subject: [PATCH] config: Add function to check if fw_cfg exists > > It was found qemu_get_present_cpus_count may return impossible > number of cpus because of not checking if fw_cfg exists before > using it. That may lead to undefined behavior of emulator, > in particular Bochs that freezes. > > Signed-off-by: Petr Berky <petr.berky@email.cz> > --- > src/fw/paravirt.c | 28 +++++++++++++++++++++------- > 1 file changed, 21 insertions(+), 7 deletions(-) > > diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c > index 707502d..b2cfc23 100644 > --- a/src/fw/paravirt.c > +++ b/src/fw/paravirt.c > @@ -220,6 +220,21 @@ qemu_cfg_select(u16 f) > outw(f, PORT_QEMU_CFG_CTL); > } > > +static int > +qemu_cfg_check_signature(void) > +{ > + int i; > + char *sig = "QEMU"; > + > + qemu_cfg_select(QEMU_CFG_SIGNATURE); > + for (i = 0; i < 4; i++) { > + if (inb(PORT_QEMU_CFG_DATA) != sig[i]) { > + return -1; > + } > + } > + return 0; > +} > + > static void > qemu_cfg_dma_transfer(void *address, u32 length, u32 control) > { > @@ -392,7 +407,9 @@ u16 > qemu_get_present_cpus_count(void) > { > u16 smp_count = 0; > - qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); > + if (qemu_cfg_check_signature() == 0) { > + qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); > + } > u16 cmos_cpu_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; > if (smp_count < cmos_cpu_count) { > smp_count = cmos_cpu_count; > @@ -563,12 +580,9 @@ void qemu_cfg_init(void) > return; > > // Detect fw_cfg interface. > - qemu_cfg_select(QEMU_CFG_SIGNATURE); > - char *sig = "QEMU"; > - int i; > - for (i = 0; i < 4; i++) > - if (inb(PORT_QEMU_CFG_DATA) != sig[i]) > - return; > + if (qemu_cfg_check_signature() != 0) { > + return; > + } > > dprintf(1, "Found QEMU fw_cfg\n"); > > "src/fw/paravirt.c" already has an extern function called qemu_cfg_dma_enabled(), whic is based on the static global variable "cfg_dma_enabled", which is set in qemu_cfg_init(). The above is about the DMA interface for fw_cfg. I think it would be a "natural" extension to add a similar global variable and helper function (called qemu_cfg_enabled()) for the basic fw_cfg presence as well. Then qemu_cfg_check_signature() would not be necessary in this patch. Just an idea of course. Laszlo _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
On 03/14/2017 09:46 PM, Laszlo Ersek wrote: > On 03/14/17 21:33, petr.berky@email.cz wrote: >> From 405de6e571a2bf332452a17ae98f7b3a0613365e Mon Sep 17 00:00:00 2001 >> From: Petr Berky <petr.berky@email.cz> >> Date: Tue, 14 Mar 2017 20:30:52 +0100 >> Subject: [PATCH] config: Add function to check if fw_cfg exists >> >> It was found qemu_get_present_cpus_count may return impossible >> number of cpus because of not checking if fw_cfg exists before >> using it. That may lead to undefined behavior of emulator, >> in particular Bochs that freezes. >> >> Signed-off-by: Petr Berky <petr.berky@email.cz> >> --- >> src/fw/paravirt.c | 28 +++++++++++++++++++++------- >> 1 file changed, 21 insertions(+), 7 deletions(-) >> >> diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c >> index 707502d..b2cfc23 100644 >> --- a/src/fw/paravirt.c >> +++ b/src/fw/paravirt.c >> @@ -220,6 +220,21 @@ qemu_cfg_select(u16 f) >> outw(f, PORT_QEMU_CFG_CTL); >> } >> >> +static int >> +qemu_cfg_check_signature(void) >> +{ >> + int i; >> + char *sig = "QEMU"; >> + >> + qemu_cfg_select(QEMU_CFG_SIGNATURE); >> + for (i = 0; i < 4; i++) { >> + if (inb(PORT_QEMU_CFG_DATA) != sig[i]) { >> + return -1; >> + } >> + } >> + return 0; >> +} >> + >> static void >> qemu_cfg_dma_transfer(void *address, u32 length, u32 control) >> { >> @@ -392,7 +407,9 @@ u16 >> qemu_get_present_cpus_count(void) >> { >> u16 smp_count = 0; >> - qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); >> + if (qemu_cfg_check_signature() == 0) { >> + qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); >> + } >> u16 cmos_cpu_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; >> if (smp_count < cmos_cpu_count) { >> smp_count = cmos_cpu_count; >> @@ -563,12 +580,9 @@ void qemu_cfg_init(void) >> return; >> >> // Detect fw_cfg interface. >> - qemu_cfg_select(QEMU_CFG_SIGNATURE); >> - char *sig = "QEMU"; >> - int i; >> - for (i = 0; i < 4; i++) >> - if (inb(PORT_QEMU_CFG_DATA) != sig[i]) >> - return; >> + if (qemu_cfg_check_signature() != 0) { >> + return; >> + } >> >> dprintf(1, "Found QEMU fw_cfg\n"); >> >> > > "src/fw/paravirt.c" already has an extern function called > qemu_cfg_dma_enabled(), whic is based on the static global variable > "cfg_dma_enabled", which is set in qemu_cfg_init(). > > The above is about the DMA interface for fw_cfg. I think it would be a > "natural" extension to add a similar global variable and helper function > (called qemu_cfg_enabled()) for the basic fw_cfg presence as well. > > Then qemu_cfg_check_signature() would not be necessary in this patch. > > Just an idea of course. > > Laszlo > I think you are right. I will prepare a second patch _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
From b06589c683a7defb4853a3b810bd7e6a12abe2d6 Mon Sep 17 00:00:00 2001 From: Petr Berky <petr.berky@email.cz> Date: Tue, 14 Mar 2017 23:32:15 +0100 Subject: [PATCH v2] config: Add function to check if fw_cfg exists It was found qemu_get_present_cpus_count may return impossible number of cpus because of not checking if fw_cfg exists before using it. That may lead to undefined behavior of emulator, in particular Bochs that freezes. Signed-off-by: Petr Berky <petr.berky@email.cz> --- src/fw/paravirt.c | 12 +++++++++++- src/fw/paravirt.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 707502d..dfc69d4 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -32,9 +32,16 @@ u32 RamSize; u64 RamSizeOver4G; // Type of emulator platform. int PlatformRunningOn VARFSEG; +// cfg enabled +int cfg_enabled = 0; // cfg_dma enabled int cfg_dma_enabled = 0; +inline int qemu_cfg_enabled(void) +{ + return cfg_enabled; +} + inline int qemu_cfg_dma_enabled(void) { return cfg_dma_enabled; @@ -392,7 +399,9 @@ u16 qemu_get_present_cpus_count(void) { u16 smp_count = 0; - qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); + if (qemu_cfg_enabled()) { + qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); + } u16 cmos_cpu_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; if (smp_count < cmos_cpu_count) { smp_count = cmos_cpu_count; @@ -570,6 +579,7 @@ void qemu_cfg_init(void) if (inb(PORT_QEMU_CFG_DATA) != sig[i]) return; + cfg_enabled = 1; dprintf(1, "Found QEMU fw_cfg\n"); // Detect DMA interface. diff --git a/src/fw/paravirt.h b/src/fw/paravirt.h index 16f3d9a..a14d83e 100644 --- a/src/fw/paravirt.h +++ b/src/fw/paravirt.h @@ -49,6 +49,7 @@ static inline int runningOnKVM(void) { // QEMU_CFG_DMA ID bit #define QEMU_CFG_VERSION_DMA 2 +int qemu_cfg_enabled(void); int qemu_cfg_dma_enabled(void); void qemu_preinit(void); void qemu_platform_setup(void); -- 2.11.0 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
On Wed, Mar 15, 2017 at 12:09:11AM +0100, Petr Berky wrote: > From b06589c683a7defb4853a3b810bd7e6a12abe2d6 Mon Sep 17 00:00:00 2001 > From: Petr Berky <petr.berky@email.cz> > Date: Tue, 14 Mar 2017 23:32:15 +0100 > Subject: [PATCH v2] config: Add function to check if fw_cfg exists > > It was found qemu_get_present_cpus_count may return impossible > number of cpus because of not checking if fw_cfg exists before > using it. That may lead to undefined behavior of emulator, > in particular Bochs that freezes. Thanks. The patch looks fine to me. However, it looks like it got whitespace corrupted. Can you retry with "git send-email", or if that's not applicable, try attaching the patch. -Kevin _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
On 03/22/2017 04:34 PM, Kevin O'Connor wrote: > On Wed, Mar 15, 2017 at 12:09:11AM +0100, Petr Berky wrote: >> From b06589c683a7defb4853a3b810bd7e6a12abe2d6 Mon Sep 17 00:00:00 2001 >> From: Petr Berky <petr.berky@email.cz> >> Date: Tue, 14 Mar 2017 23:32:15 +0100 >> Subject: [PATCH v2] config: Add function to check if fw_cfg exists >> >> It was found qemu_get_present_cpus_count may return impossible >> number of cpus because of not checking if fw_cfg exists before >> using it. That may lead to undefined behavior of emulator, >> in particular Bochs that freezes. > > Thanks. The patch looks fine to me. However, it looks like it got > whitespace corrupted. Can you retry with "git send-email", or if > that's not applicable, try attaching the patch. > > -Kevin > I just send a patch v3 with this tiny change mentioned by Laszlo. I used "git send-email" as you advised and I hope you will receive it in the correct form this time. -Petr _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
On 03/15/17 00:09, Petr Berky wrote: > From b06589c683a7defb4853a3b810bd7e6a12abe2d6 Mon Sep 17 00:00:00 2001 > From: Petr Berky <petr.berky@email.cz> > Date: Tue, 14 Mar 2017 23:32:15 +0100 > Subject: [PATCH v2] config: Add function to check if fw_cfg exists > > It was found qemu_get_present_cpus_count may return impossible > number of cpus because of not checking if fw_cfg exists before > using it. That may lead to undefined behavior of emulator, > in particular Bochs that freezes. > > Signed-off-by: Petr Berky <petr.berky@email.cz> > --- > src/fw/paravirt.c | 12 +++++++++++- > src/fw/paravirt.h | 1 + > 2 files changed, 12 insertions(+), 1 deletion(-) > > diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c > index 707502d..dfc69d4 100644 > --- a/src/fw/paravirt.c > +++ b/src/fw/paravirt.c > @@ -32,9 +32,16 @@ u32 RamSize; > u64 RamSizeOver4G; > // Type of emulator platform. > int PlatformRunningOn VARFSEG; > +// cfg enabled > +int cfg_enabled = 0; > // cfg_dma enabled > int cfg_dma_enabled = 0; > > +inline int qemu_cfg_enabled(void) > +{ > + return cfg_enabled; > +} > + > inline int qemu_cfg_dma_enabled(void) > { > return cfg_dma_enabled; > @@ -392,7 +399,9 @@ u16 > qemu_get_present_cpus_count(void) > { > u16 smp_count = 0; > - qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, sizeof(smp_count)); > + if (qemu_cfg_enabled()) { > + qemu_cfg_read_entry(&smp_count, QEMU_CFG_NB_CPUS, > sizeof(smp_count)); > + } > u16 cmos_cpu_count = rtc_read(CMOS_BIOS_SMP_COUNT) + 1; > if (smp_count < cmos_cpu_count) { > smp_count = cmos_cpu_count; > @@ -570,6 +579,7 @@ void qemu_cfg_init(void) > if (inb(PORT_QEMU_CFG_DATA) != sig[i]) > return; > > + cfg_enabled = 1; > dprintf(1, "Found QEMU fw_cfg\n"); > > // Detect DMA interface. If we wanted to parallel the DMA check 100%, we'd set the variable under the debug message, not above it, but even I am not that pedantic. :) Reviewed-by: Laszlo Ersek <lersek@redhat.com> Igor, can you check if this is safe for S3 resume too? I think it is, but I had better ask you. Thanks Laszlo > diff --git a/src/fw/paravirt.h b/src/fw/paravirt.h > index 16f3d9a..a14d83e 100644 > --- a/src/fw/paravirt.h > +++ b/src/fw/paravirt.h > @@ -49,6 +49,7 @@ static inline int runningOnKVM(void) { > // QEMU_CFG_DMA ID bit > #define QEMU_CFG_VERSION_DMA 2 > > +int qemu_cfg_enabled(void); > int qemu_cfg_dma_enabled(void); > void qemu_preinit(void); > void qemu_platform_setup(void); _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios
© 2016 - 2025 Red Hat, Inc.