]> xenbits.xensource.com Git - xen.git/commitdiff
xen/arm: traps: Introduce a helper to read the hypersivor fault register
authorJulien Grall <julien.grall@arm.com>
Tue, 12 Sep 2017 10:03:16 +0000 (11:03 +0100)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 20 Sep 2017 00:26:05 +0000 (17:26 -0700)
While ARM32 has 2 distinct registers for the hypervisor fault register
(one for prefetch abort, the other for data abort), AArch64 has only
one.

Currently, the logic is open-code but a follow-up patch will require to
read it too. So move the logic in a separate helper and use it instead
of open-coding it.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/traps.c

index 200cf16b64fa3cbd57408b2627fd8704c26fb7da..cc08dab6005e4f1630f27114d4c5aabde4cbe840 100644 (file)
@@ -1931,6 +1931,28 @@ done:
     if (first) unmap_domain_page(first);
 }
 
+/*
+ * Return the value of the hypervisor fault address register.
+ *
+ * On ARM32, the register will be different depending whether the
+ * fault is a prefetch abort or data abort.
+ */
+static inline vaddr_t get_hfar(bool is_data)
+{
+    vaddr_t gva;
+
+#ifdef CONFIG_ARM_32
+    if ( is_data )
+        gva = READ_CP32(HDFAR);
+    else
+        gva = READ_CP32(HIFAR);
+#else
+    gva =  READ_SYSREG(FAR_EL2);
+#endif
+
+    return gva;
+}
+
 static inline paddr_t get_faulting_ipa(vaddr_t gva)
 {
     register_t hpfar = READ_SYSREG(HPFAR_EL2);
@@ -1966,11 +1988,7 @@ static void do_trap_instr_abort_guest(struct cpu_user_regs *regs,
     paddr_t gpa;
     mfn_t mfn;
 
-#ifdef CONFIG_ARM_32
-    gva = READ_CP32(HIFAR);
-#else
-    gva = READ_SYSREG64(FAR_EL2);
-#endif
+    gva = get_hfar(false /* is_data */);
 
     /*
      * If this bit has been set, it means that this instruction abort is caused
@@ -2112,11 +2130,8 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs,
         return __do_trap_serror(regs, true);
 
     info.dabt = dabt;
-#ifdef CONFIG_ARM_32
-    info.gva = READ_CP32(HDFAR);
-#else
-    info.gva = READ_SYSREG64(FAR_EL2);
-#endif
+
+    info.gva = get_hfar(true /* is_data */);
 
     if ( hpfar_is_valid(dabt.s1ptw, fsc) )
         info.gpa = get_faulting_ipa(info.gva);