aboutsummaryrefslogtreecommitdiff
path: root/system/xen/xsa/xsa303-0004-xen-arm64-Don-t-blindly-unmask-interrupts-on-trap-wi.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/xen/xsa/xsa303-0004-xen-arm64-Don-t-blindly-unmask-interrupts-on-trap-wi.patch')
-rw-r--r--system/xen/xsa/xsa303-0004-xen-arm64-Don-t-blindly-unmask-interrupts-on-trap-wi.patch114
1 files changed, 114 insertions, 0 deletions
diff --git a/system/xen/xsa/xsa303-0004-xen-arm64-Don-t-blindly-unmask-interrupts-on-trap-wi.patch b/system/xen/xsa/xsa303-0004-xen-arm64-Don-t-blindly-unmask-interrupts-on-trap-wi.patch
new file mode 100644
index 0000000000000..106cbf98f1771
--- /dev/null
+++ b/system/xen/xsa/xsa303-0004-xen-arm64-Don-t-blindly-unmask-interrupts-on-trap-wi.patch
@@ -0,0 +1,114 @@
+From c6d290ce157a044dec417fdda8db71e41a37d744 Mon Sep 17 00:00:00 2001
+From: Julien Grall <julien.grall@arm.com>
+Date: Mon, 7 Oct 2019 18:10:56 +0100
+Subject: [PATCH 4/4] xen/arm64: Don't blindly unmask interrupts on trap
+ without a change of level
+
+Some of the traps without a change of the level (i.e. hypervisor ->
+hypervisor) will unmask interrupts regardless the state of them in the
+interrupted context.
+
+One of the consequences is IRQ will be unmasked when receiving a
+synchronous exception (used by WARN*()). This could result to unexpected
+behavior such as deadlock (if a lock was shared with interrupts).
+
+In a nutshell, interrupts should only be unmasked when it is safe to
+do. Xen only unmask IRQ and Abort interrupts, so the logic can stay
+simple:
+ - hyp_error: All the interrupts are now kept masked. SError should
+ be pretty rare and if ever happen then we most likely want to
+ avoid any other interrupts to be generated. The potential main
+ "caller" is during virtual SError synchronization on the exit
+ path from the guest (see check_pending_vserror).
+
+ - hyp_sync: The interrupts state is inherited from the interrupted
+ context.
+
+ - hyp_irq: All the interrupts but IRQ state are inherited from the
+ interrupted context. IRQ is kept masked.
+
+This is part of XSA-303.
+
+Reported-by: Julien Grall <Julien.Grall@arm.com>
+Signed-off-by: Julien Grall <julien.grall@arm.com>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+---
+ xen/arch/arm/arm64/entry.S | 47 ++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 43 insertions(+), 4 deletions(-)
+
+diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
+index 2d9a2713a1..3e41ba65b6 100644
+--- a/xen/arch/arm/arm64/entry.S
++++ b/xen/arch/arm/arm64/entry.S
+@@ -188,24 +188,63 @@ hyp_error_invalid:
+ entry hyp=1
+ invalid BAD_ERROR
+
++/*
++ * SError received while running in the hypervisor mode.
++ *
++ * Technically, we could unmask the IRQ if it were unmasked in the
++ * interrupted context. However, this require to check the PSTATE. For
++ * simplicity, as SError should be rare and potentially fatal,
++ * all interrupts are kept masked.
++ */
+ hyp_error:
+ entry hyp=1
+- msr daifclr, #2
+ mov x0, sp
+ bl do_trap_hyp_serror
+ exit hyp=1
+
+-/* Traps taken in Current EL with SP_ELx */
++/*
++ * Synchronous exception received while running in the hypervisor mode.
++ *
++ * While the exception could be executed with all the interrupts (e.g.
++ * IRQ) unmasked, the interrupted context may have purposefully masked
++ * some of them. So we want to inherit the state from the interrupted
++ * context.
++ */
+ hyp_sync:
+ entry hyp=1
+- msr daifclr, #6
++
++ /* Inherit interrupts */
++ mrs x0, SPSR_el2
++ and x0, x0, #(PSR_DBG_MASK | PSR_ABT_MASK | PSR_IRQ_MASK | PSR_FIQ_MASK)
++ msr daif, x0
++
+ mov x0, sp
+ bl do_trap_hyp_sync
+ exit hyp=1
+
++/*
++ * IRQ received while running in the hypervisor mode.
++ *
++ * While the exception could be executed with all the interrupts but IRQ
++ * unmasked, the interrupted context may have purposefully masked some
++ * of them. So we want to inherit the state from the interrupt context
++ * and keep IRQ masked.
++ *
++ * XXX: We may want to consider an ordering between interrupts (e.g. if
++ * SError are masked, then IRQ should be masked too). However, this
++ * would require some rework in some paths (e.g. panic, livepatch) to
++ * ensure the ordering is enforced everywhere.
++ */
+ hyp_irq:
+ entry hyp=1
+- msr daifclr, #4
++
++ /* Inherit D, A, F interrupts and keep I masked */
++ mrs x0, SPSR_el2
++ mov x1, #(PSR_DBG_MASK | PSR_ABT_MASK | PSR_FIQ_MASK)
++ and x0, x0, x1
++ orr x0, x0, #PSR_IRQ_MASK
++ msr daif, x0
++
+ mov x0, sp
+ bl do_trap_irq
+ exit hyp=1
+--
+2.11.0
+