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
/
i386
/
mm
/
fault-xen.c
diff --git
a/arch/i386/mm/fault-xen.c
b/arch/i386/mm/fault-xen.c
index
9561f24
..
7cc2043
100644
(file)
--- a/
arch/i386/mm/fault-xen.c
+++ b/
arch/i386/mm/fault-xen.c
@@
-22,26
+22,29
@@
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/highmem.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/desc.h>
#include <asm/kdebug.h>
#include <asm/desc.h>
#include <asm/kdebug.h>
+#include <asm/segment.h>
extern void die(const char *,struct pt_regs *,long);
extern void die(const char *,struct pt_regs *,long);
-#ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
+static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
+
int register_page_fault_notifier(struct notifier_block *nb)
{
vmalloc_sync_all();
return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
}
int register_page_fault_notifier(struct notifier_block *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)
@@
-55,13
+58,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
/*
* Unlock any spinlocks which will prevent us from getting the
/*
* Unlock any spinlocks which will prevent us from getting the
@@
-118,10
+114,10
@@
static inline unsigned long get_segment_eip(struct pt_regs *regs,
}
/* The standard kernel/user address space limit. */
}
/* The standard kernel/user address space limit. */
- *eip_limit =
(seg & 2
) ? USER_DS.seg : KERNEL_DS.seg;
-
+ *eip_limit =
user_mode(regs
) ? USER_DS.seg : KERNEL_DS.seg;
+
/* By far the most common cases. */
/* By far the most common cases. */
- if (likely(
seg == __USER_CS || seg == GET_KERNEL_CS(
)))
+ if (likely(
SEGMENT_IS_FLAT_CODE(seg
)))
return eip;
/* Check the segment exists, is within the current LDT/GDT size,
return eip;
/* Check the segment exists, is within the current LDT/GDT size,
@@
-171,7
+167,7
@@
static inline unsigned long get_segment_eip(struct pt_regs *regs,
static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
{
unsigned long limit;
static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
{
unsigned long limit;
- unsigned
long instr =
get_segment_eip (regs, &limit);
+ unsigned
char *instr = (unsigned char *)
get_segment_eip (regs, &limit);
int scan_more = 1;
int prefetch = 0;
int i;
int scan_more = 1;
int prefetch = 0;
int i;
@@
-181,9
+177,9
@@
static 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 (instr > limit)
+ if (instr >
(unsigned char *)
limit)
break;
break;
- if (
__get_user(opcode, (unsigned char __user *) instr
))
+ if (
probe_kernel_address(instr, opcode
))
break;
instr_hi = opcode & 0xf0;
break;
instr_hi = opcode & 0xf0;
@@
-208,9
+204,9
@@
static 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 (instr > limit)
+ if (instr >
(unsigned char *)
limit)
break;
break;
- if (
__get_user(opcode, (unsigned char __user *) 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);
@@
-560,11
+556,7
@@
good_area:
write = 0;
switch (error_code & 3) {
default: /* 3: write, present */
write = 0;
switch (error_code & 3) {
default: /* 3: write, present */
-#ifdef TEST_VERIFY_AREA
- if (regs->cs == GET_KERNEL_CS())
- printk("WP fault at %08lx\n", regs->eip);
-#endif
- /* fall through */
+ /* fall through */
case 2: /* write, not present */
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
case 2: /* write, not present */
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@
-573,7
+565,7
@@
good_area:
case 1: /* read, present */
goto bad_area;
case 0: /* read, not present */
case 1: /* 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;
}
@@
-705,12
+697,13
@@
no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (
tsk->pid == 1
) {
+ if (
is_init(tsk)
) {
yield();
down_read(&mm->mmap_sem);
goto survive;
}
yield();
down_read(&mm->mmap_sem);
goto survive;
}
- 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;