All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM
@ 2015-05-11 13:48 Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 01/31] pc: add 2.4 machine types Paolo Bonzini
                   ` (31 more replies)
  0 siblings, 32 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

These patches implement almost everything that is needed for SMM
support in OVMF and KVM.  The only missing bit is support for
SMRAM regions in KVM, but it need not block review of these ones,
and possibly inclusion of the first 26.

There are many small parts in this patches, but I am posting them
together because each small part alone adds very little.

Patch 1 comes from mst's pull request.

Patches 2-6 are target-i386 patches.  They add support for memory
attributes in target-i386, enabling the "secure" attribute whenever
the CPU is in system management mode.  They also fix two SMM bugs
found while working on KVM support.

Patches 7-9 add support for secure access to parallel flash.  If
enabled, parallel flash behaves as ROM unless the "secure" memory
transaction attribute is set.

Patches 10-12 are general infrastructure patches that didn't fit
elsewhere.  Note that patch 10 introduces new command-line syntax.

Patches 13-16 rewrite the SMRAM handling in TCG mode, so that the
SMRAM setup is done just once using the memory API, and then
enabled/disabled by the CPU without intervention from the chipset.
The resulting chipset code is simpler and...

... patches 17-23 then rely on this to implement support for
more q35 SMI features, in particular high SMRAM, TSEG and SMI_LOCK.
This part was done almost entirely by Gerd.

Patches 24-26 are for q35 feature parity with PIIX4.  They are from Laszlo
and they are included just because they conflict with the next few.

Patches 27 and 28 implement KVM support for SMM.  Note that this support
is not yet upstream (will be in Linux 4.2); these patches will be
rebased after the updated KVM headers are taken from kvm.git.

Patches 29-31 add a "-machine smm=on|off|auto" option (QOM property)
that can be used to hide SMM or make it available on any accelerator.
The compat gunk makes it available by default on TCG but not on KVM.

That's it.  Go ahead and review.

Paolo


Gerd Hoffmann (6):
  q35: fix ESMRAMC default
  q35: add config space wmask for SMRAM and ESMRAMC
  q35: implement SMRAM.D_LCK
  q35: add test for SMRAM.D_LCK
  q35: implement TSEG
  ich9: implement SMI_LOCK

Jason Wang (1):
  pc: add 2.4 machine types

Laszlo Ersek (3):
  hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4"
  hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core
  hw/acpi: piix4_pm_init(): take fw_cfg object no more

Paolo Bonzini (21):
  target-i386: introduce cpu_get_mem_attrs
  target-i386: Use correct memory attributes for memory accesses
  target-i386: Use correct memory attributes for ioport accesses
  target-i386: mask NMIs on entry to SMM
  target-i386: set G=1 in SMM big real mode selectors
  pflash_cfi01: change big-endian property to BIT type
  pflash_cfi01: change to new-style MMIO accessors
  pflash_cfi01: add secure property
  vl: allow full-blown QemuOpts syntax for -global
  qom: add object_property_add_const_link
  vl: run "late" notifiers immediately
  target-i386: create a separate AddressSpace for each CPU
  hw/i386: add a separate region that tracks the SMRAME bit
  target-i386: use memory API to implement SMRAM
  hw/i386: remove smram_update
  q35: implement high SMRAM
  target-i386: add support for SMBASE MSR and SMIs
  vga: disable chain4_alias if KVM supports SMRAM
  pc_piix: rename kvm_enabled to smm_enabled
  ich9: add smm_enabled field and arguments
  pc: add SMM property

 bsd-user/main.c             |   4 -
 hw/acpi/core.c              |  15 +-
 hw/acpi/ich9.c              |  12 +-
 hw/acpi/piix4.c             |  21 +--
 hw/block/pflash_cfi01.c     | 204 +++++++++++----------------
 hw/display/vga.c            |   8 +-
 hw/display/vga_int.h        |   1 +
 hw/i386/pc.c                |  72 +++++++---
 hw/i386/pc_piix.c           |  53 +++++--
 hw/i386/pc_q35.c            |  33 ++++-
 hw/isa/lpc_ich9.c           |  23 ++-
 hw/isa/vt82c686.c           |   2 +-
 hw/mips/mips_malta.c        |   2 +-
 hw/pci-host/pam.c           |  20 ---
 hw/pci-host/piix.c          |  39 +++---
 hw/pci-host/q35.c           | 137 ++++++++++++++++--
 include/exec/memattrs.h     |   4 +-
 include/hw/acpi/acpi.h      |   3 +-
 include/hw/acpi/ich9.h      |   4 +-
 include/hw/i386/ich9.h      |   8 +-
 include/hw/i386/pc.h        |   7 +-
 include/hw/pci-host/pam.h   |   4 -
 include/hw/pci-host/q35.h   |  36 +++--
 include/qom/object.h        |  18 +++
 include/sysemu/kvm.h        |   1 +
 kvm-all.c                   |   5 +
 kvm-stub.c                  |   5 +
 linux-headers/asm-x86/kvm.h |  11 +-
 linux-headers/linux/kvm.h   |   5 +-
 linux-user/main.c           |   4 -
 qdev-monitor.c              |  18 ++-
 qemu-options.hx             |   7 +-
 qom/object.c                |  16 +++
 target-i386/Makefile.objs   |   2 -
 target-i386/cpu-qom.h       |   3 +
 target-i386/cpu.c           |  43 ++++++
 target-i386/cpu.h           |  41 ++++--
 target-i386/helper.c        | 135 +++++++++++++++---
 target-i386/helper.h        |  12 +-
 target-i386/ioport-user.c   |  60 --------
 target-i386/kvm.c           |  75 ++++++++--
 target-i386/machine.c       |   3 +
 target-i386/misc_helper.c   |  59 ++++++--
 target-i386/seg_helper.c    |  12 +-
 target-i386/smm_helper.c    | 331 +++++++++++++++++++++++---------------------
 target-i386/svm_helper.c    | 230 +++++++++++++++---------------
 target-i386/translate.c     |  12 +-
 tests/Makefile              |   2 +
 tests/smram-test.c          |  80 +++++++++++
 vl.c                        |   6 +
 50 files changed, 1220 insertions(+), 688 deletions(-)
 delete mode 100644 target-i386/ioport-user.c
 create mode 100644 tests/smram-test.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 01/31] pc: add 2.4 machine types
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 02/31] target-i386: introduce cpu_get_mem_attrs Paolo Bonzini
                   ` (30 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jason Wang, lersek, kraxel, mst

From: Jason Wang <jasowang@redhat.com>

The following patches will limit the following things to legacy
machine type:

- maximum number of virtqueues for virtio-pci were limited to 64
- auto msix bar size for virtio-net-pci were disabled by default

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/pc_piix.c | 29 +++++++++++++++++++++++++----
 hw/i386/pc_q35.c  | 26 +++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1fe7bfb..212e263 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -310,8 +310,13 @@ static void pc_init_pci(MachineState *machine)
     pc_init1(machine, 1, 1);
 }
 
+static void pc_compat_2_3(MachineState *machine)
+{
+}
+
 static void pc_compat_2_2(MachineState *machine)
 {
+    pc_compat_2_3(machine);
     rsdp_in_ram = false;
     x86_cpu_compat_set_features("kvm64", FEAT_1_EDX, 0, CPUID_VME);
     x86_cpu_compat_set_features("kvm32", FEAT_1_EDX, 0, CPUID_VME);
@@ -413,6 +418,12 @@ static void pc_compat_1_2(MachineState *machine)
     x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI);
 }
 
+static void pc_init_pci_2_3(MachineState *machine)
+{
+    pc_compat_2_3(machine);
+    pc_init_pci(machine);
+}
+
 static void pc_init_pci_2_2(MachineState *machine)
 {
     pc_compat_2_2(machine);
@@ -512,19 +523,28 @@ static void pc_xen_hvm_init(MachineState *machine)
     .desc = "Standard PC (i440FX + PIIX, 1996)", \
     .hot_add_cpu = pc_hot_add_cpu
 
-#define PC_I440FX_2_3_MACHINE_OPTIONS                           \
+#define PC_I440FX_2_4_MACHINE_OPTIONS                           \
     PC_I440FX_MACHINE_OPTIONS,                                  \
     .default_machine_opts = "firmware=bios-256k.bin",           \
     .default_display = "std"
 
-static QEMUMachine pc_i440fx_machine_v2_3 = {
-    PC_I440FX_2_3_MACHINE_OPTIONS,
-    .name = "pc-i440fx-2.3",
+
+static QEMUMachine pc_i440fx_machine_v2_4 = {
+    PC_I440FX_2_4_MACHINE_OPTIONS,
+    .name = "pc-i440fx-2.4",
     .alias = "pc",
     .init = pc_init_pci,
     .is_default = 1,
 };
 
+#define PC_I440FX_2_3_MACHINE_OPTIONS PC_I440FX_2_4_MACHINE_OPTIONS
+
+static QEMUMachine pc_i440fx_machine_v2_3 = {
+    PC_I440FX_2_3_MACHINE_OPTIONS,
+    .name = "pc-i440fx-2.3",
+    .init = pc_init_pci_2_3,
+};
+
 #define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS
 
 static QEMUMachine pc_i440fx_machine_v2_2 = {
@@ -970,6 +990,7 @@ static QEMUMachine xenfv_machine = {
 
 static void pc_machine_init(void)
 {
+    qemu_register_pc_machine(&pc_i440fx_machine_v2_4);
     qemu_register_pc_machine(&pc_i440fx_machine_v2_3);
     qemu_register_pc_machine(&pc_i440fx_machine_v2_2);
     qemu_register_pc_machine(&pc_i440fx_machine_v2_1);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index dcc17c0..e67f2de 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -289,8 +289,13 @@ static void pc_q35_init(MachineState *machine)
     }
 }
 
+static void pc_compat_2_3(MachineState *machine)
+{
+}
+
 static void pc_compat_2_2(MachineState *machine)
 {
+    pc_compat_2_3(machine);
     rsdp_in_ram = false;
     x86_cpu_compat_set_features("kvm64", FEAT_1_EDX, 0, CPUID_VME);
     x86_cpu_compat_set_features("kvm32", FEAT_1_EDX, 0, CPUID_VME);
@@ -361,6 +366,12 @@ static void pc_compat_1_4(MachineState *machine)
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 }
 
+static void pc_q35_init_2_3(MachineState *machine)
+{
+    pc_compat_2_3(machine);
+    pc_q35_init(machine);
+}
+
 static void pc_q35_init_2_2(MachineState *machine)
 {
     pc_compat_2_2(machine);
@@ -410,16 +421,24 @@ static void pc_q35_init_1_4(MachineState *machine)
     .hot_add_cpu = pc_hot_add_cpu, \
     .units_per_default_bus = 1
 
-#define PC_Q35_2_3_MACHINE_OPTIONS                      \
+#define PC_Q35_2_4_MACHINE_OPTIONS                      \
     PC_Q35_MACHINE_OPTIONS,                             \
     .default_machine_opts = "firmware=bios-256k.bin",   \
     .default_display = "std"
 
+static QEMUMachine pc_q35_machine_v2_4 = {
+    PC_Q35_2_4_MACHINE_OPTIONS,
+    .name = "pc-q35-2.4",
+    .alias = "q35",
+    .init = pc_q35_init,
+};
+
+#define PC_Q35_2_3_MACHINE_OPTIONS PC_Q35_2_4_MACHINE_OPTIONS
+
 static QEMUMachine pc_q35_machine_v2_3 = {
     PC_Q35_2_3_MACHINE_OPTIONS,
     .name = "pc-q35-2.3",
-    .alias = "q35",
-    .init = pc_q35_init,
+    .init = pc_q35_init_2_3,
 };
 
 #define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS
@@ -506,6 +525,7 @@ static QEMUMachine pc_q35_machine_v1_4 = {
 
 static void pc_q35_machine_init(void)
 {
+    qemu_register_pc_machine(&pc_q35_machine_v2_4);
     qemu_register_pc_machine(&pc_q35_machine_v2_3);
     qemu_register_pc_machine(&pc_q35_machine_v2_2);
     qemu_register_pc_machine(&pc_q35_machine_v2_1);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 02/31] target-i386: introduce cpu_get_mem_attrs
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 01/31] pc: add 2.4 machine types Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 03/31] target-i386: Use correct memory attributes for memory accesses Paolo Bonzini
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/exec/memattrs.h | 4 +++-
 target-i386/cpu.h       | 5 +++++
 target-i386/helper.c    | 3 ++-
 target-i386/kvm.c       | 2 +-
 4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index 1389b4b..6bbf9aa 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -29,7 +29,9 @@ typedef struct MemTxAttrs {
      * "didn't specify" if necessary.
      */
     unsigned int unspecified:1;
-    /* ARM/AMBA TrustZone Secure access */
+    /* ARM/AMBA: TrustZone Secure access
+     * x86: System Management Mode access
+     */
     unsigned int secure:1;
     /* Memory access is usermode (unprivileged) */
     unsigned int user:1;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4ee12ca..64c2783 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1292,6 +1292,11 @@ static inline void cpu_load_efer(CPUX86State *env, uint64_t val)
     }
 }
 
+static inline MemTxAttrs cpu_get_mem_attrs(CPUX86State *env)
+{
+    return ((MemTxAttrs) { .secure = (env->hflags & HF_SMM_MASK) != 0 });
+}
+
 /* fpu_helper.c */
 void cpu_set_mxcsr(CPUX86State *env, uint32_t val);
 void cpu_set_fpuc(CPUX86State *env, uint16_t val);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 4f1ddf7..62e801b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -771,7 +771,8 @@ do_check_protect_pse36:
     page_offset = vaddr & (page_size - 1);
     paddr = pte + page_offset;
 
-    tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
+    tlb_set_page_with_attrs(cs, vaddr, paddr, cpu_get_mem_attrs(env),
+                            prot, mmu_idx, page_size);
     return 0;
  do_fault_rsvd:
     error_code |= PG_ERROR_RSVD_MASK;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a26d25a..009bf74 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2259,7 +2259,7 @@ MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run)
     }
     cpu_set_apic_tpr(x86_cpu->apic_state, run->cr8);
     cpu_set_apic_base(x86_cpu->apic_state, run->apic_base);
