diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/Kconfig | 25 | ||||
-rw-r--r-- | arch/x86_64/boot/install.sh | 4 | ||||
-rw-r--r-- | arch/x86_64/ia32/ia32_signal.c | 15 | ||||
-rw-r--r-- | arch/x86_64/kernel/aperture.c | 4 | ||||
-rw-r--r-- | arch/x86_64/kernel/early_printk.c | 13 | ||||
-rw-r--r-- | arch/x86_64/kernel/head64.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/i8259.c | 15 | ||||
-rw-r--r-- | arch/x86_64/kernel/kprobes.c | 190 | ||||
-rw-r--r-- | arch/x86_64/kernel/mpparse.c | 25 | ||||
-rw-r--r-- | arch/x86_64/kernel/process.c | 16 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup.c | 33 | ||||
-rw-r--r-- | arch/x86_64/kernel/signal.c | 30 | ||||
-rw-r--r-- | arch/x86_64/kernel/time.c | 42 | ||||
-rw-r--r-- | arch/x86_64/kernel/traps.c | 22 | ||||
-rw-r--r-- | arch/x86_64/lib/delay.c | 7 | ||||
-rw-r--r-- | arch/x86_64/mm/Makefile | 2 | ||||
-rw-r--r-- | arch/x86_64/mm/fault.c | 4 | ||||
-rw-r--r-- | arch/x86_64/mm/init.c | 9 | ||||
-rw-r--r-- | arch/x86_64/mm/ioremap.c | 2 | ||||
-rw-r--r-- | arch/x86_64/mm/numa.c | 8 | ||||
-rw-r--r-- | arch/x86_64/pci/k8-bus.c | 16 |
21 files changed, 365 insertions, 119 deletions
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 289f448ac89c..db259757dc8a 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -265,7 +265,7 @@ config NUMA_EMU | |||
265 | into virtual nodes when booted with "numa=fake=N", where N is the | 265 | into virtual nodes when booted with "numa=fake=N", where N is the |
266 | number of nodes. This is only useful for debugging. | 266 | number of nodes. This is only useful for debugging. |
267 | 267 | ||
268 | config DISCONTIGMEM | 268 | config ARCH_DISCONTIGMEM_ENABLE |
269 | bool | 269 | bool |
270 | depends on NUMA | 270 | depends on NUMA |
271 | default y | 271 | default y |
@@ -274,6 +274,27 @@ config NUMA | |||
274 | bool | 274 | bool |
275 | default n | 275 | default n |
276 | 276 | ||
277 | config ARCH_DISCONTIGMEM_ENABLE | ||
278 | def_bool y | ||
279 | depends on NUMA | ||
280 | |||
281 | config ARCH_DISCONTIGMEM_DEFAULT | ||
282 | def_bool y | ||
283 | depends on NUMA | ||
284 | |||
285 | config ARCH_SPARSEMEM_ENABLE | ||
286 | def_bool y | ||
287 | depends on NUMA | ||
288 | |||
289 | config ARCH_FLATMEM_ENABLE | ||
290 | def_bool y | ||
291 | depends on !NUMA | ||
292 | |||
293 | source "mm/Kconfig" | ||
294 | |||
295 | config HAVE_ARCH_EARLY_PFN_TO_NID | ||
296 | def_bool y | ||
297 | |||
277 | config HAVE_DEC_LOCK | 298 | config HAVE_DEC_LOCK |
278 | bool | 299 | bool |
279 | depends on SMP | 300 | depends on SMP |
@@ -381,6 +402,8 @@ config SECCOMP | |||
381 | 402 | ||
382 | If unsure, say Y. Only embedded should say N here. | 403 | If unsure, say Y. Only embedded should say N here. |
383 | 404 | ||
405 | source kernel/Kconfig.hz | ||
406 | |||
384 | endmenu | 407 | endmenu |
385 | 408 | ||
386 | # | 409 | # |
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh index 90f2452b3b9e..f17b40dfc0f4 100644 --- a/arch/x86_64/boot/install.sh +++ b/arch/x86_64/boot/install.sh | |||
@@ -21,8 +21,8 @@ | |||
21 | 21 | ||
22 | # User may have a custom install script | 22 | # User may have a custom install script |
23 | 23 | ||
24 | if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi | 24 | if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi |
25 | if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi | 25 | if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi |
26 | 26 | ||
27 | # Default install - same as make zlilo | 27 | # Default install - same as make zlilo |
28 | 28 | ||
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index fbd09b5126ce..66e2821533db 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c | |||
@@ -428,8 +428,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
428 | return (void __user *)((rsp - frame_size) & -8UL); | 428 | return (void __user *)((rsp - frame_size) & -8UL); |
429 | } | 429 | } |
430 | 430 | ||
431 | void ia32_setup_frame(int sig, struct k_sigaction *ka, | 431 | int ia32_setup_frame(int sig, struct k_sigaction *ka, |
432 | compat_sigset_t *set, struct pt_regs * regs) | 432 | compat_sigset_t *set, struct pt_regs * regs) |
433 | { | 433 | { |
434 | struct sigframe __user *frame; | 434 | struct sigframe __user *frame; |
435 | int err = 0; | 435 | int err = 0; |
@@ -514,14 +514,15 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, | |||
514 | current->comm, current->pid, frame, regs->rip, frame->pretcode); | 514 | current->comm, current->pid, frame, regs->rip, frame->pretcode); |
515 | #endif | 515 | #endif |
516 | 516 | ||
517 | return; | 517 | return 1; |
518 | 518 | ||
519 | give_sigsegv: | 519 | give_sigsegv: |
520 | force_sigsegv(sig, current); | 520 | force_sigsegv(sig, current); |
521 | return 0; | ||
521 | } | 522 | } |
522 | 523 | ||
523 | void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 524 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
524 | compat_sigset_t *set, struct pt_regs * regs) | 525 | compat_sigset_t *set, struct pt_regs * regs) |
525 | { | 526 | { |
526 | struct rt_sigframe __user *frame; | 527 | struct rt_sigframe __user *frame; |
527 | int err = 0; | 528 | int err = 0; |
@@ -613,9 +614,9 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
613 | current->comm, current->pid, frame, regs->rip, frame->pretcode); | 614 | current->comm, current->pid, frame, regs->rip, frame->pretcode); |
614 | #endif | 615 | #endif |
615 | 616 | ||
616 | return; | 617 | return 1; |
617 | 618 | ||
618 | give_sigsegv: | 619 | give_sigsegv: |
619 | force_sigsegv(sig, current); | 620 | force_sigsegv(sig, current); |
621 | return 0; | ||
620 | } | 622 | } |
621 | |||
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index 504e63474993..c9a6b812e926 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c | |||
@@ -40,11 +40,7 @@ int fix_aperture __initdata = 1; | |||
40 | 40 | ||
41 | static u32 __init allocate_aperture(void) | 41 | static u32 __init allocate_aperture(void) |
42 | { | 42 | { |
43 | #ifdef CONFIG_DISCONTIGMEM | ||
44 | pg_data_t *nd0 = NODE_DATA(0); | 43 | pg_data_t *nd0 = NODE_DATA(0); |
45 | #else | ||
46 | pg_data_t *nd0 = &contig_page_data; | ||
47 | #endif | ||
48 | u32 aper_size; | 44 | u32 aper_size; |
49 | void *p; | 45 | void *p; |
50 | 46 | ||
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c index e3a19e8ebbf8..9631c747c5e3 100644 --- a/arch/x86_64/kernel/early_printk.c +++ b/arch/x86_64/kernel/early_printk.c | |||
@@ -2,20 +2,24 @@ | |||
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
5 | #include <linux/tty.h> | ||
5 | #include <asm/io.h> | 6 | #include <asm/io.h> |
6 | #include <asm/processor.h> | 7 | #include <asm/processor.h> |
7 | 8 | ||
8 | /* Simple VGA output */ | 9 | /* Simple VGA output */ |
9 | 10 | ||
10 | #ifdef __i386__ | 11 | #ifdef __i386__ |
12 | #include <asm/setup.h> | ||
11 | #define VGABASE (__ISA_IO_base + 0xb8000) | 13 | #define VGABASE (__ISA_IO_base + 0xb8000) |
12 | #else | 14 | #else |
15 | #include <asm/bootsetup.h> | ||
13 | #define VGABASE ((void __iomem *)0xffffffff800b8000UL) | 16 | #define VGABASE ((void __iomem *)0xffffffff800b8000UL) |
14 | #endif | 17 | #endif |
15 | 18 | ||
16 | #define MAX_YPOS 25 | 19 | #define MAX_YPOS max_ypos |
17 | #define MAX_XPOS 80 | 20 | #define MAX_XPOS max_xpos |
18 | 21 | ||
22 | static int max_ypos = 25, max_xpos = 80; | ||
19 | static int current_ypos = 1, current_xpos = 0; | 23 | static int current_ypos = 1, current_xpos = 0; |
20 | 24 | ||
21 | static void early_vga_write(struct console *con, const char *str, unsigned n) | 25 | static void early_vga_write(struct console *con, const char *str, unsigned n) |
@@ -196,7 +200,10 @@ int __init setup_early_printk(char *opt) | |||
196 | } else if (!strncmp(buf, "ttyS", 4)) { | 200 | } else if (!strncmp(buf, "ttyS", 4)) { |
197 | early_serial_init(buf); | 201 | early_serial_init(buf); |
198 | early_console = &early_serial_console; | 202 | early_console = &early_serial_console; |
199 | } else if (!strncmp(buf, "vga", 3)) { | 203 | } else if (!strncmp(buf, "vga", 3) |
204 | && SCREEN_INFO.orig_video_isVGA == 1) { | ||
205 | max_xpos = SCREEN_INFO.orig_video_cols; | ||
206 | max_ypos = SCREEN_INFO.orig_video_lines; | ||
200 | early_console = &early_vga_console; | 207 | early_console = &early_vga_console; |
201 | } | 208 | } |
202 | early_console_initialized = 1; | 209 | early_console_initialized = 1; |
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 0f8c78dcd38c..cf6ab147a2a5 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c | |||
@@ -94,7 +94,7 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
94 | s = strstr(saved_command_line, "earlyprintk="); | 94 | s = strstr(saved_command_line, "earlyprintk="); |
95 | if (s != NULL) | 95 | if (s != NULL) |
96 | setup_early_printk(s); | 96 | setup_early_printk(s); |
97 | #ifdef CONFIG_DISCONTIGMEM | 97 | #ifdef CONFIG_NUMA |
98 | s = strstr(saved_command_line, "numa="); | 98 | s = strstr(saved_command_line, "numa="); |
99 | if (s != NULL) | 99 | if (s != NULL) |
100 | numa_setup(s+5); | 100 | numa_setup(s+5); |
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 7873d9ba8814..19eafa0aa95c 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
@@ -157,14 +157,13 @@ static unsigned int startup_8259A_irq(unsigned int irq) | |||
157 | } | 157 | } |
158 | 158 | ||
159 | static struct hw_interrupt_type i8259A_irq_type = { | 159 | static struct hw_interrupt_type i8259A_irq_type = { |
160 | "XT-PIC", | 160 | .typename = "XT-PIC", |
161 | startup_8259A_irq, | 161 | .startup = startup_8259A_irq, |
162 | shutdown_8259A_irq, | 162 | .shutdown = shutdown_8259A_irq, |
163 | enable_8259A_irq, | 163 | .enable = enable_8259A_irq, |
164 | disable_8259A_irq, | 164 | .disable = disable_8259A_irq, |
165 | mask_and_ack_8259A, | 165 | .ack = mask_and_ack_8259A, |
166 | end_8259A_irq, | 166 | .end = end_8259A_irq, |
167 | NULL | ||
168 | }; | 167 | }; |
169 | 168 | ||
170 | /* | 169 | /* |
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index f77f8a0ff187..4e680f87a75f 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * <prasanna@in.ibm.com> adapted for x86_64 | 27 | * <prasanna@in.ibm.com> adapted for x86_64 |
28 | * 2005-Mar Roland McGrath <roland@redhat.com> | 28 | * 2005-Mar Roland McGrath <roland@redhat.com> |
29 | * Fixed to handle %rip-relative addressing mode correctly. | 29 | * Fixed to handle %rip-relative addressing mode correctly. |
30 | * 2005-May Rusty Lynch <rusty.lynch@intel.com> | ||
31 | * Added function return probes functionality | ||
30 | */ | 32 | */ |
31 | 33 | ||
32 | #include <linux/config.h> | 34 | #include <linux/config.h> |
@@ -37,18 +39,16 @@ | |||
37 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
38 | #include <linux/preempt.h> | 40 | #include <linux/preempt.h> |
39 | #include <linux/moduleloader.h> | 41 | #include <linux/moduleloader.h> |
40 | 42 | #include <asm/cacheflush.h> | |
41 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
42 | #include <asm/kdebug.h> | 44 | #include <asm/kdebug.h> |
43 | 45 | ||
44 | static DECLARE_MUTEX(kprobe_mutex); | 46 | static DECLARE_MUTEX(kprobe_mutex); |
45 | 47 | ||
46 | /* kprobe_status settings */ | ||
47 | #define KPROBE_HIT_ACTIVE 0x00000001 | ||
48 | #define KPROBE_HIT_SS 0x00000002 | ||
49 | |||
50 | static struct kprobe *current_kprobe; | 48 | static struct kprobe *current_kprobe; |
51 | static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags; | 49 | static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags; |
50 | static struct kprobe *kprobe_prev; | ||
51 | static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev; | ||
52 | static struct pt_regs jprobe_saved_regs; | 52 | static struct pt_regs jprobe_saved_regs; |
53 | static long *jprobe_saved_rsp; | 53 | static long *jprobe_saved_rsp; |
54 | static kprobe_opcode_t *get_insn_slot(void); | 54 | static kprobe_opcode_t *get_insn_slot(void); |
@@ -214,6 +214,21 @@ void arch_copy_kprobe(struct kprobe *p) | |||
214 | BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ | 214 | BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ |
215 | *ripdisp = disp; | 215 | *ripdisp = disp; |
216 | } | 216 | } |
217 | p->opcode = *p->addr; | ||
218 | } | ||
219 | |||
220 | void arch_arm_kprobe(struct kprobe *p) | ||
221 | { | ||
222 | *p->addr = BREAKPOINT_INSTRUCTION; | ||
223 | flush_icache_range((unsigned long) p->addr, | ||
224 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
225 | } | ||
226 | |||
227 | void arch_disarm_kprobe(struct kprobe *p) | ||
228 | { | ||
229 | *p->addr = p->opcode; | ||
230 | flush_icache_range((unsigned long) p->addr, | ||
231 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
217 | } | 232 | } |
218 | 233 | ||
219 | void arch_remove_kprobe(struct kprobe *p) | 234 | void arch_remove_kprobe(struct kprobe *p) |
@@ -223,10 +238,29 @@ void arch_remove_kprobe(struct kprobe *p) | |||
223 | down(&kprobe_mutex); | 238 | down(&kprobe_mutex); |
224 | } | 239 | } |
225 | 240 | ||
226 | static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) | 241 | static inline void save_previous_kprobe(void) |
227 | { | 242 | { |
228 | *p->addr = p->opcode; | 243 | kprobe_prev = current_kprobe; |
229 | regs->rip = (unsigned long)p->addr; | 244 | kprobe_status_prev = kprobe_status; |
245 | kprobe_old_rflags_prev = kprobe_old_rflags; | ||
246 | kprobe_saved_rflags_prev = kprobe_saved_rflags; | ||
247 | } | ||
248 | |||
249 | static inline void restore_previous_kprobe(void) | ||
250 | { | ||
251 | current_kprobe = kprobe_prev; | ||
252 | kprobe_status = kprobe_status_prev; | ||
253 | kprobe_old_rflags = kprobe_old_rflags_prev; | ||
254 | kprobe_saved_rflags = kprobe_saved_rflags_prev; | ||
255 | } | ||
256 | |||
257 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs) | ||
258 | { | ||
259 | current_kprobe = p; | ||
260 | kprobe_saved_rflags = kprobe_old_rflags | ||
261 | = (regs->eflags & (TF_MASK | IF_MASK)); | ||
262 | if (is_IF_modifier(p->ainsn.insn)) | ||
263 | kprobe_saved_rflags &= ~IF_MASK; | ||
230 | } | 264 | } |
231 | 265 | ||
232 | static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 266 | static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
@@ -240,6 +274,50 @@ static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
240 | regs->rip = (unsigned long)p->ainsn.insn; | 274 | regs->rip = (unsigned long)p->ainsn.insn; |
241 | } | 275 | } |
242 | 276 | ||
277 | struct task_struct *arch_get_kprobe_task(void *ptr) | ||
278 | { | ||
279 | return ((struct thread_info *) (((unsigned long) ptr) & | ||
280 | (~(THREAD_SIZE -1))))->task; | ||
281 | } | ||
282 | |||
283 | void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) | ||
284 | { | ||
285 | unsigned long *sara = (unsigned long *)regs->rsp; | ||
286 | struct kretprobe_instance *ri; | ||
287 | static void *orig_ret_addr; | ||
288 | |||
289 | /* | ||
290 | * Save the return address when the return probe hits | ||
291 | * the first time, and use it to populate the (krprobe | ||
292 | * instance)->ret_addr for subsequent return probes at | ||
293 | * the same addrress since stack address would have | ||
294 | * the kretprobe_trampoline by then. | ||
295 | */ | ||
296 | if (((void*) *sara) != kretprobe_trampoline) | ||
297 | orig_ret_addr = (void*) *sara; | ||
298 | |||
299 | if ((ri = get_free_rp_inst(rp)) != NULL) { | ||
300 | ri->rp = rp; | ||
301 | ri->stack_addr = sara; | ||
302 | ri->ret_addr = orig_ret_addr; | ||
303 | add_rp_inst(ri); | ||
304 | /* Replace the return addr with trampoline addr */ | ||
305 | *sara = (unsigned long) &kretprobe_trampoline; | ||
306 | } else { | ||
307 | rp->nmissed++; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | void arch_kprobe_flush_task(struct task_struct *tk) | ||
312 | { | ||
313 | struct kretprobe_instance *ri; | ||
314 | while ((ri = get_rp_inst_tsk(tk)) != NULL) { | ||
315 | *((unsigned long *)(ri->stack_addr)) = | ||
316 | (unsigned long) ri->ret_addr; | ||
317 | recycle_rp_inst(ri); | ||
318 | } | ||
319 | } | ||
320 | |||
243 | /* | 321 | /* |
244 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they | 322 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they |
245 | * remain disabled thorough out this function. | 323 | * remain disabled thorough out this function. |
@@ -264,9 +342,30 @@ int kprobe_handler(struct pt_regs *regs) | |||
264 | regs->eflags |= kprobe_saved_rflags; | 342 | regs->eflags |= kprobe_saved_rflags; |
265 | unlock_kprobes(); | 343 | unlock_kprobes(); |
266 | goto no_kprobe; | 344 | goto no_kprobe; |
345 | } else if (kprobe_status == KPROBE_HIT_SSDONE) { | ||
346 | /* TODO: Provide re-entrancy from | ||
347 | * post_kprobes_handler() and avoid exception | ||
348 | * stack corruption while single-stepping on | ||
349 | * the instruction of the new probe. | ||
350 | */ | ||
351 | arch_disarm_kprobe(p); | ||
352 | regs->rip = (unsigned long)p->addr; | ||
353 | ret = 1; | ||
354 | } else { | ||
355 | /* We have reentered the kprobe_handler(), since | ||
356 | * another probe was hit while within the | ||
357 | * handler. We here save the original kprobe | ||
358 | * variables and just single step on instruction | ||
359 | * of the new probe without calling any user | ||
360 | * handlers. | ||
361 | */ | ||
362 | save_previous_kprobe(); | ||
363 | set_current_kprobe(p, regs); | ||
364 | p->nmissed++; | ||
365 | prepare_singlestep(p, regs); | ||
366 | kprobe_status = KPROBE_REENTER; | ||
367 | return 1; | ||
267 | } | 368 | } |
268 | disarm_kprobe(p, regs); | ||
269 | ret = 1; | ||
270 | } else { | 369 | } else { |
271 | p = current_kprobe; | 370 | p = current_kprobe; |
272 | if (p->break_handler && p->break_handler(p, regs)) { | 371 | if (p->break_handler && p->break_handler(p, regs)) { |
@@ -296,11 +395,7 @@ int kprobe_handler(struct pt_regs *regs) | |||
296 | } | 395 | } |
297 | 396 | ||
298 | kprobe_status = KPROBE_HIT_ACTIVE; | 397 | kprobe_status = KPROBE_HIT_ACTIVE; |
299 | current_kprobe = p; | 398 | set_current_kprobe(p, regs); |
300 | kprobe_saved_rflags = kprobe_old_rflags | ||
301 | = (regs->eflags & (TF_MASK | IF_MASK)); | ||
302 | if (is_IF_modifier(p->ainsn.insn)) | ||
303 | kprobe_saved_rflags &= ~IF_MASK; | ||
304 | 399 | ||
305 | if (p->pre_handler && p->pre_handler(p, regs)) | 400 | if (p->pre_handler && p->pre_handler(p, regs)) |
306 | /* handler has already set things up, so skip ss setup */ | 401 | /* handler has already set things up, so skip ss setup */ |
@@ -317,6 +412,55 @@ no_kprobe: | |||
317 | } | 412 | } |
318 | 413 | ||
319 | /* | 414 | /* |
415 | * For function-return probes, init_kprobes() establishes a probepoint | ||
416 | * here. When a retprobed function returns, this probe is hit and | ||
417 | * trampoline_probe_handler() runs, calling the kretprobe's handler. | ||
418 | */ | ||
419 | void kretprobe_trampoline_holder(void) | ||
420 | { | ||
421 | asm volatile ( ".global kretprobe_trampoline\n" | ||
422 | "kretprobe_trampoline: \n" | ||
423 | "nop\n"); | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Called when we hit the probe point at kretprobe_trampoline | ||
428 | */ | ||
429 | int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | ||
430 | { | ||
431 | struct task_struct *tsk; | ||
432 | struct kretprobe_instance *ri; | ||
433 | struct hlist_head *head; | ||
434 | struct hlist_node *node; | ||
435 | unsigned long *sara = (unsigned long *)regs->rsp - 1; | ||
436 | |||
437 | tsk = arch_get_kprobe_task(sara); | ||
438 | head = kretprobe_inst_table_head(tsk); | ||
439 | |||
440 | hlist_for_each_entry(ri, node, head, hlist) { | ||
441 | if (ri->stack_addr == sara && ri->rp) { | ||
442 | if (ri->rp->handler) | ||
443 | ri->rp->handler(ri, regs); | ||
444 | } | ||
445 | } | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, | ||
450 | unsigned long flags) | ||
451 | { | ||
452 | struct kretprobe_instance *ri; | ||
453 | /* RA already popped */ | ||
454 | unsigned long *sara = ((unsigned long *)regs->rsp) - 1; | ||
455 | |||
456 | while ((ri = get_rp_inst(sara))) { | ||
457 | regs->rip = (unsigned long)ri->ret_addr; | ||
458 | recycle_rp_inst(ri); | ||
459 | } | ||
460 | regs->eflags &= ~TF_MASK; | ||
461 | } | ||
462 | |||
463 | /* | ||
320 | * Called after single-stepping. p->addr is the address of the | 464 | * Called after single-stepping. p->addr is the address of the |
321 | * instruction whose first byte has been replaced by the "int 3" | 465 | * instruction whose first byte has been replaced by the "int 3" |
322 | * instruction. To avoid the SMP problems that can occur when we | 466 | * instruction. To avoid the SMP problems that can occur when we |
@@ -401,13 +545,23 @@ int post_kprobe_handler(struct pt_regs *regs) | |||
401 | if (!kprobe_running()) | 545 | if (!kprobe_running()) |
402 | return 0; | 546 | return 0; |
403 | 547 | ||
404 | if (current_kprobe->post_handler) | 548 | if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { |
549 | kprobe_status = KPROBE_HIT_SSDONE; | ||
405 | current_kprobe->post_handler(current_kprobe, regs, 0); | 550 | current_kprobe->post_handler(current_kprobe, regs, 0); |
551 | } | ||
406 | 552 | ||
407 | resume_execution(current_kprobe, regs); | 553 | if (current_kprobe->post_handler != trampoline_post_handler) |
554 | resume_execution(current_kprobe, regs); | ||
408 | regs->eflags |= kprobe_saved_rflags; | 555 | regs->eflags |= kprobe_saved_rflags; |
409 | 556 | ||
410 | unlock_kprobes(); | 557 | /* Restore the original saved kprobes variables and continue. */ |
558 | if (kprobe_status == KPROBE_REENTER) { | ||
559 | restore_previous_kprobe(); | ||
560 | goto out; | ||
561 | } else { | ||
562 | unlock_kprobes(); | ||
563 | } | ||
564 | out: | ||
411 | preempt_enable_no_resched(); | 565 | preempt_enable_no_resched(); |
412 | 566 | ||
413 | /* | 567 | /* |
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 61a63be6b294..9c5aa2a790c7 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel_stat.h> | 23 | #include <linux/kernel_stat.h> |
24 | #include <linux/mc146818rtc.h> | 24 | #include <linux/mc146818rtc.h> |
25 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
26 | #include <linux/module.h> | ||
26 | 27 | ||
27 | #include <asm/smp.h> | 28 | #include <asm/smp.h> |
28 | #include <asm/mtrr.h> | 29 | #include <asm/mtrr.h> |
@@ -45,7 +46,8 @@ int acpi_found_madt; | |||
45 | int apic_version [MAX_APICS]; | 46 | int apic_version [MAX_APICS]; |
46 | unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; | 47 | unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; |
47 | int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; | 48 | int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; |
48 | cpumask_t pci_bus_to_cpumask [256] = { [0 ... 255] = CPU_MASK_ALL }; | 49 | unsigned char pci_bus_to_node [256]; |
50 | EXPORT_SYMBOL(pci_bus_to_node); | ||
49 | 51 | ||
50 | static int mp_current_pci_id = 0; | 52 | static int mp_current_pci_id = 0; |
51 | /* I/O APIC entries */ | 53 | /* I/O APIC entries */ |
@@ -904,11 +906,20 @@ void __init mp_config_acpi_legacy_irqs (void) | |||
904 | return; | 906 | return; |
905 | } | 907 | } |
906 | 908 | ||
909 | #define MAX_GSI_NUM 4096 | ||
910 | |||
907 | int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) | 911 | int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) |
908 | { | 912 | { |
909 | int ioapic = -1; | 913 | int ioapic = -1; |
910 | int ioapic_pin = 0; | 914 | int ioapic_pin = 0; |
911 | int idx, bit = 0; | 915 | int idx, bit = 0; |
916 | static int pci_irq = 16; | ||
917 | /* | ||
918 | * Mapping between Global System Interrupts, which | ||
919 | * represent all possible interrupts, to the IRQs | ||
920 | * assigned to actual devices. | ||
921 | */ | ||
922 | static int gsi_to_irq[MAX_GSI_NUM]; | ||
912 | 923 | ||
913 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) | 924 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) |
914 | return gsi; | 925 | return gsi; |
@@ -943,11 +954,21 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) | |||
943 | if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { | 954 | if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { |
944 | Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", | 955 | Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", |
945 | mp_ioapic_routing[ioapic].apic_id, ioapic_pin); | 956 | mp_ioapic_routing[ioapic].apic_id, ioapic_pin); |
946 | return gsi; | 957 | return gsi_to_irq[gsi]; |
947 | } | 958 | } |
948 | 959 | ||
949 | mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); | 960 | mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); |
950 | 961 | ||
962 | if (edge_level) { | ||
963 | /* | ||
964 | * For PCI devices assign IRQs in order, avoiding gaps | ||
965 | * due to unused I/O APIC pins. | ||
966 | */ | ||
967 | int irq = gsi; | ||
968 | gsi = pci_irq++; | ||
969 | gsi_to_irq[irq] = gsi; | ||
970 | } | ||
971 | |||
951 | io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, | 972 | io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, |
952 | edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, | 973 | edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, |
953 | active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); | 974 | active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index dce8bab4306c..e59d1f9d6163 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/ptrace.h> | 34 | #include <linux/ptrace.h> |
35 | #include <linux/utsname.h> | 35 | #include <linux/utsname.h> |
36 | #include <linux/random.h> | 36 | #include <linux/random.h> |
37 | #include <linux/kprobes.h> | ||
37 | 38 | ||
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | #include <asm/pgtable.h> | 40 | #include <asm/pgtable.h> |
@@ -293,6 +294,14 @@ void exit_thread(void) | |||
293 | { | 294 | { |
294 | struct task_struct *me = current; | 295 | struct task_struct *me = current; |
295 | struct thread_struct *t = &me->thread; | 296 | struct thread_struct *t = &me->thread; |
297 | |||
298 | /* | ||
299 | * Remove function-return probe instances associated with this task | ||
300 | * and put them back on the free list. Do not insert an exit probe for | ||
301 | * this function, it will be disabled by kprobe_flush_task if you do. | ||
302 | */ | ||
303 | kprobe_flush_task(me); | ||
304 | |||
296 | if (me->thread.io_bitmap_ptr) { | 305 | if (me->thread.io_bitmap_ptr) { |
297 | struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); | 306 | struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); |
298 | 307 | ||
@@ -312,6 +321,13 @@ void flush_thread(void) | |||
312 | struct task_struct *tsk = current; | 321 | struct task_struct *tsk = current; |
313 | struct thread_info *t = current_thread_info(); | 322 | struct thread_info *t = current_thread_info(); |
314 | 323 | ||
324 | /* | ||
325 | * Remove function-return probe instances associated with this task | ||
326 | * and put them back on the free list. Do not insert an exit probe for | ||
327 | * this function, it will be disabled by kprobe_flush_task if you do. | ||
328 | */ | ||
329 | kprobe_flush_task(tsk); | ||
330 | |||
315 | if (t->flags & _TIF_ABI_PENDING) | 331 | if (t->flags & _TIF_ABI_PENDING) |
316 | t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32); | 332 | t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32); |
317 | 333 | ||
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 99f038ede23c..000015dd5a8b 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
41 | #include <linux/kallsyms.h> | 41 | #include <linux/kallsyms.h> |
42 | #include <linux/edd.h> | 42 | #include <linux/edd.h> |
43 | #include <linux/mmzone.h> | ||
44 | |||
43 | #include <asm/mtrr.h> | 45 | #include <asm/mtrr.h> |
44 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
45 | #include <asm/system.h> | 47 | #include <asm/system.h> |
@@ -348,7 +350,7 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
348 | if (!memcmp(from, "mem=", 4)) | 350 | if (!memcmp(from, "mem=", 4)) |
349 | parse_memopt(from+4, &from); | 351 | parse_memopt(from+4, &from); |
350 | 352 | ||
351 | #ifdef CONFIG_DISCONTIGMEM | 353 | #ifdef CONFIG_NUMA |
352 | if (!memcmp(from, "numa=", 5)) | 354 | if (!memcmp(from, "numa=", 5)) |
353 | numa_setup(from+5); | 355 | numa_setup(from+5); |
354 | #endif | 356 | #endif |
@@ -377,17 +379,20 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
377 | *cmdline_p = command_line; | 379 | *cmdline_p = command_line; |
378 | } | 380 | } |
379 | 381 | ||
380 | #ifndef CONFIG_DISCONTIGMEM | 382 | #ifndef CONFIG_NUMA |
381 | static void __init contig_initmem_init(void) | 383 | static void __init |
384 | contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | ||
382 | { | 385 | { |
383 | unsigned long bootmap_size, bootmap; | 386 | unsigned long bootmap_size, bootmap; |
384 | bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; | 387 | |
385 | bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); | 388 | memory_present(0, start_pfn, end_pfn); |
386 | if (bootmap == -1L) | 389 | bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; |
387 | panic("Cannot find bootmem map of size %ld\n",bootmap_size); | 390 | bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); |
388 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); | 391 | if (bootmap == -1L) |
389 | e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); | 392 | panic("Cannot find bootmem map of size %ld\n",bootmap_size); |
390 | reserve_bootmem(bootmap, bootmap_size); | 393 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); |
394 | e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); | ||
395 | reserve_bootmem(bootmap, bootmap_size); | ||
391 | } | 396 | } |
392 | #endif | 397 | #endif |
393 | 398 | ||
@@ -554,10 +559,10 @@ void __init setup_arch(char **cmdline_p) | |||
554 | acpi_numa_init(); | 559 | acpi_numa_init(); |
555 | #endif | 560 | #endif |
556 | 561 | ||
557 | #ifdef CONFIG_DISCONTIGMEM | 562 | #ifdef CONFIG_NUMA |
558 | numa_initmem_init(0, end_pfn); | 563 | numa_initmem_init(0, end_pfn); |
559 | #else | 564 | #else |
560 | contig_initmem_init(); | 565 | contig_initmem_init(0, end_pfn); |
561 | #endif | 566 | #endif |
562 | 567 | ||
563 | /* Reserve direct mapping */ | 568 | /* Reserve direct mapping */ |
@@ -618,6 +623,8 @@ void __init setup_arch(char **cmdline_p) | |||
618 | } | 623 | } |
619 | } | 624 | } |
620 | #endif | 625 | #endif |
626 | |||
627 | sparse_init(); | ||
621 | paging_init(); | 628 | paging_init(); |
622 | 629 | ||
623 | check_ioapic(); | 630 | check_ioapic(); |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 429c0269dc4e..98b7ba95d581 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -34,9 +34,9 @@ | |||
34 | 34 | ||
35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
36 | 36 | ||
37 | void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 37 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
38 | sigset_t *set, struct pt_regs * regs); | 38 | sigset_t *set, struct pt_regs * regs); |
39 | void ia32_setup_frame(int sig, struct k_sigaction *ka, | 39 | int ia32_setup_frame(int sig, struct k_sigaction *ka, |
40 | sigset_t *set, struct pt_regs * regs); | 40 | sigset_t *set, struct pt_regs * regs); |
41 | 41 | ||
42 | asmlinkage long | 42 | asmlinkage long |
@@ -238,7 +238,7 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) | |||
238 | return (void __user *)round_down(rsp - size, 16); | 238 | return (void __user *)round_down(rsp - size, 16); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 241 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
242 | sigset_t *set, struct pt_regs * regs) | 242 | sigset_t *set, struct pt_regs * regs) |
243 | { | 243 | { |
244 | struct rt_sigframe __user *frame; | 244 | struct rt_sigframe __user *frame; |
@@ -327,20 +327,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
327 | current->comm, current->pid, frame, regs->rip, frame->pretcode); | 327 | current->comm, current->pid, frame, regs->rip, frame->pretcode); |
328 | #endif | 328 | #endif |
329 | 329 | ||
330 | return; | 330 | return 1; |
331 | 331 | ||
332 | give_sigsegv: | 332 | give_sigsegv: |
333 | force_sigsegv(sig, current); | 333 | force_sigsegv(sig, current); |
334 | return 0; | ||
334 | } | 335 | } |
335 | 336 | ||
336 | /* | 337 | /* |
337 | * OK, we're invoking a handler | 338 | * OK, we're invoking a handler |
338 | */ | 339 | */ |
339 | 340 | ||
340 | static void | 341 | static int |
341 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 342 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
342 | sigset_t *oldset, struct pt_regs *regs) | 343 | sigset_t *oldset, struct pt_regs *regs) |
343 | { | 344 | { |
345 | int ret; | ||
346 | |||
344 | #ifdef DEBUG_SIG | 347 | #ifdef DEBUG_SIG |
345 | printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", | 348 | printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", |
346 | current->pid, sig, | 349 | current->pid, sig, |
@@ -384,20 +387,22 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
384 | #ifdef CONFIG_IA32_EMULATION | 387 | #ifdef CONFIG_IA32_EMULATION |
385 | if (test_thread_flag(TIF_IA32)) { | 388 | if (test_thread_flag(TIF_IA32)) { |
386 | if (ka->sa.sa_flags & SA_SIGINFO) | 389 | if (ka->sa.sa_flags & SA_SIGINFO) |
387 | ia32_setup_rt_frame(sig, ka, info, oldset, regs); | 390 | ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs); |
388 | else | 391 | else |
389 | ia32_setup_frame(sig, ka, oldset, regs); | 392 | ret = ia32_setup_frame(sig, ka, oldset, regs); |
390 | } else | 393 | } else |
391 | #endif | 394 | #endif |
392 | setup_rt_frame(sig, ka, info, oldset, regs); | 395 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
393 | 396 | ||
394 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 397 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { |
395 | spin_lock_irq(¤t->sighand->siglock); | 398 | spin_lock_irq(¤t->sighand->siglock); |
396 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 399 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
397 | sigaddset(¤t->blocked,sig); | 400 | sigaddset(¤t->blocked,sig); |
398 | recalc_sigpending(); | 401 | recalc_sigpending(); |
399 | spin_unlock_irq(¤t->sighand->siglock); | 402 | spin_unlock_irq(¤t->sighand->siglock); |
400 | } | 403 | } |
404 | |||
405 | return ret; | ||
401 | } | 406 | } |
402 | 407 | ||
403 | /* | 408 | /* |
@@ -417,7 +422,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
417 | * kernel mode. Just return without doing anything | 422 | * kernel mode. Just return without doing anything |
418 | * if so. | 423 | * if so. |
419 | */ | 424 | */ |
420 | if ((regs->cs & 3) != 3) | 425 | if (!user_mode(regs)) |
421 | return 1; | 426 | return 1; |
422 | 427 | ||
423 | if (try_to_freeze(0)) | 428 | if (try_to_freeze(0)) |
@@ -434,11 +439,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
434 | * inside the kernel. | 439 | * inside the kernel. |
435 | */ | 440 | */ |
436 | if (current->thread.debugreg7) | 441 | if (current->thread.debugreg7) |
437 | asm volatile("movq %0,%%db7" : : "r" (current->thread.debugreg7)); | 442 | set_debugreg(current->thread.debugreg7, 7); |
438 | 443 | ||
439 | /* Whee! Actually deliver the signal. */ | 444 | /* Whee! Actually deliver the signal. */ |
440 | handle_signal(signr, &info, &ka, oldset, regs); | 445 | return handle_signal(signr, &info, &ka, oldset, regs); |
441 | return 1; | ||
442 | } | 446 | } |
443 | 447 | ||
444 | no_signal: | 448 | no_signal: |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index fb8c809b4cd9..66bf6ddeb0c3 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -64,6 +64,7 @@ static int notsc __initdata = 0; | |||
64 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ | 64 | unsigned int cpu_khz; /* TSC clocks / usec, not used here */ |
65 | static unsigned long hpet_period; /* fsecs / HPET clock */ | 65 | static unsigned long hpet_period; /* fsecs / HPET clock */ |
66 | unsigned long hpet_tick; /* HPET clocks / interrupt */ | 66 | unsigned long hpet_tick; /* HPET clocks / interrupt */ |
67 | static int hpet_use_timer; | ||
67 | unsigned long vxtime_hz = PIT_TICK_RATE; | 68 | unsigned long vxtime_hz = PIT_TICK_RATE; |
68 | int report_lost_ticks; /* command line option */ | 69 | int report_lost_ticks; /* command line option */ |
69 | unsigned long long monotonic_base; | 70 | unsigned long long monotonic_base; |
@@ -105,7 +106,9 @@ static inline unsigned int do_gettimeoffset_tsc(void) | |||
105 | 106 | ||
106 | static inline unsigned int do_gettimeoffset_hpet(void) | 107 | static inline unsigned int do_gettimeoffset_hpet(void) |
107 | { | 108 | { |
108 | return ((hpet_readl(HPET_COUNTER) - vxtime.last) * vxtime.quot) >> 32; | 109 | /* cap counter read to one tick to avoid inconsistencies */ |
110 | unsigned long counter = hpet_readl(HPET_COUNTER) - vxtime.last; | ||
111 | return (min(counter,hpet_tick) * vxtime.quot) >> 32; | ||
109 | } | 112 | } |
110 | 113 | ||
111 | unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; | 114 | unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; |
@@ -301,7 +304,7 @@ unsigned long long monotonic_clock(void) | |||
301 | 304 | ||
302 | last_offset = vxtime.last; | 305 | last_offset = vxtime.last; |
303 | base = monotonic_base; | 306 | base = monotonic_base; |
304 | this_offset = hpet_readl(HPET_T0_CMP) - hpet_tick; | 307 | this_offset = hpet_readl(HPET_COUNTER); |
305 | 308 | ||
306 | } while (read_seqretry(&xtime_lock, seq)); | 309 | } while (read_seqretry(&xtime_lock, seq)); |
307 | offset = (this_offset - last_offset); | 310 | offset = (this_offset - last_offset); |
@@ -377,7 +380,14 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
377 | 380 | ||
378 | write_seqlock(&xtime_lock); | 381 | write_seqlock(&xtime_lock); |
379 | 382 | ||
380 | if (vxtime.hpet_address) { | 383 | if (vxtime.hpet_address) |
384 | offset = hpet_readl(HPET_COUNTER); | ||
385 | |||
386 | if (hpet_use_timer) { | ||
387 | /* if we're using the hpet timer functionality, | ||
388 | * we can more accurately know the counter value | ||
389 | * when the timer interrupt occured. | ||
390 | */ | ||
381 | offset = hpet_readl(HPET_T0_CMP) - hpet_tick; | 391 | offset = hpet_readl(HPET_T0_CMP) - hpet_tick; |
382 | delay = hpet_readl(HPET_COUNTER) - offset; | 392 | delay = hpet_readl(HPET_COUNTER) - offset; |
383 | } else { | 393 | } else { |
@@ -803,17 +813,18 @@ static int hpet_timer_stop_set_go(unsigned long tick) | |||
803 | * Set up timer 0, as periodic with first interrupt to happen at hpet_tick, | 813 | * Set up timer 0, as periodic with first interrupt to happen at hpet_tick, |
804 | * and period also hpet_tick. | 814 | * and period also hpet_tick. |
805 | */ | 815 | */ |
806 | 816 | if (hpet_use_timer) { | |
807 | hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | | 817 | hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | |
808 | HPET_TN_32BIT, HPET_T0_CFG); | 818 | HPET_TN_32BIT, HPET_T0_CFG); |
809 | hpet_writel(hpet_tick, HPET_T0_CMP); | 819 | hpet_writel(hpet_tick, HPET_T0_CMP); |
810 | hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */ | 820 | hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */ |
811 | 821 | cfg |= HPET_CFG_LEGACY; | |
822 | } | ||
812 | /* | 823 | /* |
813 | * Go! | 824 | * Go! |
814 | */ | 825 | */ |
815 | 826 | ||
816 | cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY; | 827 | cfg |= HPET_CFG_ENABLE; |
817 | hpet_writel(cfg, HPET_CFG); | 828 | hpet_writel(cfg, HPET_CFG); |
818 | 829 | ||
819 | return 0; | 830 | return 0; |
@@ -834,8 +845,7 @@ static int hpet_init(void) | |||
834 | 845 | ||
835 | id = hpet_readl(HPET_ID); | 846 | id = hpet_readl(HPET_ID); |
836 | 847 | ||
837 | if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER) || | 848 | if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER)) |
838 | !(id & HPET_ID_LEGSUP)) | ||
839 | return -1; | 849 | return -1; |
840 | 850 | ||
841 | hpet_period = hpet_readl(HPET_PERIOD); | 851 | hpet_period = hpet_readl(HPET_PERIOD); |
@@ -845,6 +855,8 @@ static int hpet_init(void) | |||
845 | hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) / | 855 | hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) / |
846 | hpet_period; | 856 | hpet_period; |
847 | 857 | ||
858 | hpet_use_timer = (id & HPET_ID_LEGSUP); | ||
859 | |||
848 | return hpet_timer_stop_set_go(hpet_tick); | 860 | return hpet_timer_stop_set_go(hpet_tick); |
849 | } | 861 | } |
850 | 862 | ||
@@ -901,9 +913,11 @@ void __init time_init(void) | |||
901 | set_normalized_timespec(&wall_to_monotonic, | 913 | set_normalized_timespec(&wall_to_monotonic, |
902 | -xtime.tv_sec, -xtime.tv_nsec); | 914 | -xtime.tv_sec, -xtime.tv_nsec); |
903 | 915 | ||
904 | if (!hpet_init()) { | 916 | if (!hpet_init()) |
905 | vxtime_hz = (1000000000000000L + hpet_period / 2) / | 917 | vxtime_hz = (1000000000000000L + hpet_period / 2) / |
906 | hpet_period; | 918 | hpet_period; |
919 | |||
920 | if (hpet_use_timer) { | ||
907 | cpu_khz = hpet_calibrate_tsc(); | 921 | cpu_khz = hpet_calibrate_tsc(); |
908 | timename = "HPET"; | 922 | timename = "HPET"; |
909 | #ifdef CONFIG_X86_PM_TIMER | 923 | #ifdef CONFIG_X86_PM_TIMER |
@@ -968,7 +982,7 @@ void __init time_init_gtod(void) | |||
968 | if (unsynchronized_tsc()) | 982 | if (unsynchronized_tsc()) |
969 | notsc = 1; | 983 | notsc = 1; |
970 | if (vxtime.hpet_address && notsc) { | 984 | if (vxtime.hpet_address && notsc) { |
971 | timetype = "HPET"; | 985 | timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; |
972 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | 986 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; |
973 | vxtime.mode = VXTIME_HPET; | 987 | vxtime.mode = VXTIME_HPET; |
974 | do_gettimeoffset = do_gettimeoffset_hpet; | 988 | do_gettimeoffset = do_gettimeoffset_hpet; |
@@ -983,7 +997,7 @@ void __init time_init_gtod(void) | |||
983 | printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n"); | 997 | printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n"); |
984 | #endif | 998 | #endif |
985 | } else { | 999 | } else { |
986 | timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; | 1000 | timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; |
987 | vxtime.mode = VXTIME_TSC; | 1001 | vxtime.mode = VXTIME_TSC; |
988 | } | 1002 | } |
989 | 1003 | ||
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 3dfec8fdabcd..121646fc43f6 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -274,7 +274,7 @@ EXPORT_SYMBOL(dump_stack); | |||
274 | void show_registers(struct pt_regs *regs) | 274 | void show_registers(struct pt_regs *regs) |
275 | { | 275 | { |
276 | int i; | 276 | int i; |
277 | int in_kernel = (regs->cs & 3) == 0; | 277 | int in_kernel = !user_mode(regs); |
278 | unsigned long rsp; | 278 | unsigned long rsp; |
279 | const int cpu = safe_smp_processor_id(); | 279 | const int cpu = safe_smp_processor_id(); |
280 | struct task_struct *cur = cpu_pda[cpu].pcurrent; | 280 | struct task_struct *cur = cpu_pda[cpu].pcurrent; |
@@ -318,7 +318,7 @@ void handle_BUG(struct pt_regs *regs) | |||
318 | struct bug_frame f; | 318 | struct bug_frame f; |
319 | char tmp; | 319 | char tmp; |
320 | 320 | ||
321 | if (regs->cs & 3) | 321 | if (user_mode(regs)) |
322 | return; | 322 | return; |
323 | if (__copy_from_user(&f, (struct bug_frame *) regs->rip, | 323 | if (__copy_from_user(&f, (struct bug_frame *) regs->rip, |
324 | sizeof(struct bug_frame))) | 324 | sizeof(struct bug_frame))) |
@@ -437,7 +437,7 @@ static void do_trap(int trapnr, int signr, char *str, | |||
437 | } | 437 | } |
438 | #endif | 438 | #endif |
439 | 439 | ||
440 | if ((regs->cs & 3) != 0) { | 440 | if (user_mode(regs)) { |
441 | struct task_struct *tsk = current; | 441 | struct task_struct *tsk = current; |
442 | 442 | ||
443 | if (exception_trace && unhandled_signal(tsk, signr)) | 443 | if (exception_trace && unhandled_signal(tsk, signr)) |
@@ -522,7 +522,7 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) | |||
522 | } | 522 | } |
523 | #endif | 523 | #endif |
524 | 524 | ||
525 | if ((regs->cs & 3)!=0) { | 525 | if (user_mode(regs)) { |
526 | struct task_struct *tsk = current; | 526 | struct task_struct *tsk = current; |
527 | 527 | ||
528 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) | 528 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) |
@@ -638,7 +638,7 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
638 | if (eregs == (struct pt_regs *)eregs->rsp) | 638 | if (eregs == (struct pt_regs *)eregs->rsp) |
639 | ; | 639 | ; |
640 | /* Exception from user space */ | 640 | /* Exception from user space */ |
641 | else if (eregs->cs & 3) | 641 | else if (user_mode(eregs)) |
642 | regs = ((struct pt_regs *)current->thread.rsp0) - 1; | 642 | regs = ((struct pt_regs *)current->thread.rsp0) - 1; |
643 | /* Exception from kernel and interrupts are enabled. Move to | 643 | /* Exception from kernel and interrupts are enabled. Move to |
644 | kernel process stack. */ | 644 | kernel process stack. */ |
@@ -669,7 +669,7 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code) | |||
669 | } | 669 | } |
670 | #endif | 670 | #endif |
671 | 671 | ||
672 | asm("movq %%db6,%0" : "=r" (condition)); | 672 | get_debugreg(condition, 6); |
673 | 673 | ||
674 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, | 674 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, |
675 | SIGTRAP) == NOTIFY_STOP) | 675 | SIGTRAP) == NOTIFY_STOP) |
@@ -697,7 +697,7 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code) | |||
697 | * allowing programs to debug themselves without the ptrace() | 697 | * allowing programs to debug themselves without the ptrace() |
698 | * interface. | 698 | * interface. |
699 | */ | 699 | */ |
700 | if ((regs->cs & 3) == 0) | 700 | if (!user_mode(regs)) |
701 | goto clear_TF_reenable; | 701 | goto clear_TF_reenable; |
702 | /* | 702 | /* |
703 | * Was the TF flag set by a debugger? If so, clear it now, | 703 | * Was the TF flag set by a debugger? If so, clear it now, |
@@ -715,13 +715,13 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code) | |||
715 | info.si_signo = SIGTRAP; | 715 | info.si_signo = SIGTRAP; |
716 | info.si_errno = 0; | 716 | info.si_errno = 0; |
717 | info.si_code = TRAP_BRKPT; | 717 | info.si_code = TRAP_BRKPT; |
718 | if ((regs->cs & 3) == 0) | 718 | if (!user_mode(regs)) |
719 | goto clear_dr7; | 719 | goto clear_dr7; |
720 | 720 | ||
721 | info.si_addr = (void __user *)regs->rip; | 721 | info.si_addr = (void __user *)regs->rip; |
722 | force_sig_info(SIGTRAP, &info, tsk); | 722 | force_sig_info(SIGTRAP, &info, tsk); |
723 | clear_dr7: | 723 | clear_dr7: |
724 | asm volatile("movq %0,%%db7"::"r"(0UL)); | 724 | set_debugreg(0UL, 7); |
725 | return; | 725 | return; |
726 | 726 | ||
727 | clear_TF_reenable: | 727 | clear_TF_reenable: |
@@ -756,7 +756,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs) | |||
756 | unsigned short cwd, swd; | 756 | unsigned short cwd, swd; |
757 | 757 | ||
758 | conditional_sti(regs); | 758 | conditional_sti(regs); |
759 | if ((regs->cs & 3) == 0 && | 759 | if (!user_mode(regs) && |
760 | kernel_math_error(regs, "kernel x87 math error")) | 760 | kernel_math_error(regs, "kernel x87 math error")) |
761 | return; | 761 | return; |
762 | 762 | ||
@@ -822,7 +822,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) | |||
822 | unsigned short mxcsr; | 822 | unsigned short mxcsr; |
823 | 823 | ||
824 | conditional_sti(regs); | 824 | conditional_sti(regs); |
825 | if ((regs->cs & 3) == 0 && | 825 | if (!user_mode(regs) && |
826 | kernel_math_error(regs, "kernel simd math error")) | 826 | kernel_math_error(regs, "kernel simd math error")) |
827 | return; | 827 | return; |
828 | 828 | ||
diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c index aed61a668a1b..33a873a3c223 100644 --- a/arch/x86_64/lib/delay.c +++ b/arch/x86_64/lib/delay.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <asm/delay.h> | 14 | #include <asm/delay.h> |
15 | #include <asm/msr.h> | ||
15 | 16 | ||
16 | #ifdef CONFIG_SMP | 17 | #ifdef CONFIG_SMP |
17 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
@@ -19,6 +20,12 @@ | |||
19 | 20 | ||
20 | int x86_udelay_tsc = 0; /* Delay via TSC */ | 21 | int x86_udelay_tsc = 0; /* Delay via TSC */ |
21 | 22 | ||
23 | int read_current_timer(unsigned long *timer_value) | ||
24 | { | ||
25 | rdtscll(*timer_value); | ||
26 | return 0; | ||
27 | } | ||
28 | |||
22 | void __delay(unsigned long loops) | 29 | void __delay(unsigned long loops) |
23 | { | 30 | { |
24 | unsigned bclock, now; | 31 | unsigned bclock, now; |
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile index 66c354ad80ca..1d232a87f113 100644 --- a/arch/x86_64/mm/Makefile +++ b/arch/x86_64/mm/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-y := init.o fault.o ioremap.o extable.o pageattr.o | 5 | obj-y := init.o fault.o ioremap.o extable.o pageattr.o |
6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
7 | obj-$(CONFIG_DISCONTIGMEM) += numa.o | 7 | obj-$(CONFIG_NUMA) += numa.o |
8 | obj-$(CONFIG_K8_NUMA) += k8topology.o | 8 | obj-$(CONFIG_K8_NUMA) += k8topology.o |
9 | obj-$(CONFIG_ACPI_NUMA) += srat.o | 9 | obj-$(CONFIG_ACPI_NUMA) += srat.o |
10 | 10 | ||
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 57d3ab15a5c7..2f187986f940 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -74,7 +74,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, | |||
74 | instr = (unsigned char *)convert_rip_to_linear(current, regs); | 74 | instr = (unsigned char *)convert_rip_to_linear(current, regs); |
75 | max_instr = instr + 15; | 75 | max_instr = instr + 15; |
76 | 76 | ||
77 | if ((regs->cs & 3) != 0 && instr >= (unsigned char *)TASK_SIZE) | 77 | if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE) |
78 | return 0; | 78 | return 0; |
79 | 79 | ||
80 | while (scan_more && instr < max_instr) { | 80 | while (scan_more && instr < max_instr) { |
@@ -106,7 +106,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, | |||
106 | /* Could check the LDT for lm, but for now it's good | 106 | /* Could check the LDT for lm, but for now it's good |
107 | enough to assume that long mode only uses well known | 107 | enough to assume that long mode only uses well known |
108 | segments or kernel. */ | 108 | segments or kernel. */ |
109 | scan_more = ((regs->cs & 3) == 0) || (regs->cs == __USER_CS); | 109 | scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS); |
110 | break; | 110 | break; |
111 | 111 | ||
112 | case 0x60: | 112 | case 0x60: |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index dbe53b4c7e66..72e4b364ed73 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -318,7 +318,7 @@ void zap_low_mappings(void) | |||
318 | flush_tlb_all(); | 318 | flush_tlb_all(); |
319 | } | 319 | } |
320 | 320 | ||
321 | #ifndef CONFIG_DISCONTIGMEM | 321 | #ifndef CONFIG_NUMA |
322 | void __init paging_init(void) | 322 | void __init paging_init(void) |
323 | { | 323 | { |
324 | { | 324 | { |
@@ -427,13 +427,16 @@ void __init mem_init(void) | |||
427 | reservedpages = 0; | 427 | reservedpages = 0; |
428 | 428 | ||
429 | /* this will put all low memory onto the freelists */ | 429 | /* this will put all low memory onto the freelists */ |
430 | #ifdef CONFIG_DISCONTIGMEM | 430 | #ifdef CONFIG_NUMA |
431 | totalram_pages += numa_free_all_bootmem(); | 431 | totalram_pages += numa_free_all_bootmem(); |
432 | tmp = 0; | 432 | tmp = 0; |
433 | /* should count reserved pages here for all nodes */ | 433 | /* should count reserved pages here for all nodes */ |
434 | #else | 434 | #else |
435 | |||
436 | #ifdef CONFIG_FLATMEM | ||
435 | max_mapnr = end_pfn; | 437 | max_mapnr = end_pfn; |
436 | if (!mem_map) BUG(); | 438 | if (!mem_map) BUG(); |
439 | #endif | ||
437 | 440 | ||
438 | totalram_pages += free_all_bootmem(); | 441 | totalram_pages += free_all_bootmem(); |
439 | 442 | ||
@@ -515,7 +518,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
515 | void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | 518 | void __init reserve_bootmem_generic(unsigned long phys, unsigned len) |
516 | { | 519 | { |
517 | /* Should check here against the e820 map to avoid double free */ | 520 | /* Should check here against the e820 map to avoid double free */ |
518 | #ifdef CONFIG_DISCONTIGMEM | 521 | #ifdef CONFIG_NUMA |
519 | int nid = phys_to_nid(phys); | 522 | int nid = phys_to_nid(phys); |
520 | reserve_bootmem_node(NODE_DATA(nid), phys, len); | 523 | reserve_bootmem_node(NODE_DATA(nid), phys, len); |
521 | #else | 524 | #else |
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index 58aac23760ef..6972df480d2b 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c | |||
@@ -178,7 +178,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l | |||
178 | if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS) | 178 | if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS) |
179 | return (__force void __iomem *)phys_to_virt(phys_addr); | 179 | return (__force void __iomem *)phys_to_virt(phys_addr); |
180 | 180 | ||
181 | #ifndef CONFIG_DISCONTIGMEM | 181 | #ifdef CONFIG_FLATMEM |
182 | /* | 182 | /* |
183 | * Don't allow anybody to remap normal RAM that we're using.. | 183 | * Don't allow anybody to remap normal RAM that we're using.. |
184 | */ | 184 | */ |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index fd9f25d7a6c4..84cde796ecb1 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -66,6 +66,13 @@ int __init compute_hash_shift(struct node *nodes, int numnodes) | |||
66 | return -1; | 66 | return -1; |
67 | } | 67 | } |
68 | 68 | ||
69 | #ifdef CONFIG_SPARSEMEM | ||
70 | int early_pfn_to_nid(unsigned long pfn) | ||
71 | { | ||
72 | return phys_to_nid(pfn << PAGE_SHIFT); | ||
73 | } | ||
74 | #endif | ||
75 | |||
69 | /* Initialize bootmem allocator for a node */ | 76 | /* Initialize bootmem allocator for a node */ |
70 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) | 77 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) |
71 | { | 78 | { |
@@ -80,6 +87,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
80 | start_pfn = start >> PAGE_SHIFT; | 87 | start_pfn = start >> PAGE_SHIFT; |
81 | end_pfn = end >> PAGE_SHIFT; | 88 | end_pfn = end >> PAGE_SHIFT; |
82 | 89 | ||
90 | memory_present(nodeid, start_pfn, end_pfn); | ||
83 | nodedata_phys = find_e820_area(start, end, pgdat_size); | 91 | nodedata_phys = find_e820_area(start, end, pgdat_size); |
84 | if (nodedata_phys == -1L) | 92 | if (nodedata_phys == -1L) |
85 | panic("Cannot find memory pgdat in node %d\n", nodeid); | 93 | panic("Cannot find memory pgdat in node %d\n", nodeid); |
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c index 62349c78db57..7e7d0c2a0025 100644 --- a/arch/x86_64/pci/k8-bus.c +++ b/arch/x86_64/pci/k8-bus.c | |||
@@ -53,25 +53,11 @@ fill_mp_bus_to_cpumask(void) | |||
53 | for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); | 53 | for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); |
54 | j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); | 54 | j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); |
55 | j++) | 55 | j++) |
56 | pci_bus_to_cpumask[j] = | 56 | pci_bus_to_node[j] = NODE_ID(nid); |
57 | node_to_cpumask(NODE_ID(nid)); | ||
58 | } | 57 | } |
59 | } | 58 | } |
60 | } | 59 | } |
61 | 60 | ||
62 | /* quick sanity check */ | ||
63 | printed = 0; | ||
64 | for (i = 0; i < 256; i++) { | ||
65 | if (cpus_empty(pci_bus_to_cpumask[i])) { | ||
66 | pci_bus_to_cpumask[i] = CPU_MASK_ALL; | ||
67 | if (printed) | ||
68 | continue; | ||
69 | printk(KERN_ERR | ||
70 | "k8-bus.c: some busses have empty cpu mask\n"); | ||
71 | printed = 1; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | return 0; | 61 | return 0; |
76 | } | 62 | } |
77 | 63 | ||