Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
9210 remove KMDB branch debugging support
9211 ::crregs could do with cr2/cr3 support
9209 ::ttrace should be able to filter by thread
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
9207 kdi_idt: Cast GATESEG_GETOFFSET through uintptr_t
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/kdi/kdi_idt.c
+++ new/usr/src/uts/intel/kdi/kdi_idt.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 2009 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 28 /*
27 29 * Management of KMDB's IDT, which is installed upon KMDB activation.
28 30 *
29 31 * Debugger activation has two flavors, which cover the cases where KMDB is
30 32 * loaded at boot, and when it is loaded after boot. In brief, in both cases,
31 33 * the KDI needs to interpose upon several handlers in the IDT. When
32 34 * mod-loaded KMDB is deactivated, we undo the IDT interposition, restoring the
33 35 * handlers to what they were before we started.
34 36 *
35 37 * We also take over the entirety of IDT (except the double-fault handler) on
36 38 * the active CPU when we're in kmdb so we can handle things like page faults
37 39 * sensibly.
38 40 *
39 41 * Boot-loaded KMDB
40 42 *
41 43 * When we're first activated, we're running on boot's IDT. We need to be able
42 44 * to function in this world, so we'll install our handlers into boot's IDT.
43 45 * This is a little complicated: we're using the fake cpu_t set up by
44 46 * boot_kdi_tmpinit(), so we can't access cpu_idt directly. Instead,
45 47 * kdi_idt_write() notices that cpu_idt is NULL, and works around this problem.
46 48 *
47 49 * Later, when we're about to switch to the kernel's IDT, it'll call us via
48 50 * kdi_idt_sync(), allowing us to add our handlers to the new IDT. While
49 51 * boot-loaded KMDB can't be unloaded, we still need to save the descriptors we
50 52 * replace so we can pass traps back to the kernel as necessary.
51 53 *
52 54 * The last phase of boot-loaded KMDB activation occurs at non-boot CPU
53 55 * startup. We will be called on each non-boot CPU, thus allowing us to set up
54 56 * any watchpoints that may have been configured on the boot CPU and interpose
55 57 * on the given CPU's IDT. We don't save the interposed descriptors in this
56 58 * case -- see kdi_cpu_init() for details.
57 59 *
58 60 * Mod-loaded KMDB
59 61 *
60 62 * This style of activation is much simpler, as the CPUs are already running,
61 63 * and are using their own copy of the kernel's IDT. We simply interpose upon
62 64 * each CPU's IDT. We save the handlers we replace, both for deactivation and
63 65 * for passing traps back to the kernel. Note that for the hypervisors'
64 66 * benefit, we need to xcall to the other CPUs to do this, since we need to
65 67 * actively set the trap entries in its virtual IDT from that vcpu's context
66 68 * rather than just modifying the IDT table from the CPU running kdi_activate().
67 69 */
68 70
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
69 71 #include <sys/types.h>
70 72 #include <sys/segments.h>
71 73 #include <sys/trap.h>
72 74 #include <sys/cpuvar.h>
73 75 #include <sys/reboot.h>
74 76 #include <sys/sunddi.h>
75 77 #include <sys/archsystm.h>
76 78 #include <sys/kdi_impl.h>
77 79 #include <sys/x_call.h>
78 80 #include <ia32/sys/psw.h>
81 +#include <vm/hat_i86.h>
79 82
80 83 #define KDI_GATE_NVECS 3
81 84
82 85 #define KDI_IDT_NOSAVE 0
83 86 #define KDI_IDT_SAVE 1
84 87
85 88 #define KDI_IDT_DTYPE_KERNEL 0
86 89 #define KDI_IDT_DTYPE_BOOT 1
87 90
88 91 kdi_cpusave_t *kdi_cpusave;
89 92 int kdi_ncpusave;
90 93
91 94 static kdi_main_t kdi_kmdb_main;
92 95
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
93 96 kdi_drreg_t kdi_drreg;
94 97
95 98 #ifndef __amd64
96 99 /* Used to track the current set of valid kernel selectors. */
97 100 uint32_t kdi_cs;
98 101 uint32_t kdi_ds;
99 102 uint32_t kdi_fs;
100 103 uint32_t kdi_gs;
101 104 #endif
102 105
103 -uint_t kdi_msr_wrexit_msr;
104 -uint64_t *kdi_msr_wrexit_valp;
105 -
106 106 uintptr_t kdi_kernel_handler;
107 107
108 108 int kdi_trap_switch;
109 109
110 110 #define KDI_MEMRANGES_MAX 2
111 111
112 112 kdi_memrange_t kdi_memranges[KDI_MEMRANGES_MAX];
113 113 int kdi_nmemranges;
114 114
115 115 typedef void idt_hdlr_f(void);
116 116
117 117 extern idt_hdlr_f kdi_trap0, kdi_trap1, kdi_int2, kdi_trap3, kdi_trap4;
118 118 extern idt_hdlr_f kdi_trap5, kdi_trap6, kdi_trap7, kdi_trap9;
119 119 extern idt_hdlr_f kdi_traperr10, kdi_traperr11, kdi_traperr12;
120 -extern idt_hdlr_f kdi_traperr13, kdi_traperr14, kdi_trap16, kdi_trap17;
120 +extern idt_hdlr_f kdi_traperr13, kdi_traperr14, kdi_trap16, kdi_traperr17;
121 121 extern idt_hdlr_f kdi_trap18, kdi_trap19, kdi_trap20, kdi_ivct32;
122 122 extern idt_hdlr_f kdi_invaltrap;
123 123 extern size_t kdi_ivct_size;
124 -extern char kdi_slave_entry_patch;
125 124
126 125 typedef struct kdi_gate_spec {
127 126 uint_t kgs_vec;
128 127 uint_t kgs_dpl;
129 128 } kdi_gate_spec_t;
130 129
131 130 /*
132 131 * Beware: kdi_pass_to_kernel() has unpleasant knowledge of this list.
133 132 */
134 133 static const kdi_gate_spec_t kdi_gate_specs[KDI_GATE_NVECS] = {
135 134 { T_SGLSTP, TRP_KPL },
136 135 { T_BPTFLT, TRP_UPL },
137 136 { T_DBGENTR, TRP_KPL }
138 137 };
139 138
140 139 static gate_desc_t kdi_kgates[KDI_GATE_NVECS];
141 140
142 -gate_desc_t kdi_idt[NIDT];
141 +extern gate_desc_t kdi_idt[NIDT];
143 142
144 143 struct idt_description {
145 144 uint_t id_low;
146 145 uint_t id_high;
147 146 idt_hdlr_f *id_basehdlr;
148 147 size_t *id_incrp;
149 148 } idt_description[] = {
150 149 { T_ZERODIV, 0, kdi_trap0, NULL },
151 150 { T_SGLSTP, 0, kdi_trap1, NULL },
152 151 { T_NMIFLT, 0, kdi_int2, NULL },
153 152 { T_BPTFLT, 0, kdi_trap3, NULL },
154 153 { T_OVFLW, 0, kdi_trap4, NULL },
155 154 { T_BOUNDFLT, 0, kdi_trap5, NULL },
156 155 { T_ILLINST, 0, kdi_trap6, NULL },
157 156 { T_NOEXTFLT, 0, kdi_trap7, NULL },
158 157 #if !defined(__xpv)
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
159 158 { T_DBLFLT, 0, syserrtrap, NULL },
160 159 #endif
161 160 { T_EXTOVRFLT, 0, kdi_trap9, NULL },
162 161 { T_TSSFLT, 0, kdi_traperr10, NULL },
163 162 { T_SEGFLT, 0, kdi_traperr11, NULL },
164 163 { T_STKFLT, 0, kdi_traperr12, NULL },
165 164 { T_GPFLT, 0, kdi_traperr13, NULL },
166 165 { T_PGFLT, 0, kdi_traperr14, NULL },
167 166 { 15, 0, kdi_invaltrap, NULL },
168 167 { T_EXTERRFLT, 0, kdi_trap16, NULL },
169 - { T_ALIGNMENT, 0, kdi_trap17, NULL },
168 + { T_ALIGNMENT, 0, kdi_traperr17, NULL },
170 169 { T_MCE, 0, kdi_trap18, NULL },
171 170 { T_SIMDFPE, 0, kdi_trap19, NULL },
172 171 { T_DBGENTR, 0, kdi_trap20, NULL },
173 172 { 21, 31, kdi_invaltrap, NULL },
174 173 { 32, 255, kdi_ivct32, &kdi_ivct_size },
175 174 { 0, 0, NULL },
176 175 };
177 176
178 177 void
179 178 kdi_idt_init(selector_t sel)
180 179 {
181 180 struct idt_description *id;
182 181 int i;
183 182
184 183 for (id = idt_description; id->id_basehdlr != NULL; id++) {
185 184 uint_t high = id->id_high != 0 ? id->id_high : id->id_low;
186 185 size_t incr = id->id_incrp != NULL ? *id->id_incrp : 0;
187 186
187 +#if !defined(__xpv)
188 + if (kpti_enable && sel == KCS_SEL && id->id_low == T_DBLFLT)
189 + id->id_basehdlr = tr_syserrtrap;
190 +#endif
191 +
188 192 for (i = id->id_low; i <= high; i++) {
189 193 caddr_t hdlr = (caddr_t)id->id_basehdlr +
190 194 incr * (i - id->id_low);
191 195 set_gatesegd(&kdi_idt[i], (void (*)())hdlr, sel,
192 - SDT_SYSIGT, TRP_KPL, i);
196 + SDT_SYSIGT, TRP_KPL, IST_DBG);
193 197 }
194 198 }
195 199 }
196 200
197 -/*
198 - * Patch caller-provided code into the debugger's IDT handlers. This code is
199 - * used to save MSRs that must be saved before the first branch. All handlers
200 - * are essentially the same, and end with a branch to kdi_cmnint. To save the
201 - * MSR, we need to patch in before the branch. The handlers have the following
202 - * structure: KDI_MSR_PATCHOFF bytes of code, KDI_MSR_PATCHSZ bytes of
203 - * patchable space, followed by more code.
204 - */
205 -void
206 -kdi_idt_patch(caddr_t code, size_t sz)
207 -{
208 - int i;
209 -
210 - ASSERT(sz <= KDI_MSR_PATCHSZ);
211 -
212 - for (i = 0; i < sizeof (kdi_idt) / sizeof (struct gate_desc); i++) {
213 - gate_desc_t *gd;
214 - uchar_t *patch;
215 -
216 - if (i == T_DBLFLT)
217 - continue; /* uses kernel's handler */
218 -
219 - gd = &kdi_idt[i];
220 - patch = (uchar_t *)GATESEG_GETOFFSET(gd) + KDI_MSR_PATCHOFF;
221 -
222 - /*
223 - * We can't ASSERT that there's a nop here, because this may be
224 - * a debugger restart. In that case, we're copying the new
225 - * patch point over the old one.
226 - */
227 - /* FIXME: dtrace fbt ... */
228 - bcopy(code, patch, sz);
229 -
230 - /* Fill the rest with nops to be sure */
231 - while (sz < KDI_MSR_PATCHSZ)
232 - patch[sz++] = 0x90; /* nop */
233 - }
234 -}
235 -
236 201 static void
237 202 kdi_idt_gates_install(selector_t sel, int saveold)
238 203 {
239 204 gate_desc_t gates[KDI_GATE_NVECS];
240 205 int i;
241 206
242 207 bzero(gates, sizeof (*gates));
243 208
244 209 for (i = 0; i < KDI_GATE_NVECS; i++) {
245 210 const kdi_gate_spec_t *gs = &kdi_gate_specs[i];
246 211 uintptr_t func = GATESEG_GETOFFSET(&kdi_idt[gs->kgs_vec]);
247 212 set_gatesegd(&gates[i], (void (*)())func, sel, SDT_SYSIGT,
248 - gs->kgs_dpl, gs->kgs_vec);
213 + gs->kgs_dpl, IST_DBG);
249 214 }
250 215
251 216 for (i = 0; i < KDI_GATE_NVECS; i++) {
252 217 uint_t vec = kdi_gate_specs[i].kgs_vec;
253 218
254 219 if (saveold)
255 220 kdi_kgates[i] = CPU->cpu_m.mcpu_idt[vec];
256 221
257 222 kdi_idt_write(&gates[i], vec);
258 223 }
259 224 }
260 225
261 226 static void
262 227 kdi_idt_gates_restore(void)
263 228 {
264 229 int i;
265 230
266 231 for (i = 0; i < KDI_GATE_NVECS; i++)
267 232 kdi_idt_write(&kdi_kgates[i], kdi_gate_specs[i].kgs_vec);
268 233 }
269 234
270 235 /*
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
271 236 * Called when we switch to the kernel's IDT. We need to interpose on the
272 237 * kernel's IDT entries and stop using KMDBCODE_SEL.
273 238 */
274 239 void
275 240 kdi_idt_sync(void)
276 241 {
277 242 kdi_idt_init(KCS_SEL);
278 243 kdi_idt_gates_install(KCS_SEL, KDI_IDT_SAVE);
279 244 }
280 245
281 -/*
282 - * On some processors, we'll need to clear a certain MSR before proceeding into
283 - * the debugger. Complicating matters, this MSR must be cleared before we take
284 - * any branches. We have patch points in every trap handler, which will cover
285 - * all entry paths for master CPUs. We also have a patch point in the slave
286 - * entry code.
287 - */
288 -static void
289 -kdi_msr_add_clrentry(uint_t msr)
290 -{
291 -#ifdef __amd64
292 - uchar_t code[] = {
293 - 0x51, 0x50, 0x52, /* pushq %rcx, %rax, %rdx */
294 - 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */
295 - 0x31, 0xc0, /* clr %eax */
296 - 0x31, 0xd2, /* clr %edx */
297 - 0x0f, 0x30, /* wrmsr */
298 - 0x5a, 0x58, 0x59 /* popq %rdx, %rax, %rcx */
299 - };
300 - uchar_t *patch = &code[4];
301 -#else
302 - uchar_t code[] = {
303 - 0x60, /* pushal */
304 - 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */
305 - 0x31, 0xc0, /* clr %eax */
306 - 0x31, 0xd2, /* clr %edx */
307 - 0x0f, 0x30, /* wrmsr */
308 - 0x61 /* popal */
309 - };
310 - uchar_t *patch = &code[2];
311 -#endif
312 -
313 - bcopy(&msr, patch, sizeof (uint32_t));
314 -
315 - kdi_idt_patch((caddr_t)code, sizeof (code));
316 -
317 - bcopy(code, &kdi_slave_entry_patch, sizeof (code));
318 -}
319 -
320 -static void
321 -kdi_msr_add_wrexit(uint_t msr, uint64_t *valp)
322 -{
323 - kdi_msr_wrexit_msr = msr;
324 - kdi_msr_wrexit_valp = valp;
325 -}
326 -
327 246 void
328 -kdi_set_debug_msrs(kdi_msr_t *msrs)
329 -{
330 - int nmsrs, i;
331 -
332 - ASSERT(kdi_cpusave[0].krs_msr == NULL);
333 -
334 - /* Look in CPU0's MSRs for any special MSRs. */
335 - for (nmsrs = 0; msrs[nmsrs].msr_num != 0; nmsrs++) {
336 - switch (msrs[nmsrs].msr_type) {
337 - case KDI_MSR_CLEARENTRY:
338 - kdi_msr_add_clrentry(msrs[nmsrs].msr_num);
339 - break;
340 -
341 - case KDI_MSR_WRITEDELAY:
342 - kdi_msr_add_wrexit(msrs[nmsrs].msr_num,
343 - msrs[nmsrs].kdi_msr_valp);
344 - break;
345 - }
346 - }
347 -
348 - nmsrs++;
349 -
350 - for (i = 0; i < kdi_ncpusave; i++)
351 - kdi_cpusave[i].krs_msr = &msrs[nmsrs * i];
352 -}
353 -
354 -void
355 247 kdi_update_drreg(kdi_drreg_t *drreg)
356 248 {
357 249 kdi_drreg = *drreg;
358 250 }
359 251
360 252 void
361 253 kdi_memrange_add(caddr_t base, size_t len)
362 254 {
363 255 kdi_memrange_t *mr = &kdi_memranges[kdi_nmemranges];
364 256
365 257 ASSERT(kdi_nmemranges != KDI_MEMRANGES_MAX);
366 258
367 259 mr->mr_base = base;
368 260 mr->mr_lim = base + len - 1;
369 261 kdi_nmemranges++;
370 262 }
371 263
372 264 void
373 265 kdi_idt_switch(kdi_cpusave_t *cpusave)
374 266 {
375 267 if (cpusave == NULL)
376 268 kdi_idtr_set(kdi_idt, sizeof (kdi_idt) - 1);
377 269 else
378 270 kdi_idtr_set(cpusave->krs_idt, (sizeof (*idt0) * NIDT) - 1);
379 271 }
380 272
381 273 /*
382 274 * Activation for CPUs other than the boot CPU, called from that CPU's
383 275 * mp_startup(). We saved the kernel's descriptors when we initialized the
384 276 * boot CPU, so we don't want to do it again. Saving the handlers from this
385 277 * CPU's IDT would actually be dangerous with the CPU initialization method in
386 278 * use at the time of this writing. With that method, the startup code creates
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
387 279 * the IDTs for slave CPUs by copying the one used by the boot CPU, which has
388 280 * already been interposed upon by KMDB. Were we to interpose again, we'd
389 281 * replace the kernel's descriptors with our own in the save area. By not
390 282 * saving, but still overwriting, we'll work in the current world, and in any
391 283 * future world where the IDT is generated from scratch.
392 284 */
393 285 void
394 286 kdi_cpu_init(void)
395 287 {
396 288 kdi_idt_gates_install(KCS_SEL, KDI_IDT_NOSAVE);
397 - /* Load the debug registers and MSRs */
289 + /* Load the debug registers. */
398 290 kdi_cpu_debug_init(&kdi_cpusave[CPU->cpu_id]);
399 291 }
400 292
401 293 /*
402 294 * Activation for all CPUs for mod-loaded kmdb, i.e. a kmdb that wasn't
403 295 * loaded at boot.
404 296 */
405 297 static int
406 298 kdi_cpu_activate(void)
407 299 {
408 300 kdi_idt_gates_install(KCS_SEL, KDI_IDT_SAVE);
409 301 return (0);
410 302 }
411 303
412 304 void
413 305 kdi_activate(kdi_main_t main, kdi_cpusave_t *cpusave, uint_t ncpusave)
414 306 {
415 307 int i;
416 308 cpuset_t cpuset;
417 309
418 310 CPUSET_ALL(cpuset);
419 311
420 312 kdi_cpusave = cpusave;
421 313 kdi_ncpusave = ncpusave;
422 314
423 315 kdi_kmdb_main = main;
424 316
425 317 for (i = 0; i < kdi_ncpusave; i++) {
426 318 kdi_cpusave[i].krs_cpu_id = i;
427 319
428 320 kdi_cpusave[i].krs_curcrumb =
429 321 &kdi_cpusave[i].krs_crumbs[KDI_NCRUMBS - 1];
430 322 kdi_cpusave[i].krs_curcrumbidx = KDI_NCRUMBS - 1;
431 323 }
432 324
433 325 if (boothowto & RB_KMDB)
434 326 kdi_idt_init(KMDBCODE_SEL);
435 327 else
436 328 kdi_idt_init(KCS_SEL);
437 329
438 330 /* The initial selector set. Updated by the debugger-entry code */
439 331 #ifndef __amd64
440 332 kdi_cs = B32CODE_SEL;
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
441 333 kdi_ds = kdi_fs = kdi_gs = B32DATA_SEL;
442 334 #endif
443 335
444 336 kdi_memranges[0].mr_base = kdi_segdebugbase;
445 337 kdi_memranges[0].mr_lim = kdi_segdebugbase + kdi_segdebugsize - 1;
446 338 kdi_nmemranges = 1;
447 339
448 340 kdi_drreg.dr_ctl = KDIREG_DRCTL_RESERVED;
449 341 kdi_drreg.dr_stat = KDIREG_DRSTAT_RESERVED;
450 342
451 - kdi_msr_wrexit_msr = 0;
452 - kdi_msr_wrexit_valp = NULL;
453 -
454 343 if (boothowto & RB_KMDB) {
455 344 kdi_idt_gates_install(KMDBCODE_SEL, KDI_IDT_NOSAVE);
456 345 } else {
457 346 xc_call(0, 0, 0, CPUSET2BV(cpuset),
458 347 (xc_func_t)kdi_cpu_activate);
459 348 }
460 349 }
461 350
462 351 static int
463 352 kdi_cpu_deactivate(void)
464 353 {
465 354 kdi_idt_gates_restore();
466 355 return (0);
467 356 }
468 357
469 358 void
470 359 kdi_deactivate(void)
471 360 {
472 361 cpuset_t cpuset;
473 362 CPUSET_ALL(cpuset);
474 363
475 364 xc_call(0, 0, 0, CPUSET2BV(cpuset), (xc_func_t)kdi_cpu_deactivate);
476 365 kdi_nmemranges = 0;
477 366 }
478 367
479 368 /*
480 369 * We receive all breakpoints and single step traps. Some of them,
481 370 * including those from userland and those induced by DTrace providers,
482 371 * are intended for the kernel, and must be processed there. We adopt
483 372 * this ours-until-proven-otherwise position due to the painful
484 373 * consequences of sending the kernel an unexpected breakpoint or
485 374 * single step. Unless someone can prove to us that the kernel is
486 375 * prepared to handle the trap, we'll assume there's a problem and will
487 376 * give the user a chance to debug it.
488 377 */
489 378 int
490 379 kdi_trap_pass(kdi_cpusave_t *cpusave)
491 380 {
492 381 greg_t tt = cpusave->krs_gregs[KDIREG_TRAPNO];
493 382 greg_t pc = cpusave->krs_gregs[KDIREG_PC];
494 383 greg_t cs = cpusave->krs_gregs[KDIREG_CS];
495 384
496 385 if (USERMODE(cs))
497 386 return (1);
498 387
499 388 if (tt != T_BPTFLT && tt != T_SGLSTP)
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
500 389 return (0);
501 390
502 391 if (tt == T_BPTFLT && kdi_dtrace_get_state() ==
503 392 KDI_DTSTATE_DTRACE_ACTIVE)
504 393 return (1);
505 394
506 395 /*
507 396 * See the comments in the kernel's T_SGLSTP handler for why we need to
508 397 * do this.
509 398 */
399 +#if !defined(__xpv)
510 400 if (tt == T_SGLSTP &&
511 - (pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter))
401 + (pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter ||
402 + pc == (greg_t)tr_sys_sysenter ||
403 + pc == (greg_t)tr_brand_sys_sysenter)) {
404 +#else
405 + if (tt == T_SGLSTP &&
406 + (pc == (greg_t)sys_sysenter || pc == (greg_t)brand_sys_sysenter)) {
407 +#endif
512 408 return (1);
409 + }
513 410
514 411 return (0);
515 412 }
516 413
517 414 /*
518 415 * State has been saved, and all CPUs are on the CPU-specific stacks. All
519 416 * CPUs enter here, and head off into the debugger proper.
520 417 */
521 418 void
522 419 kdi_debugger_entry(kdi_cpusave_t *cpusave)
523 420 {
524 421 /*
525 422 * BPTFLT gives us control with %eip set to the instruction *after*
526 423 * the int 3. Back it off, so we're looking at the instruction that
527 424 * triggered the fault.
528 425 */
529 426 if (cpusave->krs_gregs[KDIREG_TRAPNO] == T_BPTFLT)
530 427 cpusave->krs_gregs[KDIREG_PC]--;
531 428
532 429 kdi_kmdb_main(cpusave);
533 430 }
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX