diff options
author | Marc Zyngier <[email protected]> | 2024-07-20 22:06:00 +0100 |
---|---|---|
committer | Marc Zyngier <[email protected]> | 2024-08-30 12:04:20 +0100 |
commit | d95bb9ef164edb33565cb73e3f0b0a581b3e4fbb (patch) | |
tree | 1873801519042931153d7be9d86a73abc8662522 | |
parent | 2441418f3aadb3f9232431aeb10d89e48a934d94 (diff) |
KVM: arm64: nv: Make AT+PAN instructions aware of FEAT_PAN3
FEAT_PAN3 added a check for executable permissions to FEAT_PAN2.
Add the required SCTLR_ELx.EPAN and descriptor checks to handle
this correctly.
Reviewed-by: Alexandru Elisei <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
-rw-r--r-- | arch/arm64/kvm/at.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c index e037eb73738a..60f1ca3a897d 100644 --- a/arch/arm64/kvm/at.c +++ b/arch/arm64/kvm/at.c @@ -731,6 +731,21 @@ static u64 compute_par_s1(struct kvm_vcpu *vcpu, struct s1_walk_result *wr, return par; } +static bool pan3_enabled(struct kvm_vcpu *vcpu, enum trans_regime regime) +{ + u64 sctlr; + + if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, PAN, PAN3)) + return false; + + if (regime == TR_EL10) + sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); + else + sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL2); + + return sctlr & SCTLR_EL1_EPAN; +} + static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) { bool perm_fail, ur, uw, ux, pr, pw, px; @@ -797,7 +812,7 @@ static u64 handle_at_slow(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) bool pan; pan = *vcpu_cpsr(vcpu) & PSR_PAN_BIT; - pan &= ur || uw; + pan &= ur || uw || (pan3_enabled(vcpu, wi.regime) && ux); pw &= !pan; pr &= !pan; } |