KVM: x86: emulating descriptor load misses long-mode case
[sfrench/cifs-2.6.git] / arch / x86 / kvm / emulate.c
index 0892622f9258e6265c575b4f9157fc5decc4ee35..a46207a0583508ad662d179f2db1ede320a7645e 100644 (file)
@@ -1504,6 +1504,15 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
                        if (rpl > cpl || dpl != cpl)
                                goto exception;
                }
+               /* in long-mode d/b must be clear if l is set */
+               if (seg_desc.d && seg_desc.l) {
+                       u64 efer = 0;
+
+                       ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+                       if (efer & EFER_LMA)
+                               goto exception;
+               }
+
                /* CS(RPL) <- CPL */
                selector = (selector & 0xfffc) | cpl;
                break;
@@ -3688,8 +3697,8 @@ static const struct gprefix pfx_0f_6f_0f_7f = {
        I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
 };
 
-static const struct gprefix pfx_vmovntpx = {
-       I(0, em_mov), N, N, N,
+static const struct gprefix pfx_0f_2b = {
+       I(0, em_mov), I(0, em_mov), N, N,
 };
 
 static const struct gprefix pfx_0f_28_0f_29 = {
@@ -3906,7 +3915,7 @@ static const struct opcode twobyte_table[256] = {
        N, N, N, N,
        GP(ModRM | DstReg | SrcMem | Mov | Sse, &pfx_0f_28_0f_29),
        GP(ModRM | DstMem | SrcReg | Mov | Sse, &pfx_0f_28_0f_29),
-       N, GP(ModRM | DstMem | SrcReg | Sse | Mov | Aligned, &pfx_vmovntpx),
+       N, GP(ModRM | DstMem | SrcReg | Mov | Sse, &pfx_0f_2b),
        N, N, N, N,
        /* 0x30 - 0x3F */
        II(ImplicitOps | Priv, em_wrmsr, wrmsr),