git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git]
/
arch
/
x86_64
/
mm
/
fault.c
diff --git
a/arch/x86_64/mm/fault.c
b/arch/x86_64/mm/fault.c
index
94ae93d
..
9a46b46
100644
(file)
--- a/
arch/x86_64/mm/fault.c
+++ b/
arch/x86_64/mm/fault.c
@@
-23,9
+23,9
@@
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/kprobes.h>
+#include <linux/uaccess.h>
#include <asm/system.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/smp.h>
#include <asm/tlbflush.h>
#include <asm/pgalloc.h>
#include <asm/smp.h>
#include <asm/tlbflush.h>
@@
-40,8
+40,7
@@
#define PF_RSVD (1<<3)
#define PF_INSTR (1<<4)
#define PF_RSVD (1<<3)
#define PF_INSTR (1<<4)
-#ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
+static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
/* Hook to register for page fault notifications */
int register_page_fault_notifier(struct notifier_block *nb)
/* Hook to register for page fault notifications */
int register_page_fault_notifier(struct notifier_block *nb)
@@
-49,11
+48,13
@@
int register_page_fault_notifier(struct notifier_block *nb)
vmalloc_sync_all();
return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
}
vmalloc_sync_all();
return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
}
+EXPORT_SYMBOL_GPL(register_page_fault_notifier);
int unregister_page_fault_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
}
int unregister_page_fault_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
}
+EXPORT_SYMBOL_GPL(unregister_page_fault_notifier);
static inline int notify_page_fault(enum die_val val, const char *str,
struct pt_regs *regs, long err, int trap, int sig)
static inline int notify_page_fault(enum die_val val, const char *str,
struct pt_regs *regs, long err, int trap, int sig)
@@
-67,13
+68,6
@@
static inline int notify_page_fault(enum die_val val, const char *str,
};
return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
}
};
return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
}
-#else
-static inline int notify_page_fault(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- return NOTIFY_DONE;
-}
-#endif
void bust_spinlocks(int yes)
{
void bust_spinlocks(int yes)
{
@@
-111,7
+105,7
@@
static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
if (error_code & PF_INSTR)
return 0;
if (error_code & PF_INSTR)
return 0;
- instr = (unsigned char *)convert_rip_to_linear(current, regs);
+ instr = (unsigned char
__user
*)convert_rip_to_linear(current, regs);
max_instr = instr + 15;
if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE64)
max_instr = instr + 15;
if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE64)
@@
-122,7
+116,7
@@
static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
unsigned char instr_hi;
unsigned char instr_lo;
unsigned char instr_hi;
unsigned char instr_lo;
- if (
__get_user(opcode, instr
))
+ if (
probe_kernel_address(instr, opcode
))
break;
instr_hi = opcode & 0xf0;
break;
instr_hi = opcode & 0xf0;
@@
-160,7
+154,7
@@
static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
case 0x00:
/* Prefetch instruction is 0x0F0D or 0x0F18 */
scan_more = 0;
case 0x00:
/* Prefetch instruction is 0x0F0D or 0x0F18 */
scan_more = 0;
- if (
__get_user(opcode, instr))
+ if (
probe_kernel_address(instr, opcode))
break;
prefetch = (instr_lo == 0xF) &&
(opcode == 0x0D || opcode == 0x18);
break;
prefetch = (instr_lo == 0xF) &&
(opcode == 0x0D || opcode == 0x18);
@@
-176,7
+170,7
@@
static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
static int bad_address(void *p)
{
unsigned long dummy;
static int bad_address(void *p)
{
unsigned long dummy;
- return
__get_user(dummy, (unsigned long *)p
);
+ return
probe_kernel_address((unsigned long *)p, dummy
);
}
void dump_pagetable(unsigned long address)
}
void dump_pagetable(unsigned long address)
@@
-250,7
+244,7
@@
static int is_errata93(struct pt_regs *regs, unsigned long address)
int unhandled_signal(struct task_struct *tsk, int sig)
{
int unhandled_signal(struct task_struct *tsk, int sig)
{
- if (
tsk->pid == 1
)
+ if (
is_init(tsk)
)
return 1;
if (tracehook_consider_fatal_signal(tsk, sig))
return 0;
return 1;
if (tracehook_consider_fatal_signal(tsk, sig))
return 0;
@@
-299,7
+293,7
@@
static int vmalloc_fault(unsigned long address)
if (pgd_none(*pgd))
set_pgd(pgd, *pgd_ref);
else
if (pgd_none(*pgd))
set_pgd(pgd, *pgd_ref);
else
- BUG_ON(pgd_page
(*pgd) != pgd_page
(*pgd_ref));
+ BUG_ON(pgd_page
_vaddr(*pgd) != pgd_page_vaddr
(*pgd_ref));
/* Below here mismatches are bugs because these lower tables
are shared */
/* Below here mismatches are bugs because these lower tables
are shared */
@@
-308,7
+302,7
@@
static int vmalloc_fault(unsigned long address)
pud_ref = pud_offset(pgd_ref, address);
if (pud_none(*pud_ref))
return -1;
pud_ref = pud_offset(pgd_ref, address);
if (pud_none(*pud_ref))
return -1;
- if (pud_none(*pud) || pud_page
(*pud) != pud_page
(*pud_ref))
+ if (pud_none(*pud) || pud_page
_vaddr(*pud) != pud_page_vaddr
(*pud_ref))
BUG();
pmd = pmd_offset(pud, address);
pmd_ref = pmd_offset(pud_ref, address);
BUG();
pmd = pmd_offset(pud, address);
pmd_ref = pmd_offset(pud_ref, address);
@@
-470,7
+464,7
@@
good_area:
case PF_PROT: /* read, present */
goto bad_area;
case 0: /* read, not present */
case PF_PROT: /* read, present */
goto bad_area;
case 0: /* read, not present */
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC
| VM_WRITE
)))
goto bad_area;
}
goto bad_area;
}
@@
-520,10
+514,10
@@
bad_area_nosemaphore:
if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
printk(
if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
printk(
- "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+ "%s%s[%d
:#%u
]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
- tsk->comm, tsk->pid,
address, regs->rip
,
- regs->rsp, error_code);
+ tsk->comm, tsk->pid,
tsk->xid, address
,
+ regs->r
ip, regs->r
sp, error_code);
}
tsk->thread.cr2 = address;
}
tsk->thread.cr2 = address;
@@
-586,11
+580,12
@@
no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (
current->pid == 1) {
+ if (
is_init(current)) {
yield();
goto again;
}
yield();
goto again;
}
- printk("VM: killing process %s\n", tsk->comm);
+ printk("VM: killing process %s(%d:#%u)\n",
+ tsk->comm, tsk->pid, tsk->xid);
if (error_code & 4)
do_exit(SIGKILL);
goto no_context;
if (error_code & 4)
do_exit(SIGKILL);
goto no_context;
@@
-641,7
+636,7
@@
void vmalloc_sync_all(void)
if (pgd_none(*pgd))
set_pgd(pgd, *pgd_ref);
else
if (pgd_none(*pgd))
set_pgd(pgd, *pgd_ref);
else
- BUG_ON(pgd_page
(*pgd) != pgd_page
(*pgd_ref));
+ BUG_ON(pgd_page
_vaddr(*pgd) != pgd_page_vaddr
(*pgd_ref));
}
spin_unlock(&pgd_lock);
set_bit(pgd_index(address), insync);
}
spin_unlock(&pgd_lock);
set_bit(pgd_index(address), insync);