[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.9] xen/arm64: Don't blindly unmask interrupts on trap without a change of level



commit 2e15a199969a7ed729b22cacac6528dc16e2768a
Author:     Julien Grall <julien.grall@xxxxxxx>
AuthorDate: Mon Nov 4 15:12:00 2019 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Nov 4 15:12:00 2019 +0100

    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@xxxxxxx>
    Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    Reviewed-by: Andre Przywara <andre.przywara@xxxxxxx>
    master commit: 3ed885a8874003f6011460f4f46d1d130dd6b2db
    master date: 2019-10-31 16:22:55 +0100
---
 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 06afc8a4e4..8ebce1e9c9 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -177,24 +177,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
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.9

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.