diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2016-09-06 16:02:12 +0300 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2016-09-08 13:53:00 +0300 |
commit | c39798f471259dacf56df6bfb2bd071dfe074486 (patch) | |
tree | 00f8627556aa1260b71828f69186c94be11eedc2 /arch/arm/kvm/hyp/entry.S | |
parent | 435bca5fe913e2e5f96881a77ab20e653f5ad894 (diff) | |
download | linux-c39798f471259dacf56df6bfb2bd071dfe074486.tar.xz |
arm: KVM: Handle async aborts delivered while at HYP
Just like for arm64, we can handle asynchronous aborts being
delivered at HYP while being caused by the guest. We use
the exact same method to catch such an abort, and soldier on.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'arch/arm/kvm/hyp/entry.S')
-rw-r--r-- | arch/arm/kvm/hyp/entry.S | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/arm/kvm/hyp/entry.S b/arch/arm/kvm/hyp/entry.S index 21c238871c9e..60783f3b57cc 100644 --- a/arch/arm/kvm/hyp/entry.S +++ b/arch/arm/kvm/hyp/entry.S @@ -18,6 +18,7 @@ #include <linux/linkage.h> #include <asm/asm-offsets.h> #include <asm/kvm_arm.h> +#include <asm/kvm_asm.h> .arch_extension virt @@ -63,6 +64,36 @@ ENTRY(__guest_exit) ldr lr, [r0, #4] mov r0, r1 + mrs r1, SPSR + mrs r2, ELR_hyp + mrc p15, 4, r3, c5, c2, 0 @ HSR + + /* + * Force loads and stores to complete before unmasking aborts + * and forcing the delivery of the exception. This gives us a + * single instruction window, which the handler will try to + * match. + */ + dsb sy + cpsie a + + .global abort_guest_exit_start +abort_guest_exit_start: + + isb + + .global abort_guest_exit_end +abort_guest_exit_end: + + /* + * If we took an abort, r0[31] will be set, and cmp will set + * the N bit in PSTATE. + */ + cmp r0, #0 + msrmi SPSR_cxsf, r1 + msrmi ELR_hyp, r2 + mcrmi p15, 4, r3, c5, c2, 0 @ HSR + bx lr ENDPROC(__guest_exit) |