summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-10 10:14:52 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-10 10:14:52 -0800
commit296a7b7eb79246912de31ee799cb85220931231a (patch)
treeaa077c9bd7185eee43c0baaab3191eefecbf5b01 /arch
parent3ecc37918c80ffdbfa8f08d3e75a0a9fca1c1979 (diff)
parent73a0b6ee5d6269f92df43e1d09b3278a2886bf8a (diff)
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM fix from Russell King: "One further ARM fix for 6.1 from Wang Kefeng, fixing up the handling for kfence faults" * tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm: ARM: 9278/1: kfence: only handle translation faults
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mm/fault.c18
-rw-r--r--arch/arm/mm/fault.h9
2 files changed, 22 insertions, 5 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 46cccd6bf705..de988cba9a4b 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -105,6 +105,19 @@ static inline bool is_write_fault(unsigned int fsr)
return (fsr & FSR_WRITE) && !(fsr & FSR_CM);
}
+static inline bool is_translation_fault(unsigned int fsr)
+{
+ int fs = fsr_fs(fsr);
+#ifdef CONFIG_ARM_LPAE
+ if ((fs & FS_MMU_NOLL_MASK) == FS_TRANS_NOLL)
+ return true;
+#else
+ if (fs == FS_L1_TRANS || fs == FS_L2_TRANS)
+ return true;
+#endif
+ return false;
+}
+
static void die_kernel_fault(const char *msg, struct mm_struct *mm,
unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
@@ -140,7 +153,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
if (addr < PAGE_SIZE) {
msg = "NULL pointer dereference";
} else {
- if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
+ if (is_translation_fault(fsr) &&
+ kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
return;
msg = "paging request";
@@ -208,7 +222,7 @@ static inline bool is_permission_fault(unsigned int fsr)
{
int fs = fsr_fs(fsr);
#ifdef CONFIG_ARM_LPAE
- if ((fs & FS_PERM_NOLL_MASK) == FS_PERM_NOLL)
+ if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL)
return true;
#else
if (fs == FS_L1_PERM || fs == FS_L2_PERM)
diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
index 83b5ab32d7a4..54927ba1fa6e 100644
--- a/arch/arm/mm/fault.h
+++ b/arch/arm/mm/fault.h
@@ -14,8 +14,9 @@
#ifdef CONFIG_ARM_LPAE
#define FSR_FS_AEA 17
+#define FS_TRANS_NOLL 0x4
#define FS_PERM_NOLL 0xC
-#define FS_PERM_NOLL_MASK 0x3C
+#define FS_MMU_NOLL_MASK 0x3C
static inline int fsr_fs(unsigned int fsr)
{
@@ -23,8 +24,10 @@ static inline int fsr_fs(unsigned int fsr)
}
#else
#define FSR_FS_AEA 22
-#define FS_L1_PERM 0xD
-#define FS_L2_PERM 0xF
+#define FS_L1_TRANS 0x5
+#define FS_L2_TRANS 0x7
+#define FS_L1_PERM 0xD
+#define FS_L2_PERM 0xF
static inline int fsr_fs(unsigned int fsr)
{