KVM: arm64: nv: Add basic emulation of AT S1E1{R,W}P
authorMarc Zyngier <maz@kernel.org>
Sun, 14 Jul 2024 09:40:43 +0000 (10:40 +0100)
committerMarc Zyngier <maz@kernel.org>
Fri, 30 Aug 2024 11:04:20 +0000 (12:04 +0100)
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>
arch/arm64/kvm/at.c

index da378ad834cd8d5cbc536152152b6f002690edeb..92df948350e1896a1a15858ab093675253c79491 100644 (file)
@@ -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;