diff options
Diffstat (limited to 'system/xen/xsa/xsa201-4.patch')
-rw-r--r-- | system/xen/xsa/xsa201-4.patch | 130 |
1 files changed, 0 insertions, 130 deletions
diff --git a/system/xen/xsa/xsa201-4.patch b/system/xen/xsa/xsa201-4.patch deleted file mode 100644 index 8060a5be13..0000000000 --- a/system/xen/xsa/xsa201-4.patch +++ /dev/null @@ -1,130 +0,0 @@ -From: Wei Chen <Wei.Chen@arm.com> -Subject: arm32: handle async aborts delivered while at HYP - -If guest generates an asynchronous abort and then traps into HYP -(by HVC or IRQ) before the abort has been delivered, the hypervisor -could not catch it, because the PSTATE.A bit is masked all the time -in hypervisor. So this asynchronous abort may be slipped to next -running guest with PSTATE.A bit unmasked. - -In order to avoid this, it is necessary to take the abort at HYP, by -clearing the PSTATE.A bit. In this patch, we unmask the PSTATE.A bit -to open a window to catch guest-generated asynchronous abort in all -Guest -> HYP switch paths. If we caught such asynchronous abort in -checking window, the HYP data abort exception will be triggered and -the abort source guest will be crashed. - -This is CVE-2016-9818, part of XSA-201. - -Signed-off-by: Wei Chen <Wei.Chen@arm.com> -Reviewed-by: Julien Grall <julien.grall@arm.com> - ---- a/xen/arch/arm/arm32/entry.S -+++ b/xen/arch/arm/arm32/entry.S -@@ -42,6 +42,61 @@ save_guest_regs: - SAVE_BANKED(fiq) - SAVE_ONE_BANKED(R8_fiq); SAVE_ONE_BANKED(R9_fiq); SAVE_ONE_BANKED(R10_fiq) - SAVE_ONE_BANKED(R11_fiq); SAVE_ONE_BANKED(R12_fiq); -+ /* -+ * Start to check pending virtual abort in the gap of Guest -> HYP -+ * world switch. -+ * -+ * Save ELR_hyp to check whether the pending virtual abort exception -+ * takes place while we are doing this trap exception. -+ */ -+ mrs r1, ELR_hyp -+ -+ /* -+ * Force loads and stores to complete before unmasking asynchronous -+ * aborts and forcing the delivery of the exception. -+ */ -+ dsb sy -+ -+ /* -+ * Unmask asynchronous abort bit. If there is a pending asynchronous -+ * abort, the data_abort exception will happen after A bit is cleared. -+ */ -+ cpsie a -+ -+ /* -+ * This is our single instruction exception window. A pending -+ * asynchronous abort is guaranteed to occur at the earliest when we -+ * unmask it, and at the latest just after the ISB. -+ * -+ * If a pending abort occurs, the program will jump to data_abort -+ * exception handler, and the ELR_hyp will be set to -+ * abort_guest_exit_start or abort_guest_exit_end. -+ */ -+ .global abort_guest_exit_start -+abort_guest_exit_start: -+ -+ isb -+ -+ .global abort_guest_exit_end -+abort_guest_exit_end: -+ /* Mask CPSR asynchronous abort bit, close the checking window. */ -+ cpsid a -+ -+ /* -+ * Compare ELR_hyp and the saved value to check whether we are -+ * returning from a valid exception caused by pending virtual -+ * abort. -+ */ -+ mrs r2, ELR_hyp -+ cmp r1, r2 -+ -+ /* -+ * Not equal, the pending virtual abort exception took place, the -+ * initial exception does not have any significance to be handled. -+ * Exit ASAP. -+ */ -+ bne return_from_trap -+ - mov pc, lr - - #define DEFINE_TRAP_ENTRY(trap) \ ---- a/xen/arch/arm/arm32/traps.c -+++ b/xen/arch/arm/arm32/traps.c -@@ -63,7 +63,10 @@ asmlinkage void do_trap_prefetch_abort(struct cpu_user_regs *regs) - - asmlinkage void do_trap_data_abort(struct cpu_user_regs *regs) - { -- do_unexpected_trap("Data Abort", regs); -+ if ( VABORT_GEN_BY_GUEST(regs) ) -+ do_trap_guest_error(regs); -+ else -+ do_unexpected_trap("Data Abort", regs); - } - - /* ---- a/xen/include/asm-arm/arm32/processor.h -+++ b/xen/include/asm-arm/arm32/processor.h -@@ -55,6 +55,17 @@ struct cpu_user_regs - - uint32_t pad1; /* Doubleword-align the user half of the frame */ - }; -+ -+/* Functions for pending virtual abort checking window. */ -+void abort_guest_exit_start(void); -+void abort_guest_exit_end(void); -+ -+#define VABORT_GEN_BY_GUEST(r) \ -+( \ -+ ( (unsigned long)abort_guest_exit_start == (r)->pc ) || \ -+ ( (unsigned long)abort_guest_exit_end == (r)->pc ) \ -+) -+ - #endif - - /* Layout as used in assembly, with src/dest registers mixed in */ ---- a/xen/include/asm-arm/processor.h -+++ b/xen/include/asm-arm/processor.h -@@ -690,6 +690,8 @@ void vcpu_regs_user_to_hyp(struct vcpu *vcpu, - int call_smc(register_t function_id, register_t arg0, register_t arg1, - register_t arg2); - -+void do_trap_guest_error(struct cpu_user_regs *regs); -+ - #endif /* __ASSEMBLY__ */ - #endif /* __ASM_ARM_PROCESSOR_H */ - /* |