Baby steps toward cleaning up KERNEL_STACK_OFFSET
Subsystems (3)
v2 cover Baby steps toward cleaning up KERNEL_STACK_OFFSET
Denys is right that KERNEL_STACK_OFFSET is a mess. Let's start fixing it.
This removes all C code that *reads* kernel_stack. It also fixes the KERNEL_STACK_OFFSET abomination in ia32_sysenter_target.
It does not fix the KERNEL_STACK_OFFSET abomination in GET_THREAD_INFO and THREAD_INFO. I think that should be its own patch.
It also doesn't change the two syscall targets. To fix them, we should make a decision. Either we should make KERNEL_STACK_OFFSET have the correct nonzero value to save an instruction or we should get rid of kernel_stack entirely.
Changes from v1:
- Fix missing export.
- Fix lguest code.
- Add more init_tss naming cleanups (Ingo's suggestion).
- Changelog improvements (Ingo).
- Improve the check in ist_begin_non_atomic (Denys).
Andy Lutomirski (6):
x86: Add this_cpu_sp0() to read sp0 for the current cpu
x86: Switch all C consumers of kernel_stack to this_cpu_sp0 x86, asm: Change the 32-bit sysenter code to use sp0
x86: Rename init_tss to cpu_tss
x86: Remove INIT_TSS and fold the definitions into cpu_tss x86, asm: Rename INIT_TSS_IST to TSS_IST
arch/x86/ia32/ia32entry.S | 3 +-- arch/x86/include/asm/processor.h | 27 ++++++--------------------- arch/x86/include/asm/thread_info.h | 3 +-- arch/x86/kernel/asm-offsets_64.c | 1 + arch/x86/kernel/cpu/common.c | 6 +++--- arch/x86/kernel/entry_64.S | 6 +++--- arch/x86/kernel/ioport.c | 2 +- arch/x86/kernel/process.c | 23 +++++++++++++++++++++-- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/traps.c | 4 ++-- arch/x86/kernel/vm86_32.c | 4 ++-- arch/x86/lguest/boot.c | 1 + arch/x86/power/cpu.c | 2 +- arch/x86/xen/enlighten.c | 1 + 15 files changed, 46 insertions(+), 41 deletions(-)
Signature · 1 line
2.1.0
PATCH v2 1/6 x86: Add this_cpu_sp0() to read sp0 for the current cpu
We currently store references to the top of the kernel stack in multiple places: kernel_stack (with an offset) and init_tss.x86_tss.sp0 (no offset). The latter is defined by hardware and is a clean canonical way to find the top of the stack. Add an accessor so we can start using it.
This needs minor paravirt tweaks. On native, sp0 defines the top of the kernel stack and is therefore always correct. On Xen and lguest, the hypervisor tracks the top of the stack, but we want to start reading sp0 in the kernel. Fixing this is simple: just update our local copy of sp0 as well as the hypervisor's copy on task switches.
--- arch/x86/include/asm/processor.h | 5 +++++ arch/x86/kernel/process.c | 1 + arch/x86/lguest/boot.c | 1 + arch/x86/xen/enlighten.c | 1 + 4 files changed, 8 insertions(+)
arch/x86/include/asm/processor.h +5 -0
@@ -564,6 +564,11 @@ static inline void native_swapgs(void)#endif } +static inline unsigned long this_cpu_sp0 (void ) +{ +return this_cpu_read_stable (init_tss.x86_tss.sp0); +} +#ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else
arch/x86/kernel/process.c +1 -0
@@ -38,6 +38,7 @@* on exact cacheline boundaries, to eliminate cacheline ping-pong. */ __visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,init_tss ) =INIT_TSS ; +EXPORT_PER_CPU_SYMBOL_GPL (init_tss);#ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle);
arch/x86/lguest/boot.c +1 -0
@@ -1076,6 +1076,7 @@ static void lguest_load_sp0(struct tss_struct *tss, {lazy_hcall3 (LHCALL_SET_STACK , __KERNEL_DS |0x1 , thread->sp0,THREAD_SIZE /PAGE_SIZE ); + tss->x86_tss.sp0 = thread->sp0; }/* Let's just say, I wouldn't do debugging under a Guest. */
arch/x86/xen/enlighten.c +1 -0
@@ -912,6 +912,7 @@ static void xen_load_sp0(struct tss_struct *tss, mcs =xen_mc_entry (0 );MULTI_stack_switch (mcs.mc, __KERNEL_DS, thread->sp0);xen_mc_issue (PARAVIRT_LAZY_CPU ); + tss->x86_tss.sp0 = thread->sp0; }static void xen_set_iopl_mask (unsigned mask)
Signature · 1 line
2.1.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry: Add this_cpu_sp0() to read sp0 for the current cpu
x86/asm/entry: Add this_cpu_sp0() to read sp0 for the current cpu
Commit-ID: 8ef46a672a7d852709561d10672b6eaa8a4acd82 Gitweb: http://git.kernel.org/tip/8ef46a672a7d852709561d10672b6eaa8a4acd82 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 5 Mar 2015 19:19:02 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 6 Mar 2015 08:32:57 +0100
x86/asm/entry: Add this_cpu_sp0() to read sp0 for the current cpu
We currently store references to the top of the kernel stack in multiple places: kernel_stack (with an offset) and init_tss.x86_tss.sp0 (no offset). The latter is defined by hardware and is a clean canonical way to find the top of the stack. Add an accessor so we can start using it.
This needs minor paravirt tweaks. On native, sp0 defines the top of the kernel stack and is therefore always correct. On Xen and lguest, the hypervisor tracks the top of the stack, but we want to start reading sp0 in the kernel. Fixing this is simple:
just update our local copy of sp0 as well as the hypervisor's copy on task switches.
--- arch/x86/include/asm/processor.h | 5 +++++ arch/x86/kernel/process.c | 1 + arch/x86/lguest/boot.c | 1 + arch/x86/xen/enlighten.c | 1 + 4 files changed, 8 insertions(+)
arch/x86/include/asm/processor.h +5 -0
@@ -564,6 +564,11 @@ static inline void native_swapgs(void)#endif } +static inline unsigned long this_cpu_sp0 (void ) +{ +return this_cpu_read_stable (init_tss.x86_tss.sp0); +} +#ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else
arch/x86/kernel/process.c +1 -0
@@ -38,6 +38,7 @@* on exact cacheline boundaries, to eliminate cacheline ping-pong. */ __visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,init_tss ) =INIT_TSS ; +EXPORT_PER_CPU_SYMBOL_GPL (init_tss);#ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle);
arch/x86/lguest/boot.c +1 -0
@@ -1076,6 +1076,7 @@ static void lguest_load_sp0(struct tss_struct *tss, {lazy_hcall3 (LHCALL_SET_STACK , __KERNEL_DS |0x1 , thread->sp0,THREAD_SIZE /PAGE_SIZE ); + tss->x86_tss.sp0 = thread->sp0; }/* Let's just say, I wouldn't do debugging under a Guest. */
arch/x86/xen/enlighten.c +1 -0
@@ -912,6 +912,7 @@ static void xen_load_sp0(struct tss_struct *tss, mcs =xen_mc_entry (0 );MULTI_stack_switch (mcs.mc, __KERNEL_DS, thread->sp0);xen_mc_issue (PARAVIRT_LAZY_CPU ); + tss->x86_tss.sp0 = thread->sp0; }static void xen_set_iopl_mask (unsigned mask)
PATCH v2 2/6 x86: Switch all C consumers of kernel_stack to this_cpu_sp0
In reply to Andy LutomirskiThis will make modifying the semantics of kernel_stack easier.
The change to ist_begin_non_atomic() is necessary because sp0 no longer points to the same THREAD_SIZE-aligned region as rsp; it's one byte too high for that. At Denys' suggestion, rather than offsetting it, just check explicitly that we're in the correct range ending at sp0. This has the added benefit that we no longer assume that the thread stack is aligned to THREAD_SIZE.
--- arch/x86/include/asm/thread_info.h | 3 +-- arch/x86/kernel/traps.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-)
arch/x86/include/asm/thread_info.h +1 -2
@@ -159,8 +159,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack);static inline struct thread_info *current_thread_info (void ) {struct thread_info *ti; - ti = (void *)(this_cpu_read_stable (kernel_stack) + -KERNEL_STACK_OFFSET -THREAD_SIZE ); + ti = (void *)(this_cpu_sp0 () -THREAD_SIZE );return ti; }
arch/x86/kernel/traps.c +2 -2
@@ -174,8 +174,8 @@ void ist_begin_non_atomic(struct pt_regs *regs)* will catch asm bugs and any attempt to use ist_preempt_enable * from double_fault. */ -BUG_ON (((current_stack_pointer () ^this_cpu_read_stable (kernel_stack)) - & ~(THREAD_SIZE -1 )) !=0 ); +BUG_ON ((unsigned long )(this_cpu_sp0 () -current_stack_pointer ()) >= +THREAD_SIZE );preempt_count_sub (HARDIRQ_OFFSET ); }
Signature · 1 line
2.1.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry: Switch all C consumers of kernel_stack to this_cpu_sp0()
x86/asm/entry: Switch all C consumers of kernel_stack to this_cpu_sp0()
Commit-ID: 75182b1632a89f12540baa1806a7c5c180db620c Gitweb: http://git.kernel.org/tip/75182b1632a89f12540baa1806a7c5c180db620c Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 5 Mar 2015 19:19:03 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 6 Mar 2015 08:32:57 +0100
x86/asm/entry: Switch all C consumers of kernel_stack to this_cpu_sp0()
This will make modifying the semantics of kernel_stack easier.
The change to ist_begin_non_atomic() is necessary because sp0 no longer points to the same THREAD_SIZE-aligned region as RSP; it's one byte too high for that. At Denys' suggestion, rather than offsetting it, just check explicitly that we're in the correct range ending at sp0. This has the added benefit that we no longer assume that the thread stack is aligned to THREAD_SIZE.
--- arch/x86/include/asm/thread_info.h | 3 +-- arch/x86/kernel/traps.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-)
arch/x86/include/asm/thread_info.h +1 -2
@@ -159,8 +159,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack);static inline struct thread_info *current_thread_info (void ) {struct thread_info *ti; - ti = (void *)(this_cpu_read_stable (kernel_stack) + -KERNEL_STACK_OFFSET -THREAD_SIZE ); + ti = (void *)(this_cpu_sp0 () -THREAD_SIZE );return ti; }
arch/x86/kernel/traps.c +2 -2
@@ -174,8 +174,8 @@ void ist_begin_non_atomic(struct pt_regs *regs)* will catch asm bugs and any attempt to use ist_preempt_enable * from double_fault. */ -BUG_ON (((current_stack_pointer () ^this_cpu_read_stable (kernel_stack)) - & ~(THREAD_SIZE -1 )) !=0 ); +BUG_ON ((unsigned long )(this_cpu_sp0 () -current_stack_pointer ()) >= +THREAD_SIZE );preempt_count_sub (HARDIRQ_OFFSET ); }
PATCH v2 3/6 x86, asm: Change the 32-bit sysenter code to use sp0
In reply to Andy LutomirskiThe ia32 sysenter code loaded the top of the kernel stack into rsp by loading kernel_stack and then adjusting it. It can be simplified to just read sp0 directly.
This requires the addition of a new asm-offsets entry for sp0.
--- arch/x86/ia32/ia32entry.S | 3 +-- arch/x86/kernel/asm-offsets_64.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/ia32/ia32entry.S +1 -2
@@ -113,8 +113,7 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq PER_CPU_VAR(kernel_stack), %rsp - addq $(KERNEL_STACK_OFFSET),%rsp + movq PER_CPU_VAR(init_tss + TSS_sp0), %rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry:
arch/x86/kernel/asm-offsets_64.c +1 -0
@@ -81,6 +81,7 @@ int main(void)#undef ENTRYOFFSET (TSS_ist, tss_struct, x86_tss.ist); +OFFSET (TSS_sp0, tss_struct, x86_tss.sp0);BLANK ();DEFINE (__NR_syscall_max,sizeof (syscalls_64) -1 );
Signature · 1 line
2.1.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry/64/compat: Change the 32-bit sysenter code to use sp0
x86/asm/entry/64/compat: Change the 32-bit sysenter code to use sp0
Commit-ID: 9d0c914c60f4d3123debb653340dc1f7cf44939d Gitweb: http://git.kernel.org/tip/9d0c914c60f4d3123debb653340dc1f7cf44939d Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 5 Mar 2015 19:19:04 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 6 Mar 2015 08:32:58 +0100
x86/asm/entry/64/compat: Change the 32-bit sysenter code to use sp0
The ia32 sysenter code loaded the top of the kernel stack into rsp by loading kernel_stack and then adjusting it. It can be simplified to just read sp0 directly.
This requires the addition of a new asm-offsets entry for sp0.
--- arch/x86/ia32/ia32entry.S | 3 +-- arch/x86/kernel/asm-offsets_64.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/ia32/ia32entry.S +1 -2
@@ -113,8 +113,7 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq PER_CPU_VAR(kernel_stack), %rsp - addq $(KERNEL_STACK_OFFSET),%rsp + movq PER_CPU_VAR(init_tss + TSS_sp0), %rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry:
arch/x86/kernel/asm-offsets_64.c +1 -0
@@ -81,6 +81,7 @@ int main(void)#undef ENTRYOFFSET (TSS_ist, tss_struct, x86_tss.ist); +OFFSET (TSS_sp0, tss_struct, x86_tss.sp0);BLANK ();DEFINE (__NR_syscall_max,sizeof (syscalls_64) -1 );
PATCH v2 4/6 x86: Rename init_tss to cpu_tss
In reply to Andy LutomirskiIt has nothing to do with init -- there's only one tss per cpu.
Other names considered include:
- current_tss: Confusing because we never switch the tss.
- singleton_tss: Too long.
This patch was generated with 's/init_tss/cpu_tss/g'. Followup patches will fix INIT_TSS and INIT_TSS_IST by hand.
--- arch/x86/ia32/ia32entry.S | 2 +- arch/x86/include/asm/processor.h | 4 ++-- arch/x86/kernel/cpu/common.c | 6 +++--- arch/x86/kernel/entry_64.S | 2 +- arch/x86/kernel/ioport.c | 2 +- arch/x86/kernel/process.c | 6 +++--- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/vm86_32.c | 4 ++-- arch/x86/power/cpu.c | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/ia32/ia32entry.S +1 -1
@@ -113,7 +113,7 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq PER_CPU_VAR(init_tss + TSS_sp0), %rsp + movq PER_CPU_VAR(cpu_tss + TSS_sp0), %rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry:
arch/x86/include/asm/processor.h +2 -2
@@ -282,7 +282,7 @@ struct tss_struct { }____cacheline_aligned ; -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss); +DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss);/* * Save the original ist values for checking stack pointers during debugging
@@ -566,7 +566,7 @@ static inline void native_swapgs(void)static inline unsigned long this_cpu_sp0 (void ) { -return this_cpu_read_stable (init_tss.x86_tss.sp0); +return this_cpu_read_stable (cpu_tss.x86_tss.sp0); }#ifdef CONFIG_PARAVIRT
arch/x86/kernel/cpu/common.c +3 -3
@@ -979,7 +979,7 @@ static void syscall32_cpu_init(void)void enable_sep_cpu (void ) {int cpu =get_cpu (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); +struct tss_struct *tss = &per_cpu (cpu_tss, cpu);if (!boot_cpu_has (X86_FEATURE_SEP )) {put_cpu ();
@@ -1307,7 +1307,7 @@ void cpu_init(void)*/ load_ucode_ap (); - t = &per_cpu (init_tss, cpu); + t = &per_cpu (cpu_tss, cpu); oist = &per_cpu (orig_ist, cpu);#ifdef CONFIG_NUMA
@@ -1391,7 +1391,7 @@ void cpu_init(void) {int cpu =smp_processor_id ();struct task_struct *curr = current; -struct tss_struct *t = &per_cpu (init_tss, cpu); +struct tss_struct *t = &per_cpu (cpu_tss, cpu);struct thread_struct *thread = &curr->thread;wait_for_master_cpu (cpu);
arch/x86/kernel/entry_64.S +1 -1
@@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) +#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym)
arch/x86/kernel/ioport.c +1 -1
@@ -54,7 +54,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)* because the ->io_bitmap_max value must match the bitmap * contents: */ - tss = &per_cpu (init_tss,get_cpu ()); + tss = &per_cpu (cpu_tss,get_cpu ());if (turn_on)bitmap_clear (t->io_bitmap_ptr, from, num);
arch/x86/kernel/process.c +3 -3
@@ -37,8 +37,8 @@* section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,init_tss ) =INIT_TSS ; -EXPORT_PER_CPU_SYMBOL_GPL (init_tss); +__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,cpu_tss ) =INIT_TSS ; +EXPORT_PER_CPU_SYMBOL_GPL (cpu_tss);#ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle);
@@ -110,7 +110,7 @@ void exit_thread(void)unsigned long *bp = t->io_bitmap_ptr;if (bp) { -struct tss_struct *tss = &per_cpu (init_tss,get_cpu ()); +struct tss_struct *tss = &per_cpu (cpu_tss,get_cpu ()); t->io_bitmap_ptr =NULL ;clear_thread_flag (TIF_IO_BITMAP );
arch/x86/kernel/process_32.c +1 -1
@@ -248,7 +248,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread;int cpu =smp_processor_id (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); +struct tss_struct *tss = &per_cpu (cpu_tss, cpu);fpu_switch_t fpu;/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
arch/x86/kernel/process_64.c +1 -1
@@ -277,7 +277,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)struct thread_struct *prev = &prev_p->thread;struct thread_struct *next = &next_p->thread;int cpu =smp_processor_id (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); +struct tss_struct *tss = &per_cpu (cpu_tss, cpu);unsigned fsindex, gsindex;fpu_switch_t fpu;
arch/x86/kernel/vm86_32.c +2 -2
@@ -150,7 +150,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs)do_exit (SIGSEGV ); } - tss = &per_cpu (init_tss,get_cpu ()); + tss = &per_cpu (cpu_tss,get_cpu ()); current->thread.sp0 = current->thread.saved_sp0; current->thread.sysenter_cs = __KERNEL_CS;load_sp0 (tss, ¤t->thread);
@@ -318,7 +318,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk tsk->thread.saved_fs = info->regs32->fs; tsk->thread.saved_gs =get_user_gs (info->regs32); - tss = &per_cpu (init_tss,get_cpu ()); + tss = &per_cpu (cpu_tss,get_cpu ()); tsk->thread.sp0 = (unsigned long ) &info->VM86_TSS_ESP0;if (cpu_has_sep) tsk->thread.sysenter_cs =0 ;
arch/x86/power/cpu.c +1 -1
@@ -134,7 +134,7 @@ static void do_fpu_end(void)static void fix_processor_context (void ) {int cpu =smp_processor_id (); -struct tss_struct *t = &per_cpu (init_tss, cpu); +struct tss_struct *t = &per_cpu (cpu_tss, cpu);#ifdef CONFIG_X86_64 struct desc_struct *desc =get_cpu_gdt_table (cpu);tss_desc tss;
Signature · 1 line
2.1.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry: Rename 'init_tss' to 'cpu_tss'
x86/asm/entry: Rename 'init_tss' to 'cpu_tss'
Commit-ID: 24933b82c0d9a711475a5ef7904eb733f561e637 Gitweb: http://git.kernel.org/tip/24933b82c0d9a711475a5ef7904eb733f561e637 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 5 Mar 2015 19:19:05 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 6 Mar 2015 08:32:58 +0100
x86/asm/entry: Rename 'init_tss' to 'cpu_tss'
It has nothing to do with init -- there's only one TSS per cpu.
Other names considered include:
- current_tss: Confusing because we never switch the tss.
- singleton_tss: Too long.
This patch was generated with 's/init_tss/cpu_tss/g'. Followup patches will fix INIT_TSS and INIT_TSS_IST by hand.
--- arch/x86/ia32/ia32entry.S | 2 +- arch/x86/include/asm/processor.h | 4 ++-- arch/x86/kernel/cpu/common.c | 6 +++--- arch/x86/kernel/entry_64.S | 2 +- arch/x86/kernel/ioport.c | 2 +- arch/x86/kernel/process.c | 6 +++--- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/vm86_32.c | 4 ++-- arch/x86/power/cpu.c | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/ia32/ia32entry.S +1 -1
@@ -113,7 +113,7 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq PER_CPU_VAR(init_tss + TSS_sp0), %rsp + movq PER_CPU_VAR(cpu_tss + TSS_sp0), %rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry:
arch/x86/include/asm/processor.h +2 -2
@@ -282,7 +282,7 @@ struct tss_struct { }____cacheline_aligned ; -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss); +DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss);/* * Save the original ist values for checking stack pointers during debugging
@@ -566,7 +566,7 @@ static inline void native_swapgs(void)static inline unsigned long this_cpu_sp0 (void ) { -return this_cpu_read_stable (init_tss.x86_tss.sp0); +return this_cpu_read_stable (cpu_tss.x86_tss.sp0); }#ifdef CONFIG_PARAVIRT
arch/x86/kernel/cpu/common.c +3 -3
@@ -979,7 +979,7 @@ static void syscall32_cpu_init(void)void enable_sep_cpu (void ) {int cpu =get_cpu (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); +struct tss_struct *tss = &per_cpu (cpu_tss, cpu);if (!boot_cpu_has (X86_FEATURE_SEP )) {put_cpu ();
@@ -1307,7 +1307,7 @@ void cpu_init(void)*/ load_ucode_ap (); - t = &per_cpu (init_tss, cpu); + t = &per_cpu (cpu_tss, cpu); oist = &per_cpu (orig_ist, cpu);#ifdef CONFIG_NUMA
@@ -1391,7 +1391,7 @@ void cpu_init(void) {int cpu =smp_processor_id ();struct task_struct *curr = current; -struct tss_struct *t = &per_cpu (init_tss, cpu); +struct tss_struct *t = &per_cpu (cpu_tss, cpu);struct thread_struct *thread = &curr->thread;wait_for_master_cpu (cpu);
arch/x86/kernel/entry_64.S +1 -1
@@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) +#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym)
arch/x86/kernel/ioport.c +1 -1
@@ -54,7 +54,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)* because the ->io_bitmap_max value must match the bitmap * contents: */ - tss = &per_cpu (init_tss,get_cpu ()); + tss = &per_cpu (cpu_tss,get_cpu ());if (turn_on)bitmap_clear (t->io_bitmap_ptr, from, num);
arch/x86/kernel/process.c +3 -3
@@ -37,8 +37,8 @@* section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,init_tss ) =INIT_TSS ; -EXPORT_PER_CPU_SYMBOL_GPL (init_tss); +__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,cpu_tss ) =INIT_TSS ; +EXPORT_PER_CPU_SYMBOL_GPL (cpu_tss);#ifdef CONFIG_X86_64 static DEFINE_PER_CPU(unsigned char, is_idle);
@@ -110,7 +110,7 @@ void exit_thread(void)unsigned long *bp = t->io_bitmap_ptr;if (bp) { -struct tss_struct *tss = &per_cpu (init_tss,get_cpu ()); +struct tss_struct *tss = &per_cpu (cpu_tss,get_cpu ()); t->io_bitmap_ptr =NULL ;clear_thread_flag (TIF_IO_BITMAP );
arch/x86/kernel/process_32.c +1 -1
@@ -248,7 +248,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread;int cpu =smp_processor_id (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); +struct tss_struct *tss = &per_cpu (cpu_tss, cpu);fpu_switch_t fpu;/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
arch/x86/kernel/process_64.c +1 -1
@@ -277,7 +277,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)struct thread_struct *prev = &prev_p->thread;struct thread_struct *next = &next_p->thread;int cpu =smp_processor_id (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); +struct tss_struct *tss = &per_cpu (cpu_tss, cpu);unsigned fsindex, gsindex;fpu_switch_t fpu;
arch/x86/kernel/vm86_32.c +2 -2
@@ -150,7 +150,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs)do_exit (SIGSEGV ); } - tss = &per_cpu (init_tss,get_cpu ()); + tss = &per_cpu (cpu_tss,get_cpu ()); current->thread.sp0 = current->thread.saved_sp0; current->thread.sysenter_cs = __KERNEL_CS;load_sp0 (tss, ¤t->thread);
@@ -318,7 +318,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk tsk->thread.saved_fs = info->regs32->fs; tsk->thread.saved_gs =get_user_gs (info->regs32); - tss = &per_cpu (init_tss,get_cpu ()); + tss = &per_cpu (cpu_tss,get_cpu ()); tsk->thread.sp0 = (unsigned long ) &info->VM86_TSS_ESP0;if (cpu_has_sep) tsk->thread.sysenter_cs =0 ;
arch/x86/power/cpu.c +1 -1
@@ -134,7 +134,7 @@ static void do_fpu_end(void)static void fix_processor_context (void ) {int cpu =smp_processor_id (); -struct tss_struct *t = &per_cpu (init_tss, cpu); +struct tss_struct *t = &per_cpu (cpu_tss, cpu);#ifdef CONFIG_X86_64 struct desc_struct *desc =get_cpu_gdt_table (cpu);tss_desc tss;
PATCH v2 5/6 x86: Remove INIT_TSS and fold the definitions into cpu_tss
In reply to Andy LutomirskiThe INIT_TSS is unnecessary. Just define the initial TSS where cpu_tss is defined.
While we're at it, merge the 32-bit and 64-bit definitions. The only syntactic change is that 32-bit kernels were computing sp0 as long, but now they compute it as unsigned long.
Verified by objdump: the contents and relocations of .data..percpu..shared_aligned are unchanged on 32-bit and 64-bit kernels.
--- arch/x86/include/asm/processor.h | 20 -------------------- arch/x86/kernel/process.c | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 21 deletions(-)
arch/x86/include/asm/processor.h +0 -20
@@ -818,22 +818,6 @@ static inline void spin_lock_prefetch(const void *x) .io_bitmap_ptr = NULL, \ } -/* -* Note that the .io_bitmap member must be extra-big. This is 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. -*/ -#define INIT_TSS { \ - .x86_tss = { \ - .sp0 = sizeof(init_stack) + (long)&init_stack, \ - .ss0 = __KERNEL_DS, \ - .ss1 = __KERNEL_CS, \ - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ - }, \ - .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, \ -} -extern unsigned long thread_saved_pc (struct task_struct *tsk);#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
@@ -892,10 +876,6 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -#define INIT_TSS { \ - .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ -} -/* * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork.
arch/x86/kernel/process.c +19 -1
@@ -37,7 +37,25 @@* section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,cpu_tss ) =INIT_TSS ; +__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,cpu_tss ) = { + .x86_tss = { + .sp0 = (unsigned long )&init_stack +sizeof (init_stack), +#ifdef CONFIG_X86_32 + .ss0 = __KERNEL_DS, + .ss1 = __KERNEL_CS, + .io_bitmap_base =INVALID_IO_BITMAP_OFFSET , +#endif + }, +#ifdef CONFIG_X86_32 + /* + * Note that the .io_bitmap member must be extra-big. This is 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. + */ + .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, +#endif +};EXPORT_PER_CPU_SYMBOL_GPL (cpu_tss);#ifdef CONFIG_X86_64
Signature · 1 line
2.1.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry: Remove INIT_TSS and fold the definitions into 'cpu_tss'
x86/asm/entry: Remove INIT_TSS and fold the definitions into 'cpu_tss'
Commit-ID: d0a0de21f82bbc1737ea3c831f018d0c2bc6b9c2 Gitweb: http://git.kernel.org/tip/d0a0de21f82bbc1737ea3c831f018d0c2bc6b9c2 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 5 Mar 2015 19:19:06 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 6 Mar 2015 08:32:58 +0100
x86/asm/entry: Remove INIT_TSS and fold the definitions into 'cpu_tss'
The INIT_TSS is unnecessary. Just define the initial TSS where 'cpu_tss' is defined.
While we're at it, merge the 32-bit and 64-bit definitions. The only syntactic change is that 32-bit kernels were computing sp0 as long, but now they compute it as unsigned long.
Verified by objdump: the contents and relocations of .data..percpu..shared_aligned are unchanged on 32-bit and 64-bit kernels.
--- arch/x86/include/asm/processor.h | 20 -------------------- arch/x86/kernel/process.c | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 21 deletions(-)
arch/x86/include/asm/processor.h +0 -20
@@ -818,22 +818,6 @@ static inline void spin_lock_prefetch(const void *x) .io_bitmap_ptr = NULL, \ } -/* -* Note that the .io_bitmap member must be extra-big. This is 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. -*/ -#define INIT_TSS { \ - .x86_tss = { \ - .sp0 = sizeof(init_stack) + (long)&init_stack, \ - .ss0 = __KERNEL_DS, \ - .ss1 = __KERNEL_CS, \ - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ - }, \ - .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, \ -} -extern unsigned long thread_saved_pc (struct task_struct *tsk);#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
@@ -892,10 +876,6 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } -#define INIT_TSS { \ - .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ -} -/* * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork.
arch/x86/kernel/process.c +19 -1
@@ -37,7 +37,25 @@* section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,cpu_tss ) =INIT_TSS ; +__visible DEFINE_PER_CPU_SHARED_ALIGNED (struct tss_struct ,cpu_tss ) = { + .x86_tss = { + .sp0 = (unsigned long )&init_stack +sizeof (init_stack), +#ifdef CONFIG_X86_32 + .ss0 = __KERNEL_DS, + .ss1 = __KERNEL_CS, + .io_bitmap_base =INVALID_IO_BITMAP_OFFSET , +#endif + }, +#ifdef CONFIG_X86_32 + /* + * Note that the .io_bitmap member must be extra-big. This is 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. + */ + .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, +#endif +};EXPORT_PER_CPU_SYMBOL_GPL (cpu_tss);#ifdef CONFIG_X86_64
PATCH v2 6/6 x86, asm: Rename INIT_TSS_IST to TSS_IST
In reply to Andy LutomirskiThis has nothing to do with the init thread or the initial anything. It's just the TSS.
--- arch/x86/kernel/entry_64.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/entry_64.S +3 -3
@@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) +#define TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym)
@@ -1015,13 +1015,13 @@ ENTRY(\sym) .endif .if \shift_ist != -1 - subq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + subq $EXCEPTION_STKSZ, TSS_IST(\shift_ist) .endif call \do_sym .if \shift_ist != -1 - addq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + addq $EXCEPTION_STKSZ, TSS_IST(\shift_ist) .endif /* these procedures expect "no swapgs" flag in ebx */
Signature · 1 line
2.1.0
Re: [PATCH v2 6/6] x86, asm: Rename INIT_TSS_IST to TSS_IST
Quoted 27 lines · Andy Lutomirski
This has nothing to do with the init thread or the initial anything. It's just the TSS.
Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/kernel/entry_64.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)arch/x86/kernel/entry_64.S +2
-2@@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) +#define TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym)@@ -1015,13 +1015,13 @@ ENTRY(\sym) .endif .if \shift_ist != -1 - subq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + subq $EXCEPTION_STKSZ, TSS_IST(\shift_ist)
arch/x86/kernel/entry_64.S ENTRY(\sym) · line 1027
Quoted 10 lines
arch/x86/kernel/entry_64.S +1
-1.endif call \do_sym .if \shift_ist != -1 - addq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + addq $EXCEPTION_STKSZ, TSS_IST(\shift_ist) .endif /* these procedures expect "no swapgs" flag in ebx */
If you don't mind I've renamed this to 'CPU_TSS_IST', to be in line with cpu_tss.
The per-cpuness of this symbol gets lost at the usage sites, because the PER_CPU_VAR() reference is hidden in a macro.
Thanks,
Ingo
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry: Rename 'INIT_TSS_IST' to ' CPU_TSS_IST'
In reply to Andy Lutomirskix86/asm/entry: Rename 'INIT_TSS_IST' to 'CPU_TSS_IST'
Commit-ID: 9b47668843d800ed57f6f6bfd6f5c4cffdf201c6 Gitweb: http://git.kernel.org/tip/9b47668843d800ed57f6f6bfd6f5c4cffdf201c6 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 5 Mar 2015 19:19:07 -0800 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 6 Mar 2015 08:32:58 +0100
x86/asm/entry: Rename 'INIT_TSS_IST' to 'CPU_TSS_IST'
This has nothing to do with the init thread or the initial anything. It's just the CPU's TSS.
--- arch/x86/kernel/entry_64.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/entry_64.S +3 -3
@@ -959,7 +959,7 @@ apicinterrupt IRQ_WORK_VECTOR \ /* * Exception entry points. */ -#define INIT_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) +#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8) .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym)
@@ -1015,13 +1015,13 @@ ENTRY(\sym) .endif .if \shift_ist != -1 - subq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + subq $EXCEPTION_STKSZ, CPU_TSS_IST(\shift_ist) .endif call \do_sym .if \shift_ist != -1 - addq $EXCEPTION_STKSZ, INIT_TSS_IST(\shift_ist) + addq $EXCEPTION_STKSZ, CPU_TSS_IST(\shift_ist) .endif /* these procedures expect "no swapgs" flag in ebx */