All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: xen-devel <xen-devel@lists.xenproject.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Subject: [PATCH 1/5] x86emul: support UMIP
Date: Thu, 08 Sep 2016 07:42:56 -0600	[thread overview]
Message-ID: <57D18700020000780010D264@prv-mh.provo.novell.com> (raw)
In-Reply-To: <57D18589020000780010D251@prv-mh.provo.novell.com>

[-- Attachment #1: Type: text/plain, Size: 4577 bytes --]

To make this complete, also add support for SLDT and STR. Note that by
just looking at the guest CR4 bit, this is independent of actually
making available the UMIP feature to guests.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -182,7 +182,7 @@ static const opcode_desc_t opcode_table[
 
 static const opcode_desc_t twobyte_table[256] = {
     /* 0x00 - 0x07 */
-    SrcMem16|ModRM, ImplicitOps|ModRM, ModRM, ModRM,
+    ModRM, ImplicitOps|ModRM, ModRM, ModRM,
     0, ImplicitOps, ImplicitOps, ImplicitOps,
     /* 0x08 - 0x0F */
     ImplicitOps, ImplicitOps, 0, ImplicitOps,
@@ -421,6 +421,7 @@ typedef union {
 /* Control register flags. */
 #define CR0_PE    (1<<0)
 #define CR4_TSD   (1<<2)
+#define CR4_UMIP  (1<<11)
 
 /* EFLAGS bit definitions. */
 #define EFLG_VIP  (1<<20)
@@ -1484,6 +1485,17 @@ static bool is_aligned(enum x86_segment
     return !((reg.base + offs) & (size - 1));
 }
 
+static bool is_umip(struct x86_emulate_ctxt *ctxt,
+                    const struct x86_emulate_ops *ops)
+{
+    unsigned long cr4;
+
+    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
+    return get_cpl(ctxt, ops) > 0 &&
+           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
+           (cr4 & CR4_UMIP);
+}
+
 /* Inject a software interrupt/exception, emulating if needed. */
 static int inject_swint(enum x86_swint_type type,
                         uint8_t vector, uint8_t insn_len,
@@ -2051,10 +2063,20 @@ x86_decode(
             break;
 
         case ext_0f:
-        case ext_0f3a:
-        case ext_8f08:
-        case ext_8f09:
-        case ext_8f0a:
+            switch ( b )
+            {
+            case 0x00: /* Grp6 */
+                switch ( modrm_reg & 6 )
+                {
+                case 0:
+                    d |= DstMem | SrcImplicit | Mov;
+                    break;
+                case 2: case 4:
+                    d |= SrcMem16;
+                    break;
+                }
+                break;
+            }
             break;
 
         case ext_0f38:
@@ -2070,6 +2092,12 @@ x86_decode(
             }
             break;
 
+        case ext_0f3a:
+        case ext_8f08:
+        case ext_8f09:
+        case ext_8f0a:
+            break;
+
         default:
             ASSERT_UNREACHABLE();
         }
@@ -4177,14 +4205,31 @@ x86_emulate(
         }
         break;
 
-    case X86EMUL_OPC(0x0f, 0x00): /* Grp6 */
-        fail_if((modrm_reg & 6) != 2);
+    case X86EMUL_OPC(0x0f, 0x00): /* Grp6 */ {
+        enum x86_segment seg = (modrm_reg & 1) ? x86_seg_tr : x86_seg_ldtr;
+
+        fail_if(modrm_reg & 4);
         generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
-        generate_exception_if(!mode_ring0(), EXC_GP, 0);
-        if ( (rc = load_seg((modrm_reg & 1) ? x86_seg_tr : x86_seg_ldtr,
-                            src.val, 0, NULL, ctxt, ops)) != 0 )
-            goto done;
+        if ( modrm_reg & 2 )
+        {
+            generate_exception_if(!mode_ring0(), EXC_GP, 0);
+            if ( (rc = load_seg(seg, src.val, 0, NULL, ctxt, ops)) != 0 )
+                goto done;
+        }
+        else
+        {
+            struct segment_register reg;
+
+            generate_exception_if(is_umip(ctxt, ops), EXC_GP, 0);
+            fail_if(!ops->read_segment);
+            if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
+                goto done;
+            dst.val = reg.sel;
+            if ( dst.type == OP_MEM )
+                dst.bytes = 2;
+        }
         break;
+    }
 
     case X86EMUL_OPC(0x0f, 0x01): /* Grp7 */ {
         struct segment_register reg;
@@ -4282,6 +4327,7 @@ x86_emulate(
         case 0: /* sgdt */
         case 1: /* sidt */
             generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
+            generate_exception_if(is_umip(ctxt, ops), EXC_GP, 0);
             fail_if(ops->read_segment == NULL);
             if ( (rc = ops->read_segment((modrm_reg & 1) ?
                                          x86_seg_idtr : x86_seg_gdtr,
@@ -4316,6 +4362,7 @@ x86_emulate(
                 goto done;
             break;
         case 4: /* smsw */
+            generate_exception_if(is_umip(ctxt, ops), EXC_GP, 0);
             ea.bytes = (ea.type == OP_MEM) ? 2 : op_bytes;
             dst = ea;
             fail_if(ops->read_cr == NULL);



[-- Attachment #2: x86emul-UMIP.patch --]
[-- Type: text/plain, Size: 4598 bytes --]

x86emul: support UMIP

To make this complete, also add support for SLDT and STR. Note that by
just looking at the guest CR4 bit, this is independent of actually
making available the UMIP feature to guests.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -182,7 +182,7 @@ static const opcode_desc_t opcode_table[
 
 static const opcode_desc_t twobyte_table[256] = {
     /* 0x00 - 0x07 */
-    SrcMem16|ModRM, ImplicitOps|ModRM, ModRM, ModRM,
+    ModRM, ImplicitOps|ModRM, ModRM, ModRM,
     0, ImplicitOps, ImplicitOps, ImplicitOps,
     /* 0x08 - 0x0F */
     ImplicitOps, ImplicitOps, 0, ImplicitOps,
@@ -421,6 +421,7 @@ typedef union {
 /* Control register flags. */
 #define CR0_PE    (1<<0)
 #define CR4_TSD   (1<<2)
+#define CR4_UMIP  (1<<11)
 
 /* EFLAGS bit definitions. */
 #define EFLG_VIP  (1<<20)
@@ -1484,6 +1485,17 @@ static bool is_aligned(enum x86_segment
     return !((reg.base + offs) & (size - 1));
 }
 
+static bool is_umip(struct x86_emulate_ctxt *ctxt,
+                    const struct x86_emulate_ops *ops)
+{
+    unsigned long cr4;
+
+    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
+    return get_cpl(ctxt, ops) > 0 &&
+           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
+           (cr4 & CR4_UMIP);
+}
+
 /* Inject a software interrupt/exception, emulating if needed. */
 static int inject_swint(enum x86_swint_type type,
                         uint8_t vector, uint8_t insn_len,
@@ -2051,10 +2063,20 @@ x86_decode(
             break;
 
         case ext_0f:
-        case ext_0f3a:
-        case ext_8f08:
-        case ext_8f09:
-        case ext_8f0a:
+            switch ( b )
+            {
+            case 0x00: /* Grp6 */
+                switch ( modrm_reg & 6 )
+                {
+                case 0:
+                    d |= DstMem | SrcImplicit | Mov;
+                    break;
+                case 2: case 4:
+                    d |= SrcMem16;
+                    break;
+                }
+                break;
+            }
             break;
 
         case ext_0f38:
@@ -2070,6 +2092,12 @@ x86_decode(
             }
             break;
 
+        case ext_0f3a:
+        case ext_8f08:
+        case ext_8f09:
+        case ext_8f0a:
+            break;
+
         default:
             ASSERT_UNREACHABLE();
         }
@@ -4177,14 +4205,31 @@ x86_emulate(
         }
         break;
 
-    case X86EMUL_OPC(0x0f, 0x00): /* Grp6 */
-        fail_if((modrm_reg & 6) != 2);
+    case X86EMUL_OPC(0x0f, 0x00): /* Grp6 */ {
+        enum x86_segment seg = (modrm_reg & 1) ? x86_seg_tr : x86_seg_ldtr;
+
+        fail_if(modrm_reg & 4);
         generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
-        generate_exception_if(!mode_ring0(), EXC_GP, 0);
-        if ( (rc = load_seg((modrm_reg & 1) ? x86_seg_tr : x86_seg_ldtr,
-                            src.val, 0, NULL, ctxt, ops)) != 0 )
-            goto done;
+        if ( modrm_reg & 2 )
+        {
+            generate_exception_if(!mode_ring0(), EXC_GP, 0);
+            if ( (rc = load_seg(seg, src.val, 0, NULL, ctxt, ops)) != 0 )
+                goto done;
+        }
+        else
+        {
+            struct segment_register reg;
+
+            generate_exception_if(is_umip(ctxt, ops), EXC_GP, 0);
+            fail_if(!ops->read_segment);
+            if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
+                goto done;
+            dst.val = reg.sel;
+            if ( dst.type == OP_MEM )
+                dst.bytes = 2;
+        }
         break;
+    }
 
     case X86EMUL_OPC(0x0f, 0x01): /* Grp7 */ {
         struct segment_register reg;
@@ -4282,6 +4327,7 @@ x86_emulate(
         case 0: /* sgdt */
         case 1: /* sidt */
             generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
+            generate_exception_if(is_umip(ctxt, ops), EXC_GP, 0);
             fail_if(ops->read_segment == NULL);
             if ( (rc = ops->read_segment((modrm_reg & 1) ?
                                          x86_seg_idtr : x86_seg_gdtr,
@@ -4316,6 +4362,7 @@ x86_emulate(
                 goto done;
             break;
         case 4: /* smsw */
+            generate_exception_if(is_umip(ctxt, ops), EXC_GP, 0);
             ea.bytes = (ea.type == OP_MEM) ? 2 : op_bytes;
             dst = ea;
             fail_if(ops->read_cr == NULL);

[-- Attachment #3: Type: text/plain, Size: 127 bytes --]

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

  reply	other threads:[~2016-09-08 13:43 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-08 13:36 [PATCH 0/5] x86: further insn emulator improvements Jan Beulich
2016-09-08 13:42 ` Jan Beulich [this message]
2016-09-30 10:32   ` [PATCH 1/5] x86emul: support UMIP Andrew Cooper
2016-09-30 12:23     ` Jan Beulich
2016-09-30 12:27       ` Andrew Cooper
2016-09-30 12:44         ` Jan Beulich
2016-09-08 13:43 ` [PATCH 2/5] x86emul: consolidate segment register handling Jan Beulich
2016-09-30 10:39   ` Andrew Cooper
2016-09-30 12:15     ` Jan Beulich
2016-09-30 12:16       ` Andrew Cooper
2016-09-08 13:44 ` [PATCH 3/5] x86emul: support RTM instructions Jan Beulich
2016-09-30 12:37   ` Andrew Cooper
2016-09-30 12:51     ` Jan Beulich
2016-09-08 13:45 ` [PATCH 4/5] x86/emulate: add support for {, v}movq xmm, xmm/m64 Jan Beulich
2016-09-08 13:56   ` Mihai Donțu
2016-09-30 10:43   ` Andrew Cooper
2016-09-08 13:46 ` [PATCH 5/5] x86/emulate: add support for {, v}movd {, x}mm, r/m32 and {, v}movq {, x}mm, r/m64 Jan Beulich
2016-09-30 11:59   ` Andrew Cooper
2016-09-30 12:11     ` Jan Beulich
2016-09-30 12:12       ` Andrew Cooper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57D18700020000780010D264@prv-mh.provo.novell.com \
    --to=jbeulich@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.