From: Oliver Upton <oliver.upton@linux.dev>
To: Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
Quentin Perret <qperret@google.com>,
Will Deacon <will@kernel.org>, Reiji Watanabe <reijiw@google.com>,
Oliver Upton <oliver.upton@linux.dev>
Subject: [PATCH 3/5] KVM: arm64: Only return attributes from stage2_update_leaf_attrs()
Date: Wed, 11 Jan 2023 00:02:58 +0000 [thread overview]
Message-ID: <20230111000300.2034799-4-oliver.upton@linux.dev> (raw)
In-Reply-To: <20230111000300.2034799-1-oliver.upton@linux.dev>
Returning a single PTE from stage2_update_leaf_attrs() doesn't make a
great deal of sense given that the function could be used to apply a
change to a range of PTEs. Instead, return a bitwise OR of attributes
from all the visited PTEs.
As the walker is no longer returning the full PTE, drop the check for a
valid PTE in kvm_age_gfn().
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/hyp/pgtable.c | 32 +++++++++++++++++---------------
arch/arm64/kvm/mmu.c | 2 +-
2 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 26f61462527d..a3d599e3af60 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -980,7 +980,7 @@ int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
struct stage2_attr_data {
kvm_pte_t attr_set;
kvm_pte_t attr_clr;
- kvm_pte_t pte;
+ kvm_pte_t attr_old;
u32 level;
};
@@ -995,7 +995,7 @@ static int stage2_attr_walker(const struct kvm_pgtable_visit_ctx *ctx,
return 0;
data->level = ctx->level;
- data->pte = pte;
+ data->attr_old |= pte & KVM_PTE_LEAF_ATTRS;
pte &= ~data->attr_clr;
pte |= data->attr_set;
@@ -1004,7 +1004,7 @@ static int stage2_attr_walker(const struct kvm_pgtable_visit_ctx *ctx,
* but worst-case the access flag update gets lost and will be
* set on the next access instead.
*/
- if (data->pte != pte) {
+ if (ctx->old != pte) {
/*
* Invalidate instruction cache before updating the guest
* stage-2 PTE if we are going to add executable permission.
@@ -1023,7 +1023,7 @@ static int stage2_attr_walker(const struct kvm_pgtable_visit_ctx *ctx,
static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr,
u64 size, kvm_pte_t attr_set,
- kvm_pte_t attr_clr, kvm_pte_t *orig_pte,
+ kvm_pte_t attr_clr, kvm_pte_t *attr_old,
u32 *level, enum kvm_pgtable_walk_flags flags)
{
int ret;
@@ -1041,11 +1041,12 @@ static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr,
if (ret)
return ret;
- if (orig_pte)
- *orig_pte = data.pte;
+ if (attr_old)
+ *attr_old = data.attr_old;
if (level)
*level = data.level;
+
return 0;
}
@@ -1058,32 +1059,33 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
{
- kvm_pte_t pte = 0;
+ kvm_pte_t attr_old = 0;
+
stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0,
- &pte, NULL, 0);
+ &attr_old, NULL, 0);
dsb(ishst);
- return pte;
+ return attr_old;
}
kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr)
{
- kvm_pte_t pte = 0;
+ kvm_pte_t attr_old = 0;
stage2_update_leaf_attrs(pgt, addr, 1, 0, KVM_PTE_LEAF_ATTR_LO_S2_AF,
- &pte, NULL, 0);
+ &attr_old, NULL, 0);
/*
* "But where's the TLBI?!", you scream.
* "Over in the core code", I sigh.
*
* See the '->clear_flush_young()' callback on the KVM mmu notifier.
*/
- return pte;
+ return attr_old;
}
bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr)
{
- kvm_pte_t pte = 0;
- stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &pte, NULL, 0);
- return pte & KVM_PTE_LEAF_ATTR_LO_S2_AF;
+ kvm_pte_t attr_old = 0;
+ stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &attr_old, NULL, 0);
+ return attr_old & KVM_PTE_LEAF_ATTR_LO_S2_AF;
}
int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 31d7fa4c7c14..0741f3a8ddca 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1618,7 +1618,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
kpte = kvm_pgtable_stage2_mkold(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT);
pte = __pte(kpte);
- return pte_valid(pte) && pte_young(pte);
+ return pte_young(pte);
}
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
--
2.39.0.314.g84b9a713c41-goog
WARNING: multiple messages have this Message-ID (diff)
From: Oliver Upton <oliver.upton@linux.dev>
To: Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
Quentin Perret <qperret@google.com>,
Will Deacon <will@kernel.org>, Reiji Watanabe <reijiw@google.com>,
Oliver Upton <oliver.upton@linux.dev>
Subject: [PATCH 3/5] KVM: arm64: Only return attributes from stage2_update_leaf_attrs()
Date: Wed, 11 Jan 2023 00:02:58 +0000 [thread overview]
Message-ID: <20230111000300.2034799-4-oliver.upton@linux.dev> (raw)
In-Reply-To: <20230111000300.2034799-1-oliver.upton@linux.dev>
Returning a single PTE from stage2_update_leaf_attrs() doesn't make a
great deal of sense given that the function could be used to apply a
change to a range of PTEs. Instead, return a bitwise OR of attributes
from all the visited PTEs.
As the walker is no longer returning the full PTE, drop the check for a
valid PTE in kvm_age_gfn().
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/hyp/pgtable.c | 32 +++++++++++++++++---------------
arch/arm64/kvm/mmu.c | 2 +-
2 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 26f61462527d..a3d599e3af60 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -980,7 +980,7 @@ int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size)
struct stage2_attr_data {
kvm_pte_t attr_set;
kvm_pte_t attr_clr;
- kvm_pte_t pte;
+ kvm_pte_t attr_old;
u32 level;
};
@@ -995,7 +995,7 @@ static int stage2_attr_walker(const struct kvm_pgtable_visit_ctx *ctx,
return 0;
data->level = ctx->level;
- data->pte = pte;
+ data->attr_old |= pte & KVM_PTE_LEAF_ATTRS;
pte &= ~data->attr_clr;
pte |= data->attr_set;
@@ -1004,7 +1004,7 @@ static int stage2_attr_walker(const struct kvm_pgtable_visit_ctx *ctx,
* but worst-case the access flag update gets lost and will be
* set on the next access instead.
*/
- if (data->pte != pte) {
+ if (ctx->old != pte) {
/*
* Invalidate instruction cache before updating the guest
* stage-2 PTE if we are going to add executable permission.
@@ -1023,7 +1023,7 @@ static int stage2_attr_walker(const struct kvm_pgtable_visit_ctx *ctx,
static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr,
u64 size, kvm_pte_t attr_set,
- kvm_pte_t attr_clr, kvm_pte_t *orig_pte,
+ kvm_pte_t attr_clr, kvm_pte_t *attr_old,
u32 *level, enum kvm_pgtable_walk_flags flags)
{
int ret;
@@ -1041,11 +1041,12 @@ static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr,
if (ret)
return ret;
- if (orig_pte)
- *orig_pte = data.pte;
+ if (attr_old)
+ *attr_old = data.attr_old;
if (level)
*level = data.level;
+
return 0;
}
@@ -1058,32 +1059,33 @@ int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
kvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr)
{
- kvm_pte_t pte = 0;
+ kvm_pte_t attr_old = 0;
+
stage2_update_leaf_attrs(pgt, addr, 1, KVM_PTE_LEAF_ATTR_LO_S2_AF, 0,
- &pte, NULL, 0);
+ &attr_old, NULL, 0);
dsb(ishst);
- return pte;
+ return attr_old;
}
kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr)
{
- kvm_pte_t pte = 0;
+ kvm_pte_t attr_old = 0;
stage2_update_leaf_attrs(pgt, addr, 1, 0, KVM_PTE_LEAF_ATTR_LO_S2_AF,
- &pte, NULL, 0);
+ &attr_old, NULL, 0);
/*
* "But where's the TLBI?!", you scream.
* "Over in the core code", I sigh.
*
* See the '->clear_flush_young()' callback on the KVM mmu notifier.
*/
- return pte;
+ return attr_old;
}
bool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr)
{
- kvm_pte_t pte = 0;
- stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &pte, NULL, 0);
- return pte & KVM_PTE_LEAF_ATTR_LO_S2_AF;
+ kvm_pte_t attr_old = 0;
+ stage2_update_leaf_attrs(pgt, addr, 1, 0, 0, &attr_old, NULL, 0);
+ return attr_old & KVM_PTE_LEAF_ATTR_LO_S2_AF;
}
int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 31d7fa4c7c14..0741f3a8ddca 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1618,7 +1618,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
kpte = kvm_pgtable_stage2_mkold(kvm->arch.mmu.pgt,
range->start << PAGE_SHIFT);
pte = __pte(kpte);
- return pte_valid(pte) && pte_young(pte);
+ return pte_young(pte);
}
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
--
2.39.0.314.g84b9a713c41-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-01-11 0:03 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-11 0:02 [PATCH 0/5] KVM: arm64: Handle unaligned memslots in kvm_(test_)_age_gfn() Oliver Upton
2023-01-11 0:02 ` Oliver Upton
2023-01-11 0:02 ` [PATCH 1/5] KVM: arm64: Hoist S2 PTE definitions into kvm_pgtable.h Oliver Upton
2023-01-11 0:02 ` Oliver Upton
2023-01-11 0:02 ` [PATCH 2/5] KVM: arm64: Add a mask for all leaf PTE attributes Oliver Upton
2023-01-11 0:02 ` Oliver Upton
2023-01-11 0:02 ` Oliver Upton [this message]
2023-01-11 0:02 ` [PATCH 3/5] KVM: arm64: Only return attributes from stage2_update_leaf_attrs() Oliver Upton
2023-01-11 8:52 ` Marc Zyngier
2023-01-11 8:52 ` Marc Zyngier
2023-01-11 17:21 ` Oliver Upton
2023-01-11 17:21 ` Oliver Upton
2023-02-02 22:08 ` Oliver Upton
2023-02-02 22:08 ` Oliver Upton
2023-02-07 14:56 ` Marc Zyngier
2023-02-07 14:56 ` Marc Zyngier
2023-01-11 0:02 ` [PATCH 4/5] KVM: arm64: Correctly handle page aging notifiers for unaligned memlsot Oliver Upton
2023-01-11 0:02 ` Oliver Upton
2023-01-12 15:44 ` Marc Zyngier
2023-01-12 15:44 ` Marc Zyngier
2023-01-11 0:03 ` [PATCH 5/5] KVM: arm64: Consistently use KVM's types/helpers in kvm_age_gfn() Oliver Upton
2023-01-11 0:03 ` 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=20230111000300.2034799-4-oliver.upton@linux.dev \
--to=oliver.upton@linux.dev \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=qperret@google.com \
--cc=reijiw@google.com \
--cc=will@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.