-    return MEMTXATTRS_UNSPECIFIED;
+    return cpu_get_mem_attrs(env);
 }
 
 int kvm_arch_process_async_events(CPUState *cs)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 03/31] target-i386: Use correct memory attributes for memory accesses
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 01/31] pc: add 2.4 machine types Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 02/31] target-i386: introduce cpu_get_mem_attrs Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 04/31] target-i386: Use correct memory attributes for ioport accesses Paolo Bonzini
                   ` (28 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

These include page table walks, SVM accesses and SMM state save accesses.

The bulk of the patch is obtained with

   sed -i 's/\(\<[a-z_]*_phys\(_notdirty\)\?\>(cs\)->as,/x86_\1,/'

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/cpu.h        |  12 ++
 target-i386/helper.c     | 132 +++++++++++++++++----
 target-i386/seg_helper.c |  12 +-
 target-i386/smm_helper.c | 298 +++++++++++++++++++++++------------------------
 target-i386/svm_helper.c | 230 ++++++++++++++++++------------------
 5 files changed, 394 insertions(+), 290 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 64c2783..9f57fe9 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1105,6 +1105,18 @@ int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr,
                              int is_write, int mmu_idx);
 void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
 
+#ifndef CONFIG_USER_ONLY
+uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr);
+uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr);
+uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr);
+uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr);
+void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val);
+void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val);
+void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val);
+void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val);
+void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val);
+#endif
+
 static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
 {
     return (dr7 >> (index * 2)) & 1;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 62e801b..5480a96 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -565,7 +565,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
 
             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pml4e = ldq_phys(cs->as, pml4e_addr);
+            pml4e = x86_ldq_phys(cs, pml4e_addr);
             if (!(pml4e & PG_PRESENT_MASK)) {
                 goto do_fault;
             }
@@ -574,12 +574,12 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
             }
             if (!(pml4e & PG_ACCESSED_MASK)) {
                 pml4e |= PG_ACCESSED_MASK;
-                stl_phys_notdirty(cs->as, pml4e_addr, pml4e);
+                x86_stl_phys_notdirty(cs, pml4e_addr, pml4e);
             }
             ptep = pml4e ^ PG_NX_MASK;
             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pdpe = ldq_phys(cs->as, pdpe_addr);
+            pdpe = x86_ldq_phys(cs, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK)) {
                 goto do_fault;
             }
@@ -589,7 +589,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
             ptep &= pdpe ^ PG_NX_MASK;
             if (!(pdpe & PG_ACCESSED_MASK)) {
                 pdpe |= PG_ACCESSED_MASK;
-                stl_phys_notdirty(cs->as, pdpe_addr, pdpe);
+                x86_stl_phys_notdirty(cs, pdpe_addr, pdpe);
             }
             if (pdpe & PG_PSE_MASK) {
                 /* 1 GB page */
@@ -604,7 +604,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
             /* XXX: load them when cr3 is loaded ? */
             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                 env->a20_mask;
-            pdpe = ldq_phys(cs->as, pdpe_addr);
+            pdpe = x86_ldq_phys(cs, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK)) {
                 goto do_fault;
             }
@@ -617,7 +617,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
 
         pde_addr = ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
             env->a20_mask;
-        pde = ldq_phys(cs->as, pde_addr);
+        pde = x86_ldq_phys(cs, pde_addr);
         if (!(pde & PG_PRESENT_MASK)) {
             goto do_fault;
         }
@@ -635,11 +635,11 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
         /* 4 KB page */
         if (!(pde & PG_ACCESSED_MASK)) {
             pde |= PG_ACCESSED_MASK;
-            stl_phys_notdirty(cs->as, pde_addr, pde);
+            x86_stl_phys_notdirty(cs, pde_addr, pde);
         }
         pte_addr = ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
             env->a20_mask;
-        pte = ldq_phys(cs->as, pte_addr);
+        pte = x86_ldq_phys(cs, pte_addr);
         if (!(pte & PG_PRESENT_MASK)) {
             goto do_fault;
         }
@@ -655,7 +655,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
         /* page directory entry */
         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
             env->a20_mask;
-        pde = ldl_phys(cs->as, pde_addr);
+        pde = x86_ldl_phys(cs, pde_addr);
         if (!(pde & PG_PRESENT_MASK)) {
             goto do_fault;
         }
@@ -676,13 +676,13 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
 
         if (!(pde & PG_ACCESSED_MASK)) {
             pde |= PG_ACCESSED_MASK;
-            stl_phys_notdirty(cs->as, pde_addr, pde);
+            x86_stl_phys_notdirty(cs, pde_addr, pde);
         }
 
         /* page directory entry */
         pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
             env->a20_mask;
-        pte = ldl_phys(cs->as, pte_addr);
+        pte = x86_ldl_phys(cs, pte_addr);
         if (!(pte & PG_PRESENT_MASK)) {
             goto do_fault;
         }
@@ -737,7 +737,7 @@ do_check_protect_pse36:
         if (is_dirty) {
             pte |= PG_DIRTY_MASK;
         }
-        stl_phys_notdirty(cs->as, pte_addr, pte);
+        x86_stl_phys_notdirty(cs, pte_addr, pte);
     }
 
     /* the page can be put in the TLB */
@@ -789,7 +789,7 @@ do_check_protect_pse36:
         error_code |= PG_ERROR_I_D_MASK;
     if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
         /* cr2 is not modified in case of exceptions */
-        stq_phys(cs->as,
+        x86_stq_phys(cs,
                  env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
                  addr);
     } else {
@@ -828,13 +828,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             }
             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pml4e = ldq_phys(cs->as, pml4e_addr);
+            pml4e = x86_ldq_phys(cs, pml4e_addr);
             if (!(pml4e & PG_PRESENT_MASK)) {
                 return -1;
             }
             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
                          (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
-            pdpe = ldq_phys(cs->as, pdpe_addr);
+            pdpe = x86_ldq_phys(cs, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK)) {
                 return -1;
             }
@@ -849,14 +849,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         {
             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                 env->a20_mask;
-            pdpe = ldq_phys(cs->as, pdpe_addr);
+            pdpe = x86_ldq_phys(cs, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
         }
 
         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
                     (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
-        pde = ldq_phys(cs->as, pde_addr);
+        pde = x86_ldq_phys(cs, pde_addr);
         if (!(pde & PG_PRESENT_MASK)) {
             return -1;
         }
@@ -869,7 +869,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pte_addr = ((pde & PG_ADDRESS_MASK) +
                         (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
             page_size = 4096;
-            pte = ldq_phys(cs->as, pte_addr);
+            pte = x86_ldq_phys(cs, pte_addr);
         }
         if (!(pte & PG_PRESENT_MASK)) {
             return -1;
@@ -879,7 +879,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
         /* page directory entry */
         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
-        pde = ldl_phys(cs->as, pde_addr);
+        pde = x86_ldl_phys(cs, pde_addr);
         if (!(pde & PG_PRESENT_MASK))
             return -1;
         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
@@ -888,7 +888,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         } else {
             /* page directory entry */
             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
-            pte = ldl_phys(cs->as, pte_addr);
+            pte = x86_ldl_phys(cs, pte_addr);
             if (!(pte & PG_PRESENT_MASK)) {
                 return -1;
             }
@@ -1277,3 +1277,95 @@ void x86_cpu_exec_exit(CPUState *cs)
 
     env->eflags = cpu_compute_eflags(env);
 }
+
+#ifndef CONFIG_USER_ONLY
+uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    return address_space_ldub(cs->as, addr,
+                              cpu_get_mem_attrs(env),
+                              NULL);
+}
+
+uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    return address_space_lduw(cs->as, addr,
+                              cpu_get_mem_attrs(env),
+                              NULL);
+}
+
+uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    return address_space_ldl(cs->as, addr,
+                             cpu_get_mem_attrs(env),
+                             NULL);
+}
+
+uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    return address_space_ldq(cs->as, addr,
+                             cpu_get_mem_attrs(env),
+                             NULL);
+}
+
+void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    address_space_stb(cs->as, addr, val,
+                      cpu_get_mem_attrs(env),
+                      NULL);
+}
+
+void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    address_space_stl_notdirty(cs->as, addr, val,
+                               cpu_get_mem_attrs(env),
+                               NULL);
+}
+
+void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    address_space_stw(cs->as, addr, val,
+                      cpu_get_mem_attrs(env),
+                      NULL);
+}
+
+void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    address_space_stl(cs->as, addr, val,
+                      cpu_get_mem_attrs(env),
+                      NULL);
+}
+
+void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+
+    address_space_stq(cs->as, addr, val,
+                      cpu_get_mem_attrs(env),
+                      NULL);
+}
+#endif
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 2bc757a..8a4271e 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1144,7 +1144,7 @@ static void handle_even_inj(CPUX86State *env, int intno, int is_int,
                             int error_code, int is_hw, int rm)
 {
     CPUState *cs = CPU(x86_env_get_cpu(env));
-    uint32_t event_inj = ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    uint32_t event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                           control.event_inj));
 
     if (!(event_inj & SVM_EVTINJ_VALID)) {
@@ -1158,11 +1158,11 @@ static void handle_even_inj(CPUX86State *env, int intno, int is_int,
         event_inj = intno | type | SVM_EVTINJ_VALID;
         if (!rm && exception_has_error_code(intno)) {
             event_inj |= SVM_EVTINJ_VALID_ERR;
-            stl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+            x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                              control.event_inj_err),
                      error_code);
         }
-        stl_phys(cs->as,
+        x86_stl_phys(cs,
                  env->vm_vmcb + offsetof(struct vmcb, control.event_inj),
                  event_inj);
     }
@@ -1240,11 +1240,11 @@ static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
 #if !defined(CONFIG_USER_ONLY)
     if (env->hflags & HF_SVMI_MASK) {
         CPUState *cs = CPU(cpu);
-        uint32_t event_inj = ldl_phys(cs->as, env->vm_vmcb +
+        uint32_t event_inj = x86_ldl_phys(cs, env->vm_vmcb +
                                       offsetof(struct vmcb,
                                                control.event_inj));
 
-        stl_phys(cs->as,
+        x86_stl_phys(cs,
                  env->vm_vmcb + offsetof(struct vmcb, control.event_inj),
                  event_inj & ~SVM_EVTINJ_VALID);
     }
@@ -1339,7 +1339,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
             int intno;
             /* FIXME: this should respect TPR */
             cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0);
-            intno = ldl_phys(cs->as, env->vm_vmcb
+            intno = x86_ldl_phys(cs, env->vm_vmcb
                              + offsetof(struct vmcb, control.int_vector));
             qemu_log_mask(CPU_LOG_TB_IN_ASM,
                           "Servicing virtual hardware INT=0x%02x\n", intno);
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index c62f468..b9971b6 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -60,83 +60,83 @@ void do_smm_enter(X86CPU *cpu)
     for (i = 0; i < 6; i++) {
         dt = &env->segs[i];
         offset = 0x7e00 + i * 16;
-        stw_phys(cs->as, sm_state + offset, dt->selector);
-        stw_phys(cs->as, sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
-        stl_phys(cs->as, sm_state + offset + 4, dt->limit);
-        stq_phys(cs->as, sm_state + offset + 8, dt->base);
+        x86_stw_phys(cs, sm_state + offset, dt->selector);
+        x86_stw_phys(cs, sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
+        x86_stl_phys(cs, sm_state + offset + 4, dt->limit);
+        x86_stq_phys(cs, sm_state + offset + 8, dt->base);
     }
 
-    stq_phys(cs->as, sm_state + 0x7e68, env->gdt.base);
-    stl_phys(cs->as, sm_state + 0x7e64, env->gdt.limit);
+    x86_stq_phys(cs, sm_state + 0x7e68, env->gdt.base);
+    x86_stl_phys(cs, sm_state + 0x7e64, env->gdt.limit);
 
-    stw_phys(cs->as, sm_state + 0x7e70, env->ldt.selector);
-    stq_phys(cs->as, sm_state + 0x7e78, env->ldt.base);
-    stl_phys(cs->as, sm_state + 0x7e74, env->ldt.limit);
-    stw_phys(cs->as, sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
+    x86_stw_phys(cs, sm_state + 0x7e70, env->ldt.selector);
+    x86_stq_phys(cs, sm_state + 0x7e78, env->ldt.base);
+    x86_stl_phys(cs, sm_state + 0x7e74, env->ldt.limit);
+    x86_stw_phys(cs, sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
 
-    stq_phys(cs->as, sm_state + 0x7e88, env->idt.base);
-    stl_phys(cs->as, sm_state + 0x7e84, env->idt.limit);
+    x86_stq_phys(cs, sm_state + 0x7e88, env->idt.base);
+    x86_stl_phys(cs, sm_state + 0x7e84, env->idt.limit);
 
-    stw_phys(cs->as, sm_state + 0x7e90, env->tr.selector);
-    stq_phys(cs->as, sm_state + 0x7e98, env->tr.base);
-    stl_phys(cs->as, sm_state + 0x7e94, env->tr.limit);
-    stw_phys(cs->as, sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
+    x86_stw_phys(cs, sm_state + 0x7e90, env->tr.selector);
+    x86_stq_phys(cs, sm_state + 0x7e98, env->tr.base);
+    x86_stl_phys(cs, sm_state + 0x7e94, env->tr.limit);
+    x86_stw_phys(cs, sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
 
-    stq_phys(cs->as, sm_state + 0x7ed0, env->efer);
+    x86_stq_phys(cs, sm_state + 0x7ed0, env->efer);
 
-    stq_phys(cs->as, sm_state + 0x7ff8, env->regs[R_EAX]);
-    stq_phys(cs->as, sm_state + 0x7ff0, env->regs[R_ECX]);
-    stq_phys(cs->as, sm_state + 0x7fe8, env->regs[R_EDX]);
-    stq_phys(cs->as, sm_state + 0x7fe0, env->regs[R_EBX]);
-    stq_phys(cs->as, sm_state + 0x7fd8, env->regs[R_ESP]);
-    stq_phys(cs->as, sm_state + 0x7fd0, env->regs[R_EBP]);
-    stq_phys(cs->as, sm_state + 0x7fc8, env->regs[R_ESI]);
-    stq_phys(cs->as, sm_state + 0x7fc0, env->regs[R_EDI]);
+    x86_stq_phys(cs, sm_state + 0x7ff8, env->regs[R_EAX]);
+    x86_stq_phys(cs, sm_state + 0x7ff0, env->regs[R_ECX]);
+    x86_stq_phys(cs, sm_state + 0x7fe8, env->regs[R_EDX]);
+    x86_stq_phys(cs, sm_state + 0x7fe0, env->regs[R_EBX]);
+    x86_stq_phys(cs, sm_state + 0x7fd8, env->regs[R_ESP]);
+    x86_stq_phys(cs, sm_state + 0x7fd0, env->regs[R_EBP]);
+    x86_stq_phys(cs, sm_state + 0x7fc8, env->regs[R_ESI]);
+    x86_stq_phys(cs, sm_state + 0x7fc0, env->regs[R_EDI]);
     for (i = 8; i < 16; i++) {
-        stq_phys(cs->as, sm_state + 0x7ff8 - i * 8, env->regs[i]);
+        x86_stq_phys(cs, sm_state + 0x7ff8 - i * 8, env->regs[i]);
     }
-    stq_phys(cs->as, sm_state + 0x7f78, env->eip);
-    stl_phys(cs->as, sm_state + 0x7f70, cpu_compute_eflags(env));
-    stl_phys(cs->as, sm_state + 0x7f68, env->dr[6]);
-    stl_phys(cs->as, sm_state + 0x7f60, env->dr[7]);
+    x86_stq_phys(cs, sm_state + 0x7f78, env->eip);
+    x86_stl_phys(cs, sm_state + 0x7f70, cpu_compute_eflags(env));
+    x86_stl_phys(cs, sm_state + 0x7f68, env->dr[6]);
+    x86_stl_phys(cs, sm_state + 0x7f60, env->dr[7]);
 
-    stl_phys(cs->as, sm_state + 0x7f48, env->cr[4]);
-    stq_phys(cs->as, sm_state + 0x7f50, env->cr[3]);
-    stl_phys(cs->as, sm_state + 0x7f58, env->cr[0]);
+    x86_stl_phys(cs, sm_state + 0x7f48, env->cr[4]);
+    x86_stq_phys(cs, sm_state + 0x7f50, env->cr[3]);
+    x86_stl_phys(cs, sm_state + 0x7f58, env->cr[0]);
 
-    stl_phys(cs->as, sm_state + 0x7efc, SMM_REVISION_ID);
-    stl_phys(cs->as, sm_state + 0x7f00, env->smbase);
+    x86_stl_phys(cs, sm_state + 0x7efc, SMM_REVISION_ID);
+    x86_stl_phys(cs, sm_state + 0x7f00, env->smbase);
 #else
-    stl_phys(cs->as, sm_state + 0x7ffc, env->cr[0]);
-    stl_phys(cs->as, sm_state + 0x7ff8, env->cr[3]);
-    stl_phys(cs->as, sm_state + 0x7ff4, cpu_compute_eflags(env));
-    stl_phys(cs->as, sm_state + 0x7ff0, env->eip);
-    stl_phys(cs->as, sm_state + 0x7fec, env->regs[R_EDI]);
-    stl_phys(cs->as, sm_state + 0x7fe8, env->regs[R_ESI]);
-    stl_phys(cs->as, sm_state + 0x7fe4, env->regs[R_EBP]);
-    stl_phys(cs->as, sm_state + 0x7fe0, env->regs[R_ESP]);
-    stl_phys(cs->as, sm_state + 0x7fdc, env->regs[R_EBX]);
-    stl_phys(cs->as, sm_state + 0x7fd8, env->regs[R_EDX]);
-    stl_phys(cs->as, sm_state + 0x7fd4, env->regs[R_ECX]);
-    stl_phys(cs->as, sm_state + 0x7fd0, env->regs[R_EAX]);
-    stl_phys(cs->as, sm_state + 0x7fcc, env->dr[6]);
-    stl_phys(cs->as, sm_state + 0x7fc8, env->dr[7]);
-
-    stl_phys(cs->as, sm_state + 0x7fc4, env->tr.selector);
-    stl_phys(cs->as, sm_state + 0x7f64, env->tr.base);
-    stl_phys(cs->as, sm_state + 0x7f60, env->tr.limit);
-    stl_phys(cs->as, sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
-
-    stl_phys(cs->as, sm_state + 0x7fc0, env->ldt.selector);
-    stl_phys(cs->as, sm_state + 0x7f80, env->ldt.base);
-    stl_phys(cs->as, sm_state + 0x7f7c, env->ldt.limit);
-    stl_phys(cs->as, sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
-
-    stl_phys(cs->as, sm_state + 0x7f74, env->gdt.base);
-    stl_phys(cs->as, sm_state + 0x7f70, env->gdt.limit);
-
-    stl_phys(cs->as, sm_state + 0x7f58, env->idt.base);
-    stl_phys(cs->as, sm_state + 0x7f54, env->idt.limit);
+    x86_stl_phys(cs, sm_state + 0x7ffc, env->cr[0]);
+    x86_stl_phys(cs, sm_state + 0x7ff8, env->cr[3]);
+    x86_stl_phys(cs, sm_state + 0x7ff4, cpu_compute_eflags(env));
+    x86_stl_phys(cs, sm_state + 0x7ff0, env->eip);
+    x86_stl_phys(cs, sm_state + 0x7fec, env->regs[R_EDI]);
+    x86_stl_phys(cs, sm_state + 0x7fe8, env->regs[R_ESI]);
+    x86_stl_phys(cs, sm_state + 0x7fe4, env->regs[R_EBP]);
+    x86_stl_phys(cs, sm_state + 0x7fe0, env->regs[R_ESP]);
+    x86_stl_phys(cs, sm_state + 0x7fdc, env->regs[R_EBX]);
+    x86_stl_phys(cs, sm_state + 0x7fd8, env->regs[R_EDX]);
+    x86_stl_phys(cs, sm_state + 0x7fd4, env->regs[R_ECX]);
+    x86_stl_phys(cs, sm_state + 0x7fd0, env->regs[R_EAX]);
+    x86_stl_phys(cs, sm_state + 0x7fcc, env->dr[6]);
+    x86_stl_phys(cs, sm_state + 0x7fc8, env->dr[7]);
+
+    x86_stl_phys(cs, sm_state + 0x7fc4, env->tr.selector);
+    x86_stl_phys(cs, sm_state + 0x7f64, env->tr.base);
+    x86_stl_phys(cs, sm_state + 0x7f60, env->tr.limit);
+    x86_stl_phys(cs, sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
+
+    x86_stl_phys(cs, sm_state + 0x7fc0, env->ldt.selector);
+    x86_stl_phys(cs, sm_state + 0x7f80, env->ldt.base);
+    x86_stl_phys(cs, sm_state + 0x7f7c, env->ldt.limit);
+    x86_stl_phys(cs, sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
+
+    x86_stl_phys(cs, sm_state + 0x7f74, env->gdt.base);
+    x86_stl_phys(cs, sm_state + 0x7f70, env->gdt.limit);
+
+    x86_stl_phys(cs, sm_state + 0x7f58, env->idt.base);
+    x86_stl_phys(cs, sm_state + 0x7f54, env->idt.limit);
 
     for (i = 0; i < 6; i++) {
         dt = &env->segs[i];
@@ -145,15 +145,15 @@ void do_smm_enter(X86CPU *cpu)
         } else {
             offset = 0x7f2c + (i - 3) * 12;
         }
-        stl_phys(cs->as, sm_state + 0x7fa8 + i * 4, dt->selector);
-        stl_phys(cs->as, sm_state + offset + 8, dt->base);
-        stl_phys(cs->as, sm_state + offset + 4, dt->limit);
-        stl_phys(cs->as, sm_state + offset, (dt->flags >> 8) & 0xf0ff);
+        x86_stl_phys(cs, sm_state + 0x7fa8 + i * 4, dt->selector);
+        x86_stl_phys(cs, sm_state + offset + 8, dt->base);
+        x86_stl_phys(cs, sm_state + offset + 4, dt->limit);
+        x86_stl_phys(cs, sm_state + offset, (dt->flags >> 8) & 0xf0ff);
     }
-    stl_phys(cs->as, sm_state + 0x7f14, env->cr[4]);
+    x86_stl_phys(cs, sm_state + 0x7f14, env->cr[4]);
 
-    stl_phys(cs->as, sm_state + 0x7efc, SMM_REVISION_ID);
-    stl_phys(cs->as, sm_state + 0x7ef8, env->smbase);
+    x86_stl_phys(cs, sm_state + 0x7efc, SMM_REVISION_ID);
+    x86_stl_phys(cs, sm_state + 0x7ef8, env->smbase);
 #endif
     /* init SMM cpu state */
 
@@ -200,91 +200,91 @@ void helper_rsm(CPUX86State *env)
 
     sm_state = env->smbase + 0x8000;
 #ifdef TARGET_X86_64
-    cpu_load_efer(env, ldq_phys(cs->as, sm_state + 0x7ed0));
-
-    env->gdt.base = ldq_phys(cs->as, sm_state + 0x7e68);
-    env->gdt.limit = ldl_phys(cs->as, sm_state + 0x7e64);
-
-    env->ldt.selector = lduw_phys(cs->as, sm_state + 0x7e70);
-    env->ldt.base = ldq_phys(cs->as, sm_state + 0x7e78);
-    env->ldt.limit = ldl_phys(cs->as, sm_state + 0x7e74);
-    env->ldt.flags = (lduw_phys(cs->as, sm_state + 0x7e72) & 0xf0ff) << 8;
-
-    env->idt.base = ldq_phys(cs->as, sm_state + 0x7e88);
-    env->idt.limit = ldl_phys(cs->as, sm_state + 0x7e84);
-
-    env->tr.selector = lduw_phys(cs->as, sm_state + 0x7e90);
-    env->tr.base = ldq_phys(cs->as, sm_state + 0x7e98);
-    env->tr.limit = ldl_phys(cs->as, sm_state + 0x7e94);
-    env->tr.flags = (lduw_phys(cs->as, sm_state + 0x7e92) & 0xf0ff) << 8;
-
-    env->regs[R_EAX] = ldq_phys(cs->as, sm_state + 0x7ff8);
-    env->regs[R_ECX] = ldq_phys(cs->as, sm_state + 0x7ff0);
-    env->regs[R_EDX] = ldq_phys(cs->as, sm_state + 0x7fe8);
-    env->regs[R_EBX] = ldq_phys(cs->as, sm_state + 0x7fe0);
-    env->regs[R_ESP] = ldq_phys(cs->as, sm_state + 0x7fd8);
-    env->regs[R_EBP] = ldq_phys(cs->as, sm_state + 0x7fd0);
-    env->regs[R_ESI] = ldq_phys(cs->as, sm_state + 0x7fc8);
-    env->regs[R_EDI] = ldq_phys(cs->as, sm_state + 0x7fc0);
+    cpu_load_efer(env, x86_ldq_phys(cs, sm_state + 0x7ed0));
+
+    env->gdt.base = x86_ldq_phys(cs, sm_state + 0x7e68);
+    env->gdt.limit = x86_ldl_phys(cs, sm_state + 0x7e64);
+
+    env->ldt.selector = x86_lduw_phys(cs, sm_state + 0x7e70);
+    env->ldt.base = x86_ldq_phys(cs, sm_state + 0x7e78);
+    env->ldt.limit = x86_ldl_phys(cs, sm_state + 0x7e74);
+    env->ldt.flags = (x86_lduw_phys(cs, sm_state + 0x7e72) & 0xf0ff) << 8;
+
+    env->idt.base = x86_ldq_phys(cs, sm_state + 0x7e88);
+    env->idt.limit = x86_ldl_phys(cs, sm_state + 0x7e84);
+
+    env->tr.selector = x86_lduw_phys(cs, sm_state + 0x7e90);
+    env->tr.base = x86_ldq_phys(cs, sm_state + 0x7e98);
+    env->tr.limit = x86_ldl_phys(cs, sm_state + 0x7e94);
+    env->tr.flags = (x86_lduw_phys(cs, sm_state + 0x7e92) & 0xf0ff) << 8;
+
+    env->regs[R_EAX] = x86_ldq_phys(cs, sm_state + 0x7ff8);
+    env->regs[R_ECX] = x86_ldq_phys(cs, sm_state + 0x7ff0);
+    env->regs[R_EDX] = x86_ldq_phys(cs, sm_state + 0x7fe8);
+    env->regs[R_EBX] = x86_ldq_phys(cs, sm_state + 0x7fe0);
+    env->regs[R_ESP] = x86_ldq_phys(cs, sm_state + 0x7fd8);
+    env->regs[R_EBP] = x86_ldq_phys(cs, sm_state + 0x7fd0);
+    env->regs[R_ESI] = x86_ldq_phys(cs, sm_state + 0x7fc8);
+    env->regs[R_EDI] = x86_ldq_phys(cs, sm_state + 0x7fc0);
     for (i = 8; i < 16; i++) {
-        env->regs[i] = ldq_phys(cs->as, sm_state + 0x7ff8 - i * 8);
+        env->regs[i] = x86_ldq_phys(cs, sm_state + 0x7ff8 - i * 8);
     }
-    env->eip = ldq_phys(cs->as, sm_state + 0x7f78);
-    cpu_load_eflags(env, ldl_phys(cs->as, sm_state + 0x7f70),
+    env->eip = x86_ldq_phys(cs, sm_state + 0x7f78);
+    cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7f70),
                     ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
-    env->dr[6] = ldl_phys(cs->as, sm_state + 0x7f68);
-    env->dr[7] = ldl_phys(cs->as, sm_state + 0x7f60);
+    env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7f68);
+    env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7f60);
 
-    cpu_x86_update_cr4(env, ldl_phys(cs->as, sm_state + 0x7f48));
-    cpu_x86_update_cr3(env, ldq_phys(cs->as, sm_state + 0x7f50));
-    cpu_x86_update_cr0(env, ldl_phys(cs->as, sm_state + 0x7f58));
+    cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f48));
+    cpu_x86_update_cr3(env, x86_ldq_phys(cs, sm_state + 0x7f50));
+    cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7f58));
 
     for (i = 0; i < 6; i++) {
         offset = 0x7e00 + i * 16;
         cpu_x86_load_seg_cache(env, i,
-                               lduw_phys(cs->as, sm_state + offset),
-                               ldq_phys(cs->as, sm_state + offset + 8),
-                               ldl_phys(cs->as, sm_state + offset + 4),
-                               (lduw_phys(cs->as, sm_state + offset + 2) &
+                               x86_lduw_phys(cs, sm_state + offset),
+                               x86_ldq_phys(cs, sm_state + offset + 8),
+                               x86_ldl_phys(cs, sm_state + offset + 4),
+                               (x86_lduw_phys(cs, sm_state + offset + 2) &
                                 0xf0ff) << 8);
     }
 
-    val = ldl_phys(cs->as, sm_state + 0x7efc); /* revision ID */
+    val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
     if (val & 0x20000) {
-        env->smbase = ldl_phys(cs->as, sm_state + 0x7f00) & ~0x7fff;
+        env->smbase = x86_ldl_phys(cs, sm_state + 0x7f00) & ~0x7fff;
     }
 #else
-    cpu_x86_update_cr0(env, ldl_phys(cs->as, sm_state + 0x7ffc));
-    cpu_x86_update_cr3(env, ldl_phys(cs->as, sm_state + 0x7ff8));
-    cpu_load_eflags(env, ldl_phys(cs->as, sm_state + 0x7ff4),
+    cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7ffc));
+    cpu_x86_update_cr3(env, x86_ldl_phys(cs, sm_state + 0x7ff8));
+    cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7ff4),
                     ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
-    env->eip = ldl_phys(cs->as, sm_state + 0x7ff0);
-    env->regs[R_EDI] = ldl_phys(cs->as, sm_state + 0x7fec);
-    env->regs[R_ESI] = ldl_phys(cs->as, sm_state + 0x7fe8);
-    env->regs[R_EBP] = ldl_phys(cs->as, sm_state + 0x7fe4);
-    env->regs[R_ESP] = ldl_phys(cs->as, sm_state + 0x7fe0);
-    env->regs[R_EBX] = ldl_phys(cs->as, sm_state + 0x7fdc);
-    env->regs[R_EDX] = ldl_phys(cs->as, sm_state + 0x7fd8);
-    env->regs[R_ECX] = ldl_phys(cs->as, sm_state + 0x7fd4);
-    env->regs[R_EAX] = ldl_phys(cs->as, sm_state + 0x7fd0);
-    env->dr[6] = ldl_phys(cs->as, sm_state + 0x7fcc);
-    env->dr[7] = ldl_phys(cs->as, sm_state + 0x7fc8);
-
-    env->tr.selector = ldl_phys(cs->as, sm_state + 0x7fc4) & 0xffff;
-    env->tr.base = ldl_phys(cs->as, sm_state + 0x7f64);
-    env->tr.limit = ldl_phys(cs->as, sm_state + 0x7f60);
-    env->tr.flags = (ldl_phys(cs->as, sm_state + 0x7f5c) & 0xf0ff) << 8;
-
-    env->ldt.selector = ldl_phys(cs->as, sm_state + 0x7fc0) & 0xffff;
-    env->ldt.base = ldl_phys(cs->as, sm_state + 0x7f80);
-    env->ldt.limit = ldl_phys(cs->as, sm_state + 0x7f7c);
-    env->ldt.flags = (ldl_phys(cs->as, sm_state + 0x7f78) & 0xf0ff) << 8;
-
-    env->gdt.base = ldl_phys(cs->as, sm_state + 0x7f74);
-    env->gdt.limit = ldl_phys(cs->as, sm_state + 0x7f70);
-
-    env->idt.base = ldl_phys(cs->as, sm_state + 0x7f58);
-    env->idt.limit = ldl_phys(cs->as, sm_state + 0x7f54);
+    env->eip = x86_ldl_phys(cs, sm_state + 0x7ff0);
+    env->regs[R_EDI] = x86_ldl_phys(cs, sm_state + 0x7fec);
+    env->regs[R_ESI] = x86_ldl_phys(cs, sm_state + 0x7fe8);
+    env->regs[R_EBP] = x86_ldl_phys(cs, sm_state + 0x7fe4);
+    env->regs[R_ESP] = x86_ldl_phys(cs, sm_state + 0x7fe0);
+    env->regs[R_EBX] = x86_ldl_phys(cs, sm_state + 0x7fdc);
+    env->regs[R_EDX] = x86_ldl_phys(cs, sm_state + 0x7fd8);
+    env->regs[R_ECX] = x86_ldl_phys(cs, sm_state + 0x7fd4);
+    env->regs[R_EAX] = x86_ldl_phys(cs, sm_state + 0x7fd0);
+    env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7fcc);
+    env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7fc8);
+
+    env->tr.selector = x86_ldl_phys(cs, sm_state + 0x7fc4) & 0xffff;
+    env->tr.base = x86_ldl_phys(cs, sm_state + 0x7f64);
+    env->tr.limit = x86_ldl_phys(cs, sm_state + 0x7f60);
+    env->tr.flags = (x86_ldl_phys(cs, sm_state + 0x7f5c) & 0xf0ff) << 8;
+
+    env->ldt.selector = x86_ldl_phys(cs, sm_state + 0x7fc0) & 0xffff;
+    env->ldt.base = x86_ldl_phys(cs, sm_state + 0x7f80);
+    env->ldt.limit = x86_ldl_phys(cs, sm_state + 0x7f7c);
+    env->ldt.flags = (x86_ldl_phys(cs, sm_state + 0x7f78) & 0xf0ff) << 8;
+
+    env->gdt.base = x86_ldl_phys(cs, sm_state + 0x7f74);
+    env->gdt.limit = x86_ldl_phys(cs, sm_state + 0x7f70);
+
+    env->idt.base = x86_ldl_phys(cs, sm_state + 0x7f58);
+    env->idt.limit = x86_ldl_phys(cs, sm_state + 0x7f54);
 
     for (i = 0; i < 6; i++) {
         if (i < 3) {
@@ -293,18 +293,18 @@ void helper_rsm(CPUX86State *env)
             offset = 0x7f2c + (i - 3) * 12;
         }
         cpu_x86_load_seg_cache(env, i,
-                               ldl_phys(cs->as,
+                               x86_ldl_phys(cs,
                                         sm_state + 0x7fa8 + i * 4) & 0xffff,
-                               ldl_phys(cs->as, sm_state + offset + 8),
-                               ldl_phys(cs->as, sm_state + offset + 4),
-                               (ldl_phys(cs->as,
+                               x86_ldl_phys(cs, sm_state + offset + 8),
+                               x86_ldl_phys(cs, sm_state + offset + 4),
+                               (x86_ldl_phys(cs,
                                          sm_state + offset) & 0xf0ff) << 8);
     }
-    cpu_x86_update_cr4(env, ldl_phys(cs->as, sm_state + 0x7f14));
+    cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f14));
 
-    val = ldl_phys(cs->as, sm_state + 0x7efc); /* revision ID */
+    val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
     if (val & 0x20000) {
-        env->smbase = ldl_phys(cs->as, sm_state + 0x7ef8) & ~0x7fff;
+        env->smbase = x86_ldl_phys(cs, sm_state + 0x7ef8) & ~0x7fff;
     }
 #endif
     env->hflags &= ~HF_SMM_MASK;
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 429d029..f1fabf5 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -87,13 +87,13 @@ static inline void svm_save_seg(CPUX86State *env, hwaddr addr,
 {
     CPUState *cs = CPU(x86_env_get_cpu(env));
 
-    stw_phys(cs->as, addr + offsetof(struct vmcb_seg, selector),
+    x86_stw_phys(cs, addr + offsetof(struct vmcb_seg, selector),
              sc->selector);
-    stq_phys(cs->as, addr + offsetof(struct vmcb_seg, base),
+    x86_stq_phys(cs, addr + offsetof(struct vmcb_seg, base),
              sc->base);
-    stl_phys(cs->as, addr + offsetof(struct vmcb_seg, limit),
+    x86_stl_phys(cs, addr + offsetof(struct vmcb_seg, limit),
              sc->limit);
-    stw_phys(cs->as, addr + offsetof(struct vmcb_seg, attrib),
+    x86_stw_phys(cs, addr + offsetof(struct vmcb_seg, attrib),
              ((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00));
 }
 
@@ -103,11 +103,11 @@ static inline void svm_load_seg(CPUX86State *env, hwaddr addr,
     CPUState *cs = CPU(x86_env_get_cpu(env));
     unsigned int flags;
 
-    sc->selector = lduw_phys(cs->as,
+    sc->selector = x86_lduw_phys(cs,
                              addr + offsetof(struct vmcb_seg, selector));
-    sc->base = ldq_phys(cs->as, addr + offsetof(struct vmcb_seg, base));
-    sc->limit = ldl_phys(cs->as, addr + offsetof(struct vmcb_seg, limit));
-    flags = lduw_phys(cs->as, addr + offsetof(struct vmcb_seg, attrib));
+    sc->base = x86_ldq_phys(cs, addr + offsetof(struct vmcb_seg, base));
+    sc->limit = x86_ldl_phys(cs, addr + offsetof(struct vmcb_seg, limit));
+    flags = x86_lduw_phys(cs, addr + offsetof(struct vmcb_seg, attrib));
     sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
 }
 
@@ -141,32 +141,32 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     env->vm_vmcb = addr;
 
     /* save the current CPU state in the hsave page */
-    stq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb, save.gdtr.base),
+    x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.gdtr.base),
              env->gdt.base);
-    stl_phys(cs->as, env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit),
+    x86_stl_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit),
              env->gdt.limit);
 
-    stq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb, save.idtr.base),
+    x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.idtr.base),
              env->idt.base);
-    stl_phys(cs->as, env->vm_hsave + offsetof(struct vmcb, save.idtr.limit),
+    x86_stl_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.idtr.limit),
              env->idt.limit);
 
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.cr0), env->cr[0]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]);
 
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.efer), env->efer);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.rflags),
              cpu_compute_eflags(env));
 
@@ -179,30 +179,30 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     svm_save_seg(env, env->vm_hsave + offsetof(struct vmcb, save.ds),
                  &env->segs[R_DS]);
 
-    stq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb, save.rip),
+    x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.rip),
              env->eip + next_eip_addend);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
 
     /* load the interception bitmaps so we do not need to access the
        vmcb in svm mode */
-    env->intercept = ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    env->intercept = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                       control.intercept));
-    env->intercept_cr_read = lduw_phys(cs->as, env->vm_vmcb +
+    env->intercept_cr_read = x86_lduw_phys(cs, env->vm_vmcb +
                                        offsetof(struct vmcb,
                                                 control.intercept_cr_read));
-    env->intercept_cr_write = lduw_phys(cs->as, env->vm_vmcb +
+    env->intercept_cr_write = x86_lduw_phys(cs, env->vm_vmcb +
                                         offsetof(struct vmcb,
                                                  control.intercept_cr_write));
-    env->intercept_dr_read = lduw_phys(cs->as, env->vm_vmcb +
+    env->intercept_dr_read = x86_lduw_phys(cs, env->vm_vmcb +
                                        offsetof(struct vmcb,
                                                 control.intercept_dr_read));
-    env->intercept_dr_write = lduw_phys(cs->as, env->vm_vmcb +
+    env->intercept_dr_write = x86_lduw_phys(cs, env->vm_vmcb +
                                         offsetof(struct vmcb,
                                                  control.intercept_dr_write));
-    env->intercept_exceptions = ldl_phys(cs->as, env->vm_vmcb +
+    env->intercept_exceptions = x86_ldl_phys(cs, env->vm_vmcb +
                                          offsetof(struct vmcb,
                                                   control.intercept_exceptions
                                                   ));
@@ -210,35 +210,35 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     /* enable intercepts */
     env->hflags |= HF_SVMI_MASK;
 
-    env->tsc_offset = ldq_phys(cs->as, env->vm_vmcb +
+    env->tsc_offset = x86_ldq_phys(cs, env->vm_vmcb +
                                offsetof(struct vmcb, control.tsc_offset));
 
-    env->gdt.base  = ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    env->gdt.base  = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                       save.gdtr.base));
-    env->gdt.limit = ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    env->gdt.limit = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                       save.gdtr.limit));
 
-    env->idt.base  = ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    env->idt.base  = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                       save.idtr.base));
-    env->idt.limit = ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    env->idt.limit = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                       save.idtr.limit));
 
     /* clear exit_info_2 so we behave like the real hardware */
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
 
-    cpu_x86_update_cr0(env, ldq_phys(cs->as,
+    cpu_x86_update_cr0(env, x86_ldq_phys(cs,
                                      env->vm_vmcb + offsetof(struct vmcb,
                                                              save.cr0)));
-    cpu_x86_update_cr4(env, ldq_phys(cs->as,
+    cpu_x86_update_cr4(env, x86_ldq_phys(cs,
                                      env->vm_vmcb + offsetof(struct vmcb,
                                                              save.cr4)));
-    cpu_x86_update_cr3(env, ldq_phys(cs->as,
+    cpu_x86_update_cr3(env, x86_ldq_phys(cs,
                                      env->vm_vmcb + offsetof(struct vmcb,
                                                              save.cr3)));
-    env->cr[2] = ldq_phys(cs->as,
+    env->cr[2] = x86_ldq_phys(cs,
                           env->vm_vmcb + offsetof(struct vmcb, save.cr2));
-    int_ctl = ldl_phys(cs->as,
+    int_ctl = x86_ldl_phys(cs,
                        env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
     env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
     if (int_ctl & V_INTR_MASKING_MASK) {
@@ -250,10 +250,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     }
 
     cpu_load_efer(env,
-                  ldq_phys(cs->as,
+                  x86_ldq_phys(cs,
                            env->vm_vmcb + offsetof(struct vmcb, save.efer)));
     env->eflags = 0;
-    cpu_load_eflags(env, ldq_phys(cs->as,
+    cpu_load_eflags(env, x86_ldq_phys(cs,
                                   env->vm_vmcb + offsetof(struct vmcb,
                                                           save.rflags)),
                     ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
@@ -267,21 +267,21 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
                        R_DS);
 
-    env->eip = ldq_phys(cs->as,
+    env->eip = x86_ldq_phys(cs,
                         env->vm_vmcb + offsetof(struct vmcb, save.rip));
 
-    env->regs[R_ESP] = ldq_phys(cs->as,
+    env->regs[R_ESP] = x86_ldq_phys(cs,
                                 env->vm_vmcb + offsetof(struct vmcb, save.rsp));
-    env->regs[R_EAX] = ldq_phys(cs->as,
+    env->regs[R_EAX] = x86_ldq_phys(cs,
                                 env->vm_vmcb + offsetof(struct vmcb, save.rax));
-    env->dr[7] = ldq_phys(cs->as,
+    env->dr[7] = x86_ldq_phys(cs,
                           env->vm_vmcb + offsetof(struct vmcb, save.dr7));
-    env->dr[6] = ldq_phys(cs->as,
+    env->dr[6] = x86_ldq_phys(cs,
                           env->vm_vmcb + offsetof(struct vmcb, save.dr6));
 
     /* FIXME: guest state consistency checks */
 
-    switch (ldub_phys(cs->as,
+    switch (x86_ldub_phys(cs,
                       env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
     case TLB_CONTROL_DO_NOTHING:
         break;
@@ -300,12 +300,12 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     }
 
     /* maybe we need to inject an event */
-    event_inj = ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+    event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                  control.event_inj));
     if (event_inj & SVM_EVTINJ_VALID) {
         uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;
         uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;
-        uint32_t event_inj_err = ldl_phys(cs->as, env->vm_vmcb +
+        uint32_t event_inj_err = x86_ldl_phys(cs, env->vm_vmcb +
                                           offsetof(struct vmcb,
                                                    control.event_inj_err));
 
@@ -372,7 +372,7 @@ void helper_vmload(CPUX86State *env, int aflag)
 
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx
                   "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
-                  addr, ldq_phys(cs->as, addr + offsetof(struct vmcb,
+                  addr, x86_ldq_phys(cs, addr + offsetof(struct vmcb,
                                                           save.fs.base)),
                   env->segs[R_FS].base);
 
@@ -382,18 +382,18 @@ void helper_vmload(CPUX86State *env, int aflag)
     svm_load_seg(env, addr + offsetof(struct vmcb, save.ldtr), &env->ldt);
 
 #ifdef TARGET_X86_64
-    env->kernelgsbase = ldq_phys(cs->as, addr + offsetof(struct vmcb,
+    env->kernelgsbase = x86_ldq_phys(cs, addr + offsetof(struct vmcb,
                                                  save.kernel_gs_base));
-    env->lstar = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.lstar));
-    env->cstar = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.cstar));
-    env->fmask = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.sfmask));
+    env->lstar = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.lstar));
+    env->cstar = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.cstar));
+    env->fmask = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.sfmask));
 #endif
-    env->star = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.star));
-    env->sysenter_cs = ldq_phys(cs->as,
+    env->star = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.star));
+    env->sysenter_cs = x86_ldq_phys(cs,
                                 addr + offsetof(struct vmcb, save.sysenter_cs));
-    env->sysenter_esp = ldq_phys(cs->as, addr + offsetof(struct vmcb,
+    env->sysenter_esp = x86_ldq_phys(cs, addr + offsetof(struct vmcb,
                                                  save.sysenter_esp));
-    env->sysenter_eip = ldq_phys(cs->as, addr + offsetof(struct vmcb,
+    env->sysenter_eip = x86_ldq_phys(cs, addr + offsetof(struct vmcb,
                                                  save.sysenter_eip));
 }
 
@@ -412,7 +412,7 @@ void helper_vmsave(CPUX86State *env, int aflag)
 
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx
                   "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
-                  addr, ldq_phys(cs->as,
+                  addr, x86_ldq_phys(cs,
                                  addr + offsetof(struct vmcb, save.fs.base)),
                   env->segs[R_FS].base);
 
@@ -426,18 +426,18 @@ void helper_vmsave(CPUX86State *env, int aflag)
                  &env->ldt);
 
 #ifdef TARGET_X86_64
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.kernel_gs_base),
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.kernel_gs_base),
              env->kernelgsbase);
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.lstar), env->lstar);
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.cstar), env->cstar);
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.sfmask), env->fmask);
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.lstar), env->lstar);
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.cstar), env->cstar);
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.sfmask), env->fmask);
 #endif
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.star), env->star);
-    stq_phys(cs->as,
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.star), env->star);
+    x86_stq_phys(cs,
              addr + offsetof(struct vmcb, save.sysenter_cs), env->sysenter_cs);
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.sysenter_esp),
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.sysenter_esp),
              env->sysenter_esp);
-    stq_phys(cs->as, addr + offsetof(struct vmcb, save.sysenter_eip),
+    x86_stq_phys(cs, addr + offsetof(struct vmcb, save.sysenter_eip),
              env->sysenter_eip);
 }
 
@@ -515,7 +515,7 @@ void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
     case SVM_EXIT_MSR:
         if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
             /* FIXME: this should be read in at vmrun (faster this way?) */
-            uint64_t addr = ldq_phys(cs->as, env->vm_vmcb +
+            uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
                                      offsetof(struct vmcb,
                                               control.msrpm_base_pa));
             uint32_t t0, t1;
@@ -541,7 +541,7 @@ void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
                 t1 = 0;
                 break;
             }
-            if (ldub_phys(cs->as, addr + t1) & ((1 << param) << t0)) {
+            if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) {
                 helper_vmexit(env, type, param);
             }
         }
@@ -567,13 +567,13 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
 
     if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) {
         /* FIXME: this should be read in at vmrun (faster this way?) */
-        uint64_t addr = ldq_phys(cs->as, env->vm_vmcb +
+        uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
                                  offsetof(struct vmcb, control.iopm_base_pa));
         uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
 
-        if (lduw_phys(cs->as, addr + port / 8) & (mask << (port & 7))) {
+        if (x86_lduw_phys(cs, addr + port / 8) & (mask << (port & 7))) {
             /* next env->eip */
-            stq_phys(cs->as,
+            x86_stq_phys(cs,
                      env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
                      env->eip + next_eip_addend);
             helper_vmexit(env, SVM_EXIT_IOIO, param | (port << 16));
@@ -590,17 +590,17 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
     qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
                   PRIx64 ", " TARGET_FMT_lx ")!\n",
                   exit_code, exit_info_1,
-                  ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+                  x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                    control.exit_info_2)),
                   env->eip);
 
     if (env->hflags & HF_INHIBIT_IRQ_MASK) {
-        stl_phys(cs->as,
+        x86_stl_phys(cs,
                  env->vm_vmcb + offsetof(struct vmcb, control.int_state),
                  SVM_INTERRUPT_SHADOW_MASK);
         env->hflags &= ~HF_INHIBIT_IRQ_MASK;
     } else {
-        stl_phys(cs->as,
+        x86_stl_phys(cs,
                  env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0);
     }
 
@@ -614,50 +614,50 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
     svm_save_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
                  &env->segs[R_DS]);
 
-    stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base),
+    x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base),
              env->gdt.base);
-    stl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit),
+    x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit),
              env->gdt.limit);
 
-    stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.idtr.base),
+    x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.base),
              env->idt.base);
-    stl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit),
+    x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit),
              env->idt.limit);
 
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.efer), env->efer);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.cr0), env->cr[0]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.cr2), env->cr[2]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
 
-    int_ctl = ldl_phys(cs->as,
+    int_ctl = x86_ldl_phys(cs,
                        env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
     int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
     int_ctl |= env->v_tpr & V_TPR_MASK;
     if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
         int_ctl |= V_IRQ_MASK;
     }
-    stl_phys(cs->as,
+    x86_stl_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl);
 
-    stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
+    x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
              cpu_compute_eflags(env));
-    stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.rip),
+    x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rip),
              env->eip);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
-    stq_phys(cs->as,
+    x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]);
-    stb_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, save.cpl),
+    x86_stb_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cpl),
              env->hflags & HF_CPL_MASK);
 
     /* Reload the host state from vm_hsave */
@@ -668,32 +668,32 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
     cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
     env->tsc_offset = 0;
 
-    env->gdt.base  = ldq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
+    env->gdt.base  = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
                                                        save.gdtr.base));
-    env->gdt.limit = ldl_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
+    env->gdt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
                                                        save.gdtr.limit));
 
-    env->idt.base  = ldq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
+    env->idt.base  = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
                                                        save.idtr.base));
-    env->idt.limit = ldl_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
+    env->idt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
                                                        save.idtr.limit));
 
-    cpu_x86_update_cr0(env, ldq_phys(cs->as,
+    cpu_x86_update_cr0(env, x86_ldq_phys(cs,
                                      env->vm_hsave + offsetof(struct vmcb,
                                                               save.cr0)) |
                        CR0_PE_MASK);
-    cpu_x86_update_cr4(env, ldq_phys(cs->as,
+    cpu_x86_update_cr4(env, x86_ldq_phys(cs,
                                      env->vm_hsave + offsetof(struct vmcb,
                                                               save.cr4)));
-    cpu_x86_update_cr3(env, ldq_phys(cs->as,
+    cpu_x86_update_cr3(env, x86_ldq_phys(cs,
                                      env->vm_hsave + offsetof(struct vmcb,
                                                               save.cr3)));
     /* we need to set the efer after the crs so the hidden flags get
        set properly */
-    cpu_load_efer(env, ldq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
+    cpu_load_efer(env, x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
                                                          save.efer)));
     env->eflags = 0;
-    cpu_load_eflags(env, ldq_phys(cs->as,
+    cpu_load_eflags(env, x86_ldq_phys(cs,
                                   env->vm_hsave + offsetof(struct vmcb,
                                                            save.rflags)),
                     ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK |
@@ -708,33 +708,33 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
     svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.ds),
                        R_DS);
 
-    env->eip = ldq_phys(cs->as,
+    env->eip = x86_ldq_phys(cs,
                         env->vm_hsave + offsetof(struct vmcb, save.rip));
-    env->regs[R_ESP] = ldq_phys(cs->as, env->vm_hsave +
+    env->regs[R_ESP] = x86_ldq_phys(cs, env->vm_hsave +
                                 offsetof(struct vmcb, save.rsp));
-    env->regs[R_EAX] = ldq_phys(cs->as, env->vm_hsave +
+    env->regs[R_EAX] = x86_ldq_phys(cs, env->vm_hsave +
                                 offsetof(struct vmcb, save.rax));
 
-    env->dr[6] = ldq_phys(cs->as,
+    env->dr[6] = x86_ldq_phys(cs,
                           env->vm_hsave + offsetof(struct vmcb, save.dr6));
-    env->dr[7] = ldq_phys(cs->as,
+    env->dr[7] = x86_ldq_phys(cs,
                           env->vm_hsave + offsetof(struct vmcb, save.dr7));
 
     /* other setups */
-    stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, control.exit_code),
+    x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_code),
              exit_code);
-    stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1),
+    x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1),
              exit_info_1);
 
-    stl_phys(cs->as,
+    x86_stl_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info),
-             ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+             x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                               control.event_inj)));
-    stl_phys(cs->as,
+    x86_stl_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err),
-             ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
+             x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                               control.event_inj_err)));
-    stl_phys(cs->as,
+    x86_stl_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0);
 
     env->hflags2 &= ~HF2_GIF_MASK;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 04/31] target-i386: Use correct memory attributes for ioport accesses
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (2 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 03/31] target-i386: Use correct memory attributes for memory accesses Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 05/31] target-i386: mask NMIs on entry to SMM Paolo Bonzini
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

In order to do this, stop using the cpu_in*/out* helpers, and instead
access address_space_io directly.

cpu_in* and cpu_out* remain for usage in the monitor, in qtest, and
in Xen.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/Makefile.objs |  2 --
 target-i386/helper.h      | 12 +++++-----
 target-i386/ioport-user.c | 60 -----------------------------------------------
 target-i386/misc_helper.c | 59 ++++++++++++++++++++++++++++++++++++----------
 target-i386/translate.c   | 12 +++++-----
 5 files changed, 58 insertions(+), 87 deletions(-)
 delete mode 100644 target-i386/ioport-user.c

diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 027b94e..7a1df2c 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -5,5 +5,3 @@ obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
 obj-$(CONFIG_KVM) += kvm.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-$(CONFIG_LINUX_USER) += ioport-user.o
-obj-$(CONFIG_BSD_USER) += ioport-user.o
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 8eb0145..74308f4 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -86,12 +86,12 @@ DEF_HELPER_1(wrmsr, void, env)
 DEF_HELPER_2(check_iob, void, env, i32)
 DEF_HELPER_2(check_iow, void, env, i32)
 DEF_HELPER_2(check_iol, void, env, i32)
-DEF_HELPER_2(outb, void, i32, i32)
-DEF_HELPER_1(inb, tl, i32)
-DEF_HELPER_2(outw, void, i32, i32)
-DEF_HELPER_1(inw, tl, i32)
-DEF_HELPER_2(outl, void, i32, i32)
-DEF_HELPER_1(inl, tl, i32)
+DEF_HELPER_3(outb, void, env, i32, i32)
+DEF_HELPER_2(inb, tl, env, i32)
+DEF_HELPER_3(outw, void, env, i32, i32)
+DEF_HELPER_2(inw, tl, env, i32)
+DEF_HELPER_3(outl, void, env, i32, i32)
+DEF_HELPER_2(inl, tl, env, i32)
 
 DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64)
 DEF_HELPER_3(vmexit, void, env, i32, i64)
diff --git a/target-i386/ioport-user.c b/target-i386/ioport-user.c
deleted file mode 100644
index f7636e0..0000000
--- a/target-i386/ioport-user.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  qemu user ioport functions
- *
- *  Copyright (c) 2003-2008 Fabrice Bellard
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-
-#include "qemu.h"
-#include "qemu-common.h"
-#include "exec/ioport.h"
-
-void cpu_outb(pio_addr_t addr, uint8_t val)
-{
-    fprintf(stderr, "outb: port=0x%04"FMT_pioaddr", data=%02"PRIx8"\n",
-            addr, val);
-}
-
-void cpu_outw(pio_addr_t addr, uint16_t val)
-{
-    fprintf(stderr, "outw: port=0x%04"FMT_pioaddr", data=%04"PRIx16"\n",
-            addr, val);
-}
-
-void cpu_outl(pio_addr_t addr, uint32_t val)
-{
-    fprintf(stderr, "outl: port=0x%04"FMT_pioaddr", data=%08"PRIx32"\n",
-            addr, val);
-}
-
-uint8_t cpu_inb(pio_addr_t addr)
-{
-    fprintf(stderr, "inb: port=0x%04"FMT_pioaddr"\n", addr);
-    return 0;
-}
-
-uint16_t cpu_inw(pio_addr_t addr)
-{
-    fprintf(stderr, "inw: port=0x%04"FMT_pioaddr"\n", addr);
-    return 0;
-}
-
-uint32_t cpu_inl(pio_addr_t addr)
-{
-    fprintf(stderr, "inl: port=0x%04"FMT_pioaddr"\n", addr);
-    return 0;
-}
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 4aaf1e4..52c5d65 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -18,38 +18,71 @@
  */
 
 #include "cpu.h"
-#include "exec/ioport.h"
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
+#include "exec/address-spaces.h"
 
-void helper_outb(uint32_t port, uint32_t data)
+void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
 {
-    cpu_outb(port, data & 0xff);
+#ifdef CONFIG_USER_ONLY
+    fprintf(stderr, "outb: port=0x%04x, data=%02x\n", port, data);
+#else
+    address_space_stb(&address_space_io, port, data,
+                      cpu_get_mem_attrs(env), NULL);
+#endif
 }
 
-target_ulong helper_inb(uint32_t port)
+target_ulong helper_inb(CPUX86State *env, uint32_t port)
 {
-    return cpu_inb(port);
+#ifdef CONFIG_USER_ONLY
+    fprintf(stderr, "inb: port=0x%04x\n", port);
+    return 0;
+#else
+    return address_space_ldub(&address_space_io, port,
+                              cpu_get_mem_attrs(env), NULL);
+#endif
 }
 
-void helper_outw(uint32_t port, uint32_t data)
+void helper_outw(CPUX86State *env, uint32_t port, uint32_t data)
 {
-    cpu_outw(port, data & 0xffff);
+#ifdef CONFIG_USER_ONLY
+    fprintf(stderr, "outw: port=0x%04x, data=%04x\n", port, data);
+#else
+    address_space_stw(&address_space_io, port, data,
+                      cpu_get_mem_attrs(env), NULL);
+#endif
 }
 
-target_ulong helper_inw(uint32_t port)
+target_ulong helper_inw(CPUX86State *env, uint32_t port)
 {
-    return cpu_inw(port);
+#ifdef CONFIG_USER_ONLY
+    fprintf(stderr, "inw: port=0x%04x\n", port);
+    return 0;
+#else
+    return address_space_lduw(&address_space_io, port,
+                              cpu_get_mem_attrs(env), NULL);
+#endif
 }
 
-void helper_outl(uint32_t port, uint32_t data)
+void helper_outl(CPUX86State *env, uint32_t port, uint32_t data)
 {
-    cpu_outl(port, data);
+#ifdef CONFIG_USER_ONLY
+    fprintf(stderr, "outw: port=0x%04x, data=%08x\n", port, data);
+#else
+    address_space_stl(&address_space_io, port, data,
+                      cpu_get_mem_attrs(env), NULL);
+#endif
 }
 
-target_ulong helper_inl(uint32_t port)
+target_ulong helper_inl(CPUX86State *env, uint32_t port)
 {
-    return cpu_inl(port);
+#ifdef CONFIG_USER_ONLY
+    fprintf(stderr, "inl: port=0x%04x\n", port);
+    return 0;
+#else
+    return address_space_ldl(&address_space_io, port,
+                             cpu_get_mem_attrs(env), NULL);
+#endif
 }
 
 void helper_into(CPUX86State *env, int next_eip_addend)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 305ce50..58b1959 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -631,13 +631,13 @@ static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n)
 {
     switch (ot) {
     case MO_8:
-        gen_helper_inb(v, n);
+        gen_helper_inb(v, cpu_env, n);
         break;
     case MO_16:
-        gen_helper_inw(v, n);
+        gen_helper_inw(v, cpu_env, n);
         break;
     case MO_32:
-        gen_helper_inl(v, n);
+        gen_helper_inl(v, cpu_env, n);
         break;
     default:
         tcg_abort();
@@ -648,13 +648,13 @@ static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n)
 {
     switch (ot) {
     case MO_8:
-        gen_helper_outb(v, n);
+        gen_helper_outb(cpu_env, v, n);
         break;
     case MO_16:
-        gen_helper_outw(v, n);
+        gen_helper_outw(cpu_env, v, n);
         break;
     case MO_32:
-        gen_helper_outl(v, n);
+        gen_helper_outl(cpu_env, v, n);
         break;
     default:
         tcg_abort();
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 05/31] target-i386: mask NMIs on entry to SMM
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (3 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 04/31] target-i386: Use correct memory attributes for ioport accesses Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 06/31] target-i386: set G=1 in SMM big real mode selectors Paolo Bonzini
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

QEMU is not blocking NMIs on entry to SMM.  Implementing this has to
cover a few corner cases, because:

- NMIs can then be enabled by an IRET instruction and there
is no mechanism to _set_ the "NMIs masked" flag on exit from SMM:
"A special case can occur if an SMI handler nests inside an NMI handler
and then another NMI occurs. [...] When the processor enters SMM while
executing an NMI handler, the processor saves the SMRAM state save map
but does not save the attribute to keep NMI interrupts disabled.

- However, there is some hidden state, because "If NMIs were blocked
before the SMI occurred [and no IRET is executed while in SMM], they
are blocked after execution of RSM."  This is represented by the new
HF2_SMM_INSIDE_NMI_MASK bit.  If it is zero, NMIs are _unblocked_
on exit from RSM.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/cpu.h        | 20 +++++++++++---------
 target-i386/smm_helper.c |  9 +++++++++
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 9f57fe9..4510ae7 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -180,15 +180,17 @@
 
 /* hflags2 */
 
-#define HF2_GIF_SHIFT        0 /* if set CPU takes interrupts */
-#define HF2_HIF_SHIFT        1 /* value of IF_MASK when entering SVM */
-#define HF2_NMI_SHIFT        2 /* CPU serving NMI */
-#define HF2_VINTR_SHIFT      3 /* value of V_INTR_MASKING bit */
-
-#define HF2_GIF_MASK          (1 << HF2_GIF_SHIFT)
-#define HF2_HIF_MASK          (1 << HF2_HIF_SHIFT)
-#define HF2_NMI_MASK          (1 << HF2_NMI_SHIFT)
-#define HF2_VINTR_MASK        (1 << HF2_VINTR_SHIFT)
+#define HF2_GIF_SHIFT            0 /* if set CPU takes interrupts */
+#define HF2_HIF_SHIFT            1 /* value of IF_MASK when entering SVM */
+#define HF2_NMI_SHIFT            2 /* CPU serving NMI */
+#define HF2_VINTR_SHIFT          3 /* value of V_INTR_MASKING bit */
+#define HF2_SMM_INSIDE_NMI_SHIFT 4 /* CPU serving SMI nested inside NMI */
+
+#define HF2_GIF_MASK            (1 << HF2_GIF_SHIFT)
+#define HF2_HIF_MASK            (1 << HF2_HIF_SHIFT)
+#define HF2_NMI_MASK            (1 << HF2_NMI_SHIFT)
+#define HF2_VINTR_MASK          (1 << HF2_VINTR_SHIFT)
+#define HF2_SMM_INSIDE_NMI_MASK (1 << HF2_SMM_INSIDE_NMI_SHIFT)
 
 #define CR0_PE_SHIFT 0
 #define CR0_MP_SHIFT 1
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index b9971b6..6207c3a 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -52,6 +52,11 @@ void do_smm_enter(X86CPU *cpu)
     log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
 
     env->hflags |= HF_SMM_MASK;
+    if (env->hflags2 & HF2_NMI_MASK) {
+        env->hflags2 |= HF2_SMM_INSIDE_NMI_MASK;
+    } else {
+        env->hflags2 |= HF2_NMI_MASK;
+    }
     cpu_smm_update(env);
 
     sm_state = env->smbase + 0x8000;
@@ -307,6 +312,10 @@ void helper_rsm(CPUX86State *env)
         env->smbase = x86_ldl_phys(cs, sm_state + 0x7ef8) & ~0x7fff;
     }
 #endif
+    if ((env->hflags2 & HF2_SMM_INSIDE_NMI_MASK) == 0) {
+        env->hflags2 &= ~HF2_NMI_MASK;
+    }
+    env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
     env->hflags &= ~HF_SMM_MASK;
     cpu_smm_update(env);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 06/31] target-i386: set G=1 in SMM big real mode selectors
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (4 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 05/31] target-i386: mask NMIs on entry to SMM Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 07/31] pflash_cfi01: change big-endian property to BIT type Paolo Bonzini
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Because the limit field's bits 31:20 is 1, G should be 1.
VMX actually enforces this, let's do it for completeness
in QEMU as well.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/smm_helper.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 6207c3a..5617a14 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -177,22 +177,22 @@ void do_smm_enter(X86CPU *cpu)
     cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
                            0xffffffff,
                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
+                           DESC_G_MASK | DESC_A_MASK);
     cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff,
                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
+                           DESC_G_MASK | DESC_A_MASK);
     cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff,
                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
+                           DESC_G_MASK | DESC_A_MASK);
     cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff,
                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
+                           DESC_G_MASK | DESC_A_MASK);
     cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff,
                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
+                           DESC_G_MASK | DESC_A_MASK);
     cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff,
                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
+                           DESC_G_MASK | DESC_A_MASK);
 }
 
 void helper_rsm(CPUX86State *env)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 07/31] pflash_cfi01: change big-endian property to BIT type
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (5 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 06/31] target-i386: set G=1 in SMM big real mode selectors Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 08/31] pflash_cfi01: change to new-style MMIO accessors Paolo Bonzini
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Make this consistent with the secure property, added in the next patch.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/block/pflash_cfi01.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index d282695..7507a15 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -64,6 +64,8 @@ do {                                                        \
 #define TYPE_CFI_PFLASH01 "cfi.pflash01"
 #define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
 
+#define PFLASH_BE		0
+
 struct pflash_t {
     /*< private >*/
     SysBusDevice parent_obj;
@@ -75,7 +77,7 @@ struct pflash_t {
     uint8_t bank_width;
     uint8_t device_width; /* If 0, device width not specified. */
     uint8_t max_device_width;  /* max device width in bytes */
-    uint8_t be;
+    uint32_t features;
     uint8_t wcycle; /* if 0, the flash is read normally */
     int ro;
     uint8_t cmd;
@@ -773,7 +775,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 
     memory_region_init_rom_device(
         &pfl->mem, OBJECT(dev),
-        pfl->be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl,
+        pfl->features & (1 << PFLASH_BE) ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le,
+        pfl,
         pfl->name, total_len, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -925,7 +928,7 @@ static Property pflash_cfi01_properties[] = {
     DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0),
     DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
     DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
-    DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0),
+    DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0),
     DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
     DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
     DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
@@ -975,7 +978,7 @@ pflash_t *pflash_cfi01_register(hwaddr base,
     qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
     qdev_prop_set_uint64(dev, "sector-length", sector_len);
     qdev_prop_set_uint8(dev, "width", bank_width);
-    qdev_prop_set_uint8(dev, "big-endian", !!be);
+    qdev_prop_set_bit(dev, "big-endian", !!be);
     qdev_prop_set_uint16(dev, "id0", id0);
     qdev_prop_set_uint16(dev, "id1", id1);
     qdev_prop_set_uint16(dev, "id2", id2);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 08/31] pflash_cfi01: change to new-style MMIO accessors
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (6 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 07/31] pflash_cfi01: change big-endian property to BIT type Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 09/31] pflash_cfi01: add secure property Paolo Bonzini
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

This is a required step to implement read_with_attrs and write_with_attrs.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/block/pflash_cfi01.c | 96 ++++++-------------------------------------------
 1 file changed, 10 insertions(+), 86 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 7507a15..0b3667a 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -650,101 +650,25 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
 }
 
 
-static uint32_t pflash_readb_be(void *opaque, hwaddr addr)
-{
-    return pflash_read(opaque, addr, 1, 1);
-}
-
-static uint32_t pflash_readb_le(void *opaque, hwaddr addr)
-{
-    return pflash_read(opaque, addr, 1, 0);
-}
-
-static uint32_t pflash_readw_be(void *opaque, hwaddr addr)
+static uint64_t pflash_mem_read(void *opaque, hwaddr addr, unsigned len)
 {
     pflash_t *pfl = opaque;
+    bool be = !!(pfl->features & (1 << PFLASH_BE));
 
-    return pflash_read(pfl, addr, 2, 1);
+    return pflash_read(pfl, addr, len, be);
 }
 
-static uint32_t pflash_readw_le(void *opaque, hwaddr addr)
+static void pflash_mem_write(void *opaque, hwaddr addr, uint64_t value, unsigned len)
 {
     pflash_t *pfl = opaque;
+    bool be = !!(pfl->features & (1 << PFLASH_BE));
 
-    return pflash_read(pfl, addr, 2, 0);
+    pflash_write(pfl, addr, value, len, be);
 }
 
-static uint32_t pflash_readl_be(void *opaque, hwaddr addr)
-{
-    pflash_t *pfl = opaque;
-
-    return pflash_read(pfl, addr, 4, 1);
-}
-
-static uint32_t pflash_readl_le(void *opaque, hwaddr addr)
-{
-    pflash_t *pfl = opaque;
-
-    return pflash_read(pfl, addr, 4, 0);
-}
-
-static void pflash_writeb_be(void *opaque, hwaddr addr,
-                             uint32_t value)
-{
-    pflash_write(opaque, addr, value, 1, 1);
-}
-
-static void pflash_writeb_le(void *opaque, hwaddr addr,
-                             uint32_t value)
-{
-    pflash_write(opaque, addr, value, 1, 0);
-}
-
-static void pflash_writew_be(void *opaque, hwaddr addr,
-                             uint32_t value)
-{
-    pflash_t *pfl = opaque;
-
-    pflash_write(pfl, addr, value, 2, 1);
-}
-
-static void pflash_writew_le(void *opaque, hwaddr addr,
-                             uint32_t value)
-{
-    pflash_t *pfl = opaque;
-
-    pflash_write(pfl, addr, value, 2, 0);
-}
-
-static void pflash_writel_be(void *opaque, hwaddr addr,
-                             uint32_t value)
-{
-    pflash_t *pfl = opaque;
-
-    pflash_write(pfl, addr, value, 4, 1);
-}
-
-static void pflash_writel_le(void *opaque, hwaddr addr,
-                             uint32_t value)
-{
-    pflash_t *pfl = opaque;
-
-    pflash_write(pfl, addr, value, 4, 0);
-}
-
-static const MemoryRegionOps pflash_cfi01_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const MemoryRegionOps pflash_cfi01_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
+static const MemoryRegionOps pflash_cfi01_ops = {
+    .read = pflash_mem_read,
+    .write = pflash_mem_write,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
@@ -775,7 +699,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 
     memory_region_init_rom_device(
         &pfl->mem, OBJECT(dev),
-        pfl->features & (1 << PFLASH_BE) ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le,
+        &pflash_cfi01_ops,
         pfl,
         pfl->name, total_len, &local_err);
     if (local_err) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 09/31] pflash_cfi01: add secure property
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (7 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 08/31] pflash_cfi01: change to new-style MMIO accessors Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global Paolo Bonzini
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

When this property is set, MMIO accesses are only allowed with the
MEMTXATTRS_SECURE attribute.  This is used for secure access to UEFI
variables stored in flash.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/block/pflash_cfi01.c | 111 +++++++++++++++++++++++++++++-------------------
 1 file changed, 67 insertions(+), 44 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 0b3667a..965995a 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -65,6 +65,7 @@ do {                                                        \
 #define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
 
 #define PFLASH_BE		0
+#define PFLASH_SECURE		1
 
 struct pflash_t {
     /*< private >*/
@@ -237,12 +238,57 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
     return resp;
 }
 
+static uint32_t pflash_data_read(pflash_t *pfl, hwaddr offset,
+                                 int width, int be)
+{
+    uint8_t *p;
+    uint32_t ret;
+
+    p = pfl->storage;
+    switch (width) {
+    case 1:
+        ret = p[offset];
+        DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n",
+                __func__, offset, ret);
+        break;
+    case 2:
+        if (be) {
+            ret = p[offset] << 8;
+            ret |= p[offset + 1];
+        } else {
+            ret = p[offset];
+            ret |= p[offset + 1] << 8;
+        }
+        DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n",
+                __func__, offset, ret);
+        break;
+    case 4:
+        if (be) {
+            ret = p[offset] << 24;
+            ret |= p[offset + 1] << 16;
+            ret |= p[offset + 2] << 8;
+            ret |= p[offset + 3];
+        } else {
+            ret = p[offset];
+            ret |= p[offset + 1] << 8;
+            ret |= p[offset + 2] << 16;
+            ret |= p[offset + 3] << 24;
+        }
+        DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n",
+                __func__, offset, ret);
+        break;
+    default:
+        DPRINTF("BUG in %s\n", __func__);
+        abort();
+    }
+    return ret;
+}
+
 static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
                              int width, int be)
 {
     hwaddr boff;
     uint32_t ret;
-    uint8_t *p;
 
     ret = -1;
 
@@ -259,43 +305,7 @@ static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
         /* fall through to read code */
     case 0x00:
         /* Flash area read */
-        p = pfl->storage;
-        switch (width) {
-        case 1:
-            ret = p[offset];
-            DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n",
-                    __func__, offset, ret);
-            break;
-        case 2:
-            if (be) {
-                ret = p[offset] << 8;
-                ret |= p[offset + 1];
-            } else {
-                ret = p[offset];
-                ret |= p[offset + 1] << 8;
-            }
-            DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n",
-                    __func__, offset, ret);
-            break;
-        case 4:
-            if (be) {
-                ret = p[offset] << 24;
-                ret |= p[offset + 1] << 16;
-                ret |= p[offset + 2] << 8;
-                ret |= p[offset + 3];
-            } else {
-                ret = p[offset];
-                ret |= p[offset + 1] << 8;
-                ret |= p[offset + 2] << 16;
-                ret |= p[offset + 3] << 24;
-            }
-            DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n",
-                    __func__, offset, ret);
-            break;
-        default:
-            DPRINTF("BUG in %s\n", __func__);
-        }
-
+        ret = pflash_data_read(pfl, offset, width, be);
         break;
     case 0x10: /* Single byte program */
     case 0x20: /* Block erase */
@@ -650,25 +660,37 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
 }
 
 
-static uint64_t pflash_mem_read(void *opaque, hwaddr addr, unsigned len)
+static MemTxResult pflash_mem_read_with_attrs(void *opaque, hwaddr addr, uint64_t *value,
+                                              unsigned len, MemTxAttrs attrs)
 {
     pflash_t *pfl = opaque;
     bool be = !!(pfl->features & (1 << PFLASH_BE));
 
-    return pflash_read(pfl, addr, len, be);
+    if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
+        *value = pflash_data_read(opaque, addr, len, be);
+    } else {
+        *value = pflash_read(opaque, addr, len, be);
+    }
+    return MEMTX_OK;
 }
 
-static void pflash_mem_write(void *opaque, hwaddr addr, uint64_t value, unsigned len)
+static MemTxResult pflash_mem_write_with_attrs(void *opaque, hwaddr addr, uint64_t value,
+                                               unsigned len, MemTxAttrs attrs)
 {
     pflash_t *pfl = opaque;
     bool be = !!(pfl->features & (1 << PFLASH_BE));
 
-    pflash_write(pfl, addr, value, len, be);
+    if ((pfl->features & (1 << PFLASH_SECURE)) && !attrs.secure) {
+        return MEMTX_ERROR;
+    } else {
+        pflash_write(opaque, addr, value, len, be);
+        return MEMTX_OK;
+    }
 }
 
 static const MemoryRegionOps pflash_cfi01_ops = {
-    .read = pflash_mem_read,
-    .write = pflash_mem_write,
+    .read_with_attrs = pflash_mem_read_with_attrs,
+    .write_with_attrs = pflash_mem_write_with_attrs,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
@@ -853,6 +875,7 @@ static Property pflash_cfi01_properties[] = {
     DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
     DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
     DEFINE_PROP_BIT("big-endian", struct pflash_t, features, PFLASH_BE, 0),
+    DEFINE_PROP_BIT("secure", struct pflash_t, features, PFLASH_SECURE, 0),
     DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
     DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
     DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (8 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 09/31] pflash_cfi01: add secure property Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-19 11:49   ` Paolo Bonzini
  2015-05-19 16:30   ` Markus Armbruster
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link Paolo Bonzini
                   ` (21 subsequent siblings)
  31 siblings, 2 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

