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
linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git]
/
arch
/
x86_64
/
kernel
/
process.c
diff --git
a/arch/x86_64/kernel/process.c
b/arch/x86_64/kernel/process.c
index
051ad11
..
818ab9e
100644
(file)
--- a/
arch/x86_64/kernel/process.c
+++ b/
arch/x86_64/kernel/process.c
@@
-35,8
+35,8
@@
#include <linux/ptrace.h>
#include <linux/utsname.h>
#include <linux/random.h>
#include <linux/ptrace.h>
#include <linux/utsname.h>
#include <linux/random.h>
-#include <linux/notifier.h>
#include <linux/kprobes.h>
#include <linux/kprobes.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@
-66,17
+66,24
@@
EXPORT_SYMBOL(boot_option_idle_override);
void (*pm_idle)(void);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
void (*pm_idle)(void);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
-static ATOMIC_NOTIFIER_HEAD(idle_notifier);
+static struct notifier_block *idle_notifier;
+static DEFINE_SPINLOCK(idle_notifier_lock);
void idle_notifier_register(struct notifier_block *n)
{
void idle_notifier_register(struct notifier_block *n)
{
- atomic_notifier_chain_register(&idle_notifier, n);
+ unsigned long flags;
+ spin_lock_irqsave(&idle_notifier_lock, flags);
+ notifier_chain_register(&idle_notifier, n);
+ spin_unlock_irqrestore(&idle_notifier_lock, flags);
}
EXPORT_SYMBOL_GPL(idle_notifier_register);
void idle_notifier_unregister(struct notifier_block *n)
{
}
EXPORT_SYMBOL_GPL(idle_notifier_register);
void idle_notifier_unregister(struct notifier_block *n)
{
- atomic_notifier_chain_unregister(&idle_notifier, n);
+ unsigned long flags;
+ spin_lock_irqsave(&idle_notifier_lock, flags);
+ notifier_chain_unregister(&idle_notifier, n);
+ spin_unlock_irqrestore(&idle_notifier_lock, flags);
}
EXPORT_SYMBOL(idle_notifier_unregister);
}
EXPORT_SYMBOL(idle_notifier_unregister);
@@
-86,13
+93,13
@@
static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
void enter_idle(void)
{
__get_cpu_var(idle_state) = CPU_IDLE;
void enter_idle(void)
{
__get_cpu_var(idle_state) = CPU_IDLE;
-
atomic_
notifier_call_chain(&idle_notifier, IDLE_START, NULL);
+ notifier_call_chain(&idle_notifier, IDLE_START, NULL);
}
static void __exit_idle(void)
{
__get_cpu_var(idle_state) = CPU_NOT_IDLE;
}
static void __exit_idle(void)
{
__get_cpu_var(idle_state) = CPU_NOT_IDLE;
-
atomic_
notifier_call_chain(&idle_notifier, IDLE_END, NULL);
+ notifier_call_chain(&idle_notifier, IDLE_END, NULL);
}
/* Called from interrupts to signify idle end */
}
/* Called from interrupts to signify idle end */
@@
-107,7
+114,7
@@
void exit_idle(void)
* We use this if we don't have any better
* idle routine..
*/
* We use this if we don't have any better
* idle routine..
*/
-
static
void default_idle(void)
+void default_idle(void)
{
local_irq_enable();
{
local_irq_enable();
@@
-346,6
+353,13
@@
void exit_thread(void)
struct task_struct *me = current;
struct thread_struct *t = &me->thread;
struct task_struct *me = current;
struct thread_struct *t = &me->thread;
+ /*
+ * Remove function-return probe instances associated with this task
+ * and put them back on the free list. Do not insert an exit probe for
+ * this function, it will be disabled by kprobe_flush_task if you do.
+ */
+ kprobe_flush_task(me);
+
if (me->thread.io_bitmap_ptr) {
struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
if (me->thread.io_bitmap_ptr) {
struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
@@
-494,7
+508,7
@@
out:
/*
* This special macro can be used to load a debugging register
*/
/*
* This special macro can be used to load a debugging register
*/
-#define loaddebug(thread,r) set_debug
reg
(thread->debugreg ## r, r)
+#define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
/*
* switch_to(x,y) should switch tasks from x to y.
/*
* switch_to(x,y) should switch tasks from x to y.
@@
-570,16
+584,17
@@
__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
}
/*
}
/*
- * Switch the PDA
and FPU contexts
.
+ * Switch the PDA
context
.
*/
prev->userrsp = read_pda(oldrsp);
write_pda(oldrsp, next->userrsp);
write_pda(pcurrent, next_p);
*/
prev->userrsp = read_pda(oldrsp);
write_pda(oldrsp, next->userrsp);
write_pda(pcurrent, next_p);
- /* This must be here to ensure both math_state_restore() and
- kernel_fpu_begin() work consistently.
+ /* This must be here to ensure both math_state_restore() and
+ kernel_fpu_begin() work consistently.
And the AMD workaround requires it to be after DS reload. */
unlazy_fpu(prev_p);
And the AMD workaround requires it to be after DS reload. */
unlazy_fpu(prev_p);
+
write_pda(kernelstack,
task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
write_pda(kernelstack,
task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
@@
-649,6
+664,12
@@
void set_personality_64bit(void)
/* Make sure to be in 64bit mode */
clear_thread_flag(TIF_IA32);
/* Make sure to be in 64bit mode */
clear_thread_flag(TIF_IA32);
+
+ /* TBD: overwrites user setup. Should have two bits.
+ But 64bit processes have always behaved this way,
+ so it's not too bad. The main problem is just that
+ 32bit childs are affected again. */
+ current->personality &= ~READ_IMPLIES_EXEC;
}
asmlinkage long sys_fork(struct pt_regs *regs)
}
asmlinkage long sys_fork(struct pt_regs *regs)
@@
-777,16
+798,10
@@
long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
}
case ARCH_GET_GS: {
unsigned long base;
}
case ARCH_GET_GS: {
unsigned long base;
- unsigned gsindex;
if (task->thread.gsindex == GS_TLS_SEL)
base = read_32bit_tls(task, GS_TLS);
if (task->thread.gsindex == GS_TLS_SEL)
base = read_32bit_tls(task, GS_TLS);
- else if (doit) {
- asm("movl %%gs,%0" : "=r" (gsindex));
- if (gsindex)
- rdmsrl(MSR_KERNEL_GS_BASE, base);
- else
- base = task->thread.gs;
- }
+ else if (doit)
+ rdmsrl(MSR_KERNEL_GS_BASE, base);
else
base = task->thread.gs;
ret = put_user(base, (unsigned long __user *)addr);
else
base = task->thread.gs;
ret = put_user(base, (unsigned long __user *)addr);