[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200525112406.28224-6-zhukeqian1@huawei.com>
Date: Mon, 25 May 2020 19:24:04 +0800
From: Keqian Zhu <zhukeqian1@...wei.com>
To: <linux-kernel@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>,
<kvmarm@...ts.cs.columbia.edu>, <kvm@...r.kernel.org>
CC: Catalin Marinas <catalin.marinas@....com>,
Marc Zyngier <maz@...nel.org>,
James Morse <james.morse@....com>,
Will Deacon <will@...nel.org>,
"Suzuki K Poulose" <suzuki.poulose@....com>,
Sean Christopherson <sean.j.christopherson@...el.com>,
Julien Thierry <julien.thierry.kdev@...il.com>,
Mark Brown <broonie@...nel.org>,
"Thomas Gleixner" <tglx@...utronix.de>,
Andrew Morton <akpm@...ux-foundation.org>,
Alexios Zavras <alexios.zavras@...el.com>,
<wanghaibin.wang@...wei.com>, <zhengxiang9@...wei.com>,
Keqian Zhu <zhukeqian1@...wei.com>
Subject: [RFC PATCH 5/7] kvm: arm64: Modify stage2 young mechanism to support hw DBM
Making page table entries young (set AF bit) should be atomic to
avoid cover dirty info that is set by hardware.
Signed-off-by: Keqian Zhu <zhukeqian1@...wei.com>
---
arch/arm64/include/asm/kvm_mmu.h | 32 ++++++++++++++++++++++----------
virt/kvm/arm/mmu.c | 10 +++++-----
2 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 8df078f0ee67..a4620d87e456 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -235,6 +235,18 @@ static inline void kvm_set_s2pte_readonly(pte_t *ptep)
} while (pteval != old_pteval);
}
+static inline void kvm_set_s2pte_young(pte_t *ptep)
+{
+ pteval_t old_pteval, pteval;
+
+ pteval = READ_ONCE(pte_val(*ptep));
+ do {
+ old_pteval = pteval;
+ pteval |= PTE_AF;
+ pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval);
+ } while (pteval != old_pteval);
+}
+
static inline bool kvm_s2pte_readonly(pte_t *ptep)
{
return (READ_ONCE(pte_val(*ptep)) & PTE_S2_RDWR) == PTE_S2_RDONLY;
@@ -250,6 +262,11 @@ static inline void kvm_set_s2pmd_readonly(pmd_t *pmdp)
kvm_set_s2pte_readonly((pte_t *)pmdp);
}
+static inline void kvm_set_s2pmd_young(pmd_t *pmdp)
+{
+ kvm_set_s2pte_young((pte_t *)pmdp);
+}
+
static inline bool kvm_s2pmd_readonly(pmd_t *pmdp)
{
return kvm_s2pte_readonly((pte_t *)pmdp);
@@ -265,6 +282,11 @@ static inline void kvm_set_s2pud_readonly(pud_t *pudp)
kvm_set_s2pte_readonly((pte_t *)pudp);
}
+static inline void kvm_set_s2pud_young(pud_t *pudp)
+{
+ kvm_set_s2pte_young((pte_t *)pudp);
+}
+
static inline bool kvm_s2pud_readonly(pud_t *pudp)
{
return kvm_s2pte_readonly((pte_t *)pudp);
@@ -275,16 +297,6 @@ static inline bool kvm_s2pud_exec(pud_t *pudp)
return !(READ_ONCE(pud_val(*pudp)) & PUD_S2_XN);
}
-static inline pud_t kvm_s2pud_mkyoung(pud_t pud)
-{
- return pud_mkyoung(pud);
-}
-
-static inline bool kvm_s2pud_young(pud_t pud)
-{
- return pud_young(pud);
-}
-
#ifdef CONFIG_ARM64_HW_AFDBM
static inline bool kvm_hw_dbm_enabled(void)
{
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 779859b85d6d..e1d9e4b98cb6 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1888,15 +1888,15 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
goto out;
if (pud) { /* HugeTLB */
- *pud = kvm_s2pud_mkyoung(*pud);
+ kvm_set_s2pud_young(pud);
pfn = kvm_pud_pfn(*pud);
pfn_valid = true;
} else if (pmd) { /* THP, HugeTLB */
- *pmd = pmd_mkyoung(*pmd);
+ kvm_set_s2pmd_young(pmd);
pfn = pmd_pfn(*pmd);
pfn_valid = true;
- } else {
- *pte = pte_mkyoung(*pte); /* Just a page... */
+ } else { /* Just a page... */
+ kvm_set_s2pte_young(pte);
pfn = pte_pfn(*pte);
pfn_valid = true;
}
@@ -2141,7 +2141,7 @@ static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *
return 0;
if (pud)
- return kvm_s2pud_young(*pud);
+ return pud_young(*pud);
else if (pmd)
return pmd_young(*pmd);
else
--
2.19.1
Powered by blists - more mailing lists