]> git.hungrycats.org Git - linux/commitdiff
KVM: x86: Emulator ignores LDTR/TR extended base on LLDT/LTR
authorNadav Amit <namit@cs.technion.ac.il>
Mon, 2 Jun 2014 15:34:04 +0000 (18:34 +0300)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 25 Sep 2018 22:47:24 +0000 (23:47 +0100)
commit e37a75a13cdae5deaa2ea2cbf8d55b5dd08638b6 upstream.

The current implementation ignores the LDTR/TR base high 32-bits on long-mode.
As a result the loaded segment descriptor may be incorrect.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
arch/x86/kvm/emulate.c

index 98c567c98497a82772995023e924a2314b15bcba..e214f3a1a9ff7b7e2bd5ecc6b73fb535a6602fdd 100644 (file)
@@ -1467,6 +1467,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
        ulong desc_addr;
        int ret;
        u16 dummy;
+       u32 base3 = 0;
 
        memset(&seg_desc, 0, sizeof seg_desc);
 
@@ -1597,9 +1598,14 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
                ret = write_segment_descriptor(ctxt, selector, &seg_desc);
                if (ret != X86EMUL_CONTINUE)
                        return ret;
+       } else if (ctxt->mode == X86EMUL_MODE_PROT64) {
+               ret = ctxt->ops->read_std(ctxt, desc_addr+8, &base3,
+                               sizeof(base3), &ctxt->exception);
+               if (ret != X86EMUL_CONTINUE)
+                       return ret;
        }
 load:
-       ctxt->ops->set_segment(ctxt, selector, &seg_desc, 0, seg);
+       ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg);
        if (desc)
                *desc = seg_desc;
        return X86EMUL_CONTINUE;