Define the new system registers that POE introduces and context switch them.

Signed-off-by: Joey Gouly <joey.go...@arm.com>
Cc: Marc Zyngier <m...@kernel.org>
Cc: Oliver Upton <oliver.up...@linux.dev>
Cc: Catalin Marinas <catalin.mari...@arm.com>
Cc: Will Deacon <w...@kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h           |  4 ++--
 arch/arm64/include/asm/kvm_host.h          |  4 ++++
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 10 ++++++++++
 arch/arm64/kvm/sys_regs.c                  |  2 ++
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 5882b2415596..4022e69e17fd 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -344,14 +344,14 @@
  */
 #define __HFGRTR_EL2_RES0      (GENMASK(63, 56) | GENMASK(53, 51))
 #define __HFGRTR_EL2_MASK      GENMASK(49, 0)
-#define __HFGRTR_EL2_nMASK     (GENMASK(55, 54) | BIT(50))
+#define __HFGRTR_EL2_nMASK     (GENMASK(60, 59) | GENMASK(55, 54) | BIT(50))
 
 #define __HFGWTR_EL2_RES0      (GENMASK(63, 56) | GENMASK(53, 51) |    \
                                 BIT(46) | BIT(42) | BIT(40) | BIT(28) | \
                                 GENMASK(26, 25) | BIT(21) | BIT(18) |  \
                                 GENMASK(15, 14) | GENMASK(10, 9) | BIT(2))
 #define __HFGWTR_EL2_MASK      GENMASK(49, 0)
-#define __HFGWTR_EL2_nMASK     (GENMASK(55, 54) | BIT(50))
+#define __HFGWTR_EL2_nMASK     (GENMASK(60, 59) | GENMASK(55, 54) | BIT(50))
 
 #define __HFGITR_EL2_RES0      GENMASK(63, 57)
 #define __HFGITR_EL2_MASK      GENMASK(54, 0)
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index af06ccb7ee34..205653bc5c2c 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -365,6 +365,10 @@ enum vcpu_sysreg {
        PIR_EL1,       /* Permission Indirection Register 1 (EL1) */
        PIRE0_EL1,     /*  Permission Indirection Register 0 (EL1) */
 
+       /* Permission Overlay Extension registers */
+       POR_EL1,        /* Permission Overlay Register 1 (EL1) */
+       POR_EL0,        /* Permission Overlay Register 0 (EL0) */
+
        /* 32bit specific registers. */
        DACR32_EL2,     /* Domain Access Control Register */
        IFSR32_EL2,     /* Instruction Fault Status Register */
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h 
b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index bb6b571ec627..22f07ee43e7e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -19,6 +19,9 @@
 static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
 {
        ctxt_sys_reg(ctxt, MDSCR_EL1)   = read_sysreg(mdscr_el1);
+
+       if (system_supports_poe())
+               ctxt_sys_reg(ctxt, POR_EL0)     = read_sysreg_s(SYS_POR_EL0);
 }
 
 static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
@@ -59,6 +62,8 @@ static inline void __sysreg_save_el1_state(struct 
kvm_cpu_context *ctxt)
                ctxt_sys_reg(ctxt, PIR_EL1)     = read_sysreg_el1(SYS_PIR);
                ctxt_sys_reg(ctxt, PIRE0_EL1)   = read_sysreg_el1(SYS_PIRE0);
        }
+       if (system_supports_poe())
+               ctxt_sys_reg(ctxt, POR_EL1)     = read_sysreg_el1(SYS_POR);
        ctxt_sys_reg(ctxt, PAR_EL1)     = read_sysreg_par();
        ctxt_sys_reg(ctxt, TPIDR_EL1)   = read_sysreg(tpidr_el1);
 
@@ -89,6 +94,9 @@ static inline void __sysreg_save_el2_return_state(struct 
kvm_cpu_context *ctxt)
 static inline void __sysreg_restore_common_state(struct kvm_cpu_context *ctxt)
 {
        write_sysreg(ctxt_sys_reg(ctxt, MDSCR_EL1),  mdscr_el1);
+
+       if (system_supports_poe())
+               write_sysreg_s(ctxt_sys_reg(ctxt, POR_EL0),     SYS_POR_EL0);
 }
 
 static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt)
@@ -135,6 +143,8 @@ static inline void __sysreg_restore_el1_state(struct 
kvm_cpu_context *ctxt)
                write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1),   SYS_PIR);
                write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0);
        }
+       if (system_supports_poe())
+               write_sysreg_el1(ctxt_sys_reg(ctxt, POR_EL1),   SYS_POR);
        write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1),       par_el1);
        write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1),     tpidr_el1);
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index e92ec810d449..7d66cc7e104c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2124,6 +2124,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
        { SYS_DESC(SYS_PIRE0_EL1), access_vm_reg, reset_unknown, PIRE0_EL1 },
        { SYS_DESC(SYS_PIR_EL1), access_vm_reg, reset_unknown, PIR_EL1 },
+       { SYS_DESC(SYS_POR_EL1), NULL, reset_unknown, POR_EL1 },
        { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
 
        { SYS_DESC(SYS_LORSA_EL1), trap_loregion },
@@ -2203,6 +2204,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { PMU_SYS_REG(PMOVSSET_EL0),
          .access = access_pmovs, .reg = PMOVSSET_EL0 },
 
+       { SYS_DESC(SYS_POR_EL0), NULL, reset_unknown, POR_EL0 },
        { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
        { SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
        { SYS_DESC(SYS_TPIDR2_EL0), undef_access },
-- 
2.25.1

Reply via email to