Commit 3b52166c authored by Paolo 'Blaisorblade' Giarrusso's avatar Paolo 'Blaisorblade' Giarrusso Committed by Linus Torvalds

[PATCH] uml: fault handler micro-cleanups

Avoid chomping low bits of address for functions doing it by themselves,
fix whitespace, add a correctness checking.

I did this for remap-file-pages protection support, it was useful on its
own too.
Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1e40cd38
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "mem.h" #include "mem.h"
#include "mem_kern.h" #include "mem_kern.h"
/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
int handle_page_fault(unsigned long address, unsigned long ip, int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out) int is_write, int is_user, int *code_out)
{ {
...@@ -35,7 +36,6 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -35,7 +36,6 @@ int handle_page_fault(unsigned long address, unsigned long ip,
pud_t *pud; pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
unsigned long page;
int err = -EFAULT; int err = -EFAULT;
*code_out = SEGV_MAPERR; *code_out = SEGV_MAPERR;
...@@ -52,7 +52,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -52,7 +52,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
else if(expand_stack(vma, address)) else if(expand_stack(vma, address))
goto out; goto out;
good_area: good_area:
*code_out = SEGV_ACCERR; *code_out = SEGV_ACCERR;
if(is_write && !(vma->vm_flags & VM_WRITE)) if(is_write && !(vma->vm_flags & VM_WRITE))
goto out; goto out;
...@@ -60,9 +60,8 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -60,9 +60,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
if(!(vma->vm_flags & (VM_READ | VM_EXEC))) if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto out; goto out;
page = address & PAGE_MASK;
do { do {
survive: survive:
switch (handle_mm_fault(mm, vma, address, is_write)){ switch (handle_mm_fault(mm, vma, address, is_write)){
case VM_FAULT_MINOR: case VM_FAULT_MINOR:
current->min_flt++; current->min_flt++;
...@@ -79,16 +78,16 @@ int handle_page_fault(unsigned long address, unsigned long ip, ...@@ -79,16 +78,16 @@ int handle_page_fault(unsigned long address, unsigned long ip,
default: default:
BUG(); BUG();
} }
pgd = pgd_offset(mm, page); pgd = pgd_offset(mm, address);
pud = pud_offset(pgd, page); pud = pud_offset(pgd, address);
pmd = pmd_offset(pud, page); pmd = pmd_offset(pud, address);
pte = pte_offset_kernel(pmd, page); pte = pte_offset_kernel(pmd, address);
} while(!pte_present(*pte)); } while(!pte_present(*pte));
err = 0; err = 0;
*pte = pte_mkyoung(*pte); *pte = pte_mkyoung(*pte);
if(pte_write(*pte)) *pte = pte_mkdirty(*pte); if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
flush_tlb_page(vma, page); flush_tlb_page(vma, address);
out: out:
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
return(err); return(err);
...@@ -144,19 +143,18 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) ...@@ -144,19 +143,18 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
address, ip); address, ip);
if(err == -EACCES){ if (err == -EACCES) {
si.si_signo = SIGBUS; si.si_signo = SIGBUS;
si.si_errno = 0; si.si_errno = 0;
si.si_code = BUS_ADRERR; si.si_code = BUS_ADRERR;
si.si_addr = (void *)address; si.si_addr = (void *)address;
current->thread.arch.faultinfo = fi; current->thread.arch.faultinfo = fi;
force_sig_info(SIGBUS, &si, current); force_sig_info(SIGBUS, &si, current);
} } else if (err == -ENOMEM) {
else if(err == -ENOMEM){
printk("VM: killing process %s\n", current->comm); printk("VM: killing process %s\n", current->comm);
do_exit(SIGKILL); do_exit(SIGKILL);
} } else {
else { BUG_ON(err != -EFAULT);
si.si_signo = SIGSEGV; si.si_signo = SIGSEGV;
si.si_addr = (void *) address; si.si_addr = (void *) address;
current->thread.arch.faultinfo = fi; current->thread.arch.faultinfo = fi;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment