From: Lilit Janpoladyan <lilitj@amazon.com>
To: <kvm@vger.kernel.org>, <maz@kernel.org>, <oliver.upton@linux.dev>,
<james.morse@arm.com>, <suzuki.poulose@arm.com>,
<yuzenghui@huawei.com>, <nh-open-source@amazon.com>,
<lilitj@amazon.com>
Subject: [PATCH 8/8] KVM: arm64: make hardware manage dirty state after write faults
Date: Wed, 18 Sep 2024 15:28:07 +0000 [thread overview]
Message-ID: <20240918152807.25135-9-lilitj@amazon.com> (raw)
In-Reply-To: <20240918152807.25135-1-lilitj@amazon.com>
In case of hardware dirty logging, fault in pages with their dirty
state managed by hardware. This will allow further writes to the
faulted in pages to be logged by the page tracking device. The first
write will still be logged on write fault. To avoid faults on first
writes we need to set DBM bit when eagerly splitting huge pages (to be
added).
Add KVM_PTE_LEAF_ATTR_HI_S2_DBM for the hardware DBM flag and
KVM_PGTABLE_PROT_HWDBM as a software page protection flag.
Hardware dirty state management changes the way
KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W is interpreted. Pages whose dirty state
is managed by the hardware are always writable and
KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W bit denotes their dirty state.
Signed-off-by: Lilit Janpoladyan <lilitj@amazon.com>
---
arch/arm64/include/asm/kvm_pgtable.h | 1 +
arch/arm64/kvm/hyp/pgtable.c | 23 ++++++++++++++++++++---
arch/arm64/kvm/mmu.c | 8 ++++++++
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 19278dfe7978..d3b81d7e923b 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -210,6 +210,7 @@ enum kvm_pgtable_prot {
KVM_PGTABLE_PROT_DEVICE = BIT(3),
KVM_PGTABLE_PROT_NORMAL_NC = BIT(4),
+ KVM_PGTABLE_PROT_HWDBM = BIT(5),
KVM_PGTABLE_PROT_SW0 = BIT(55),
KVM_PGTABLE_PROT_SW1 = BIT(56),
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index d507931ab10c..c4d654e7189c 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -46,6 +46,8 @@
#define KVM_PTE_LEAF_ATTR_HI_S1_GP BIT(50)
+#define KVM_PTE_LEAF_ATTR_HI_S2_DBM BIT(51)
+
#define KVM_PTE_LEAF_ATTR_S2_PERMS (KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
KVM_PTE_LEAF_ATTR_HI_S2_XN)
@@ -746,7 +748,13 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
if (prot & KVM_PGTABLE_PROT_R)
attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
- if (prot & KVM_PGTABLE_PROT_W)
+ /*
+ * If hardware dirty state management is enabled then S2AP_W is interpreted
+ * as dirty state, don't set S2AP_W in this case
+ */
+ if (prot & KVM_PGTABLE_PROT_HWDBM)
+ attr |= KVM_PTE_LEAF_ATTR_HI_S2_DBM;
+ else if (prot & KVM_PGTABLE_PROT_W)
attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
if (!kvm_lpa2_is_enabled())
@@ -768,7 +776,10 @@ enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte)
if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R)
prot |= KVM_PGTABLE_PROT_R;
- if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W)
+
+ if (pte & KVM_PTE_LEAF_ATTR_HI_S2_DBM)
+ prot |= KVM_PGTABLE_PROT_HWDBM | KVM_PGTABLE_PROT_W;
+ else if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W)
prot |= KVM_PGTABLE_PROT_W;
if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN))
prot |= KVM_PGTABLE_PROT_X;
@@ -1367,7 +1378,13 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
if (prot & KVM_PGTABLE_PROT_R)
set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
- if (prot & KVM_PGTABLE_PROT_W)
+ /*
+ * If hardware dirty state management is enabled then S2AP_W is interpreted
+ * as dirty state, don't set S2AP_W in this case
+ */
+ if (prot & KVM_PGTABLE_PROT_HWDBM)
+ set |= KVM_PTE_LEAF_ATTR_HI_S2_DBM;
+ else if (prot & KVM_PGTABLE_PROT_W)
set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
if (prot & KVM_PGTABLE_PROT_X)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index a509b63bd4dd..a5bcc7f11083 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1418,6 +1418,11 @@ static bool kvm_vma_mte_allowed(struct vm_area_struct *vma)
return vma->vm_flags & VM_MTE_ALLOWED;
}
+static bool is_hw_logging_enabled(struct kvm *kvm)
+{
+ return kvm->arch.page_tracking_ctx != NULL;
+}
+
static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
struct kvm_s2_trans *nested,
struct kvm_memory_slot *memslot, unsigned long hva,
@@ -1658,6 +1663,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (writable)
prot |= KVM_PGTABLE_PROT_W;
+ if (is_hw_logging_enabled(kvm))
+ prot |= KVM_PGTABLE_PROT_HWDBM;
+
if (exec_fault)
prot |= KVM_PGTABLE_PROT_X;
--
2.40.1
next prev parent reply other threads:[~2024-09-18 15:28 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-18 15:27 [PATCH 0/8] *** RFC: ARM KVM dirty tracking device *** Lilit Janpoladyan
2024-09-18 15:28 ` [PATCH 1/8] arm64: add an interface for stage-2 page tracking Lilit Janpoladyan
2024-09-18 15:28 ` [PATCH 2/8] KVM: arm64: add page tracking device as a capability Lilit Janpoladyan
2024-09-18 15:28 ` [PATCH 3/8] KVM: arm64: use page tracking interface to enable dirty logging Lilit Janpoladyan
2024-09-22 7:31 ` Sean Christopherson
2024-09-18 15:28 ` [PATCH 4/8] KVM: return value from kvm_arch_sync_dirty_log Lilit Janpoladyan
2024-09-19 1:50 ` kernel test robot
2024-09-19 2:32 ` kernel test robot
2024-09-18 15:28 ` [PATCH 5/8] KVM: arm64: get dirty pages from the page tracking device Lilit Janpoladyan
2024-09-18 15:28 ` [PATCH 6/8] KVM: arm64: flush dirty logging data Lilit Janpoladyan
2024-09-18 15:28 ` [PATCH 7/8] KVM: arm64: enable hardware dirty state management for stage-2 Lilit Janpoladyan
2024-09-18 15:28 ` Lilit Janpoladyan [this message]
2024-09-19 9:11 ` [PATCH 0/8] *** RFC: ARM KVM dirty tracking device *** Oliver Upton
2024-09-20 10:12 ` Janpoladyan, Lilit
2024-09-26 10:00 ` David Woodhouse
2024-09-30 17:33 ` Oliver Upton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240918152807.25135-9-lilitj@amazon.com \
--to=lilitj@amazon.com \
--cc=james.morse@arm.com \
--cc=kvm@vger.kernel.org \
--cc=maz@kernel.org \
--cc=nh-open-source@amazon.com \
--cc=oliver.upton@linux.dev \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox