From: Zachary Amsden Add some convenient segment macros to the kernel. This makes the rather obfuscated 'seg & 4' go away. Signed-off-by: Zachary Amsden Signed-off-by: Andrew Morton --- arch/i386/kernel/entry.S | 4 ++-- arch/i386/kernel/kprobes.c | 4 ++-- arch/i386/kernel/ptrace.c | 4 +--- arch/i386/mm/fault.c | 4 ++-- include/asm-i386/segment.h | 10 ++++++++++ 5 files changed, 17 insertions(+), 9 deletions(-) diff -puN arch/i386/kernel/entry.S~i386--add-some-segment-convenience-functions arch/i386/kernel/entry.S --- 25/arch/i386/kernel/entry.S~i386--add-some-segment-convenience-functions Wed Aug 17 13:33:48 2005 +++ 25-akpm/arch/i386/kernel/entry.S Wed Aug 17 13:33:48 2005 @@ -250,8 +250,8 @@ restore_all: # See comments in process.c:copy_thread() for details. movb OLDSS(%esp), %ah movb CS(%esp), %al - andl $(VM_MASK | (4 << 8) | 3), %eax - cmpl $((4 << 8) | 3), %eax + andl $(VM_MASK | (LDT_SEGMENT << 8) | 3), %eax + cmpl $((LDT_SEGMENT << 8) | 3), %eax je ldt_ss # returning to user-space with LDT SS restore_nocheck: RESTORE_REGS diff -puN arch/i386/kernel/kprobes.c~i386--add-some-segment-convenience-functions arch/i386/kernel/kprobes.c --- 25/arch/i386/kernel/kprobes.c~i386--add-some-segment-convenience-functions Wed Aug 17 13:33:48 2005 +++ 25-akpm/arch/i386/kernel/kprobes.c Wed Aug 17 13:33:48 2005 @@ -162,8 +162,8 @@ static int kprobe_handler(struct pt_regs /* Check if the application is using LDT entry for its code segment and * calculate the address by reading the base address from the LDT entry. */ - if ((regs->xcs & 4) && (current->mm)) { - lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8) + if (segment_from_ldt(regs->xcs) && (current->mm)) { + lp = (unsigned long *) ((unsigned long)(segment_index(regs->xcs) * 8) + (char *) current->mm->context.ldt); addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip - sizeof(kprobe_opcode_t)); diff -puN arch/i386/kernel/ptrace.c~i386--add-some-segment-convenience-functions arch/i386/kernel/ptrace.c --- 25/arch/i386/kernel/ptrace.c~i386--add-some-segment-convenience-functions Wed Aug 17 13:33:48 2005 +++ 25-akpm/arch/i386/kernel/ptrace.c Wed Aug 17 13:33:48 2005 @@ -146,8 +146,6 @@ static unsigned long getreg(struct task_ return retval; } -#define LDT_SEGMENT 4 - static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_regs *regs) { unsigned long addr, seg; @@ -165,7 +163,7 @@ static unsigned long convert_eip_to_line * TLS segments are used for data, and the PNPBIOS * and APM bios ones we just ignore here. */ - if (seg & LDT_SEGMENT) { + if (segment_from_ldt(seg)) { u32 *desc; unsigned long base; diff -puN arch/i386/mm/fault.c~i386--add-some-segment-convenience-functions arch/i386/mm/fault.c --- 25/arch/i386/mm/fault.c~i386--add-some-segment-convenience-functions Wed Aug 17 13:33:48 2005 +++ 25-akpm/arch/i386/mm/fault.c Wed Aug 17 13:33:48 2005 @@ -100,7 +100,7 @@ static inline unsigned long get_segment_ /* Get the GDT/LDT descriptor base. When you look for races in this code remember that LDT and other horrors are only used in user space. */ - if (seg & (1<<2)) { + if (segment_from_ldt(seg)) { /* Must lock the LDT while reading it. */ down(¤t->mm->context.sem); desc = current->mm->context.ldt; @@ -114,7 +114,7 @@ static inline unsigned long get_segment_ /* Decode the code segment base from the descriptor */ base = get_desc_base((unsigned long *)desc); - if (seg & (1<<2)) { + if (segment_from_ldt(seg)) { up(¤t->mm->context.sem); } else put_cpu(); diff -puN include/asm-i386/segment.h~i386--add-some-segment-convenience-functions include/asm-i386/segment.h --- 25/include/asm-i386/segment.h~i386--add-some-segment-convenience-functions Wed Aug 17 13:33:48 2005 +++ 25-akpm/include/asm-i386/segment.h Wed Aug 17 13:33:48 2005 @@ -98,4 +98,14 @@ */ #define IDT_ENTRIES 256 +/* + * This bit is set to indicate segment selectors are in the LDT + */ +#define LDT_SEGMENT 4 + +#ifndef __ASSEMBLY__ +#define segment_index(seg) ((seg) >> 3) +#define segment_from_ldt(seg) ((seg) & LDT_SEGMENT) +#endif + #endif _