]> git.proxmox.com Git - pve-kernel.git/blame - patches/kernel/0147-x86-entry-Fix-assumptions-that-the-HW-TSS-is-at-the-.patch
revert buggy SCSI error handler commit
[pve-kernel.git] / patches / kernel / 0147-x86-entry-Fix-assumptions-that-the-HW-TSS-is-at-the-.patch
CommitLineData
321d628a
FG
1From 01e4ee94acbd960e302c23481529a5f5323d9969 Mon Sep 17 00:00:00 2001
2From: Andy Lutomirski <luto@kernel.org>
3Date: Mon, 4 Dec 2017 15:07:17 +0100
633c5ed1 4Subject: [PATCH 147/242] x86/entry: Fix assumptions that the HW TSS is at the
321d628a
FG
5 beginning of cpu_tss
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10CVE-2017-5754
11
12A future patch will move SYSENTER_stack to the beginning of cpu_tss
13to help detect overflow. Before this can happen, fix several code
14paths that hardcode assumptions about the old layout.
15
16Signed-off-by: Andy Lutomirski <luto@kernel.org>
17Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
18Reviewed-by: Borislav Petkov <bp@suse.de>
19Reviewed-by: Dave Hansen <dave.hansen@intel.com>
20Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
21Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
22Cc: Borislav Petkov <bp@alien8.de>
23Cc: Borislav Petkov <bpetkov@suse.de>
24Cc: Brian Gerst <brgerst@gmail.com>
25Cc: Dave Hansen <dave.hansen@linux.intel.com>
26Cc: David Laight <David.Laight@aculab.com>
27Cc: Denys Vlasenko <dvlasenk@redhat.com>
28Cc: Eduardo Valentin <eduval@amazon.com>
29Cc: Greg KH <gregkh@linuxfoundation.org>
30Cc: H. Peter Anvin <hpa@zytor.com>
31Cc: Josh Poimboeuf <jpoimboe@redhat.com>
32Cc: Juergen Gross <jgross@suse.com>
33Cc: Linus Torvalds <torvalds@linux-foundation.org>
34Cc: Peter Zijlstra <peterz@infradead.org>
35Cc: Rik van Riel <riel@redhat.com>
36Cc: Will Deacon <will.deacon@arm.com>
37Cc: aliguori@amazon.com
38Cc: daniel.gruss@iaik.tugraz.at
39Cc: hughd@google.com
40Cc: keescook@google.com
41Link: https://lkml.kernel.org/r/20171204150605.722425540@linutronix.de
42Signed-off-by: Ingo Molnar <mingo@kernel.org>
43(backported from commit 7fb983b4dd569e08564134a850dfd4eb1c63d9b8)
44Signed-off-by: Andy Whitcroft <apw@canonical.com>
45Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
46(cherry picked from commit 7123a5de72dc59dea18ce8886e7db726f7259caf)
47Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
48---
49 arch/x86/include/asm/desc.h | 2 +-
50 arch/x86/include/asm/processor.h | 9 +++++++--
51 arch/x86/kernel/cpu/common.c | 8 ++++----
52 arch/x86/kernel/doublefault.c | 36 +++++++++++++++++-------------------
53 arch/x86/kvm/vmx.c | 2 +-
54 arch/x86/power/cpu.c | 13 +++++++------
55 6 files changed, 37 insertions(+), 33 deletions(-)
56
57diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
58index 81c9b1e8cae9..b817fe247506 100644
59--- a/arch/x86/include/asm/desc.h
60+++ b/arch/x86/include/asm/desc.h
61@@ -190,7 +190,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr,
62 #endif
63 }
64
65-static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
66+static inline void __set_tss_desc(unsigned cpu, unsigned int entry, struct x86_hw_tss *addr)
67 {
68 struct desc_struct *d = get_cpu_gdt_rw(cpu);
69 tss_desc tss;
70diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
71index 5225917f9760..78123abdb046 100644
72--- a/arch/x86/include/asm/processor.h
73+++ b/arch/x86/include/asm/processor.h
74@@ -161,7 +161,7 @@ extern struct cpuinfo_x86 new_cpu_data;
75
76 #include <linux/thread_info.h>
77
78-extern struct tss_struct doublefault_tss;
79+extern struct x86_hw_tss doublefault_tss;
80 extern __u32 cpu_caps_cleared[NCAPINTS];
81 extern __u32 cpu_caps_set[NCAPINTS];
82
83@@ -246,6 +246,11 @@ static inline void load_cr3(pgd_t *pgdir)
84 write_cr3(__pa(pgdir));
85 }
86
87+/*
88+ * Note that while the legacy 'TSS' name comes from 'Task State Segment',
89+ * on modern x86 CPUs the TSS also holds information important to 64-bit mode,
90+ * unrelated to the task-switch mechanism:
91+ */
92 #ifdef CONFIG_X86_32
93 /* This is the TSS defined by the hardware. */
94 struct x86_hw_tss {
95@@ -316,7 +321,7 @@ struct x86_hw_tss {
96 #define IO_BITMAP_BITS 65536
97 #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
98 #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
99-#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap)
100+#define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss))
101 #define INVALID_IO_BITMAP_OFFSET 0x8000
102
103 struct tss_struct {
104diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
105index ffee73ec1af1..e526d82b546c 100644
106--- a/arch/x86/kernel/cpu/common.c
107+++ b/arch/x86/kernel/cpu/common.c
108@@ -1558,7 +1558,7 @@ void cpu_init(void)
109 }
110 }
111
112- t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
113+ t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
114
115 /*
116 * <= is required because the CPU will access up to
117@@ -1576,7 +1576,7 @@ void cpu_init(void)
118 * Initialize the TSS. Don't bother initializing sp0, as the initial
119 * task never enters user mode.
120 */
121- set_tss_desc(cpu, t);
122+ set_tss_desc(cpu, &t->x86_tss);
123 load_TR_desc();
124
125 load_mm_ldt(&init_mm);
126@@ -1633,12 +1633,12 @@ void cpu_init(void)
127 * Initialize the TSS. Don't bother initializing sp0, as the initial
128 * task never enters user mode.
129 */
130- set_tss_desc(cpu, t);
131+ set_tss_desc(cpu, &t->x86_tss);
132 load_TR_desc();
133
134 load_mm_ldt(&init_mm);
135
136- t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
137+ t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
138
139 #ifdef CONFIG_DOUBLEFAULT
140 /* Set up doublefault TSS pointer in the GDT */
141diff --git a/arch/x86/kernel/doublefault.c b/arch/x86/kernel/doublefault.c
142index f9c324e08d85..a9fe79d49d39 100644
143--- a/arch/x86/kernel/doublefault.c
144+++ b/arch/x86/kernel/doublefault.c
145@@ -49,25 +49,23 @@ static void doublefault_fn(void)
146 cpu_relax();
147 }
148
149-struct tss_struct doublefault_tss __cacheline_aligned = {
150- .x86_tss = {
151- .sp0 = STACK_START,
152- .ss0 = __KERNEL_DS,
153- .ldt = 0,
154- .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
155-
156- .ip = (unsigned long) doublefault_fn,
157- /* 0x2 bit is always set */
158- .flags = X86_EFLAGS_SF | 0x2,
159- .sp = STACK_START,
160- .es = __USER_DS,
161- .cs = __KERNEL_CS,
162- .ss = __KERNEL_DS,
163- .ds = __USER_DS,
164- .fs = __KERNEL_PERCPU,
165-
166- .__cr3 = __pa_nodebug(swapper_pg_dir),
167- }
168+struct x86_hw_tss doublefault_tss __cacheline_aligned = {
169+ .sp0 = STACK_START,
170+ .ss0 = __KERNEL_DS,
171+ .ldt = 0,
172+ .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
173+
174+ .ip = (unsigned long) doublefault_fn,
175+ /* 0x2 bit is always set */
176+ .flags = X86_EFLAGS_SF | 0x2,
177+ .sp = STACK_START,
178+ .es = __USER_DS,
179+ .cs = __KERNEL_CS,
180+ .ss = __KERNEL_DS,
181+ .ds = __USER_DS,
182+ .fs = __KERNEL_PERCPU,
183+
184+ .__cr3 = __pa_nodebug(swapper_pg_dir),
185 };
186
187 /* dummy for do_double_fault() call */
188diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
189index dd4996a96c71..a7c5a47beab7 100644
190--- a/arch/x86/kvm/vmx.c
191+++ b/arch/x86/kvm/vmx.c
192@@ -2280,7 +2280,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
193 * processors. See 22.2.4.
194 */
195 vmcs_writel(HOST_TR_BASE,
196- (unsigned long)this_cpu_ptr(&cpu_tss));
197+ (unsigned long)this_cpu_ptr(&cpu_tss.x86_tss));
198 vmcs_writel(HOST_GDTR_BASE, (unsigned long)gdt); /* 22.2.4 */
199
200 /*
201diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
202index 78459a6d455a..48cd87fc7222 100644
203--- a/arch/x86/power/cpu.c
204+++ b/arch/x86/power/cpu.c
205@@ -165,12 +165,13 @@ static void fix_processor_context(void)
206 struct desc_struct *desc = get_cpu_gdt_rw(cpu);
207 tss_desc tss;
208 #endif
209- set_tss_desc(cpu, t); /*
210- * This just modifies memory; should not be
211- * necessary. But... This is necessary, because
212- * 386 hardware has concept of busy TSS or some
213- * similar stupidity.
214- */
215+
216+ /*
217+ * This just modifies memory; should not be necessary. But... This is
218+ * necessary, because 386 hardware has concept of busy TSS or some
219+ * similar stupidity.
220+ */
221+ set_tss_desc(cpu, &t->x86_tss);
222
223 #ifdef CONFIG_X86_64
224 memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc));
225--
2262.14.2
227