From: Kefeng Wang <hidden> Date: 2021-06-02 06:53:51
Clean up the multiple goto statements and drops local variable
vm_fault_t fault, which will make the __do_page_fault() much
more readability.
No functional change.
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 34 +++++++++++++---------------------
1 file changed, 13 insertions(+), 21 deletions(-)
@@ -27,15 +27,23 @@#ifdef CONFIG_MMU/*-*Thisisusefultodumpoutthepagetablesassociatedwith-*'addr'inmm'mm'.+*Dumpoutthepagetablesassociatedwith'addr'inthecurrentlyactivemm*/-voidshow_pte(constchar*lvl,structmm_struct*mm,unsignedlongaddr)+voidshow_pte(constchar*lvl,unsignedlongaddr){pgd_t*pgd;--if(!mm)+structmm_struct*mm;++if(addr<TASK_SIZE){+mm=current->active_mm;+if(mm==&init_mm){+printk("%s[%08lx] user address but active_mm is swapper\n",+lvl,addr);+return;+}+}else{mm=&init_mm;+}printk("%spgd = %p\n",lvl,mm->pgd);pgd=pgd_offset(mm,addr);
@@ -122,7 +129,7 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,(addr<PAGE_SIZE)?"NULL pointer dereference":"paging request",addr);-show_pte(KERN_ALERT,mm,addr);+show_pte(KERN_ALERT,addr);die("Oops",regs,fsr);bust_spinlocks(0);do_exit(SIGKILL);
@@ -147,7 +154,7 @@ __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig,pr_err("8<--- cut here ---\n");pr_err("%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",tsk->comm,sig,addr,fsr);-show_pte(KERN_ERR,tsk->mm,addr);+show_pte(KERN_ERR,addr);show_regs(regs);}#endif
@@ -166,9 +173,6 @@ __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig,voiddo_bad_area(unsignedlongaddr,unsignedintfsr,structpt_regs*regs){-structtask_struct*tsk=current;-structmm_struct*mm=tsk->active_mm;-/**Ifweareinkernelmodeatthispoint,we*havenocontexttohandlethisfaultwith.
@@ -176,7 +180,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if(user_mode(regs))__do_user_fault(addr,fsr,SIGSEGV,SEGV_MAPERR,regs);else-__do_kernel_fault(mm,addr,fsr,regs);+__do_kernel_fault(addr,fsr,regs);}#ifdef CONFIG_MMU
@@ -336,7 +340,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)return0;no_context:-__do_kernel_fault(mm,addr,fsr,regs);+__do_kernel_fault(addr,fsr,regs);return0;}#else /* CONFIG_MMU */
@@ -503,7 +507,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)pr_alert("8<--- cut here ---\n");pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",inf->name,fsr,addr);-show_pte(KERN_ALERT,current->mm,addr);+show_pte(KERN_ALERT,addr);arm_notify_die("",regs,inf->sig,inf->code,(void__user*)addr,fsr,0);
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Kefeng Wang <hidden> Date: 2021-06-02 06:53:54
When user code execution with privilege mode, it will lead to
infinite loop in the page fault handler if ARM_LPAE enabled,
The issue could be reproduced with
"echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT"
Lets' fix it by adding the check in do_page_fault() and panic
when ARM_LPAE enabled.
Fixes: 1d4d37159d01 ("ARM: 8235/1: Support for the PXN CPU feature on ARMv7")
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
@@ -257,8 +257,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)vm_flags=VM_WRITE;}-if(fsr&FSR_LNX_PF)+if(fsr&FSR_LNX_PF){vm_flags=VM_EXEC;+#ifdef CONFIG_ARM_LPAE+if(addr&&addr<TASK_SIZE&&!user_mode(regs))+die_kernel_fault("execution of user memory",+addr,fsr,regs);+#endif+}perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS,1,regs,addr);
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Kefeng Wang <hidden> Date: 2021-06-02 06:54:01
The __do_page_fault() won't use task_struct argument, kill it
and also use current->mm directly in do_page_fault().
No functional change.
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
@@ -231,8 +230,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,staticint__kprobesdo_page_fault(unsignedlongaddr,unsignedintfsr,structpt_regs*regs){-structtask_struct*tsk;-structmm_struct*mm;+structmm_struct*mm=current->mm;intsig,code;vm_fault_tfault;unsignedintflags=FAULT_FLAG_DEFAULT;
@@ -240,8 +238,6 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if(kprobe_page_fault(regs,fsr))return0;-tsk=current;-mm=tsk->mm;/* Enable interrupts if they were enabled in the parent context. */if(interrupts_enabled(regs))
@@ -285,7 +281,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)#endif}-fault=__do_page_fault(mm,addr,fsr,flags,tsk,regs);+fault=__do_page_fault(mm,addr,fsr,flags,regs);/* If we need to retry but a fatal signal is pending, handle the*signalfirst.Wedonotneedtoreleasethemmap_lockbecause
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Kefeng Wang <hidden> Date: 2021-06-02 06:54:02
Now the show_pts() will dump the virtual (hashed) address of page
table base, it is useless, let's print the page table base pointer
as a physical address for debug.
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Kefeng Wang <hidden> Date: 2021-06-02 06:54:10
Provide die_kernel_fault() helper to do the kernel fault reporting,
which with msg argument, it could report different message in different
scenes, and the later patch "ARM: mm: Fix PXN process with LPAE feature"
will use it.
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
From: Kefeng Wang <hidden> Date: 2021-06-02 06:54:11
Now the write fault check in do_page_fault() and access_error() twice,
we can cleanup access_error(), and make the fault check and vma flags set
into do_page_fault() directly, then pass the vma flags to __do_page_fault.
No functional change.
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 38 ++++++++++++++------------------------
1 file changed, 14 insertions(+), 24 deletions(-)
@@ -183,26 +183,9 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)#define VM_FAULT_BADMAP 0x010000#define VM_FAULT_BADACCESS 0x020000-/*-*CheckthatthepermissionsontheVMAallowforthefaultwhichoccurred.-*Ifweencounteredawritefault,wemusthavewritepermission,otherwise-*weallowanypermission.-*/-staticinlineboolaccess_error(unsignedintfsr,structvm_area_struct*vma)-{-unsignedintmask=VM_ACCESS_FLAGS;--if((fsr&FSR_WRITE)&&!(fsr&FSR_CM))-mask=VM_WRITE;-if(fsr&FSR_LNX_PF)-mask=VM_EXEC;--returnvma->vm_flags&mask?false:true;-}-staticvm_fault_t__kprobes-__do_page_fault(structmm_struct*mm,unsignedlongaddr,unsignedintfsr,-unsignedintflags,structpt_regs*regs)+__do_page_fault(structmm_struct*mm,unsignedlongaddr,unsignedintflags,+unsignedlongvma_flags,structpt_regs*regs){structvm_area_struct*vma=find_vma(mm,addr);if(unlikely(!vma))
@@ -218,10 +201,10 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,}/*-*Ok,wehaveagoodvm_areaforthis-*memoryaccess,sowecanhandleit.+*ok,wehaveagoodvm_areaforthismemoryaccess,checkthe+*permissionsontheVMAallowforthefaultwhichoccurred.*/-if(access_error(fsr,vma))+if(!(vma->vm_flags&vma_flags))returnVM_FAULT_BADACCESS;returnhandle_mm_fault(vma,addr&PAGE_MASK,flags,regs);
@@ -234,6 +217,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)intsig,code;vm_fault_tfault;unsignedintflags=FAULT_FLAG_DEFAULT;+unsignedlongvm_flags=VM_ACCESS_FLAGS;if(kprobe_page_fault(regs,fsr))return0;
@@ -252,8 +236,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if(user_mode(regs))flags|=FAULT_FLAG_USER;-if((fsr&FSR_WRITE)&&!(fsr&FSR_CM))++if((fsr&FSR_WRITE)&&!(fsr&FSR_CM)){flags|=FAULT_FLAG_WRITE;+vm_flags=VM_WRITE;+}++if(fsr&FSR_LNX_PF)+vm_flags=VM_EXEC;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS,1,regs,addr);
@@ -281,7 +271,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)#endif}-fault=__do_page_fault(mm,addr,fsr,flags,regs);+fault=__do_page_fault(mm,addr,flags,vm_flags,regs);/* If we need to retry but a fatal signal is pending, handle the*signalfirst.Wedonotneedtoreleasethemmap_lockbecause
--
2.26.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:29:37
Hi,
On Wed, Jun 02, 2021 at 03:02:40PM +0800, Kefeng Wang wrote:
Clean up the multiple goto statements and drops local variable
vm_fault_t fault, which will make the __do_page_fault() much
more readability.
No functional change.
Signed-off-by: Kefeng Wang <redacted>
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:31:33
Hi,
On Wed, Jun 02, 2021 at 03:02:41PM +0800, Kefeng Wang wrote:
The __do_page_fault() won't use task_struct argument, kill it
and also use current->mm directly in do_page_fault().
No functional change.
Signed-off-by: Kefeng Wang <redacted>
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:39:17
Hi,
On Wed, Jun 02, 2021 at 03:02:42PM +0800, Kefeng Wang wrote:
Now the write fault check in do_page_fault() and access_error() twice,
we can cleanup access_error(), and make the fault check and vma flags set
into do_page_fault() directly, then pass the vma flags to __do_page_fault.
No functional change.
Signed-off-by: Kefeng Wang <redacted>
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:45:05
On Wed, Jun 02, 2021 at 03:02:43PM +0800, Kefeng Wang wrote:
Like commit 67ce16ec15ce ("arm64: mm: print out correct page table entries")
does, drop the struct mm_struct argument of show_pte(), print the tables
based on the faulting address.
Signed-off-by: Kefeng Wang <redacted>
This can be misleading on 32-bit ARM.
The effective page tables for each thread are the threads *own* page
tables. There is no hardware magic for addresses above PAGE_OFFSET being
directed to the init_mm page tables.
So, when we hit a fault in kernel space, we need to be printing the
currently in-use page tables associated with the running thread.
Hence:
/*
- * This is useful to dump out the page tables associated with
- * 'addr' in mm 'mm'.
+ * Dump out the page tables associated with 'addr' in the currently active mm
*/
-void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
+void show_pte(const char *lvl, unsigned long addr)
{
pgd_t *pgd;
-
- if (!mm)
+ struct mm_struct *mm;
+
+ if (addr < TASK_SIZE) {
+ mm = current->active_mm;
+ if (mm == &init_mm) {
+ printk("%s[%08lx] user address but active_mm is swapper\n",
+ lvl, addr);
+ return;
+ }
+ } else {
mm = &init_mm;
+ }
is incorrect here.
It's completely fine for architectures where kernel accesses always go
to the init_mm page tables, but for 32-bit ARM that is not the case.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:49:02
Hi,
On Wed, Jun 02, 2021 at 03:02:44PM +0800, Kefeng Wang wrote:
Now the show_pts() will dump the virtual (hashed) address of page
table base, it is useless, let's print the page table base pointer
as a physical address for debug.
I think we could probably get rid of this line - I think the last time
the PGD address was of use was a very long time ago.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:50:39
Hi,
On Wed, Jun 02, 2021 at 03:02:45PM +0800, Kefeng Wang wrote:
Provide die_kernel_fault() helper to do the kernel fault reporting,
which with msg argument, it could report different message in different
scenes, and the later patch "ARM: mm: Fix PXN process with LPAE feature"
will use it.
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 10:53:02
Hi,
On Wed, Jun 02, 2021 at 03:02:46PM +0800, Kefeng Wang wrote:
quoted hunk
When user code execution with privilege mode, it will lead to
infinite loop in the page fault handler if ARM_LPAE enabled,
The issue could be reproduced with
"echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT"
Lets' fix it by adding the check in do_page_fault() and panic
when ARM_LPAE enabled.
Fixes: 1d4d37159d01 ("ARM: 8235/1: Support for the PXN CPU feature on ARMv7")
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
@@ -257,8 +257,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)vm_flags=VM_WRITE;}-if(fsr&FSR_LNX_PF)+if(fsr&FSR_LNX_PF){vm_flags=VM_EXEC;+#ifdef CONFIG_ARM_LPAE+if(addr&&addr<TASK_SIZE&&!user_mode(regs))+die_kernel_fault("execution of user memory",+addr,fsr,regs);+#endif+}
Do we need to do this test here?
Also, is this really LPAE specific? We have similar protection on 32-bit
ARM using domains to disable access to userspace except when the user
accessors are being used, so I would expect kernel-mode execution to
also cause a fault there.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Kefeng Wang <hidden> Date: 2021-06-02 11:25:50
On 2021/6/2 18:44, Russell King (Oracle) wrote:
On Wed, Jun 02, 2021 at 03:02:43PM +0800, Kefeng Wang wrote:
quoted
Like commit 67ce16ec15ce ("arm64: mm: print out correct page table entries")
does, drop the struct mm_struct argument of show_pte(), print the tables
based on the faulting address.
Signed-off-by: Kefeng Wang <redacted>
This can be misleading on 32-bit ARM.
The effective page tables for each thread are the threads *own* page
tables. There is no hardware magic for addresses above PAGE_OFFSET being
directed to the init_mm page tables.
So, when we hit a fault in kernel space, we need to be printing the
currently in-use page tables associated with the running thread.
Hence:
quoted
/*
- * This is useful to dump out the page tables associated with
- * 'addr' in mm 'mm'.
+ * Dump out the page tables associated with 'addr' in the currently active mm
*/
-void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
+void show_pte(const char *lvl, unsigned long addr)
{
pgd_t *pgd;
-
- if (!mm)
+ struct mm_struct *mm;
+
+ if (addr < TASK_SIZE) {
+ mm = current->active_mm;
+ if (mm == &init_mm) {
+ printk("%s[%08lx] user address but active_mm is swapper\n",
+ lvl, addr);
+ return;
+ }
+ } else {
mm = &init_mm;
+ }
is incorrect here.
It's completely fine for architectures where kernel accesses always go
to the init_mm page tables, but for 32-bit ARM that is not the case.
From: Kefeng Wang <hidden> Date: 2021-06-02 11:26:46
On 2021/6/2 18:47, Russell King (Oracle) wrote:
Hi,
On Wed, Jun 02, 2021 at 03:02:44PM +0800, Kefeng Wang wrote:
quoted
Now the show_pts() will dump the virtual (hashed) address of page
table base, it is useless, let's print the page table base pointer
as a physical address for debug.
I think we could probably get rid of this line - I think the last time
the PGD address was of use was a very long time ago.
From: Kefeng Wang <hidden> Date: 2021-06-02 15:13:21
On 2021/6/2 18:52, Russell King (Oracle) wrote:
Hi,
On Wed, Jun 02, 2021 at 03:02:46PM +0800, Kefeng Wang wrote:
quoted
When user code execution with privilege mode, it will lead to
infinite loop in the page fault handler if ARM_LPAE enabled,
The issue could be reproduced with
"echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT"
Lets' fix it by adding the check in do_page_fault() and panic
when ARM_LPAE enabled.
Fixes: 1d4d37159d01 ("ARM: 8235/1: Support for the PXN CPU feature on ARMv7")
Signed-off-by: Kefeng Wang <redacted>
---
arch/arm/mm/fault.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
@@ -257,8 +257,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)vm_flags=VM_WRITE;}-if(fsr&FSR_LNX_PF)+if(fsr&FSR_LNX_PF){vm_flags=VM_EXEC;+#ifdef CONFIG_ARM_LPAE+if(addr&&addr<TASK_SIZE&&!user_mode(regs))+die_kernel_fault("execution of user memory",+addr,fsr,regs);+#endif+}
Do we need to do this test here?
Also, is this really LPAE specific? We have similar protection on 32-bit
ARM using domains to disable access to userspace except when the user
accessors are being used, so I would expect kernel-mode execution to
also cause a fault there.
IFSR format when using the Short-descriptor translation table format
Domain fault 01001 First level 01011 Second level
Permission fault 01101 First level 01111 Second level
IFSR format when using the Long-descriptor translation table format
0011LL Permission fault. LL bits indicate levelb.
After check the ARM spec, I think for the permission fault, we should panic
with or without LPAE, will change to
@@ -257,8 +257,11 @@ do_page_fault(unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
vm_flags = VM_WRITE;
}
- if (fsr & FSR_LNX_PF)
+ if (fsr & FSR_LNX_PF) {
vm_flags = VM_EXEC;
+ if (!user_mode(regs))
+ die_kernel_fault("execution of memory", addr,
fsr, regs);
+ }
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
If no object, I will send all patches with updates to patch system,
thanks.
From: "Russell King (Oracle)" <linux@armlinux.org.uk> Date: 2021-06-02 15:58:54
On Wed, Jun 02, 2021 at 11:13:14PM +0800, Kefeng Wang wrote:
IFSR format when using the Short-descriptor translation table format
Domain fault 01001 First level 01011 Second level
Permission fault 01101 First level 01111 Second level
IFSR format when using the Long-descriptor translation table format
0011LL Permission fault. LL bits indicate levelb.
After check the ARM spec, I think for the permission fault, we should panic
with or without LPAE, will change to
As I explained in one of the previous patches, the page tables that get
used for mapping kernel space are the _tasks_ own page tables. Any new
kernel mappings are lazily copied to the task page tables - such as
when a module is loaded.
The first time we touch a page, we could end up with a page translation
fault. This will call do_page_fault(), and so with your proposal,
loading a module will potentially cause a kernel panic in this case,
probably leading to systems that panic early during userspace boot.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Kefeng Wang <hidden> Date: 2021-06-03 09:38:56
On 2021/6/2 23:58, Russell King (Oracle) wrote:
On Wed, Jun 02, 2021 at 11:13:14PM +0800, Kefeng Wang wrote:
quoted
IFSR format when using the Short-descriptor translation table format
Domain fault 01001 First level 01011 Second level
Permission fault 01101 First level 01111 Second level
IFSR format when using the Long-descriptor translation table format
0011LL Permission fault. LL bits indicate levelb.
After check the ARM spec, I think for the permission fault, we should panic
with or without LPAE, will change to
As I explained in one of the previous patches, the page tables that get
used for mapping kernel space are the _tasks_ own page tables. Any new
kernel mappings are lazily copied to the task page tables - such as
when a module is loaded.
The first time we touch a page, we could end up with a page translation
fault. This will call do_page_fault(), and so with your proposal,
loading a module will potentially cause a kernel panic in this case,
probably leading to systems that panic early during userspace boot.
Could we add some FSR_FS check, only panic when the permission fault, eg,
+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)
+ return true;
+#else
+ if (fs == FS_L1_PERM || fs == )
+ return true;
+#endif
+ return false;
+}
+
static int __kprobes
do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
@@ -255,8 +268,7 @@ do_page_fault(unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
if (fsr & FSR_LNX_PF) {
vm_flags = VM_EXEC;
-
- if (!user_mode(regs))
+ if (is_permission_fault && !user_mode(regs))
die_kernel_fault("execution of memory",
mm, addr, fsr, regs);
}
From: Kefeng Wang <hidden> Date: 2021-06-07 08:33:00
Hi Russell, any comments, thanks.
On 2021/6/3 17:38, Kefeng Wang wrote:
quoted hunk
On 2021/6/2 23:58, Russell King (Oracle) wrote:
quoted
On Wed, Jun 02, 2021 at 11:13:14PM +0800, Kefeng Wang wrote:
quoted
IFSR format when using the Short-descriptor translation table format
Domain fault 01001 First level 01011
Second level
Permission fault 01101 First level 01111 Second level
IFSR format when using the Long-descriptor translation table format
0011LL Permission fault. LL bits indicate levelb.
After check the ARM spec, I think for the permission fault, we
should panic
with or without LPAE, will change to
As I explained in one of the previous patches, the page tables that get
used for mapping kernel space are the _tasks_ own page tables. Any new
kernel mappings are lazily copied to the task page tables - such as
when a module is loaded.
The first time we touch a page, we could end up with a page translation
fault. This will call do_page_fault(), and so with your proposal,
loading a module will potentially cause a kernel panic in this case,
probably leading to systems that panic early during userspace boot.
Could we add some FSR_FS check, only panic when the permission fault,
eg,
+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)
+ return true;
+#else
+ if (fs == FS_L1_PERM || fs == FS_L2_PERM )
+ return true;
+#endif
+ return false;
+}
+
static int __kprobes
do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs
*regs)
{
@@ -255,8 +268,7 @@ do_page_fault(unsigned long addr, unsigned int
fsr, struct pt_regs *regs)
if (fsr & FSR_LNX_PF) {
vm_flags = VM_EXEC;
-
- if (!user_mode(regs))
+ if (is_permission_fault && !user_mode(regs))
die_kernel_fault("execution of memory",
mm, addr, fsr, regs);
}