-global does not work for drivers that have a dot in their name, such as
cfi.pflash01.  This is just a parsing limitation, because such globals
can be declared easily inside a -readconfig file.

To allow this usage, support the full QemuOpts key/value syntax for -global
too, for example "-global driver=cfi.pflash01,property=secure,value=on".
The two formats do not conflict, because the key/value syntax does not have
a period before the first equal sign.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qdev-monitor.c  | 18 +++++++++++-------
 qemu-options.hx |  7 ++++++-
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/qdev-monitor.c b/qdev-monitor.c
index 1d87f57..9f17c81 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -822,15 +822,19 @@ int qemu_global_option(const char *str)
     QemuOpts *opts;
     int rc, offset;
 
-    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
-    if (rc < 2 || str[offset] != '=') {
-        error_report("can't parse: \"%s\"", str);
+    rc = sscanf(str, "%63[^.=].%63[^=]%n", driver, property, &offset);
+    if (rc == 2 && str[offset] == '=') {
+        opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
+        qemu_opt_set(opts, "driver", driver, &error_abort);
+        qemu_opt_set(opts, "property", property, &error_abort);
+        qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
+        return 0;
+    }
+
+    opts = qemu_opts_parse(&qemu_global_opts, str, false);
+    if (!opts) {
         return -1;
     }
 
-    opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
-    qemu_opt_set(opts, "driver", driver, &error_abort);
-    qemu_opt_set(opts, "property", property, &error_abort);
-    qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
     return 0;
 }
diff --git a/qemu-options.hx b/qemu-options.hx
index ec356f6..43c9ee0 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -171,11 +171,13 @@ Set parameter @var{arg} for item @var{id} of type @var{group}\n"
 ETEXI
 
 DEF("global", HAS_ARG, QEMU_OPTION_global,
-    "-global driver.prop=value\n"
+    "-global driver.property=value\n"
+    "-global driver=driver,property=property,value=value\n"
     "                set a global default for a driver property\n",
     QEMU_ARCH_ALL)
 STEXI
 @item -global @var{driver}.@var{prop}=@var{value}
+@itemx -global driver=@var{driver},property=@var{property},value=@var{value}
 @findex -global
 Set default value of @var{driver}'s property @var{prop} to @var{value}, e.g.:
 
@@ -186,6 +188,9 @@ qemu-system-i386 -global ide-drive.physical_block_size=4096 -drive file=file,if=
 In particular, you can use this to set driver properties for devices which are 
 created automatically by the machine model. To create a device which is not 
 created automatically and set properties on it, use -@option{device}.
