KVM: Don't complain about cpu erratum AA15
[powerpc.git] / drivers / kvm / vmx.c
index 6270df5..d28c848 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "kvm.h"
 #include "vmx.h"
-#include "kvm_vmx.h"
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -70,6 +69,10 @@ static struct kvm_vmx_segment_field {
        VMX_SEGMENT_FIELD(LDTR),
 };
 
+/*
+ * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
+ * away by decrementing the array size.
+ */
 static const u32 vmx_msr_index[] = {
 #ifdef CONFIG_X86_64
        MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
@@ -81,8 +84,14 @@ static const u32 vmx_msr_index[] = {
 #ifdef CONFIG_X86_64
 static unsigned msr_offset_kernel_gs_base;
 #define NR_64BIT_MSRS 4
+/*
+ * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
+ * mechanism (cpu bug AA24)
+ */
+#define NR_BAD_MSRS 2
 #else
 #define NR_64BIT_MSRS 0
+#define NR_BAD_MSRS 0
 #endif
 
 static inline int is_page_fault(u32 intr_info)
@@ -318,6 +327,18 @@ static void setup_msrs(struct kvm_vcpu *vcpu)
                nr_skip = NR_64BIT_MSRS;
        nr_good_msrs = vcpu->nmsrs - nr_skip;
 
+       /*
+        * MSR_K6_STAR is only needed on long mode guests, and only
+        * if efer.sce is enabled.
+        */
+       if (find_msr_entry(vcpu, MSR_K6_STAR)) {
+               --nr_good_msrs;
+#ifdef CONFIG_X86_64
+               if (is_long_mode(vcpu) && (vcpu->shadow_efer & EFER_SCE))
+                       ++nr_good_msrs;
+#endif
+       }
+
        vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR,
                    virt_to_phys(vcpu->guest_msrs + nr_skip));
        vmcs_writel(VM_EXIT_MSR_STORE_ADDR,
@@ -1375,7 +1396,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                case EMULATE_DONE:
                        return 1;
                case EMULATE_DO_MMIO:
-                       ++kvm_stat.mmio_exits;
+                       ++vcpu->stat.mmio_exits;
                        kvm_run->exit_reason = KVM_EXIT_MMIO;
                        return 0;
                 case EMULATE_FAIL:
@@ -1404,7 +1425,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 static int handle_external_interrupt(struct kvm_vcpu *vcpu,
                                     struct kvm_run *kvm_run)
 {
-       ++kvm_stat.irq_exits;
+       ++vcpu->stat.irq_exits;
        return 1;
 }
 
@@ -1471,7 +1492,7 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        unsigned long count;
        gva_t address;
 
-       ++kvm_stat.io_exits;
+       ++vcpu->stat.io_exits;
        exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
        in = (exit_qualification & 8) != 0;
        size = (exit_qualification & 7) + 1;
@@ -1545,8 +1566,6 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                        skip_emulated_instruction(vcpu);
                        return 1;
                case 8:
-                       printk(KERN_DEBUG "handle_cr: read CR8 "
-                              "cpu erratum AA15\n");
                        vcpu_load_rsp_rip(vcpu);
                        vcpu->regs[reg] = vcpu->cr8;
                        vcpu_put_rsp_rip(vcpu);
@@ -1661,7 +1680,7 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu,
        if (kvm_run->request_interrupt_window &&
            !vcpu->irq_summary) {
                kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
-               ++kvm_stat.irq_window_exits;
+               ++vcpu->stat.irq_window_exits;
                return 0;
        }
        return 1;
@@ -1674,7 +1693,7 @@ static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                return 1;
 
        kvm_run->exit_reason = KVM_EXIT_HLT;
-       ++kvm_stat.halt_exits;
+       ++vcpu->stat.halt_exits;
        return 0;
 }
 
@@ -1935,7 +1954,7 @@ again:
 
                reload_tss();
        }
-       ++kvm_stat.exits;
+       ++vcpu->stat.exits;
 
 #ifdef CONFIG_X86_64
        if (is_long_mode(vcpu)) {
@@ -1967,14 +1986,14 @@ again:
                if (r > 0) {
                        /* Give scheduler a change to reschedule. */
                        if (signal_pending(current)) {
-                               ++kvm_stat.signal_exits;
+                               ++vcpu->stat.signal_exits;
                                post_kvm_run_save(vcpu, kvm_run);
                                kvm_run->exit_reason = KVM_EXIT_INTR;
                                return -EINTR;
                        }
 
                        if (dm_request_for_irq_injection(vcpu, kvm_run)) {
-                               ++kvm_stat.request_irq_exits;
+                               ++vcpu->stat.request_irq_exits;
                                post_kvm_run_save(vcpu, kvm_run);
                                kvm_run->exit_reason = KVM_EXIT_INTR;
                                return -EINTR;
@@ -2000,7 +2019,7 @@ static void vmx_inject_page_fault(struct kvm_vcpu *vcpu,
 {
        u32 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
 
-       ++kvm_stat.pf_guest;
+       ++vcpu->stat.pf_guest;
 
        if (is_page_fault(vect_info)) {
                printk(KERN_DEBUG "inject_page_fault: "