[Xen-devel,for-4.13,v4,05/19] xen/arm: traps: Update the correct PC when inject a virtual SError to the guest

Message ID 20191031150922.22938-6-julien.grall@arm.com
State New
Headers show
Series
  • xen/arm: XSA-201 and XSA-263 fixes
Related show

Commit Message

Julien Grall Oct. 31, 2019, 3:09 p.m.
When injecting a virtual Abort to the guest, we want to update the guest
PC so it can re-execute the HVC/SMC once it has handled the SError.

This is unfortunately not the case when the SError is synchronized on
entry from the guest. As the SError will be received while running in
hypervisor context, we will update the PC of hypervisor context (i.e
the trap).

Rework inject_vabt_exception so it uses the guest context rather than
the current one.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>

---

Technically, updating the PC is only necessary when guest SError are
received while running in hypervisor. The code should be reworked to get
the path a bit simpler, but this is post Xen 4.13 work.

    Changes in v4:
        - Add Stefano's acked-by

    Changes in v3:
        - s/vcpu_info/vcpu/

    Changes in v2:
        - Add patch
---
 xen/arch/arm/traps.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

Patch

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 3262052f47..12c52a3860 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -629,11 +629,18 @@  static void inject_dabt_exception(struct cpu_user_regs *regs,
 #endif
 }
 
-/* Inject a virtual Abort/SError into the guest. */
-static void inject_vabt_exception(struct cpu_user_regs *regs)
+/*
+ * Inject a virtual Abort/SError into the guest.
+ *
+ * This should only be called with 'current'.
+ */
+static void inject_vabt_exception(struct vcpu *v)
 {
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
     const union hsr hsr = { .bits = regs->hsr };
 
+    ASSERT(v == current);
+
     /*
      * SVC/HVC/SMC already have an adjusted PC (See ARM ARM DDI 0487A.j
      * D1.10.1 for more details), which we need to correct in order to
@@ -656,7 +663,7 @@  static void inject_vabt_exception(struct cpu_user_regs *regs)
         break;
     }
 
-    vcpu_hcr_set_flags(current, HCR_VA);
+    vcpu_hcr_set_flags(v, HCR_VA);
 }
 
 /*
@@ -683,7 +690,7 @@  static void __do_trap_serror(struct cpu_user_regs *regs, bool guest)
      * forwarded to the currently running vCPU.
      */
     if ( serrors_op == SERRORS_DIVERSE && guest )
-            return inject_vabt_exception(regs);
+            return inject_vabt_exception(current);
 
     do_unexpected_trap("SError", regs);
 }