+
+The two syntaxes are equivalent.  The longer one works for drivers whose name
+contains a dot.
 ETEXI
 
 DEF("boot", HAS_ARG, QEMU_OPTION_boot,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (9 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 14:40   ` Laszlo Ersek
                     ` (2 more replies)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 12/31] vl: run "late" notifiers immediately Paolo Bonzini
                   ` (20 subsequent siblings)
  31 siblings, 3 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qom/object.h | 18 ++++++++++++++++++
 qom/object.c         | 16 ++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index d2d7748..0505f20 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1290,6 +1290,24 @@ void object_property_add_alias(Object *obj, const char *name,
                                Error **errp);
 
 /**
+ * object_property_add_const_link:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @target: the object to be referred by the link
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an unmodifiable link for a property on an object.  This function will
+ * add a property of type link<TYPE> where TYPE is the type of @target.
+ *
+ * The caller must ensure that @target stays alive as long as
+ * this property exists.  In the case @target is a child of @obj,
+ * this will be the case.  Otherwise, the caller is responsible for
+ * taking a reference.
+ */
+void object_property_add_const_link(Object *obj, const char *name,
+                                    Object *target, Error **errp);
+
+/**
  * object_property_set_description:
  * @obj: the object owning the property
  * @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index b8dff43..ba89518 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1266,6 +1266,22 @@ out:
     g_free(full_type);
 }
 
+void object_property_add_const_link(Object *obj, const char *name,
+                                    Object *target, Error **errp)
+{
+    char *link_type;
+    ObjectProperty *op;
+   
+    link_type = g_strdup_printf("link<%s>", object_get_typename(target));
+    op = object_property_add(obj, name, link_type,
+                             object_get_child_property, NULL,
+                             NULL, target, errp);
+    if (op != NULL) {
+        op->resolve = object_resolve_child_property;
+    }
+    g_free(link_type);
+}
+
 gchar *object_get_canonical_path_component(Object *obj)
 {
     ObjectProperty *prop = NULL;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 12/31] vl: run "late" notifiers immediately
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (10 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 13/31] target-i386: create a separate AddressSpace for each CPU Paolo Bonzini
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

If a machine_init_done notifier is added late, as part of a hot-plugged
device, run it immediately.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 vl.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/vl.c b/vl.c
index 15bccc4..3bfb6a6 100644
--- a/vl.c
+++ b/vl.c
@@ -2501,14 +2501,20 @@ static void qemu_run_exit_notifiers(void)
     notifier_list_notify(&exit_notifiers, NULL);
 }
 
+static bool machine_init_done;
+
 void qemu_add_machine_init_done_notifier(Notifier *notify)
 {
     notifier_list_add(&machine_init_done_notifiers, notify);
+    if (machine_init_done) {
+        notify->notify(notify, NULL);
+    }
 }
 
 static void qemu_run_machine_init_done_notifiers(void)
 {
     notifier_list_notify(&machine_init_done_notifiers, NULL);
+    machine_init_done = true;
 }
 
 static const QEMUOption *lookup_opt(int argc, char **argv,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 13/31] target-i386: create a separate AddressSpace for each CPU
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (11 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 12/31] vl: run "late" notifiers immediately Paolo Bonzini
@ 2015-05-11 13:48 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 14/31] hw/i386: add a separate region that tracks the SMRAME bit Paolo Bonzini
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Different CPUs can be in SMM or not at the same time, thus they
will see different things where the chipset places SMRAM.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/cpu-qom.h |  1 +
 target-i386/cpu.c     | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 31a0c1e..39cd878 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -111,6 +111,7 @@ typedef struct X86CPU {
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct DeviceState *apic_state;
+    struct MemoryRegion *cpu_as_root;
 } X86CPU;
 
 static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 3305e09..97c4804 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -44,6 +44,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/cpu/icc_bus.h"
 #ifndef CONFIG_USER_ONLY
+#include "exec/address-spaces.h"
 #include "hw/xen/xen.h"
 #include "hw/i386/apic_internal.h"
 #endif
@@ -2811,6 +2812,18 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
 #endif
 
     mce_init(cpu);
+
+#ifndef CONFIG_USER_ONLY
+    if (tcg_enabled()) {
+        cpu->cpu_as_root = g_new(MemoryRegion, 1);
+        cs->as = g_new(AddressSpace, 1);
+        memory_region_init_alias(cpu->cpu_as_root, OBJECT(cpu), "memory",
+                                 get_system_memory(), 0, ~0ull);
+        memory_region_set_enabled(cpu->cpu_as_root, true);
+        address_space_init(cs->as, cpu->cpu_as_root, "CPU");
+    }
+#endif
+
     qemu_init_vcpu(cs);
 
     /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this
@@ -2834,6 +2847,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     cpu_reset(cs);
 
     xcc->parent_realize(dev, &local_err);
+
 out:
     if (local_err != NULL) {
         error_propagate(errp, local_err);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 14/31] hw/i386: add a separate region that tracks the SMRAME bit
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (12 preceding siblings ...)
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 13/31] target-i386: create a separate AddressSpace for each CPU Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM Paolo Bonzini
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

This region is exported at /machine/smram.  It is "empty" if
SMRAME=0 and points to SMRAM if SMRAME=1.  The CPU will
enable/disable it as it enters or exits SMRAM.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/piix.c        | 15 +++++++++++++++
 hw/pci-host/q35.c         | 15 ++++++++++++++-
 include/hw/pci-host/q35.h |  1 +
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 723836f..a280d57 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -105,6 +105,7 @@ struct PCII440FXState {
     MemoryRegion *ram_memory;
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
+    MemoryRegion smram, low_smram;
     uint8_t smm_enabled;
 };
 
@@ -139,6 +140,8 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
                    pd->config[I440FX_PAM + ((i + 1) / 2)]);
     }
     smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
+    memory_region_set_enabled(&d->smram,
+                              pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
     memory_region_transaction_commit();
 }
 
@@ -346,11 +349,23 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
                            f->pci_address_space);
 
+    /* if *disabled* show SMRAM to all CPUs */
     memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
                              f->pci_address_space, 0xa0000, 0x20000);
     memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
                                         &f->smram_region, 1);
     memory_region_set_enabled(&f->smram_region, false);
+
+    /* smram, as seen by SMM CPUs */
+    memory_region_init(&f->smram, OBJECT(d), "smram", 1ull << 32);
+    memory_region_set_enabled(&f->smram, true);
+    memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
+                             f->system_memory, 0xa0000, 0x20000);
+    memory_region_set_enabled(&f->low_smram, true);
+    memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
+    object_property_add_alias(qdev_get_machine(), "smram",
+                              OBJECT(&f->smram), ".", NULL);
+
     init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,
              &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
     for (i = 0; i < 12; ++i) {
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index c8827cc..de8326a 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -270,6 +270,8 @@ static void mch_update_smram(MCHPCIState *mch)
     memory_region_transaction_begin();
     smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
                     mch->smm_enabled);
+    memory_region_set_enabled(&mch->smram,
+                              pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
     memory_region_transaction_commit();
 }
 
@@ -399,13 +401,24 @@ static void mch_realize(PCIDevice *d, Error **errp)
     pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
                            mch->pci_address_space);
 
-    /* smram */
+    /* if *disabled* show SMRAM to all CPUs */
     cpu_smm_register(&mch_set_smm, mch);
     memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
                              mch->pci_address_space, 0xa0000, 0x20000);
     memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
                                         &mch->smram_region, 1);
     memory_region_set_enabled(&mch->smram_region, false);
+
+    /* smram, as seen by SMM CPUs */
+    memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
+    memory_region_set_enabled(&mch->smram, true);
+    memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
+                             mch->system_memory, 0xa0000, 0x20000);
+    memory_region_set_enabled(&mch->low_smram, true);
+    memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
+    object_property_add_const_link(qdev_get_machine(), "smram",
+				   OBJECT(&mch->smram), &error_abort);
+
     init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
              mch->pci_address_space, &mch->pam_regions[0],
              PAM_BIOS_BASE, PAM_BIOS_SIZE);
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 96d4cdc..4c9eacc 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -53,6 +53,7 @@ typedef struct MCHPCIState {
     MemoryRegion *address_space_io;
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
+    MemoryRegion smram, low_smram;
     PcPciInfo pci_info;
     uint8_t smm_enabled;
     ram_addr_t below_4g_mem_size;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (13 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 14/31] hw/i386: add a separate region that tracks the SMRAME bit Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-31 18:09   ` Michael S. Tsirkin
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 16/31] hw/i386: remove smram_update Paolo Bonzini
                   ` (16 subsequent siblings)
  31 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Remove cpu_smm_register and cpu_smm_update.  Instead, each CPU
address space gets an extra region which is an alias of
/machine/smram.  This extra region is enabled or disabled
as the CPU enters/exits SMM.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 bsd-user/main.c           |  4 ----
 hw/i386/pc.c              | 21 ---------------------
 hw/pci-host/pam.c         | 18 ++----------------
 hw/pci-host/piix.c        | 25 +++++--------------------
 hw/pci-host/q35.c         | 19 +++----------------
 include/hw/i386/pc.h      |  1 -
 include/hw/pci-host/pam.h |  5 +----
 include/hw/pci-host/q35.h |  1 -
 linux-user/main.c         |  4 ----
 target-i386/cpu-qom.h     |  4 +++-
 target-i386/cpu.c         | 33 +++++++++++++++++++++++++++++++--
 target-i386/cpu.h         |  3 ++-
 target-i386/machine.c     |  3 +++
 target-i386/smm_helper.c  | 12 ++++++++++--
 14 files changed, 60 insertions(+), 93 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 5bfaf5c..ba0b998 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -108,10 +108,6 @@ void cpu_list_unlock(void)
 /***********************************************************/
 /* CPUX86 core interface */
 
-void cpu_smm_update(CPUX86State *env)
-{
-}
-
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
     return cpu_get_real_ticks();
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a8e6be1..a7ee9ef 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -163,27 +163,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
     return cpu_get_ticks();
 }
 
-/* SMM support */
-
-static cpu_set_smm_t smm_set;
-static void *smm_arg;
-
-void cpu_smm_register(cpu_set_smm_t callback, void *arg)
-{
-    assert(smm_set == NULL);
-    assert(smm_arg == NULL);
-    smm_set = callback;
-    smm_arg = arg;
-}
-
-void cpu_smm_update(CPUX86State *env)
-{
-    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
-        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
-    }
-}
-
-
 /* IRQ handling */
 int cpu_get_pic_interrupt(CPUX86State *env)
 {
diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c
index 8272de3..99d7af9 100644
--- a/hw/pci-host/pam.c
+++ b/hw/pci-host/pam.c
@@ -31,26 +31,12 @@
 #include "sysemu/sysemu.h"
 #include "hw/pci-host/pam.h"
 
-void smram_update(MemoryRegion *smram_region, uint8_t smram,
-                  uint8_t smm_enabled)
+void smram_update(MemoryRegion *smram_region, uint8_t smram)
 {
-    bool smram_enabled;
-
-    smram_enabled = ((smm_enabled && (smram & SMRAM_G_SMRAME)) ||
-                        (smram & SMRAM_D_OPEN));
+    bool smram_enabled = (smram & SMRAM_D_OPEN);
     memory_region_set_enabled(smram_region, !smram_enabled);
 }
 
-void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
-                   MemoryRegion *smram_region)
-{
-    uint8_t smm_enabled = (smm != 0);
-    if (*host_smm_enabled != smm_enabled) {
-        *host_smm_enabled = smm_enabled;
-        smram_update(smram_region, smram, *host_smm_enabled);
-    }
-}
-
 void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
               MemoryRegion *system_memory, MemoryRegion *pci_address_space,
               PAMMemoryRegion *mem, uint32_t start, uint32_t size)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index a280d57..46c0278 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -106,7 +106,6 @@ struct PCII440FXState {
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
     MemoryRegion smram, low_smram;
-    uint8_t smm_enabled;
 };
 
 
@@ -139,23 +138,12 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
         pam_update(&d->pam_regions[i], i,
                    pd->config[I440FX_PAM + ((i + 1) / 2)]);
     }
-    smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
+    smram_update(&d->smram_region, pd->config[I440FX_SMRAM]);
     memory_region_set_enabled(&d->smram,
                               pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
     memory_region_transaction_commit();
 }
 
-static void i440fx_set_smm(int val, void *arg)
-{
-    PCII440FXState *d = arg;
-    PCIDevice *pd = PCI_DEVICE(d);
-
-    memory_region_transaction_begin();
-    smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
-                  &d->smram_region);
-    memory_region_transaction_commit();
-}
-
 
 static void i440fx_write_config(PCIDevice *dev,
                                 uint32_t address, uint32_t val, int len)
@@ -175,12 +163,13 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
     PCII440FXState *d = opaque;
     PCIDevice *pd = PCI_DEVICE(d);
     int ret, i;
+    uint8_t smm_enabled;
 
     ret = pci_device_load(pd, f);
     if (ret < 0)
         return ret;
     i440fx_update_memory_mappings(d);
-    qemu_get_8s(f, &d->smm_enabled);
+    qemu_get_8s(f, &smm_enabled);
 
     if (version_id == 2) {
         for (i = 0; i < PIIX_NUM_PIRQS; i++) {
@@ -208,7 +197,7 @@ static const VMStateDescription vmstate_i440fx = {
     .post_load = i440fx_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
-        VMSTATE_UINT8(smm_enabled, PCII440FXState),
+        VMSTATE_UNUSED(1),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -300,11 +289,7 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
 
 static void i440fx_realize(PCIDevice *dev, Error **errp)
 {
-    PCII440FXState *d = I440FX_PCI_DEVICE(dev);
-
     dev->config[I440FX_SMRAM] = 0x02;
-
-    cpu_smm_register(&i440fx_set_smm, d);
 }
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
@@ -360,7 +345,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     memory_region_init(&f->smram, OBJECT(d), "smram", 1ull << 32);
     memory_region_set_enabled(&f->smram, true);
     memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
-                             f->system_memory, 0xa0000, 0x20000);
+                             f->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&f->low_smram, true);
     memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
     object_property_add_alias(qdev_get_machine(), "smram",
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index de8326a..bd17a05 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -268,24 +268,12 @@ static void mch_update_smram(MCHPCIState *mch)
     PCIDevice *pd = PCI_DEVICE(mch);
 
     memory_region_transaction_begin();
-    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
-                    mch->smm_enabled);
+    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM]);
     memory_region_set_enabled(&mch->smram,
                               pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
     memory_region_transaction_commit();
 }
 
-static void mch_set_smm(int smm, void *arg)
-{
-    MCHPCIState *mch = arg;
-    PCIDevice *pd = PCI_DEVICE(mch);
-
-    memory_region_transaction_begin();
-    smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
-                    &mch->smram_region);
-    memory_region_transaction_commit();
-}
-
 static void mch_write_config(PCIDevice *d,
                               uint32_t address, uint32_t val, int len)
 {
@@ -331,7 +319,7 @@ static const VMStateDescription vmstate_mch = {
     .post_load = mch_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
-        VMSTATE_UINT8(smm_enabled, MCHPCIState),
+        VMSTATE_UNUSED(1),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -402,7 +390,6 @@ static void mch_realize(PCIDevice *d, Error **errp)
                            mch->pci_address_space);
 
     /* if *disabled* show SMRAM to all CPUs */
-    cpu_smm_register(&mch_set_smm, mch);
     memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
                              mch->pci_address_space, 0xa0000, 0x20000);
     memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
@@ -413,7 +400,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
     memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
     memory_region_set_enabled(&mch->smram, true);
     memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
-                             mch->system_memory, 0xa0000, 0x20000);
+                             mch->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&mch->low_smram, true);
     memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
     object_property_add_const_link(qdev_get_machine(), "smram",
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 1b35168..c9a9f6e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -211,7 +211,6 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_pci_device_init(PCIBus *pci_bus);
 
 typedef void (*cpu_set_smm_t)(int smm, void *arg);
-void cpu_smm_register(cpu_set_smm_t callback, void *arg);
 
 void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
 
diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h
index 4d03e4b..80dd605 100644
--- a/include/hw/pci-host/pam.h
+++ b/include/hw/pci-host/pam.h
@@ -86,10 +86,7 @@ typedef struct PAMMemoryRegion {
     unsigned current;
 } PAMMemoryRegion;
 
-void smram_update(MemoryRegion *smram_region, uint8_t smram,
-                  uint8_t smm_enabled);
-void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
-                   MemoryRegion *smram_region);
+void smram_update(MemoryRegion *smram_region, uint8_t smram);
 void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system,
               MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size);
 void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val);
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 4c9eacc..17adeaa 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -55,7 +55,6 @@ typedef struct MCHPCIState {
     MemoryRegion smram_region;
     MemoryRegion smram, low_smram;
     PcPciInfo pci_info;
-    uint8_t smm_enabled;
     ram_addr_t below_4g_mem_size;
     ram_addr_t above_4g_mem_size;
     uint64_t pci_hole64_size;
diff --git a/linux-user/main.c b/linux-user/main.c
index 3f32db0..6989b82 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -215,10 +215,6 @@ void cpu_list_unlock(void)
 /***********************************************************/
 /* CPUX86 core interface */
 
-void cpu_smm_update(CPUX86State *env)
-{
-}
-
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
     return cpu_get_real_ticks();
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 39cd878..7a4fddd 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -23,6 +23,7 @@
 #include "qom/cpu.h"
 #include "cpu.h"
 #include "qapi/error.h"
+#include "qemu/notify.h"
 
 #ifdef TARGET_X86_64
 #define TYPE_X86_CPU "x86_64-cpu"
@@ -111,7 +112,8 @@ typedef struct X86CPU {
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct DeviceState *apic_state;
-    struct MemoryRegion *cpu_as_root;
+    struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
+    Notifier machine_done;
 } X86CPU;
 
 static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 97c4804..7b6f9e4 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2751,6 +2751,21 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
     object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
                              errp);
 }
+
+static void x86_cpu_machine_done(Notifier *n, void *unused)
+{
+    X86CPU *cpu = container_of(n, X86CPU, machine_done);
+    MemoryRegion *smram =
+        (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
+
+    if (smram) {
+        cpu->smram = g_new(MemoryRegion, 1);
+        memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
+                                 smram, 0, 1ull << 32);
+        memory_region_set_enabled(cpu->smram, false);
+        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
+    }
+}
 #else
 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
 {
@@ -2815,12 +2830,26 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
 
 #ifndef CONFIG_USER_ONLY
     if (tcg_enabled()) {
+        cpu->cpu_as_mem = g_new(MemoryRegion, 1);
         cpu->cpu_as_root = g_new(MemoryRegion, 1);
         cs->as = g_new(AddressSpace, 1);
-        memory_region_init_alias(cpu->cpu_as_root, OBJECT(cpu), "memory",
-                                 get_system_memory(), 0, ~0ull);
+
+        /* Outer container... */
+        memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
         memory_region_set_enabled(cpu->cpu_as_root, true);
+
+        /* ... with two regions inside: normal system memory with low
+         * priority, and...
+         */
+        memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
+                                 get_system_memory(), 0, ~0ull);
+        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
+        memory_region_set_enabled(cpu->cpu_as_mem, true);
         address_space_init(cs->as, cpu->cpu_as_root, "CPU");
+
+        /* ... SMRAM with higher priority, linked from /machine/smram.  */
+        cpu->machine_done.notify = x86_cpu_machine_done;
+        qemu_add_machine_init_done_notifier(&cpu->machine_done);
     }
 #endif
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4510ae7..df6e885 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1157,7 +1157,6 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 
 /* hw/pc.c */
-void cpu_smm_update(CPUX86State *env);
 uint64_t cpu_get_tsc(CPUX86State *env);
 
 #define TARGET_PAGE_BITS 12
@@ -1323,7 +1322,9 @@ void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
 /* seg_helper.c */
 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
 
+/* smm_helper.c */
 void do_smm_enter(X86CPU *cpu);
+void cpu_smm_update(X86CPU *cpu);
 
 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
 
diff --git a/target-i386/machine.c b/target-i386/machine.c
index cd1ddd2..69d86cb 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -372,6 +372,9 @@ static int cpu_post_load(void *opaque, int version_id)
     }
     tlb_flush(cs, 1);
 
+    if (tcg_enabled()) {
+        cpu_smm_update(cpu);
+    }
     return 0;
 }
 
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 5617a14..762f4e5 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -40,6 +40,14 @@ void helper_rsm(CPUX86State *env)
 #define SMM_REVISION_ID 0x00020000
 #endif
 
+void cpu_smm_update(X86CPU *cpu)
+{
+    CPUX86State *env = &cpu->env;
+    bool smm_enabled = (env->hflags & HF_SMM_MASK);
+
+    memory_region_set_enabled(cpu->smram, smm_enabled);
+}
+
 void do_smm_enter(X86CPU *cpu)
 {
     CPUX86State *env = &cpu->env;
@@ -57,7 +65,7 @@ void do_smm_enter(X86CPU *cpu)
     } else {
         env->hflags2 |= HF2_NMI_MASK;
     }
-    cpu_smm_update(env);
+    cpu_smm_update(cpu);
 
     sm_state = env->smbase + 0x8000;
 
@@ -317,7 +325,7 @@ void helper_rsm(CPUX86State *env)
     }
     env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
     env->hflags &= ~HF_SMM_MASK;
-    cpu_smm_update(env);
+    cpu_smm_update(cpu);
 
     qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
     log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 16/31] hw/i386: remove smram_update
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (14 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 17/31] q35: implement high SMRAM Paolo Bonzini
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

It's easier to inline it now that most of its work is done by the CPU
(rather than the chipset) through /machine/smram and the memory API.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/pam.c         | 6 ------
 hw/pci-host/piix.c        | 3 ++-
 hw/pci-host/q35.c         | 3 ++-
 include/hw/pci-host/pam.h | 1 -
 4 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c
index 99d7af9..17d826c 100644
--- a/hw/pci-host/pam.c
+++ b/hw/pci-host/pam.c
@@ -31,12 +31,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/pci-host/pam.h"
 
-void smram_update(MemoryRegion *smram_region, uint8_t smram)
-{
-    bool smram_enabled = (smram & SMRAM_D_OPEN);
-    memory_region_set_enabled(smram_region, !smram_enabled);
-}
-
 void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
               MemoryRegion *system_memory, MemoryRegion *pci_address_space,
               PAMMemoryRegion *mem, uint32_t start, uint32_t size)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 46c0278..e67b24f 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -138,7 +138,8 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
         pam_update(&d->pam_regions[i], i,
                    pd->config[I440FX_PAM + ((i + 1) / 2)]);
     }
-    smram_update(&d->smram_region, pd->config[I440FX_SMRAM]);
+    memory_region_set_enabled(&d->smram_region,
+                              !(pd->config[I440FX_SMRAM] & SMRAM_D_OPEN));
     memory_region_set_enabled(&d->smram,
                               pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
     memory_region_transaction_commit();
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index bd17a05..e7372b1 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -268,7 +268,8 @@ static void mch_update_smram(MCHPCIState *mch)
     PCIDevice *pd = PCI_DEVICE(mch);
 
     memory_region_transaction_begin();
-    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM]);
+    memory_region_set_enabled(&mch->smram_region,
+                              !(pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN));
     memory_region_set_enabled(&mch->smram,
                               pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
     memory_region_transaction_commit();
diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h
index 80dd605..6116c63 100644
--- a/include/hw/pci-host/pam.h
+++ b/include/hw/pci-host/pam.h
@@ -86,7 +86,6 @@ typedef struct PAMMemoryRegion {
     unsigned current;
 } PAMMemoryRegion;
 
-void smram_update(MemoryRegion *smram_region, uint8_t smram);
 void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system,
               MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size);
 void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 17/31] q35: implement high SMRAM
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (15 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 16/31] hw/i386: remove smram_update Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 18/31] q35: fix ESMRAMC default Paolo Bonzini
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

When H_SMRAME is 1, low memory at 0xa0000 is left alone by
SMM, and instead the chipset maps the 0xa0000-0xbffff window at
0xfeda0000-0xfedbffff.  This affects both the "non-SMM" view controlled
by D_OPEN and the SMM view controlled by G_SMRAME, so add two new
MemoryRegions and toggle the enabled/disabled state of all four
in mch_update_smram.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/q35.c         | 35 +++++++++++++++++++++++++++++++----
 include/hw/pci-host/q35.h | 16 ++++++++--------
 2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index e7372b1..35b89da 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -266,12 +266,29 @@ static void mch_update_pam(MCHPCIState *mch)
 static void mch_update_smram(MCHPCIState *mch)
 {
     PCIDevice *pd = PCI_DEVICE(mch);
+    bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);
 
     memory_region_transaction_begin();
-    memory_region_set_enabled(&mch->smram_region,
-                              !(pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN));
-    memory_region_set_enabled(&mch->smram,
-                              pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
+
+    if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) {
+        /* Hide (!) low SMRAM if H_SMRAME = 1 */
+        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);
+    } 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);
+    }
+
     memory_region_transaction_commit();
 }
 
@@ -397,6 +414,12 @@ static void mch_realize(PCIDevice *d, Error **errp)
                                         &mch->smram_region, 1);
     memory_region_set_enabled(&mch->smram_region, false);
 
+    memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high",
+                             mch->ram_memory, 0xa0000, 0x20000);
+    memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000,
+                                        &mch->open_high_smram, 1);
+    memory_region_set_enabled(&mch->open_high_smram, false);
+
     /* smram, as seen by SMM CPUs */
     memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
     memory_region_set_enabled(&mch->smram, true);
@@ -404,6 +427,10 @@ static void mch_realize(PCIDevice *d, Error **errp)
                              mch->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&mch->low_smram, true);
     memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
+    memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high",
+                             mch->ram_memory, 0xa0000, 0x20000);
+    memory_region_set_enabled(&mch->high_smram, true);
+    memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
     object_property_add_const_link(qdev_get_machine(), "smram",
 				   OBJECT(&mch->smram), &error_abort);
 
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 17adeaa..0fff6a2 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -52,8 +52,8 @@ typedef struct MCHPCIState {
     MemoryRegion *system_memory;
     MemoryRegion *address_space_io;
     PAMMemoryRegion pam_regions[13];
-    MemoryRegion smram_region;
-    MemoryRegion smram, low_smram;
+    MemoryRegion smram_region, open_high_smram;
+    MemoryRegion smram, low_smram, high_smram;
     PcPciInfo pci_info;
     ram_addr_t below_4g_mem_size;
     ram_addr_t above_4g_mem_size;
@@ -127,7 +127,7 @@ typedef struct Q35PCIHost {
 #define MCH_HOST_BRIDGE_PAM_MASK               ((uint8_t)0x3)
 
 #define MCH_HOST_BRIDGE_SMRAM                  0x9d
-#define MCH_HOST_BRIDGE_SMRAM_SIZE             1
+#define MCH_HOST_BRIDGE_SMRAM_SIZE             2
 #define MCH_HOST_BRIDGE_SMRAM_DEFAULT          ((uint8_t)0x2)
 #define MCH_HOST_BRIDGE_SMRAM_D_OPEN           ((uint8_t)(1 << 6))
 #define MCH_HOST_BRIDGE_SMRAM_D_CLS            ((uint8_t)(1 << 5))
@@ -141,11 +141,11 @@ typedef struct Q35PCIHost {
 #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END  0x100000
 
 #define MCH_HOST_BRIDGE_ESMRAMC                0x9e
-#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 6))
-#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR        ((uint8_t)(1 << 5))
-#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE       ((uint8_t)(1 << 4))
-#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1          ((uint8_t)(1 << 3))
-#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2          ((uint8_t)(1 << 2))
+#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
+#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR        ((uint8_t)(1 << 6))
+#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE       ((uint8_t)(1 << 5))
+#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1          ((uint8_t)(1 << 4))
+#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2          ((uint8_t)(1 << 3))
 #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK   ((uint8_t)(0x3 << 1))
 #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB    ((uint8_t)(0x0 << 1))
 #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB    ((uint8_t)(0x1 << 1))
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 18/31] q35: fix ESMRAMC default
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (16 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 17/31] q35: implement high SMRAM Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-12  6:52   ` Gerd Hoffmann
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 19/31] q35: add config space wmask for SMRAM and ESMRAMC Paolo Bonzini
                   ` (13 subsequent siblings)
  31 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

From: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/q35.c         | 1 +
 include/hw/pci-host/q35.h | 7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 35b89da..8471d7a 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -351,6 +351,7 @@ static void mch_reset(DeviceState *qdev)
                  MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
 
     d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
+    d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
 
     mch_update(mch);
 }
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 0fff6a2..d3c7bbb 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -128,7 +128,6 @@ typedef struct Q35PCIHost {
 
 #define MCH_HOST_BRIDGE_SMRAM                  0x9d
 #define MCH_HOST_BRIDGE_SMRAM_SIZE             2
-#define MCH_HOST_BRIDGE_SMRAM_DEFAULT          ((uint8_t)0x2)
 #define MCH_HOST_BRIDGE_SMRAM_D_OPEN           ((uint8_t)(1 << 6))
 #define MCH_HOST_BRIDGE_SMRAM_D_CLS            ((uint8_t)(1 << 5))
 #define MCH_HOST_BRIDGE_SMRAM_D_LCK            ((uint8_t)(1 << 4))
@@ -139,6 +138,8 @@ typedef struct Q35PCIHost {
 #define MCH_HOST_BRIDGE_SMRAM_C_END            0xc0000
 #define MCH_HOST_BRIDGE_SMRAM_C_SIZE           0x20000
 #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END  0x100000
+#define MCH_HOST_BRIDGE_SMRAM_DEFAULT           \
+    MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG
 
 #define MCH_HOST_BRIDGE_ESMRAMC                0x9e
 #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
@@ -151,6 +152,10 @@ typedef struct Q35PCIHost {
 #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB    ((uint8_t)(0x1 << 1))
 #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB    ((uint8_t)(0x2 << 1))
 #define MCH_HOST_BRIDGE_ESMRAMC_T_EN           ((uint8_t)1)
+#define MCH_HOST_BRIDGE_ESMRAMC_DEFAULT \
+    (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \
+     MCH_HOST_BRIDGE_ESMRAMC_SM_L1 |    \
+     MCH_HOST_BRIDGE_ESMRAMC_SM_L2)
 
 /* D1:F0 PCIE* port*/
 #define MCH_PCIE_DEV                           1
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 19/31] q35: add config space wmask for SMRAM and ESMRAMC
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (17 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 18/31] q35: fix ESMRAMC default Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-12  6:55   ` Gerd Hoffmann
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 21/31] q35: add test for SMRAM.D_LCK Paolo Bonzini
                   ` (12 subsequent siblings)
  31 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

From: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/q35.c         | 2 ++
 include/hw/pci-host/q35.h | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 8471d7a..df0032e 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -352,6 +352,8 @@ static void mch_reset(DeviceState *qdev)
 
     d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
     d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
+    d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
+    d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
 
     mch_update(mch);
 }
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index d3c7bbb..01b8492 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -140,6 +140,11 @@ typedef struct Q35PCIHost {
 #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END  0x100000
 #define MCH_HOST_BRIDGE_SMRAM_DEFAULT           \
     MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG
+#define MCH_HOST_BRIDGE_SMRAM_WMASK             \
+    (MCH_HOST_BRIDGE_SMRAM_D_OPEN |             \
+     MCH_HOST_BRIDGE_SMRAM_D_CLS |              \
+     MCH_HOST_BRIDGE_SMRAM_D_LCK |              \
+     MCH_HOST_BRIDGE_SMRAM_G_SMRAME)
 
 #define MCH_HOST_BRIDGE_ESMRAMC                0x9e
 #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
@@ -156,6 +161,10 @@ typedef struct Q35PCIHost {
     (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \
      MCH_HOST_BRIDGE_ESMRAMC_SM_L1 |    \
      MCH_HOST_BRIDGE_ESMRAMC_SM_L2)
+#define MCH_HOST_BRIDGE_ESMRAMC_WMASK               \
+    (MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME |             \
+     MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK |         \
+     MCH_HOST_BRIDGE_ESMRAMC_T_EN)
 
 /* D1:F0 PCIE* port*/
 #define MCH_PCIE_DEV                           1
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 21/31] q35: add test for SMRAM.D_LCK
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (18 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 19/31] q35: add config space wmask for SMRAM and ESMRAMC Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 22/31] q35: implement TSEG Paolo Bonzini
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

From: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/Makefile     |  2 ++
 tests/smram-test.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100644 tests/smram-test.c

diff --git a/tests/Makefile b/tests/Makefile
index 666aee2..b9355dd 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -174,6 +174,7 @@ gcov-files-i386-y += hw/usb/dev-storage.c
 check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF)
 gcov-files-i386-y += hw/usb/hcd-xhci.c
 check-qtest-i386-y += tests/pc-cpu-test$(EXESUF)
+check-qtest-i386-y += tests/smram-test$(EXESUF)
 check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
@@ -389,6 +390,7 @@ tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y)
 tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y)
 tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
 tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
+tests/smram-test$(EXESUF): tests/smram-test.o $(libqos-pc-obj-y)
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y)
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a
diff --git a/tests/smram-test.c b/tests/smram-test.c
new file mode 100644
index 0000000..339d5d1
--- /dev/null
+++ b/tests/smram-test.c
@@ -0,0 +1,80 @@
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "libqos/pci.h"
+#include "libqos/pci-pc.h"
+#include "qemu/osdep.h"
+#include "hw/pci-host/q35.h"
+
+static void smram_set_bit(QPCIDevice *pcidev, uint8_t mask, bool enabled)
+{
+    uint8_t smram;
+
+    smram = qpci_config_readb(pcidev, MCH_HOST_BRIDGE_SMRAM);
+    if (enabled) {
+        smram |= mask;
+    } else {
+        smram &= ~mask;
+    }
+    qpci_config_writeb(pcidev, MCH_HOST_BRIDGE_SMRAM, smram);
+}
+
+static bool smram_test_bit(QPCIDevice *pcidev, uint8_t mask)
+{
+    uint8_t smram;
+
+    smram = qpci_config_readb(pcidev, MCH_HOST_BRIDGE_SMRAM);
+    return smram & mask;
+}
+
+static void test_smram_lock(void)
+{
+    QPCIBus *pcibus;
+    QPCIDevice *pcidev;
+    QDict *response;
+
+    pcibus = qpci_init_pc();
+    g_assert(pcibus != NULL);
+
+    pcidev = qpci_device_find(pcibus, 0);
+    g_assert(pcidev != NULL);
+
+    /* check open is settable */
+    smram_set_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN, false);
+    g_assert(smram_test_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN) == false);
+    smram_set_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN, true);
+    g_assert(smram_test_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN) == true);
+
+    /* lock, check open is cleared & not settable */
+    smram_set_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_LCK, true);
+    g_assert(smram_test_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN) == false);
+    smram_set_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN, true);
+    g_assert(smram_test_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN) == false);
+
+    /* reset */
+    response = qmp("{'execute': 'system_reset', 'arguments': {} }");
+    g_assert(response);
+    g_assert(!qdict_haskey(response, "error"));
+    QDECREF(response);
+
+    /* check open is settable again */
+    smram_set_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN, false);
+    g_assert(smram_test_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN) == false);
+    smram_set_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN, true);
+    g_assert(smram_test_bit(pcidev, MCH_HOST_BRIDGE_SMRAM_D_OPEN) == true);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/smram/lock", test_smram_lock);
+
+    qtest_start("-M q35");
+    ret = g_test_run();
+    qtest_end();
+
+    return ret;
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 22/31] q35: implement TSEG
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (19 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 21/31] q35: add test for SMRAM.D_LCK Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK Paolo Bonzini
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

From: Gerd Hoffmann <kraxel@redhat.com>

TSEG provides larger amounts of SMRAM than the 128 KB available with
legacy SMRAM and high SMRAM.

Route access to tseg into nowhere when enabled, for both cpus and
busmaster dma, and add tseg window to smram region, so cpus can access
it in smm mode.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pci-host/q35.c         | 72 ++++++++++++++++++++++++++++++++++++++++++++++-
 include/hw/pci-host/q35.h |  1 +
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 972d31e..89ff44b 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -198,6 +198,28 @@ static const TypeInfo q35_host_info = {
  * MCH D0:F0
  */
 
+static uint64_t tseg_blackhole_read(void *ptr, hwaddr reg, unsigned size)
+{
+    return 0xffffffff;
+}
+
+static void tseg_blackhole_write(void *opaque, hwaddr addr, uint64_t val,
+                                 unsigned width)
+{
+    /* nothing */
+}
+
+static const MemoryRegionOps tseg_blackhole_ops = {
+    .read = tseg_blackhole_read,
+    .write = tseg_blackhole_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 /* PCIe MMCFG */
 static void mch_update_pciexbar(MCHPCIState *mch)
 {
@@ -267,6 +289,7 @@ static void mch_update_smram(MCHPCIState *mch)
 {
     PCIDevice *pd = PCI_DEVICE(mch);
     bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);
+    uint32_t tseg_size;
 
     /* implement SMRAM.D_LCK */
     if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) {
@@ -296,6 +319,39 @@ static void mch_update_smram(MCHPCIState *mch)
         memory_region_set_enabled(&mch->high_smram, false);
     }
 
+    if (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) {
+        switch (pd->config[MCH_HOST_BRIDGE_ESMRAMC] &
+                MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK) {
+        case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB:
+            tseg_size = 1024 * 1024;
+            break;
+        case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB:
+            tseg_size = 1024 * 1024 * 2;
+            break;
+        case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB:
+            tseg_size = 1024 * 1024 * 8;
+            break;
+        default:
+            tseg_size = 0;
+            break;
+        }
+    } else {
+        tseg_size = 0;
+    }
+    memory_region_del_subregion(mch->system_memory, &mch->tseg_blackhole);
+    memory_region_set_enabled(&mch->tseg_blackhole, tseg_size);
+    memory_region_set_size(&mch->tseg_blackhole, tseg_size);
+    memory_region_add_subregion_overlap(mch->system_memory,
+                                        mch->below_4g_mem_size - tseg_size,
+                                        &mch->tseg_blackhole, 1);
+
+    memory_region_set_enabled(&mch->tseg_window, tseg_size);
+    memory_region_set_size(&mch->tseg_window, tseg_size);
+    memory_region_set_address(&mch->tseg_window,
+                              mch->below_4g_mem_size - tseg_size);
+    memory_region_set_alias_offset(&mch->tseg_window,
+                                   mch->below_4g_mem_size - tseg_size);
+
     memory_region_transaction_commit();
 }
 
@@ -440,9 +496,23 @@ static void mch_realize(PCIDevice *d, Error **errp)
                              mch->ram_memory, 0xa0000, 0x20000);
     memory_region_set_enabled(&mch->high_smram, true);
     memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram);
+
+    memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch),
+                          &tseg_blackhole_ops, NULL,
+                          "tseg-blackhole", 0);
+    memory_region_set_enabled(&mch->tseg_blackhole, false);
+    memory_region_add_subregion_overlap(mch->system_memory,
+                                        mch->below_4g_mem_size,
+                                        &mch->tseg_blackhole, 1);
+
+    memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window",
+                             mch->ram_memory, mch->below_4g_mem_size, 0);
+    memory_region_set_enabled(&mch->tseg_window, false);
+    memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size,
+                                &mch->tseg_window);
+
     object_property_add_const_link(qdev_get_machine(), "smram",
 				   OBJECT(&mch->smram), &error_abort);
-
     init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
              mch->pci_address_space, &mch->pam_regions[0],
              PAM_BIOS_BASE, PAM_BIOS_SIZE);
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 113cbe8..dbe6dc0 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -54,6 +54,7 @@ typedef struct MCHPCIState {
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region, open_high_smram;
     MemoryRegion smram, low_smram, high_smram;
+    MemoryRegion tseg_blackhole, tseg_window;
     PcPciInfo pci_info;
     ram_addr_t below_4g_mem_size;
     ram_addr_t above_4g_mem_size;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (20 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 22/31] q35: implement TSEG Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 15:17   ` Laszlo Ersek
  2015-05-12  7:07   ` Gerd Hoffmann
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 24/31] hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4" Paolo Bonzini
                   ` (9 subsequent siblings)
  31 siblings, 2 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

From: Gerd Hoffmann <kraxel@redhat.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/ich9.c         |  4 +++-
 hw/isa/lpc_ich9.c      | 19 +++++++++++++++++++
 include/hw/acpi/ich9.h |  1 +
 include/hw/i386/ich9.h |  6 ++++++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 5352e19..310aa64 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -94,7 +94,8 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
     ICH9LPCPMRegs *pm = opaque;
     switch (addr) {
     case 0:
-        pm->smi_en = val;
+        pm->smi_en &= ~pm->smi_en_wmask;
+        pm->smi_en |= (val & pm->smi_en_wmask);
         break;
     }
 }
@@ -198,6 +199,7 @@ static void pm_reset(void *opaque)
          * support SMM mode. */
         pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
     }
+    pm->smi_en_wmask = ~0;
 
     acpi_update_sci(&pm->acpi_regs, pm->irq);
 }
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index dba7585..0269cfe 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -410,12 +410,28 @@ static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
     }
 }
 
+/* config:GEN_PMCON* */
+static void
+ich9_lpc_pmcon_update(ICH9LPCState *lpc)
+{
+    uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1);
+    uint16_t wmask;
+
+    if (gen_pmcon_1 & ICH9_LPC_GEN_PMCON_1_SMI_LOCK) {
+        wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1);
+        wmask &= ~ICH9_LPC_GEN_PMCON_1_SMI_LOCK;
+        pci_set_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1, wmask);
+        lpc->pm.smi_en_wmask &= ~1;
+    }
+}
+
 static int ich9_lpc_post_load(void *opaque, int version_id)
 {
     ICH9LPCState *lpc = opaque;
 
     ich9_lpc_pmbase_update(lpc);
     ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
+    ich9_lpc_pmcon_update(lpc);
     return 0;
 }
 
@@ -438,6 +454,9 @@ static void ich9_lpc_config_write(PCIDevice *d,
     if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
         pci_bus_fire_intx_routing_notifier(lpc->d.bus);
     }
+    if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
+        ich9_lpc_pmcon_update(lpc);
+    }
 }
 
 static void ich9_lpc_reset(DeviceState *qdev)
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index c2d3dba..77cc65c 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -39,6 +39,7 @@ typedef struct ICH9LPCPMRegs {
     MemoryRegion io_smi;
 
     uint32_t smi_en;
+    uint32_t smi_en_wmask;
     uint32_t smi_sts;
 
     qemu_irq irq;      /* SCI */
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index f4e522c..a2cc15c 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -152,6 +152,12 @@ Object *ich9_lpc_find(void);
 #define ICH9_LPC_PIRQ_ROUT_MASK                 Q35_MASK(8, 3, 0)
 #define ICH9_LPC_PIRQ_ROUT_DEFAULT              0x80
 
+#define ICH9_LPC_GEN_PMCON_1                    0xa0
+#define ICH9_LPC_GEN_PMCON_1_SMI_LOCK           (1 << 4)
+#define ICH9_LPC_GEN_PMCON_2                    0xa2
+#define ICH9_LPC_GEN_PMCON_3                    0xa4
+#define ICH9_LPC_GEN_PMCON_LOCK                 0xa6
+
 #define ICH9_LPC_RCBA                           0xf0
 #define ICH9_LPC_RCBA_BA_MASK                   Q35_MASK(32, 31, 14)
 #define ICH9_LPC_RCBA_EN                        0x1
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 24/31] hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4"
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (21 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 25/31] hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core Paolo Bonzini
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, mst, Leon Alrae, kraxel, Amit Shah, lersek,
	Aurelien Jarno, Richard Henderson

From: Laszlo Ersek <lersek@redhat.com>

This patch only modifies the function prototype and updates all chipset
code that calls acpi_pm1_cnt_init() to pass in their own disable_s3 and
disable_s4 settings. vt82c686 is assumed to be fixed "S3 and S4 enabled".

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1204696
Cc: Amit Shah <amit.shah@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/core.c         | 3 ++-
 hw/acpi/ich9.c         | 3 ++-
 hw/acpi/piix4.c        | 2 +-
 hw/isa/vt82c686.c      | 2 +-
 include/hw/acpi/acpi.h | 3 ++-
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 51913d6..c19be8f 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -592,7 +592,8 @@ static const MemoryRegionOps acpi_pm_cnt_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, uint8_t s4_val)
+void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
+                       bool disable_s3, bool disable_s4, uint8_t s4_val)
 {
     ar->pm1.cnt.s4_val = s4_val;
     ar->wakeup.notify = acpi_notify_wakeup;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 310aa64..e6eae8c 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -221,7 +221,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
     acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
     acpi_pm1_evt_init(&pm->acpi_regs, ich9_pm_update_sci_fn, &pm->io);
-    acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, pm->s4_val);
+    acpi_pm1_cnt_init(&pm->acpi_regs, &pm->io, pm->disable_s3, pm->disable_s4,
+                      pm->s4_val);
 
     acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN);
     memory_region_init_io(&pm->io_gpe, OBJECT(lpc_pci), &ich9_gpe_ops, pm,
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index d1f1179..321b309 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -464,7 +464,7 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
-    acpi_pm1_cnt_init(&s->ar, &s->io, s->s4_val);
+    acpi_pm1_cnt_init(&s->ar, &s->io, s->disable_s3, s->disable_s4, s->s4_val);
     acpi_gpe_init(&s->ar, GPE_LEN);
 
     s->powerdown_notifier.notify = piix4_pm_powerdown_req;
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index b8197b1..b2ba870 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -356,7 +356,7 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp)
 
     acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
     acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
-    acpi_pm1_cnt_init(&s->ar, &s->io, 2);
+    acpi_pm1_cnt_init(&s->ar, &s->io, false, false, 2);
 }
 
 I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 1f678b4..b0ce094 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -160,7 +160,8 @@ void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                        MemoryRegion *parent);
 
 /* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
-void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, uint8_t s4_val);
+void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
+                       bool disable_s3, bool disable_s4, uint8_t s4_val);
 void acpi_pm1_cnt_update(ACPIREGS *ar,
                          bool sci_enable, bool sci_disable);
 void acpi_pm1_cnt_reset(ACPIREGS *ar);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 25/31] hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (22 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 24/31] hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4" Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 26/31] hw/acpi: piix4_pm_init(): take fw_cfg object no more Paolo Bonzini
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, mst, Leon Alrae, kraxel, Amit Shah, lersek,
	Aurelien Jarno, Richard Henderson

From: Laszlo Ersek <lersek@redhat.com>

The acpi_pm1_cnt_init() core function is responsible for setting up the
register block that will ultimately react to S3 and S4 requests (see
acpi_pm1_cnt_write()). It makes sense to advertise this configuration to
the guest firmware via an easy to parse fw_cfg file (ACPI is too complex
for firmware to parse), and indeed PIIX4 does that. However, since
acpi_pm1_cnt_init() is not specific to PIIX4, neither should be the fw_cfg
file.

This patch makes "etc/system-states" appear on all chipsets modified in
the previous patch, not just PIIX4 (assuming they have fw_cfg at all).

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1204696
Cc: Amit Shah <amit.shah@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/core.c  | 12 ++++++++++++
 hw/acpi/piix4.c |  8 --------
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index c19be8f..f70377f 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -22,6 +22,7 @@
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
 #include "hw/acpi/acpi.h"
+#include "hw/nvram/fw_cfg.h"
 #include "qemu/config-file.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/dealloc-visitor.h"
@@ -595,12 +596,23 @@ static const MemoryRegionOps acpi_pm_cnt_ops = {
 void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent,
                        bool disable_s3, bool disable_s4, uint8_t s4_val)
 {
+    FWCfgState *fw_cfg;
+
     ar->pm1.cnt.s4_val = s4_val;
     ar->wakeup.notify = acpi_notify_wakeup;
     qemu_register_wakeup_notifier(&ar->wakeup);
     memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent),
                           &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
     memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
+
+    fw_cfg = fw_cfg_find();
+    if (fw_cfg) {
+        uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
+        suspend[3] = 1 | ((!disable_s3) << 7);
+        suspend[4] = s4_val | ((!disable_s4) << 7);
+
+        fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
+    }
 }
 
 void acpi_pm1_cnt_reset(ACPIREGS *ar)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 321b309..c53a31a 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -514,14 +514,6 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
 
     qdev_init_nofail(dev);
 
-    if (fw_cfg) {
-        uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
-        suspend[3] = 1 | ((!s->disable_s3) << 7);
-        suspend[4] = s->s4_val | ((!s->disable_s4) << 7);
-
-        fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
-    }
-
     return s->smb.smbus;
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 26/31] hw/acpi: piix4_pm_init(): take fw_cfg object no more
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (23 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 25/31] hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 27/31] target-i386: add support for SMBASE MSR and SMIs Paolo Bonzini
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, mst, Leon Alrae, kraxel, Amit Shah, lersek,
	Aurelien Jarno, Richard Henderson

From: Laszlo Ersek <lersek@redhat.com>

This PIIX4 init function has no more reason to receive a pointer to the
FwCfg object. Remove the parameter from the prototype, and update callers.

As a result, the pc_init1() function no longer needs to save the return
value of pc_memory_init() and xen_load_linux(), which makes it more
similar to pc_q35_init().

The return type & value of pc_memory_init() and xen_load_linux() are not
changed themselves; maybe we'll need their return values sometime later.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1204696
Cc: Amit Shah <amit.shah@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/piix4.c      |  3 +--
 hw/i386/pc_piix.c    | 19 +++++++++----------
 hw/mips/mips_malta.c |  2 +-
 include/hw/i386/pc.h |  3 +--
 4 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index c53a31a..1e8e174 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -492,8 +492,7 @@ Object *piix4_pm_find(void)
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int kvm_enabled, FWCfgState *fw_cfg,
-                      DeviceState **piix4_pm)
+                      int kvm_enabled, DeviceState **piix4_pm)
 {
     DeviceState *dev;
     PIIX4PMState *s;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 212e263..7d75a51 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -99,7 +99,6 @@ static void pc_init1(MachineState *machine,
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
     DeviceState *icc_bridge;
-    FWCfgState *fw_cfg = NULL;
     PcGuestInfo *guest_info;
     ram_addr_t lowmem;
 
@@ -180,16 +179,16 @@ static void pc_init1(MachineState *machine,
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
-        fw_cfg = pc_memory_init(machine, system_memory,
-                                below_4g_mem_size, above_4g_mem_size,
-                                rom_memory, &ram_memory, guest_info);
+        pc_memory_init(machine, system_memory,
+                       below_4g_mem_size, above_4g_mem_size,
+                       rom_memory, &ram_memory, guest_info);
     } else if (machine->kernel_filename != NULL) {
         /* For xen HVM direct kernel boot, load linux here */
-        fw_cfg = xen_load_linux(machine->kernel_filename,
-                                machine->kernel_cmdline,
-                                machine->initrd_filename,
-                                below_4g_mem_size,
-                                guest_info);
+        xen_load_linux(machine->kernel_filename,
+                       machine->kernel_cmdline,
+                       machine->initrd_filename,
+                       below_4g_mem_size,
+                       guest_info);
     }
 
     gsi_state = g_malloc0(sizeof(*gsi_state));
@@ -288,7 +287,7 @@ static void pc_init1(MachineState *machine,
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                               gsi[9], *smi_irq,
-                              kvm_enabled(), fw_cfg, &piix4_pm);
+                              kvm_enabled(), &piix4_pm);
         smbus_eeprom_init(smbus, 8, NULL, 0);
 
         object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 482250d..5140882 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1161,7 +1161,7 @@ void mips_malta_init(MachineState *machine)
     pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
     pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
-                          isa_get_irq(NULL, 9), NULL, 0, NULL, NULL);
+                          isa_get_irq(NULL, 9), NULL, 0, NULL);
     smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
     g_free(smbus_eeprom_buf);
     pit = pit_init(isa_bus, 0x40, 0, NULL);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c9a9f6e..74cece1 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -218,8 +218,7 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int kvm_enabled, FWCfgState *fw_cfg,
-                      DeviceState **piix4_pm);
+                      int kvm_enabled, DeviceState **piix4_pm);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 
 /* hpet.c */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 27/31] target-i386: add support for SMBASE MSR and SMIs
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (24 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 26/31] hw/acpi: piix4_pm_init(): take fw_cfg object no more Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 28/31] vga: disable chain4_alias if KVM supports SMRAM Paolo Bonzini
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Apart from the MSR, the smi field of struct kvm_vcpu_events has to be
translated into the corresponding CPUX86State fields.  Also,
memory transaction flags depend on SMM state, so pull it from struct
kvm_run on every exit from KVM to userspace.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 linux-headers/asm-x86/kvm.h | 11 ++++++-
 linux-headers/linux/kvm.h   |  5 +++-
 target-i386/cpu.h           |  1 +
 target-i386/kvm.c           | 73 ++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
index d7dcef5..cf84866 100644
--- a/linux-headers/asm-x86/kvm.h
+++ b/linux-headers/asm-x86/kvm.h
@@ -48,6 +48,8 @@
 /* Architectural interrupt line count. */
 #define KVM_NR_INTERRUPTS 256
 
+#define KVM_RUN_X86_SMM (1 << 0)
+
 struct kvm_memory_alias {
 	__u32 slot;  /* this has a different namespace than memory slots */
 	__u32 flags;
@@ -281,6 +283,7 @@ struct kvm_reinject_control {
 #define KVM_VCPUEVENT_VALID_NMI_PENDING	0x00000001
 #define KVM_VCPUEVENT_VALID_SIPI_VECTOR	0x00000002
 #define KVM_VCPUEVENT_VALID_SHADOW	0x00000004
+#define KVM_VCPUEVENT_VALID_SMM		0x00000008
 
 /* Interrupt shadow states */
 #define KVM_X86_SHADOW_INT_MOV_SS	0x01
@@ -309,7 +312,13 @@ struct kvm_vcpu_events {
 	} nmi;
 	__u32 sipi_vector;
 	__u32 flags;
-	__u32 reserved[10];
+	struct {
+		__u8 smm;
+		__u8 pending;
+		__u8 smm_inside_nmi;
+		__u8 pad;
+	} smi;
+	__u32 reserved[9];
 };
 
 /* for KVM_GET/SET_DEBUGREGS */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index b96d978..15beebb 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -202,7 +202,7 @@ struct kvm_run {
 	__u32 exit_reason;
 	__u8 ready_for_interrupt_injection;
 	__u8 if_flag;
-	__u8 padding2[2];
+	__u16 flags;
 
 	/* in (pre_kvm_run), out (post_kvm_run) */
 	__u64 cr8;
@@ -814,6 +814,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_S390_INJECT_IRQ 113
 #define KVM_CAP_S390_IRQ_STATE 114
 #define KVM_CAP_PPC_HWRNG 115
+#define KVM_CAP_X86_SMM 116
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1199,6 +1200,8 @@ struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_S390_IRQ_STATE */
 #define KVM_S390_SET_IRQ_STATE	  _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state)
 #define KVM_S390_GET_IRQ_STATE	  _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
+/* Available with KVM_CAP_X86_SMM */
+#define KVM_SMI                   _IO(KVMIO,   0xb7)
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index df6e885..684e3a0 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -314,6 +314,7 @@
 
 #define MSR_P6_PERFCTR0                 0xc1
 
+#define MSR_IA32_SMBASE                 0x9e
 #define MSR_MTRRcap                     0xfe
 #define MSR_MTRRcap_VCNT                8
 #define MSR_MTRRcap_FIXRANGE_SUPPORT    (1 << 8)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 009bf74..09b4fc7 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -74,6 +74,7 @@ static bool has_msr_feature_control;
 static bool has_msr_async_pf_en;
 static bool has_msr_pv_eoi_en;
 static bool has_msr_misc_enable;
+static bool has_msr_smbase;
 static bool has_msr_bndcfgs;
 static bool has_msr_kvm_steal_time;
 static int lm_capable_kernel;
@@ -820,6 +821,10 @@ static int kvm_get_supported_msrs(KVMState *s)
                     has_msr_tsc_deadline = true;
                     continue;
                 }
+                if (kvm_msr_list->indices[i] == MSR_IA32_SMBASE) {
+                    has_msr_smbase = true;
+                    continue;
+                }
                 if (kvm_msr_list->indices[i] == MSR_IA32_MISC_ENABLE) {
                     has_msr_misc_enable = true;
                     continue;
@@ -1246,6 +1251,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
         kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE,
                           env->msr_ia32_misc_enable);
     }
