Re: [PATCH V7 10/10] arm/arm64: KVM: add guest SEA support

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

 



Hello Marc,


On 1/16/2017 4:58 AM, Marc Zyngier wrote:
Hi Tyler,

On 12/01/17 18:15, Tyler Baicar wrote:
Currently external aborts are unsupported by the guest abort
handling. Add handling for SEAs so that the host kernel reports
SEAs which occur in the guest kernel.

Signed-off-by: Tyler Baicar <tbaicar@xxxxxxxxxxxxxx>
---
  arch/arm/include/asm/kvm_arm.h       |  1 +
  arch/arm/include/asm/system_misc.h   |  5 +++++
  arch/arm/kvm/mmu.c                   | 18 ++++++++++++++++--
  arch/arm64/include/asm/kvm_arm.h     |  1 +
  arch/arm64/include/asm/system_misc.h |  2 ++
  arch/arm64/mm/fault.c                | 13 +++++++++++++
  6 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index e22089f..33a77509 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -187,6 +187,7 @@
  #define FSC_FAULT	(0x04)
  #define FSC_ACCESS	(0x08)
  #define FSC_PERM	(0x0c)
+#define FSC_EXTABT	(0x10)
/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
  #define HPFAR_MASK	(~0xf)
diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
index a3d61ad..ea45d94 100644
--- a/arch/arm/include/asm/system_misc.h
+++ b/arch/arm/include/asm/system_misc.h
@@ -24,4 +24,9 @@ extern unsigned int user_debug;
#endif /* !__ASSEMBLY__ */ +static inline int handle_guest_sea(unsigned long addr, unsigned int esr)
+{
+	return -1;
+}
+
  #endif /* __ASM_ARM_SYSTEM_MISC_H */
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index e9a5c0e..1152966 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -29,6 +29,7 @@
  #include <asm/kvm_asm.h>
  #include <asm/kvm_emulate.h>
  #include <asm/virt.h>
+#include <asm/system_misc.h>
#include "trace.h" @@ -1441,8 +1442,21 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) /* Check the stage-2 fault is trans. fault or write fault */
  	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
-	if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
-	    fault_status != FSC_ACCESS) {
+
+	/* The host kernel will handle the synchronous external abort. There
+	 * is no need to pass the error into the guest.
+	 */
+	if (fault_status == FSC_EXTABT) {
+		if(handle_guest_sea((unsigned long)fault_ipa,
+				    kvm_vcpu_get_hsr(vcpu))) {
+			kvm_err("Failed to handle guest SEA, FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
+				kvm_vcpu_trap_get_class(vcpu),
+				(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
+				(unsigned long)kvm_vcpu_get_hsr(vcpu));
So there's one thing I don't like here, which is that we just gave the
guest a very nice way to pollute the host's kernel log with spurious
messages. So I'd rather make it silent, or at the very least rate limited.
Before this patch, if a guest exits with FSC_EXTABT, then the below print for "Unsupported FSC..." would happen. So this print isn't really adding any noise that isn't already there. Also, this print would only happen if handle_guest_sea fails. If you still think this print should be removed then I will remove it though.
+			return -EFAULT;
+		}
+	} else if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
+		   fault_status != FSC_ACCESS) {
  		kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
  			kvm_vcpu_trap_get_class(vcpu),
  			(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 4b5c977..be0efb6 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -201,6 +201,7 @@
  #define FSC_FAULT	ESR_ELx_FSC_FAULT
  #define FSC_ACCESS	ESR_ELx_FSC_ACCESS
  #define FSC_PERM	ESR_ELx_FSC_PERM
+#define FSC_EXTABT	ESR_ELx_FSC_EXTABT
/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
  #define HPFAR_MASK	(~UL(0xf))
diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
index e7f3440..27816cb 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -77,4 +77,6 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
  int register_sea_notifier(struct notifier_block *nb);
  void unregister_sea_notifier(struct notifier_block *nb);
+int handle_guest_sea(unsigned long addr, unsigned int esr);
+
  #endif	/* __ASM_SYSTEM_MISC_H */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 81039c7..fa8d4d7 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -597,6 +597,19 @@ static const char *fault_name(unsigned int esr)
  }
/*
+ * Handle Synchronous External Aborts that occur in a guest kernel.
+ */
+int handle_guest_sea(unsigned long addr, unsigned int esr)
+{
+	atomic_notifier_call_chain(&sea_handler_chain, 0, NULL);
+
+	pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
+		fault_name(esr), esr, addr);
Same here.
I will remove this print.
+
+	return 0;
+}
+
+/*
   * Dispatch a data abort to the relevant handler.
   */
  asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,

Thanks,

	M.
Thanks,
Tyler

--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux