diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/head_64.S | 48 | ||||
-rw-r--r-- | arch/x86/kernel/setup64.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/x8664_ksyms_64.c | 5 |
5 files changed, 26 insertions, 63 deletions
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 918a2711aff6..32f5a114d1a2 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -203,7 +203,7 @@ ENTRY(secondary_startup_64) | |||
203 | * addresses where we're currently running on. We have to do that here | 203 | * addresses where we're currently running on. We have to do that here |
204 | * because in 32bit we couldn't load a 64bit linear address. | 204 | * because in 32bit we couldn't load a 64bit linear address. |
205 | */ | 205 | */ |
206 | lgdt cpu_gdt_descr(%rip) | 206 | lgdt early_gdt_descr(%rip) |
207 | 207 | ||
208 | /* set up data segments. actually 0 would do too */ | 208 | /* set up data segments. actually 0 would do too */ |
209 | movl $__KERNEL_DS,%eax | 209 | movl $__KERNEL_DS,%eax |
@@ -391,54 +391,16 @@ NEXT_PAGE(level2_spare_pgt) | |||
391 | 391 | ||
392 | .data | 392 | .data |
393 | .align 16 | 393 | .align 16 |
394 | .globl cpu_gdt_descr | 394 | .globl early_gdt_descr |
395 | cpu_gdt_descr: | 395 | early_gdt_descr: |
396 | .word gdt_end-cpu_gdt_table-1 | 396 | .word GDT_ENTRIES*8-1 |
397 | gdt: | 397 | .quad per_cpu__gdt_page |
398 | .quad cpu_gdt_table | ||
399 | #ifdef CONFIG_SMP | ||
400 | .rept NR_CPUS-1 | ||
401 | .word 0 | ||
402 | .quad 0 | ||
403 | .endr | ||
404 | #endif | ||
405 | 398 | ||
406 | ENTRY(phys_base) | 399 | ENTRY(phys_base) |
407 | /* This must match the first entry in level2_kernel_pgt */ | 400 | /* This must match the first entry in level2_kernel_pgt */ |
408 | .quad 0x0000000000000000 | 401 | .quad 0x0000000000000000 |
409 | 402 | ||
410 | /* We need valid kernel segments for data and code in long mode too | ||
411 | * IRET will check the segment types kkeil 2000/10/28 | ||
412 | * Also sysret mandates a special GDT layout | ||
413 | */ | ||
414 | |||
415 | .section .data.page_aligned, "aw" | ||
416 | .align PAGE_SIZE | ||
417 | |||
418 | /* The TLS descriptors are currently at a different place compared to i386. | ||
419 | Hopefully nobody expects them at a fixed place (Wine?) */ | ||
420 | 403 | ||
421 | ENTRY(cpu_gdt_table) | ||
422 | .quad 0x0000000000000000 /* NULL descriptor */ | ||
423 | .quad 0x00cf9b000000ffff /* __KERNEL32_CS */ | ||
424 | .quad 0x00af9b000000ffff /* __KERNEL_CS */ | ||
425 | .quad 0x00cf93000000ffff /* __KERNEL_DS */ | ||
426 | .quad 0x00cffb000000ffff /* __USER32_CS */ | ||
427 | .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */ | ||
428 | .quad 0x00affb000000ffff /* __USER_CS */ | ||
429 | .quad 0x0 /* unused */ | ||
430 | .quad 0,0 /* TSS */ | ||
431 | .quad 0,0 /* LDT */ | ||
432 | .quad 0,0,0 /* three TLS descriptors */ | ||
433 | .quad 0x0000f40000000000 /* node/CPU stored in limit */ | ||
434 | gdt_end: | ||
435 | /* asm/segment.h:GDT_ENTRIES must match this */ | ||
436 | /* This should be a multiple of the cache line size */ | ||
437 | /* GDTs of other CPUs are now dynamically allocated */ | ||
438 | |||
439 | /* zero the remaining page */ | ||
440 | .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0 | ||
441 | |||
442 | .section .bss, "aw", @nobits | 404 | .section .bss, "aw", @nobits |
443 | .align L1_CACHE_BYTES | 405 | .align L1_CACHE_BYTES |
444 | ENTRY(idt_table) | 406 | ENTRY(idt_table) |
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index fc1a56da8240..70ff07186772 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c | |||
@@ -202,11 +202,8 @@ void __cpuinit cpu_init (void) | |||
202 | * Initialize the per-CPU GDT with the boot GDT, | 202 | * Initialize the per-CPU GDT with the boot GDT, |
203 | * and set up the GDT descriptor: | 203 | * and set up the GDT descriptor: |
204 | */ | 204 | */ |
205 | if (cpu) | ||
206 | memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE); | ||
207 | 205 | ||
208 | cpu_gdt_descr[cpu].size = GDT_SIZE; | 206 | switch_to_new_gdt(); |
209 | load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]); | ||
210 | load_idt((const struct desc_ptr *)&idt_descr); | 207 | load_idt((const struct desc_ptr *)&idt_descr); |
211 | 208 | ||
212 | memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); | 209 | memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 504caeaffd58..a93300de4da9 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -81,8 +81,6 @@ | |||
81 | #define ARCH_SETUP | 81 | #define ARCH_SETUP |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | #include "cpu/cpu.h" | ||
85 | |||
86 | /* | 84 | /* |
87 | * Machine setup.. | 85 | * Machine setup.. |
88 | */ | 86 | */ |
@@ -228,6 +226,23 @@ static inline void copy_edd(void) | |||
228 | } | 226 | } |
229 | #endif | 227 | #endif |
230 | 228 | ||
229 | /* Overridden in paravirt.c if CONFIG_PARAVIRT */ | ||
230 | void __attribute__((weak)) __init memory_setup(void) | ||
231 | { | ||
232 | machine_specific_memory_setup(); | ||
233 | } | ||
234 | |||
235 | /* Current gdt points %fs at the "master" per-cpu area: after this, | ||
236 | * it's on the real one. */ | ||
237 | void switch_to_new_gdt(void) | ||
238 | { | ||
239 | struct desc_ptr gdt_descr; | ||
240 | |||
241 | gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); | ||
242 | gdt_descr.size = GDT_SIZE - 1; | ||
243 | load_gdt(&gdt_descr); | ||
244 | } | ||
245 | |||
231 | /* | 246 | /* |
232 | * setup_arch - architecture-specific boot-time initializations | 247 | * setup_arch - architecture-specific boot-time initializations |
233 | * | 248 | * |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a71e3cad5470..fe2bd515d6cc 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -849,14 +849,8 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
849 | .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), | 849 | .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), |
850 | }; | 850 | }; |
851 | INIT_WORK(&c_idle.work, do_fork_idle); | 851 | INIT_WORK(&c_idle.work, do_fork_idle); |
852 | #ifdef CONFIG_X86_64 | ||
853 | /* allocate memory for gdts of secondary cpus. Hotplug is considered */ | ||
854 | if (!cpu_gdt_descr[cpu].address && | ||
855 | !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) { | ||
856 | printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu); | ||
857 | return -1; | ||
858 | } | ||
859 | 852 | ||
853 | #ifdef CONFIG_X86_64 | ||
860 | /* Allocate node local memory for AP pdas */ | 854 | /* Allocate node local memory for AP pdas */ |
861 | if (cpu > 0) { | 855 | if (cpu > 0) { |
862 | boot_error = get_local_pda(cpu); | 856 | boot_error = get_local_pda(cpu); |
@@ -898,7 +892,6 @@ do_rest: | |||
898 | #ifdef CONFIG_X86_32 | 892 | #ifdef CONFIG_X86_32 |
899 | per_cpu(current_task, cpu) = c_idle.idle; | 893 | per_cpu(current_task, cpu) = c_idle.idle; |
900 | init_gdt(cpu); | 894 | init_gdt(cpu); |
901 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | ||
902 | c_idle.idle->thread.ip = (unsigned long) start_secondary; | 895 | c_idle.idle->thread.ip = (unsigned long) start_secondary; |
903 | /* Stack for startup_32 can be just as for start_secondary onwards */ | 896 | /* Stack for startup_32 can be just as for start_secondary onwards */ |
904 | irq_ctx_init(cpu); | 897 | irq_ctx_init(cpu); |
@@ -908,6 +901,7 @@ do_rest: | |||
908 | initial_code = (unsigned long)start_secondary; | 901 | initial_code = (unsigned long)start_secondary; |
909 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); | 902 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); |
910 | #endif | 903 | #endif |
904 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | ||
911 | stack_start.sp = (void *) c_idle.idle->thread.sp; | 905 | stack_start.sp = (void *) c_idle.idle->thread.sp; |
912 | 906 | ||
913 | /* start_ip had better be page-aligned! */ | 907 | /* start_ip had better be page-aligned! */ |
@@ -1252,8 +1246,8 @@ void __init native_smp_prepare_boot_cpu(void) | |||
1252 | int me = smp_processor_id(); | 1246 | int me = smp_processor_id(); |
1253 | #ifdef CONFIG_X86_32 | 1247 | #ifdef CONFIG_X86_32 |
1254 | init_gdt(me); | 1248 | init_gdt(me); |
1255 | switch_to_new_gdt(); | ||
1256 | #endif | 1249 | #endif |
1250 | switch_to_new_gdt(); | ||
1257 | /* already set me in cpu_online_map in boot_cpu_init() */ | 1251 | /* already set me in cpu_online_map in boot_cpu_init() */ |
1258 | cpu_set(me, cpu_callout_map); | 1252 | cpu_set(me, cpu_callout_map); |
1259 | per_cpu(cpu_state, me) = CPU_ONLINE; | 1253 | per_cpu(cpu_state, me) = CPU_ONLINE; |
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index f6c05d0410fb..2f306a826897 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -53,8 +53,3 @@ EXPORT_SYMBOL(init_level4_pgt); | |||
53 | EXPORT_SYMBOL(load_gs_index); | 53 | EXPORT_SYMBOL(load_gs_index); |
54 | 54 | ||
55 | EXPORT_SYMBOL(_proxy_pda); | 55 | EXPORT_SYMBOL(_proxy_pda); |
56 | |||
57 | #ifdef CONFIG_PARAVIRT | ||
58 | /* Virtualized guests may want to use it */ | ||
59 | EXPORT_SYMBOL_GPL(cpu_gdt_descr); | ||
60 | #endif | ||