+    if (has_msr_smbase) {
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_SMBASE, env->smbase);
+    }
     if (has_msr_bndcfgs) {
         kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs);
     }
@@ -1607,6 +1615,9 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_misc_enable) {
         msrs[n++].index = MSR_IA32_MISC_ENABLE;
     }
+    if (has_msr_smbase) {
+        msrs[n++].index = MSR_IA32_SMBASE;
+    }
     if (has_msr_feature_control) {
         msrs[n++].index = MSR_IA32_FEATURE_CONTROL;
     }
@@ -1761,6 +1772,9 @@ static int kvm_get_msrs(X86CPU *cpu)
         case MSR_IA32_MISC_ENABLE:
             env->msr_ia32_misc_enable = msrs[i].data;
             break;
+        case MSR_IA32_SMBASE:
+            env->smbase = msrs[i].data;
+            break;
         case MSR_IA32_FEATURE_CONTROL:
             env->msr_ia32_feature_control = msrs[i].data;
             break;
@@ -1948,6 +1962,16 @@ static int kvm_put_vcpu_events(X86CPU *cpu, int level)
 
     events.sipi_vector = env->sipi_vector;
 
+    if (has_msr_smbase) {
+        events.smi.smm = !!(env->hflags & HF_SMM_MASK);
+        /* smi.pending is stored as CPU_INTERRUPT_SMI in cpu->interrupt_request.
+         * It is transferred to the kernel before the next vmentry
+         */
+        events.smi.pending = 0;
+        events.smi.smm_inside_nmi = !!(env->hflags2 & HF2_SMM_INSIDE_NMI_MASK);
+        events.flags |= KVM_VCPUEVENT_VALID_SMM;
+    }
+
     events.flags = 0;
     if (level >= KVM_PUT_RESET_STATE) {
         events.flags |=
@@ -1967,6 +1991,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu)
         return 0;
     }
 
+    memset(&events, 0, sizeof(events));
     ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_VCPU_EVENTS, &events);
     if (ret < 0) {
        return ret;
@@ -1988,6 +2013,24 @@ static int kvm_get_vcpu_events(X86CPU *cpu)
         env->hflags2 &= ~HF2_NMI_MASK;
     }
 
+    if (events.flags & KVM_VCPUEVENT_VALID_SMM) {
+        if (events.smi.smm) {
+            env->hflags |= HF_SMM_MASK;
+        } else {
+            env->hflags &= ~HF_SMM_MASK;
+        }
+        if (events.smi.pending) {
+            cpu_interrupt(CPU(cpu), CPU_INTERRUPT_SMI);
+        } else {
+            cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_SMI);
+        }
+        if (events.smi.smm_inside_nmi) {
+            env->hflags2 |= HF2_SMM_INSIDE_NMI_MASK;
+        } else {
+            env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
+        }
+    }
+
     env->sipi_vector = events.sipi_vector;
 
     return 0;
@@ -2191,13 +2234,24 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
     int ret;
 
     /* Inject NMI */
-    if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
-        cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
-        DPRINTF("injected NMI\n");
-        ret = kvm_vcpu_ioctl(cpu, KVM_NMI);
-        if (ret < 0) {
-            fprintf(stderr, "KVM: injection failed, NMI lost (%s)\n",
-                    strerror(-ret));
+    if (cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
+        if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
+            cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
+            DPRINTF("injected NMI\n");
+            ret = kvm_vcpu_ioctl(cpu, KVM_NMI);
+            if (ret < 0) {
+                fprintf(stderr, "KVM: injection failed, NMI lost (%s)\n",
+                        strerror(-ret));
+            }
+        }
+        if (cpu->interrupt_request & CPU_INTERRUPT_SMI) {
+            cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
+            DPRINTF("injected SMI\n");
+            ret = kvm_vcpu_ioctl(cpu, KVM_SMI);
+            if (ret < 0) {
+                fprintf(stderr, "KVM: injection failed, SMI lost (%s)\n",
+                        strerror(-ret));
+            }
         }
     }
 
@@ -2252,6 +2306,11 @@ MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run)
     X86CPU *x86_cpu = X86_CPU(cpu);
     CPUX86State *env = &x86_cpu->env;
 
+    if (run->flags & KVM_RUN_X86_SMM) {
+        env->hflags |= HF_SMM_MASK;
+    } else {
+        env->hflags &= HF_SMM_MASK;
+    }
     if (run->if_flag) {
         env->eflags |= IF_MASK;
     } else {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 28/31] vga: disable chain4_alias if KVM supports SMRAM
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (25 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 27/31] target-i386: add support for SMBASE MSR and SMIs Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-19 11:51   ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 29/31] pc_piix: rename kvm_enabled to smm_enabled Paolo Bonzini
                   ` (4 subsequent siblings)
  31 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

KVM is okay with SMRAM overlapping an MMIO area underneath it, but it does
not want to have two overlapping RAM slots for SMRAM and video RAM.
Unfortunately, the chain4_alias optimization results in the latter
situation.  Disable it if KVM supports system management mode.

Note that the chain4_alias optimization is misguided, because it assumes
that chain4 data is at VRAM address 0,1,2,3,4,5,6,7...16383.  This is
incorrect, because chain4 data is at VRAM address 0,1,2,3, 16,17,18,19,
..., 65523.  But we cannot fix the VRAM format without breaking migration,
so keep the optimization and just disable it if it gets in the way.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/display/vga.c     | 8 ++++++--
 hw/display/vga_int.h | 1 +
 include/sysemu/kvm.h | 1 +
 kvm-all.c            | 5 +++++
 kvm-stub.c           | 5 +++++
 5 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index d1d296c..b1925a0 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -154,7 +154,8 @@ static void vga_update_memory_access(VGACommonState *s)
         s->has_chain4_alias = false;
         s->plane_updated = 0xf;
     }
-    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
+    if (s->use_chain4_alias &&
+	(s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
         VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
         offset = 0;
         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
@@ -2219,8 +2220,11 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
 
     qemu_register_reset(vga_reset, s);
 
-    s->bank_offset = 0;
+    if (!kvm_enabled() || !kvm_has_smm()) {
+        s->use_chain4_alias = true;
+    }
 
+    s->bank_offset = 0;
     s->legacy_address_space = address_space;
 
     vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index fcfcc5f..646e64c 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -95,6 +95,7 @@ typedef struct VGACommonState {
     uint32_t vram_size_mb; /* property */
     uint32_t vbe_size;
     uint32_t latch;
+    bool use_chain4_alias;
     bool has_chain4_alias;
     MemoryRegion chain4_alias;
     uint8_t sr_index;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 4878959..e1db979 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -186,6 +186,7 @@ int kvm_has_pit_state2(void);
 int kvm_has_many_ioeventfds(void);
 int kvm_has_gsi_routing(void);
 int kvm_has_intx_set_mask(void);
+int kvm_has_smm(void);
 
 int kvm_init_vcpu(CPUState *cpu);
 int kvm_cpu_exec(CPUState *cpu);
diff --git a/kvm-all.c b/kvm-all.c
index 17a3771..5ad4877 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1990,6 +1990,11 @@ int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr)
     return ret ? 0 : 1;
 }
 
+int kvm_has_smm(void)
+{
+    return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
+}
+
 int kvm_has_sync_mmu(void)
 {
     return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);
diff --git a/kvm-stub.c b/kvm-stub.c
index 7ba90c5..c3428a5 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -56,6 +56,11 @@ int kvm_cpu_exec(CPUState *cpu)
     abort();
 }
 
+int kvm_has_smm(void)
+{
+    return 0;
+}
+
 int kvm_has_sync_mmu(void)
 {
     return 0;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 29/31] pc_piix: rename kvm_enabled to smm_enabled
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (26 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 28/31] vga: disable chain4_alias if KVM supports SMRAM Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 30/31] ich9: add smm_enabled field and arguments Paolo Bonzini
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

We will enable SMM even if KVM is in use.  Rename the field and
arguments.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/piix4.c      | 10 +++++-----
 include/hw/i386/pc.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 1e8e174..dcbecd9 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -72,7 +72,7 @@ typedef struct PIIX4PMState {
 
     qemu_irq irq;
     qemu_irq smi_irq;
-    int kvm_enabled;
+    int smm_enabled;
     Notifier machine_ready;
     Notifier powerdown_notifier;
 
@@ -321,7 +321,7 @@ static void piix4_reset(void *opaque)
     pci_conf[0x40] = 0x01; /* PM io base read only bit */
     pci_conf[0x80] = 0;
 
-    if (s->kvm_enabled) {
+    if (!s->smm_enabled) {
         /* Mark SMM as already inited (until KVM supports SMM). */
         pci_conf[0x5B] = 0x02;
     }
@@ -441,7 +441,7 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
     /* APM */
     apm_init(dev, &s->apm, apm_ctrl_changed, s);
 
-    if (s->kvm_enabled) {
+    if (!s->smm_enabled) {
         /* Mark SMM as already inited to prevent SMM from running.  KVM does not
          * support SMM mode. */
         pci_conf[0x5B] = 0x02;
@@ -492,7 +492,7 @@ Object *piix4_pm_find(void)
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int kvm_enabled, DeviceState **piix4_pm)
+                      int smm_enabled, DeviceState **piix4_pm)
 {
     DeviceState *dev;
     PIIX4PMState *s;
@@ -506,7 +506,7 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     s = PIIX4_PM(dev);
     s->irq = sci_irq;
     s->smi_irq = smi_irq;
-    s->kvm_enabled = kvm_enabled;
+    s->smm_enabled = smm_enabled;
     if (xen_enabled()) {
         s->use_acpi_pci_hotplug = false;
     }
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 74cece1..3898f65 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -218,7 +218,7 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int kvm_enabled, DeviceState **piix4_pm);
+                      int smm_enabled, DeviceState **piix4_pm);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 
 /* hpet.c */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 30/31] ich9: add smm_enabled field and arguments
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (27 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 29/31] pc_piix: rename kvm_enabled to smm_enabled Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 31/31] pc: add SMM property Paolo Bonzini
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Q35's ACPI device is hard-coding SMM availability to KVM.  Place the
logic where the board is created instead, so that it will be possible
to override it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/ich9.c         | 5 +++--
 hw/i386/pc_q35.c       | 2 +-
 hw/isa/lpc_ich9.c      | 4 ++--
 include/hw/acpi/ich9.h | 3 ++-
 include/hw/i386/ich9.h | 2 +-
 5 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index e6eae8c..86deb2b 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -194,7 +194,7 @@ static void pm_reset(void *opaque)
     acpi_pm_tmr_reset(&pm->acpi_regs);
     acpi_gpe_reset(&pm->acpi_regs);
 
-    if (kvm_enabled()) {
+    if (!pm->smm_enabled) {
         /* Mark SMM as already inited to prevent SMM from running. KVM does not
          * support SMM mode. */
         pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
@@ -211,7 +211,7 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
     acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
+void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, bool smm_enabled,
                   qemu_irq sci_irq)
 {
     memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE);
@@ -233,6 +233,7 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
                           "acpi-smi", 8);
     memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
 
+    pm->smm_enabled = smm_enabled;
     pm->irq = sci_irq;
     qemu_register_reset(pm_reset, pm);
     pm->powerdown_notifier.notify = pm_powerdown_req;
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index e67f2de..ad8bb2a 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -254,7 +254,7 @@ static void pc_q35_init(MachineState *machine)
                          (pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104);
 
     /* connect pm stuff to lpc */
-    ich9_lpc_pm_init(lpc);
+    ich9_lpc_pm_init(lpc, kvm_enabled());
 
     /* ahci and SATA device, for q35 1 ahci controller is built-in */
     ahci = pci_create_simple_multifunction(host_bus,
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 0269cfe..ac0e63e 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -357,13 +357,13 @@ static void ich9_set_sci(void *opaque, int irq_num, int level)
     }
 }
 
-void ich9_lpc_pm_init(PCIDevice *lpc_pci)
+void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
     qemu_irq *sci_irq;
 
     sci_irq = qemu_allocate_irqs(ich9_set_sci, lpc, 1);
-    ich9_pm_init(lpc_pci, &lpc->pm, sci_irq[0]);
+    ich9_pm_init(lpc_pci, &lpc->pm, smm_enabled, sci_irq[0]);
 
     ich9_lpc_reset(&lpc->d.qdev);
 }
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 77cc65c..ac24bbe 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -54,10 +54,11 @@ typedef struct ICH9LPCPMRegs {
     uint8_t disable_s3;
     uint8_t disable_s4;
     uint8_t s4_val;
+    uint8_t smm_enabled;
 } ICH9LPCPMRegs;
 
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
-                  qemu_irq sci_irq);
+                  bool smm_enabled, qemu_irq sci_irq);
 void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base);
 extern const VMStateDescription vmstate_ich9_pm;
 
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index a2cc15c..b317a48 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -17,7 +17,7 @@
 void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
 int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
 PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
-void ich9_lpc_pm_init(PCIDevice *pci_lpc);
+void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
 I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
 
 #define ICH9_CC_SIZE                            (16 * 1024)     /* 16KB */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [Qemu-devel] [PATCH 31/31] pc: add SMM property
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (28 preceding siblings ...)
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 30/31] ich9: add smm_enabled field and arguments Paolo Bonzini
@ 2015-05-11 13:49 ` Paolo Bonzini
       [not found] ` <1431352157-40283-21-git-send-email-pbonzini@redhat.com>
  2015-05-31 18:10 ` [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Michael S. Tsirkin
  31 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 13:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/pc.c         | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/i386/pc_piix.c    |  7 ++++++-
 hw/i386/pc_q35.c     |  7 ++++++-
 include/hw/i386/pc.h |  3 +++
 4 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a7ee9ef..3a005a3 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1790,6 +1790,48 @@ static void pc_machine_set_vmport(Object *obj, Visitor *v, void *opaque,
     visit_type_OnOffAuto(v, &pcms->vmport, name, errp);
 }
 
+bool pc_machine_is_smm_enabled(PCMachineState *pcms)
+{
+    bool smm_available = false;
+
+    if (pcms->smm == ON_OFF_AUTO_OFF) {
+        return false;
+    }
+
+    if (tcg_enabled() || qtest_enabled()) {
+        smm_available = true;
+    } else if (kvm_enabled()) {
+        smm_available = kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
+    }
+
+    if (smm_available) {
+        return true;
+    }
+
+    if (pcms->smm == ON_OFF_AUTO_ON) {
+        error_report("System Management Mode not supported by this hypervisor.");
+        exit(1);
+    }
+    return false;
+}
+
+static void pc_machine_get_smm(Object *obj, Visitor *v, void *opaque,
+                              const char *name, Error **errp)
+{
+    PCMachineState *pcms = PC_MACHINE(obj);
+    OnOffAuto smm = pcms->smm;
+
+    visit_type_OnOffAuto(v, &smm, name, errp);
+}
+
+static void pc_machine_set_smm(Object *obj, Visitor *v, void *opaque,
+                                  const char *name, Error **errp)
+{
+    PCMachineState *pcms = PC_MACHINE(obj);
+
+    visit_type_OnOffAuto(v, &pcms->smm, name, errp);
+}
+
 static bool pc_machine_get_aligned_dimm(Object *obj, Error **errp)
 {
     PCMachineState *pcms = PC_MACHINE(obj);
@@ -1814,6 +1856,15 @@ static void pc_machine_initfn(Object *obj)
                                     "Maximum ram below the 4G boundary (32bit boundary)",
                                     NULL);
 
+    pcms->smm = ON_OFF_AUTO_AUTO;
+    object_property_add(obj, PC_MACHINE_SMM, "OnOffAuto",
+                        pc_machine_get_smm,
+                        pc_machine_set_smm,
+                        NULL, NULL, NULL);
+    object_property_set_description(obj, PC_MACHINE_SMM,
+                                    "Enable SMM (pc & q35)",
+                                    NULL);
+
     pcms->vmport = ON_OFF_AUTO_AUTO;
     object_property_add(obj, PC_MACHINE_VMPORT, "OnOffAuto",
                         pc_machine_get_vmport,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7d75a51..de6fcb9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -287,7 +287,8 @@ static void pc_init1(MachineState *machine,
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                               gsi[9], *smi_irq,
-                              kvm_enabled(), &piix4_pm);
+                              pc_machine_is_smm_enabled(pc_machine),
+                              &piix4_pm);
         smbus_eeprom_init(smbus, 8, NULL, 0);
 
         object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
@@ -311,6 +312,10 @@ static void pc_init_pci(MachineState *machine)
 
 static void pc_compat_2_3(MachineState *machine)
 {
+    PCMachineState *pcms = PC_MACHINE(machine);
+    if (kvm_enabled()) {
+        pcms->smm = ON_OFF_AUTO_OFF;
+    }
 }
 
 static void pc_compat_2_2(MachineState *machine)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index ad8bb2a..683e40c 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -254,7 +254,7 @@ static void pc_q35_init(MachineState *machine)
                          (pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104);
 
     /* connect pm stuff to lpc */
-    ich9_lpc_pm_init(lpc, kvm_enabled());
+    ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pc_machine));
 
     /* ahci and SATA device, for q35 1 ahci controller is built-in */
     ahci = pci_create_simple_multifunction(host_bus,
@@ -291,6 +291,11 @@ static void pc_q35_init(MachineState *machine)
 
 static void pc_compat_2_3(MachineState *machine)
 {
+    /* FIXME -> 2.3 */
+    PCMachineState *pcms = PC_MACHINE(machine);
+    if (kvm_enabled()) {
+        pcms->smm = ON_OFF_AUTO_OFF;
+    }
 }
 
 static void pc_compat_2_2(MachineState *machine)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3898f65..f0cfd1d 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -40,6 +40,7 @@ struct PCMachineState {
 
     uint64_t max_ram_below_4g;
     OnOffAuto vmport;
+    OnOffAuto smm;
     bool enforce_aligned_dimm;
 };
 
@@ -47,6 +48,7 @@ struct PCMachineState {
 #define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size"
 #define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g"
 #define PC_MACHINE_VMPORT           "vmport"
+#define PC_MACHINE_SMM              "smm"
 #define PC_MACHINE_ENFORCE_ALIGNED_DIMM "enforce-aligned-dimm"
 
 /**
@@ -160,6 +162,7 @@ void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out);
 /* pc.c */
 extern int fd_bootchk;
 
+bool pc_machine_is_smm_enabled(PCMachineState *pcms);
 void pc_register_ferr_irq(qemu_irq irq);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link Paolo Bonzini
@ 2015-05-11 14:40   ` Laszlo Ersek
  2015-05-19 11:50   ` Paolo Bonzini
  2015-05-19 19:14   ` Eduardo Habkost
  2 siblings, 0 replies; 58+ messages in thread
From: Laszlo Ersek @ 2015-05-11 14:40 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: kraxel, mst

On 05/11/15 15:48, Paolo Bonzini wrote:
> Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qom/object.h | 18 ++++++++++++++++++
>  qom/object.c         | 16 ++++++++++++++++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index d2d7748..0505f20 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -1290,6 +1290,24 @@ void object_property_add_alias(Object *obj, const char *name,
>                                 Error **errp);
>  
>  /**
> + * object_property_add_const_link:
> + * @obj: the object to add a property to
> + * @name: the name of the property
> + * @target: the object to be referred by the link
> + * @errp: if an error occurs, a pointer to an area to store the error
> + *
> + * Add an unmodifiable link for a property on an object.  This function will
> + * add a property of type link<TYPE> where TYPE is the type of @target.
> + *
> + * The caller must ensure that @target stays alive as long as
> + * this property exists.  In the case @target is a child of @obj,
> + * this will be the case.  Otherwise, the caller is responsible for
> + * taking a reference.
> + */
> +void object_property_add_const_link(Object *obj, const char *name,
> +                                    Object *target, Error **errp);
> +
> +/**
>   * object_property_set_description:
>   * @obj: the object owning the property
>   * @name: the name of the property
> diff --git a/qom/object.c b/qom/object.c
> index b8dff43..ba89518 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1266,6 +1266,22 @@ out:
>      g_free(full_type);
>  }
>  
> +void object_property_add_const_link(Object *obj, const char *name,
> +                                    Object *target, Error **errp)
> +{
> +    char *link_type;
> +    ObjectProperty *op;
> +   

git-am complained about trailing whitespace on the line above.

(Sorry that's all I can "contribute" now; I'll start using the series
for developing OVMF further on.)

Thanks
Laszlo

> +    link_type = g_strdup_printf("link<%s>", object_get_typename(target));
> +    op = object_property_add(obj, name, link_type,
> +                             object_get_child_property, NULL,
> +                             NULL, target, errp);
> +    if (op != NULL) {
> +        op->resolve = object_resolve_child_property;
> +    }
> +    g_free(link_type);
> +}
> +
>  gchar *object_get_canonical_path_component(Object *obj)
>  {
>      ObjectProperty *prop = NULL;
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK Paolo Bonzini
@ 2015-05-11 15:17   ` Laszlo Ersek
  2015-05-11 15:21     ` Paolo Bonzini
  2015-05-12  7:07   ` Gerd Hoffmann
  1 sibling, 1 reply; 58+ messages in thread
From: Laszlo Ersek @ 2015-05-11 15:17 UTC (permalink / raw)
  To: Paolo Bonzini, kraxel; +Cc: qemu-devel, mst

On 05/11/15 15:49, Paolo Bonzini wrote:
> From: Gerd Hoffmann <kraxel@redhat.com>
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/acpi/ich9.c         |  4 +++-
>  hw/isa/lpc_ich9.c      | 19 +++++++++++++++++++
>  include/hw/acpi/ich9.h |  1 +
>  include/hw/i386/ich9.h |  6 ++++++
>  4 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index 5352e19..310aa64 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -94,7 +94,8 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
>      ICH9LPCPMRegs *pm = opaque;
>      switch (addr) {
>      case 0:
> -        pm->smi_en = val;
> +        pm->smi_en &= ~pm->smi_en_wmask;
> +        pm->smi_en |= (val & pm->smi_en_wmask);
>          break;
>      }
>  }
> @@ -198,6 +199,7 @@ static void pm_reset(void *opaque)
>           * support SMM mode. */
>          pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
>      }
> +    pm->smi_en_wmask = ~0;
>  
>      acpi_update_sci(&pm->acpi_regs, pm->irq);
>  }
> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> index dba7585..0269cfe 100644
> --- a/hw/isa/lpc_ich9.c
> +++ b/hw/isa/lpc_ich9.c
> @@ -410,12 +410,28 @@ static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
>      }
>  }
>  
> +/* config:GEN_PMCON* */
> +static void
> +ich9_lpc_pmcon_update(ICH9LPCState *lpc)
> +{
> +    uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1);
> +    uint16_t wmask;
> +
> +    if (gen_pmcon_1 & ICH9_LPC_GEN_PMCON_1_SMI_LOCK) {
> +        wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1);
> +        wmask &= ~ICH9_LPC_GEN_PMCON_1_SMI_LOCK;
> +        pci_set_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1, wmask);
> +        lpc->pm.smi_en_wmask &= ~1;

If I understand correctly, this makes SMI_LOCK lock down the GBL_SMI_EN
bit (and my OVMF patch that relies on that / tests it is satisfied too).

But, it doesn't seem to lock down APMC_EN. According to the ICH9 spec,
it doesn't need to -- however when we discussed this earlier (see
Message-Id: <553F4D23.3060305@redhat.com>), the idea was to lock down
APMC_EN as well. (And I don't understand why the ICH9 spec / hw
implementation doesn't lock APMC_EN; without that, APM_CNT won't
necessarily trigger an SMI.)

Thanks!
Laszlo

> +    }
> +}
> +
>  static int ich9_lpc_post_load(void *opaque, int version_id)
>  {
>      ICH9LPCState *lpc = opaque;
>  
>      ich9_lpc_pmbase_update(lpc);
>      ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
> +    ich9_lpc_pmcon_update(lpc);
>      return 0;
>  }
>  
> @@ -438,6 +454,9 @@ static void ich9_lpc_config_write(PCIDevice *d,
>      if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
>          pci_bus_fire_intx_routing_notifier(lpc->d.bus);
>      }
> +    if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
> +        ich9_lpc_pmcon_update(lpc);
> +    }
>  }
>  
>  static void ich9_lpc_reset(DeviceState *qdev)
> diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> index c2d3dba..77cc65c 100644
> --- a/include/hw/acpi/ich9.h
> +++ b/include/hw/acpi/ich9.h
> @@ -39,6 +39,7 @@ typedef struct ICH9LPCPMRegs {
>      MemoryRegion io_smi;
>  
>      uint32_t smi_en;
> +    uint32_t smi_en_wmask;
>      uint32_t smi_sts;
>  
>      qemu_irq irq;      /* SCI */
> diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
> index f4e522c..a2cc15c 100644
> --- a/include/hw/i386/ich9.h
> +++ b/include/hw/i386/ich9.h
> @@ -152,6 +152,12 @@ Object *ich9_lpc_find(void);
>  #define ICH9_LPC_PIRQ_ROUT_MASK                 Q35_MASK(8, 3, 0)
>  #define ICH9_LPC_PIRQ_ROUT_DEFAULT              0x80
>  
> +#define ICH9_LPC_GEN_PMCON_1                    0xa0
> +#define ICH9_LPC_GEN_PMCON_1_SMI_LOCK           (1 << 4)
> +#define ICH9_LPC_GEN_PMCON_2                    0xa2
> +#define ICH9_LPC_GEN_PMCON_3                    0xa4
> +#define ICH9_LPC_GEN_PMCON_LOCK                 0xa6
> +
>  #define ICH9_LPC_RCBA                           0xf0
>  #define ICH9_LPC_RCBA_BA_MASK                   Q35_MASK(32, 31, 14)
>  #define ICH9_LPC_RCBA_EN                        0x1
> 

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK
  2015-05-11 15:17   ` Laszlo Ersek
@ 2015-05-11 15:21     ` Paolo Bonzini
  2015-05-11 15:36       ` Laszlo Ersek
  0 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 15:21 UTC (permalink / raw)
  To: Laszlo Ersek, kraxel; +Cc: qemu-devel, mst



On 11/05/2015 17:17, Laszlo Ersek wrote:
> If I understand correctly, this makes SMI_LOCK lock down the GBL_SMI_EN
> bit (and my OVMF patch that relies on that / tests it is satisfied too).
> 
> But, it doesn't seem to lock down APMC_EN. According to the ICH9 spec,
> it doesn't need to -- however when we discussed this earlier (see
> Message-Id: <553F4D23.3060305@redhat.com>), the idea was to lock down
> APMC_EN as well. (And I don't understand why the ICH9 spec / hw
> implementation doesn't lock APMC_EN; without that, APM_CNT won't
> necessarily trigger an SMI.)

I don't think it should.  See here
<https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg02758.html>
where I wrote explicitly "Even if the OS tries to maliciously set
APMC_EN to 0 (SMI_LOCK doesn't lock APMC_EN)...".

Paolo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK
  2015-05-11 15:21     ` Paolo Bonzini
@ 2015-05-11 15:36       ` Laszlo Ersek
  2015-05-11 15:45         ` Paolo Bonzini
  0 siblings, 1 reply; 58+ messages in thread
From: Laszlo Ersek @ 2015-05-11 15:36 UTC (permalink / raw)
  To: Paolo Bonzini, kraxel; +Cc: qemu-devel, mst

On 05/11/15 17:21, Paolo Bonzini wrote:
> 
> 
> On 11/05/2015 17:17, Laszlo Ersek wrote:
>> If I understand correctly, this makes SMI_LOCK lock down the GBL_SMI_EN
>> bit (and my OVMF patch that relies on that / tests it is satisfied too).
>>
>> But, it doesn't seem to lock down APMC_EN. According to the ICH9 spec,
>> it doesn't need to -- however when we discussed this earlier (see
>> Message-Id: <553F4D23.3060305@redhat.com>), the idea was to lock down
>> APMC_EN as well. (And I don't understand why the ICH9 spec / hw
>> implementation doesn't lock APMC_EN; without that, APM_CNT won't
>> necessarily trigger an SMI.)
> 
> I don't think it should.  See here
> <https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg02758.html>
> where I wrote explicitly "Even if the OS tries to maliciously set
> APMC_EN to 0 (SMI_LOCK doesn't lock APMC_EN)...".

It's not about feature detection -- the question (from
<553F4D23.3060305@redhat.com>) is whether I should set APMC_EN myself
*every time* before writing to APM_CNT, in the
EFI_SMM_CONTROL2_PROTOCOL.Trigger() method. That protocol is provided by
a runtime DXE driver and would be exercised by eg. the non-privileged
half of the runtime variable service driver.

It's no problem to set it, I have the code ready, I was just wondering
if I should keep that hunk. (In fact it might not even matter: if the OS
interferes and clears APMC_EN before the non-privileged half mentioned
above manages to raise the SMI, then the call / transition to SMM will
simply not happen, which is bad for the OS, and probably irrelevant for
the firmware (... the security thereof).)

I guess I'll keep re-setting APMC_EN in the Trigger() method; it won't hurt.

Thanks
Laszlo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK
  2015-05-11 15:36       ` Laszlo Ersek
@ 2015-05-11 15:45         ` Paolo Bonzini
  0 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-11 15:45 UTC (permalink / raw)
  To: Laszlo Ersek, kraxel; +Cc: qemu-devel, mst



On 11/05/2015 17:36, Laszlo Ersek wrote:
> It's not about feature detection -- the question (from
> <553F4D23.3060305@redhat.com>) is whether I should set APMC_EN myself
> *every time* before writing to APM_CNT, in the
> EFI_SMM_CONTROL2_PROTOCOL.Trigger() method. That protocol is provided by
> a runtime DXE driver and would be exercised by eg. the non-privileged
> half of the runtime variable service driver.

Oh sorry, I couldn't find that message ID.

> It's no problem to set it, I have the code ready, I was just wondering
> if I should keep that hunk. (In fact it might not even matter: if the OS
> interferes and clears APMC_EN before the non-privileged half mentioned
> above manages to raise the SMI, then the call / transition to SMM will
> simply not happen, which is bad for the OS, and probably irrelevant for
> the firmware (... the security thereof).)

The OS can also race against you and clear APMC_EN, so it's even
unnecessary to reset it.

Paolo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 18/31] q35: fix ESMRAMC default
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 18/31] q35: fix ESMRAMC default Paolo Bonzini
@ 2015-05-12  6:52   ` Gerd Hoffmann
  0 siblings, 0 replies; 58+ messages in thread
From: Gerd Hoffmann @ 2015-05-12  6:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, mst

On Mo, 2015-05-11 at 15:49 +0200, Paolo Bonzini wrote:
> From: Gerd Hoffmann <kraxel@redhat.com>

[ more verbose commit message for squashing in ]

The cache bits in ESMRAMC are hardcoded to 1 (=disabled) according to
the q35 mch specs.  Add and use a define with this default.

While being at it also update the SMRAM default to use the name (no code
change, just makes things a bit more readable).

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/pci-host/q35.c         | 1 +
>  include/hw/pci-host/q35.h | 7 ++++++-
>  2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index 35b89da..8471d7a 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -351,6 +351,7 @@ static void mch_reset(DeviceState *qdev)
>                   MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
>  
>      d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
> +    d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
>  
>      mch_update(mch);
>  }
> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> index 0fff6a2..d3c7bbb 100644
> --- a/include/hw/pci-host/q35.h
> +++ b/include/hw/pci-host/q35.h
> @@ -128,7 +128,6 @@ typedef struct Q35PCIHost {
>  
>  #define MCH_HOST_BRIDGE_SMRAM                  0x9d
>  #define MCH_HOST_BRIDGE_SMRAM_SIZE             2
> -#define MCH_HOST_BRIDGE_SMRAM_DEFAULT          ((uint8_t)0x2)
>  #define MCH_HOST_BRIDGE_SMRAM_D_OPEN           ((uint8_t)(1 << 6))
>  #define MCH_HOST_BRIDGE_SMRAM_D_CLS            ((uint8_t)(1 << 5))
>  #define MCH_HOST_BRIDGE_SMRAM_D_LCK            ((uint8_t)(1 << 4))
> @@ -139,6 +138,8 @@ typedef struct Q35PCIHost {
>  #define MCH_HOST_BRIDGE_SMRAM_C_END            0xc0000
>  #define MCH_HOST_BRIDGE_SMRAM_C_SIZE           0x20000
>  #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END  0x100000
> +#define MCH_HOST_BRIDGE_SMRAM_DEFAULT           \
> +    MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG
>  
>  #define MCH_HOST_BRIDGE_ESMRAMC                0x9e
>  #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
> @@ -151,6 +152,10 @@ typedef struct Q35PCIHost {
>  #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB    ((uint8_t)(0x1 << 1))
>  #define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB    ((uint8_t)(0x2 << 1))
>  #define MCH_HOST_BRIDGE_ESMRAMC_T_EN           ((uint8_t)1)
> +#define MCH_HOST_BRIDGE_ESMRAMC_DEFAULT \
> +    (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \
> +     MCH_HOST_BRIDGE_ESMRAMC_SM_L1 |    \
> +     MCH_HOST_BRIDGE_ESMRAMC_SM_L2)
>  
>  /* D1:F0 PCIE* port*/
>  #define MCH_PCIE_DEV                           1

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 19/31] q35: add config space wmask for SMRAM and ESMRAMC
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 19/31] q35: add config space wmask for SMRAM and ESMRAMC Paolo Bonzini
@ 2015-05-12  6:55   ` Gerd Hoffmann
  0 siblings, 0 replies; 58+ messages in thread
From: Gerd Hoffmann @ 2015-05-12  6:55 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, mst

On Mo, 2015-05-11 at 15:49 +0200, Paolo Bonzini wrote:
> From: Gerd Hoffmann <kraxel@redhat.com>

[ more verbose commit message for squashing in ]

