1 /*- 2 * Copyright (c) 2003 Peter Wemm. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 4. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/lock.h> 39 #include <sys/proc.h> 40 #include <sys/sysproto.h> 41 #include <machine/specialreg.h> 42 #include <machine/sysarch.h> 43 #include <machine/pcb.h> 44 45 #include <vm/vm.h> 46 #include <vm/pmap.h> 47 #include <machine/vmparam.h> 48 49 #ifndef _SYS_SYSPROTO_H_ 50 struct sysarch_args { 51 int op; 52 char *parms; 53 }; 54 #endif 55 56 int 57 sysarch(td, uap) 58 struct thread *td; 59 register struct sysarch_args *uap; 60 { 61 int error = 0; 62 struct pcb *pcb = curthread->td_pcb; 63 uint32_t i386base; 64 uint64_t a64base; 65 66 switch(uap->op) { 67 case I386_GET_FSBASE: 68 i386base = pcb->pcb_fsbase; 69 error = copyout(&i386base, uap->parms, sizeof(i386base)); 70 break; 71 case I386_SET_FSBASE: 72 error = copyin(uap->parms, &i386base, sizeof(i386base)); 73 if (!error) { 74 critical_enter(); 75 wrmsr(MSR_FSBASE, i386base); 76 pcb->pcb_fsbase = i386base; 77 critical_exit(); 78 } 79 break; 80 case I386_GET_GSBASE: 81 i386base = pcb->pcb_gsbase; 82 error = copyout(&i386base, uap->parms, sizeof(i386base)); 83 break; 84 case I386_SET_GSBASE: 85 error = copyin(uap->parms, &i386base, sizeof(i386base)); 86 if (!error) { 87 critical_enter(); 88 wrmsr(MSR_KGSBASE, i386base); 89 pcb->pcb_gsbase = i386base; 90 critical_exit(); 91 } 92 break; 93 case AMD64_GET_FSBASE: 94 error = copyout(&pcb->pcb_fsbase, uap->parms, sizeof(pcb->pcb_fsbase)); 95 break; 96 97 case AMD64_SET_FSBASE: 98 error = copyin(uap->parms, &a64base, sizeof(a64base)); 99 if (!error) { 100 if (a64base < VM_MAXUSER_ADDRESS) { 101 critical_enter(); 102 wrmsr(MSR_FSBASE, a64base); 103 pcb->pcb_fsbase = a64base; 104 critical_exit(); 105 } else { 106 error = EINVAL; 107 } 108 } 109 break; 110 111 case AMD64_GET_GSBASE: 112 error = copyout(&pcb->pcb_gsbase, uap->parms, sizeof(pcb->pcb_gsbase)); 113 break; 114 115 case AMD64_SET_GSBASE: 116 error = copyin(uap->parms, &a64base, sizeof(a64base)); 117 if (!error) { 118 if (a64base < VM_MAXUSER_ADDRESS) { 119 critical_enter(); 120 wrmsr(MSR_KGSBASE, a64base); 121 pcb->pcb_gsbase = a64base; 122 critical_exit(); 123 } else { 124 error = EINVAL; 125 } 126 } 127 break; 128 129 default: 130 error = EINVAL; 131 break; 132 } 133 return (error); 134 } 135