Loading arch/x86/kvm/mmu.c +28 −8 Original line number Diff line number Diff line Loading @@ -2506,6 +2506,14 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) mmu_free_roots(vcpu); } static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level) { int bit7; bit7 = (gpte >> 7) & 1; return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0; } static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool no_dirty_log) { Loading @@ -2518,6 +2526,26 @@ static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, return gfn_to_pfn_memslot_atomic(slot, gfn); } static bool prefetch_invalid_gpte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *spte, u64 gpte) { if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) goto no_present; if (!is_present_gpte(gpte)) goto no_present; if (!(gpte & PT_ACCESSED_MASK)) goto no_present; return false; no_present: drop_spte(vcpu->kvm, spte); return true; } static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *start, u64 *end) Loading Loading @@ -3395,14 +3423,6 @@ static void paging_free(struct kvm_vcpu *vcpu) nonpaging_free(vcpu); } static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level) { int bit7; bit7 = (gpte >> 7) & 1; return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0; } static inline void protect_clean_gpte(unsigned *access, unsigned gpte) { unsigned mask; Loading arch/x86/kvm/paging_tmpl.h +3 −23 Original line number Diff line number Diff line Loading @@ -305,26 +305,6 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker, addr, access); } static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *spte, pt_element_t gpte) { if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) goto no_present; if (!is_present_gpte(gpte)) goto no_present; if (!(gpte & PT_ACCESSED_MASK)) goto no_present; return false; no_present: drop_spte(vcpu->kvm, spte); return true; } static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *spte, const void *pte) { Loading @@ -333,7 +313,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, pfn_t pfn; gpte = *(const pt_element_t *)pte; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) if (prefetch_invalid_gpte(vcpu, sp, spte, gpte)) return; pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); Loading Loading @@ -408,7 +388,7 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, gpte = gptep[i]; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) if (prefetch_invalid_gpte(vcpu, sp, spte, gpte)) continue; pte_access = sp->role.access & gpte_access(vcpu, gpte); Loading Loading @@ -751,7 +731,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) sizeof(pt_element_t))) return -EINVAL; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) { if (prefetch_invalid_gpte(vcpu, sp, &sp->spt[i], gpte)) { vcpu->kvm->tlbs_dirty++; continue; } Loading Loading
arch/x86/kvm/mmu.c +28 −8 Original line number Diff line number Diff line Loading @@ -2506,6 +2506,14 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) mmu_free_roots(vcpu); } static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level) { int bit7; bit7 = (gpte >> 7) & 1; return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0; } static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, bool no_dirty_log) { Loading @@ -2518,6 +2526,26 @@ static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn, return gfn_to_pfn_memslot_atomic(slot, gfn); } static bool prefetch_invalid_gpte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *spte, u64 gpte) { if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) goto no_present; if (!is_present_gpte(gpte)) goto no_present; if (!(gpte & PT_ACCESSED_MASK)) goto no_present; return false; no_present: drop_spte(vcpu->kvm, spte); return true; } static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *start, u64 *end) Loading Loading @@ -3395,14 +3423,6 @@ static void paging_free(struct kvm_vcpu *vcpu) nonpaging_free(vcpu); } static bool is_rsvd_bits_set(struct kvm_mmu *mmu, u64 gpte, int level) { int bit7; bit7 = (gpte >> 7) & 1; return (gpte & mmu->rsvd_bits_mask[bit7][level-1]) != 0; } static inline void protect_clean_gpte(unsigned *access, unsigned gpte) { unsigned mask; Loading
arch/x86/kvm/paging_tmpl.h +3 −23 Original line number Diff line number Diff line Loading @@ -305,26 +305,6 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker, addr, access); } static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *spte, pt_element_t gpte) { if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) goto no_present; if (!is_present_gpte(gpte)) goto no_present; if (!(gpte & PT_ACCESSED_MASK)) goto no_present; return false; no_present: drop_spte(vcpu->kvm, spte); return true; } static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, u64 *spte, const void *pte) { Loading @@ -333,7 +313,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, pfn_t pfn; gpte = *(const pt_element_t *)pte; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) if (prefetch_invalid_gpte(vcpu, sp, spte, gpte)) return; pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); Loading Loading @@ -408,7 +388,7 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, gpte = gptep[i]; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) if (prefetch_invalid_gpte(vcpu, sp, spte, gpte)) continue; pte_access = sp->role.access & gpte_access(vcpu, gpte); Loading Loading @@ -751,7 +731,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) sizeof(pt_element_t))) return -EINVAL; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) { if (prefetch_invalid_gpte(vcpu, sp, &sp->spt[i], gpte)) { vcpu->kvm->tlbs_dirty++; continue; } Loading