Date: Sun, 24 Jul 2005 18:33:58 GMT From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 80922 for review Message-ID: <200507241833.j6OIXwNW035022@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80922 Change 80922 by peter@peter_overcee on 2005/07/24 18:33:46 Finally do what I've been threatening to do for months and move load_gs() to a function and catch traps from it. Affected files ... .. //depot/projects/hammer/sys/amd64/amd64/exception.S#43 edit .. //depot/projects/hammer/sys/amd64/amd64/support.S#32 edit .. //depot/projects/hammer/sys/amd64/amd64/trap.c#71 edit .. //depot/projects/hammer/sys/amd64/amd64/vm_machdep.c#78 edit .. //depot/projects/hammer/sys/amd64/include/cpufunc.h#35 edit .. //depot/projects/hammer/sys/amd64/include/md_var.h#34 edit Differences ... ==== //depot/projects/hammer/sys/amd64/amd64/exception.S#43 (text+ko) ==== @@ -221,9 +221,12 @@ movq $T_PROTFLT,TF_TRAPNO(%rsp) movq $0,TF_ADDR(%rsp) movq %rdi,TF_RDI(%rsp) /* free up a GP register */ - leaq doreti_iret(%rip),%rdi + leaq doreti_iret(%rip),%rdi /* iretq trapped */ cmpq %rdi,TF_RIP(%rsp) je 2f /* kernel but with user gsbase!! */ + leaq load_gs_load(%rip),%rdi /* load_gs() trapped */ + cmpq %rdi,TF_RIP(%rsp) + je 2f testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ jz 1f /* already running with kernel GS.base */ 2: ==== //depot/projects/hammer/sys/amd64/amd64/support.S#32 (text+ko) ==== @@ -612,6 +612,24 @@ MEXITCOUNT lretq +/* + * Special handling of %gs selector. + * This is done as an asm function so that traps can be recovered + * from while in the intermediate gsbase state. + * %edi + */ +/* void load_gs(u_int sel); */ +ENTRY(load_gs) + pushfq + cli + swapgs + .globl load_gs_load +load_gs_load: + movl %edi,%gs + swapgs + popfq + ret + /*****************************************************************************/ /* setjump, longjump */ /*****************************************************************************/ ==== //depot/projects/hammer/sys/amd64/amd64/trap.c#71 (text+ko) ==== @@ -393,6 +393,20 @@ frame.tf_rip = (long)doreti_iret_fault; goto out; } + /* + * Handle invalid userland selectors causing a trap + * by turning it onto a SIGBUS. + */ + if (frame.tf_rip == (long)load_gs_load) { + ucode = code + BUS_SEGM_FAULT; + i = SIGBUS; + goto out; + } + /* + * Handle things like users passing non-canonical + * pointers to syscalls which will cause a GPF during + * copyin etc. + */ if (PCPU_GET(curpcb)->pcb_onfault != NULL) { frame.tf_rip = (long)PCPU_GET(curpcb)->pcb_onfault; ==== //depot/projects/hammer/sys/amd64/amd64/vm_machdep.c#78 (text+ko) ==== @@ -69,6 +69,7 @@ #include <machine/cpu.h> #include <machine/md_var.h> #include <machine/pcb.h> +#include <machine/specialreg.h> #include <vm/vm.h> #include <vm/vm_extern.h> ==== //depot/projects/hammer/sys/amd64/include/cpufunc.h#35 (text+ko) ==== @@ -514,47 +514,17 @@ __asm __volatile("movl %0,%%es" : : "rm" (sel)); } -#ifdef _KERNEL -/* This is defined in <machine/specialreg.h> but is too painful to get to */ -#ifndef MSR_FSBASE -#define MSR_FSBASE 0xc0000100 -#endif static __inline void load_fs(u_int sel) { - register u_int32_t fsbase __asm("ecx"); - /* Preserve the fsbase value across the selector load */ - fsbase = MSR_FSBASE; - __asm __volatile("rdmsr; movl %0,%%fs; wrmsr" - : : "rm" (sel), "c" (fsbase) : "eax", "edx"); + __asm __volatile("movl %0,%%fs" : : "rm" (sel)); } -#ifndef MSR_GSBASE -#define MSR_GSBASE 0xc0000101 -#endif -static __inline void -load_gs(u_int sel) -{ - register u_int32_t gsbase __asm("ecx"); - - /* - * Preserve the gsbase value across the selector load. - * Note that we have to disable interrupts because the gsbase - * being trashed happens to be the kernel gsbase at the time. - */ - gsbase = MSR_GSBASE; - __asm __volatile("pushfq; cli; rdmsr; movl %0,%%gs; wrmsr; popfq" - : : "rm" (sel), "c" (gsbase) : "eax", "edx"); -} +#ifdef _KERNEL +/* In assembler so we can recover from traps */ +void load_gs(u_int sel); #else -/* Usable by userland */ -static __inline void -load_fs(u_int sel) -{ - __asm __volatile("movl %0,%%fs" : : "rm" (sel)); -} - static __inline void load_gs(u_int sel) { ==== //depot/projects/hammer/sys/amd64/include/md_var.h#34 (text+ko) ==== @@ -64,6 +64,7 @@ void cpu_setregs(void); void doreti_iret(void) __asm(__STRING(doreti_iret)); void doreti_iret_fault(void) __asm(__STRING(doreti_iret_fault)); +void load_gs_load(void) __asm(__STRING(load_gs_load)); void initializecpu(void); void fillw(int /*u_short*/ pat, void *base, size_t cnt); void fpstate_drop(struct thread *td);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507241833.j6OIXwNW035022>