KVM: arm64: Take the SRCU lock for page table walks in fault injection and AT emulation
PATCH 1/1 KVM: arm64: Take the SRCU lock for page table walks in fault injection and AT emulation
[ Upstream commit f2ca45b50d4216c9cc7ffabf50d9ad1932209251 ]
walk_s1() and kvm_walk_nested_s2() expect to be called while holding kvm->srcu to guard against memslot changes. While this is generally the case, __kvm_at_s12() and __kvm_find_s1_desc_level() call into the respective walkers without taking kvm->srcu.
Fix by acquiring kvm->srcu prior to the table walk in both instances.
[ Hyunwoo Kim: __kvm_at_s12() still returns void in 6.18.y, so the
surrounding context differs from upstream (return; instead of return ret;); the added scoped_guard() is unchanged. ]
--- arch/arm64/kvm/at.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/arm64/kvm/at.c +4 -2
@@ -1528,7 +1528,8 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)/* Do the stage-2 translation */ ipa = (par &GENMASK_ULL (47 ,12 )) | (vaddr &GENMASK_ULL (11 ,0 )); out.esr =0 ; - ret =kvm_walk_nested_s2 (vcpu, ipa, &out); +scoped_guard (srcu, &vcpu->kvm->srcu) + ret = kvm_walk_nested_s2(vcpu, ipa, &out);if (ret <0 )return ;
@@ -1623,7 +1624,8 @@ int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa, int *level) }/* Walk the guest's PT, looking for a match along the way */ - ret =walk_s1 (vcpu, &wi, &wr, va); +scoped_guard (srcu, &vcpu->kvm->srcu) + ret = walk_s1(vcpu, &wi, &wr, va);switch (ret) {case -EINTR :/* We interrupted the walk on a match, return the level */
Signature · 1 line
2.43.0
Quoted 41 lines · Hyunwoo Kim
[ Upstream commit
f2ca45b50d4216c9cc7ffabf50d9ad1932209251]
walk_s1()andkvm_walk_nested_s2()expect to be called while holdingkvm->srcuto guard against memslot changes. While this is generally the case,__kvm_at_s12()and__kvm_find_s1_desc_level()call into the respective walkers without takingkvm->srcu.Fix by acquiring
kvm->srcuprior to the table walk in both instances.Fixes 50f77dc87f13 ("KVM: arm64: Populate level on S1PTW SEA injection")Fixes be04cebf3e78 ("KVM: arm64: nv: Add emulation of AT S12E{0,1}{R,W}")Suggested-by Oliver Upton <[email protected]>Signed-off-by Hyunwoo Kim <[email protected]>Reviewed-by Oliver Upton <[email protected]>Signed-off-by Marc Zyngier <[email protected]>[ Hyunwoo Kim:
__kvm_at_s12()still returns void in 6.18.y, so the
surrounding context differs from upstream (return; instead of return ret;); the addedscoped_guard()is unchanged. ]Signed-off-by Hyunwoo Kim <[email protected]>--- arch/arm64/kvm/at.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)arch/arm64/kvm/at.c +2
-1@@ -1528,7 +1528,8 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)/* Do the stage-2 translation */ ipa = (par &GENMASK_ULL (47 ,12 )) | (vaddr &GENMASK_ULL (11 ,0 )); out.esr =0 ; - ret =kvm_walk_nested_s2 (vcpu, ipa, &out); +scoped_guard (srcu, &vcpu->kvm->srcu) + ret = kvm_walk_nested_s2(vcpu, ipa, &out);if (ret <0 )return ;
arch/arm64/kvm/at.c int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa, int *level) · line 1631
Quoted 9 lines
arch/arm64/kvm/at.c +2
-1@@ -1623,7 +1624,8 @@ int __kvm_find_s1_desc_level(struct kvm_vcpu *vcpu, u64 va, u64 ipa, int *level) }/* Walk the guest's PT, looking for a match along the way */ - ret =walk_s1 (vcpu, &wi, &wr, va); +scoped_guard (srcu, &vcpu->kvm->srcu) + ret = walk_s1(vcpu, &wi, &wr, va);switch (ret) {case -EINTR :/* We interrupted the walk on a match, return the level */
Thanks for going the extra mile and doing the backport, much appreciated.
M.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Quoted 6 lines · Hyunwoo Kim
[ Upstream commit
f2ca45b50d4216c9cc7ffabf50d9ad1932209251]
walk_s1()andkvm_walk_nested_s2()expect to be called while holdingkvm->srcuto guard against memslot changes. While this is generally the case,__kvm_at_s12()and__kvm_find_s1_desc_level()call into the respective walkers without takingkvm->srcu.
Queued for 6.18, thanks.
Signature · 2 lines
Thanks, Sasha