Not all bits in SMRAM and ESMRAMC can be changed by the guest.
Add wmask defines accordingly and set them in mch_reset().

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/pci-host/q35.c         | 2 ++
>  include/hw/pci-host/q35.h | 9 +++++++++
>  2 files changed, 11 insertions(+)
> 
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index 8471d7a..df0032e 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -352,6 +352,8 @@ static void mch_reset(DeviceState *qdev)
>  
>      d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
>      d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT;
> +    d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK;
> +    d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK;
>  
>      mch_update(mch);
>  }
> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> index d3c7bbb..01b8492 100644
> --- a/include/hw/pci-host/q35.h
> +++ b/include/hw/pci-host/q35.h
> @@ -140,6 +140,11 @@ typedef struct Q35PCIHost {
>  #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END  0x100000
>  #define MCH_HOST_BRIDGE_SMRAM_DEFAULT           \
>      MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG
> +#define MCH_HOST_BRIDGE_SMRAM_WMASK             \
> +    (MCH_HOST_BRIDGE_SMRAM_D_OPEN |             \
> +     MCH_HOST_BRIDGE_SMRAM_D_CLS |              \
> +     MCH_HOST_BRIDGE_SMRAM_D_LCK |              \
> +     MCH_HOST_BRIDGE_SMRAM_G_SMRAME)
>  
>  #define MCH_HOST_BRIDGE_ESMRAMC                0x9e
>  #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
> @@ -156,6 +161,10 @@ typedef struct Q35PCIHost {
>      (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \
>       MCH_HOST_BRIDGE_ESMRAMC_SM_L1 |    \
>       MCH_HOST_BRIDGE_ESMRAMC_SM_L2)
> +#define MCH_HOST_BRIDGE_ESMRAMC_WMASK               \
> +    (MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME |             \
> +     MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK |         \
> +     MCH_HOST_BRIDGE_ESMRAMC_T_EN)
>  
>  /* D1:F0 PCIE* port*/
>  #define MCH_PCIE_DEV                           1

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 20/31] q35: implement SMRAM.D_LCK
       [not found] ` <1431352157-40283-21-git-send-email-pbonzini@redhat.com>
@ 2015-05-12  6:59   ` Gerd Hoffmann
  0 siblings, 0 replies; 58+ messages in thread
From: Gerd Hoffmann @ 2015-05-12  6:59 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, mst

On Mo, 2015-05-11 at 15:49 +0200, Paolo Bonzini wrote:
> From: Gerd Hoffmann <kraxel@redhat.com>

[ more verbose commit message for squashing in ]

Once the SMRAM.D_LCK bit has been set by the guest several bits in SMRAM
and ESMRAMC become readonly until the next machine reset.  Implement
this by updating the wmask accordingly when the guest sets the lock bit.
As the lock it itself is locked down too we don't need to worry about
the guest clearing the lock bit.

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/pci-host/q35.c         | 8 +++++++-
>  include/hw/pci-host/q35.h | 3 +++
>  2 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index df0032e..972d31e 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -268,6 +268,13 @@ static void mch_update_smram(MCHPCIState *mch)
>      PCIDevice *pd = PCI_DEVICE(mch);
>      bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);
>  
> +    /* implement SMRAM.D_LCK */
> +    if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) {
> +        pd->config[MCH_HOST_BRIDGE_SMRAM] &= ~MCH_HOST_BRIDGE_SMRAM_D_OPEN;
> +        pd->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK_LCK;
> +        pd->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK;
> +    }
> +
>      memory_region_transaction_begin();
>  
>      if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) {
> @@ -297,7 +304,6 @@ static void mch_write_config(PCIDevice *d,
>  {
>      MCHPCIState *mch = MCH_PCI_DEVICE(d);
>  
> -    /* XXX: implement SMRAM.D_LOCK */
>      pci_default_write_config(d, address, val, len);
>  
>      if (ranges_overlap(address, len, MCH_HOST_BRIDGE_PAM0,
> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> index 01b8492..113cbe8 100644
> --- a/include/hw/pci-host/q35.h
> +++ b/include/hw/pci-host/q35.h
> @@ -145,6 +145,8 @@ typedef struct Q35PCIHost {
>       MCH_HOST_BRIDGE_SMRAM_D_CLS |              \
>       MCH_HOST_BRIDGE_SMRAM_D_LCK |              \
>       MCH_HOST_BRIDGE_SMRAM_G_SMRAME)
> +#define MCH_HOST_BRIDGE_SMRAM_WMASK_LCK         \
> +    MCH_HOST_BRIDGE_SMRAM_D_CLS
>  
>  #define MCH_HOST_BRIDGE_ESMRAMC                0x9e
>  #define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
> @@ -165,6 +167,7 @@ typedef struct Q35PCIHost {
>      (MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME |             \
>       MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK |         \
>       MCH_HOST_BRIDGE_ESMRAMC_T_EN)
> +#define MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK     0
>  
>  /* D1:F0 PCIE* port*/
>  #define MCH_PCIE_DEV                           1

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK Paolo Bonzini
  2015-05-11 15:17   ` Laszlo Ersek
@ 2015-05-12  7:07   ` Gerd Hoffmann
  1 sibling, 0 replies; 58+ messages in thread
From: Gerd Hoffmann @ 2015-05-12  7:07 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, mst

On Mo, 2015-05-11 at 15:49 +0200, Paolo Bonzini wrote:
> From: Gerd Hoffmann <kraxel@redhat.com>

[ more verbose commit message for squashing in ]

Add write mask for the smi enable register, so we can disable write
access to certain bits.  Open all bits on reset.  Disable write access
to GBL_SMI_EN when SMI_LOCK (in ich9 lpc pci config space) is set.
Write access to SMI_LOCK itself is disabled too.

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/acpi/ich9.c         |  4 +++-
>  hw/isa/lpc_ich9.c      | 19 +++++++++++++++++++
>  include/hw/acpi/ich9.h |  1 +
>  include/hw/i386/ich9.h |  6 ++++++
>  4 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index 5352e19..310aa64 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -94,7 +94,8 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
>      ICH9LPCPMRegs *pm = opaque;
>      switch (addr) {
>      case 0:
> -        pm->smi_en = val;
> +        pm->smi_en &= ~pm->smi_en_wmask;
> +        pm->smi_en |= (val & pm->smi_en_wmask);
>          break;
>      }
>  }
> @@ -198,6 +199,7 @@ static void pm_reset(void *opaque)
>           * support SMM mode. */
>          pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
>      }
> +    pm->smi_en_wmask = ~0;
>  
>      acpi_update_sci(&pm->acpi_regs, pm->irq);
>  }
> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> index dba7585..0269cfe 100644
> --- a/hw/isa/lpc_ich9.c
> +++ b/hw/isa/lpc_ich9.c
> @@ -410,12 +410,28 @@ static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
>      }
>  }
>  
> +/* config:GEN_PMCON* */
> +static void
> +ich9_lpc_pmcon_update(ICH9LPCState *lpc)
> +{
> +    uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1);
> +    uint16_t wmask;
> +
> +    if (gen_pmcon_1 & ICH9_LPC_GEN_PMCON_1_SMI_LOCK) {
> +        wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1);
> +        wmask &= ~ICH9_LPC_GEN_PMCON_1_SMI_LOCK;
> +        pci_set_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1, wmask);
> +        lpc->pm.smi_en_wmask &= ~1;
> +    }
> +}
> +
>  static int ich9_lpc_post_load(void *opaque, int version_id)
>  {
>      ICH9LPCState *lpc = opaque;
>  
>      ich9_lpc_pmbase_update(lpc);
>      ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
> +    ich9_lpc_pmcon_update(lpc);
>      return 0;
>  }
>  
> @@ -438,6 +454,9 @@ static void ich9_lpc_config_write(PCIDevice *d,
>      if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
>          pci_bus_fire_intx_routing_notifier(lpc->d.bus);
>      }
> +    if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
> +        ich9_lpc_pmcon_update(lpc);
> +    }
>  }
>  
>  static void ich9_lpc_reset(DeviceState *qdev)
> diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> index c2d3dba..77cc65c 100644
> --- a/include/hw/acpi/ich9.h
> +++ b/include/hw/acpi/ich9.h
> @@ -39,6 +39,7 @@ typedef struct ICH9LPCPMRegs {
>      MemoryRegion io_smi;
>  
>      uint32_t smi_en;
> +    uint32_t smi_en_wmask;
>      uint32_t smi_sts;
>  
>      qemu_irq irq;      /* SCI */
> diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
> index f4e522c..a2cc15c 100644
> --- a/include/hw/i386/ich9.h
> +++ b/include/hw/i386/ich9.h
> @@ -152,6 +152,12 @@ Object *ich9_lpc_find(void);
>  #define ICH9_LPC_PIRQ_ROUT_MASK                 Q35_MASK(8, 3, 0)
>  #define ICH9_LPC_PIRQ_ROUT_DEFAULT              0x80
>  
> +#define ICH9_LPC_GEN_PMCON_1                    0xa0
> +#define ICH9_LPC_GEN_PMCON_1_SMI_LOCK           (1 << 4)
> +#define ICH9_LPC_GEN_PMCON_2                    0xa2
> +#define ICH9_LPC_GEN_PMCON_3                    0xa4
> +#define ICH9_LPC_GEN_PMCON_LOCK                 0xa6
> +
>  #define ICH9_LPC_RCBA                           0xf0
>  #define ICH9_LPC_RCBA_BA_MASK                   Q35_MASK(32, 31, 14)
>  #define ICH9_LPC_RCBA_EN                        0x1

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global Paolo Bonzini
@ 2015-05-19 11:49   ` Paolo Bonzini
  2015-05-19 14:34     ` Markus Armbruster
  2015-05-19 16:30   ` Markus Armbruster
  1 sibling, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-19 11:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, lersek, kraxel, mst

Markus, can you review this one?

Thanks,

Paolo

On 11/05/2015 15:48, Paolo Bonzini wrote:
> -global does not work for drivers that have a dot in their name, such as
> cfi.pflash01.  This is just a parsing limitation, because such globals
> can be declared easily inside a -readconfig file.
> 
> To allow this usage, support the full QemuOpts key/value syntax for -global
> too, for example "-global driver=cfi.pflash01,property=secure,value=on".
> The two formats do not conflict, because the key/value syntax does not have
> a period before the first equal sign.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  qdev-monitor.c  | 18 +++++++++++-------
>  qemu-options.hx |  7 ++++++-
>  2 files changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/qdev-monitor.c b/qdev-monitor.c
> index 1d87f57..9f17c81 100644
> --- a/qdev-monitor.c
> +++ b/qdev-monitor.c
> @@ -822,15 +822,19 @@ int qemu_global_option(const char *str)
>      QemuOpts *opts;
>      int rc, offset;
>  
> -    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
> -    if (rc < 2 || str[offset] != '=') {
> -        error_report("can't parse: \"%s\"", str);
> +    rc = sscanf(str, "%63[^.=].%63[^=]%n", driver, property, &offset);
> +    if (rc == 2 && str[offset] == '=') {
> +        opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
> +        qemu_opt_set(opts, "driver", driver, &error_abort);
> +        qemu_opt_set(opts, "property", property, &error_abort);
> +        qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
> +        return 0;
> +    }
> +
> +    opts = qemu_opts_parse(&qemu_global_opts, str, false);
> +    if (!opts) {
>          return -1;
>      }
>  
> -    opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
> -    qemu_opt_set(opts, "driver", driver, &error_abort);
> -    qemu_opt_set(opts, "property", property, &error_abort);
> -    qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
>      return 0;
>  }
> diff --git a/qemu-options.hx b/qemu-options.hx
> index ec356f6..43c9ee0 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -171,11 +171,13 @@ Set parameter @var{arg} for item @var{id} of type @var{group}\n"
>  ETEXI
>  
>  DEF("global", HAS_ARG, QEMU_OPTION_global,
> -    "-global driver.prop=value\n"
> +    "-global driver.property=value\n"
> +    "-global driver=driver,property=property,value=value\n"
>      "                set a global default for a driver property\n",
>      QEMU_ARCH_ALL)
>  STEXI
>  @item -global @var{driver}.@var{prop}=@var{value}
> +@itemx -global driver=@var{driver},property=@var{property},value=@var{value}
>  @findex -global
>  Set default value of @var{driver}'s property @var{prop} to @var{value}, e.g.:
>  
> @@ -186,6 +188,9 @@ qemu-system-i386 -global ide-drive.physical_block_size=4096 -drive file=file,if=
>  In particular, you can use this to set driver properties for devices which are 
>  created automatically by the machine model. To create a device which is not 
>  created automatically and set properties on it, use -@option{device}.
> +
> +The two syntaxes are equivalent.  The longer one works for drivers whose name
> +contains a dot.
>  ETEXI
>  
>  DEF("boot", HAS_ARG, QEMU_OPTION_boot,
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link Paolo Bonzini
  2015-05-11 14:40   ` Laszlo Ersek
@ 2015-05-19 11:50   ` Paolo Bonzini
  2015-05-19 19:14   ` Eduardo Habkost
  2 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-19 11:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eduardo Habkost, lersek, kraxel, Andreas Färber, mst

Andreas, Eduardo,

can you review and ack this one?

On 11/05/2015 15:48, Paolo Bonzini wrote:
> Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qom/object.h | 18 ++++++++++++++++++
>  qom/object.c         | 16 ++++++++++++++++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index d2d7748..0505f20 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -1290,6 +1290,24 @@ void object_property_add_alias(Object *obj, const char *name,
>                                 Error **errp);
>  
>  /**
> + * object_property_add_const_link:
> + * @obj: the object to add a property to
> + * @name: the name of the property
> + * @target: the object to be referred by the link
> + * @errp: if an error occurs, a pointer to an area to store the error
> + *
> + * Add an unmodifiable link for a property on an object.  This function will
> + * add a property of type link<TYPE> where TYPE is the type of @target.
> + *
> + * The caller must ensure that @target stays alive as long as
> + * this property exists.  In the case @target is a child of @obj,
> + * this will be the case.  Otherwise, the caller is responsible for
> + * taking a reference.
> + */
> +void object_property_add_const_link(Object *obj, const char *name,
> +                                    Object *target, Error **errp);
> +
> +/**
>   * object_property_set_description:
>   * @obj: the object owning the property
>   * @name: the name of the property
> diff --git a/qom/object.c b/qom/object.c
> index b8dff43..ba89518 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1266,6 +1266,22 @@ out:
>      g_free(full_type);
>  }
>  
> +void object_property_add_const_link(Object *obj, const char *name,
> +                                    Object *target, Error **errp)
> +{
> +    char *link_type;
> +    ObjectProperty *op;
> +   
> +    link_type = g_strdup_printf("link<%s>", object_get_typename(target));
> +    op = object_property_add(obj, name, link_type,
> +                             object_get_child_property, NULL,
> +                             NULL, target, errp);
> +    if (op != NULL) {
> +        op->resolve = object_resolve_child_property;
> +    }
> +    g_free(link_type);
> +}
> +
>  gchar *object_get_canonical_path_component(Object *obj)
>  {
>      ObjectProperty *prop = NULL;
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 28/31] vga: disable chain4_alias if KVM supports SMRAM
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 28/31] vga: disable chain4_alias if KVM supports SMRAM Paolo Bonzini
@ 2015-05-19 11:51   ` Paolo Bonzini
  0 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-19 11:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: lersek, kraxel, mst

This actually is not needed anymore in the latest incarnation of the
kernel-side interface.

Paolo

On 11/05/2015 15:49, Paolo Bonzini wrote:
> KVM is okay with SMRAM overlapping an MMIO area underneath it, but it does
> not want to have two overlapping RAM slots for SMRAM and video RAM.
> Unfortunately, the chain4_alias optimization results in the latter
> situation.  Disable it if KVM supports system management mode.
> 
> Note that the chain4_alias optimization is misguided, because it assumes
> that chain4 data is at VRAM address 0,1,2,3,4,5,6,7...16383.  This is
> incorrect, because chain4 data is at VRAM address 0,1,2,3, 16,17,18,19,
> ..., 65523.  But we cannot fix the VRAM format without breaking migration,
> so keep the optimization and just disable it if it gets in the way.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/display/vga.c     | 8 ++++++--
>  hw/display/vga_int.h | 1 +
>  include/sysemu/kvm.h | 1 +
>  kvm-all.c            | 5 +++++
>  kvm-stub.c           | 5 +++++
>  5 files changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/display/vga.c b/hw/display/vga.c
> index d1d296c..b1925a0 100644
> --- a/hw/display/vga.c
> +++ b/hw/display/vga.c
> @@ -154,7 +154,8 @@ static void vga_update_memory_access(VGACommonState *s)
>          s->has_chain4_alias = false;
>          s->plane_updated = 0xf;
>      }
> -    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
> +    if (s->use_chain4_alias &&
> +	(s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
>          VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
>          offset = 0;
>          switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
> @@ -2219,8 +2220,11 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
>  
>      qemu_register_reset(vga_reset, s);
>  
> -    s->bank_offset = 0;
> +    if (!kvm_enabled() || !kvm_has_smm()) {
> +        s->use_chain4_alias = true;
> +    }
>  
> +    s->bank_offset = 0;
>      s->legacy_address_space = address_space;
>  
>      vga_io_memory = vga_init_io(s, obj, &vga_ports, &vbe_ports);
> diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
> index fcfcc5f..646e64c 100644
> --- a/hw/display/vga_int.h
> +++ b/hw/display/vga_int.h
> @@ -95,6 +95,7 @@ typedef struct VGACommonState {
>      uint32_t vram_size_mb; /* property */
>      uint32_t vbe_size;
>      uint32_t latch;
> +    bool use_chain4_alias;
>      bool has_chain4_alias;
>      MemoryRegion chain4_alias;
>      uint8_t sr_index;
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 4878959..e1db979 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -186,6 +186,7 @@ int kvm_has_pit_state2(void);
>  int kvm_has_many_ioeventfds(void);
>  int kvm_has_gsi_routing(void);
>  int kvm_has_intx_set_mask(void);
> +int kvm_has_smm(void);
>  
>  int kvm_init_vcpu(CPUState *cpu);
>  int kvm_cpu_exec(CPUState *cpu);
> diff --git a/kvm-all.c b/kvm-all.c
> index 17a3771..5ad4877 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1990,6 +1990,11 @@ int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr)
>      return ret ? 0 : 1;
>  }
>  
> +int kvm_has_smm(void)
> +{
> +    return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
> +}
> +
>  int kvm_has_sync_mmu(void)
>  {
>      return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 7ba90c5..c3428a5 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -56,6 +56,11 @@ int kvm_cpu_exec(CPUState *cpu)
>      abort();
>  }
>  
> +int kvm_has_smm(void)
> +{
> +    return 0;
> +}
> +
>  int kvm_has_sync_mmu(void)
>  {
>      return 0;
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global
  2015-05-19 11:49   ` Paolo Bonzini
@ 2015-05-19 14:34     ` Markus Armbruster
  0 siblings, 0 replies; 58+ messages in thread
From: Markus Armbruster @ 2015-05-19 14:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: mst, lersek, qemu-devel, kraxel

Paolo Bonzini <pbonzini@redhat.com> writes:

> Markus, can you review this one?

Okay.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global Paolo Bonzini
  2015-05-19 11:49   ` Paolo Bonzini
@ 2015-05-19 16:30   ` Markus Armbruster
  2015-05-19 16:40     ` Paolo Bonzini
  1 sibling, 1 reply; 58+ messages in thread
From: Markus Armbruster @ 2015-05-19 16:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: mst, lersek, qemu-devel, kraxel

Paolo Bonzini <pbonzini@redhat.com> writes:

> -global does not work for drivers that have a dot in their name, such as
> cfi.pflash01.  This is just a parsing limitation, because such globals
> can be declared easily inside a -readconfig file.
>
> To allow this usage, support the full QemuOpts key/value syntax for -global
> too, for example "-global driver=cfi.pflash01,property=secure,value=on".
> The two formats do not conflict, because the key/value syntax does not have
> a period before the first equal sign.

Overloading syntax isn't exactly pretty, but I guess it's the best we
can do.

> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  qdev-monitor.c  | 18 +++++++++++-------
>  qemu-options.hx |  7 ++++++-
>  2 files changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/qdev-monitor.c b/qdev-monitor.c
> index 1d87f57..9f17c81 100644
> --- a/qdev-monitor.c
> +++ b/qdev-monitor.c
> @@ -822,15 +822,19 @@ int qemu_global_option(const char *str)
>      QemuOpts *opts;
>      int rc, offset;
>  
> -    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
> -    if (rc < 2 || str[offset] != '=') {
> -        error_report("can't parse: \"%s\"", str);
> +    rc = sscanf(str, "%63[^.=].%63[^=]%n", driver, property, &offset);
> +    if (rc == 2 && str[offset] == '=') {
> +        opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
> +        qemu_opt_set(opts, "driver", driver, &error_abort);
> +        qemu_opt_set(opts, "property", property, &error_abort);
> +        qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
> +        return 0;
> +    }
> +
> +    opts = qemu_opts_parse(&qemu_global_opts, str, false);
> +    if (!opts) {
>          return -1;
>      }
>  
> -    opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
> -    qemu_opt_set(opts, "driver", driver, &error_abort);
> -    qemu_opt_set(opts, "property", property, &error_abort);
> -    qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
>      return 0;
>  }

Restrictions on driver and property names in the shorthand syntax
driver.property=value before the patch:

* Both are at most 63 characters long, no whitespace

* Driver name cannot contain '.'

* Property name cannot contain '='

After the patch, we additionally have:

* Driver name cannot contain '='.

Okay as long as no such driver name exists.  Have you checked?

Please spell out the new restriction in the commit message.

In the new longhand syntax, driver name, property name and value all
appear in QemuOpts value position, and as such are restricted to at most
1023 characters long (see opts_do_parse()).  Okay.

I feel we should reject anti-social names for the same reasons we reject
anti-social IDs.  But that's out of scope for this patch.

> diff --git a/qemu-options.hx b/qemu-options.hx
> index ec356f6..43c9ee0 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -171,11 +171,13 @@ Set parameter @var{arg} for item @var{id} of type @var{group}\n"
>  ETEXI
>  
>  DEF("global", HAS_ARG, QEMU_OPTION_global,
> -    "-global driver.prop=value\n"
> +    "-global driver.property=value\n"
> +    "-global driver=driver,property=property,value=value\n"
>      "                set a global default for a driver property\n",
>      QEMU_ARCH_ALL)
>  STEXI
>  @item -global @var{driver}.@var{prop}=@var{value}
> +@itemx -global driver=@var{driver},property=@var{property},value=@var{value}
>  @findex -global
>  Set default value of @var{driver}'s property @var{prop} to @var{value}, e.g.:
>  

Aside: I had to look up @itemx.  There are a few @item in this file that
should really be @itemx.

> @@ -186,6 +188,9 @@ qemu-system-i386 -global ide-drive.physical_block_size=4096 -drive file=file,if=
>  In particular, you can use this to set driver properties for devices which are 
>  created automatically by the machine model. To create a device which is not 
>  created automatically and set properties on it, use -@option{device}.
> +
> +The two syntaxes are equivalent.  The longer one works for drivers whose name
> +contains a dot.
>  ETEXI
>  
>  DEF("boot", HAS_ARG, QEMU_OPTION_boot,

I'd explain this as follows:

    -global @var{driver}.@var{prop}=@var{value} is shorthand for -global
    driver=@var{driver},property=@var{prop},value=@var{value}.  The
    longhand syntax works even when @var{driver} contains a dot.

But I can accept your version.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global
  2015-05-19 16:30   ` Markus Armbruster
@ 2015-05-19 16:40     ` Paolo Bonzini
  2015-06-08 18:04       ` Markus Armbruster
  0 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-05-19 16:40 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: mst, lersek, qemu-devel, kraxel



On 19/05/2015 18:30, Markus Armbruster wrote:
> Restrictions on driver and property names in the shorthand syntax
> driver.property=value before the patch:
> 
> * Both are at most 63 characters long, no whitespace
> 
> * Driver name cannot contain '.'
> 
> * Property name cannot contain '='
> 
> After the patch, we additionally have:
> 
> * Driver name cannot contain '='.
> 
> Okay as long as no such driver name exists.  Have you checked?

Good catch!  I now have.

I've grepped for

- \\..*\".*=.*\",

- TYPE_.*\".*=.*\"

with no hits.

> Please spell out the new restriction in the commit message.

Will do.

>> @@ -186,6 +188,9 @@ qemu-system-i386 -global ide-drive.physical_block_size=4096 -drive file=file,if=
>>  In particular, you can use this to set driver properties for devices which are 
>>  created automatically by the machine model. To create a device which is not 
>>  created automatically and set properties on it, use -@option{device}.
>> +
>> +The two syntaxes are equivalent.  The longer one works for drivers whose name
>> +contains a dot.
>>  ETEXI
>>  
>>  DEF("boot", HAS_ARG, QEMU_OPTION_boot,
> 
> I'd explain this as follows:
> 
>     -global @var{driver}.@var{prop}=@var{value} is shorthand for -global
>     driver=@var{driver},property=@var{prop},value=@var{value}.  The
>     longhand syntax works even when @var{driver} contains a dot.

Will do.

Paolo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link
  2015-05-11 13:48 ` [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link Paolo Bonzini
  2015-05-11 14:40   ` Laszlo Ersek
  2015-05-19 11:50   ` Paolo Bonzini
@ 2015-05-19 19:14   ` Eduardo Habkost
  2015-05-20 14:36     ` Andreas Färber
  2 siblings, 1 reply; 58+ messages in thread
From: Eduardo Habkost @ 2015-05-19 19:14 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: mst, lersek, qemu-devel, Andreas Färber, kraxel

On Mon, May 11, 2015 at 03:48:57PM +0200, Paolo Bonzini wrote:
> Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Assuming that the whitespace warning Laszlo pointed out will be fixed:

Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>

-- 
Eduardo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link
  2015-05-19 19:14   ` Eduardo Habkost
@ 2015-05-20 14:36     ` Andreas Färber
  0 siblings, 0 replies; 58+ messages in thread
From: Andreas Färber @ 2015-05-20 14:36 UTC (permalink / raw)
  To: Eduardo Habkost, Paolo Bonzini; +Cc: kraxel, lersek, qemu-devel, mst

Am 19.05.2015 um 21:14 schrieb Eduardo Habkost:
> On Mon, May 11, 2015 at 03:48:57PM +0200, Paolo Bonzini wrote:
>> Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> Assuming that the whitespace warning Laszlo pointed out will be fixed:
> 
> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>

Three spaces deleted and commit message extended, applied to qom-next:
https://github.com/afaerber/qemu-cpu/commits/qom-next

Thanks,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM
  2015-05-11 13:49 ` [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM Paolo Bonzini
@ 2015-05-31 18:09   ` Michael S. Tsirkin
  2015-06-01  7:30     ` Paolo Bonzini
  0 siblings, 1 reply; 58+ messages in thread
From: Michael S. Tsirkin @ 2015-05-31 18:09 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, kraxel

On Mon, May 11, 2015 at 03:49:01PM +0200, Paolo Bonzini wrote:
> Remove cpu_smm_register and cpu_smm_update.  Instead, each CPU
> address space gets an extra region which is an alias of
> /machine/smram.  This extra region is enabled or disabled
> as the CPU enters/exits SMM.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  bsd-user/main.c           |  4 ----
>  hw/i386/pc.c              | 21 ---------------------
>  hw/pci-host/pam.c         | 18 ++----------------
>  hw/pci-host/piix.c        | 25 +++++--------------------
>  hw/pci-host/q35.c         | 19 +++----------------
>  include/hw/i386/pc.h      |  1 -
>  include/hw/pci-host/pam.h |  5 +----
>  include/hw/pci-host/q35.h |  1 -
>  linux-user/main.c         |  4 ----
>  target-i386/cpu-qom.h     |  4 +++-
>  target-i386/cpu.c         | 33 +++++++++++++++++++++++++++++++--
>  target-i386/cpu.h         |  3 ++-
>  target-i386/machine.c     |  3 +++
>  target-i386/smm_helper.c  | 12 ++++++++++--
>  14 files changed, 60 insertions(+), 93 deletions(-)
> 
> diff --git a/bsd-user/main.c b/bsd-user/main.c
> index 5bfaf5c..ba0b998 100644
> --- a/bsd-user/main.c
> +++ b/bsd-user/main.c
> @@ -108,10 +108,6 @@ void cpu_list_unlock(void)
>  /***********************************************************/
>  /* CPUX86 core interface */
>  
> -void cpu_smm_update(CPUX86State *env)
> -{
> -}
> -
>  uint64_t cpu_get_tsc(CPUX86State *env)
>  {
>      return cpu_get_real_ticks();
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index a8e6be1..a7ee9ef 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -163,27 +163,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
>      return cpu_get_ticks();
>  }
>  
> -/* SMM support */
> -
> -static cpu_set_smm_t smm_set;
> -static void *smm_arg;
> -
> -void cpu_smm_register(cpu_set_smm_t callback, void *arg)
> -{
> -    assert(smm_set == NULL);
> -    assert(smm_arg == NULL);
> -    smm_set = callback;
> -    smm_arg = arg;
> -}
> -
> -void cpu_smm_update(CPUX86State *env)
> -{
> -    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
> -        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
> -    }
> -}
> -
> -
>  /* IRQ handling */
>  int cpu_get_pic_interrupt(CPUX86State *env)
>  {
> diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c
> index 8272de3..99d7af9 100644
> --- a/hw/pci-host/pam.c
> +++ b/hw/pci-host/pam.c
> @@ -31,26 +31,12 @@
>  #include "sysemu/sysemu.h"
>  #include "hw/pci-host/pam.h"
>  
> -void smram_update(MemoryRegion *smram_region, uint8_t smram,
> -                  uint8_t smm_enabled)
> +void smram_update(MemoryRegion *smram_region, uint8_t smram)
>  {
> -    bool smram_enabled;
> -
> -    smram_enabled = ((smm_enabled && (smram & SMRAM_G_SMRAME)) ||
> -                        (smram & SMRAM_D_OPEN));
> +    bool smram_enabled = (smram & SMRAM_D_OPEN);
>      memory_region_set_enabled(smram_region, !smram_enabled);
>  }
>  
> -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
> -                   MemoryRegion *smram_region)
> -{
> -    uint8_t smm_enabled = (smm != 0);
> -    if (*host_smm_enabled != smm_enabled) {
> -        *host_smm_enabled = smm_enabled;
> -        smram_update(smram_region, smram, *host_smm_enabled);
> -    }
> -}
> -
>  void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
>                MemoryRegion *system_memory, MemoryRegion *pci_address_space,
>                PAMMemoryRegion *mem, uint32_t start, uint32_t size)
> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index a280d57..46c0278 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -106,7 +106,6 @@ struct PCII440FXState {
>      PAMMemoryRegion pam_regions[13];
>      MemoryRegion smram_region;
>      MemoryRegion smram, low_smram;
> -    uint8_t smm_enabled;
>  };
>  
>  
> @@ -139,23 +138,12 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
>          pam_update(&d->pam_regions[i], i,
>                     pd->config[I440FX_PAM + ((i + 1) / 2)]);
>      }
> -    smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
> +    smram_update(&d->smram_region, pd->config[I440FX_SMRAM]);
>      memory_region_set_enabled(&d->smram,
>                                pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
>      memory_region_transaction_commit();
>  }
>  
> -static void i440fx_set_smm(int val, void *arg)
> -{
> -    PCII440FXState *d = arg;
> -    PCIDevice *pd = PCI_DEVICE(d);
> -
> -    memory_region_transaction_begin();
> -    smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
> -                  &d->smram_region);
> -    memory_region_transaction_commit();
> -}
> -
>  
>  static void i440fx_write_config(PCIDevice *dev,
>                                  uint32_t address, uint32_t val, int len)
> @@ -175,12 +163,13 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
>      PCII440FXState *d = opaque;
>      PCIDevice *pd = PCI_DEVICE(d);
>      int ret, i;
> +    uint8_t smm_enabled;
>  
>      ret = pci_device_load(pd, f);
>      if (ret < 0)
>          return ret;
>      i440fx_update_memory_mappings(d);
> -    qemu_get_8s(f, &d->smm_enabled);
> +    qemu_get_8s(f, &smm_enabled);
>  
>      if (version_id == 2) {
>          for (i = 0; i < PIIX_NUM_PIRQS; i++) {
> @@ -208,7 +197,7 @@ static const VMStateDescription vmstate_i440fx = {
>      .post_load = i440fx_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
> -        VMSTATE_UINT8(smm_enabled, PCII440FXState),
> +        VMSTATE_UNUSED(1),
>          VMSTATE_END_OF_LIST()
>      }
>  };

Won't this cause problems for cross-version migration?
Old qemu receiving this will think smm is enabled,
unconditionally.


> @@ -300,11 +289,7 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
>  
>  static void i440fx_realize(PCIDevice *dev, Error **errp)
>  {
> -    PCII440FXState *d = I440FX_PCI_DEVICE(dev);
> -
>      dev->config[I440FX_SMRAM] = 0x02;
> -
> -    cpu_smm_register(&i440fx_set_smm, d);
>  }
>  
>  PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
> @@ -360,7 +345,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>      memory_region_init(&f->smram, OBJECT(d), "smram", 1ull << 32);
>      memory_region_set_enabled(&f->smram, true);
>      memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
> -                             f->system_memory, 0xa0000, 0x20000);
> +                             f->ram_memory, 0xa0000, 0x20000);
>      memory_region_set_enabled(&f->low_smram, true);
>      memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
>      object_property_add_alias(qdev_get_machine(), "smram",
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index de8326a..bd17a05 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -268,24 +268,12 @@ static void mch_update_smram(MCHPCIState *mch)
>      PCIDevice *pd = PCI_DEVICE(mch);
>  
>      memory_region_transaction_begin();
> -    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
> -                    mch->smm_enabled);
> +    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM]);
>      memory_region_set_enabled(&mch->smram,
>                                pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
>      memory_region_transaction_commit();
>  }
>  
> -static void mch_set_smm(int smm, void *arg)
> -{
> -    MCHPCIState *mch = arg;
> -    PCIDevice *pd = PCI_DEVICE(mch);
> -
> -    memory_region_transaction_begin();
> -    smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
> -                    &mch->smram_region);
> -    memory_region_transaction_commit();
> -}
> -
>  static void mch_write_config(PCIDevice *d,
>                                uint32_t address, uint32_t val, int len)
>  {
> @@ -331,7 +319,7 @@ static const VMStateDescription vmstate_mch = {
>      .post_load = mch_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
> -        VMSTATE_UINT8(smm_enabled, MCHPCIState),
> +        VMSTATE_UNUSED(1),
>          VMSTATE_END_OF_LIST()
>      }
>  };
> @@ -402,7 +390,6 @@ static void mch_realize(PCIDevice *d, Error **errp)
>                             mch->pci_address_space);
>  
>      /* if *disabled* show SMRAM to all CPUs */
> -    cpu_smm_register(&mch_set_smm, mch);
>      memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
>                               mch->pci_address_space, 0xa0000, 0x20000);
>      memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
> @@ -413,7 +400,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
>      memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
>      memory_region_set_enabled(&mch->smram, true);
>      memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
> -                             mch->system_memory, 0xa0000, 0x20000);
> +                             mch->ram_memory, 0xa0000, 0x20000);
>      memory_region_set_enabled(&mch->low_smram, true);
>      memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
>      object_property_add_const_link(qdev_get_machine(), "smram",
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 1b35168..c9a9f6e 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -211,7 +211,6 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
>  void pc_pci_device_init(PCIBus *pci_bus);
>  
>  typedef void (*cpu_set_smm_t)(int smm, void *arg);
> -void cpu_smm_register(cpu_set_smm_t callback, void *arg);
>  
>  void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
>  
> diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h
> index 4d03e4b..80dd605 100644
> --- a/include/hw/pci-host/pam.h
> +++ b/include/hw/pci-host/pam.h
> @@ -86,10 +86,7 @@ typedef struct PAMMemoryRegion {
>      unsigned current;
>  } PAMMemoryRegion;
>  
> -void smram_update(MemoryRegion *smram_region, uint8_t smram,
> -                  uint8_t smm_enabled);
> -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
> -                   MemoryRegion *smram_region);
> +void smram_update(MemoryRegion *smram_region, uint8_t smram);
>  void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system,
>                MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size);
>  void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val);
> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> index 4c9eacc..17adeaa 100644
> --- a/include/hw/pci-host/q35.h
> +++ b/include/hw/pci-host/q35.h
> @@ -55,7 +55,6 @@ typedef struct MCHPCIState {
>      MemoryRegion smram_region;
>      MemoryRegion smram, low_smram;
>      PcPciInfo pci_info;
> -    uint8_t smm_enabled;
>      ram_addr_t below_4g_mem_size;
>      ram_addr_t above_4g_mem_size;
>      uint64_t pci_hole64_size;
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 3f32db0..6989b82 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -215,10 +215,6 @@ void cpu_list_unlock(void)
>  /***********************************************************/
>  /* CPUX86 core interface */
>  
> -void cpu_smm_update(CPUX86State *env)
> -{
> -}
> -
>  uint64_t cpu_get_tsc(CPUX86State *env)
>  {
>      return cpu_get_real_ticks();
> diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
> index 39cd878..7a4fddd 100644
> --- a/target-i386/cpu-qom.h
> +++ b/target-i386/cpu-qom.h
> @@ -23,6 +23,7 @@
>  #include "qom/cpu.h"
>  #include "cpu.h"
>  #include "qapi/error.h"
> +#include "qemu/notify.h"
>  
>  #ifdef TARGET_X86_64
>  #define TYPE_X86_CPU "x86_64-cpu"
> @@ -111,7 +112,8 @@ typedef struct X86CPU {
>      /* in order to simplify APIC support, we leave this pointer to the
>         user */
>      struct DeviceState *apic_state;
> -    struct MemoryRegion *cpu_as_root;
> +    struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
> +    Notifier machine_done;
>  } X86CPU;
>  
>  static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 97c4804..7b6f9e4 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -2751,6 +2751,21 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
>      object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
>                               errp);
>  }
> +
> +static void x86_cpu_machine_done(Notifier *n, void *unused)
> +{
> +    X86CPU *cpu = container_of(n, X86CPU, machine_done);
> +    MemoryRegion *smram =
> +        (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
> +
> +    if (smram) {
> +        cpu->smram = g_new(MemoryRegion, 1);
> +        memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
> +                                 smram, 0, 1ull << 32);
> +        memory_region_set_enabled(cpu->smram, false);
> +        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
> +    }
> +}
>  #else
>  static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
>  {
> @@ -2815,12 +2830,26 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>  
>  #ifndef CONFIG_USER_ONLY
>      if (tcg_enabled()) {
> +        cpu->cpu_as_mem = g_new(MemoryRegion, 1);
>          cpu->cpu_as_root = g_new(MemoryRegion, 1);
>          cs->as = g_new(AddressSpace, 1);
> -        memory_region_init_alias(cpu->cpu_as_root, OBJECT(cpu), "memory",
> -                                 get_system_memory(), 0, ~0ull);
> +
> +        /* Outer container... */
> +        memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
>          memory_region_set_enabled(cpu->cpu_as_root, true);
> +
> +        /* ... with two regions inside: normal system memory with low
> +         * priority, and...
> +         */
> +        memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
> +                                 get_system_memory(), 0, ~0ull);
> +        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
> +        memory_region_set_enabled(cpu->cpu_as_mem, true);
>          address_space_init(cs->as, cpu->cpu_as_root, "CPU");
> +
> +        /* ... SMRAM with higher priority, linked from /machine/smram.  */
> +        cpu->machine_done.notify = x86_cpu_machine_done;
> +        qemu_add_machine_init_done_notifier(&cpu->machine_done);
>      }
>  #endif
>  
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 4510ae7..df6e885 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1157,7 +1157,6 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
>  void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
>  
>  /* hw/pc.c */
> -void cpu_smm_update(CPUX86State *env);
>  uint64_t cpu_get_tsc(CPUX86State *env);
>  
>  #define TARGET_PAGE_BITS 12
> @@ -1323,7 +1322,9 @@ void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
>  /* seg_helper.c */
>  void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
>  
> +/* smm_helper.c */
>  void do_smm_enter(X86CPU *cpu);
> +void cpu_smm_update(X86CPU *cpu);
>  
>  void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
>  
> diff --git a/target-i386/machine.c b/target-i386/machine.c
> index cd1ddd2..69d86cb 100644
> --- a/target-i386/machine.c
> +++ b/target-i386/machine.c
> @@ -372,6 +372,9 @@ static int cpu_post_load(void *opaque, int version_id)
>      }
>      tlb_flush(cs, 1);
>  
> +    if (tcg_enabled()) {
> +        cpu_smm_update(cpu);
> +    }
>      return 0;
>  }
>  
> diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
> index 5617a14..762f4e5 100644
> --- a/target-i386/smm_helper.c
> +++ b/target-i386/smm_helper.c
> @@ -40,6 +40,14 @@ void helper_rsm(CPUX86State *env)
>  #define SMM_REVISION_ID 0x00020000
>  #endif
>  
> +void cpu_smm_update(X86CPU *cpu)
> +{
> +    CPUX86State *env = &cpu->env;
> +    bool smm_enabled = (env->hflags & HF_SMM_MASK);
> +
> +    memory_region_set_enabled(cpu->smram, smm_enabled);
> +}
> +
>  void do_smm_enter(X86CPU *cpu)
>  {
>      CPUX86State *env = &cpu->env;
> @@ -57,7 +65,7 @@ void do_smm_enter(X86CPU *cpu)
>      } else {
>          env->hflags2 |= HF2_NMI_MASK;
>      }
> -    cpu_smm_update(env);
> +    cpu_smm_update(cpu);
>  
>      sm_state = env->smbase + 0x8000;
>  
> @@ -317,7 +325,7 @@ void helper_rsm(CPUX86State *env)
>      }
>      env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
>      env->hflags &= ~HF_SMM_MASK;
> -    cpu_smm_update(env);
> +    cpu_smm_update(cpu);
>  
>      qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
>      log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
> -- 
> 1.8.3.1
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM
  2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
                   ` (30 preceding siblings ...)
       [not found] ` <1431352157-40283-21-git-send-email-pbonzini@redhat.com>
