Merge branch 'master' into for_paulus
[linux-drm-fsl-dcu.git] / drivers / kvm / vmx.c
index 54c35c0b31815670dd56cbc54b18826e1ea6f80d..1e640b899175df4f178d5828e1d2025ed9551e57 100644 (file)
@@ -98,7 +98,7 @@ static struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr)
        for (i = 0; i < vcpu->nmsrs; ++i)
                if (vcpu->guest_msrs[i].index == msr)
                        return &vcpu->guest_msrs[i];
-       return 0;
+       return NULL;
 }
 
 static void vmcs_clear(struct vmcs *vmcs)
@@ -125,6 +125,15 @@ static void __vcpu_clear(void *arg)
                per_cpu(current_vmcs, cpu) = NULL;
 }
 
+static void vcpu_clear(struct kvm_vcpu *vcpu)
+{
+       if (vcpu->cpu != raw_smp_processor_id() && vcpu->cpu != -1)
+               smp_call_function_single(vcpu->cpu, __vcpu_clear, vcpu, 0, 1);
+       else
+               __vcpu_clear(vcpu);
+       vcpu->launched = 0;
+}
+
 static unsigned long vmcs_readl(unsigned long field)
 {
        unsigned long value;
@@ -202,10 +211,8 @@ static struct kvm_vcpu *vmx_vcpu_load(struct kvm_vcpu *vcpu)
 
        cpu = get_cpu();
 
-       if (vcpu->cpu != cpu) {
-               smp_call_function(__vcpu_clear, vcpu, 0, 1);
-               vcpu->launched = 0;
-       }
+       if (vcpu->cpu != cpu)
+               vcpu_clear(vcpu);
 
        if (per_cpu(current_vmcs, cpu) != vcpu->vmcs) {
                u8 error;
@@ -243,6 +250,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
        put_cpu();
 }
 
+static void vmx_vcpu_decache(struct kvm_vcpu *vcpu)
+{
+       vcpu_clear(vcpu);
+}
+
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
        return vmcs_readl(GUEST_RFLAGS);
@@ -502,7 +514,7 @@ static __init int vmx_disabled_by_bios(void)
        return (msr & 5) == 1; /* locked but not enabled */
 }
 
-static __init void hardware_enable(void *garbage)
+static void hardware_enable(void *garbage)
 {
        int cpu = raw_smp_processor_id();
        u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
@@ -1375,6 +1387,11 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu,
        return 1;
 }
 
+static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+       kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
+       return 0;
+}
 
 static int get_io_count(struct kvm_vcpu *vcpu, u64 *count)
 {
@@ -1635,6 +1652,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
                                      struct kvm_run *kvm_run) = {
        [EXIT_REASON_EXCEPTION_NMI]           = handle_exception,
        [EXIT_REASON_EXTERNAL_INTERRUPT]      = handle_external_interrupt,
+       [EXIT_REASON_TRIPLE_FAULT]            = handle_triple_fault,
        [EXIT_REASON_IO_INSTRUCTION]          = handle_io,
        [EXIT_REASON_CR_ACCESS]               = handle_cr,
        [EXIT_REASON_DR_ACCESS]               = handle_dr,
@@ -1786,10 +1804,10 @@ again:
                "kvm_vmx_return: "
                /* Save guest registers, load host registers, keep flags */
 #ifdef CONFIG_X86_64
-               "xchg %3,     0(%%rsp) \n\t"
+               "xchg %3,     (%%rsp) \n\t"
                "mov %%rax, %c[rax](%3) \n\t"
                "mov %%rbx, %c[rbx](%3) \n\t"
-               "pushq 0(%%rsp); popq %c[rcx](%3) \n\t"
+               "pushq (%%rsp); popq %c[rcx](%3) \n\t"
                "mov %%rdx, %c[rdx](%3) \n\t"
                "mov %%rsi, %c[rsi](%3) \n\t"
                "mov %%rdi, %c[rdi](%3) \n\t"
@@ -1804,24 +1822,24 @@ again:
                "mov %%r15, %c[r15](%3) \n\t"
                "mov %%cr2, %%rax   \n\t"
                "mov %%rax, %c[cr2](%3) \n\t"
-               "mov 0(%%rsp), %3 \n\t"
+               "mov (%%rsp), %3 \n\t"
 
                "pop  %%rcx; pop  %%r15; pop  %%r14; pop  %%r13; pop  %%r12;"
                "pop  %%r11; pop  %%r10; pop  %%r9;  pop  %%r8;"
                "pop  %%rbp; pop  %%rdi; pop  %%rsi;"
                "pop  %%rdx; pop  %%rbx; pop  %%rax \n\t"
 #else
-               "xchg %3, 0(%%esp) \n\t"
+               "xchg %3, (%%esp) \n\t"
                "mov %%eax, %c[rax](%3) \n\t"
                "mov %%ebx, %c[rbx](%3) \n\t"
-               "pushl 0(%%esp); popl %c[rcx](%3) \n\t"
+               "pushl (%%esp); popl %c[rcx](%3) \n\t"
                "mov %%edx, %c[rdx](%3) \n\t"
                "mov %%esi, %c[rsi](%3) \n\t"
                "mov %%edi, %c[rdi](%3) \n\t"
                "mov %%ebp, %c[rbp](%3) \n\t"
                "mov %%cr2, %%eax  \n\t"
                "mov %%eax, %c[cr2](%3) \n\t"
-               "mov 0(%%esp), %3 \n\t"
+               "mov (%%esp), %3 \n\t"
 
                "pop %%ecx; popa \n\t"
 #endif
@@ -1859,9 +1877,7 @@ again:
        fx_restore(vcpu->host_fx_image);
        vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
 
-#ifndef CONFIG_X86_64
        asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
-#endif
 
        /*
         * Profile KVM exit RIPs:
@@ -2012,6 +2028,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
 
        .vcpu_load = vmx_vcpu_load,
        .vcpu_put = vmx_vcpu_put,
+       .vcpu_decache = vmx_vcpu_decache,
 
        .set_guest_debug = set_guest_debug,
        .get_msr = vmx_get_msr,