target-i386: register a separate KVM address space including SMRAM regions

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2015-06-18 18:30:16 +02:00
parent 8db4936bb6
commit 6410848bec

View File

@ -22,7 +22,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/kvm.h" #include "sysemu/kvm_int.h"
#include "kvm_i386.h" #include "kvm_i386.h"
#include "cpu.h" #include "cpu.h"
#include "exec/gdbstub.h" #include "exec/gdbstub.h"
@ -845,6 +845,40 @@ static int kvm_get_supported_msrs(KVMState *s)
return ret; return ret;
} }
static Notifier smram_machine_done;
static KVMMemoryListener smram_listener;
static AddressSpace smram_address_space;
static MemoryRegion smram_as_root;
static MemoryRegion smram_as_mem;
static void register_smram_listener(Notifier *n, void *unused)
{
MemoryRegion *smram =
(MemoryRegion *) object_resolve_path("/machine/smram", NULL);
/* Outer container... */
memory_region_init(&smram_as_root, OBJECT(kvm_state), "mem-container-smram", ~0ull);
memory_region_set_enabled(&smram_as_root, true);
/* ... with two regions inside: normal system memory with low
* priority, and...
*/
memory_region_init_alias(&smram_as_mem, OBJECT(kvm_state), "mem-smram",
get_system_memory(), 0, ~0ull);
memory_region_add_subregion_overlap(&smram_as_root, 0, &smram_as_mem, 0);
memory_region_set_enabled(&smram_as_mem, true);
if (smram) {
/* ... SMRAM with higher priority */
memory_region_add_subregion_overlap(&smram_as_root, 0, smram, 10);
memory_region_set_enabled(smram, true);
}
address_space_init(&smram_address_space, &smram_as_root, "KVM-SMRAM");
kvm_memory_listener_register(kvm_state, &smram_listener,
&smram_address_space, 1);
}
int kvm_arch_init(MachineState *ms, KVMState *s) int kvm_arch_init(MachineState *ms, KVMState *s)
{ {
uint64_t identity_base = 0xfffbc000; uint64_t identity_base = 0xfffbc000;
@ -903,6 +937,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
return ret; return ret;
} }
} }
if (kvm_check_extension(s, KVM_CAP_X86_SMM)) {
smram_machine_done.notify = register_smram_listener;
qemu_add_machine_init_done_notifier(&smram_machine_done);
}
return 0; return 0;
} }