@ 2015-05-31 18:10 ` Michael S. Tsirkin
  2015-06-01  7:32   ` Paolo Bonzini
  31 siblings, 1 reply; 58+ messages in thread
From: Michael S. Tsirkin @ 2015-05-31 18:10 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, kraxel

On Mon, May 11, 2015 at 03:48:46PM +0200, Paolo Bonzini wrote:
> These patches implement almost everything that is needed for SMM
> support in OVMF and KVM.  The only missing bit is support for
> SMRAM regions in KVM, but it need not block review of these ones,
> and possibly inclusion of the first 26.

Overall this looks good to me.
Sent some comments, and IIUC there will v2 down the road?


> There are many small parts in this patches, but I am posting them
> together because each small part alone adds very little.
> 
> Patch 1 comes from mst's pull request.
> 
> Patches 2-6 are target-i386 patches.  They add support for memory
> attributes in target-i386, enabling the "secure" attribute whenever
> the CPU is in system management mode.  They also fix two SMM bugs
> found while working on KVM support.
> 
> Patches 7-9 add support for secure access to parallel flash.  If
> enabled, parallel flash behaves as ROM unless the "secure" memory
> transaction attribute is set.
> 
> Patches 10-12 are general infrastructure patches that didn't fit
> elsewhere.  Note that patch 10 introduces new command-line syntax.
> 
> Patches 13-16 rewrite the SMRAM handling in TCG mode, so that the
> SMRAM setup is done just once using the memory API, and then
> enabled/disabled by the CPU without intervention from the chipset.
> The resulting chipset code is simpler and...
> 
> ... patches 17-23 then rely on this to implement support for
> more q35 SMI features, in particular high SMRAM, TSEG and SMI_LOCK.
> This part was done almost entirely by Gerd.
> 
> Patches 24-26 are for q35 feature parity with PIIX4.  They are from Laszlo
> and they are included just because they conflict with the next few.
> 
> Patches 27 and 28 implement KVM support for SMM.  Note that this support
> is not yet upstream (will be in Linux 4.2); these patches will be
> rebased after the updated KVM headers are taken from kvm.git.
> 
> Patches 29-31 add a "-machine smm=on|off|auto" option (QOM property)
> that can be used to hide SMM or make it available on any accelerator.
> The compat gunk makes it available by default on TCG but not on KVM.
> 
> That's it.  Go ahead and review.
> 
> Paolo
> 
> 
> Gerd Hoffmann (6):
>   q35: fix ESMRAMC default
>   q35: add config space wmask for SMRAM and ESMRAMC
>   q35: implement SMRAM.D_LCK
>   q35: add test for SMRAM.D_LCK
>   q35: implement TSEG
>   ich9: implement SMI_LOCK
> 
> Jason Wang (1):
>   pc: add 2.4 machine types
> 
> Laszlo Ersek (3):
>   hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4"
>   hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core
>   hw/acpi: piix4_pm_init(): take fw_cfg object no more
> 
> Paolo Bonzini (21):
>   target-i386: introduce cpu_get_mem_attrs
>   target-i386: Use correct memory attributes for memory accesses
>   target-i386: Use correct memory attributes for ioport accesses
>   target-i386: mask NMIs on entry to SMM
>   target-i386: set G=1 in SMM big real mode selectors
>   pflash_cfi01: change big-endian property to BIT type
>   pflash_cfi01: change to new-style MMIO accessors
>   pflash_cfi01: add secure property
>   vl: allow full-blown QemuOpts syntax for -global
>   qom: add object_property_add_const_link
>   vl: run "late" notifiers immediately
>   target-i386: create a separate AddressSpace for each CPU
>   hw/i386: add a separate region that tracks the SMRAME bit
>   target-i386: use memory API to implement SMRAM
>   hw/i386: remove smram_update
>   q35: implement high SMRAM
>   target-i386: add support for SMBASE MSR and SMIs
>   vga: disable chain4_alias if KVM supports SMRAM
>   pc_piix: rename kvm_enabled to smm_enabled
>   ich9: add smm_enabled field and arguments
>   pc: add SMM property
> 
>  bsd-user/main.c             |   4 -
>  hw/acpi/core.c              |  15 +-
>  hw/acpi/ich9.c              |  12 +-
>  hw/acpi/piix4.c             |  21 +--
>  hw/block/pflash_cfi01.c     | 204 +++++++++++----------------
>  hw/display/vga.c            |   8 +-
>  hw/display/vga_int.h        |   1 +
>  hw/i386/pc.c                |  72 +++++++---
>  hw/i386/pc_piix.c           |  53 +++++--
>  hw/i386/pc_q35.c            |  33 ++++-
>  hw/isa/lpc_ich9.c           |  23 ++-
>  hw/isa/vt82c686.c           |   2 +-
>  hw/mips/mips_malta.c        |   2 +-
>  hw/pci-host/pam.c           |  20 ---
>  hw/pci-host/piix.c          |  39 +++---
>  hw/pci-host/q35.c           | 137 ++++++++++++++++--
>  include/exec/memattrs.h     |   4 +-
>  include/hw/acpi/acpi.h      |   3 +-
>  include/hw/acpi/ich9.h      |   4 +-
>  include/hw/i386/ich9.h      |   8 +-
>  include/hw/i386/pc.h        |   7 +-
>  include/hw/pci-host/pam.h   |   4 -
>  include/hw/pci-host/q35.h   |  36 +++--
>  include/qom/object.h        |  18 +++
>  include/sysemu/kvm.h        |   1 +
>  kvm-all.c                   |   5 +
>  kvm-stub.c                  |   5 +
>  linux-headers/asm-x86/kvm.h |  11 +-
>  linux-headers/linux/kvm.h   |   5 +-
>  linux-user/main.c           |   4 -
>  qdev-monitor.c              |  18 ++-
>  qemu-options.hx             |   7 +-
>  qom/object.c                |  16 +++
>  target-i386/Makefile.objs   |   2 -
>  target-i386/cpu-qom.h       |   3 +
>  target-i386/cpu.c           |  43 ++++++
>  target-i386/cpu.h           |  41 ++++--
>  target-i386/helper.c        | 135 +++++++++++++++---
>  target-i386/helper.h        |  12 +-
>  target-i386/ioport-user.c   |  60 --------
>  target-i386/kvm.c           |  75 ++++++++--
>  target-i386/machine.c       |   3 +
>  target-i386/misc_helper.c   |  59 ++++++--
>  target-i386/seg_helper.c    |  12 +-
>  target-i386/smm_helper.c    | 331 +++++++++++++++++++++++---------------------
>  target-i386/svm_helper.c    | 230 +++++++++++++++---------------
>  target-i386/translate.c     |  12 +-
>  tests/Makefile              |   2 +
>  tests/smram-test.c          |  80 +++++++++++
>  vl.c                        |   6 +
>  50 files changed, 1220 insertions(+), 688 deletions(-)
>  delete mode 100644 target-i386/ioport-user.c
>  create mode 100644 tests/smram-test.c
> 
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM
  2015-05-31 18:09   ` Michael S. Tsirkin
@ 2015-06-01  7:30     ` Paolo Bonzini
  2015-06-01  8:10       ` Michael S. Tsirkin
  0 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-06-01  7:30 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: lersek, qemu-devel, kraxel



On 31/05/2015 20:09, Michael S. Tsirkin wrote:
> On Mon, May 11, 2015 at 03:49:01PM +0200, Paolo Bonzini wrote:
>> Remove cpu_smm_register and cpu_smm_update.  Instead, each CPU
>> address space gets an extra region which is an alias of
>> /machine/smram.  This extra region is enabled or disabled
>> as the CPU enters/exits SMM.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  bsd-user/main.c           |  4 ----
>>  hw/i386/pc.c              | 21 ---------------------
>>  hw/pci-host/pam.c         | 18 ++----------------
>>  hw/pci-host/piix.c        | 25 +++++--------------------
>>  hw/pci-host/q35.c         | 19 +++----------------
>>  include/hw/i386/pc.h      |  1 -
>>  include/hw/pci-host/pam.h |  5 +----
>>  include/hw/pci-host/q35.h |  1 -
>>  linux-user/main.c         |  4 ----
>>  target-i386/cpu-qom.h     |  4 +++-
>>  target-i386/cpu.c         | 33 +++++++++++++++++++++++++++++++--
>>  target-i386/cpu.h         |  3 ++-
>>  target-i386/machine.c     |  3 +++
>>  target-i386/smm_helper.c  | 12 ++++++++++--
>>  14 files changed, 60 insertions(+), 93 deletions(-)
>>
>> diff --git a/bsd-user/main.c b/bsd-user/main.c
>> index 5bfaf5c..ba0b998 100644
>> --- a/bsd-user/main.c
>> +++ b/bsd-user/main.c
>> @@ -108,10 +108,6 @@ void cpu_list_unlock(void)
>>  /***********************************************************/
>>  /* CPUX86 core interface */
>>  
>> -void cpu_smm_update(CPUX86State *env)
>> -{
>> -}
>> -
>>  uint64_t cpu_get_tsc(CPUX86State *env)
>>  {
>>      return cpu_get_real_ticks();
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index a8e6be1..a7ee9ef 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -163,27 +163,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
>>      return cpu_get_ticks();
>>  }
>>  
>> -/* SMM support */
>> -
>> -static cpu_set_smm_t smm_set;
>> -static void *smm_arg;
>> -
>> -void cpu_smm_register(cpu_set_smm_t callback, void *arg)
>> -{
>> -    assert(smm_set == NULL);
>> -    assert(smm_arg == NULL);
>> -    smm_set = callback;
>> -    smm_arg = arg;
>> -}
>> -
>> -void cpu_smm_update(CPUX86State *env)
>> -{
>> -    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
>> -        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
>> -    }
>> -}
>> -
>> -
>>  /* IRQ handling */
>>  int cpu_get_pic_interrupt(CPUX86State *env)
>>  {
>> diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c
>> index 8272de3..99d7af9 100644
>> --- a/hw/pci-host/pam.c
>> +++ b/hw/pci-host/pam.c
>> @@ -31,26 +31,12 @@
>>  #include "sysemu/sysemu.h"
>>  #include "hw/pci-host/pam.h"
>>  
>> -void smram_update(MemoryRegion *smram_region, uint8_t smram,
>> -                  uint8_t smm_enabled)
>> +void smram_update(MemoryRegion *smram_region, uint8_t smram)
>>  {
>> -    bool smram_enabled;
>> -
>> -    smram_enabled = ((smm_enabled && (smram & SMRAM_G_SMRAME)) ||
>> -                        (smram & SMRAM_D_OPEN));
>> +    bool smram_enabled = (smram & SMRAM_D_OPEN);
>>      memory_region_set_enabled(smram_region, !smram_enabled);
>>  }
>>  
>> -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
>> -                   MemoryRegion *smram_region)
>> -{
>> -    uint8_t smm_enabled = (smm != 0);
>> -    if (*host_smm_enabled != smm_enabled) {
>> -        *host_smm_enabled = smm_enabled;
>> -        smram_update(smram_region, smram, *host_smm_enabled);
>> -    }
>> -}
>> -
>>  void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
>>                MemoryRegion *system_memory, MemoryRegion *pci_address_space,
>>                PAMMemoryRegion *mem, uint32_t start, uint32_t size)
>> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
>> index a280d57..46c0278 100644
>> --- a/hw/pci-host/piix.c
>> +++ b/hw/pci-host/piix.c
>> @@ -106,7 +106,6 @@ struct PCII440FXState {
>>      PAMMemoryRegion pam_regions[13];
>>      MemoryRegion smram_region;
>>      MemoryRegion smram, low_smram;
>> -    uint8_t smm_enabled;
>>  };
>>  
>>  
>> @@ -139,23 +138,12 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
>>          pam_update(&d->pam_regions[i], i,
>>                     pd->config[I440FX_PAM + ((i + 1) / 2)]);
>>      }
>> -    smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
>> +    smram_update(&d->smram_region, pd->config[I440FX_SMRAM]);
>>      memory_region_set_enabled(&d->smram,
>>                                pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
>>      memory_region_transaction_commit();
>>  }
>>  
>> -static void i440fx_set_smm(int val, void *arg)
>> -{
>> -    PCII440FXState *d = arg;
>> -    PCIDevice *pd = PCI_DEVICE(d);
>> -
>> -    memory_region_transaction_begin();
>> -    smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
>> -                  &d->smram_region);
>> -    memory_region_transaction_commit();
>> -}
>> -
>>  
>>  static void i440fx_write_config(PCIDevice *dev,
>>                                  uint32_t address, uint32_t val, int len)
>> @@ -175,12 +163,13 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
>>      PCII440FXState *d = opaque;
>>      PCIDevice *pd = PCI_DEVICE(d);
>>      int ret, i;
>> +    uint8_t smm_enabled;
>>  
>>      ret = pci_device_load(pd, f);
>>      if (ret < 0)
>>          return ret;
>>      i440fx_update_memory_mappings(d);
>> -    qemu_get_8s(f, &d->smm_enabled);
>> +    qemu_get_8s(f, &smm_enabled);
>>  
>>      if (version_id == 2) {
>>          for (i = 0; i < PIIX_NUM_PIRQS; i++) {
>> @@ -208,7 +197,7 @@ static const VMStateDescription vmstate_i440fx = {
>>      .post_load = i440fx_post_load,
>>      .fields = (VMStateField[]) {
>>          VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
>> -        VMSTATE_UINT8(smm_enabled, PCII440FXState),
>> +        VMSTATE_UNUSED(1),
>>          VMSTATE_END_OF_LIST()
>>      }
>>  };
> 
> Won't this cause problems for cross-version migration?
> Old qemu receiving this will think smm is enabled,
> unconditionally.

UNUSED is written as zeroes, so it will think SMM is _disabled_,
unconditionally.  Note that d->smram_region is backwards: it aliases to
VRAM, so it is enabled when SMRAM is closed and disabled when SMRAM is open.

This is correct for KVM, though not for TCG.  Backwards migration is not
supported officially upstream, and I think we can agree it is even less
supported for TCG.

Paolo

> 
>> @@ -300,11 +289,7 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
>>  
>>  static void i440fx_realize(PCIDevice *dev, Error **errp)
>>  {
>> -    PCII440FXState *d = I440FX_PCI_DEVICE(dev);
>> -
>>      dev->config[I440FX_SMRAM] = 0x02;
>> -
>> -    cpu_smm_register(&i440fx_set_smm, d);
>>  }
>>  
>>  PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>> @@ -360,7 +345,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>>      memory_region_init(&f->smram, OBJECT(d), "smram", 1ull << 32);
>>      memory_region_set_enabled(&f->smram, true);
>>      memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
>> -                             f->system_memory, 0xa0000, 0x20000);
>> +                             f->ram_memory, 0xa0000, 0x20000);
>>      memory_region_set_enabled(&f->low_smram, true);
>>      memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
>>      object_property_add_alias(qdev_get_machine(), "smram",
>> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
>> index de8326a..bd17a05 100644
>> --- a/hw/pci-host/q35.c
>> +++ b/hw/pci-host/q35.c
>> @@ -268,24 +268,12 @@ static void mch_update_smram(MCHPCIState *mch)
>>      PCIDevice *pd = PCI_DEVICE(mch);
>>  
>>      memory_region_transaction_begin();
>> -    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
>> -                    mch->smm_enabled);
>> +    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM]);
>>      memory_region_set_enabled(&mch->smram,
>>                                pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
>>      memory_region_transaction_commit();
>>  }
>>  
>> -static void mch_set_smm(int smm, void *arg)
>> -{
>> -    MCHPCIState *mch = arg;
>> -    PCIDevice *pd = PCI_DEVICE(mch);
>> -
>> -    memory_region_transaction_begin();
>> -    smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
>> -                    &mch->smram_region);
>> -    memory_region_transaction_commit();
>> -}
>> -
>>  static void mch_write_config(PCIDevice *d,
>>                                uint32_t address, uint32_t val, int len)
>>  {
>> @@ -331,7 +319,7 @@ static const VMStateDescription vmstate_mch = {
>>      .post_load = mch_post_load,
>>      .fields = (VMStateField[]) {
>>          VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
>> -        VMSTATE_UINT8(smm_enabled, MCHPCIState),
>> +        VMSTATE_UNUSED(1),
>>          VMSTATE_END_OF_LIST()
>>      }
>>  };
>> @@ -402,7 +390,6 @@ static void mch_realize(PCIDevice *d, Error **errp)
>>                             mch->pci_address_space);
>>  
>>      /* if *disabled* show SMRAM to all CPUs */
>> -    cpu_smm_register(&mch_set_smm, mch);
>>      memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
>>                               mch->pci_address_space, 0xa0000, 0x20000);
>>      memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
>> @@ -413,7 +400,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
>>      memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
>>      memory_region_set_enabled(&mch->smram, true);
>>      memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
>> -                             mch->system_memory, 0xa0000, 0x20000);
>> +                             mch->ram_memory, 0xa0000, 0x20000);
>>      memory_region_set_enabled(&mch->low_smram, true);
>>      memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
>>      object_property_add_const_link(qdev_get_machine(), "smram",
>> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
>> index 1b35168..c9a9f6e 100644
>> --- a/include/hw/i386/pc.h
>> +++ b/include/hw/i386/pc.h
>> @@ -211,7 +211,6 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
>>  void pc_pci_device_init(PCIBus *pci_bus);
>>  
>>  typedef void (*cpu_set_smm_t)(int smm, void *arg);
>> -void cpu_smm_register(cpu_set_smm_t callback, void *arg);
>>  
>>  void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
>>  
>> diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h
>> index 4d03e4b..80dd605 100644
>> --- a/include/hw/pci-host/pam.h
>> +++ b/include/hw/pci-host/pam.h
>> @@ -86,10 +86,7 @@ typedef struct PAMMemoryRegion {
>>      unsigned current;
>>  } PAMMemoryRegion;
>>  
>> -void smram_update(MemoryRegion *smram_region, uint8_t smram,
>> -                  uint8_t smm_enabled);
>> -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
>> -                   MemoryRegion *smram_region);
>> +void smram_update(MemoryRegion *smram_region, uint8_t smram);
>>  void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system,
>>                MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size);
>>  void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val);
>> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
>> index 4c9eacc..17adeaa 100644
>> --- a/include/hw/pci-host/q35.h
>> +++ b/include/hw/pci-host/q35.h
>> @@ -55,7 +55,6 @@ typedef struct MCHPCIState {
>>      MemoryRegion smram_region;
>>      MemoryRegion smram, low_smram;
>>      PcPciInfo pci_info;
>> -    uint8_t smm_enabled;
>>      ram_addr_t below_4g_mem_size;
>>      ram_addr_t above_4g_mem_size;
>>      uint64_t pci_hole64_size;
>> diff --git a/linux-user/main.c b/linux-user/main.c
>> index 3f32db0..6989b82 100644
>> --- a/linux-user/main.c
>> +++ b/linux-user/main.c
>> @@ -215,10 +215,6 @@ void cpu_list_unlock(void)
>>  /***********************************************************/
>>  /* CPUX86 core interface */
>>  
>> -void cpu_smm_update(CPUX86State *env)
>> -{
>> -}
>> -
>>  uint64_t cpu_get_tsc(CPUX86State *env)
>>  {
>>      return cpu_get_real_ticks();
>> diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
>> index 39cd878..7a4fddd 100644
>> --- a/target-i386/cpu-qom.h
>> +++ b/target-i386/cpu-qom.h
>> @@ -23,6 +23,7 @@
>>  #include "qom/cpu.h"
>>  #include "cpu.h"
>>  #include "qapi/error.h"
>> +#include "qemu/notify.h"
>>  
>>  #ifdef TARGET_X86_64
>>  #define TYPE_X86_CPU "x86_64-cpu"
>> @@ -111,7 +112,8 @@ typedef struct X86CPU {
>>      /* in order to simplify APIC support, we leave this pointer to the
>>         user */
>>      struct DeviceState *apic_state;
>> -    struct MemoryRegion *cpu_as_root;
>> +    struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
>> +    Notifier machine_done;
>>  } X86CPU;
>>  
>>  static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
>> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> index 97c4804..7b6f9e4 100644
>> --- a/target-i386/cpu.c
>> +++ b/target-i386/cpu.c
>> @@ -2751,6 +2751,21 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
>>      object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
>>                               errp);
>>  }
>> +
>> +static void x86_cpu_machine_done(Notifier *n, void *unused)
>> +{
>> +    X86CPU *cpu = container_of(n, X86CPU, machine_done);
>> +    MemoryRegion *smram =
>> +        (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
>> +
>> +    if (smram) {
>> +        cpu->smram = g_new(MemoryRegion, 1);
>> +        memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
>> +                                 smram, 0, 1ull << 32);
>> +        memory_region_set_enabled(cpu->smram, false);
>> +        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
>> +    }
>> +}
>>  #else
>>  static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
>>  {
>> @@ -2815,12 +2830,26 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>>  
>>  #ifndef CONFIG_USER_ONLY
>>      if (tcg_enabled()) {
>> +        cpu->cpu_as_mem = g_new(MemoryRegion, 1);
>>          cpu->cpu_as_root = g_new(MemoryRegion, 1);
>>          cs->as = g_new(AddressSpace, 1);
>> -        memory_region_init_alias(cpu->cpu_as_root, OBJECT(cpu), "memory",
>> -                                 get_system_memory(), 0, ~0ull);
>> +
>> +        /* Outer container... */
>> +        memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
>>          memory_region_set_enabled(cpu->cpu_as_root, true);
>> +
>> +        /* ... with two regions inside: normal system memory with low
>> +         * priority, and...
>> +         */
>> +        memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
>> +                                 get_system_memory(), 0, ~0ull);
>> +        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
>> +        memory_region_set_enabled(cpu->cpu_as_mem, true);
>>          address_space_init(cs->as, cpu->cpu_as_root, "CPU");
>> +
>> +        /* ... SMRAM with higher priority, linked from /machine/smram.  */
>> +        cpu->machine_done.notify = x86_cpu_machine_done;
>> +        qemu_add_machine_init_done_notifier(&cpu->machine_done);
>>      }
>>  #endif
>>  
>> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
>> index 4510ae7..df6e885 100644
>> --- a/target-i386/cpu.h
>> +++ b/target-i386/cpu.h
>> @@ -1157,7 +1157,6 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
>>  void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
>>  
>>  /* hw/pc.c */
>> -void cpu_smm_update(CPUX86State *env);
>>  uint64_t cpu_get_tsc(CPUX86State *env);
>>  
>>  #define TARGET_PAGE_BITS 12
>> @@ -1323,7 +1322,9 @@ void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
>>  /* seg_helper.c */
>>  void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
>>  
>> +/* smm_helper.c */
>>  void do_smm_enter(X86CPU *cpu);
>> +void cpu_smm_update(X86CPU *cpu);
>>  
>>  void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
>>  
>> diff --git a/target-i386/machine.c b/target-i386/machine.c
>> index cd1ddd2..69d86cb 100644
>> --- a/target-i386/machine.c
>> +++ b/target-i386/machine.c
>> @@ -372,6 +372,9 @@ static int cpu_post_load(void *opaque, int version_id)
>>      }
>>      tlb_flush(cs, 1);
>>  
>> +    if (tcg_enabled()) {
>> +        cpu_smm_update(cpu);
>> +    }
>>      return 0;
>>  }
>>  
>> diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
>> index 5617a14..762f4e5 100644
>> --- a/target-i386/smm_helper.c
>> +++ b/target-i386/smm_helper.c
>> @@ -40,6 +40,14 @@ void helper_rsm(CPUX86State *env)
>>  #define SMM_REVISION_ID 0x00020000
>>  #endif
>>  
>> +void cpu_smm_update(X86CPU *cpu)
>> +{
>> +    CPUX86State *env = &cpu->env;
>> +    bool smm_enabled = (env->hflags & HF_SMM_MASK);
>> +
>> +    memory_region_set_enabled(cpu->smram, smm_enabled);
>> +}
>> +
>>  void do_smm_enter(X86CPU *cpu)
>>  {
>>      CPUX86State *env = &cpu->env;
>> @@ -57,7 +65,7 @@ void do_smm_enter(X86CPU *cpu)
>>      } else {
>>          env->hflags2 |= HF2_NMI_MASK;
>>      }
>> -    cpu_smm_update(env);
>> +    cpu_smm_update(cpu);
>>  
>>      sm_state = env->smbase + 0x8000;
>>  
>> @@ -317,7 +325,7 @@ void helper_rsm(CPUX86State *env)
>>      }
>>      env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
>>      env->hflags &= ~HF_SMM_MASK;
>> -    cpu_smm_update(env);
>> +    cpu_smm_update(cpu);
>>  
>>      qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
>>      log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
>> -- 
>> 1.8.3.1
>>
> 
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM
  2015-05-31 18:10 ` [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Michael S. Tsirkin
@ 2015-06-01  7:32   ` Paolo Bonzini
  2015-06-01  7:51     ` Michael S. Tsirkin
  0 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-06-01  7:32 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: lersek, qemu-devel, kraxel



On 31/05/2015 20:10, Michael S. Tsirkin wrote:
> On Mon, May 11, 2015 at 03:48:46PM +0200, Paolo Bonzini wrote:
>> These patches implement almost everything that is needed for SMM
>> support in OVMF and KVM.  The only missing bit is support for
>> SMRAM regions in KVM, but it need not block review of these ones,
>> and possibly inclusion of the first 26.
> 
> Overall this looks good to me.
> Sent some comments, and IIUC there will v2 down the road?

I would like to send a pull request for the non-KVM parts (up to patch
23) on Wednesday or Thursday.  The remaining pieces have to wait for
inclusion of KVM support in the kernel, and there will be a v2 with
minimal changes posted during soft freeze.

Let me know, either now or after I post v2, if you want to merge them
yourself or provide your Acked-by.

Paolo

> 
>> There are many small parts in this patches, but I am posting them
>> together because each small part alone adds very little.
>>
>> Patch 1 comes from mst's pull request.
>>
>> Patches 2-6 are target-i386 patches.  They add support for memory
>> attributes in target-i386, enabling the "secure" attribute whenever
>> the CPU is in system management mode.  They also fix two SMM bugs
>> found while working on KVM support.
>>
>> Patches 7-9 add support for secure access to parallel flash.  If
>> enabled, parallel flash behaves as ROM unless the "secure" memory
>> transaction attribute is set.
>>
>> Patches 10-12 are general infrastructure patches that didn't fit
>> elsewhere.  Note that patch 10 introduces new command-line syntax.
>>
>> Patches 13-16 rewrite the SMRAM handling in TCG mode, so that the
>> SMRAM setup is done just once using the memory API, and then
>> enabled/disabled by the CPU without intervention from the chipset.
>> The resulting chipset code is simpler and...
>>
>> ... patches 17-23 then rely on this to implement support for
>> more q35 SMI features, in particular high SMRAM, TSEG and SMI_LOCK.
>> This part was done almost entirely by Gerd.
>>
>> Patches 24-26 are for q35 feature parity with PIIX4.  They are from Laszlo
>> and they are included just because they conflict with the next few.
>>
>> Patches 27 and 28 implement KVM support for SMM.  Note that this support
>> is not yet upstream (will be in Linux 4.2); these patches will be
>> rebased after the updated KVM headers are taken from kvm.git.
>>
>> Patches 29-31 add a "-machine smm=on|off|auto" option (QOM property)
>> that can be used to hide SMM or make it available on any accelerator.
>> The compat gunk makes it available by default on TCG but not on KVM.
>>
>> That's it.  Go ahead and review.
>>
>> Paolo
>>
>>
>> Gerd Hoffmann (6):
>>   q35: fix ESMRAMC default
>>   q35: add config space wmask for SMRAM and ESMRAMC
>>   q35: implement SMRAM.D_LCK
>>   q35: add test for SMRAM.D_LCK
>>   q35: implement TSEG
>>   ich9: implement SMI_LOCK
>>
>> Jason Wang (1):
>>   pc: add 2.4 machine types
>>
>> Laszlo Ersek (3):
>>   hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4"
>>   hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core
>>   hw/acpi: piix4_pm_init(): take fw_cfg object no more
>>
>> Paolo Bonzini (21):
>>   target-i386: introduce cpu_get_mem_attrs
>>   target-i386: Use correct memory attributes for memory accesses
>>   target-i386: Use correct memory attributes for ioport accesses
>>   target-i386: mask NMIs on entry to SMM
>>   target-i386: set G=1 in SMM big real mode selectors
>>   pflash_cfi01: change big-endian property to BIT type
>>   pflash_cfi01: change to new-style MMIO accessors
>>   pflash_cfi01: add secure property
>>   vl: allow full-blown QemuOpts syntax for -global
>>   qom: add object_property_add_const_link
>>   vl: run "late" notifiers immediately
>>   target-i386: create a separate AddressSpace for each CPU
>>   hw/i386: add a separate region that tracks the SMRAME bit
>>   target-i386: use memory API to implement SMRAM
>>   hw/i386: remove smram_update
>>   q35: implement high SMRAM
>>   target-i386: add support for SMBASE MSR and SMIs
>>   vga: disable chain4_alias if KVM supports SMRAM
>>   pc_piix: rename kvm_enabled to smm_enabled
>>   ich9: add smm_enabled field and arguments
>>   pc: add SMM property
>>
>>  bsd-user/main.c             |   4 -
>>  hw/acpi/core.c              |  15 +-
>>  hw/acpi/ich9.c              |  12 +-
>>  hw/acpi/piix4.c             |  21 +--
>>  hw/block/pflash_cfi01.c     | 204 +++++++++++----------------
>>  hw/display/vga.c            |   8 +-
>>  hw/display/vga_int.h        |   1 +
>>  hw/i386/pc.c                |  72 +++++++---
>>  hw/i386/pc_piix.c           |  53 +++++--
>>  hw/i386/pc_q35.c            |  33 ++++-
>>  hw/isa/lpc_ich9.c           |  23 ++-
>>  hw/isa/vt82c686.c           |   2 +-
>>  hw/mips/mips_malta.c        |   2 +-
>>  hw/pci-host/pam.c           |  20 ---
>>  hw/pci-host/piix.c          |  39 +++---
>>  hw/pci-host/q35.c           | 137 ++++++++++++++++--
>>  include/exec/memattrs.h     |   4 +-
>>  include/hw/acpi/acpi.h      |   3 +-
>>  include/hw/acpi/ich9.h      |   4 +-
>>  include/hw/i386/ich9.h      |   8 +-
>>  include/hw/i386/pc.h        |   7 +-
>>  include/hw/pci-host/pam.h   |   4 -
>>  include/hw/pci-host/q35.h   |  36 +++--
>>  include/qom/object.h        |  18 +++
>>  include/sysemu/kvm.h        |   1 +
>>  kvm-all.c                   |   5 +
>>  kvm-stub.c                  |   5 +
>>  linux-headers/asm-x86/kvm.h |  11 +-
>>  linux-headers/linux/kvm.h   |   5 +-
>>  linux-user/main.c           |   4 -
>>  qdev-monitor.c              |  18 ++-
>>  qemu-options.hx             |   7 +-
>>  qom/object.c                |  16 +++
>>  target-i386/Makefile.objs   |   2 -
>>  target-i386/cpu-qom.h       |   3 +
>>  target-i386/cpu.c           |  43 ++++++
>>  target-i386/cpu.h           |  41 ++++--
>>  target-i386/helper.c        | 135 +++++++++++++++---
>>  target-i386/helper.h        |  12 +-
>>  target-i386/ioport-user.c   |  60 --------
>>  target-i386/kvm.c           |  75 ++++++++--
>>  target-i386/machine.c       |   3 +
>>  target-i386/misc_helper.c   |  59 ++++++--
>>  target-i386/seg_helper.c    |  12 +-
>>  target-i386/smm_helper.c    | 331 +++++++++++++++++++++++---------------------
>>  target-i386/svm_helper.c    | 230 +++++++++++++++---------------
>>  target-i386/translate.c     |  12 +-
>>  tests/Makefile              |   2 +
>>  tests/smram-test.c          |  80 +++++++++++
>>  vl.c                        |   6 +
>>  50 files changed, 1220 insertions(+), 688 deletions(-)
>>  delete mode 100644 target-i386/ioport-user.c
>>  create mode 100644 tests/smram-test.c
>>
>> -- 
>> 1.8.3.1
> 
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM
  2015-06-01  7:32   ` Paolo Bonzini
@ 2015-06-01  7:51     ` Michael S. Tsirkin
  2015-06-01  8:56       ` Paolo Bonzini
  0 siblings, 1 reply; 58+ messages in thread
From: Michael S. Tsirkin @ 2015-06-01  7:51 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, kraxel

On Mon, Jun 01, 2015 at 09:32:47AM +0200, Paolo Bonzini wrote:
> 
> 
> On 31/05/2015 20:10, Michael S. Tsirkin wrote:
> > On Mon, May 11, 2015 at 03:48:46PM +0200, Paolo Bonzini wrote:
> >> These patches implement almost everything that is needed for SMM
> >> support in OVMF and KVM.  The only missing bit is support for
> >> SMRAM regions in KVM, but it need not block review of these ones,
> >> and possibly inclusion of the first 26.
> > 
> > Overall this looks good to me.
> > Sent some comments, and IIUC there will v2 down the road?
> 
> I would like to send a pull request for the non-KVM parts (up to patch
> 23) on Wednesday or Thursday.  The remaining pieces have to wait for
> inclusion of KVM support in the kernel, and there will be a v2 with
> minimal changes posted during soft freeze.
> 
> Let me know, either now or after I post v2, if you want to merge them
> yourself or provide your Acked-by.
> 
> Paolo

I think the pc tree makes sense for the non kvm parts,
and will help avoid merge conflicts.
If you split non-kvm bits out anyway, then I'll merge it.

> > 
> >> There are many small parts in this patches, but I am posting them
> >> together because each small part alone adds very little.
> >>
> >> Patch 1 comes from mst's pull request.
> >>
> >> Patches 2-6 are target-i386 patches.  They add support for memory
> >> attributes in target-i386, enabling the "secure" attribute whenever
> >> the CPU is in system management mode.  They also fix two SMM bugs
> >> found while working on KVM support.
> >>
> >> Patches 7-9 add support for secure access to parallel flash.  If
> >> enabled, parallel flash behaves as ROM unless the "secure" memory
> >> transaction attribute is set.
> >>
> >> Patches 10-12 are general infrastructure patches that didn't fit
> >> elsewhere.  Note that patch 10 introduces new command-line syntax.
> >>
> >> Patches 13-16 rewrite the SMRAM handling in TCG mode, so that the
> >> SMRAM setup is done just once using the memory API, and then
> >> enabled/disabled by the CPU without intervention from the chipset.
> >> The resulting chipset code is simpler and...
> >>
> >> ... patches 17-23 then rely on this to implement support for
> >> more q35 SMI features, in particular high SMRAM, TSEG and SMI_LOCK.
> >> This part was done almost entirely by Gerd.
> >>
> >> Patches 24-26 are for q35 feature parity with PIIX4.  They are from Laszlo
> >> and they are included just because they conflict with the next few.
> >>
> >> Patches 27 and 28 implement KVM support for SMM.  Note that this support
> >> is not yet upstream (will be in Linux 4.2); these patches will be
> >> rebased after the updated KVM headers are taken from kvm.git.
> >>
> >> Patches 29-31 add a "-machine smm=on|off|auto" option (QOM property)
> >> that can be used to hide SMM or make it available on any accelerator.
> >> The compat gunk makes it available by default on TCG but not on KVM.
> >>
> >> That's it.  Go ahead and review.
> >>
> >> Paolo
> >>
> >>
> >> Gerd Hoffmann (6):
> >>   q35: fix ESMRAMC default
> >>   q35: add config space wmask for SMRAM and ESMRAMC
> >>   q35: implement SMRAM.D_LCK
> >>   q35: add test for SMRAM.D_LCK
> >>   q35: implement TSEG
> >>   ich9: implement SMI_LOCK
> >>
> >> Jason Wang (1):
> >>   pc: add 2.4 machine types
> >>
> >> Laszlo Ersek (3):
> >>   hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4"
> >>   hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core
> >>   hw/acpi: piix4_pm_init(): take fw_cfg object no more
> >>
> >> Paolo Bonzini (21):
> >>   target-i386: introduce cpu_get_mem_attrs
> >>   target-i386: Use correct memory attributes for memory accesses
> >>   target-i386: Use correct memory attributes for ioport accesses
> >>   target-i386: mask NMIs on entry to SMM
> >>   target-i386: set G=1 in SMM big real mode selectors
> >>   pflash_cfi01: change big-endian property to BIT type
> >>   pflash_cfi01: change to new-style MMIO accessors
> >>   pflash_cfi01: add secure property
> >>   vl: allow full-blown QemuOpts syntax for -global
> >>   qom: add object_property_add_const_link
> >>   vl: run "late" notifiers immediately
> >>   target-i386: create a separate AddressSpace for each CPU
> >>   hw/i386: add a separate region that tracks the SMRAME bit
> >>   target-i386: use memory API to implement SMRAM
> >>   hw/i386: remove smram_update
> >>   q35: implement high SMRAM
> >>   target-i386: add support for SMBASE MSR and SMIs
> >>   vga: disable chain4_alias if KVM supports SMRAM
> >>   pc_piix: rename kvm_enabled to smm_enabled
> >>   ich9: add smm_enabled field and arguments
> >>   pc: add SMM property
> >>
> >>  bsd-user/main.c             |   4 -
> >>  hw/acpi/core.c              |  15 +-
> >>  hw/acpi/ich9.c              |  12 +-
> >>  hw/acpi/piix4.c             |  21 +--
> >>  hw/block/pflash_cfi01.c     | 204 +++++++++++----------------
> >>  hw/display/vga.c            |   8 +-
> >>  hw/display/vga_int.h        |   1 +
> >>  hw/i386/pc.c                |  72 +++++++---
> >>  hw/i386/pc_piix.c           |  53 +++++--
> >>  hw/i386/pc_q35.c            |  33 ++++-
> >>  hw/isa/lpc_ich9.c           |  23 ++-
> >>  hw/isa/vt82c686.c           |   2 +-
> >>  hw/mips/mips_malta.c        |   2 +-
> >>  hw/pci-host/pam.c           |  20 ---
> >>  hw/pci-host/piix.c          |  39 +++---
> >>  hw/pci-host/q35.c           | 137 ++++++++++++++++--
> >>  include/exec/memattrs.h     |   4 +-
> >>  include/hw/acpi/acpi.h      |   3 +-
> >>  include/hw/acpi/ich9.h      |   4 +-
> >>  include/hw/i386/ich9.h      |   8 +-
> >>  include/hw/i386/pc.h        |   7 +-
> >>  include/hw/pci-host/pam.h   |   4 -
> >>  include/hw/pci-host/q35.h   |  36 +++--
> >>  include/qom/object.h        |  18 +++
> >>  include/sysemu/kvm.h        |   1 +
> >>  kvm-all.c                   |   5 +
> >>  kvm-stub.c                  |   5 +
> >>  linux-headers/asm-x86/kvm.h |  11 +-
> >>  linux-headers/linux/kvm.h   |   5 +-
> >>  linux-user/main.c           |   4 -
> >>  qdev-monitor.c              |  18 ++-
> >>  qemu-options.hx             |   7 +-
> >>  qom/object.c                |  16 +++
> >>  target-i386/Makefile.objs   |   2 -
> >>  target-i386/cpu-qom.h       |   3 +
> >>  target-i386/cpu.c           |  43 ++++++
> >>  target-i386/cpu.h           |  41 ++++--
> >>  target-i386/helper.c        | 135 +++++++++++++++---
> >>  target-i386/helper.h        |  12 +-
> >>  target-i386/ioport-user.c   |  60 --------
> >>  target-i386/kvm.c           |  75 ++++++++--
> >>  target-i386/machine.c       |   3 +
> >>  target-i386/misc_helper.c   |  59 ++++++--
> >>  target-i386/seg_helper.c    |  12 +-
> >>  target-i386/smm_helper.c    | 331 +++++++++++++++++++++++---------------------
> >>  target-i386/svm_helper.c    | 230 +++++++++++++++---------------
> >>  target-i386/translate.c     |  12 +-
> >>  tests/Makefile              |   2 +
> >>  tests/smram-test.c          |  80 +++++++++++
> >>  vl.c                        |   6 +
> >>  50 files changed, 1220 insertions(+), 688 deletions(-)
> >>  delete mode 100644 target-i386/ioport-user.c
> >>  create mode 100644 tests/smram-test.c
> >>
> >> -- 
> >> 1.8.3.1
> > 
> > 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM
  2015-06-01  7:30     ` Paolo Bonzini
@ 2015-06-01  8:10       ` Michael S. Tsirkin
  2015-06-01  8:58         ` Paolo Bonzini
  0 siblings, 1 reply; 58+ messages in thread
From: Michael S. Tsirkin @ 2015-06-01  8:10 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, kraxel

On Mon, Jun 01, 2015 at 09:30:38AM +0200, Paolo Bonzini wrote:
> 
> 
> On 31/05/2015 20:09, Michael S. Tsirkin wrote:
> > On Mon, May 11, 2015 at 03:49:01PM +0200, Paolo Bonzini wrote:
> >> Remove cpu_smm_register and cpu_smm_update.  Instead, each CPU
> >> address space gets an extra region which is an alias of
> >> /machine/smram.  This extra region is enabled or disabled
> >> as the CPU enters/exits SMM.
> >>
> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >> ---
> >>  bsd-user/main.c           |  4 ----
> >>  hw/i386/pc.c              | 21 ---------------------
> >>  hw/pci-host/pam.c         | 18 ++----------------
> >>  hw/pci-host/piix.c        | 25 +++++--------------------
> >>  hw/pci-host/q35.c         | 19 +++----------------
> >>  include/hw/i386/pc.h      |  1 -
> >>  include/hw/pci-host/pam.h |  5 +----
> >>  include/hw/pci-host/q35.h |  1 -
> >>  linux-user/main.c         |  4 ----
> >>  target-i386/cpu-qom.h     |  4 +++-
> >>  target-i386/cpu.c         | 33 +++++++++++++++++++++++++++++++--
> >>  target-i386/cpu.h         |  3 ++-
> >>  target-i386/machine.c     |  3 +++
> >>  target-i386/smm_helper.c  | 12 ++++++++++--
> >>  14 files changed, 60 insertions(+), 93 deletions(-)
> >>
> >> diff --git a/bsd-user/main.c b/bsd-user/main.c
> >> index 5bfaf5c..ba0b998 100644
> >> --- a/bsd-user/main.c
> >> +++ b/bsd-user/main.c
> >> @@ -108,10 +108,6 @@ void cpu_list_unlock(void)
> >>  /***********************************************************/
> >>  /* CPUX86 core interface */
> >>  
> >> -void cpu_smm_update(CPUX86State *env)
> >> -{
> >> -}
> >> -
> >>  uint64_t cpu_get_tsc(CPUX86State *env)
> >>  {
> >>      return cpu_get_real_ticks();
> >> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> >> index a8e6be1..a7ee9ef 100644
> >> --- a/hw/i386/pc.c
> >> +++ b/hw/i386/pc.c
> >> @@ -163,27 +163,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
> >>      return cpu_get_ticks();
> >>  }
> >>  
> >> -/* SMM support */
> >> -
> >> -static cpu_set_smm_t smm_set;
> >> -static void *smm_arg;
> >> -
> >> -void cpu_smm_register(cpu_set_smm_t callback, void *arg)
> >> -{
> >> -    assert(smm_set == NULL);
> >> -    assert(smm_arg == NULL);
> >> -    smm_set = callback;
> >> -    smm_arg = arg;
> >> -}
> >> -
> >> -void cpu_smm_update(CPUX86State *env)
> >> -{
> >> -    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
> >> -        smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
> >> -    }
> >> -}
> >> -
> >> -
> >>  /* IRQ handling */
> >>  int cpu_get_pic_interrupt(CPUX86State *env)
> >>  {
> >> diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c
> >> index 8272de3..99d7af9 100644
> >> --- a/hw/pci-host/pam.c
> >> +++ b/hw/pci-host/pam.c
> >> @@ -31,26 +31,12 @@
> >>  #include "sysemu/sysemu.h"
> >>  #include "hw/pci-host/pam.h"
> >>  
> >> -void smram_update(MemoryRegion *smram_region, uint8_t smram,
> >> -                  uint8_t smm_enabled)
> >> +void smram_update(MemoryRegion *smram_region, uint8_t smram)
> >>  {
> >> -    bool smram_enabled;
> >> -
> >> -    smram_enabled = ((smm_enabled && (smram & SMRAM_G_SMRAME)) ||
> >> -                        (smram & SMRAM_D_OPEN));
> >> +    bool smram_enabled = (smram & SMRAM_D_OPEN);
> >>      memory_region_set_enabled(smram_region, !smram_enabled);
> >>  }
> >>  
> >> -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
> >> -                   MemoryRegion *smram_region)
> >> -{
> >> -    uint8_t smm_enabled = (smm != 0);
> >> -    if (*host_smm_enabled != smm_enabled) {
> >> -        *host_smm_enabled = smm_enabled;
> >> -        smram_update(smram_region, smram, *host_smm_enabled);
> >> -    }
> >> -}
> >> -
> >>  void init_pam(DeviceState *dev, MemoryRegion *ram_memory,
> >>                MemoryRegion *system_memory, MemoryRegion *pci_address_space,
> >>                PAMMemoryRegion *mem, uint32_t start, uint32_t size)
> >> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> >> index a280d57..46c0278 100644
> >> --- a/hw/pci-host/piix.c
> >> +++ b/hw/pci-host/piix.c
> >> @@ -106,7 +106,6 @@ struct PCII440FXState {
> >>      PAMMemoryRegion pam_regions[13];
> >>      MemoryRegion smram_region;
> >>      MemoryRegion smram, low_smram;
> >> -    uint8_t smm_enabled;
> >>  };
> >>  
> >>  
> >> @@ -139,23 +138,12 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
> >>          pam_update(&d->pam_regions[i], i,
> >>                     pd->config[I440FX_PAM + ((i + 1) / 2)]);
> >>      }
> >> -    smram_update(&d->smram_region, pd->config[I440FX_SMRAM], d->smm_enabled);
> >> +    smram_update(&d->smram_region, pd->config[I440FX_SMRAM]);
> >>      memory_region_set_enabled(&d->smram,
> >>                                pd->config[I440FX_SMRAM] & SMRAM_G_SMRAME);
> >>      memory_region_transaction_commit();
> >>  }
> >>  
> >> -static void i440fx_set_smm(int val, void *arg)
> >> -{
> >> -    PCII440FXState *d = arg;
> >> -    PCIDevice *pd = PCI_DEVICE(d);
> >> -
> >> -    memory_region_transaction_begin();
> >> -    smram_set_smm(&d->smm_enabled, val, pd->config[I440FX_SMRAM],
> >> -                  &d->smram_region);
> >> -    memory_region_transaction_commit();
> >> -}
> >> -
> >>  
> >>  static void i440fx_write_config(PCIDevice *dev,
> >>                                  uint32_t address, uint32_t val, int len)
> >> @@ -175,12 +163,13 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
> >>      PCII440FXState *d = opaque;
> >>      PCIDevice *pd = PCI_DEVICE(d);
> >>      int ret, i;
> >> +    uint8_t smm_enabled;
> >>  
> >>      ret = pci_device_load(pd, f);
> >>      if (ret < 0)
> >>          return ret;
> >>      i440fx_update_memory_mappings(d);
> >> -    qemu_get_8s(f, &d->smm_enabled);
> >> +    qemu_get_8s(f, &smm_enabled);
> >>  
> >>      if (version_id == 2) {
> >>          for (i = 0; i < PIIX_NUM_PIRQS; i++) {
> >> @@ -208,7 +197,7 @@ static const VMStateDescription vmstate_i440fx = {
> >>      .post_load = i440fx_post_load,
> >>      .fields = (VMStateField[]) {
> >>          VMSTATE_PCI_DEVICE(parent_obj, PCII440FXState),
> >> -        VMSTATE_UINT8(smm_enabled, PCII440FXState),
> >> +        VMSTATE_UNUSED(1),
> >>          VMSTATE_END_OF_LIST()
> >>      }
> >>  };
> > 
> > Won't this cause problems for cross-version migration?
> > Old qemu receiving this will think smm is enabled,
> > unconditionally.
> 
> UNUSED is written as zeroes, so it will think SMM is _disabled_,
> unconditionally.  Note that d->smram_region is backwards: it aliases to
> VRAM, so it is enabled when SMRAM is closed and disabled when SMRAM is open.
> 
> This is correct for KVM, though not for TCG.  Backwards migration is not
> supported officially upstream, and I think we can agree it is even less
> supported for TCG.
> 
> Paolo

Generally backwards migration is nice to have to test cross-version
migration properly by doing ping-pong.
Looks like we only need to set smm_enabled correctly before save,
and it'll work cleanly.
No?


> > 
> >> @@ -300,11 +289,7 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
> >>  
> >>  static void i440fx_realize(PCIDevice *dev, Error **errp)
> >>  {
> >> -    PCII440FXState *d = I440FX_PCI_DEVICE(dev);
> >> -
> >>      dev->config[I440FX_SMRAM] = 0x02;
> >> -
> >> -    cpu_smm_register(&i440fx_set_smm, d);
> >>  }
> >>  
> >>  PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
> >> @@ -360,7 +345,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
> >>      memory_region_init(&f->smram, OBJECT(d), "smram", 1ull << 32);
> >>      memory_region_set_enabled(&f->smram, true);
> >>      memory_region_init_alias(&f->low_smram, OBJECT(d), "smram-low",
> >> -                             f->system_memory, 0xa0000, 0x20000);
> >> +                             f->ram_memory, 0xa0000, 0x20000);
> >>      memory_region_set_enabled(&f->low_smram, true);
> >>      memory_region_add_subregion(&f->smram, 0xa0000, &f->low_smram);
> >>      object_property_add_alias(qdev_get_machine(), "smram",
> >> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> >> index de8326a..bd17a05 100644
> >> --- a/hw/pci-host/q35.c
> >> +++ b/hw/pci-host/q35.c
> >> @@ -268,24 +268,12 @@ static void mch_update_smram(MCHPCIState *mch)
> >>      PCIDevice *pd = PCI_DEVICE(mch);
> >>  
> >>      memory_region_transaction_begin();
> >> -    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
> >> -                    mch->smm_enabled);
> >> +    smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM]);
> >>      memory_region_set_enabled(&mch->smram,
> >>                                pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
> >>      memory_region_transaction_commit();
> >>  }
> >>  
> >> -static void mch_set_smm(int smm, void *arg)
> >> -{
> >> -    MCHPCIState *mch = arg;
> >> -    PCIDevice *pd = PCI_DEVICE(mch);
> >> -
> >> -    memory_region_transaction_begin();
> >> -    smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
> >> -                    &mch->smram_region);
> >> -    memory_region_transaction_commit();
> >> -}
> >> -
> >>  static void mch_write_config(PCIDevice *d,
> >>                                uint32_t address, uint32_t val, int len)
> >>  {
> >> @@ -331,7 +319,7 @@ static const VMStateDescription vmstate_mch = {
> >>      .post_load = mch_post_load,
> >>      .fields = (VMStateField[]) {
> >>          VMSTATE_PCI_DEVICE(parent_obj, MCHPCIState),
> >> -        VMSTATE_UINT8(smm_enabled, MCHPCIState),
> >> +        VMSTATE_UNUSED(1),
> >>          VMSTATE_END_OF_LIST()
> >>      }
> >>  };
> >> @@ -402,7 +390,6 @@ static void mch_realize(PCIDevice *d, Error **errp)
> >>                             mch->pci_address_space);
> >>  
> >>      /* if *disabled* show SMRAM to all CPUs */
> >> -    cpu_smm_register(&mch_set_smm, mch);
> >>      memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
> >>                               mch->pci_address_space, 0xa0000, 0x20000);
> >>      memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
> >> @@ -413,7 +400,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
> >>      memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
> >>      memory_region_set_enabled(&mch->smram, true);
> >>      memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
> >> -                             mch->system_memory, 0xa0000, 0x20000);
> >> +                             mch->ram_memory, 0xa0000, 0x20000);
> >>      memory_region_set_enabled(&mch->low_smram, true);
> >>      memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
> >>      object_property_add_const_link(qdev_get_machine(), "smram",
> >> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> >> index 1b35168..c9a9f6e 100644
> >> --- a/include/hw/i386/pc.h
> >> +++ b/include/hw/i386/pc.h
> >> @@ -211,7 +211,6 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
> >>  void pc_pci_device_init(PCIBus *pci_bus);
> >>  
> >>  typedef void (*cpu_set_smm_t)(int smm, void *arg);
> >> -void cpu_smm_register(cpu_set_smm_t callback, void *arg);
> >>  
> >>  void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
> >>  
> >> diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h
> >> index 4d03e4b..80dd605 100644
> >> --- a/include/hw/pci-host/pam.h
> >> +++ b/include/hw/pci-host/pam.h
> >> @@ -86,10 +86,7 @@ typedef struct PAMMemoryRegion {
> >>      unsigned current;
> >>  } PAMMemoryRegion;
> >>  
> >> -void smram_update(MemoryRegion *smram_region, uint8_t smram,
> >> -                  uint8_t smm_enabled);
> >> -void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
> >> -                   MemoryRegion *smram_region);
> >> +void smram_update(MemoryRegion *smram_region, uint8_t smram);
> >>  void init_pam(DeviceState *dev, MemoryRegion *ram, MemoryRegion *system,
> >>                MemoryRegion *pci, PAMMemoryRegion *mem, uint32_t start, uint32_t size);
> >>  void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val);
> >> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> >> index 4c9eacc..17adeaa 100644
> >> --- a/include/hw/pci-host/q35.h
> >> +++ b/include/hw/pci-host/q35.h
> >> @@ -55,7 +55,6 @@ typedef struct MCHPCIState {
> >>      MemoryRegion smram_region;
> >>      MemoryRegion smram, low_smram;
> >>      PcPciInfo pci_info;
> >> -    uint8_t smm_enabled;
> >>      ram_addr_t below_4g_mem_size;
> >>      ram_addr_t above_4g_mem_size;
> >>      uint64_t pci_hole64_size;
> >> diff --git a/linux-user/main.c b/linux-user/main.c
> >> index 3f32db0..6989b82 100644
> >> --- a/linux-user/main.c
> >> +++ b/linux-user/main.c
> >> @@ -215,10 +215,6 @@ void cpu_list_unlock(void)
> >>  /***********************************************************/
> >>  /* CPUX86 core interface */
> >>  
> >> -void cpu_smm_update(CPUX86State *env)
> >> -{
> >> -}
> >> -
> >>  uint64_t cpu_get_tsc(CPUX86State *env)
> >>  {
> >>      return cpu_get_real_ticks();
> >> diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
> >> index 39cd878..7a4fddd 100644
> >> --- a/target-i386/cpu-qom.h
> >> +++ b/target-i386/cpu-qom.h
> >> @@ -23,6 +23,7 @@
> >>  #include "qom/cpu.h"
> >>  #include "cpu.h"
> >>  #include "qapi/error.h"
> >> +#include "qemu/notify.h"
> >>  
> >>  #ifdef TARGET_X86_64
> >>  #define TYPE_X86_CPU "x86_64-cpu"
> >> @@ -111,7 +112,8 @@ typedef struct X86CPU {
> >>      /* in order to simplify APIC support, we leave this pointer to the
> >>         user */
> >>      struct DeviceState *apic_state;
> >> -    struct MemoryRegion *cpu_as_root;
> >> +    struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
> >> +    Notifier machine_done;
> >>  } X86CPU;
> >>  
> >>  static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> >> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> >> index 97c4804..7b6f9e4 100644
> >> --- a/target-i386/cpu.c
> >> +++ b/target-i386/cpu.c
> >> @@ -2751,6 +2751,21 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
> >>      object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
> >>                               errp);
> >>  }
> >> +
> >> +static void x86_cpu_machine_done(Notifier *n, void *unused)
> >> +{
> >> +    X86CPU *cpu = container_of(n, X86CPU, machine_done);
> >> +    MemoryRegion *smram =
> >> +        (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
> >> +
> >> +    if (smram) {
> >> +        cpu->smram = g_new(MemoryRegion, 1);
> >> +        memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
> >> +                                 smram, 0, 1ull << 32);
> >> +        memory_region_set_enabled(cpu->smram, false);
> >> +        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
> >> +    }
> >> +}
> >>  #else
> >>  static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
> >>  {
> >> @@ -2815,12 +2830,26 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
> >>  
> >>  #ifndef CONFIG_USER_ONLY
> >>      if (tcg_enabled()) {
> >> +        cpu->cpu_as_mem = g_new(MemoryRegion, 1);
> >>          cpu->cpu_as_root = g_new(MemoryRegion, 1);
> >>          cs->as = g_new(AddressSpace, 1);
> >> -        memory_region_init_alias(cpu->cpu_as_root, OBJECT(cpu), "memory",
> >> -                                 get_system_memory(), 0, ~0ull);
> >> +
> >> +        /* Outer container... */
> >> +        memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
> >>          memory_region_set_enabled(cpu->cpu_as_root, true);
> >> +
> >> +        /* ... with two regions inside: normal system memory with low
> >> +         * priority, and...
> >> +         */
> >> +        memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
> >> +                                 get_system_memory(), 0, ~0ull);
> >> +        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
> >> +        memory_region_set_enabled(cpu->cpu_as_mem, true);
> >>          address_space_init(cs->as, cpu->cpu_as_root, "CPU");
> >> +
> >> +        /* ... SMRAM with higher priority, linked from /machine/smram.  */
> >> +        cpu->machine_done.notify = x86_cpu_machine_done;
> >> +        qemu_add_machine_init_done_notifier(&cpu->machine_done);
> >>      }
> >>  #endif
> >>  
> >> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> >> index 4510ae7..df6e885 100644
> >> --- a/target-i386/cpu.h
> >> +++ b/target-i386/cpu.h
> >> @@ -1157,7 +1157,6 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
> >>  void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
> >>  
> >>  /* hw/pc.c */
> >> -void cpu_smm_update(CPUX86State *env);
> >>  uint64_t cpu_get_tsc(CPUX86State *env);
> >>  
> >>  #define TARGET_PAGE_BITS 12
> >> @@ -1323,7 +1322,9 @@ void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
> >>  /* seg_helper.c */
> >>  void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
> >>  
> >> +/* smm_helper.c */
> >>  void do_smm_enter(X86CPU *cpu);
> >> +void cpu_smm_update(X86CPU *cpu);
> >>  
> >>  void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
> >>  
> >> diff --git a/target-i386/machine.c b/target-i386/machine.c
> >> index cd1ddd2..69d86cb 100644
> >> --- a/target-i386/machine.c
> >> +++ b/target-i386/machine.c
> >> @@ -372,6 +372,9 @@ static int cpu_post_load(void *opaque, int version_id)
> >>      }
> >>      tlb_flush(cs, 1);
> >>  
> >> +    if (tcg_enabled()) {
> >> +        cpu_smm_update(cpu);
> >> +    }
> >>      return 0;
> >>  }
> >>  
> >> diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
> >> index 5617a14..762f4e5 100644
> >> --- a/target-i386/smm_helper.c
> >> +++ b/target-i386/smm_helper.c
> >> @@ -40,6 +40,14 @@ void helper_rsm(CPUX86State *env)
> >>  #define SMM_REVISION_ID 0x00020000
> >>  #endif
> >>  
> >> +void cpu_smm_update(X86CPU *cpu)
> >> +{
> >> +    CPUX86State *env = &cpu->env;
> >> +    bool smm_enabled = (env->hflags & HF_SMM_MASK);
> >> +
> >> +    memory_region_set_enabled(cpu->smram, smm_enabled);
> >> +}
> >> +
> >>  void do_smm_enter(X86CPU *cpu)
> >>  {
> >>      CPUX86State *env = &cpu->env;
> >> @@ -57,7 +65,7 @@ void do_smm_enter(X86CPU *cpu)
> >>      } else {
> >>          env->hflags2 |= HF2_NMI_MASK;
> >>      }
> >> -    cpu_smm_update(env);
> >> +    cpu_smm_update(cpu);
> >>  
> >>      sm_state = env->smbase + 0x8000;
> >>  
> >> @@ -317,7 +325,7 @@ void helper_rsm(CPUX86State *env)
> >>      }
> >>      env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
> >>      env->hflags &= ~HF_SMM_MASK;
> >> -    cpu_smm_update(env);
> >> +    cpu_smm_update(cpu);
> >>  
> >>      qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
> >>      log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
> >> -- 
> >> 1.8.3.1
> >>
> > 
> > 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM
  2015-06-01  7:51     ` Michael S. Tsirkin
@ 2015-06-01  8:56       ` Paolo Bonzini
  0 siblings, 0 replies; 58+ messages in thread
