mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 00:21:32 +00:00
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
This commit is contained in:
commit
01565479e9
@ -28,11 +28,11 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
|
||||
struct desc_struct *desc;
|
||||
unsigned long base;
|
||||
|
||||
seg &= ~7UL;
|
||||
seg >>= 3;
|
||||
|
||||
mutex_lock(&child->mm->context.lock);
|
||||
if (unlikely(!child->mm->context.ldt ||
|
||||
(seg >> 3) >= child->mm->context.ldt->size))
|
||||
seg >= child->mm->context.ldt->size))
|
||||
addr = -1L; /* bogus selector, access would fault */
|
||||
else {
|
||||
desc = &child->mm->context.ldt->entries[seg];
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/user.h>
|
||||
#include <asm/fpu/internal.h>
|
||||
|
||||
@ -181,7 +180,7 @@ void math_emulate(struct math_emu_info *info)
|
||||
math_abort(FPU_info, SIGILL);
|
||||
}
|
||||
|
||||
code_descriptor = LDT_DESCRIPTOR(FPU_CS);
|
||||
code_descriptor = FPU_get_ldt_descriptor(FPU_CS);
|
||||
if (SEG_D_SIZE(code_descriptor)) {
|
||||
/* The above test may be wrong, the book is not clear */
|
||||
/* Segmented 32 bit protected mode */
|
||||
|
@ -16,9 +16,24 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
/* s is always from a cpu register, and the cpu does bounds checking
|
||||
* during register load --> no further bounds checks needed */
|
||||
#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3])
|
||||
#include <asm/desc.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
static inline struct desc_struct FPU_get_ldt_descriptor(unsigned seg)
|
||||
{
|
||||
static struct desc_struct zero_desc;
|
||||
struct desc_struct ret = zero_desc;
|
||||
|
||||
#ifdef CONFIG_MODIFY_LDT_SYSCALL
|
||||
seg >>= 3;
|
||||
mutex_lock(¤t->mm->context.lock);
|
||||
if (current->mm->context.ldt && seg < current->mm->context.ldt->size)
|
||||
ret = current->mm->context.ldt->entries[seg];
|
||||
mutex_unlock(¤t->mm->context.lock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SEG_D_SIZE(x) ((x).b & (3 << 21))
|
||||
#define SEG_G_BIT(x) ((x).b & (1 << 23))
|
||||
#define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1)
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <linux/stddef.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
#include "fpu_system.h"
|
||||
#include "exception.h"
|
||||
@ -158,7 +157,7 @@ static long pm_address(u_char FPU_modrm, u_char segment,
|
||||
addr->selector = PM_REG_(segment);
|
||||
}
|
||||
|
||||
descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
|
||||
descriptor = FPU_get_ldt_descriptor(addr->selector);
|
||||
base_address = SEG_BASE_ADDR(descriptor);
|
||||
address = base_address + offset;
|
||||
limit = base_address
|
||||
|
Loading…
Reference in New Issue
Block a user