From a46ff73d53f011de1dfc1983b05db2c04d193713 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:30:57 +0100 Subject: x86: setup64 eflags constants This cleans up arch/x86/kernel/setup64.c to use the X86_EFLAGS_* constants from instead of the EF_* enum in . Signed-off-by: Roland McGrath Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 3558ac78c926..51297cca6b42 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -169,7 +169,8 @@ void syscall_init(void) #endif /* Flags to clear on syscall */ - wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); + wrmsrl(MSR_SYSCALL_MASK, + X86_EFLAGS_TF|X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_IOPL); } void __cpuinit check_efer(void) -- cgit v1.2.3 From f6dc247cac1a8ee64e59019c3b948d23f3b1a36f Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:12 +0100 Subject: x86: change gdt acessor macro name This patch changes the name of x86_64 macro used to access the per-cpu gdt. It is now equal to the i386 version, which will allow code to be shared. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup64.c | 2 +- arch/x86/kernel/suspend_64.c | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/asm-x86/desc_64.h | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 51297cca6b42..05cafcb94109 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -228,7 +228,7 @@ void __cpuinit cpu_init (void) * and set up the GDT descriptor: */ if (cpu) - memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE); + memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE); cpu_gdt_descr[cpu].size = GDT_SIZE; load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]); diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index 569f1b540e36..279c25775d19 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c @@ -140,7 +140,7 @@ void fix_processor_context(void) set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ - cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9; + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; syscall_init(); /* This sets MSR_*STAR and related */ load_TR_desc(); /* This does ltr */ diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index c4c5e765cd2c..e5c1118a8098 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -297,7 +297,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu) /* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU); + d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU); *d = 0x0f40000000000ULL; *d |= cpu; *d |= (node & 0xf) << 12; diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 230ac6e50a0f..4d67f61b4c23 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -48,7 +48,7 @@ static inline void write_ldt_entry(struct desc_struct *ldt, } /* the cpu gdt accessor */ -#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) static inline void load_gdt(const struct desc_ptr *ptr) { @@ -141,15 +141,15 @@ static inline void set_tss_desc(unsigned cpu, void *addr) * -1? seg base+limit should be pointing to the address of the * last valid byte */ - set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS], (unsigned long)addr, DESC_TSS, IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); } static inline void set_ldt_desc(unsigned cpu, void *addr, int size) { - set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr, - DESC_LDT, size * 8 - 1); + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], + (unsigned long)addr, DESC_LDT, size * 8 - 1); } #define LDT_entry_a(info) \ @@ -183,7 +183,7 @@ static inline void set_ldt_desc(unsigned cpu, void *addr, int size) static inline void load_TLS(struct thread_struct *t, unsigned int cpu) { unsigned int i; - u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN); + u64 *gdt = (u64 *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) gdt[i] = t->tls_array[i]; -- cgit v1.2.3 From ca241c75037b32e0216a68e39ad2801d04fa1f87 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:31:31 +0100 Subject: x86: unify tss_struct Although slighly different, the tss_struct is very similar in x86_64 and i386. The really different part, which matchs the hardware vision of it, is now called x86_hw_tss, and each of the architectures provides yours. It's then used as a field in the outter tss_struct. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/asm-offsets_64.c | 2 +- arch/x86/kernel/doublefault_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/setup64.c | 4 +-- arch/x86/kernel/smpboot_64.c | 2 +- include/asm-x86/lguest.h | 2 +- include/asm-x86/processor.h | 77 ++++++++++++++++++++++++++++++++++++++++ include/asm-x86/processor_32.h | 62 -------------------------------- include/asm-x86/processor_64.h | 35 +----------------- 9 files changed, 85 insertions(+), 103 deletions(-) (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index a05428764314..2b32719a3fea 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -110,7 +110,7 @@ int main(void) ENTRY(cr8); BLANK(); #undef ENTRY - DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist)); BLANK(); DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); BLANK(); diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c index d16122a8e4eb..a47798b59f07 100644 --- a/arch/x86/kernel/doublefault_32.c +++ b/arch/x86/kernel/doublefault_32.c @@ -33,7 +33,7 @@ static void doublefault_fn(void) printk(KERN_EMERG "double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { - struct i386_hw_tss *t = (struct i386_hw_tss *)tss; + struct x86_hw_tss *t = (struct x86_hw_tss *)tss; printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->ip, t->sp); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 836a71adfa11..af56104b73ff 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -639,7 +639,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* * Reload esp0, LDT and the page table pointer: */ - tss->sp0 = next->sp0; + tss->x86_tss.sp0 = next->sp0; /* * Switch DS and ES. diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 05cafcb94109..3b0ffa31f3c0 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -258,10 +258,10 @@ void __cpuinit cpu_init (void) v, cpu); } estacks += PAGE_SIZE << order[v]; - orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; + orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; } - t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap); + t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); /* * <= is required because the CPU will access up to * 8 bits beyond the end of the IO permission bitmap. diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 4c03ddccd681..2ea02a71b644 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -614,7 +614,7 @@ do_rest: start_rip = setup_trampoline(); init_rsp = c_idle.idle->thread.sp; - per_cpu(init_tss,cpu).sp0 = init_rsp; + per_cpu(init_tss, cpu).x86_tss.sp0 = init_rsp; initial_code = start_secondary; clear_tsk_thread_flag(c_idle.idle, TIF_FORK); diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index 3585a1628b59..1c8367a692f6 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -51,7 +51,7 @@ struct lguest_ro_state /* Fields which are used when guest is running. */ struct desc_ptr guest_idt_desc; struct desc_ptr guest_gdt_desc; - struct i386_hw_tss guest_tss; + struct x86_hw_tss guest_tss; struct desc_struct guest_idt[IDT_ENTRIES]; struct desc_struct guest_gdt[GDT_ENTRIES]; }; diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 3deb5ba55f55..cede9ad3dc6e 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h @@ -8,6 +8,7 @@ struct task_struct; struct mm_struct; #include +#include #include /* @@ -38,6 +39,82 @@ static inline void load_cr3(pgd_t *pgdir) write_cr3(__pa(pgdir)); } +#ifdef CONFIG_X86_32 +/* This is the TSS defined by the hardware. */ +struct x86_hw_tss { + unsigned short back_link, __blh; + unsigned long sp0; + unsigned short ss0, __ss0h; + unsigned long sp1; + unsigned short ss1, __ss1h; /* ss1 caches MSR_IA32_SYSENTER_CS */ + unsigned long sp2; + unsigned short ss2, __ss2h; + unsigned long __cr3; + unsigned long ip; + unsigned long flags; + unsigned long ax, cx, dx, bx; + unsigned long sp, bp, si, di; + unsigned short es, __esh; + unsigned short cs, __csh; + unsigned short ss, __ssh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; + unsigned short ldt, __ldth; + unsigned short trace, io_bitmap_base; +} __attribute__((packed)); +#else +struct x86_hw_tss { + u32 reserved1; + u64 sp0; + u64 sp1; + u64 sp2; + u64 reserved2; + u64 ist[7]; + u32 reserved3; + u32 reserved4; + u16 reserved5; + u16 io_bitmap_base; +} __attribute__((packed)) ____cacheline_aligned; +#endif + +/* + * Size of io_bitmap. + */ +#define IO_BITMAP_BITS 65536 +#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) +#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) +#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap) +#define INVALID_IO_BITMAP_OFFSET 0x8000 +#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 + +struct tss_struct { + struct x86_hw_tss x86_tss; + + /* + * The extra 1 is there because the CPU will access an + * additional byte beyond the end of the IO permission + * bitmap. The extra byte must be all 1 bits, and must + * be within the limit. + */ + unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; + /* + * Cache the current maximum and the last task that used the bitmap: + */ + unsigned long io_bitmap_max; + struct thread_struct *io_bitmap_owner; + /* + * pads the TSS to be cacheline-aligned (size is 0x100) + */ + unsigned long __cacheline_filler[35]; + /* + * .. and then another 0x100 bytes for emergency kernel stack + */ + unsigned long stack[64]; +} __attribute__((packed)); + +DECLARE_PER_CPU(struct tss_struct, init_tss); + #ifdef CONFIG_X86_32 # include "processor_32.h" #else diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 6cd2149dcbad..57b345bc3c74 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h @@ -81,7 +81,6 @@ struct cpuinfo_x86 { extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; extern struct tss_struct doublefault_tss; -DECLARE_PER_CPU(struct tss_struct, init_tss); #ifdef CONFIG_SMP DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); @@ -123,16 +122,6 @@ extern unsigned int mca_pentium_flag; #define TASK_SIZE (PAGE_OFFSET) -/* - * Size of io_bitmap. - */ -#define IO_BITMAP_BITS 65536 -#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) -#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) -#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) -#define INVALID_IO_BITMAP_OFFSET 0x8000 -#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 - struct i387_fsave_struct { long cwd; long swd; @@ -185,57 +174,6 @@ typedef struct { unsigned long seg; } mm_segment_t; -struct thread_struct; - -/* This is the TSS defined by the hardware. */ -struct i386_hw_tss { - unsigned short back_link,__blh; - unsigned long sp0; - unsigned short ss0,__ss0h; - unsigned long sp1; - unsigned short ss1,__ss1h; /* ss1 is used to cache MSR_IA32_SYSENTER_CS */ - unsigned long sp2; - unsigned short ss2,__ss2h; - unsigned long __cr3; - unsigned long ip; - unsigned long flags; - unsigned long ax, cx, dx, bx; - unsigned long sp, bp, si, di; - unsigned short es, __esh; - unsigned short cs, __csh; - unsigned short ss, __ssh; - unsigned short ds, __dsh; - unsigned short fs, __fsh; - unsigned short gs, __gsh; - unsigned short ldt, __ldth; - unsigned short trace, io_bitmap_base; -} __attribute__((packed)); - -struct tss_struct { - struct i386_hw_tss x86_tss; - - /* - * The extra 1 is there because the CPU will access an - * additional byte beyond the end of the IO permission - * bitmap. The extra byte must be all 1 bits, and must - * be within the limit. - */ - unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; - /* - * Cache the current maximum and the last task that used the bitmap: - */ - unsigned long io_bitmap_max; - struct thread_struct *io_bitmap_owner; - /* - * pads the TSS to be cacheline-aligned (size is 0x100) - */ - unsigned long __cacheline_filler[35]; - /* - * .. and then another 0x100 bytes for emergency kernel stack - */ - unsigned long stack[64]; -} __attribute__((packed)); - #define ARCH_MIN_TASKALIGN 16 struct thread_struct { diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 1984a4a38b74..8d342c23ad14 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -91,14 +91,6 @@ extern void identify_cpu(struct cpuinfo_x86 *); #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) -/* - * Size of io_bitmap. - */ -#define IO_BITMAP_BITS 65536 -#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) -#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) -#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) -#define INVALID_IO_BITMAP_OFFSET 0x8000 struct i387_fxsave_struct { u16 cwd; @@ -118,32 +110,7 @@ union i387_union { struct i387_fxsave_struct fxsave; }; -struct tss_struct { - u32 reserved1; - u64 sp0; - u64 sp1; - u64 sp2; - u64 reserved2; - u64 ist[7]; - u32 reserved3; - u32 reserved4; - u16 reserved5; - u16 io_bitmap_base; - /* - * The extra 1 is there because the CPU will access an - * additional byte beyond the end of the IO permission - * bitmap. The extra byte must be all 1 bits, and must - * be within the limit. Thus we have: - * - * 128 bytes, the bitmap itself, for ports 0..0x3ff - * 8 bytes, for an extra "long" of ~0UL - */ - unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; -} __attribute__((packed)) ____cacheline_aligned; - - extern struct cpuinfo_x86 boot_cpu_data; -DECLARE_PER_CPU(struct tss_struct,init_tss); /* Save the original ist values for checking stack pointers during debugging */ struct orig_ist { unsigned long ist[7]; @@ -195,7 +162,7 @@ struct thread_struct { } #define INIT_TSS { \ - .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ + .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } #define INIT_MMAP \ -- cgit v1.2.3 From 6d7d7433750c7c6eec93d7b3206019e329228686 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Wed, 30 Jan 2008 13:32:51 +0100 Subject: x86 boot : export boot_params via debugfs for debugging This patch export the boot parameters via debugfs for debugging. The files added are as follow: boot_params/data : binary file for struct boot_params boot_params/version : boot protocol version This patch is based on 2.6.24-rc5-mm1 and has been tested on i386 and x86_64 platform. This patch is based on the Peter Anvin's proposal. Signed-off-by: Huang Ying Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/Kconfig.debug | 7 +++++ arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/kdebugfs.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup64.c | 4 +++ arch/x86/kernel/setup_32.c | 4 +++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 arch/x86/kernel/kdebugfs.c (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 660200915baa..15854b53badc 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -185,4 +185,11 @@ config DEFAULT_IO_DELAY_TYPE default IO_DELAY_TYPE_NONE endif +config DEBUG_BOOT_PARAMS + bool "Debug boot parameters" + depends on DEBUG_KERNEL + depends on DEBUG_FS + help + This option will cause struct boot_params to be exported via debugfs. + endmenu diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index b40bed4baa77..3d23ccd366ea 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o obj-y += pci-dma_$(BITS).o bootflag.o e820_$(BITS).o -obj-y += quirks.o i8237.o topology.o +obj-y += quirks.o i8237.o topology.o kdebugfs.o obj-y += alternative.o i8253.o obj-$(CONFIG_X86_64) += pci-nommu_64.o bugs_64.o obj-y += tsc_$(BITS).o io_delay.o rtc.o diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c new file mode 100644 index 000000000000..73354302fda7 --- /dev/null +++ b/arch/x86/kernel/kdebugfs.c @@ -0,0 +1,65 @@ +/* + * Architecture specific debugfs files + * + * Copyright (C) 2007, Intel Corp. + * Huang Ying + * + * This file is released under the GPLv2. + */ + +#include +#include +#include + +#include + +#ifdef CONFIG_DEBUG_BOOT_PARAMS +static struct debugfs_blob_wrapper boot_params_blob = { + .data = &boot_params, + .size = sizeof(boot_params), +}; + +static int __init boot_params_kdebugfs_init(void) +{ + int error; + struct dentry *dbp, *version, *data; + + dbp = debugfs_create_dir("boot_params", NULL); + if (!dbp) { + error = -ENOMEM; + goto err_return; + } + version = debugfs_create_x16("version", S_IRUGO, dbp, + &boot_params.hdr.version); + if (!version) { + error = -ENOMEM; + goto err_dir; + } + data = debugfs_create_blob("data", S_IRUGO, dbp, + &boot_params_blob); + if (!data) { + error = -ENOMEM; + goto err_version; + } + return 0; +err_version: + debugfs_remove(version); +err_dir: + debugfs_remove(dbp); +err_return: + return error; +} +#endif + +static int __init arch_kdebugfs_init(void) +{ + int error = 0; + +#ifdef CONFIG_DEBUG_BOOT_PARAMS + error = boot_params_kdebugfs_init(); +#endif + + return error; +} + +arch_initcall(arch_kdebugfs_init); diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 3b0ffa31f3c0..8fa0de810d0b 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -24,7 +24,11 @@ #include #include +#ifndef CONFIG_DEBUG_BOOT_PARAMS struct boot_params __initdata boot_params; +#else +struct boot_params boot_params; +#endif cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 704550fdb84c..3bce4af60bb6 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -194,7 +194,11 @@ unsigned long saved_videomode; static char __initdata command_line[COMMAND_LINE_SIZE]; +#ifndef CONFIG_DEBUG_BOOT_PARAMS struct boot_params __initdata boot_params; +#else +struct boot_params boot_params; +#endif #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; -- cgit v1.2.3 From 834beda15ecc43c110c0a6ac39ec1aa79f891716 Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:21 +0100 Subject: x86: change NR_CPUS arrays in numa_64 fixup Change the following static arrays sized by NR_CPUS to per_cpu data variables: char cpu_to_node_map[NR_CPUS]; fixup: - Split cpu_to_node function into "early" and "late" versions so that x86_cpu_to_node_map_early_ptr is not EXPORT'ed and the cpu_to_node inline function is more streamlined. - This also involves setting up the percpu maps as early as possible. - Fix X86_32 NUMA build errors that previous version of this patch caused. V2->V3: - add early_cpu_to_node function to keep cpu_to_node efficient - move and rename smp_set_apicids() to setup_percpu_maps() - call setup_percpu_maps() as early as possible V1->V2: - Removed extraneous casts - Fix !NUMA builds with '#ifdef CONFIG_NUMA" Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup64.c | 41 +++++++++++++++++++++++++++++++++++++++-- arch/x86/kernel/smpboot_32.c | 2 +- arch/x86/kernel/smpboot_64.c | 34 ---------------------------------- arch/x86/mm/srat_64.c | 5 +++-- include/asm-x86/topology.h | 23 +++++++++++++++++++++++ 5 files changed, 66 insertions(+), 39 deletions(-) (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 8fa0de810d0b..855ec82e4f76 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -83,6 +83,40 @@ static int __init nonx32_setup(char *str) } __setup("noexec32=", nonx32_setup); +/* + * Copy data used in early init routines from the initial arrays to the + * per cpu data areas. These arrays then become expendable and the *_ptrs + * are zeroed indicating that the static arrays are gone. + */ +void __init setup_percpu_maps(void) +{ + int cpu; + + for_each_possible_cpu(cpu) { +#ifdef CONFIG_SMP + if (per_cpu_offset(cpu)) { +#endif + per_cpu(x86_cpu_to_apicid, cpu) = + x86_cpu_to_apicid_init[cpu]; +#ifdef CONFIG_NUMA + per_cpu(x86_cpu_to_node_map, cpu) = + x86_cpu_to_node_map_init[cpu]; +#endif +#ifdef CONFIG_SMP + } + else + printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n", + cpu); +#endif + } + + /* indicate the early static arrays are gone */ + x86_cpu_to_apicid_early_ptr = NULL; +#ifdef CONFIG_NUMA + x86_cpu_to_node_map_early_ptr = NULL; +#endif +} + /* * Great future plan: * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. @@ -104,18 +138,21 @@ void __init setup_per_cpu_areas(void) for_each_cpu_mask (i, cpu_possible_map) { char *ptr; - if (!NODE_DATA(cpu_to_node(i))) { + if (!NODE_DATA(early_cpu_to_node(i))) { printk("cpu with no node %d, num_online_nodes %d\n", i, num_online_nodes()); ptr = alloc_bootmem_pages(size); } else { - ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); + ptr = alloc_bootmem_pages_node(NODE_DATA(early_cpu_to_node(i)), size); } if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); cpu_pda(i)->data_offset = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); } + + /* setup percpu data maps early */ + setup_percpu_maps(); } void pda_init(int cpu) diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index 915ec6267326..50232d476a27 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c @@ -465,7 +465,7 @@ cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; EXPORT_SYMBOL(node_to_cpumask_map); /* which node each logical CPU is on */ -int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; +u8 cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_to_node_map); /* set up a mapping between cpu and node. */ diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 93071cdf0849..4e14ecb90764 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -851,39 +851,6 @@ static int __init smp_sanity_check(unsigned max_cpus) return 0; } -/* - * Copy data used in early init routines from the initial arrays to the - * per cpu data areas. These arrays then become expendable and the - * *_ptrs are zeroed indicating that the static arrays are gone. - */ -void __init smp_set_apicids(void) -{ - int cpu; - - for_each_possible_cpu(cpu) { - if (per_cpu_offset(cpu)) { - per_cpu(x86_cpu_to_apicid, cpu) = - x86_cpu_to_apicid_init[cpu]; -#ifdef CONFIG_NUMA - per_cpu(x86_cpu_to_node_map, cpu) = - x86_cpu_to_node_map_init[cpu]; -#endif - per_cpu(x86_bios_cpu_apicid, cpu) = - x86_bios_cpu_apicid_init[cpu]; - } - else - printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n", - cpu); - } - - /* indicate the early static arrays are gone */ - x86_cpu_to_apicid_early_ptr = NULL; -#ifdef CONFIG_NUMA - x86_cpu_to_node_map_early_ptr = NULL; -#endif - x86_bios_cpu_apicid_early_ptr = NULL; -} - static void __init smp_cpu_index_default(void) { int i; @@ -906,7 +873,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_cpu_index_default(); current_cpu_data = boot_cpu_data; current_thread_info()->cpu = 0; /* needed? */ - smp_set_apicids(); set_cpu_sibling_map(0); if (smp_sanity_check(max_cpus) < 0) { diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index e5a1ec8342dc..04cbecaeca81 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -382,9 +382,10 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) setup_node_bootmem(i, nodes[i].start, nodes[i].end); for (i = 0; i < NR_CPUS; i++) { - if (cpu_to_node(i) == NUMA_NO_NODE) + int node = cpu_to_node(i); + if (node == NUMA_NO_NODE) continue; - if (!node_isset(cpu_to_node(i), node_possible_map)) + if (!node_isset(node, node_possible_map)) numa_set_node(i, NUMA_NO_NODE); } numa_init_array(); diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 2da1464ecbef..040374f030cf 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -30,15 +30,29 @@ #include /* Mappings between logical cpu number and node number */ +#ifdef CONFIG_X86_32 +extern u8 cpu_to_node_map[]; + +#else DECLARE_PER_CPU(u16, x86_cpu_to_node_map); extern u16 x86_cpu_to_node_map_init[]; extern void *x86_cpu_to_node_map_early_ptr; +#endif + extern cpumask_t node_to_cpumask_map[]; #define NUMA_NO_NODE ((u16)(~0)) /* Returns the number of the node containing CPU 'cpu' */ +#ifdef CONFIG_X86_32 +#define early_cpu_to_node(cpu) cpu_to_node(cpu) static inline int cpu_to_node(int cpu) +{ + return cpu_to_node_map[cpu]; +} + +#else /* CONFIG_X86_64 */ +static inline int early_cpu_to_node(int cpu) { u16 *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; @@ -50,6 +64,15 @@ static inline int cpu_to_node(int cpu) return NUMA_NO_NODE; } +static inline int cpu_to_node(int cpu) +{ + if(per_cpu_offset(cpu)) + return per_cpu(x86_cpu_to_node_map, cpu); + else + return NUMA_NO_NODE; +} +#endif /* CONFIG_X86_64 */ + /* * Returns the number of the node containing Node 'node'. This * architecture is flat, so it is a pretty simple function! -- cgit v1.2.3 From 602a54a8cab2759fceb20b3e0c2a27c4eac005df Mon Sep 17 00:00:00 2001 From: "travis@sgi.com" Date: Wed, 30 Jan 2008 13:33:21 +0100 Subject: x86: change bios_cpu_apicid to percpu data variable fixup Change static bios_cpu_apicid array to a per_cpu data variable. This includes using a static array used during initialization similar to the way x86_cpu_to_apicid[] is handled. There is one early use of bios_cpu_apicid in apic_is_clustered_box(). The other reference in cpu_present_to_apicid() is called after smp_set_apicids() has setup the percpu version of bios_cpu_apicid. Signed-off-by: Mike Travis Reviewed-by: Christoph Lameter Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/apic_64.c | 6 +++--- arch/x86/kernel/setup64.c | 13 ++++++++----- arch/x86/kernel/setup_64.c | 1 + arch/x86/kernel/smpboot_32.c | 2 +- arch/x86/mm/srat_64.c | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index a7a38c9da136..d8d03e09dea2 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c @@ -1205,9 +1205,9 @@ __cpuinit int apic_is_clustered_box(void) /* Problem: Partially populated chassis may not have CPUs in some of * the APIC clusters they have been allocated. Only present CPUs have - * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap. Since - * clusters are allocated sequentially, count zeros only if they are - * bounded by ones. + * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap. + * Since clusters are allocated sequentially, count zeros only if + * they are bounded by ones. */ clusters = 0; zeros = 0; diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 855ec82e4f76..0389331059ad 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -85,10 +85,10 @@ __setup("noexec32=", nonx32_setup); /* * Copy data used in early init routines from the initial arrays to the - * per cpu data areas. These arrays then become expendable and the *_ptrs - * are zeroed indicating that the static arrays are gone. + * per cpu data areas. These arrays then become expendable and the + * *_early_ptr's are zeroed indicating that the static arrays are gone. */ -void __init setup_percpu_maps(void) +static void __init setup_per_cpu_maps(void) { int cpu; @@ -98,6 +98,8 @@ void __init setup_percpu_maps(void) #endif per_cpu(x86_cpu_to_apicid, cpu) = x86_cpu_to_apicid_init[cpu]; + per_cpu(x86_bios_cpu_apicid, cpu) = + x86_bios_cpu_apicid_init[cpu]; #ifdef CONFIG_NUMA per_cpu(x86_cpu_to_node_map, cpu) = x86_cpu_to_node_map_init[cpu]; @@ -110,8 +112,9 @@ void __init setup_percpu_maps(void) #endif } - /* indicate the early static arrays are gone */ + /* indicate the early static arrays will soon be gone */ x86_cpu_to_apicid_early_ptr = NULL; + x86_bios_cpu_apicid_early_ptr = NULL; #ifdef CONFIG_NUMA x86_cpu_to_node_map_early_ptr = NULL; #endif @@ -152,7 +155,7 @@ void __init setup_per_cpu_areas(void) } /* setup percpu data maps early */ - setup_percpu_maps(); + setup_per_cpu_maps(); } void pda_init(int cpu) diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 79635b7bd57a..f84e2662f1ca 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -334,6 +334,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_SMP /* setup to use the early static init tables during kernel startup */ x86_cpu_to_apicid_early_ptr = (void *)&x86_cpu_to_apicid_init; + x86_bios_cpu_apicid_early_ptr = (void *)&x86_bios_cpu_apicid_init; #ifdef CONFIG_NUMA x86_cpu_to_node_map_early_ptr = (void *)&x86_cpu_to_node_map_init; #endif diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index 50232d476a27..915ec6267326 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c @@ -465,7 +465,7 @@ cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; EXPORT_SYMBOL(node_to_cpumask_map); /* which node each logical CPU is on */ -u8 cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; +int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_to_node_map); /* set up a mapping between cpu and node. */ diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index f828e6a6973d..4aed38fa4a65 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -397,7 +397,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) static int fake_node_to_pxm_map[MAX_NUMNODES] __initdata = { [0 ... MAX_NUMNODES-1] = PXM_INVAL }; -static u16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = { +static s16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = { [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE }; static int __init find_node_by_addr(unsigned long addr) -- cgit v1.2.3 From e68decb52104388ed6c6218be926e10e6cde2814 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Wed, 30 Jan 2008 13:33:24 +0100 Subject: x86: export __supported_pte_mask export __supported_pte_mask variable as GPL symbol. lguest is a user of it. Signed-off-by: Glauber de Oliveira Costa Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup64.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/kernel/setup64.c') diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 0389331059ad..309366f8f603 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -41,6 +41,8 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); unsigned long __supported_pte_mask __read_mostly = ~0UL; +EXPORT_SYMBOL_GPL(__supported_pte_mask); + static int do_not_nx __cpuinitdata = 0; /* noexec=on|off -- cgit v1.2.3