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>
This commit is contained in:
committed by
Paolo Bonzini
parent
8a9522d2fe
commit
5712846808
+3
-2
@@ -107,7 +107,8 @@ void __mmu_notifier_release(struct mm_struct *mm)
|
||||
* existed or not.
|
||||
*/
|
||||
int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
|
||||
unsigned long address)
|
||||
unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
struct mmu_notifier *mn;
|
||||
int young = 0, id;
|
||||
@@ -115,7 +116,7 @@ int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
|
||||
id = srcu_read_lock(&srcu);
|
||||
hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) {
|
||||
if (mn->ops->clear_flush_young)
|
||||
young |= mn->ops->clear_flush_young(mn, mm, address);
|
||||
young |= mn->ops->clear_flush_young(mn, mm, start, end);
|
||||
}
|
||||
srcu_read_unlock(&srcu, id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user