hw/i386/microvm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
microvm places the 64-bit PCI MMIO hole at the top of the physical
address space. With SEV, the c-bit reduces the usable address space,
so the MMIO hole ends up at addresses the guest cannot reach (the
guest always strips the c-bit on MMIO accesses).
Fix by placing the MMIO hole within the sev guest addressable range.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3245
Tested-by: Cyril Leclerc <cyril.leclerc@subnoto.com>
Signed-off-by: Cyril Leclerc <cyril.leclerc@subnoto.com>
---
hw/i386/microvm.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 94d22a232a..cb43a399ff 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -36,6 +36,7 @@
#include "hw/i386/microvm.h"
#include "hw/i386/x86.h"
#include "target/i386/cpu.h"
+#include "target/i386/sev.h"
#include "hw/intc/i8259.h"
#include "hw/timer/i8254.h"
#include "hw/rtc/mc146818rtc.h"
@@ -230,7 +231,11 @@ static void microvm_devices_init(MicrovmMachineState *mms)
if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie == ON_OFF_AUTO_ON) {
/* use topmost 25% of the address space available */
- hwaddr phys_size = (hwaddr)1 << X86_CPU(first_cpu)->phys_bits;
+ int phys_bits = X86_CPU(first_cpu)->phys_bits;
+ if (sev_enabled()) {
+ phys_bits -= sev_get_reduced_phys_bits();
+ }
+ hwaddr phys_size = (hwaddr)1 << phys_bits;
if (phys_size > 0x1000000ll) {
mms->gpex.mmio64.size = phys_size / 4;
mms->gpex.mmio64.base = phys_size - mms->gpex.mmio64.size;
--
2.47.3
Hi Cyril,
On 16/12/25 20:49, Cyril Leclerc via wrote:
> microvm places the 64-bit PCI MMIO hole at the top of the physical
> address space. With SEV, the c-bit reduces the usable address space,
> so the MMIO hole ends up at addresses the guest cannot reach (the
> guest always strips the c-bit on MMIO accesses).
>
> Fix by placing the MMIO hole within the sev guest addressable range.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3245
>
> Tested-by: Cyril Leclerc <cyril.leclerc@subnoto.com>
> Signed-off-by: Cyril Leclerc <cyril.leclerc@subnoto.com>
> ---
> hw/i386/microvm.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
> index 94d22a232a..cb43a399ff 100644
> --- a/hw/i386/microvm.c
> +++ b/hw/i386/microvm.c
> @@ -36,6 +36,7 @@
> #include "hw/i386/microvm.h"
> #include "hw/i386/x86.h"
> #include "target/i386/cpu.h"
> +#include "target/i386/sev.h"
> #include "hw/intc/i8259.h"
> #include "hw/timer/i8254.h"
> #include "hw/rtc/mc146818rtc.h"
> @@ -230,7 +231,11 @@ static void microvm_devices_init(MicrovmMachineState *mms)
>
> if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie == ON_OFF_AUTO_ON) {
> /* use topmost 25% of the address space available */
> - hwaddr phys_size = (hwaddr)1 << X86_CPU(first_cpu)->phys_bits;
> + int phys_bits = X86_CPU(first_cpu)->phys_bits;
> + if (sev_enabled()) {
> + phys_bits -= sev_get_reduced_phys_bits();
No clue whether this is right or not, but please use logical operation
to remove a bit from a mask:
phys_bits &= ~sev_get_reduced_phys_bits();
> + }
> + hwaddr phys_size = (hwaddr)1 << phys_bits;
> if (phys_size > 0x1000000ll) {
> mms->gpex.mmio64.size = phys_size / 4;
> mms->gpex.mmio64.base = phys_size - mms->gpex.mmio64.size;
Hello Philippe,
I'd have thought that phys_bits was a bit count not a mask. we want to
remove the number of reduced phys bit from the total to get the usable
address width
Le ven. 19 déc. 2025 à 15:42, Philippe Mathieu-Daudé <philmd@linaro.org> a
écrit :
> Hi Cyril,
>
> On 16/12/25 20:49, Cyril Leclerc via wrote:
> > microvm places the 64-bit PCI MMIO hole at the top of the physical
> > address space. With SEV, the c-bit reduces the usable address space,
> > so the MMIO hole ends up at addresses the guest cannot reach (the
> > guest always strips the c-bit on MMIO accesses).
> >
> > Fix by placing the MMIO hole within the sev guest addressable range.
> >
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3245
> >
> > Tested-by: Cyril Leclerc <cyril.leclerc@subnoto.com>
> > Signed-off-by: Cyril Leclerc <cyril.leclerc@subnoto.com>
> > ---
> > hw/i386/microvm.c | 7 ++++++-
> > 1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
> > index 94d22a232a..cb43a399ff 100644
> > --- a/hw/i386/microvm.c
> > +++ b/hw/i386/microvm.c
> > @@ -36,6 +36,7 @@
> > #include "hw/i386/microvm.h"
> > #include "hw/i386/x86.h"
> > #include "target/i386/cpu.h"
> > +#include "target/i386/sev.h"
> > #include "hw/intc/i8259.h"
> > #include "hw/timer/i8254.h"
> > #include "hw/rtc/mc146818rtc.h"
> > @@ -230,7 +231,11 @@ static void
> microvm_devices_init(MicrovmMachineState *mms)
> >
> > if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie ==
> ON_OFF_AUTO_ON) {
> > /* use topmost 25% of the address space available */
> > - hwaddr phys_size = (hwaddr)1 << X86_CPU(first_cpu)->phys_bits;
> > + int phys_bits = X86_CPU(first_cpu)->phys_bits;
> > + if (sev_enabled()) {
> > + phys_bits -= sev_get_reduced_phys_bits();
>
> No clue whether this is right or not, but please use logical operation
> to remove a bit from a mask:
>
> phys_bits &= ~sev_get_reduced_phys_bits();
>
> > + }
> > + hwaddr phys_size = (hwaddr)1 << phys_bits;
> > if (phys_size > 0x1000000ll) {
> > mms->gpex.mmio64.size = phys_size / 4;
> > mms->gpex.mmio64.base = phys_size - mms->gpex.mmio64.size;
>
>
© 2016 - 2026 Red Hat, Inc.