[PATCH 12/20] [Bionic] (upstream) KVM: PPC: Book3S HV: Use a helper to unmap ptes in the radix fault path
Leonardo Bras
leonardo at linux.ibm.com
Mon Mar 11 21:39:59 UTC 2019
From: Nicholas Piggin <npiggin at gmail.com>
BugLink: https://bugs.launchpad.net/bugs/1788098
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
Signed-off-by: Paul Mackerras <paulus at ozlabs.org>
(cherry picked from commit a5fad1e959529eda20f38d1e02be65ab629de899 v4.19)
Signed-off-by: Leonardo Bras <leonardo at linux.ibm.com>
---
arch/powerpc/kvm/book3s_64_mmu_radix.c | 46 +++++++++++++-------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index 481da8f93fa4..2c49b31ec7fb 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -228,6 +228,25 @@ static void kvmppc_pmd_free(pmd_t *pmdp)
kmem_cache_free(kvm_pmd_cache, pmdp);
}
+static void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte,
+ unsigned long gpa, unsigned int shift)
+
+{
+ unsigned long page_size = 1ul << shift;
+ unsigned long old;
+
+ old = kvmppc_radix_update_pte(kvm, pte, ~0UL, 0, gpa, shift);
+ kvmppc_radix_tlbie_page(kvm, gpa, shift);
+ if (old & _PAGE_DIRTY) {
+ unsigned long gfn = gpa >> PAGE_SHIFT;
+ struct kvm_memory_slot *memslot;
+
+ memslot = gfn_to_memslot(kvm, gfn);
+ if (memslot && memslot->dirty_bitmap)
+ kvmppc_update_dirty_map(memslot, gfn, page_size);
+ }
+}
+
static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
unsigned int level, unsigned long mmu_seq)
{
@@ -235,7 +254,6 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
pud_t *pud, *new_pud = NULL;
pmd_t *pmd, *new_pmd = NULL;
pte_t *ptep, *new_ptep = NULL;
- unsigned long old;
int ret;
/* Traverse the guest's 2nd-level tree, allocate new levels needed */
@@ -287,17 +305,7 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
goto out_unlock;
}
/* Valid 1GB page here already, remove it */
- old = kvmppc_radix_update_pte(kvm, (pte_t *)pud,
- ~0UL, 0, hgpa, PUD_SHIFT);
- kvmppc_radix_tlbie_page(kvm, hgpa, PUD_SHIFT);
- if (old & _PAGE_DIRTY) {
- unsigned long gfn = hgpa >> PAGE_SHIFT;
- struct kvm_memory_slot *memslot;
- memslot = gfn_to_memslot(kvm, gfn);
- if (memslot && memslot->dirty_bitmap)
- kvmppc_update_dirty_map(memslot,
- gfn, PUD_SIZE);
- }
+ kvmppc_unmap_pte(kvm, (pte_t *)pud, hgpa, PUD_SHIFT);
}
if (level == 2) {
if (!pud_none(*pud)) {
@@ -338,17 +346,7 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
goto out_unlock;
}
/* Valid 2MB page here already, remove it */
- old = kvmppc_radix_update_pte(kvm, pmdp_ptep(pmd),
- ~0UL, 0, lgpa, PMD_SHIFT);
- kvmppc_radix_tlbie_page(kvm, lgpa, PMD_SHIFT);
- if (old & _PAGE_DIRTY) {
- unsigned long gfn = lgpa >> PAGE_SHIFT;
- struct kvm_memory_slot *memslot;
- memslot = gfn_to_memslot(kvm, gfn);
- if (memslot && memslot->dirty_bitmap)
- kvmppc_update_dirty_map(memslot,
- gfn, PMD_SIZE);
- }
+ kvmppc_unmap_pte(kvm, pmdp_ptep(pmd), lgpa, PMD_SHIFT);
}
if (level == 1) {
if (!pmd_none(*pmd)) {
@@ -373,6 +371,8 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
}
ptep = pte_offset_kernel(pmd, gpa);
if (pte_present(*ptep)) {
+ unsigned long old;
+
/* Check if someone else set the same thing */
if (pte_raw(*ptep) == pte_raw(pte)) {
ret = 0;
--
2.20.1
More information about the kernel-team
mailing list