PERFORCE change 80922 for review
Peter Wemm
peter at FreeBSD.org
Sun Jul 24 18:34:00 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80922
Change 80922 by peter at 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);
More information about the p4-projects
mailing list