From: Huang Ying <[email protected]> In QEMU-KVM, physical address != RAM address. While MCE simulation needs physical address instead of RAM address. So kvm_physical_memory_addr_from_ram() is implemented to do the conversion, and it is invoked before being filled in the IA32_MCi_ADDR MSR.
Reported-by: Dean Nelson <[email protected]> Signed-off-by: Huang Ying <[email protected]> Signed-off-by: Marcelo Tosatti <[email protected]> diff --git a/kvm-all.c b/kvm-all.c index d4b0861..c28d91e 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -141,6 +141,24 @@ static KVMSlot *kvm_lookup_overlapping_slot(KVMState *s, return found; } +int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr, + target_phys_addr_t *phys_addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + KVMSlot *mem = &s->slots[i]; + + if (ram_addr >= mem->phys_offset && + ram_addr < mem->phys_offset + mem->memory_size) { + *phys_addr = mem->start_addr + (ram_addr - mem->phys_offset); + return 1; + } + } + + return 0; +} + static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) { struct kvm_userspace_memory_region mem; diff --git a/kvm.h b/kvm.h index 56236ae..d728836 100644 --- a/kvm.h +++ b/kvm.h @@ -195,4 +195,7 @@ int kvm_set_irqfd(int gsi, int fd, bool assigned) #endif int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign); + +int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr, + target_phys_addr_t *phys_addr); #endif diff --git a/qemu-kvm.c b/qemu-kvm.c index 060c47d..d747ed8 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -1137,12 +1137,15 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, if (first_cpu->mcg_cap && siginfo->ssi_addr && siginfo->ssi_code == BUS_MCEERR_AO) { uint64_t status; + void *vaddr; + ram_addr_t ram_addr; unsigned long paddr; CPUState *cenv; /* Hope we are lucky for AO MCE */ - if (do_qemu_ram_addr_from_host((void *)(intptr_t)siginfo->ssi_addr, - &paddr)) { + vaddr = (void *)(intptr_t)siginfo->ssi_addr; + if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) || + !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) { fprintf(stderr, "Hardware memory error for memory used by " "QEMU itself instead of guest system!: %llx\n", (unsigned long long)siginfo->ssi_addr); @@ -1316,6 +1319,8 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t *siginfo) struct kvm_x86_mce mce = { .bank = 9, }; + void *vaddr; + ram_addr_t ram_addr; unsigned long paddr; int r; @@ -1347,7 +1352,9 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t *siginfo) mce.misc = (MCM_ADDR_PHYS << 6) | 0xc; mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; } - if (do_qemu_ram_addr_from_host((void *)siginfo->si_addr, &paddr)) { + vaddr = (void *)siginfo->si_addr; + if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) || + !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) { fprintf(stderr, "Hardware memory error for memory used by " "QEMU itself instaed of guest system!\n"); /* Hope we are lucky for AO MCE */ -- To unsubscribe from this list: send the line "unsubscribe kvm-commits" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
