qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 6/7] i386: disable the region in /machine/smram when


From: Paolo Bonzini
Subject: [Qemu-devel] [PATCH 6/7] i386: disable the region in /machine/smram when SMRAM is open
Date: Fri, 15 May 2015 18:37:02 +0200

This patch provides some help from the chipset in handling SMRAM.

SMRAM regions can overlap with e.g. PCI BARs.  When this happens, PCI
BARs will be hidden behind SMRAM and will cause a userspace MMIO exit.
This can be achieved easily with KVM just by giving a higher priority
to the SMRAM region.  The SMRAM region is changed to a KVM_MEM_X86_SMRAM
memory slot and causes a MMIO exit when outside SMM.

Unfortunately, when SMRAM is open, the SMRAM region in system memory
would be treated like a PCI BAR and would be hidden behind SMRAM.  In
order to avoid this, disable the region in /machine/smram when SMRAM
is open.  Then the KVM address space will include the SMRAM region
through system memory (thus without the flag) rather than through
/machine/smram.

Signed-off-by: Paolo Bonzini <address@hidden>
---
 hw/pci-host/piix.c |  6 ++++++
 hw/pci-host/q35.c  | 20 +++++++++++++-------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 3f23851..ee8a680 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -142,6 +142,12 @@ static void i440fx_update_memory_mappings(PCII440FXState 
*d)
                               !(pd->config[I440FX_SMRAM] & SMRAM_D_OPEN));
     memory_region_set_enabled(&d->smram,
                               pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
+
+    /* KVM requires disabling the region in /machine/smram when SMRAM
+     * is open.
+     */
+    memory_region_set_enabled(&d->low_smram,
+                              !(pd->config[I440FX_SMRAM] & SMRAM_D_OPEN));
     memory_region_transaction_commit();
 }
 
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 60a9f2c..3a016fa 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -305,18 +305,24 @@ static void mch_update_smram(MCHPCIState *mch)
         memory_region_set_enabled(&mch->smram_region, h_smrame);
         /* Show high SMRAM if H_SMRAME = 1 */
         memory_region_set_enabled(&mch->open_high_smram, h_smrame);
+
+        /* KVM requires disabling the region in /machine/smram when SMRAM
+         * is open.
+         */
+        memory_region_set_enabled(&mch->low_smram, false);
+        memory_region_set_enabled(&mch->high_smram, false);
     } else {
         /* Hide high SMRAM and low SMRAM */
         memory_region_set_enabled(&mch->smram_region, true);
         memory_region_set_enabled(&mch->open_high_smram, false);
-    }
 
-    if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) {
-        memory_region_set_enabled(&mch->low_smram, !h_smrame);
-        memory_region_set_enabled(&mch->high_smram, h_smrame);
-    } else {
-        memory_region_set_enabled(&mch->low_smram, false);
-        memory_region_set_enabled(&mch->high_smram, false);
+        if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) {
+            memory_region_set_enabled(&mch->low_smram, !h_smrame);
+            memory_region_set_enabled(&mch->high_smram, h_smrame);
+        } else {
+            memory_region_set_enabled(&mch->low_smram, false);
+            memory_region_set_enabled(&mch->high_smram, false);
+        }
     }
 
     if (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) {
-- 
1.8.3.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]