Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-microblaze.git] / arch / x86 / kvm / x86.c
index 02cf0a7..0c0ca59 100644 (file)
@@ -1748,9 +1748,6 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data,
 {
        struct msr_data msr;
 
-       if (!host_initiated && !kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_WRITE))
-               return KVM_MSR_RET_FILTERED;
-
        switch (index) {
        case MSR_FS_BASE:
        case MSR_GS_BASE:
@@ -1832,9 +1829,6 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data,
        struct msr_data msr;
        int ret;
 
-       if (!host_initiated && !kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_READ))
-               return KVM_MSR_RET_FILTERED;
-
        switch (index) {
        case MSR_TSC_AUX:
                if (!kvm_is_supported_user_return_msr(MSR_TSC_AUX))
@@ -1871,6 +1865,20 @@ static int kvm_get_msr_ignored_check(struct kvm_vcpu *vcpu,
        return ret;
 }
 
+static int kvm_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 index, u64 *data)
+{
+       if (!kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_READ))
+               return KVM_MSR_RET_FILTERED;
+       return kvm_get_msr_ignored_check(vcpu, index, data, false);
+}
+
+static int kvm_set_msr_with_filter(struct kvm_vcpu *vcpu, u32 index, u64 data)
+{
+       if (!kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_WRITE))
+               return KVM_MSR_RET_FILTERED;
+       return kvm_set_msr_ignored_check(vcpu, index, data, false);
+}
+
 int kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data)
 {
        return kvm_get_msr_ignored_check(vcpu, index, data, false);
@@ -1953,7 +1961,7 @@ int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu)
        u64 data;
        int r;
 
-       r = kvm_get_msr(vcpu, ecx, &data);
+       r = kvm_get_msr_with_filter(vcpu, ecx, &data);
 
        if (!r) {
                trace_kvm_msr_read(ecx, data);
@@ -1978,7 +1986,7 @@ int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu)
        u64 data = kvm_read_edx_eax(vcpu);
        int r;
 
-       r = kvm_set_msr(vcpu, ecx, data);
+       r = kvm_set_msr_with_filter(vcpu, ecx, data);
 
        if (!r) {
                trace_kvm_msr_write(ecx, data);
@@ -5938,7 +5946,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
                smp_wmb();
                kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
                kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
-               kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT);
+               kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_ABSENT);
                r = 0;
 split_irqchip_unlock:
                mutex_unlock(&kvm->lock);
@@ -6335,7 +6343,7 @@ set_identity_unlock:
                /* Write kvm->irq_routing before enabling irqchip_in_kernel. */
                smp_wmb();
                kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
-               kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT);
+               kvm_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_ABSENT);
        create_irqchip_unlock:
                mutex_unlock(&kvm->lock);
                break;
@@ -6726,7 +6734,7 @@ void kvm_get_segment(struct kvm_vcpu *vcpu,
        static_call(kvm_x86_get_segment)(vcpu, var, seg);
 }
 
-gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access,
+gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u64 access,
                           struct x86_exception *exception)
 {
        struct kvm_mmu *mmu = vcpu->arch.mmu;
@@ -6746,7 +6754,7 @@ gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
 
-       u32 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+       u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
        return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception);
 }
 EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_read);
@@ -6756,7 +6764,7 @@ EXPORT_SYMBOL_GPL(kvm_mmu_gva_to_gpa_read);
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
 
-       u32 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+       u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
        access |= PFERR_FETCH_MASK;
        return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception);
 }
@@ -6766,7 +6774,7 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
 
-       u32 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+       u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
        access |= PFERR_WRITE_MASK;
        return mmu->gva_to_gpa(vcpu, mmu, gva, access, exception);
 }
@@ -6782,7 +6790,7 @@ gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
 }
 
 static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
