Provide arm64 implementation of user_access_region_active.

Check the status of PAN or SW PAN if needed.

Signed-off-by: Julien Thierry <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
---
 arch/arm64/include/asm/sysreg.h  |  2 ++
 arch/arm64/include/asm/uaccess.h | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 72dc4c0..f0b2f32 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -114,6 +114,8 @@
 #define SYS_DC_CSW                     sys_insn(1, 0, 7, 10, 2)
 #define SYS_DC_CISW                    sys_insn(1, 0, 7, 14, 2)

+#define SYS_PSTATE_PAN                 sys_reg(3, 0, 4, 2, 3)
+
 #define SYS_OSDTRRX_EL1                        sys_reg(2, 0, 0, 0, 2)
 #define SYS_MDCCINT_EL1                        sys_reg(2, 0, 0, 2, 0)
 #define SYS_MDSCR_EL1                  sys_reg(2, 0, 0, 2, 2)
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 6a70c75..1a8acc9 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -225,6 +225,18 @@ static inline void uaccess_enable_not_uao(void)
        __uaccess_enable(ARM64_ALT_PAN_NOT_UAO);
 }

+#define unsafe_user_region_active      uaccess_region_active
+static inline bool uaccess_region_active(void)
+{
+       if (system_uses_ttbr0_pan()) {
+               return read_sysreg(ttbr1_el1) & TTBR_ASID_MASK;
+       } else if (cpus_have_const_cap(ARM64_ALT_PAN_NOT_UAO) &&
+                  alternatives_applied) {
+               return !read_sysreg_s(SYS_PSTATE_PAN);
+       }
+       return false;
+}
+
 /*
  * Sanitise a uaccess pointer such that it becomes NULL if above the
  * current addr_limit.
--
1.9.1

Reply via email to