]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/x86/kvm/vmx.c
KVM: VMX: update live TR selector if it changes in real mode
[mv-sheeva.git] / arch / x86 / kvm / vmx.c
index da468c26639d55740b1a6623d931eca4d76a94ce..dafb67eddd604adab7bbc2973ff69ec212ad3333 100644 (file)
@@ -1333,19 +1333,25 @@ static __init int vmx_disabled_by_bios(void)
 
        rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
        if (msr & FEATURE_CONTROL_LOCKED) {
+               /* launched w/ TXT and VMX disabled */
                if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX)
                        && tboot_enabled())
                        return 1;
+               /* launched w/o TXT and VMX only enabled w/ TXT */
                if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX)
+                       && (msr & FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX)
                        && !tboot_enabled()) {
                        printk(KERN_WARNING "kvm: disable TXT in the BIOS or "
-                               " activate TXT before enabling KVM\n");
+                               "activate TXT before enabling KVM\n");
                        return 1;
                }
+               /* launched w/o TXT and VMX disabled */
+               if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX)
+                       && !tboot_enabled())
+                       return 1;
        }
 
        return 0;
-       /* locked but not enabled */
 }
 
 static void kvm_cpu_vmxon(u64 addr)
@@ -2132,6 +2138,7 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
        u32 ar;
 
        if (vmx->rmode.vm86_active && seg == VCPU_SREG_TR) {
+               vmcs_write16(sf->selector, var->selector);
                vmx->rmode.tr.selector = var->selector;
                vmx->rmode.tr.base = var->base;
                vmx->rmode.tr.limit = var->limit;
@@ -3993,7 +4000,7 @@ static void vmx_cancel_injection(struct kvm_vcpu *vcpu)
 #define Q "l"
 #endif
 
-static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
+static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
@@ -4022,6 +4029,7 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
        asm(
                /* Store host registers */
                "push %%"R"dx; push %%"R"bp;"
+               "push %%"R"cx \n\t" /* placeholder for guest rcx */
                "push %%"R"cx \n\t"
                "cmp %%"R"sp, %c[host_rsp](%0) \n\t"
                "je 1f \n\t"
@@ -4063,7 +4071,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
                ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
                ".Lkvm_vmx_return: "
                /* Save guest registers, load host registers, keep flags */
-               "xchg %0,     (%%"R"sp) \n\t"
+               "mov %0, %c[wordsize](%%"R"sp) \n\t"
+               "pop %0 \n\t"
                "mov %%"R"ax, %c[rax](%0) \n\t"
                "mov %%"R"bx, %c[rbx](%0) \n\t"
                "pop"Q" %c[rcx](%0) \n\t"
@@ -4107,7 +4116,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
                [r14]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R14])),
                [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
 #endif
-               [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
+               [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)),
+               [wordsize]"i"(sizeof(ulong))
              : "cc", "memory"
                , R"ax", R"bx", R"di", R"si"
 #ifdef CONFIG_X86_64