All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander van Heukelum <heukelum@fastmail.fm>
To: Andy Lutomirski <luto@amacapital.net>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Cc: Frederic Weisbecker <fweisbec@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>, Borislav Petkov <bp@suse.de>,
	Rik van Riel <riel@redhat.com>
Subject: [PATCHv2 3/4] i386: clean up KERNEL_STACK_OFFSET
Date: Sun, 18 Jan 2015 12:45:19 +0100	[thread overview]
Message-ID: <1421581520-2816-4-git-send-email-heukelum@fastmail.fm> (raw)
In-Reply-To: <1421581520-2816-1-git-send-email-heukelum@fastmail.fm>

On i386, 8 bytes are reserved above the user ptregs frame. The area is
unused, but "necessary to guarantee that the entire "struct pt_regs" is
accessible even if the CPU haven't stored the SS/ESP registers on the
stack (interrupt gate does not save these registers when switching to
the same priv ring)."

Use KERNEL_STACK_OFFSET to make the size of this area configurable and
remove the difference between the sp0 setting in the tss and the percpu
variable kernel_stack.

For i386, KERNEL_STACK_OFFSET must be at least 8 bytes for the reason
mentioned above and must be a multiple of 4 bytes, the minimal stack
alignment.

Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
---
 arch/x86/include/asm/processor.h   | 32 +++++++-------------------------
 arch/x86/include/asm/thread_info.h | 10 ++++++----
 arch/x86/kernel/entry_32.S         |  5 +++--
 3 files changed, 16 insertions(+), 31 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 97117d1..f424e5f 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -842,7 +842,8 @@ static inline void spin_lock_prefetch(const void *x)
 #define STACK_TOP_MAX		STACK_TOP
 
 #define INIT_THREAD  {							  \
-	.sp0			= sizeof(init_stack) + (long)&init_stack, \
+	.sp0			= sizeof(init_stack) + (long)&init_stack  \
+						- KERNEL_STACK_OFFSET,    \
 	.vm86_info		= NULL,					  \
 	.sysenter_cs		= __KERNEL_CS,				  \
 	.io_bitmap_ptr		= NULL,					  \
@@ -856,7 +857,8 @@ static inline void spin_lock_prefetch(const void *x)
  */
 #define INIT_TSS  {							  \
 	.x86_tss = {							  \
-		.sp0		= sizeof(init_stack) + (long)&init_stack, \
+		.sp0		= sizeof(init_stack) + (long)&init_stack  \
+						- KERNEL_STACK_OFFSET,    \
 		.ss0		= __KERNEL_DS,				  \
 		.ss1		= __KERNEL_CS,				  \
 		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,		  \
@@ -866,29 +868,9 @@ static inline void spin_lock_prefetch(const void *x)
 
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
-#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
-#define KSTK_TOP(info)                                                 \
-({                                                                     \
-       unsigned long *__ptr = (unsigned long *)(info);                 \
-       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
-})
-
-/*
- * The below -8 is to reserve 8 bytes on top of the ring0 stack.
- * This is necessary to guarantee that the entire "struct pt_regs"
- * is accessible even if the CPU haven't stored the SS/ESP registers
- * on the stack (interrupt gate does not save these registers
- * when switching to the same priv ring).
- * Therefore beware: accessing the ss/esp fields of the
- * "struct pt_regs" is possible, but they may contain the
- * completely wrong values.
- */
-#define task_pt_regs(task)                                             \
-({                                                                     \
-       struct pt_regs *__regs__;                                       \
-       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
-       __regs__ - 1;                                                   \
-})
+#define task_pt_regs(task) \
+	((struct pt_regs *)((unsigned long)task_stack_page(task) + \
+			THREAD_SIZE - KERNEL_STACK_OFFSET) - 1)
 
 #define KSTK_ESP(task)		(task_pt_regs(task)->sp)
 
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 9f0c47f..36b8a10 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -153,14 +153,16 @@ struct thread_info {
 /*
  * Amount of reserved space between the top of the kernel stack page and the
  * user ptregs frame.
+ * On i386, this is necessary to guarantee that the entire "struct pt_regs"
+ * is accessible even if the CPU hasn't stored the SS/ESP registers on the
+ * stack (an interrupt gate does not save these registers when switching to
+ * the same priv ring). Therefore beware: accessing the ss/esp fields of the
+ * "struct pt_regs" is possible, but they may contain the completely wrong
+ * values.
  * On x86_64, KERNEL_STACK_OFFSET must be set to a multiple of 16 bytes due
  * to its automatic stack alignment for interrupts, traps, and exceptions.
  */
-#ifdef CONFIG_X86_32
-#define KERNEL_STACK_OFFSET	(5*(BITS_PER_LONG/8))
-#else
 #define KERNEL_STACK_OFFSET	(2*(BITS_PER_LONG/8))
-#endif
 
 /*
  * macros/functions for gaining access to the thread information structure
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 000d419..e94b994 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -396,9 +396,10 @@ sysenter_past_esp:
 	/*
 	 * 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.
+	 * pushed above; KERNEL_STACK_OFFSET corresponds to copy_thread's
+	 * esp0 setting.
 	 */
-	pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+8+4*4)(%esp)
+	pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+KERNEL_STACK_OFFSET+4*4)(%esp)
 	CFI_REL_OFFSET eip, 0
 
 	pushl_cfi %eax
-- 
2.1.0


  parent reply	other threads:[~2015-01-18 11:46 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-18 11:45 [PATCHv2 0/4] x86, entry: some cleanup and simplification Alexander van Heukelum
2015-01-18 11:45 ` [PATCHv2 1/4] x86_64: cleanup THREAD_INFO(reg,offset) macro Alexander van Heukelum
2015-01-21 13:40   ` Denys Vlasenko
2015-01-21 16:20     ` Alexander van Heukelum
2015-01-21 18:04       ` Borislav Petkov
2015-01-21 18:48         ` Alexander van Heukelum
2015-01-18 11:45 ` [PATCHv2 2/4] x86_64: embrace KERNEL_STACK_OFFSET Alexander van Heukelum
2015-01-21 13:44   ` Denys Vlasenko
2015-01-21 16:29     ` Alexander van Heukelum
2015-01-23  0:53       ` Denys Vlasenko
2015-01-18 11:45 ` Alexander van Heukelum [this message]
2015-01-18 11:45 ` [PATCHv2 4/4] x86_64, entry: Create IRET-compatible stack frame at syscall entry Alexander van Heukelum
2015-01-18 16:38   ` Andy Lutomirski
2015-01-18 17:22     ` Alexander van Heukelum
2015-01-18 12:05 ` [PATCHv2 0/4] x86, entry: some cleanup and simplification Borislav Petkov
2015-01-18 15:47   ` Alexander van Heukelum
2015-01-21 13:26     ` Denys Vlasenko
2015-01-21 15:51       ` Alexander van Heukelum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1421581520-2816-4-git-send-email-heukelum@fastmail.fm \
    --to=heukelum@fastmail.fm \
    --cc=bp@suse.de \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=oleg@redhat.com \
    --cc=riel@redhat.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.