Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[pandora-kernel.git] / drivers / kvm / svm.c
index a33a89c..9ec8763 100644 (file)
@@ -287,7 +287,7 @@ static void svm_hardware_enable(void *garbage)
 
        struct svm_cpu_data *svm_data;
        uint64_t efer;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        struct desc_ptr gdt_descr;
 #else
        struct Xgt_desc_struct gdt_descr;
@@ -377,6 +377,7 @@ static __init int svm_hardware_setup(void)
        void *msrpm_va;
        int r;
 
+       kvm_emulator_want_group7_invlpg();
 
        iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER);
 
@@ -397,15 +398,15 @@ static __init int svm_hardware_setup(void)
        memset(msrpm_va, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER));
        msrpm_base = page_to_pfn(msrpm_pages) << PAGE_SHIFT;
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1);
        set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1);
        set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1);
-       set_msr_interception(msrpm_va, MSR_STAR, 1, 1);
        set_msr_interception(msrpm_va, MSR_LSTAR, 1, 1);
        set_msr_interception(msrpm_va, MSR_CSTAR, 1, 1);
        set_msr_interception(msrpm_va, MSR_SYSCALL_MASK, 1, 1);
 #endif
+       set_msr_interception(msrpm_va, MSR_K6_STAR, 1, 1);
        set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_CS, 1, 1);
        set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1);
        set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1);
@@ -574,6 +575,8 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
        memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs));
        init_vmcb(vcpu->svm->vmcb);
 
+       fx_init(vcpu);
+
        return 0;
 
 out2:
@@ -704,7 +707,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
 
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        if (vcpu->shadow_efer & KVM_EFER_LME) {
                if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK)) {
                        vcpu->shadow_efer |= KVM_EFER_LMA;
@@ -1070,6 +1073,8 @@ static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_ru
 static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 {
        switch (ecx) {
+       case MSR_IA32_P5_MC_ADDR:
+       case MSR_IA32_P5_MC_TYPE:
        case MSR_IA32_MC0_CTL:
        case MSR_IA32_MCG_STATUS:
        case MSR_IA32_MCG_CAP:
@@ -1097,10 +1102,10 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
        case MSR_IA32_APICBASE:
                *data = vcpu->apic_base;
                break;
-#ifdef __x86_64__
-       case MSR_STAR:
+       case MSR_K6_STAR:
                *data = vcpu->svm->vmcb->save.star;
                break;
+#ifdef CONFIG_X86_64
        case MSR_LSTAR:
                *data = vcpu->svm->vmcb->save.lstar;
                break;
@@ -1149,7 +1154,7 @@ static int rdmsr_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 {
        switch (ecx) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        case MSR_EFER:
                set_efer(vcpu, data);
                break;
@@ -1172,10 +1177,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
        case MSR_IA32_APICBASE:
                vcpu->apic_base = data;
                break;
-#ifdef __x86_64___
-       case MSR_STAR:
+       case MSR_K6_STAR:
                vcpu->svm->vmcb->save.star = data;
                break;
+#ifdef CONFIG_X86_64_
        case MSR_LSTAR:
                vcpu->svm->vmcb->save.lstar = data;
                break;
@@ -1345,53 +1350,18 @@ static void kvm_reput_irq(struct kvm_vcpu *vcpu)
 
 static void save_db_regs(unsigned long *db_regs)
 {
-#ifdef __x86_64__
-       asm ("mov %%dr0, %%rax \n\t"
-            "mov %%rax, %[dr0] \n\t"
-            "mov %%dr1, %%rax \n\t"
-            "mov %%rax, %[dr1] \n\t"
-            "mov %%dr2, %%rax \n\t"
-            "mov %%rax, %[dr2] \n\t"
-            "mov %%dr3, %%rax \n\t"
-            "mov %%rax, %[dr3] \n\t"
-            : [dr0] "=m"(db_regs[0]),
-              [dr1] "=m"(db_regs[1]),
-              [dr2] "=m"(db_regs[2]),
-              [dr3] "=m"(db_regs[3])
-            : : "rax");
-#else
-       asm ("mov %%dr0, %%eax \n\t"
-            "mov %%eax, %[dr0] \n\t"
-            "mov %%dr1, %%eax \n\t"
-            "mov %%eax, %[dr1] \n\t"
-            "mov %%dr2, %%eax \n\t"
-            "mov %%eax, %[dr2] \n\t"
-            "mov %%dr3, %%eax \n\t"
-            "mov %%eax, %[dr3] \n\t"
-            : [dr0] "=m"(db_regs[0]),
-              [dr1] "=m"(db_regs[1]),
-              [dr2] "=m"(db_regs[2]),
-              [dr3] "=m"(db_regs[3])
-            : : "eax");
-#endif
+       asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0]));
+       asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1]));
+       asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2]));
+       asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3]));
 }
 
 static void load_db_regs(unsigned long *db_regs)
 {
-       asm volatile ("mov %[dr0], %%dr0 \n\t"
-            "mov %[dr1], %%dr1 \n\t"
-            "mov %[dr2], %%dr2 \n\t"
-            "mov %[dr3], %%dr3 \n\t"
-            :
-            : [dr0] "r"(db_regs[0]),
-              [dr1] "r"(db_regs[1]),
-              [dr2] "r"(db_regs[2]),
-              [dr3] "r"(db_regs[3])
-#ifdef __x86_64__
-            : "rax");
-#else
-            : "eax");
-#endif
+       asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0]));
+       asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1]));
+       asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2]));
+       asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
 }
 
 static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1421,8 +1391,12 @@ again:
                save_db_regs(vcpu->svm->host_db_regs);
                load_db_regs(vcpu->svm->db_regs);
        }
