]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/amd64/amd64/sys_machdep.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / amd64 / amd64 / sys_machdep.c
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 }