|
@@ -1817,18 +1817,6 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *dat
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
|
|
|
-{
|
|
|
- unsigned long end = hva + PAGE_SIZE;
|
|
|
-
|
|
|
- if (!kvm->arch.pgd)
|
|
|
- return 0;
|
|
|
-
|
|
|
- trace_kvm_unmap_hva(hva);
|
|
|
- handle_hva_to_gpa(kvm, hva, end, &kvm_unmap_hva_handler, NULL);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
int kvm_unmap_hva_range(struct kvm *kvm,
|
|
|
unsigned long start, unsigned long end)
|
|
|
{
|
|
@@ -1860,13 +1848,20 @@ static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data
|
|
|
void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
|
|
|
{
|
|
|
unsigned long end = hva + PAGE_SIZE;
|
|
|
+ kvm_pfn_t pfn = pte_pfn(pte);
|
|
|
pte_t stage2_pte;
|
|
|
|
|
|
if (!kvm->arch.pgd)
|
|
|
return;
|
|
|
|
|
|
trace_kvm_set_spte_hva(hva);
|
|
|
- stage2_pte = pfn_pte(pte_pfn(pte), PAGE_S2);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We've moved a page around, probably through CoW, so let's treat it
|
|
|
+ * just like a translation fault and clean the cache to the PoC.
|
|
|
+ */
|
|
|
+ clean_dcache_guest_page(pfn, PAGE_SIZE);
|
|
|
+ stage2_pte = pfn_pte(pfn, PAGE_S2);
|
|
|
handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte);
|
|
|
}
|
|
|
|