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

[xen staging] x86/svm: Apply the virtual-8086 IOPL check to INT n only



commit bd7e286e877cf4f86479226ba67c2b00e9eaba16
Author:     Stefano Stabellini <stefano.stabellini@xxxxxxx>
AuthorDate: Tue Oct 20 15:41:23 2026 -0700
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Mon Oct 26 18:36:52 2026 +0000

    x86/svm: Apply the virtual-8086 IOPL check to INT n only
    
    In virtual-8086 mode with IOPL < 3, INT n raises #GP(0).  INT1, INT3
    and INTO are not affected.  They are delivered normally.
    
    svm_emul_swint_injection() applies the check to all of them, so an ICEBP
    raises #GP instead of #DB.  It also reports the IDT entry in the #GP
    error code instead of 0.
    
    Move the check earier prior to setting up ec, and limit it to INT n only.
    
    Fixes: 897d59a426f1 ("x86/svm: Introduce svm_emul_swint_injection()")
    Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 4e22322f4b..1628c5e0ae 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1139,6 +1139,17 @@ static void svm_emul_swint_injection(struct x86_event 
*event)
     if ( !(vmcb_get_cr0(vmcb) & X86_CR0_PE) )
         goto raise_exception; /* TODO: support real-mode injection? */
 
+    /*
+     * In vm86 mode, INT $N is subject to IOPL.
+     *
+     * TODO: It is also subject to CR4.VME=1, which would require reading the
+     * TSS Software Interrupt Redirection bitmap.
+     */
+    if ( type == X86_ET_SW_INT &&
+         regs->eflags & X86_EFLAGS_VM &&
+         MASK_EXTR(regs->eflags, X86_EFLAGS_IOPL) != 3 )
+        goto raise_exception;
+
     idte_size   = lm ? 16 : 8;
     idte_offset = trap * idte_size;
 
@@ -1146,16 +1157,6 @@ static void svm_emul_swint_injection(struct x86_event 
*event)
     ec = (trap << 3) | X86_XEC_IDT |
          (type == X86_ET_PRIV_SW_EXC ? X86_XEC_EXT : 0);
 
-    /*
-     * TODO: This does not cover the v8086 mode with CR4.VME case
-     * correctly, but falls on the safe side from the point of view of a
-     * 32bit OS.  Someone with many TUITs can see about reading the TSS
-     * Software Interrupt Redirection bitmap.
-     */
-    if ( (regs->eflags & X86_EFLAGS_VM) &&
-         MASK_EXTR(regs->eflags, X86_EFLAGS_IOPL) != 3 )
-        goto raise_exception;
-
     /*
      * Read all 8/16 bytes so the idtr limit check is applied properly to
      * this entry, even though we don't look at all the words read.
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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