]> git.proxmox.com Git - pve-kernel.git/blame - patches/kernel/0027-x86-idt-Unify-gate_struct-handling-for-32-64-bit-ker.patch
add objtool build fix
[pve-kernel.git] / patches / kernel / 0027-x86-idt-Unify-gate_struct-handling-for-32-64-bit-ker.patch
CommitLineData
321d628a
FG
1From 12f71c3ef98c53a158abec93ef40cd15c9120284 Mon Sep 17 00:00:00 2001
2From: Thomas Gleixner <tglx@linutronix.de>
3Date: Mon, 28 Aug 2017 08:47:37 +0200
b378f209 4Subject: [PATCH 027/233] x86/idt: Unify gate_struct handling for 32/64-bit
321d628a
FG
5 kernels
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10CVE-2017-5754
11
12The first 32 bits of gate struct are the same for 32 and 64 bit kernels.
13
14The 32-bit version uses desc_struct and no designated data structure,
15so we need different accessors for 32 and 64 bit kernels.
16
17Aside of that the macros which are necessary to build the 32-bit
18gate descriptor are horrible to read.
19
20Unify the gate structs and switch all code fiddling with it over.
21
22Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
23Cc: Andy Lutomirski <luto@kernel.org>
24Cc: Borislav Petkov <bp@alien8.de>
25Cc: Brian Gerst <brgerst@gmail.com>
26Cc: Denys Vlasenko <dvlasenk@redhat.com>
27Cc: H. Peter Anvin <hpa@zytor.com>
28Cc: Josh Poimboeuf <jpoimboe@redhat.com>
29Cc: Linus Torvalds <torvalds@linux-foundation.org>
30Cc: Peter Zijlstra <peterz@infradead.org>
31Cc: Steven Rostedt <rostedt@goodmis.org>
32Link: http://lkml.kernel.org/r/20170828064957.861974317@linutronix.de
33Signed-off-by: Ingo Molnar <mingo@kernel.org>
34(cherry picked from commit 64b163fab684e3de47aa8db6cc08ae7d2e194373)
35Signed-off-by: Andy Whitcroft <apw@canonical.com>
36Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
37(cherry picked from commit 587719b1926757eb7531e0631d63fb93cd60d0d3)
38Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
39---
40 arch/x86/include/asm/desc.h | 45 ++++++++++++++-----------------
41 arch/x86/include/asm/desc_defs.h | 57 ++++++++++++++++++++++++++--------------
42 arch/x86/kvm/vmx.c | 2 +-
43 arch/x86/xen/enlighten_pv.c | 12 ++++-----
44 4 files changed, 63 insertions(+), 53 deletions(-)
45
46diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
47index d0a21b12dd58..57e502a4e92f 100644
48--- a/arch/x86/include/asm/desc.h
49+++ b/arch/x86/include/asm/desc.h
50@@ -83,33 +83,25 @@ static inline phys_addr_t get_cpu_gdt_paddr(unsigned int cpu)
51 return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu));
52 }
53
54-#ifdef CONFIG_X86_64
55-
56 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
57 unsigned dpl, unsigned ist, unsigned seg)
58 {
59- gate->offset_low = PTR_LOW(func);
60+ gate->offset_low = (u16) func;
61+ gate->bits.p = 1;
62+ gate->bits.dpl = dpl;
63+ gate->bits.zero = 0;
64+ gate->bits.type = type;
65+ gate->offset_middle = (u16) (func >> 16);
66+#ifdef CONFIG_X86_64
67 gate->segment = __KERNEL_CS;
68- gate->ist = ist;
69- gate->p = 1;
70- gate->dpl = dpl;
71- gate->zero0 = 0;
72- gate->zero1 = 0;
73- gate->type = type;
74- gate->offset_middle = PTR_MIDDLE(func);
75- gate->offset_high = PTR_HIGH(func);
76-}
77-
78+ gate->bits.ist = ist;
79+ gate->reserved = 0;
80+ gate->offset_high = (u32) (func >> 32);
81 #else
82-static inline void pack_gate(gate_desc *gate, unsigned char type,
83- unsigned long base, unsigned dpl, unsigned flags,
84- unsigned short seg)
85-{
86- gate->a = (seg << 16) | (base & 0xffff);
87- gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8);
88-}
89-
90+ gate->segment = seg;
91+ gate->bits.ist = 0;
92 #endif
93+}
94
95 static inline int desc_empty(const void *ptr)
96 {
97@@ -185,7 +177,8 @@ static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
98 }
99
100
101-static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size)
102+static inline void set_tssldt_descriptor(void *d, unsigned long addr,
103+ unsigned type, unsigned size)
104 {
105 #ifdef CONFIG_X86_64
106 struct ldttss_desc64 *desc = d;
107@@ -193,13 +186,13 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t
108 memset(desc, 0, sizeof(*desc));
109
110 desc->limit0 = size & 0xFFFF;
111- desc->base0 = PTR_LOW(addr);
112- desc->base1 = PTR_MIDDLE(addr) & 0xFF;
113+ desc->base0 = (u16) addr;
114+ desc->base1 = (addr >> 16) & 0xFF;
115 desc->type = type;
116 desc->p = 1;
117 desc->limit1 = (size >> 16) & 0xF;
118- desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF;
119- desc->base3 = PTR_HIGH(addr);
120+ desc->base2 = (addr >> 24) & 0xFF;
121+ desc->base3 = (u32) (addr >> 32);
122 #else
123 pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
124 #endif
125diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
126index 49265345d4d2..d684bee8a59a 100644
127--- a/arch/x86/include/asm/desc_defs.h
128+++ b/arch/x86/include/asm/desc_defs.h
129@@ -47,20 +47,6 @@ enum {
130 GATE_TASK = 0x5,
131 };
132
133-/* 16byte gate */
134-struct gate_struct64 {
135- u16 offset_low;
136- u16 segment;
137- unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
138- u16 offset_middle;
139- u32 offset_high;
140- u32 zero1;
141-} __attribute__((packed));
142-
143-#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF)
144-#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF)
145-#define PTR_HIGH(x) ((unsigned long long)(x) >> 32)
146-
147 enum {
148 DESC_TSS = 0x9,
149 DESC_LDT = 0x2,
150@@ -77,20 +63,51 @@ struct ldttss_desc64 {
151 u32 zero1;
152 } __attribute__((packed));
153
154+
155 #ifdef CONFIG_X86_64
156-typedef struct gate_struct64 gate_desc;
157 typedef struct ldttss_desc64 ldt_desc;
158 typedef struct ldttss_desc64 tss_desc;
159-#define gate_offset(g) ((g).offset_low | ((unsigned long)(g).offset_middle << 16) | ((unsigned long)(g).offset_high << 32))
160-#define gate_segment(g) ((g).segment)
161 #else
162-typedef struct desc_struct gate_desc;
163 typedef struct desc_struct ldt_desc;
164 typedef struct desc_struct tss_desc;
165-#define gate_offset(g) (((g).b & 0xffff0000) | ((g).a & 0x0000ffff))
166-#define gate_segment(g) ((g).a >> 16)
167 #endif
168
169+struct idt_bits {
170+ u16 ist : 3,
171+ zero : 5,
172+ type : 5,
173+ dpl : 2,
174+ p : 1;
175+} __attribute__((packed));
176+
177+struct gate_struct {
178+ u16 offset_low;
179+ u16 segment;
180+ struct idt_bits bits;
181+ u16 offset_middle;
182+#ifdef CONFIG_X86_64
183+ u32 offset_high;
184+ u32 reserved;
185+#endif
186+} __attribute__((packed));
187+
188+typedef struct gate_struct gate_desc;
189+
190+static inline unsigned long gate_offset(const gate_desc *g)
191+{
192+#ifdef CONFIG_X86_64
193+ return g->offset_low | ((unsigned long)g->offset_middle << 16) |
194+ ((unsigned long) g->offset_high << 32);
195+#else
196+ return g->offset_low | ((unsigned long)g->offset_middle << 16);
197+#endif
198+}
199+
200+static inline unsigned long gate_segment(const gate_desc *g)
201+{
202+ return g->segment;
203+}
204+
205 struct desc_ptr {
206 unsigned short size;
207 unsigned long address;
208diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
209index a2c95522ac99..7b447d126d17 100644
210--- a/arch/x86/kvm/vmx.c
211+++ b/arch/x86/kvm/vmx.c
212@@ -8838,7 +8838,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
213
214 vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
215 desc = (gate_desc *)vmx->host_idt_base + vector;
216- entry = gate_offset(*desc);
217+ entry = gate_offset(desc);
218 asm volatile(
219 #ifdef CONFIG_X86_64
220 "mov %%" _ASM_SP ", %[sp]\n\t"
221diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
222index 6c279c8f0a0e..49ee3315b9f7 100644
223--- a/arch/x86/xen/enlighten_pv.c
224+++ b/arch/x86/xen/enlighten_pv.c
225@@ -591,12 +591,12 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
226 {
227 unsigned long addr;
228
229- if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
230+ if (val->bits.type != GATE_TRAP && val->bits.type != GATE_INTERRUPT)
231 return 0;
232
233 info->vector = vector;
234
235- addr = gate_offset(*val);
236+ addr = gate_offset(val);
237 #ifdef CONFIG_X86_64
238 /*
239 * Look for known traps using IST, and substitute them
240@@ -629,16 +629,16 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
241 ;
242 else {
243 /* Some other trap using IST? */
244- if (WARN_ON(val->ist != 0))
245+ if (WARN_ON(val->bits.ist != 0))
246 return 0;
247 }
248 #endif /* CONFIG_X86_64 */
249 info->address = addr;
250
251- info->cs = gate_segment(*val);
252- info->flags = val->dpl;
253+ info->cs = gate_segment(val);
254+ info->flags = val->bits.dpl;
255 /* interrupt gates clear IF */
256- if (val->type == GATE_INTERRUPT)
257+ if (val->bits.type == GATE_INTERRUPT)
258 info->flags |= 1 << 2;
259
260 return 1;
261--
2622.14.2
263