x86_32, asm: Minor stack/tss cleanups
cover x86_32, asm: Minor stack/tss cleanups
This cleans up some leftovers from the 32-bit tss cleanups.
Andy Lutomirski (2):
x86_32, asm: Improve a TOP_OF_KERNEL_STACK_PADDING comment and long
asm line
x86_32: Stop caching MSR_IA32_SYSENTER_ESP in tss.sp1
arch/x86/include/asm/processor.h | 22 +++++++++++----------- arch/x86/kernel/cpu/common.c | 10 ++++++---- arch/x86/kernel/entry_32.S | 10 +++++++--- 3 files changed, 24 insertions(+), 18 deletions(-)
Signature · 1 line
2.3.0
PATCH 1/2 x86_32, asm: Improve a TOP_OF_KERNEL_STACK_PADDING comment and long asm line
From: Andy Lutomirski <[email protected]>
At Denys' request, clean up the comment describing stack padding in the 32-bit sysenter path. This also fixes a long line of asm. No code changes.
--- arch/x86/kernel/entry_32.S | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
arch/x86/kernel/entry_32.S +7 -3
@@ -395,10 +395,14 @@ sysenter_past_esp: /*CFI_REL_OFFSET cs, 0*/ /* * Push current_thread_info()->sysenter_return to the stack. - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words - * pushed above; +8 corresponds to copy_thread's esp0 setting. + * A tiny bit of offset fixup is necessary: TI_sysenter_return + * is relative to thread_info, which is at the bottom of the + * kernel stack page. 4*4 means the 4 words pushed above; + * TOP_OF_KERNEL_STACK_PADDING takes us to the top of the stack; + * and THREAD_SIZE takes us to the bottom. */ - pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+TOP_OF_KERNEL_STACK_PADDING+4*4)(%esp) + pushl_cfi ((TI_sysenter_return) - THREAD_SIZE + \ + TOP_OF_KERNEL_STACK_PADDING + 4*4)(%esp) CFI_REL_OFFSET eip, 0 pushl_cfi %eax
Signature · 1 line
2.3.0
PATCH 2/2 x86_32: Stop caching MSR_IA32_SYSENTER_ESP in tss.sp1
In reply to Andy LutomirskiFrom: Andy Lutomirski <[email protected]>
We write a stack pointer to MSR_IA32_SYSENTER_ESP exactly once, and we unnecessarily cache the value in tss.sp1. We never read the cached value.
Remove all of the caching. It serves no purpose.
--- arch/x86/include/asm/processor.h | 22 +++++++++++----------- arch/x86/kernel/cpu/common.c | 10 ++++++---- 2 files changed, 17 insertions(+), 15 deletions(-)
arch/x86/include/asm/processor.h +11 -11
@@ -209,21 +209,21 @@ struct x86_hw_tss {unsigned short back_link, __blh;unsigned long sp0;unsigned short ss0, __ss0h; +unsigned long sp1;/* -* We don't use ring 1, so sp1 and ss1 are convenient scratch -* spaces in the same cacheline as sp0. We use them to cache -* some MSR values to avoid unnecessary wrmsr instructions. +* We don't use ring 1, so ss1 is a convenient scratch space in +* the same cacheline as sp0. We use ss1 to cache the value in +* MSR_IA32_SYSENTER_CS. When we context switch +* MSR_IA32_SYSENTER_CS, we first check if the new value being +* written matches ss1, and, if it's not, then we wrmsr the new +* value and update ss1. * -* We use SYSENTER_ESP to find sp0 and for the NMI emergency -* stack, but we need to context switch it because we do -* horrible things to the kernel stack in vm86 mode. -* -* We use SYSENTER_CS to disable sysenter in vm86 mode to avoid -* corrupting the stack if we went through the sysenter path -* from vm86 mode. +* The only reason we context switch MSR_IA32_SYSENTER_CS is +* that we set it to zero in vm86 tasks to avoid corrupting the +* stack if we were to go through the sysenter path from vm86 +* mode. */ -unsigned long sp1;/* MSR_IA32_SYSENTER_ESP */ unsigned short ss1;/* MSR_IA32_SYSENTER_CS */ unsigned short __ss1h;
arch/x86/kernel/cpu/common.c +6 -4
@@ -976,15 +976,17 @@ void enable_sep_cpu(void) goto out;/* -* The struct::SS1 and tss_struct::SP1 fields are not used by the hardware, -* we cache the SYSENTER CS and ESP values there for easy access: +* We cache MSR_IA32_SYSENTER_CS's value in the TSS's ss1 field -- +* see the big comment in struct x86_hw_tss's definition. */ tss->x86_tss.ss1 = __KERNEL_CS;wrmsr (MSR_IA32_SYSENTER_CS , tss->x86_tss.ss1,0 ); - tss->x86_tss.sp1 = (unsigned long)tss + offsetofend(struct tss_struct, SYSENTER_stack); -wrmsr (MSR_IA32_SYSENTER_ESP , tss->x86_tss.sp1,0 ); +wrmsr (MSR_IA32_SYSENTER_ESP , + (unsigned long )tss + + offsetofend(struct tss_struct, SYSENTER_stack), +0 );wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long )ia32_sysenter_target,0 );
Signature · 1 line
2.3.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry/32: Stop caching MSR_IA32_SYSENTER_ESP in tss.sp1
x86/asm/entry/32: Stop caching MSR_IA32_SYSENTER_ESP in tss.sp1
Commit-ID: cf9328cc9989e028fdc64d8c0a7b1b043dc96735 Gitweb: http://git.kernel.org/tip/cf9328cc9989e028fdc64d8c0a7b1b043dc96735 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 2 Apr 2015 12:41:45 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 3 Apr 2015 08:30:44 +0200
x86/asm/entry/32: Stop caching MSR_IA32_SYSENTER_ESP in tss.sp1
We write a stack pointer to MSR_IA32_SYSENTER_ESP exactly once, and we unnecessarily cache the value in tss.sp1. We never read the cached value.
Remove all of the caching. It serves no purpose.
--- arch/x86/include/asm/processor.h | 22 +++++++++++----------- arch/x86/kernel/cpu/common.c | 9 +++++---- 2 files changed, 16 insertions(+), 15 deletions(-)
arch/x86/include/asm/processor.h +11 -11
@@ -209,21 +209,21 @@ struct x86_hw_tss {unsigned short back_link, __blh;unsigned long sp0;unsigned short ss0, __ss0h; +unsigned long sp1;/* -* We don't use ring 1, so sp1 and ss1 are convenient scratch -* spaces in the same cacheline as sp0. We use them to cache -* some MSR values to avoid unnecessary wrmsr instructions. +* We don't use ring 1, so ss1 is a convenient scratch space in +* the same cacheline as sp0. We use ss1 to cache the value in +* MSR_IA32_SYSENTER_CS. When we context switch +* MSR_IA32_SYSENTER_CS, we first check if the new value being +* written matches ss1, and, if it's not, then we wrmsr the new +* value and update ss1. * -* We use SYSENTER_ESP to find sp0 and for the NMI emergency -* stack, but we need to context switch it because we do -* horrible things to the kernel stack in vm86 mode. -* -* We use SYSENTER_CS to disable sysenter in vm86 mode to avoid -* corrupting the stack if we went through the sysenter path -* from vm86 mode. +* The only reason we context switch MSR_IA32_SYSENTER_CS is +* that we set it to zero in vm86 tasks to avoid corrupting the +* stack if we were to go through the sysenter path from vm86 +* mode. */ -unsigned long sp1;/* MSR_IA32_SYSENTER_ESP */ unsigned short ss1;/* MSR_IA32_SYSENTER_CS */ unsigned short __ss1h;
arch/x86/kernel/cpu/common.c +5 -4
@@ -976,15 +976,16 @@ void enable_sep_cpu(void) goto out;/* -* The struct::SS1 and tss_struct::SP1 fields are not used by the hardware, -* we cache the SYSENTER CS and ESP values there for easy access: +* We cache MSR_IA32_SYSENTER_CS's value in the TSS's ss1 field -- +* see the big comment in struct x86_hw_tss's definition. */ tss->x86_tss.ss1 = __KERNEL_CS;wrmsr (MSR_IA32_SYSENTER_CS , tss->x86_tss.ss1,0 ); - tss->x86_tss.sp1 = (unsigned long)tss + offsetofend(struct tss_struct, SYSENTER_stack); -wrmsr (MSR_IA32_SYSENTER_ESP , tss->x86_tss.sp1,0 ); +wrmsr (MSR_IA32_SYSENTER_ESP , + (unsigned long)tss + offsetofend(struct tss_struct, SYSENTER_stack), +0 );wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long )ia32_sysenter_target,0 );
tip-bot for Andy Lutomirski
merge bot[tip:x86/asm] x86/asm/entry/32: Improve a TOP_OF_KERNEL_STACK_PADDING comment
In reply to Andy Lutomirskix86/asm/entry/32: Improve a TOP_OF_KERNEL_STACK_PADDING comment
Commit-ID: ff8287f36381deff729aa4e7b02296a080519fd0 Gitweb: http://git.kernel.org/tip/ff8287f36381deff729aa4e7b02296a080519fd0 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 2 Apr 2015 12:41:44 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 3 Apr 2015 08:30:44 +0200
x86/asm/entry/32: Improve a TOP_OF_KERNEL_STACK_PADDING comment
At Denys' request, clean up the comment describing stack padding in the 32-bit sysenter path.
No code changes.
--- arch/x86/kernel/entry_32.S | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/x86/kernel/entry_32.S +6 -3
@@ -395,10 +395,13 @@ sysenter_past_esp: /*CFI_REL_OFFSET cs, 0*/ /* * Push current_thread_info()->sysenter_return to the stack. - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words - * pushed above; +8 corresponds to copy_thread's esp0 setting. + * A tiny bit of offset fixup is necessary: TI_sysenter_return + * is relative to thread_info, which is at the bottom of the + * kernel stack page. 4*4 means the 4 words pushed above; + * TOP_OF_KERNEL_STACK_PADDING takes us to the top of the stack; + * and THREAD_SIZE takes us to the bottom. */ - pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+TOP_OF_KERNEL_STACK_PADDING+4*4)(%esp) + pushl_cfi ((TI_sysenter_return) - THREAD_SIZE + TOP_OF_KERNEL_STACK_PADDING + 4*4)(%esp) CFI_REL_OFFSET eip, 0 pushl_cfi %eax