|
@@ -206,6 +206,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|
int is_write = 0;
|
|
int is_write = 0;
|
|
int trap = TRAP(regs);
|
|
int trap = TRAP(regs);
|
|
int is_exec = trap == 0x400;
|
|
int is_exec = trap == 0x400;
|
|
|
|
+ int is_user = user_mode(regs);
|
|
int fault;
|
|
int fault;
|
|
int rc = 0, store_update_sp = 0;
|
|
int rc = 0, store_update_sp = 0;
|
|
|
|
|
|
@@ -247,7 +248,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|
* The kernel should never take an execute fault nor should it
|
|
* The kernel should never take an execute fault nor should it
|
|
* take a page fault to a kernel address.
|
|
* take a page fault to a kernel address.
|
|
*/
|
|
*/
|
|
- if (!user_mode(regs) && (is_exec || (address >= TASK_SIZE))) {
|
|
|
|
|
|
+ if (!is_user && (is_exec || (address >= TASK_SIZE))) {
|
|
rc = SIGSEGV;
|
|
rc = SIGSEGV;
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
@@ -266,7 +267,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|
local_irq_enable();
|
|
local_irq_enable();
|
|
|
|
|
|
if (faulthandler_disabled() || mm == NULL) {
|
|
if (faulthandler_disabled() || mm == NULL) {
|
|
- if (!user_mode(regs)) {
|
|
|
|
|
|
+ if (!is_user) {
|
|
rc = SIGSEGV;
|
|
rc = SIGSEGV;
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
@@ -287,10 +288,10 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|
* can result in fault, which will cause a deadlock when called with
|
|
* can result in fault, which will cause a deadlock when called with
|
|
* mmap_sem held
|
|
* mmap_sem held
|
|
*/
|
|
*/
|
|
- if (is_write && user_mode(regs))
|
|
|
|
|
|
+ if (is_write && is_user)
|
|
store_update_sp = store_updates_sp(regs);
|
|
store_update_sp = store_updates_sp(regs);
|
|
|
|
|
|
- if (user_mode(regs))
|
|
|
|
|
|
+ if (is_user)
|
|
flags |= FAULT_FLAG_USER;
|
|
flags |= FAULT_FLAG_USER;
|
|
|
|
|
|
/* When running in the kernel we expect faults to occur only to
|
|
/* When running in the kernel we expect faults to occur only to
|
|
@@ -309,7 +310,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|
* thus avoiding the deadlock.
|
|
* thus avoiding the deadlock.
|
|
*/
|
|
*/
|
|
if (!down_read_trylock(&mm->mmap_sem)) {
|
|
if (!down_read_trylock(&mm->mmap_sem)) {
|
|
- if (!user_mode(regs) && !search_exception_tables(regs->nip))
|
|
|
|
|
|
+ if (!is_user && !search_exception_tables(regs->nip))
|
|
goto bad_area_nosemaphore;
|
|
goto bad_area_nosemaphore;
|
|
|
|
|
|
retry:
|
|
retry:
|
|
@@ -509,7 +510,7 @@ bad_area:
|
|
|
|
|
|
bad_area_nosemaphore:
|
|
bad_area_nosemaphore:
|
|
/* User mode accesses cause a SIGSEGV */
|
|
/* User mode accesses cause a SIGSEGV */
|
|
- if (user_mode(regs)) {
|
|
|
|
|
|
+ if (is_user) {
|
|
_exception(SIGSEGV, regs, code, address);
|
|
_exception(SIGSEGV, regs, code, address);
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|