[RFC PATCH 2/7] KVM: arm64: Set DBM bit of PTEs if hw DBM enabled

From: Keqian Zhu
Date: Mon May 25 2020 - 07:25:59 EST


In user_mem_abort, for normal case (mem_type is PAGE_S2), set DBM bit
of PTEs if hw DBM enabled. We also check and set DBM bit during write
protect PTEs to make it works well if we miss some cases.

Signed-off-by: Keqian Zhu <zhukeqian1@xxxxxxxxxx>
Signed-off-by: Peng Liang <liangpeng10@xxxxxxxxxx>
---
arch/arm64/include/asm/pgtable-prot.h | 1 +
virt/kvm/arm/mmu.c | 14 +++++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 1305e28225fc..f9910ba2afd8 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -79,6 +79,7 @@ extern bool arm64_use_ng_mappings;
})

#define PAGE_S2 __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PAGE_S2_XN)
+#define PAGE_S2_DBM __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PAGE_S2_XN | PTE_DBM)
#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN)

#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index e3b9ee268823..dc97988eb2e0 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1426,6 +1426,10 @@ static void stage2_wp_ptes(pmd_t *pmd, phys_addr_t addr, phys_addr_t end)
pte = pte_offset_kernel(pmd, addr);
do {
if (!pte_none(*pte)) {
+#ifdef CONFIG_ARM64_HW_AFDBM
+ if (kvm_hw_dbm_enabled() && !kvm_s2pte_dbm(pte))
+ kvm_set_s2pte_dbm(pte);
+#endif
if (!kvm_s2pte_readonly(pte))
kvm_set_s2pte_readonly(pte);
}
@@ -1827,7 +1831,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,

ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd);
} else {
- pte_t new_pte = kvm_pfn_pte(pfn, mem_type);
+ pte_t new_pte;
+
+#ifdef CONFIG_ARM64_HW_AFDBM
+ if (kvm_hw_dbm_enabled() &&
+ pgprot_val(mem_type) == pgprot_val(PAGE_S2)) {
+ mem_type = PAGE_S2_DBM;
+ }
+#endif
+ new_pte = kvm_pfn_pte(pfn, mem_type);

if (writable) {
new_pte = kvm_s2pte_mkwrite(new_pte);
--
2.19.1