KVM: arm64: Move VHE direct sysreg accessors into kvm_host.h
authorMarc Zyngier <maz@kernel.org>
Wed, 14 Oct 2020 18:36:11 +0000 (19:36 +0100)
committerMarc Zyngier <maz@kernel.org>
Tue, 10 Nov 2020 08:34:25 +0000 (08:34 +0000)
As we are about to need to access system registers from the HYP
code based on their internal encoding, move the direct sysreg
accessors to a common include file, with a VHE-specific guard.

No functionnal change.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/sys_regs.c

index 7991a1c..0672b3d 100644 (file)
@@ -439,6 +439,97 @@ struct kvm_vcpu_arch {
 u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
 void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
 
+static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
+{
+       /*
+        * *** VHE ONLY ***
+        *
+        * System registers listed in the switch are not saved on every
+        * exit from the guest but are only saved on vcpu_put.
+        *
+        * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
+        * should never be listed below, because the guest cannot modify its
+        * own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's
+        * thread when emulating cross-VCPU communication.
+        */
+       if (!has_vhe())
+               return false;
+
+       switch (reg) {
+       case CSSELR_EL1:        *val = read_sysreg_s(SYS_CSSELR_EL1);   break;
+       case SCTLR_EL1:         *val = read_sysreg_s(SYS_SCTLR_EL12);   break;
+       case CPACR_EL1:         *val = read_sysreg_s(SYS_CPACR_EL12);   break;
+       case TTBR0_EL1:         *val = read_sysreg_s(SYS_TTBR0_EL12);   break;
+       case TTBR1_EL1:         *val = read_sysreg_s(SYS_TTBR1_EL12);   break;
+       case TCR_EL1:           *val = read_sysreg_s(SYS_TCR_EL12);     break;
+       case ESR_EL1:           *val = read_sysreg_s(SYS_ESR_EL12);     break;
+       case AFSR0_EL1:         *val = read_sysreg_s(SYS_AFSR0_EL12);   break;
+       case AFSR1_EL1:         *val = read_sysreg_s(SYS_AFSR1_EL12);   break;
+       case FAR_EL1:           *val = read_sysreg_s(SYS_FAR_EL12);     break;
+       case MAIR_EL1:          *val = read_sysreg_s(SYS_MAIR_EL12);    break;
+       case VBAR_EL1:          *val = read_sysreg_s(SYS_VBAR_EL12);    break;
+       case CONTEXTIDR_EL1:    *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break;
+       case TPIDR_EL0:         *val = read_sysreg_s(SYS_TPIDR_EL0);    break;
+       case TPIDRRO_EL0:       *val = read_sysreg_s(SYS_TPIDRRO_EL0);  break;
+       case TPIDR_EL1:         *val = read_sysreg_s(SYS_TPIDR_EL1);    break;
+       case AMAIR_EL1:         *val = read_sysreg_s(SYS_AMAIR_EL12);   break;
+       case CNTKCTL_EL1:       *val = read_sysreg_s(SYS_CNTKCTL_EL12); break;
+       case ELR_EL1:           *val = read_sysreg_s(SYS_ELR_EL12);     break;
+       case PAR_EL1:           *val = read_sysreg_par();               break;
+       case DACR32_EL2:        *val = read_sysreg_s(SYS_DACR32_EL2);   break;
+       case IFSR32_EL2:        *val = read_sysreg_s(SYS_IFSR32_EL2);   break;
+       case DBGVCR32_EL2:      *val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
+       default:                return false;
+       }
+
+       return true;
+}
+
+static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
+{
+       /*
+        * *** VHE ONLY ***
+        *
+        * System registers listed in the switch are not restored on every
+        * entry to the guest but are only restored on vcpu_load.
+        *
+        * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
+        * should never be listed below, because the MPIDR should only be set
+        * once, before running the VCPU, and never changed later.
+        */
+       if (!has_vhe())
+               return false;
+
+       switch (reg) {
+       case CSSELR_EL1:        write_sysreg_s(val, SYS_CSSELR_EL1);    break;
+       case SCTLR_EL1:         write_sysreg_s(val, SYS_SCTLR_EL12);    break;
+       case CPACR_EL1:         write_sysreg_s(val, SYS_CPACR_EL12);    break;
+       case TTBR0_EL1:         write_sysreg_s(val, SYS_TTBR0_EL12);    break;
+       case TTBR1_EL1:         write_sysreg_s(val, SYS_TTBR1_EL12);    break;
+       case TCR_EL1:           write_sysreg_s(val, SYS_TCR_EL12);      break;
+       case ESR_EL1:           write_sysreg_s(val, SYS_ESR_EL12);      break;
+       case AFSR0_EL1:         write_sysreg_s(val, SYS_AFSR0_EL12);    break;
+       case AFSR1_EL1:         write_sysreg_s(val, SYS_AFSR1_EL12);    break;
+       case FAR_EL1:           write_sysreg_s(val, SYS_FAR_EL12);      break;
+       case MAIR_EL1:          write_sysreg_s(val, SYS_MAIR_EL12);     break;
+       case VBAR_EL1:          write_sysreg_s(val, SYS_VBAR_EL12);     break;
+       case CONTEXTIDR_EL1:    write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break;
+       case TPIDR_EL0:         write_sysreg_s(val, SYS_TPIDR_EL0);     break;
+       case TPIDRRO_EL0:       write_sysreg_s(val, SYS_TPIDRRO_EL0);   break;
+       case TPIDR_EL1:         write_sysreg_s(val, SYS_TPIDR_EL1);     break;
+       case AMAIR_EL1:         write_sysreg_s(val, SYS_AMAIR_EL12);    break;
+       case CNTKCTL_EL1:       write_sysreg_s(val, SYS_CNTKCTL_EL12);  break;
+       case ELR_EL1:           write_sysreg_s(val, SYS_ELR_EL12);      break;
+       case PAR_EL1:           write_sysreg_s(val, SYS_PAR_EL1);       break;
+       case DACR32_EL2:        write_sysreg_s(val, SYS_DACR32_EL2);    break;
+       case IFSR32_EL2:        write_sysreg_s(val, SYS_IFSR32_EL2);    break;
+       case DBGVCR32_EL2:      write_sysreg_s(val, SYS_DBGVCR32_EL2);  break;
+       default:                return false;
+       }
+
+       return true;
+}
+
 /*
  * CP14 and CP15 live in the same array, as they are backed by the
  * same system registers.
index 6a6f062..26c7c25 100644 (file)
@@ -64,87 +64,6 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu,
        return false;
 }
 
-static bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
-{
-       /*
-        * System registers listed in the switch are not saved on every
-        * exit from the guest but are only saved on vcpu_put.
-        *
-        * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
-        * should never be listed below, because the guest cannot modify its
-        * own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's
-        * thread when emulating cross-VCPU communication.
-        */
-       switch (reg) {
-       case CSSELR_EL1:        *val = read_sysreg_s(SYS_CSSELR_EL1);   break;
-       case SCTLR_EL1:         *val = read_sysreg_s(SYS_SCTLR_EL12);   break;
-       case CPACR_EL1:         *val = read_sysreg_s(SYS_CPACR_EL12);   break;
-       case TTBR0_EL1:         *val = read_sysreg_s(SYS_TTBR0_EL12);   break;
-       case TTBR1_EL1:         *val = read_sysreg_s(SYS_TTBR1_EL12);   break;
-       case TCR_EL1:           *val = read_sysreg_s(SYS_TCR_EL12);     break;
-       case ESR_EL1:           *val = read_sysreg_s(SYS_ESR_EL12);     break;
-       case AFSR0_EL1:         *val = read_sysreg_s(SYS_AFSR0_EL12);   break;
-       case AFSR1_EL1:         *val = read_sysreg_s(SYS_AFSR1_EL12);   break;
-       case FAR_EL1:           *val = read_sysreg_s(SYS_FAR_EL12);     break;
-       case MAIR_EL1:          *val = read_sysreg_s(SYS_MAIR_EL12);    break;
-       case VBAR_EL1:          *val = read_sysreg_s(SYS_VBAR_EL12);    break;
-       case CONTEXTIDR_EL1:    *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break;
-       case TPIDR_EL0:         *val = read_sysreg_s(SYS_TPIDR_EL0);    break;
-       case TPIDRRO_EL0:       *val = read_sysreg_s(SYS_TPIDRRO_EL0);  break;
-       case TPIDR_EL1:         *val = read_sysreg_s(SYS_TPIDR_EL1);    break;
-       case AMAIR_EL1:         *val = read_sysreg_s(SYS_AMAIR_EL12);   break;
-       case CNTKCTL_EL1:       *val = read_sysreg_s(SYS_CNTKCTL_EL12); break;
-       case ELR_EL1:           *val = read_sysreg_s(SYS_ELR_EL12);     break;
-       case PAR_EL1:           *val = read_sysreg_par();               break;
-       case DACR32_EL2:        *val = read_sysreg_s(SYS_DACR32_EL2);   break;
-       case IFSR32_EL2:        *val = read_sysreg_s(SYS_IFSR32_EL2);   break;
-       case DBGVCR32_EL2:      *val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
-       default:                return false;
-       }
-
-       return true;
-}
-
-static bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
-{
-       /*
-        * System registers listed in the switch are not restored on every
-        * entry to the guest but are only restored on vcpu_load.
-        *
-        * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
-        * should never be listed below, because the MPIDR should only be set
-        * once, before running the VCPU, and never changed later.
-        */
-       switch (reg) {
-       case CSSELR_EL1:        write_sysreg_s(val, SYS_CSSELR_EL1);    break;
-       case SCTLR_EL1:         write_sysreg_s(val, SYS_SCTLR_EL12);    break;
-       case CPACR_EL1:         write_sysreg_s(val, SYS_CPACR_EL12);    break;
-       case TTBR0_EL1:         write_sysreg_s(val, SYS_TTBR0_EL12);    break;
-       case TTBR1_EL1:         write_sysreg_s(val, SYS_TTBR1_EL12);    break;
-       case TCR_EL1:           write_sysreg_s(val, SYS_TCR_EL12);      break;
-       case ESR_EL1:           write_sysreg_s(val, SYS_ESR_EL12);      break;
-       case AFSR0_EL1:         write_sysreg_s(val, SYS_AFSR0_EL12);    break;
-       case AFSR1_EL1:         write_sysreg_s(val, SYS_AFSR1_EL12);    break;
-       case FAR_EL1:           write_sysreg_s(val, SYS_FAR_EL12);      break;
-       case MAIR_EL1:          write_sysreg_s(val, SYS_MAIR_EL12);     break;
-       case VBAR_EL1:          write_sysreg_s(val, SYS_VBAR_EL12);     break;
-       case CONTEXTIDR_EL1:    write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break;
-       case TPIDR_EL0:         write_sysreg_s(val, SYS_TPIDR_EL0);     break;
-       case TPIDRRO_EL0:       write_sysreg_s(val, SYS_TPIDRRO_EL0);   break;
-       case TPIDR_EL1:         write_sysreg_s(val, SYS_TPIDR_EL1);     break;
-       case AMAIR_EL1:         write_sysreg_s(val, SYS_AMAIR_EL12);    break;
-       case CNTKCTL_EL1:       write_sysreg_s(val, SYS_CNTKCTL_EL12);  break;
-       case ELR_EL1:           write_sysreg_s(val, SYS_ELR_EL12);      break;
-       case PAR_EL1:           write_sysreg_s(val, SYS_PAR_EL1);       break;
-       case DACR32_EL2:        write_sysreg_s(val, SYS_DACR32_EL2);    break;
-       case IFSR32_EL2:        write_sysreg_s(val, SYS_IFSR32_EL2);    break;
-       case DBGVCR32_EL2:      write_sysreg_s(val, SYS_DBGVCR32_EL2);  break;
-       default:                return false;
-       }
-
-       return true;
-}
-
 u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
 {
        u64 val = 0x8badf00d8badf00d;