mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: Dave Hansen <dave.hansen@intel.com>
Cc: Andy Lutomirski <luto@kernel.org>, X86 ML <x86@kernel.org>,
	Borislav Petkov <bpetkov@suse.de>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Brian Gerst <brgerst@gmail.com>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH v2] x86/entry: Fix assumptions that the HW TSS is at the beginning of cpu_tss
Date: Sun, 26 Nov 2017 14:48:44 +0100	[thread overview]
Message-ID: <20171126134844.o4nz6kuuzsflxrw6@gmail.com> (raw)
In-Reply-To: <2fdf9cf9-ec48-e63f-2ec8-44160c206c9a@intel.com>


* Dave Hansen <dave.hansen@intel.com> wrote:

> On 11/10/2017 08:05 PM, Andy Lutomirski wrote:
> > -struct tss_struct doublefault_tss __cacheline_aligned = {
> > -	.x86_tss = {
> > -		.sp0		= STACK_START,
> > -		.ss0		= __KERNEL_DS,
> > -		.ldt		= 0,
> ...
> > +struct x86_hw_tss doublefault_tss __cacheline_aligned = {
> > +	.sp0		= STACK_START,
> > +	.ss0		= __KERNEL_DS,
> > +	.ldt		= 0,
> > +	.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,
> 
> FWIW, I really like the trend of renaming the hardware structures in
> such a way that it's clear that they *are* hardware structures.
> 
> It might also be nice to reference the relevant SDM sections on the
> topic, or even to include a comment along the lines of how it get used.
> This chunk from the SDM is particularly relevant:
> 
> "The TSS holds information important to 64-bit mode and that is not
> directly related to the task-switch mechanism."

That makes sense - I've updated this patch with the following description added to 
struct x86_hw_tss:

+/*
+ * Note that while the legacy 'TSS' name comes from 'Task State Segment',
+ * on modern x86 CPUs the TSS holds information important to 64-bit mode
+ * unrelated to the task-switch mechanism:
+ */

I have also added your Reviewed-by tag. Updated patch below.

Thanks,

	Ingo

=====================>
Subject: x86/entry: Fix assumptions that the HW TSS is at the beginning of cpu_tss
From: Andy Lutomirski <luto@kernel.org>
Date: Thu, 23 Nov 2017 20:32:52 -0800

A future patch will move SYSENTER_stack to the beginning of cpu_tss
to help detect overflow.  Before this can happen, fix several code
paths that hardcode assumptions about the old layout.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ Updated the 'struct tss_struct' comments, as suggested by Dave Hansen. ]
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Dave Hansen <dave.hansen@intel.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lkml.kernel.org/r/d40a2c5ae4539d64090849a374f3169ec492f4e2.1511497875.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/desc.h      |    2 +-
 arch/x86/include/asm/processor.h |    9 +++++++--
 arch/x86/kernel/cpu/common.c     |    8 ++++----
 arch/x86/kernel/doublefault.c    |   32 +++++++++++++++-----------------
 arch/x86/power/cpu.c             |   13 +++++++------
 5 files changed, 34 insertions(+), 30 deletions(-)

Index: tip/arch/x86/include/asm/desc.h
===================================================================
--- tip.orig/arch/x86/include/asm/desc.h
+++ tip/arch/x86/include/asm/desc.h
@@ -178,7 +178,7 @@ static inline void set_tssldt_descriptor
 #endif
 }
 
-static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
+static inline void __set_tss_desc(unsigned cpu, unsigned int entry, struct x86_hw_tss *addr)
 {
 	struct desc_struct *d = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
Index: tip/arch/x86/include/asm/processor.h
===================================================================
--- tip.orig/arch/x86/include/asm/processor.h
+++ tip/arch/x86/include/asm/processor.h
@@ -163,7 +163,7 @@ enum cpuid_regs_idx {
 extern struct cpuinfo_x86	boot_cpu_data;
 extern struct cpuinfo_x86	new_cpu_data;
 
-extern struct tss_struct	doublefault_tss;
+extern struct x86_hw_tss	doublefault_tss;
 extern __u32			cpu_caps_cleared[NCAPINTS];
 extern __u32			cpu_caps_set[NCAPINTS];
 
@@ -253,6 +253,11 @@ static inline void load_cr3(pgd_t *pgdir
 	write_cr3(__sme_pa(pgdir));
 }
 
+/*
+ * Note that while the legacy 'TSS' name comes from 'Task State Segment',
+ * on modern x86 CPUs the TSS also holds information important to 64-bit mode,
+ * unrelated to the task-switch mechanism:
+ */
 #ifdef CONFIG_X86_32
 /* This is the TSS defined by the hardware. */
 struct x86_hw_tss {
@@ -323,7 +328,7 @@ struct x86_hw_tss {
 #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 IO_BITMAP_OFFSET		(offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss))
 #define INVALID_IO_BITMAP_OFFSET	0x8000
 
 struct tss_struct {
Index: tip/arch/x86/kernel/cpu/common.c
===================================================================
--- tip.orig/arch/x86/kernel/cpu/common.c
+++ tip/arch/x86/kernel/cpu/common.c
@@ -1582,7 +1582,7 @@ void cpu_init(void)
 		}
 	}
 
-	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
+	t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
 
 	/*
 	 * <= is required because the CPU will access up to
@@ -1601,7 +1601,7 @@ void cpu_init(void)
 	 * Initialize the TSS.  Don't bother initializing sp0, as the initial
 	 * task never enters user mode.
 	 */
-	set_tss_desc(cpu, t);
+	set_tss_desc(cpu, &t->x86_tss);
 	load_TR_desc();
 
 	load_mm_ldt(&init_mm);
@@ -1659,12 +1659,12 @@ void cpu_init(void)
 	 * Initialize the TSS.  Don't bother initializing sp0, as the initial
 	 * task never enters user mode.
 	 */
-	set_tss_desc(cpu, t);
+	set_tss_desc(cpu, &t->x86_tss);
 	load_TR_desc();
 
 	load_mm_ldt(&init_mm);
 
-	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
+	t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
 
 #ifdef CONFIG_DOUBLEFAULT
 	/* Set up doublefault TSS pointer in the GDT */
Index: tip/arch/x86/kernel/doublefault.c
===================================================================
--- tip.orig/arch/x86/kernel/doublefault.c
+++ tip/arch/x86/kernel/doublefault.c
@@ -50,25 +50,23 @@ static void doublefault_fn(void)
 		cpu_relax();
 }
 
-struct tss_struct doublefault_tss __cacheline_aligned = {
-	.x86_tss = {
-		.sp0		= STACK_START,
-		.ss0		= __KERNEL_DS,
-		.ldt		= 0,
-		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,
+struct x86_hw_tss doublefault_tss __cacheline_aligned = {
+	.sp0		= STACK_START,
+	.ss0		= __KERNEL_DS,
+	.ldt		= 0,
+	.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,
 
-		.ip		= (unsigned long) doublefault_fn,
-		/* 0x2 bit is always set */
-		.flags		= X86_EFLAGS_SF | 0x2,
-		.sp		= STACK_START,
-		.es		= __USER_DS,
-		.cs		= __KERNEL_CS,
-		.ss		= __KERNEL_DS,
-		.ds		= __USER_DS,
-		.fs		= __KERNEL_PERCPU,
+	.ip		= (unsigned long) doublefault_fn,
+	/* 0x2 bit is always set */
+	.flags		= X86_EFLAGS_SF | 0x2,
+	.sp		= STACK_START,
+	.es		= __USER_DS,
+	.cs		= __KERNEL_CS,
+	.ss		= __KERNEL_DS,
+	.ds		= __USER_DS,
+	.fs		= __KERNEL_PERCPU,
 
-		.__cr3		= __pa_nodebug(swapper_pg_dir),
-	}
+	.__cr3		= __pa_nodebug(swapper_pg_dir),
 };
 
 /* dummy for do_double_fault() call */
Index: tip/arch/x86/power/cpu.c
===================================================================
--- tip.orig/arch/x86/power/cpu.c
+++ tip/arch/x86/power/cpu.c
@@ -165,12 +165,13 @@ static void fix_processor_context(void)
 	struct desc_struct *desc = get_cpu_gdt_rw(cpu);
 	tss_desc tss;
 #endif
-	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.
-				 */
+
+	/*
+	 * This just modifies memory; should not be necessary. But... This is
+	 * necessary, because 386 hardware has concept of busy TSS or some
+	 * similar stupidity.
+	 */
+	set_tss_desc(cpu, &t->x86_tss);
 
 #ifdef CONFIG_X86_64
 	memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc));

  reply	other threads:[~2017-11-26 13:48 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-11  4:05 [RFC 0/7] Prep code for better stack switching Andy Lutomirski
2017-11-11  4:05 ` [RFC 1/7] x86/asm/64: Allocate and enable the SYSENTER stack Andy Lutomirski
2017-11-13 19:07   ` Dave Hansen
2017-11-14  2:17     ` Andy Lutomirski
2017-11-14  7:15       ` Ingo Molnar
2017-11-11  4:05 ` [RFC 2/7] x86/gdt: Put per-cpu GDT remaps in ascending order Andy Lutomirski
2017-11-11  4:05 ` [RFC 3/7] x86/fixmap: Generalize the GDT fixmap mechanism Andy Lutomirski
2017-11-11  4:05 ` [RFC 4/7] x86/asm: Fix assumptions that the HW TSS is at the beginning of cpu_tss Andy Lutomirski
2017-11-13 17:01   ` Dave Hansen
2017-11-26 13:48     ` Ingo Molnar [this message]
2017-11-26 15:41       ` [PATCH v2] x86/entry: " Andy Lutomirski
2017-11-26 15:58         ` Ingo Molnar
2017-11-26 16:00           ` Ingo Molnar
2017-11-26 16:05             ` Andy Lutomirski
2017-11-26 16:43               ` Ingo Molnar
2017-11-11  4:05 ` [RFC 5/7] x86/asm: Rearrange struct cpu_tss to enlarge SYSENTER_stack and fix alignment Andy Lutomirski
2017-11-11  4:11   ` Andy Lutomirski
2017-11-13 19:19   ` Dave Hansen
2017-11-11  4:05 ` [RFC 6/7] x86/asm: Remap the TSS into the cpu entry area Andy Lutomirski
2017-11-13 19:22   ` Dave Hansen
2017-11-13 19:36     ` Linus Torvalds
2017-11-14  2:25       ` Andy Lutomirski
2017-11-14  2:28         ` Linus Torvalds
2017-11-14  2:30           ` Andy Lutomirski
2017-11-14  2:27     ` Andy Lutomirski
2017-11-11  4:05 ` [RFC 7/7] x86/unwind/64: Add support for the SYSENTER stack Andy Lutomirski
2017-11-13 22:46   ` Josh Poimboeuf
2017-11-14  2:13     ` Andy Lutomirski
2017-11-11 10:58 ` [RFC 0/7] Prep code for better stack switching Borislav Petkov
2017-11-12  2:59   ` Andy Lutomirski
2017-11-12  4:25     ` Andy Lutomirski
2017-11-13  4:37       ` Andy Lutomirski

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=20171126134844.o4nz6kuuzsflxrw6@gmail.com \
    --to=mingo@kernel.org \
    --cc=bpetkov@suse.de \
    --cc=brgerst@gmail.com \
    --cc=dave.hansen@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome