KVM: x86 emulator: make loading TR set the busy bit
authorAvi Kivity <avi@redhat.com>
Wed, 13 Jun 2012 13:30:53 +0000 (16:30 +0300)
committerAvi Kivity <avi@redhat.com>
Mon, 9 Jul 2012 11:19:05 +0000 (14:19 +0300)
Guest software doesn't actually depend on it, but vmx will refuse us
entry if we don't.  Set the bit in both the cached segment and memory,
just to be nice.

Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/emulate.c

index 99e3df2bf880f361f7919f8bdffd671b66e26621..92a1adde0b4443509b1fc57dcfcd8ea5aaf9e87d 100644 (file)
@@ -1335,7 +1335,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
                                   u16 selector, int seg)
 {
-       struct desc_struct seg_desc;
+       struct desc_struct seg_desc, old_desc;
        u8 dpl, rpl, cpl;
        unsigned err_vec = GP_VECTOR;
        u32 err_code = 0;
@@ -1422,6 +1422,12 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
        case VCPU_SREG_TR:
                if (seg_desc.s || (seg_desc.type != 1 && seg_desc.type != 9))
                        goto exception;
+               old_desc = seg_desc;
+               seg_desc.type |= 2; /* busy */
+               ret = ctxt->ops->cmpxchg_emulated(ctxt, desc_addr, &old_desc, &seg_desc,
+                                                 sizeof(seg_desc), &ctxt->exception);
+               if (ret != X86EMUL_CONTINUE)
+                       return ret;
                break;
        case VCPU_SREG_LDTR:
                if (seg_desc.s || seg_desc.type != 2)