diff options
author | Marc Zyngier <maz@kernel.org> | 2024-07-14 11:40:43 +0200 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2024-08-30 13:04:20 +0200 |
commit | be0135bde1df5e80cffacd2ed6f952e6d38d6f71 (patch) | |
tree | b1dc5a6be2569fc3964a3d5e6affc9c8a6043dc6 /arch/arm64/kvm | |
parent | KVM: arm64: nv: Add basic emulation of AT S1E{0,1}{R,W} (diff) | |
download | linux-be0135bde1df5e80cffacd2ed6f952e6d38d6f71.tar.xz linux-be0135bde1df5e80cffacd2ed6f952e6d38d6f71.zip |
KVM: arm64: nv: Add basic emulation of AT S1E1{R,W}P
Building on top of our primitive AT S1E{0,1}{R,W} emulation,
add minimal support for the FEAT_PAN2 instructions, momentary
context-switching PSTATE.PAN so that it takes effect in the
context of the guest.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'arch/arm64/kvm')
-rw-r--r-- | arch/arm64/kvm/at.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c index da378ad834cd..92df948350e1 100644 --- a/arch/arm64/kvm/at.c +++ b/arch/arm64/kvm/at.c @@ -49,6 +49,28 @@ static void __mmu_config_restore(struct mmu_config *config) write_sysreg(config->vtcr, vtcr_el2); } +static bool at_s1e1p_fast(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) +{ + u64 host_pan; + bool fail; + + host_pan = read_sysreg_s(SYS_PSTATE_PAN); + write_sysreg_s(*vcpu_cpsr(vcpu) & PSTATE_PAN, SYS_PSTATE_PAN); + + switch (op) { + case OP_AT_S1E1RP: + fail = __kvm_at(OP_AT_S1E1RP, vaddr); + break; + case OP_AT_S1E1WP: + fail = __kvm_at(OP_AT_S1E1WP, vaddr); + break; + } + + write_sysreg_s(host_pan, SYS_PSTATE_PAN); + + return fail; +} + /* * Return the PAR_EL1 value as the result of a valid translation. * @@ -105,6 +127,10 @@ skip_mmu_switch: isb(); switch (op) { + case OP_AT_S1E1RP: + case OP_AT_S1E1WP: + fail = at_s1e1p_fast(vcpu, op, vaddr); + break; case OP_AT_S1E1R: fail = __kvm_at(OP_AT_S1E1R, vaddr); break; |