Thread (31 messages) 31 messages, 4 authors, 2017-01-24

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

From: Baicar, Tyler <hidden>
Date: 2017-01-16 20:14:51
Also in: kvm, kvmarm, linux-acpi, linux-efi, lkml

Hello Marc,


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

On 12/01/17 18:15, Tyler Baicar wrote:
quoted
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 <redacted>
---
  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.
quoted
+			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.
quoted
+
+	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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help