From: Paolo Bonzini @ 2015-06-01  8:56 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: lersek, qemu-devel, kraxel



On 01/06/2015 09:51, Michael S. Tsirkin wrote:
> > I would like to send a pull request for the non-KVM parts (up to patch
> > 23) on Wednesday or Thursday.  The remaining pieces have to wait for
> > inclusion of KVM support in the kernel, and there will be a v2 with
> > minimal changes posted during soft freeze.
> > 
> > Let me know, either now or after I post v2, if you want to merge them
> > yourself or provide your Acked-by.
> 
> I think the pc tree makes sense for the non kvm parts,
> and will help avoid merge conflicts.
> If you split non-kvm bits out anyway, then I'll merge it.

Are you still okay with me sending out non-PC, non-KVM parts (up to
patch 23) on my own?

Note I'd happily pass you the KVM parts of patches >=24 too.  It's just
a couple of commits, there is no need to split the merge.

Paolo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM
  2015-06-01  8:10       ` Michael S. Tsirkin
@ 2015-06-01  8:58         ` Paolo Bonzini
  2015-06-01 10:38           ` Michael S. Tsirkin
  0 siblings, 1 reply; 58+ messages in thread
From: Paolo Bonzini @ 2015-06-01  8:58 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: lersek, qemu-devel, kraxel



On 01/06/2015 10:10, Michael S. Tsirkin wrote:
> > UNUSED is written as zeroes, so it will think SMM is _disabled_,
> > unconditionally.  Note that d->smram_region is backwards: it aliases to
> > VRAM, so it is enabled when SMRAM is closed and disabled when SMRAM is open.
> > 
> > This is correct for KVM, though not for TCG.  Backwards migration is not
> > supported officially upstream, and I think we can agree it is even less
> > supported for TCG.
>
> Generally backwards migration is nice to have to test cross-version
> migration properly by doing ping-pong.
> Looks like we only need to set smm_enabled correctly before save,
> and it'll work cleanly.
> No?

Sort of.  Old QEMU is not able to handle the case where some CPUs are in
SMM and some are not.  It is also a layering violation to compute
smm_enabled from the CPUs.

Old SeaBIOS never uses SMM after POST, and executes a dozen instructions
or so inside SMRAM.  New SeaBIOS does use SMM after POST (e.g. during
grub), but it _literally_ executes two instructions inside SMRAM and
then jumps to the F-segment, so even if you do not migrate smm_enabled
the chance that something break is basically zero.

This is why I decided that it wasn't worth the complication (and the
layering violation).

Paolo

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM
  2015-06-01  8:58         ` Paolo Bonzini
@ 2015-06-01 10:38           ` Michael S. Tsirkin
  0 siblings, 0 replies; 58+ messages in thread
From: Michael S. Tsirkin @ 2015-06-01 10:38 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lersek, qemu-devel, kraxel

On Mon, Jun 01, 2015 at 10:58:57AM +0200, Paolo Bonzini wrote:
> 
> 
> On 01/06/2015 10:10, Michael S. Tsirkin wrote:
> > > UNUSED is written as zeroes, so it will think SMM is _disabled_,
> > > unconditionally.  Note that d->smram_region is backwards: it aliases to
> > > VRAM, so it is enabled when SMRAM is closed and disabled when SMRAM is open.
> > > 
> > > This is correct for KVM, though not for TCG.  Backwards migration is not
> > > supported officially upstream, and I think we can agree it is even less
> > > supported for TCG.
> >
> > Generally backwards migration is nice to have to test cross-version
> > migration properly by doing ping-pong.
> > Looks like we only need to set smm_enabled correctly before save,
> > and it'll work cleanly.
> > No?
> 
> Sort of.  Old QEMU is not able to handle the case where some CPUs are in
> SMM and some are not.  It is also a layering violation to compute
> smm_enabled from the CPUs.

Yes, I got that. But I guess typically only one CPU is running so
something like smm_enabled_any will DTRT, without layering violations,
right?

> Old SeaBIOS never uses SMM after POST, and executes a dozen instructions
> or so inside SMRAM.  New SeaBIOS does use SMM after POST (e.g. during
> grub), but it _literally_ executes two instructions inside SMRAM and
> then jumps to the F-segment, so even if you do not migrate smm_enabled
> the chance that something break is basically zero.
> 
> This is why I decided that it wasn't worth the complication (and the
> layering violation).
> 
> Paolo

To me it seems easier to support than to explain why we don't
have to, but if you are strongly against that, please add
code comments explaining all this.

-- 
MST

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global
  2015-05-19 16:40     ` Paolo Bonzini
@ 2015-06-08 18:04       ` Markus Armbruster
  0 siblings, 0 replies; 58+ messages in thread
From: Markus Armbruster @ 2015-06-08 18:04 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kraxel, lersek, qemu-devel, mst

Paolo Bonzini <pbonzini@redhat.com> writes:

> On 19/05/2015 18:30, Markus Armbruster wrote:
>> Restrictions on driver and property names in the shorthand syntax
>> driver.property=value before the patch:
>> 
>> * Both are at most 63 characters long, no whitespace
>> 
>> * Driver name cannot contain '.'
>> 
>> * Property name cannot contain '='
>> 
>> After the patch, we additionally have:
>> 
>> * Driver name cannot contain '='.
>> 
>> Okay as long as no such driver name exists.  Have you checked?
>
> Good catch!  I now have.
>
> I've grepped for
>
> - \\..*\".*=.*\",
>
> - TYPE_.*\".*=.*\"
>
> with no hits.
>
>> Please spell out the new restriction in the commit message.
>
> Will do.

I'm afraid you didn't.

>>> @@ -186,6 +188,9 @@ qemu-system-i386 -global
>>> ide-drive.physical_block_size=4096 -drive file=file,if=
>>>  In particular, you can use this to set driver properties for
>>> devices which are
>>>  created automatically by the machine model. To create a device which is not 
>>>  created automatically and set properties on it, use -@option{device}.
>>> +
>>> +The two syntaxes are equivalent.  The longer one works for drivers
>>> whose name
>>> +contains a dot.
>>>  ETEXI
>>>  
>>>  DEF("boot", HAS_ARG, QEMU_OPTION_boot,
>> 
>> I'd explain this as follows:
>> 
>>     -global @var{driver}.@var{prop}=@var{value} is shorthand for -global
>>     driver=@var{driver},property=@var{prop},value=@var{value}.  The
>>     longhand syntax works even when @var{driver} contains a dot.
>
> Will do.

I'm afraid you didn't.  I'll post a follow-up patch.

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2015-06-08 18:04 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-11 13:48 [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 01/31] pc: add 2.4 machine types Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 02/31] target-i386: introduce cpu_get_mem_attrs Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 03/31] target-i386: Use correct memory attributes for memory accesses Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 04/31] target-i386: Use correct memory attributes for ioport accesses Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 05/31] target-i386: mask NMIs on entry to SMM Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 06/31] target-i386: set G=1 in SMM big real mode selectors Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 07/31] pflash_cfi01: change big-endian property to BIT type Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 08/31] pflash_cfi01: change to new-style MMIO accessors Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 09/31] pflash_cfi01: add secure property Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 10/31] vl: allow full-blown QemuOpts syntax for -global Paolo Bonzini
2015-05-19 11:49   ` Paolo Bonzini
2015-05-19 14:34     ` Markus Armbruster
2015-05-19 16:30   ` Markus Armbruster
2015-05-19 16:40     ` Paolo Bonzini
2015-06-08 18:04       ` Markus Armbruster
2015-05-11 13:48 ` [Qemu-devel] [PATCH 11/31] qom: add object_property_add_const_link Paolo Bonzini
2015-05-11 14:40   ` Laszlo Ersek
2015-05-19 11:50   ` Paolo Bonzini
2015-05-19 19:14   ` Eduardo Habkost
2015-05-20 14:36     ` Andreas Färber
2015-05-11 13:48 ` [Qemu-devel] [PATCH 12/31] vl: run "late" notifiers immediately Paolo Bonzini
2015-05-11 13:48 ` [Qemu-devel] [PATCH 13/31] target-i386: create a separate AddressSpace for each CPU Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 14/31] hw/i386: add a separate region that tracks the SMRAME bit Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 15/31] target-i386: use memory API to implement SMRAM Paolo Bonzini
2015-05-31 18:09   ` Michael S. Tsirkin
2015-06-01  7:30     ` Paolo Bonzini
2015-06-01  8:10       ` Michael S. Tsirkin
2015-06-01  8:58         ` Paolo Bonzini
2015-06-01 10:38           ` Michael S. Tsirkin
2015-05-11 13:49 ` [Qemu-devel] [PATCH 16/31] hw/i386: remove smram_update Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 17/31] q35: implement high SMRAM Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 18/31] q35: fix ESMRAMC default Paolo Bonzini
2015-05-12  6:52   ` Gerd Hoffmann
2015-05-11 13:49 ` [Qemu-devel] [PATCH 19/31] q35: add config space wmask for SMRAM and ESMRAMC Paolo Bonzini
2015-05-12  6:55   ` Gerd Hoffmann
2015-05-11 13:49 ` [Qemu-devel] [PATCH 21/31] q35: add test for SMRAM.D_LCK Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 22/31] q35: implement TSEG Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 23/31] ich9: implement SMI_LOCK Paolo Bonzini
2015-05-11 15:17   ` Laszlo Ersek
2015-05-11 15:21     ` Paolo Bonzini
2015-05-11 15:36       ` Laszlo Ersek
2015-05-11 15:45         ` Paolo Bonzini
2015-05-12  7:07   ` Gerd Hoffmann
2015-05-11 13:49 ` [Qemu-devel] [PATCH 24/31] hw/acpi: acpi_pm1_cnt_init(): take "disable_s3" and "disable_s4" Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 25/31] hw/acpi: move "etc/system-states" fw_cfg file from PIIX4 to core Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 26/31] hw/acpi: piix4_pm_init(): take fw_cfg object no more Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 27/31] target-i386: add support for SMBASE MSR and SMIs Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 28/31] vga: disable chain4_alias if KVM supports SMRAM Paolo Bonzini
2015-05-19 11:51   ` Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 29/31] pc_piix: rename kvm_enabled to smm_enabled Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 30/31] ich9: add smm_enabled field and arguments Paolo Bonzini
2015-05-11 13:49 ` [Qemu-devel] [PATCH 31/31] pc: add SMM property Paolo Bonzini
     [not found] ` <1431352157-40283-21-git-send-email-pbonzini@redhat.com>
2015-05-12  6:59   ` [Qemu-devel] [PATCH 20/31] q35: implement SMRAM.D_LCK Gerd Hoffmann
2015-05-31 18:10 ` [Qemu-devel] [PATCH 00/31] target-i386: SMM improvements and partial support under KVM Michael S. Tsirkin
2015-06-01  7:32   ` Paolo Bonzini
2015-06-01  7:51     ` Michael S. Tsirkin
2015-06-01  8:56       ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.