PERFORCE change 31199 for review
Peter Wemm
peter at FreeBSD.org
Wed May 14 15:02:27 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=31199
Change 31199 by peter at 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
More information about the p4-projects
mailing list