[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v13 12/12] target-arm: kvm64: handle SIGBUS signal f
From: |
Dongjiu Geng |
Subject: |
[Qemu-devel] [PATCH v13 12/12] target-arm: kvm64: handle SIGBUS signal from kernel or KVM |
Date: |
Tue, 28 Nov 2017 02:49:55 +0800 |
Add SIGBUS signal handler. In this handler, it checks the SIGBUS type,
translate the host VA which is delivered by host to guest PA, then fill
this PA to CPER and fill the CPER to guest APEI GHES memory, finally
notify guest according the SIGBUS type. There are two kinds of SIGBUS
that QEMU need to handle, which are BUS_MCEERR_AO and BUS_MCEERR_AR.
Guest access device type poisoned memory, generate SError interrupt,
so it reports it to host firmware. Host kernel gets an APEI notification
and memory_failure() causes the affected page to be unmapped from the
guest's stage2, and SIGBUS_MCEERR_AO is sent to user-space. Here Qemu
will create a new CPER and add it to guest APEI GHES memory, and notify the
guest with a GPIO-Signal notification.
When guest hit a PG_hwpoison page, it will trap to KVM as stage2 fault,
here a SIGBUS_MCEERR_AR synchronous signal is delivered to user-space,
Qemu record this error into guest APEI GHES memory and notify guest using
Synchronous-External-Abort(SEA).
Suggested-by: James Morse <address@hidden>
Signed-off-by: Dongjiu Geng <address@hidden>
Signed-off-by: Quanming Wu <address@hidden>
---
Address James's comments to record CPER and notify guest for SIGBUS signal
handling.
Shown some discussion in [1].
[1]:
https://lkml.org/lkml/2017/2/27/246
https://lkml.org/lkml/2017/9/14/241
https://lkml.org/lkml/2017/9/22/499
---
include/sysemu/kvm.h | 2 +-
target/arm/kvm.c | 2 ++
target/arm/kvm64.c | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 3a458f5..90c1605 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -361,7 +361,7 @@ bool kvm_vcpu_id_is_valid(int vcpu_id);
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
unsigned long kvm_arch_vcpu_id(CPUState *cpu);
-#ifdef TARGET_I386
+#if defined(TARGET_I386) || defined(TARGET_AARCH64)
#define KVM_HAVE_MCE_INJECTION 1
void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
#endif
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index d85e36a..8523158 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -26,6 +26,7 @@
#include "exec/address-spaces.h"
#include "hw/boards.h"
#include "qemu/log.h"
+#include "exec/ram_addr.h"
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
@@ -182,6 +183,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
+ qemu_register_reset(kvm_unpoison_all, NULL);
type_register_static(&host_arm_cpu_type_info);
return 0;
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 7f662e9..d83863d 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -27,6 +27,9 @@
#include "kvm_arm.h"
#include "internals.h"
#include "hw/arm/arm.h"
+#include "exec/ram_addr.h"
+#include "hw/acpi/acpi-defs.h"
+#include "hw/acpi/hest_ghes.h"
static bool have_guest_debug;
@@ -943,6 +946,37 @@ int kvm_arch_get_registers(CPUState *cs)
return ret;
}
+void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
+{
+ ram_addr_t ram_addr;
+ hwaddr paddr;
+
+ assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO);
+ if (addr) {
+ ram_addr = qemu_ram_addr_from_host(addr);
+ if (ram_addr != RAM_ADDR_INVALID &&
+ kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
+ kvm_hwpoison_page_add(ram_addr);
+ if (code == BUS_MCEERR_AR) {
+ kvm_cpu_synchronize_state(c);
+ ghes_update_guest(ACPI_HEST_NOTIFY_SEA, paddr);
+ kvm_inject_arm_sea(c);
+ } else if (code == BUS_MCEERR_AO) {
+ ghes_update_guest(ACPI_HEST_NOTIFY_GPIO, paddr);
+ qemu_hardware_error_notify();
+ }
+ return;
+ }
+ fprintf(stderr, "Hardware memory error for memory used by "
+ "QEMU itself instead of guest system!\n");
+ }
+
+ if (code == BUS_MCEERR_AR) {
+ fprintf(stderr, "Hardware memory error!\n");
+ exit(1);
+ }
+}
+
/* C6.6.29 BRK instruction */
static const uint32_t brk_insn = 0xd4200000;
--
1.8.3.1
- [Qemu-devel] [PATCH v13 00/12] Add ARMv8 RAS virtualization support in QEMU, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 06/12] target-arm: kvm64: detect whether can set vsesr_el2, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 05/12] linux-headers: sync against Linux v4.14-rc8, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 04/12] ACPI: enable APEI GHES in the configure file and build it, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 03/12] docs: APEI GHES generation description, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 07/12] target-arm: handle SError interrupt exception from the guest OS, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 02/12] ACPI: Add APEI GHES table generation and CPER record support, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 11/12] hw/arm/virt: Add RAS platform version for migration, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 09/12] Move related hwpoison page function to accel/kvm/ folder, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 12/12] target-arm: kvm64: handle SIGBUS signal from kernel or KVM,
Dongjiu Geng <=
- [Qemu-devel] [PATCH v13 01/12] ACPI: add related GHES structures and macros definition, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 08/12] target-arm: kvm64: inject synchronous External Abort, Dongjiu Geng, 2017/11/27
- [Qemu-devel] [PATCH v13 10/12] ARM: ACPI: Add _E04 for hardware error device, Dongjiu Geng, 2017/11/27