Skip to content

Commit 531f520

Browse files
committed
Merge branch 'mm-delete-change-gpte' into HEAD
The .change_pte() MMU notifier callback was intended as an optimization and for this reason it was initially called without a surrounding mmu_notifier_invalidate_range_{start,end}() pair. It was only ever implemented by KVM (which was also the original user of MMU notifiers) and the rules on when to call set_pte_at_notify() rather than set_pte_at() have always been pretty obscure. It may seem a miracle that it has never caused any hard to trigger bugs, but there's a good reason for that: KVM's implementation has been nonfunctional for a good part of its existence. Already in 2012, commit 6bdb913 ("mm: wrap calls to set_pte_at_notify with invalidate_range_start and invalidate_range_end", 2012-10-09) changed the .change_pte() callback to occur within an invalidate_range_start/end() pair; and because KVM unmaps the sPTEs during .invalidate_range_start(), .change_pte() has no hope of finding a sPTE to change. Therefore, all the code for .change_pte() can be removed from both KVM and mm/, and set_pte_at_notify() can be replaced with just set_pte_at(). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2 parents 9bc60f7 + f784274 commit 531f520

26 files changed

Lines changed: 16 additions & 419 deletions

File tree

arch/arm64/kvm/mmu.c

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,40 +1768,6 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
17681768
return false;
17691769
}
17701770

1771-
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
1772-
{
1773-
kvm_pfn_t pfn = pte_pfn(range->arg.pte);
1774-
1775-
if (!kvm->arch.mmu.pgt)
1776-
return false;
1777-
1778-
WARN_ON(range->end - range->start != 1);
1779-
1780-
/*
1781-
* If the page isn't tagged, defer to user_mem_abort() for sanitising
1782-
* the MTE tags. The S2 pte should have been unmapped by
1783-
* mmu_notifier_invalidate_range_end().
1784-
*/
1785-
if (kvm_has_mte(kvm) && !page_mte_tagged(pfn_to_page(pfn)))
1786-
return false;
1787-
1788-
/*
1789-
* We've moved a page around, probably through CoW, so let's treat
1790-
* it just like a translation fault and the map handler will clean
1791-
* the cache to the PoC.
1792-
*
1793-
* The MMU notifiers will have unmapped a huge PMD before calling
1794-
* ->change_pte() (which in turn calls kvm_set_spte_gfn()) and
1795-
* therefore we never need to clear out a huge PMD through this
1796-
* calling path and a memcache is not required.
1797-
*/
1798-
kvm_pgtable_stage2_map(kvm->arch.mmu.pgt, range->start << PAGE_SHIFT,
1799-
PAGE_SIZE, __pfn_to_phys(pfn),
1800-
KVM_PGTABLE_PROT_R, NULL, 0);
1801-
1802-
return false;
1803-
}
1804-
18051771
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
18061772
{
18071773
u64 size = (range->end - range->start) << PAGE_SHIFT;

arch/loongarch/include/asm/kvm_host.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ void kvm_flush_tlb_all(void);
203203
void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa);
204204
int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long badv, bool write);
205205

206-
void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
207206
int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, bool blockable);
208207
int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
209208
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);

arch/loongarch/kvm/mmu.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -494,38 +494,6 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
494494
range->end << PAGE_SHIFT, &ctx);
495495
}
496496

497-
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
498-
{
499-
unsigned long prot_bits;
500-
kvm_pte_t *ptep;
501-
kvm_pfn_t pfn = pte_pfn(range->arg.pte);
502-
gpa_t gpa = range->start << PAGE_SHIFT;
503-
504-
ptep = kvm_populate_gpa(kvm, NULL, gpa, 0);
505-
if (!ptep)
506-
return false;
507-
508-
/* Replacing an absent or old page doesn't need flushes */
509-
if (!kvm_pte_present(NULL, ptep) || !kvm_pte_young(*ptep)) {
510-
kvm_set_pte(ptep, 0);
511-
return false;
512-
}
513-
514-
/* Fill new pte if write protected or page migrated */
515-
prot_bits = _PAGE_PRESENT | __READABLE;
516-
prot_bits |= _CACHE_MASK & pte_val(range->arg.pte);
517-
518-
/*
519-
* Set _PAGE_WRITE or _PAGE_DIRTY iff old and new pte both support
520-
* _PAGE_WRITE for map_page_fast if next page write fault
521-
* _PAGE_DIRTY since gpa has already recorded as dirty page
522-
*/
523-
prot_bits |= __WRITEABLE & *ptep & pte_val(range->arg.pte);
524-
kvm_set_pte(ptep, kvm_pfn_pte(pfn, __pgprot(prot_bits)));
525-
526-
return true;
527-
}
528-
529497
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
530498
{
531499
kvm_ptw_ctx ctx;

arch/mips/kvm/mmu.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -444,36 +444,6 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
444444
return true;
445445
}
446446

447-
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
448-
{
449-
gpa_t gpa = range->start << PAGE_SHIFT;
450-
pte_t hva_pte = range->arg.pte;
451-
pte_t *gpa_pte = kvm_mips_pte_for_gpa(kvm, NULL, gpa);
452-
pte_t old_pte;
453-
454-
if (!gpa_pte)
455-
return false;
456-
457-
/* Mapping may need adjusting depending on memslot flags */
458-
old_pte = *gpa_pte;
459-
if (range->slot->flags & KVM_MEM_LOG_DIRTY_PAGES && !pte_dirty(old_pte))
460-
hva_pte = pte_mkclean(hva_pte);
461-
else if (range->slot->flags & KVM_MEM_READONLY)
462-
hva_pte = pte_wrprotect(hva_pte);
463-
464-
set_pte(gpa_pte, hva_pte);
465-
466-
/* Replacing an absent or old page doesn't need flushes */
467-
if (!pte_present(old_pte) || !pte_young(old_pte))
468-
return false;
469-
470-
/* Pages swapped, aged, moved, or cleaned require flushes */
471-
return !pte_present(hva_pte) ||
472-
!pte_young(hva_pte) ||
473-
pte_pfn(old_pte) != pte_pfn(hva_pte) ||
474-
(pte_dirty(old_pte) && !pte_dirty(hva_pte));
475-
}
476-
477447
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
478448
{
479449
return kvm_mips_mkold_gpa_pt(kvm, range->start, range->end);

arch/powerpc/include/asm/kvm_ppc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ struct kvmppc_ops {
287287
bool (*unmap_gfn_range)(struct kvm *kvm, struct kvm_gfn_range *range);
288288
bool (*age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
289289
bool (*test_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
290-
bool (*set_spte_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
291290
void (*free_memslot)(struct kvm_memory_slot *slot);
292291
int (*init_vm)(struct kvm *kvm);
293292
void (*destroy_vm)(struct kvm *kvm);

arch/powerpc/kvm/book3s.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -899,11 +899,6 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
899899
return kvm->arch.kvm_ops->test_age_gfn(kvm, range);
900900
}
901901

902-
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
903-
{
904-
return kvm->arch.kvm_ops->set_spte_gfn(kvm, range);
905-
}
906-
907902
int kvmppc_core_init_vm(struct kvm *kvm)
908903
{
909904

arch/powerpc/kvm/book3s.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ extern void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
1212
extern bool kvm_unmap_gfn_range_hv(struct kvm *kvm, struct kvm_gfn_range *range);
1313
extern bool kvm_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
1414
extern bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
15-
extern bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
1615

1716
extern int kvmppc_mmu_init_pr(struct kvm_vcpu *vcpu);
1817
extern void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu);

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,18 +1010,6 @@ bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
10101010
return kvm_test_age_rmapp(kvm, range->slot, range->start);
10111011
}
10121012

1013-
bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
1014-
{
1015-
WARN_ON(range->start + 1 != range->end);
1016-
1017-
if (kvm_is_radix(kvm))
1018-
kvm_unmap_radix(kvm, range->slot, range->start);
1019-
else
1020-
kvm_unmap_rmapp(kvm, range->slot, range->start);
1021-
1022-
return false;
1023-
}
1024-
10251013
static int vcpus_running(struct kvm *kvm)
10261014
{
10271015
return atomic_read(&kvm->arch.vcpus_running) != 0;

arch/powerpc/kvm/book3s_hv.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6364,7 +6364,6 @@ static struct kvmppc_ops kvm_ops_hv = {
63646364
.unmap_gfn_range = kvm_unmap_gfn_range_hv,
63656365
.age_gfn = kvm_age_gfn_hv,
63666366
.test_age_gfn = kvm_test_age_gfn_hv,
6367-
.set_spte_gfn = kvm_set_spte_gfn_hv,
63686367
.free_memslot = kvmppc_core_free_memslot_hv,
63696368
.init_vm = kvmppc_core_init_vm_hv,
63706369
.destroy_vm = kvmppc_core_destroy_vm_hv,

arch/powerpc/kvm/book3s_pr.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,12 +461,6 @@ static bool kvm_test_age_gfn_pr(struct kvm *kvm, struct kvm_gfn_range *range)
461461
return false;
462462
}
463463

464-
static bool kvm_set_spte_gfn_pr(struct kvm *kvm, struct kvm_gfn_range *range)
465-
{
466-
/* The page will get remapped properly on its next fault */
467-
return do_kvm_unmap_gfn(kvm, range);
468-
}
469-
470464
/*****************************************/
471465

472466
static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)
@@ -2071,7 +2065,6 @@ static struct kvmppc_ops kvm_ops_pr = {
20712065
.unmap_gfn_range = kvm_unmap_gfn_range_pr,
20722066
.age_gfn = kvm_age_gfn_pr,
20732067
.test_age_gfn = kvm_test_age_gfn_pr,
2074-
.set_spte_gfn = kvm_set_spte_gfn_pr,
20752068
.free_memslot = kvmppc_core_free_memslot_pr,
20762069
.init_vm = kvmppc_core_init_vm_pr,
20772070
.destroy_vm = kvmppc_core_destroy_vm_pr,

0 commit comments

Comments
 (0)