aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-08-16 18:11:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-08-16 18:11:25 -0400
commit01565479e99882e873e4dd2f6f067b7cba3acf8f (patch)
tree014de0c29378ef1380ab6bb48baca135468aca35
parent8ed1f0e22f49ef42e63875fd2529389a32ff3566 (diff)
parent12e244f4b550498bbaf654a52f93633f7dde2dc7 (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Merge x86 fixes from Ingo Molnar: "Two followup fixes related to the previous LDT fix" Also applied a further FPU emulation fix from Andy Lutomirski to the branch before actually merging it. * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip x86/ldt: Further fix FPU emulation x86/ldt: Correct FPU emulation access to LDT x86/ldt: Correct LDT access in single stepping logic
-rw-r--r--arch/x86/kernel/step.c4
-rw-r--r--arch/x86/math-emu/fpu_entry.c3
-rw-r--r--arch/x86/math-emu/fpu_system.h21
-rw-r--r--arch/x86/math-emu/get_address.c3
4 files changed, 22 insertions, 9 deletions
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index 6273324186ac..0ccb53a9fcd9 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -28,11 +28,11 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
28 struct desc_struct *desc; 28 struct desc_struct *desc;
29 unsigned long base; 29 unsigned long base;
30 30
31 seg &= ~7UL; 31 seg >>= 3;
32 32
33 mutex_lock(&child->mm->context.lock); 33 mutex_lock(&child->mm->context.lock);
34 if (unlikely(!child->mm->context.ldt || 34 if (unlikely(!child->mm->context.ldt ||
35 (seg >> 3) >= child->mm->context.ldt->size)) 35 seg >= child->mm->context.ldt->size))
36 addr = -1L; /* bogus selector, access would fault */ 36 addr = -1L; /* bogus selector, access would fault */
37 else { 37 else {
38 desc = &child->mm->context.ldt->entries[seg]; 38 desc = &child->mm->context.ldt->entries[seg];
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c
index f37e84ab49f3..3d8f2e421466 100644
--- a/arch/x86/math-emu/fpu_entry.c
+++ b/arch/x86/math-emu/fpu_entry.c
@@ -29,7 +29,6 @@
29 29
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
31#include <asm/traps.h> 31#include <asm/traps.h>
32#include <asm/desc.h>
33#include <asm/user.h> 32#include <asm/user.h>
34#include <asm/fpu/internal.h> 33#include <asm/fpu/internal.h>
35 34
@@ -181,7 +180,7 @@ void math_emulate(struct math_emu_info *info)
181 math_abort(FPU_info, SIGILL); 180 math_abort(FPU_info, SIGILL);
182 } 181 }
183 182
184 code_descriptor = LDT_DESCRIPTOR(FPU_CS); 183 code_descriptor = FPU_get_ldt_descriptor(FPU_CS);
185 if (SEG_D_SIZE(code_descriptor)) { 184 if (SEG_D_SIZE(code_descriptor)) {
186 /* The above test may be wrong, the book is not clear */ 185 /* The above test may be wrong, the book is not clear */
187 /* Segmented 32 bit protected mode */ 186 /* Segmented 32 bit protected mode */
diff --git a/arch/x86/math-emu/fpu_system.h b/arch/x86/math-emu/fpu_system.h
index 9ccecb61a4fa..5e044d506b7a 100644
--- a/arch/x86/math-emu/fpu_system.h
+++ b/arch/x86/math-emu/fpu_system.h
@@ -16,9 +16,24 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18 18
19/* s is always from a cpu register, and the cpu does bounds checking 19#include <asm/desc.h>
20 * during register load --> no further bounds checks needed */ 20#include <asm/mmu_context.h>
21#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) 21
22static inline struct desc_struct FPU_get_ldt_descriptor(unsigned seg)
23{
24 static struct desc_struct zero_desc;
25 struct desc_struct ret = zero_desc;
26
27#ifdef CONFIG_MODIFY_LDT_SYSCALL
28 seg >>= 3;
29 mutex_lock(&current->mm->context.lock);
30 if (current->mm->context.ldt && seg < current->mm->context.ldt->size)
31 ret = current->mm->context.ldt->entries[seg];
32 mutex_unlock(&current->mm->context.lock);
33#endif
34 return ret;
35}
36
22#define SEG_D_SIZE(x) ((x).b & (3 << 21)) 37#define SEG_D_SIZE(x) ((x).b & (3 << 21))
23#define SEG_G_BIT(x) ((x).b & (1 << 23)) 38#define SEG_G_BIT(x) ((x).b & (1 << 23))
24#define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) 39#define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1)
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index 6ef5e99380f9..8300db71c2a6 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -20,7 +20,6 @@
20#include <linux/stddef.h> 20#include <linux/stddef.h>
21 21
22#include <asm/uaccess.h> 22#include <asm/uaccess.h>
23#include <asm/desc.h>
24 23
25#include "fpu_system.h" 24#include "fpu_system.h"
26#include "exception.h" 25#include "exception.h"
@@ -158,7 +157,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
158 addr->selector = PM_REG_(segment); 157 addr->selector = PM_REG_(segment);
159 } 158 }
160 159
161 descriptor = LDT_DESCRIPTOR(PM_REG_(segment)); 160 descriptor = FPU_get_ldt_descriptor(addr->selector);
162 base_address = SEG_BASE_ADDR(descriptor); 161 base_address = SEG_BASE_ADDR(descriptor);
163 address = base_address + offset; 162 address = base_address + offset;
164 limit = base_address 163 limit = base_address