Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / arch / x86 / kvm / mmu.c
index f1b36cf..5b2bf2b 100644 (file)
@@ -2451,6 +2451,9 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
        int emulate = 0;
        gfn_t pseudo_gfn;
 
+       if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+               return 0;
+
        for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
                if (iterator.level == level) {
                        unsigned pte_access = ACC_ALL;
@@ -2839,7 +2842,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
        if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
                return;
 
-       vcpu_clear_mmio_info(vcpu, ~0ul);
+       vcpu_clear_mmio_info(vcpu, MMIO_GVA_ANY);
        trace_kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC);
        if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
                hpa_t root = vcpu->arch.mmu.root_hpa;
@@ -3008,12 +3011,15 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn)
        return kvm_setup_async_pf(vcpu, gva, gfn, &arch);
 }
 
-static bool can_do_async_pf(struct kvm_vcpu *vcpu)
+bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu)
 {
        if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
                     kvm_event_needs_reinjection(vcpu)))
                return false;
 
+       if (is_guest_mode(vcpu))
+               return false;
+
        return kvm_x86_ops->interrupt_allowed(vcpu);
 }
 
@@ -3029,7 +3035,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
 
        put_page(pfn_to_page(*pfn));
 
-       if (!prefault && can_do_async_pf(vcpu)) {
+       if (!prefault && kvm_can_do_async_pf(vcpu)) {
                trace_kvm_try_async_get_page(gva, gfn);
                if (kvm_find_async_pf_gfn(vcpu, gfn)) {
                        trace_kvm_async_pf_doublefault(gva, gfn);
@@ -3606,7 +3612,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
                }
        }
 
-       mask.cr0_wp = mask.cr4_pae = mask.nxe = 1;
+       mask.cr0_wp = mask.cr4_pae = mask.nxe = mask.smep_andnot_wp = 1;
        for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn, node) {
                pte_size = sp->role.cr4_pae ? 8 : 4;
                misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);