From owner-p4-projects@FreeBSD.ORG Sun Jul 24 18:34:00 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C592016A421; Sun, 24 Jul 2005 18:33:59 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7F6DA16A41F for ; Sun, 24 Jul 2005 18:33:59 +0000 (GMT) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2F52043D4C for ; Sun, 24 Jul 2005 18:33:59 +0000 (GMT) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6OIXxSh035025 for ; Sun, 24 Jul 2005 18:33:59 GMT (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6OIXwNW035022 for perforce@freebsd.org; Sun, 24 Jul 2005 18:33:58 GMT (envelope-from peter@freebsd.org) Date: Sun, 24 Jul 2005 18:33:58 GMT Message-Id: <200507241833.j6OIXwNW035022@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Cc: Subject: PERFORCE change 80922 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Jul 2005 18:34:00 -0000 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 #include #include +#include #include #include ==== //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 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);