Date: Wed, 14 May 2003 15:02:25 -0700 (PDT) From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 31199 for review Message-ID: <200305142202.h4EM2P9G061160@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=31199 Change 31199 by peter@peter_hammer on 2003/05/14 15:02:11 Collect the nastiness about load_gs vs gsbase into a single file. Do load_fs/fsbase while here, except it doesn't need to disable the interrupts. Affected files ... .. //depot/projects/hammer/sys/amd64/amd64/machdep.c#35 edit .. //depot/projects/hammer/sys/amd64/ia32/ia32_sysvec.c#6 edit .. //depot/projects/hammer/sys/amd64/include/cpufunc.h#8 edit Differences ... ==== //depot/projects/hammer/sys/amd64/amd64/machdep.c#35 (text+ko) ==== @@ -476,7 +476,6 @@ { struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; - u_int64_t pc; wrmsr(MSR_FSBASE, 0); wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ @@ -486,11 +485,7 @@ load_ds(_udatasel); load_es(_udatasel); load_fs(_udatasel); - critical_enter(); - pc = rdmsr(MSR_GSBASE); - load_gs(_udatasel); /* Clobbers kernel %GS.base */ - wrmsr(MSR_GSBASE, pc); - critical_exit(); + load_gs(_udatasel); pcb->pcb_ds = _udatasel; pcb->pcb_es = _udatasel; pcb->pcb_fs = _udatasel; ==== //depot/projects/hammer/sys/amd64/ia32/ia32_sysvec.c#6 (text+ko) ==== @@ -241,8 +241,6 @@ { struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; - u_int64_t pc; - register_t s; wrmsr(MSR_FSBASE, 0); wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ @@ -252,11 +250,7 @@ load_ds(_udatasel); load_es(_udatasel); load_fs(_udatasel); - s = intr_disable(); - pc = rdmsr(MSR_GSBASE); - load_gs(_udatasel); /* Clobbers kernel %GS.base */ - wrmsr(MSR_GSBASE, pc); - intr_restore(s); + load_gs(_udatasel); pcb->pcb_ds = _udatasel; pcb->pcb_es = _udatasel; pcb->pcb_fs = _udatasel; ==== //depot/projects/hammer/sys/amd64/include/cpufunc.h#8 (text+ko) ==== @@ -475,6 +475,41 @@ __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"); +} + +#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"); +} +#else +/* Usable by userland */ static __inline void load_fs(u_int sel) { @@ -486,6 +521,7 @@ { __asm __volatile("movl %0,%%gs" : : "rm" (sel)); } +#endif /* void lidt(struct region_descriptor *addr); */ static __inline void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200305142202.h4EM2P9G061160>