Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/i86pc/os/mach_kdi.c
+++ new/usr/src/uts/i86pc/os/mach_kdi.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + *
25 + * Copyright 2018 Joyent, Inc.
24 26 */
25 27
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 28 /*
29 29 * Kernel/Debugger Interface (KDI) routines. Called during debugger under
30 30 * various system states (boot, while running, while the debugger has control).
31 31 * Functions intended for use while the debugger has control may not grab any
32 32 * locks or perform any functions that assume the availability of other system
33 33 * services.
34 34 */
35 35
36 36 #include <sys/systm.h>
37 37 #include <sys/x86_archext.h>
38 38 #include <sys/kdi_impl.h>
39 39 #include <sys/smp_impldefs.h>
40 40 #include <sys/psm_types.h>
41 41 #include <sys/segments.h>
42 42 #include <sys/archsystm.h>
43 43 #include <sys/controlregs.h>
44 44 #include <sys/trap.h>
45 45 #include <sys/kobj.h>
46 46 #include <sys/kobj_impl.h>
47 47 #include <sys/mach_mmu.h>
48 48
49 49 void
50 50 kdi_idt_write(gate_desc_t *gate, uint_t vec)
51 51 {
52 52 gate_desc_t *idt = CPU->cpu_m.mcpu_idt;
53 53
54 54 /*
55 55 * See kdi_idtr_set().
56 56 */
57 57 if (idt == NULL) {
58 58 desctbr_t idtr;
59 59 rd_idtr(&idtr);
60 60 idt = (gate_desc_t *)idtr.dtr_base;
61 61 }
62 62
63 63 idt[vec] = *gate;
64 64 }
65 65
66 66 ulong_t
67 67 kdi_dreg_get(int reg)
68 68 {
69 69 switch (reg) {
70 70 case 0:
71 71 return (kdi_getdr0());
72 72 case 1:
73 73 return (kdi_getdr1());
74 74 case 2:
75 75 return (kdi_getdr2());
76 76 case 3:
77 77 return (kdi_getdr3());
78 78 case 6:
79 79 return (kdi_getdr6());
80 80 case 7:
81 81 return (kdi_getdr7());
82 82 default:
83 83 panic("invalid debug register dr%d", reg);
84 84 /*NOTREACHED*/
85 85 }
86 86 }
87 87
88 88 void
89 89 kdi_dreg_set(int reg, ulong_t value)
90 90 {
91 91 switch (reg) {
92 92 case 0:
93 93 kdi_setdr0(value);
94 94 break;
95 95 case 1:
96 96 kdi_setdr1(value);
97 97 break;
98 98 case 2:
99 99 kdi_setdr2(value);
100 100 break;
101 101 case 3:
102 102 kdi_setdr3(value);
103 103 break;
104 104 case 6:
105 105 kdi_setdr6(value);
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
106 106 break;
107 107 case 7:
108 108 kdi_setdr7(value);
109 109 break;
110 110 default:
111 111 panic("invalid debug register dr%d", reg);
112 112 /*NOTREACHED*/
113 113 }
114 114 }
115 115
116 -void
117 -kdi_flush_caches(void)
118 -{
119 - reload_cr3();
120 -}
121 -
122 116 extern void kdi_slave_entry(void);
123 117
124 118 void
125 119 kdi_stop_slaves(int cpu, int doxc)
126 120 {
127 121 if (doxc)
128 122 kdi_xc_others(cpu, kdi_slave_entry);
129 123 }
130 124
131 125 /*
132 126 * On i86pc, slaves busy-loop, so we don't need to do anything here.
133 127 */
134 128 void
135 129 kdi_start_slaves(void)
136 130 {
137 131 }
138 132
139 133 void
140 134 kdi_slave_wait(void)
141 135 {
142 136 }
143 137
144 138 /*
145 139 * Caution.
146 140 * These routines are called -extremely- early, during kmdb initialization.
147 141 *
148 142 * Many common kernel functions assume that %gs has been initialized,
149 143 * and fail horribly if it hasn't. At this point, the boot code has
150 144 * reserved a descriptor for us (KMDBGS_SEL) in it's GDT; arrange for it
151 145 * to point at a dummy cpu_t, temporarily at least.
152 146 *
153 147 * Note that kmdb entry relies on the fake cpu_t having zero cpu_idt/cpu_id.
154 148 */
155 149
156 150 #if defined(__amd64)
157 151
158 152 void *
159 153 boot_kdi_tmpinit(void)
160 154 {
161 155 cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP);
162 156 uintptr_t old;
163 157
164 158 cpu->cpu_self = cpu;
165 159
166 160 old = (uintptr_t)rdmsr(MSR_AMD_GSBASE);
167 161 wrmsr(MSR_AMD_GSBASE, (uint64_t)cpu);
168 162 return ((void *)old);
169 163 }
170 164
171 165 void
172 166 boot_kdi_tmpfini(void *old)
173 167 {
174 168 wrmsr(MSR_AMD_GSBASE, (uint64_t)old);
175 169 }
176 170
177 171 #elif defined(__i386)
178 172
179 173 void *
180 174 boot_kdi_tmpinit(void)
181 175 {
182 176 cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP);
183 177 uintptr_t old;
184 178 desctbr_t b_gdtr;
185 179 user_desc_t *bgdt;
186 180
187 181 cpu->cpu_self = cpu;
188 182
189 183 rd_gdtr(&b_gdtr);
190 184 bgdt = (user_desc_t *)(b_gdtr.dtr_base);
191 185
192 186 set_usegd(&bgdt[GDT_BGSTMP],
193 187 cpu, sizeof (*cpu), SDT_MEMRWA, SEL_KPL, SDP_BYTES, SDP_OP32);
194 188
195 189 /*
196 190 * Now switch %gs to point at it.
197 191 */
198 192 old = getgs();
199 193 setgs(KMDBGS_SEL);
200 194
201 195 return ((void *)old);
202 196 }
203 197
204 198 void
205 199 boot_kdi_tmpfini(void *old)
206 200 {
207 201 setgs((uintptr_t)old);
208 202 }
209 203
210 204 #endif /* __i386 */
↓ open down ↓ |
79 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX