aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
authorAndres Lagar-Cavilla <andreslc@google.com>2014-09-22 17:54:42 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-24 08:07:58 -0400
commit57128468080a8b6ea452223036d3e417f748af55 (patch)
treee89cfc349a9c39710cfab4e387119365a0d64958 /virt/kvm/kvm_main.c
parent8a9522d2fe6a1b643d3aef5ab7f097f73c601e7a (diff)
kvm: Fix page ageing bugs
1. We were calling clear_flush_young_notify in unmap_one, but we are within an mmu notifier invalidate range scope. The spte exists no more (due to range_start) and the accessed bit info has already been propagated (due to kvm_pfn_set_accessed). Simply call clear_flush_young. 2. We clear_flush_young on a primary MMU PMD, but this may be mapped as a collection of PTEs by the secondary MMU (e.g. during log-dirty). This required expanding the interface of the clear_flush_young mmu notifier, so a lot of code has been trivially touched. 3. In the absence of shadow_accessed_mask (e.g. EPT A bit), we emulate the access bit by blowing the spte. This requires proper synchronizing with MMU notifier consumers, like every other removal of spte's does. Signed-off-by: Andres Lagar-Cavilla <andreslc@google.com> Acked-by: Rik van Riel <riel@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index ff42b11d2b9c..0316314d48f4 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -369,7 +369,8 @@ static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
369 369
370static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn, 370static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
371 struct mm_struct *mm, 371 struct mm_struct *mm,
372 unsigned long address) 372 unsigned long start,
373 unsigned long end)
373{ 374{
374 struct kvm *kvm = mmu_notifier_to_kvm(mn); 375 struct kvm *kvm = mmu_notifier_to_kvm(mn);
375 int young, idx; 376 int young, idx;
@@ -377,7 +378,7 @@ static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
377 idx = srcu_read_lock(&kvm->srcu); 378 idx = srcu_read_lock(&kvm->srcu);
378 spin_lock(&kvm->mmu_lock); 379 spin_lock(&kvm->mmu_lock);
379 380
380 young = kvm_age_hva(kvm, address); 381 young = kvm_age_hva(kvm, start, end);
381 if (young) 382 if (young)
382 kvm_flush_remote_tlbs(kvm); 383 kvm_flush_remote_tlbs(kvm);
383 384