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

[Xen-devel] [PATCH v4 4/6] x86emul: support VME and PVI



... affecting POPF, CLI, and STI.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -433,6 +433,8 @@ typedef union {
 #define CR0_EM    (1<<2)
 #define CR0_TS    (1<<3)
 
+#define CR4_VME        (1<<0)
+#define CR4_PVI        (1<<1)
 #define CR4_TSD        (1<<2)
 #define CR4_OSFXSR     (1<<9)
 #define CR4_OSXMMEXCPT (1<<10)
@@ -1178,6 +1180,15 @@ _mode_iopl(
     fail_if(_iopl < 0);                         \
     _iopl;                                      \
 })
+#define mode_pvi() ({                                        \
+    unsigned long cr4 = 0;                                   \
+    if ( ops->read_cr && get_cpl(ctxt, ops) == 3 )           \
+    {                                                        \
+        rc = ops->read_cr(4, &cr4, ctxt);                    \
+        if ( rc != X86EMUL_OKAY ) goto done;                 \
+    }                                                        \
+    !!(cr4 & (_regs._eflags & EFLG_VM ? CR4_VME : CR4_PVI)); \
+})
 
 static int ioport_access_check(
     unsigned int first_port,
@@ -3273,12 +3284,22 @@ x86_emulate(
 
     case 0x9d: /* popf */ {
         uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM;
+        unsigned long cr4 = 0;
 
         if ( !mode_ring0() )
         {
-            generate_exception_if((_regs._eflags & EFLG_VM) &&
-                                  MASK_EXTR(_regs._eflags, EFLG_IOPL) != 3,
-                                  EXC_GP, 0);
+            if ( _regs._eflags & EFLG_VM )
+            {
+                if ( op_bytes == 2 && ops->read_cr )
+                {
+                    rc = ops->read_cr(4, &cr4, ctxt);
+                    if ( rc != X86EMUL_OKAY )
+                        goto done;
+                }
+                generate_exception_if(!(cr4 & CR4_VME) &&
+                                      MASK_EXTR(_regs._eflags, EFLG_IOPL) != 3,
+                                      EXC_GP, 0);
+            }
             mask |= EFLG_IOPL;
             if ( !mode_iopl() )
                 mask |= EFLG_IF;
@@ -3290,7 +3311,20 @@ x86_emulate(
                               &dst.val, op_bytes, ctxt, ops)) != 0 )
             goto done;
         if ( op_bytes == 2 )
+        {
             dst.val = (uint16_t)dst.val | (_regs._eflags & 0xffff0000u);
+            if ( cr4 & CR4_VME )
+            {
+                if ( dst.val & EFLG_IF )
+                {
+                    generate_exception_if(_regs._eflags & EFLG_VIP, EXC_GP, 0);
+                    dst.val |= EFLG_VIF;
+                }
+                else
+                    dst.val &= ~EFLG_VIF;
+                mask &= ~EFLG_VIF;
+            }
+        }
         dst.val &= EFLAGS_MODIFIABLE;
         _regs._eflags &= mask;
         _regs._eflags |= (dst.val & ~mask) | EFLG_MBS;
@@ -4397,16 +4431,29 @@ x86_emulate(
         break;
 
     case 0xfa: /* cli */
-        generate_exception_if(!mode_iopl(), EXC_GP, 0);
-        _regs._eflags &= ~EFLG_IF;
+        if ( mode_iopl() )
+            _regs._eflags &= ~EFLG_IF;
+        else
+        {
+            generate_exception_if(!mode_pvi(), EXC_GP, 0);
+            _regs._eflags &= ~EFLG_VIF;
+        }
         break;
 
     case 0xfb: /* sti */
-        generate_exception_if(!mode_iopl(), EXC_GP, 0);
-        if ( !(_regs._eflags & EFLG_IF) )
+        if ( mode_iopl() )
         {
+            if ( !(_regs._eflags & EFLG_IF) )
+                ctxt->retire.sti = true;
             _regs._eflags |= EFLG_IF;
-            ctxt->retire.sti = true;
+        }
+        else
+        {
+            generate_exception_if((_regs._eflags & EFLG_VIP) || !mode_pvi(),
+                                  EXC_GP, 0);
+            if ( !(_regs._eflags & EFLG_VIF) )
+                ctxt->retire.sti = true;
+            _regs._eflags |= EFLG_VIF;
         }
         break;
 



Attachment: x86emul-VME-PVI.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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