|
|
@@ -66,7 +66,7 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
|
|
|
struct vm_area_struct *vma = NULL;
|
|
|
struct task_struct *tsk = current;
|
|
|
struct mm_struct *mm = tsk->mm;
|
|
|
- int si_code = 0;
|
|
|
+ int si_code = SEGV_MAPERR;
|
|
|
int ret;
|
|
|
vm_fault_t fault;
|
|
|
int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
|
|
|
@@ -81,16 +81,14 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
|
|
|
* only copy the information from the master page table,
|
|
|
* nothing more.
|
|
|
*/
|
|
|
- if (address >= VMALLOC_START) {
|
|
|
+ if (address >= VMALLOC_START && !user_mode(regs)) {
|
|
|
ret = handle_kernel_vaddr_fault(address);
|
|
|
if (unlikely(ret))
|
|
|
- goto bad_area_nosemaphore;
|
|
|
+ goto no_context;
|
|
|
else
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- si_code = SEGV_MAPERR;
|
|
|
-
|
|
|
/*
|
|
|
* If we're in an interrupt or have no user
|
|
|
* context, we must not take the fault..
|
|
|
@@ -198,7 +196,6 @@ good_area:
|
|
|
bad_area:
|
|
|
up_read(&mm->mmap_sem);
|
|
|
|
|
|
-bad_area_nosemaphore:
|
|
|
/* User mode accesses just cause a SIGSEGV */
|
|
|
if (user_mode(regs)) {
|
|
|
tsk->thread.fault_address = address;
|