From: Jan Kiszka <[email protected]>

The unconditional writing of both redirection table words created an
invalid intermediate state when masking a previously unmasked pin: As
the entry was to be masked, the index in result was set to 0xffff. This
value was then programmed into the upper word while the pin was still
unmasked.

QEMU detected this invalid redirection table entry but only a message
was logged on the host terminal because QEMU does not emulate error
reporting for VT-d. If an interrupt had come in on real hardware right
at this point, we would have seen a VT-d fault. Still, no kitten would
have been harmed.

Fix this by only writing the upper half when we are unmasking the pin
(or keeping it unmasked). And the goal of bac03e4d5f54 is still achieved
this way.

Fixes: bac03e4d5f54 ("x86: ioapic: Rework and fix redir entry programming")
Signed-off-by: Jan Kiszka <[email protected]>
---
 hypervisor/arch/x86/ioapic.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/hypervisor/arch/x86/ioapic.c b/hypervisor/arch/x86/ioapic.c
index 7b243097..65ac00f2 100644
--- a/hypervisor/arch/x86/ioapic.c
+++ b/hypervisor/arch/x86/ioapic.c
@@ -143,12 +143,12 @@ static int ioapic_virt_redir_write(struct cell_ioapic 
*ioapic,
        }
 
        /*
-        * Write all 64 bits on updates of the lower 32 bits to ensure the
-        * consistency of an entry.
+        * Write all 64 bits on updates of the lower 32 bits when unmasked to
+        * ensure the consistency of an entry.
         *
         * The index information in the higher bits does not change when the
-        * guest programs an entry, but they need to be initialized when taking
-        * their ownership (always out of masked state, see
+        * guest programs an unmasked entry, but they need to be initialized
+        * when taking their ownership (always out of masked state, see
         * ioapic_prepare_handover).
         */
        if ((reg & 1) == 0) {
@@ -157,7 +157,8 @@ static int ioapic_virt_redir_write(struct cell_ioapic 
*ioapic,
                entry.remap.remapped = 1;
                entry.remap.int_index = result;
 
-               ioapic_reg_write(phys_ioapic, reg | 1, entry.raw[1]);
+               if (!entry.native.mask)
+                       ioapic_reg_write(phys_ioapic, reg | 1, entry.raw[1]);
                ioapic_reg_write(phys_ioapic, reg, entry.raw[0]);
        }
 
-- 
2.16.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/61352e16-f5c2-2dde-ed1d-c51f10d32e4a%40siemens.com.

Reply via email to