aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-05-21 17:00:02 -0400
committerAnton Altaparmakov <aia21@cantab.net>2005-05-21 17:00:02 -0400
commit67394f8f069c2fdf90f3b6d851824c07815442af (patch)
tree0c33e62d34dbaecea434ae9ece3cc0c56db8b1f7 /kernel
parent450cbfbbbd88876e3ccec1d277f613221ca82bb7 (diff)
parent9636273dae265b9354b861b373cd43cd76a6d0fe (diff)
Merge with /usr/src/ntfs-2.6.git
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/irq/handle.c1
-rw-r--r--kernel/itimer.c6
-rw-r--r--kernel/kallsyms.c13
-rw-r--r--kernel/kprobes.c142
-rw-r--r--kernel/power/main.c6
-rw-r--r--kernel/printk.c72
-rw-r--r--kernel/profile.c16
-rw-r--r--kernel/sched.c2
-rw-r--r--kernel/sys.c2
10 files changed, 201 insertions, 61 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index eb88b446c2..b01d26fe8d 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o
29obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ 29obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
30obj-$(CONFIG_SECCOMP) += seccomp.o 30obj-$(CONFIG_SECCOMP) += seccomp.o
31 31
32ifneq ($(CONFIG_IA64),y) 32ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
33# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is 33# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
34# needed for x86 only. Why this used to be enabled for all architectures is beyond 34# needed for x86 only. Why this used to be enabled for all architectures is beyond
35# me. I suspect most platforms don't need this, but until we know that for sure 35# me. I suspect most platforms don't need this, but until we know that for sure
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 2fb0e46e11..06b5a63239 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -30,6 +30,7 @@
30 */ 30 */
31irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { 31irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
32 [0 ... NR_IRQS-1] = { 32 [0 ... NR_IRQS-1] = {
33 .status = IRQ_DISABLED,
33 .handler = &no_irq_type, 34 .handler = &no_irq_type,
34 .lock = SPIN_LOCK_UNLOCKED 35 .lock = SPIN_LOCK_UNLOCKED
35 } 36 }
diff --git a/kernel/itimer.c b/kernel/itimer.c
index e9a40e947e..1dc988e0d2 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -123,7 +123,11 @@ static inline void it_real_arm(struct task_struct *p, unsigned long interval)
123 return; 123 return;
124 if (interval > (unsigned long) LONG_MAX) 124 if (interval > (unsigned long) LONG_MAX)
125 interval = LONG_MAX; 125 interval = LONG_MAX;
126 p->signal->real_timer.expires = jiffies + interval; 126 /* the "+ 1" below makes sure that the timer doesn't go off before
127 * the interval requested. This could happen if
128 * time requested % (usecs per jiffy) is more than the usecs left
129 * in the current jiffy */
130 p->signal->real_timer.expires = jiffies + interval + 1;
127 add_timer(&p->signal->real_timer); 131 add_timer(&p->signal->real_timer);
128} 132}
129 133
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 1627f8d6e0..13bcec151b 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -46,6 +46,14 @@ static inline int is_kernel_inittext(unsigned long addr)
46 return 0; 46 return 0;
47} 47}
48 48
49static inline int is_kernel_extratext(unsigned long addr)
50{
51 if (addr >= (unsigned long)_sextratext
52 && addr <= (unsigned long)_eextratext)
53 return 1;
54 return 0;
55}
56
49static inline int is_kernel_text(unsigned long addr) 57static inline int is_kernel_text(unsigned long addr)
50{ 58{
51 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) 59 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)
@@ -169,8 +177,9 @@ const char *kallsyms_lookup(unsigned long addr,
169 namebuf[0] = 0; 177 namebuf[0] = 0;
170 178
171 if ((all_var && is_kernel(addr)) || 179 if ((all_var && is_kernel(addr)) ||
172 (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr)))) { 180 (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
173 unsigned long symbol_end=0; 181 is_kernel_extratext(addr)))) {
182 unsigned long symbol_end = 0;
174 183
175 /* do a binary search on the sorted kallsyms_addresses array */ 184 /* do a binary search on the sorted kallsyms_addresses array */
176 low = 0; 185 low = 0;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 1d5dd1337b..037142b72a 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -44,6 +44,7 @@ static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
44 44
45unsigned int kprobe_cpu = NR_CPUS; 45unsigned int kprobe_cpu = NR_CPUS;
46static DEFINE_SPINLOCK(kprobe_lock); 46static DEFINE_SPINLOCK(kprobe_lock);
47static struct kprobe *curr_kprobe;
47 48
48/* Locks kprobe: irqs must be disabled */ 49/* Locks kprobe: irqs must be disabled */
49void lock_kprobes(void) 50void lock_kprobes(void)
@@ -73,22 +74,139 @@ struct kprobe *get_kprobe(void *addr)
73 return NULL; 74 return NULL;
74} 75}
75 76
77/*
78 * Aggregate handlers for multiple kprobes support - these handlers
79 * take care of invoking the individual kprobe handlers on p->list
80 */
81int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
82{
83 struct kprobe *kp;
84
85 list_for_each_entry(kp, &p->list, list) {
86 if (kp->pre_handler) {
87 curr_kprobe = kp;
88 kp->pre_handler(kp, regs);
89 curr_kprobe = NULL;
90 }
91 }
92 return 0;
93}
94
95void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
96 unsigned long flags)
97{
98 struct kprobe *kp;
99
100 list_for_each_entry(kp, &p->list, list) {
101 if (kp->post_handler) {
102 curr_kprobe = kp;
103 kp->post_handler(kp, regs, flags);
104 curr_kprobe = NULL;
105 }
106 }
107 return;
108}
109
110int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr)
111{
112 /*
113 * if we faulted "during" the execution of a user specified
114 * probe handler, invoke just that probe's fault handler
115 */
116 if (curr_kprobe && curr_kprobe->fault_handler) {
117 if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr))
118 return 1;
119 }
120 return 0;
121}
122
123/*
124 * Fill in the required fields of the "manager kprobe". Replace the
125 * earlier kprobe in the hlist with the manager kprobe
126 */
127static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
128{
129 ap->addr = p->addr;
130 ap->opcode = p->opcode;
131 memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn));
132
133 ap->pre_handler = aggr_pre_handler;
134 ap->post_handler = aggr_post_handler;
135 ap->fault_handler = aggr_fault_handler;
136
137 INIT_LIST_HEAD(&ap->list);
138 list_add(&p->list, &ap->list);
139
140 INIT_HLIST_NODE(&ap->hlist);
141 hlist_del(&p->hlist);
142 hlist_add_head(&ap->hlist,
143 &kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]);
144}
145
146/*
147 * This is the second or subsequent kprobe at the address - handle
148 * the intricacies
149 * TODO: Move kcalloc outside the spinlock
150 */
151static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
152{
153 int ret = 0;
154 struct kprobe *ap;
155
156 if (old_p->break_handler || p->break_handler) {
157 ret = -EEXIST; /* kprobe and jprobe can't (yet) coexist */
158 } else if (old_p->pre_handler == aggr_pre_handler) {
159 list_add(&p->list, &old_p->list);
160 } else {
161 ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC);
162 if (!ap)
163 return -ENOMEM;
164 add_aggr_kprobe(ap, old_p);
165 list_add(&p->list, &ap->list);
166 }
167 return ret;
168}
169
170/* kprobe removal house-keeping routines */
171static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
172{
173 *p->addr = p->opcode;
174 hlist_del(&p->hlist);
175 flush_icache_range((unsigned long) p->addr,
176 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
177 spin_unlock_irqrestore(&kprobe_lock, flags);
178 arch_remove_kprobe(p);
179}
180
181static inline void cleanup_aggr_kprobe(struct kprobe *old_p,
182 struct kprobe *p, unsigned long flags)
183{
184 list_del(&p->list);
185 if (list_empty(&old_p->list)) {
186 cleanup_kprobe(old_p, flags);
187 kfree(old_p);
188 } else
189 spin_unlock_irqrestore(&kprobe_lock, flags);
190}
191
76int register_kprobe(struct kprobe *p) 192int register_kprobe(struct kprobe *p)
77{ 193{
78 int ret = 0; 194 int ret = 0;
79 unsigned long flags = 0; 195 unsigned long flags = 0;
196 struct kprobe *old_p;
80 197
81 if ((ret = arch_prepare_kprobe(p)) != 0) { 198 if ((ret = arch_prepare_kprobe(p)) != 0) {
82 goto rm_kprobe; 199 goto rm_kprobe;
83 } 200 }
84 spin_lock_irqsave(&kprobe_lock, flags); 201 spin_lock_irqsave(&kprobe_lock, flags);
85 INIT_HLIST_NODE(&p->hlist); 202 old_p = get_kprobe(p->addr);
86 if (get_kprobe(p->addr)) { 203 if (old_p) {
87 ret = -EEXIST; 204 ret = register_aggr_kprobe(old_p, p);
88 goto out; 205 goto out;
89 } 206 }
90 arch_copy_kprobe(p);
91 207
208 arch_copy_kprobe(p);
209 INIT_HLIST_NODE(&p->hlist);
92 hlist_add_head(&p->hlist, 210 hlist_add_head(&p->hlist,
93 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); 211 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
94 212
@@ -107,13 +225,17 @@ rm_kprobe:
107void unregister_kprobe(struct kprobe *p) 225void unregister_kprobe(struct kprobe *p)
108{ 226{
109 unsigned long flags; 227 unsigned long flags;
110 arch_remove_kprobe(p); 228 struct kprobe *old_p;
229
111 spin_lock_irqsave(&kprobe_lock, flags); 230 spin_lock_irqsave(&kprobe_lock, flags);
112 *p->addr = p->opcode; 231 old_p = get_kprobe(p->addr);
113 hlist_del(&p->hlist); 232 if (old_p) {
114 flush_icache_range((unsigned long) p->addr, 233 if (old_p->pre_handler == aggr_pre_handler)
115 (unsigned long) p->addr + sizeof(kprobe_opcode_t)); 234 cleanup_aggr_kprobe(old_p, p, flags);
116 spin_unlock_irqrestore(&kprobe_lock, flags); 235 else
236 cleanup_kprobe(p, flags);
237 } else
238 spin_unlock_irqrestore(&kprobe_lock, flags);
117} 239}
118 240
119static struct notifier_block kprobe_exceptions_nb = { 241static struct notifier_block kprobe_exceptions_nb = {
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 7960ddf04a..4cdebc972f 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state)
156 goto Unlock; 156 goto Unlock;
157 } 157 }
158 158
159 pr_debug("PM: Preparing system for suspend\n"); 159 pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
160 if ((error = suspend_prepare(state))) 160 if ((error = suspend_prepare(state)))
161 goto Unlock; 161 goto Unlock;
162 162
163 pr_debug("PM: Entering state.\n"); 163 pr_debug("PM: Entering %s sleep\n", pm_states[state]);
164 error = suspend_enter(state); 164 error = suspend_enter(state);
165 165
166 pr_debug("PM: Finishing up.\n"); 166 pr_debug("PM: Finishing wakeup.\n");
167 suspend_finish(state); 167 suspend_finish(state);
168 Unlock: 168 Unlock:
169 up(&pm_sem); 169 up(&pm_sem);
diff --git a/kernel/printk.c b/kernel/printk.c
index 290a07ce2c..01b58d7d17 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -160,42 +160,6 @@ static int __init console_setup(char *str)
160 160
161__setup("console=", console_setup); 161__setup("console=", console_setup);
162 162
163/**
164 * add_preferred_console - add a device to the list of preferred consoles.
165 *
166 * The last preferred console added will be used for kernel messages
167 * and stdin/out/err for init. Normally this is used by console_setup
168 * above to handle user-supplied console arguments; however it can also
169 * be used by arch-specific code either to override the user or more
170 * commonly to provide a default console (ie from PROM variables) when
171 * the user has not supplied one.
172 */
173int __init add_preferred_console(char *name, int idx, char *options)
174{
175 struct console_cmdline *c;
176 int i;
177
178 /*
179 * See if this tty is not yet registered, and
180 * if we have a slot free.
181 */
182 for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
183 if (strcmp(console_cmdline[i].name, name) == 0 &&
184 console_cmdline[i].index == idx) {
185 selected_console = i;
186 return 0;
187 }
188 if (i == MAX_CMDLINECONSOLES)
189 return -E2BIG;
190 selected_console = i;
191 c = &console_cmdline[i];
192 memcpy(c->name, name, sizeof(c->name));
193 c->name[sizeof(c->name) - 1] = 0;
194 c->options = options;
195 c->index = idx;
196 return 0;
197}
198
199static int __init log_buf_len_setup(char *str) 163static int __init log_buf_len_setup(char *str)
200{ 164{
201 unsigned long size = memparse(str, &str); 165 unsigned long size = memparse(str, &str);
@@ -671,6 +635,42 @@ static void call_console_drivers(unsigned long start, unsigned long end) {}
671#endif 635#endif
672 636
673/** 637/**
638 * add_preferred_console - add a device to the list of preferred consoles.
639 *
640 * The last preferred console added will be used for kernel messages
641 * and stdin/out/err for init. Normally this is used by console_setup
642 * above to handle user-supplied console arguments; however it can also
643 * be used by arch-specific code either to override the user or more
644 * commonly to provide a default console (ie from PROM variables) when
645 * the user has not supplied one.
646 */
647int __init add_preferred_console(char *name, int idx, char *options)
648{
649 struct console_cmdline *c;
650 int i;
651
652 /*
653 * See if this tty is not yet registered, and
654 * if we have a slot free.
655 */
656 for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
657 if (strcmp(console_cmdline[i].name, name) == 0 &&
658 console_cmdline[i].index == idx) {
659 selected_console = i;
660 return 0;
661 }
662 if (i == MAX_CMDLINECONSOLES)
663 return -E2BIG;
664 selected_console = i;
665 c = &console_cmdline[i];
666 memcpy(c->name, name, sizeof(c->name));
667 c->name[sizeof(c->name) - 1] = 0;
668 c->options = options;
669 c->index = idx;
670 return 0;
671}
672
673/**
674 * acquire_console_sem - lock the console system for exclusive use. 674 * acquire_console_sem - lock the console system for exclusive use.
675 * 675 *
676 * Acquires a semaphore which guarantees that the caller has 676 * Acquires a semaphore which guarantees that the caller has
diff --git a/kernel/profile.c b/kernel/profile.c
index 0221a50ca8..ad8cbb75ff 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -49,15 +49,19 @@ static DECLARE_MUTEX(profile_flip_mutex);
49 49
50static int __init profile_setup(char * str) 50static int __init profile_setup(char * str)
51{ 51{
52 static char __initdata schedstr[] = "schedule";
52 int par; 53 int par;
53 54
54 if (!strncmp(str, "schedule", 8)) { 55 if (!strncmp(str, schedstr, strlen(schedstr))) {
55 prof_on = SCHED_PROFILING; 56 prof_on = SCHED_PROFILING;
56 printk(KERN_INFO "kernel schedule profiling enabled\n"); 57 if (str[strlen(schedstr)] == ',')
57 if (str[7] == ',') 58 str += strlen(schedstr) + 1;
58 str += 8; 59 if (get_option(&str, &par))
59 } 60 prof_shift = par;
60 if (get_option(&str,&par)) { 61 printk(KERN_INFO
62 "kernel schedule profiling enabled (shift: %ld)\n",
63 prof_shift);
64 } else if (get_option(&str, &par)) {
61 prof_shift = par; 65 prof_shift = par;
62 prof_on = CPU_PROFILING; 66 prof_on = CPU_PROFILING;
63 printk(KERN_INFO "kernel profiling enabled (shift: %ld)\n", 67 printk(KERN_INFO "kernel profiling enabled (shift: %ld)\n",
diff --git a/kernel/sched.c b/kernel/sched.c
index 0dc3158667..66b2ed7848 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4243,7 +4243,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *tsk)
4243 4243
4244 /* No more Mr. Nice Guy. */ 4244 /* No more Mr. Nice Guy. */
4245 if (dest_cpu == NR_CPUS) { 4245 if (dest_cpu == NR_CPUS) {
4246 tsk->cpus_allowed = cpuset_cpus_allowed(tsk); 4246 cpus_setall(tsk->cpus_allowed);
4247 dest_cpu = any_online_cpu(tsk->cpus_allowed); 4247 dest_cpu = any_online_cpu(tsk->cpus_allowed);
4248 4248
4249 /* 4249 /*
diff --git a/kernel/sys.c b/kernel/sys.c
index f64e97cabe..f006632c2b 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1195,7 +1195,7 @@ static int groups_from_user(struct group_info *group_info,
1195 return 0; 1195 return 0;
1196} 1196}
1197 1197
1198/* a simple shell-metzner sort */ 1198/* a simple Shell sort */
1199static void groups_sort(struct group_info *group_info) 1199static void groups_sort(struct group_info *group_info)
1200{ 1200{
1201 int base, max, stride; 1201 int base, max, stride;