-                                     struct kvm_vcpu *vcpu, u32 access,
+                                     struct kvm_vcpu *vcpu, u64 access,
                                      struct x86_exception *exception)
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
@@ -6819,7 +6827,7 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt,
 {
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
-       u32 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+       u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
        unsigned offset;
        int ret;
 
@@ -6844,7 +6852,7 @@ int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
                               gva_t addr, void *val, unsigned int bytes,
                               struct x86_exception *exception)
 {
-       u32 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
+       u64 access = (static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
 
        /*
         * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED
@@ -6863,9 +6871,11 @@ static int emulator_read_std(struct x86_emulate_ctxt *ctxt,
                             struct x86_exception *exception, bool system)
 {
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
-       u32 access = 0;
+       u64 access = 0;
 
-       if (!system && static_call(kvm_x86_get_cpl)(vcpu) == 3)
+       if (system)
+               access |= PFERR_IMPLICIT_ACCESS;
+       else if (static_call(kvm_x86_get_cpl)(vcpu) == 3)
                access |= PFERR_USER_MASK;
 
        return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception);
@@ -6881,7 +6891,7 @@ static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt,
 }
 
 static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
-                                     struct kvm_vcpu *vcpu, u32 access,
+                                     struct kvm_vcpu *vcpu, u64 access,
                                      struct x86_exception *exception)
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
@@ -6915,9 +6925,11 @@ static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *v
                              bool system)
 {
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
-       u32 access = PFERR_WRITE_MASK;
+       u64 access = PFERR_WRITE_MASK;
 
-       if (!system && static_call(kvm_x86_get_cpl)(vcpu) == 3)
+       if (system)
+               access |= PFERR_IMPLICIT_ACCESS;
+       else if (static_call(kvm_x86_get_cpl)(vcpu) == 3)
                access |= PFERR_USER_MASK;
 
        return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
@@ -6984,7 +6996,7 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
                                bool write)
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
-       u32 access = ((static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0)
+       u64 access = ((static_call(kvm_x86_get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0)
                | (write ? PFERR_WRITE_MASK : 0);
 
        /*
@@ -7627,13 +7639,13 @@ static void emulator_set_segment(struct x86_emulate_ctxt *ctxt, u16 selector,
        return;
 }
 
-static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
-                           u32 msr_index, u64 *pdata)
+static int emulator_get_msr_with_filter(struct x86_emulate_ctxt *ctxt,
+                                       u32 msr_index, u64 *pdata)
 {
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
        int r;
 
-       r = kvm_get_msr(vcpu, msr_index, pdata);
+       r = kvm_get_msr_with_filter(vcpu, msr_index, pdata);
 
        if (r && kvm_msr_user_space(vcpu, msr_index, KVM_EXIT_X86_RDMSR, 0,
                                    complete_emulated_rdmsr, r)) {
@@ -7644,13 +7656,13 @@ static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
        return r;
 }
 
-static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
-                           u32 msr_index, u64 data)
+static int emulator_set_msr_with_filter(struct x86_emulate_ctxt *ctxt,
+                                       u32 msr_index, u64 data)
 {
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
        int r;
 
-       r = kvm_set_msr(vcpu, msr_index, data);
+       r = kvm_set_msr_with_filter(vcpu, msr_index, data);
 
        if (r && kvm_msr_user_space(vcpu, msr_index, KVM_EXIT_X86_WRMSR, data,
                                    complete_emulated_msr_access, r)) {
@@ -7661,6 +7673,18 @@ static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
        return r;
 }
 
+static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
+                           u32 msr_index, u64 *pdata)
+{
+       return kvm_get_msr(emul_to_vcpu(ctxt), msr_index, pdata);
+}
+
+static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
+                           u32 msr_index, u64 data)
+{
+       return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data);
+}
+
 static u64 emulator_get_smbase(struct x86_emulate_ctxt *ctxt)
 {
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
@@ -7724,6 +7748,11 @@ static bool emulator_guest_has_fxsr(struct x86_emulate_ctxt *ctxt)
        return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_FXSR);
 }
 
+static bool emulator_guest_has_rdpid(struct x86_emulate_ctxt *ctxt)
+{
+       return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_RDPID);
+}
+
 static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
 {
        return kvm_register_read_raw(emul_to_vcpu(ctxt), reg);
@@ -7794,6 +7823,8 @@ static const struct x86_emulate_ops emulate_ops = {
        .set_dr              = emulator_set_dr,
        .get_smbase          = emulator_get_smbase,
        .set_smbase          = emulator_set_smbase,
+       .set_msr_with_filter = emulator_set_msr_with_filter,
+       .get_msr_with_filter = emulator_get_msr_with_filter,
        .set_msr             = emulator_set_msr,
        .get_msr             = emulator_get_msr,
        .check_pmc           = emulator_check_pmc,
@@ -7806,6 +7837,7 @@ static const struct x86_emulate_ops emulate_ops = {
        .guest_has_long_mode = emulator_guest_has_long_mode,
        .guest_has_movbe     = emulator_guest_has_movbe,
        .guest_has_fxsr      = emulator_guest_has_fxsr,
+       .guest_has_rdpid     = emulator_guest_has_rdpid,
        .set_nmi_mask        = emulator_set_nmi_mask,
        .get_hflags          = emulator_get_hflags,
        .exiting_smm         = emulator_exiting_smm,
@@ -9058,15 +9090,29 @@ bool kvm_apicv_activated(struct kvm *kvm)
 }
 EXPORT_SYMBOL_GPL(kvm_apicv_activated);
 
+
+static void set_or_clear_apicv_inhibit(unsigned long *inhibits,
+                                      enum kvm_apicv_inhibit reason, bool set)
+{
+       if (set)
+               __set_bit(reason, inhibits);
+       else
+               __clear_bit(reason, inhibits);
+
+       trace_kvm_apicv_inhibit_changed(reason, set, *inhibits);
+}
+
 static void kvm_apicv_init(struct kvm *kvm)
 {
+       unsigned long *inhibits = &kvm->arch.apicv_inhibit_reasons;
+
        init_rwsem(&kvm->arch.apicv_update_lock);
 
-       set_bit(APICV_INHIBIT_REASON_ABSENT,
-               &kvm->arch.apicv_inhibit_reasons);
+       set_or_clear_apicv_inhibit(inhibits, APICV_INHIBIT_REASON_ABSENT, true);
+
        if (!enable_apicv)
-               set_bit(APICV_INHIBIT_REASON_DISABLE,
-                       &kvm->arch.apicv_inhibit_reasons);
+               set_or_clear_apicv_inhibit(inhibits,
+                                          APICV_INHIBIT_REASON_ABSENT, true);
 }
 
 static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id)
@@ -9740,24 +9786,21 @@ out:
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv);
 
-void __kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
+void __kvm_set_or_clear_apicv_inhibit(struct kvm *kvm,
+                                     enum kvm_apicv_inhibit reason, bool set)
 {
        unsigned long old, new;
 
        lockdep_assert_held_write(&kvm->arch.apicv_update_lock);
 
-       if (!static_call(kvm_x86_check_apicv_inhibit_reasons)(bit))
+       if (!static_call(kvm_x86_check_apicv_inhibit_reasons)(reason))
                return;
 
        old = new = kvm->arch.apicv_inhibit_reasons;
 
-       if (activate)
-               __clear_bit(bit, &new);
-       else
-               __set_bit(bit, &new);
+       set_or_clear_apicv_inhibit(&new, reason, set);
 
        if (!!old != !!new) {
-               trace_kvm_apicv_update_request(activate, bit);
                /*
                 * Kick all vCPUs before setting apicv_inhibit_reasons to avoid
                 * false positives in the sanity check WARN in svm_vcpu_run().
@@ -9776,20 +9819,22 @@ void __kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
                        unsigned long gfn = gpa_to_gfn(APIC_DEFAULT_PHYS_BASE);
                        kvm_zap_gfn_range(kvm, gfn, gfn+1);
                }
-       } else
+       } else {
                kvm->arch.apicv_inhibit_reasons = new;
+       }
 }
 
-void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
+void kvm_set_or_clear_apicv_inhibit(struct kvm *kvm,
+                                   enum kvm_apicv_inhibit reason, bool set)
 {
        if (!enable_apicv)
                return;
 
        down_write(&kvm->arch.apicv_update_lock);
-       __kvm_request_apicv_update(kvm, activate, bit);
+       __kvm_set_or_clear_apicv_inhibit(kvm, reason, set);
        up_write(&kvm->arch.apicv_update_lock);
 }
-EXPORT_SYMBOL_GPL(kvm_request_apicv_update);
+EXPORT_SYMBOL_GPL(kvm_set_or_clear_apicv_inhibit);
 
 static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
 {
@@ -10937,7 +10982,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 static void kvm_arch_vcpu_guestdbg_update_apicv_inhibit(struct kvm *kvm)
 {
-       bool inhibit = false;
+       bool set = false;
        struct kvm_vcpu *vcpu;
        unsigned long i;
 
@@ -10945,11 +10990,11 @@ static void kvm_arch_vcpu_guestdbg_update_apicv_inhibit(struct kvm *kvm)
 
        kvm_for_each_vcpu(i, vcpu, kvm) {
                if (vcpu->guest_debug & KVM_GUESTDBG_BLOCKIRQ) {
-                       inhibit = true;
+                       set = true;
                        break;
                }
        }
-       __kvm_request_apicv_update(kvm, !inhibit, APICV_INHIBIT_REASON_BLOCKIRQ);
+       __kvm_set_or_clear_apicv_inhibit(kvm, APICV_INHIBIT_REASON_BLOCKIRQ, set);
        up_write(&kvm->arch.apicv_update_lock);
 }
 
@@ -11557,10 +11602,8 @@ int kvm_arch_hardware_setup(void *opaque)
                u64 max = min(0x7fffffffULL,
                              __scale_tsc(kvm_max_tsc_scaling_ratio, tsc_khz));
                kvm_max_guest_tsc_khz = max;
-
-               kvm_default_tsc_scaling_ratio = 1ULL << kvm_tsc_scaling_ratio_frac_bits;
        }
-
+       kvm_default_tsc_scaling_ratio = 1ULL << kvm_tsc_scaling_ratio_frac_bits;
        kvm_init_msr_list();
        return 0;
 }
@@ -11629,12 +11672,13 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 
        ret = kvm_page_track_init(kvm);
        if (ret)
-               return ret;
+               goto out;
+
+       ret = kvm_mmu_init_vm(kvm);
+       if (ret)
+               goto out_page_track;
 
        INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list);
-       INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
-       INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages);
-       INIT_LIST_HEAD(&kvm->arch.lpage_disallowed_mmu_pages);
        INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
        atomic_set(&kvm->arch.noncoherent_dma_count, 0);
 
@@ -11666,10 +11710,14 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 
        kvm_apicv_init(kvm);
        kvm_hv_init_vm(kvm);
-       kvm_mmu_init_vm(kvm);
        kvm_xen_init_vm(kvm);
 
        return static_call(kvm_x86_vm_init)(kvm);
+
+out_page_track:
+       kvm_page_track_cleanup(kvm);
+out:
+       return ret;
 }
 
 int kvm_arch_post_init_vm(struct kvm *kvm)
@@ -12593,7 +12641,7 @@ void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_c
 {
        struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
        struct x86_exception fault;
-       u32 access = error_code &
+       u64 access = error_code &
                (PFERR_WRITE_MASK | PFERR_FETCH_MASK | PFERR_USER_MASK);
 
        if (!(error_code & PFERR_PRESENT_MASK) ||
@@ -12933,7 +12981,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pi_irte_update);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_unaccelerated_access);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_incomplete_ipi);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_ga_log);
-EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_update_request);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_accept_irq);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_enter);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_exit);