diff options
author | Paul Mackerras <paulus@samba.org> | 2006-08-31 01:45:48 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-08-31 01:45:48 -0400 |
commit | aa43f77939c97bf9d3580c6a5e71a5a40290e451 (patch) | |
tree | 095c0b8b3da4b6554a3f8ef4b39240a5d9216d4d /arch/x86_64/kernel | |
parent | 2818c5dec5e28d65d52afbb7695bbbafe6377ee5 (diff) | |
parent | 4c15343167b5febe7bb0ba96aad5bef42ae94d3b (diff) |
Merge branch 'merge'
Diffstat (limited to 'arch/x86_64/kernel')
-rw-r--r-- | arch/x86_64/kernel/e820.c | 35 | ||||
-rw-r--r-- | arch/x86_64/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/x86_64/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/x86_64/kernel/init_task.c | 5 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup.c | 6 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup64.c | 3 | ||||
-rw-r--r-- | arch/x86_64/kernel/traps.c | 32 |
7 files changed, 37 insertions, 48 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index e56c2adf57a4..764bf23c7103 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -71,7 +71,11 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) | |||
71 | #endif | 71 | #endif |
72 | /* kernel code + 640k memory hole (later should not be needed, but | 72 | /* kernel code + 640k memory hole (later should not be needed, but |
73 | be paranoid for now) */ | 73 | be paranoid for now) */ |
74 | if (last >= 640*1024 && addr < __pa_symbol(&_end)) { | 74 | if (last >= 640*1024 && addr < 1024*1024) { |
75 | *addrp = 1024*1024; | ||
76 | return 1; | ||
77 | } | ||
78 | if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { | ||
75 | *addrp = __pa_symbol(&_end); | 79 | *addrp = __pa_symbol(&_end); |
76 | return 1; | 80 | return 1; |
77 | } | 81 | } |
@@ -104,35 +108,6 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type) | |||
104 | return 0; | 108 | return 0; |
105 | } | 109 | } |
106 | 110 | ||
107 | /* | ||
108 | * This function checks if the entire range <start,end> is mapped with type. | ||
109 | * | ||
110 | * Note: this function only works correct if the e820 table is sorted and | ||
111 | * not-overlapping, which is the case | ||
112 | */ | ||
113 | int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | ||
114 | { | ||
115 | int i; | ||
116 | for (i = 0; i < e820.nr_map; i++) { | ||
117 | struct e820entry *ei = &e820.map[i]; | ||
118 | if (type && ei->type != type) | ||
119 | continue; | ||
120 | /* is the region (part) in overlap with the current region ?*/ | ||
121 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
122 | continue; | ||
123 | |||
124 | /* if the region is at the beginning of <start,end> we move | ||
125 | * start to the end of the region since it's ok until there | ||
126 | */ | ||
127 | if (ei->addr <= start) | ||
128 | start = ei->addr + ei->size; | ||
129 | /* if start is now at or beyond end, we're done, full coverage */ | ||
130 | if (start >= end) | ||
131 | return 1; /* we're done */ | ||
132 | } | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | /* | 111 | /* |
137 | * Find a free area in a specific range. | 112 | * Find a free area in a specific range. |
138 | */ | 113 | */ |
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 6f810424df44..aa8d8939abc1 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -973,6 +973,8 @@ ENTRY(kernel_thread) | |||
973 | ENDPROC(kernel_thread) | 973 | ENDPROC(kernel_thread) |
974 | 974 | ||
975 | child_rip: | 975 | child_rip: |
976 | pushq $0 # fake return address | ||
977 | CFI_STARTPROC | ||
976 | /* | 978 | /* |
977 | * Here we are in the child and the registers are set as they were | 979 | * Here we are in the child and the registers are set as they were |
978 | * at kernel_thread() invocation in the parent. | 980 | * at kernel_thread() invocation in the parent. |
@@ -983,6 +985,7 @@ child_rip: | |||
983 | # exit | 985 | # exit |
984 | xorl %edi, %edi | 986 | xorl %edi, %edi |
985 | call do_exit | 987 | call do_exit |
988 | CFI_ENDPROC | ||
986 | ENDPROC(child_rip) | 989 | ENDPROC(child_rip) |
987 | 990 | ||
988 | /* | 991 | /* |
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 6df05e6034fa..c9739ca81d06 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -191,6 +191,7 @@ startup_64: | |||
191 | * jump | 191 | * jump |
192 | */ | 192 | */ |
193 | movq initial_code(%rip),%rax | 193 | movq initial_code(%rip),%rax |
194 | pushq $0 # fake return address | ||
194 | jmp *%rax | 195 | jmp *%rax |
195 | 196 | ||
196 | /* SMP bootup changes these two */ | 197 | /* SMP bootup changes these two */ |
diff --git a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c index ce31d904d601..3dc5854ba21e 100644 --- a/arch/x86_64/kernel/init_task.c +++ b/arch/x86_64/kernel/init_task.c | |||
@@ -46,4 +46,9 @@ EXPORT_SYMBOL(init_task); | |||
46 | */ | 46 | */ |
47 | DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; | 47 | DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; |
48 | 48 | ||
49 | /* Copies of the original ist values from the tss are only accessed during | ||
50 | * debugging, no special alignment required. | ||
51 | */ | ||
52 | DEFINE_PER_CPU(struct orig_ist, orig_ist); | ||
53 | |||
49 | #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) | 54 | #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 8a099ff1f8bc..34afad704824 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -521,8 +521,6 @@ static void discover_ebda(void) | |||
521 | 521 | ||
522 | void __init setup_arch(char **cmdline_p) | 522 | void __init setup_arch(char **cmdline_p) |
523 | { | 523 | { |
524 | unsigned long kernel_end; | ||
525 | |||
526 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); | 524 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); |
527 | screen_info = SCREEN_INFO; | 525 | screen_info = SCREEN_INFO; |
528 | edid_info = EDID_INFO; | 526 | edid_info = EDID_INFO; |
@@ -596,8 +594,8 @@ void __init setup_arch(char **cmdline_p) | |||
596 | (table_end - table_start) << PAGE_SHIFT); | 594 | (table_end - table_start) << PAGE_SHIFT); |
597 | 595 | ||
598 | /* reserve kernel */ | 596 | /* reserve kernel */ |
599 | kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE); | 597 | reserve_bootmem_generic(__pa_symbol(&_text), |
600 | reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY); | 598 | __pa_symbol(&_end) - __pa_symbol(&_text)); |
601 | 599 | ||
602 | /* | 600 | /* |
603 | * reserve physical page 0 - it's a special BIOS page on many boxes, | 601 | * reserve physical page 0 - it's a special BIOS page on many boxes, |
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 6fe58a634b5f..417de564456e 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
@@ -189,6 +189,7 @@ void __cpuinit cpu_init (void) | |||
189 | { | 189 | { |
190 | int cpu = stack_smp_processor_id(); | 190 | int cpu = stack_smp_processor_id(); |
191 | struct tss_struct *t = &per_cpu(init_tss, cpu); | 191 | struct tss_struct *t = &per_cpu(init_tss, cpu); |
192 | struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); | ||
192 | unsigned long v; | 193 | unsigned long v; |
193 | char *estacks = NULL; | 194 | char *estacks = NULL; |
194 | struct task_struct *me; | 195 | struct task_struct *me; |
@@ -256,7 +257,7 @@ void __cpuinit cpu_init (void) | |||
256 | estacks += EXCEPTION_STKSZ; | 257 | estacks += EXCEPTION_STKSZ; |
257 | break; | 258 | break; |
258 | } | 259 | } |
259 | t->ist[v] = (unsigned long)estacks; | 260 | orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; |
260 | } | 261 | } |
261 | 262 | ||
262 | t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap); | 263 | t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap); |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 4e9938dee060..b1249774d1e8 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -107,7 +107,11 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | static int kstack_depth_to_print = 12; | 109 | static int kstack_depth_to_print = 12; |
110 | #ifdef CONFIG_STACK_UNWIND | ||
110 | static int call_trace = 1; | 111 | static int call_trace = 1; |
112 | #else | ||
113 | #define call_trace (-1) | ||
114 | #endif | ||
111 | 115 | ||
112 | #ifdef CONFIG_KALLSYMS | 116 | #ifdef CONFIG_KALLSYMS |
113 | # include <linux/kallsyms.h> | 117 | # include <linux/kallsyms.h> |
@@ -174,7 +178,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
174 | break; | 178 | break; |
175 | #endif | 179 | #endif |
176 | default: | 180 | default: |
177 | end = per_cpu(init_tss, cpu).ist[k]; | 181 | end = per_cpu(orig_ist, cpu).ist[k]; |
178 | break; | 182 | break; |
179 | } | 183 | } |
180 | /* | 184 | /* |
@@ -274,21 +278,21 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s | |||
274 | if (unwind_init_blocked(&info, tsk) == 0) | 278 | if (unwind_init_blocked(&info, tsk) == 0) |
275 | unw_ret = show_trace_unwind(&info, NULL); | 279 | unw_ret = show_trace_unwind(&info, NULL); |
276 | } | 280 | } |
277 | if (unw_ret > 0 && !arch_unw_user_mode(&info)) { | 281 | if (unw_ret > 0) { |
278 | #ifdef CONFIG_STACK_UNWIND | 282 | if (call_trace == 1 && !arch_unw_user_mode(&info)) { |
279 | unsigned long rip = info.regs.rip; | 283 | print_symbol("DWARF2 unwinder stuck at %s\n", |
280 | print_symbol("DWARF2 unwinder stuck at %s\n", rip); | 284 | UNW_PC(&info)); |
281 | if (call_trace == 1) { | 285 | if ((long)UNW_SP(&info) < 0) { |
282 | printk("Leftover inexact backtrace:\n"); | 286 | printk("Leftover inexact backtrace:\n"); |
283 | stack = (unsigned long *)info.regs.rsp; | 287 | stack = (unsigned long *)UNW_SP(&info); |
284 | } else if (call_trace > 1) | 288 | } else |
289 | printk("Full inexact backtrace again:\n"); | ||
290 | } else if (call_trace >= 1) | ||
285 | return; | 291 | return; |
286 | else | 292 | else |
287 | printk("Full inexact backtrace again:\n"); | 293 | printk("Full inexact backtrace again:\n"); |
288 | #else | 294 | } else |
289 | printk("Inexact backtrace:\n"); | 295 | printk("Inexact backtrace:\n"); |
290 | #endif | ||
291 | } | ||
292 | } | 296 | } |
293 | 297 | ||
294 | /* | 298 | /* |
@@ -529,7 +533,7 @@ void __kprobes oops_end(unsigned long flags) | |||
529 | /* Nest count reaches zero, release the lock. */ | 533 | /* Nest count reaches zero, release the lock. */ |
530 | spin_unlock_irqrestore(&die_lock, flags); | 534 | spin_unlock_irqrestore(&die_lock, flags); |
531 | if (panic_on_oops) | 535 | if (panic_on_oops) |
532 | panic("Fatal exception: panic_on_oops"); | 536 | panic("Fatal exception"); |
533 | } | 537 | } |
534 | 538 | ||
535 | void __kprobes __die(const char * str, struct pt_regs * regs, long err) | 539 | void __kprobes __die(const char * str, struct pt_regs * regs, long err) |
@@ -1120,6 +1124,7 @@ static int __init kstack_setup(char *s) | |||
1120 | } | 1124 | } |
1121 | __setup("kstack=", kstack_setup); | 1125 | __setup("kstack=", kstack_setup); |
1122 | 1126 | ||
1127 | #ifdef CONFIG_STACK_UNWIND | ||
1123 | static int __init call_trace_setup(char *s) | 1128 | static int __init call_trace_setup(char *s) |
1124 | { | 1129 | { |
1125 | if (strcmp(s, "old") == 0) | 1130 | if (strcmp(s, "old") == 0) |
@@ -1133,3 +1138,4 @@ static int __init call_trace_setup(char *s) | |||
1133 | return 1; | 1138 | return 1; |
1134 | } | 1139 | } |
1135 | __setup("call_trace=", call_trace_setup); | 1140 | __setup("call_trace=", call_trace_setup); |
1141 | #endif | ||