+
+       fx_save(vcpu->host_fx_image);
+       fx_restore(vcpu->guest_fx_image);
+
        asm volatile (
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "push %%rbx; push %%rcx; push %%rdx;"
                "push %%rsi; push %%rdi; push %%rbp;"
                "push %%r8;  push %%r9;  push %%r10; push %%r11;"
@@ -1432,7 +1406,7 @@ again:
                "push %%esi; push %%edi; push %%ebp;"
 #endif
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "mov %c[rbx](%[vcpu]), %%rbx \n\t"
                "mov %c[rcx](%[vcpu]), %%rcx \n\t"
                "mov %c[rdx](%[vcpu]), %%rdx \n\t"
@@ -1456,7 +1430,7 @@ again:
                "mov %c[rbp](%[vcpu]), %%ebp \n\t"
 #endif
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                /* Enter guest mode */
                "push %%rax \n\t"
                "mov %c[svm](%[vcpu]), %%rax \n\t"
@@ -1477,7 +1451,7 @@ again:
 #endif
 
                /* Save guest registers, load host registers */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "mov %%rbx, %c[rbx](%[vcpu]) \n\t"
                "mov %%rcx, %c[rcx](%[vcpu]) \n\t"
                "mov %%rdx, %c[rdx](%[vcpu]) \n\t"
@@ -1518,7 +1492,7 @@ again:
                  [rsi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RSI])),
                  [rdi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RDI])),
                  [rbp]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RBP]))
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                  ,[r8 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R8 ])),
                  [r9 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R9 ])),
                  [r10]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R10])),
@@ -1530,6 +1504,9 @@ again:
 #endif
                : "cc", "memory" );
 
+       fx_save(vcpu->guest_fx_image);
+       fx_restore(vcpu->host_fx_image);
+
        if ((vcpu->svm->vmcb->save.dr7 & 0xff))
                load_db_regs(vcpu->svm->host_db_regs);
 
@@ -1663,9 +1640,7 @@ static struct kvm_arch_ops svm_arch_ops = {
 
 static int __init svm_init(void)
 {
-       kvm_emulator_want_group7_invlpg();
-       kvm_init_arch(&svm_arch_ops, THIS_MODULE);
-       return 0;
+       return kvm_init_arch(&svm_arch_ops, THIS_MODULE);
 }
 
 static void __exit svm_exit(void)