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>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/intel/kmdb/kaif.c
+++ new/usr/src/cmd/mdb/intel/kmdb/kaif.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 * The debugger/"PROM" interface layer
30 30 *
31 31 * It makes more sense on SPARC. In reality, these interfaces deal with three
32 32 * things: setting break/watchpoints, stepping, and interfacing with the KDI to
33 33 * set up kmdb's IDT handlers.
34 34 */
35 35
36 36 #include <kmdb/kmdb_dpi_impl.h>
37 37 #include <kmdb/kmdb_kdi.h>
38 38 #include <kmdb/kmdb_umemglue.h>
39 39 #include <kmdb/kaif.h>
40 40 #include <kmdb/kmdb_io.h>
41 41 #include <kmdb/kaif_start.h>
42 42 #include <mdb/mdb_err.h>
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
43 43 #include <mdb/mdb_debug.h>
44 44 #include <mdb/mdb_isautil.h>
45 45 #include <mdb/mdb_io_impl.h>
46 46 #include <mdb/mdb_kreg_impl.h>
47 47 #include <mdb/mdb.h>
48 48
49 49 #include <sys/types.h>
50 50 #include <sys/bitmap.h>
51 51 #include <sys/termios.h>
52 52 #include <sys/kdi_impl.h>
53 +#include <sys/sysmacros.h>
53 54
54 55 /*
55 56 * This is the area containing the saved state when we enter
56 57 * via kmdb's IDT entries.
57 58 */
58 59 kdi_cpusave_t *kaif_cpusave;
59 60 int kaif_ncpusave;
60 61 kdi_drreg_t kaif_drreg;
61 62
62 63 uint32_t kaif_waptmap;
63 64
64 65 int kaif_trap_switch;
65 66
66 67 void (*kaif_modchg_cb)(struct modctl *, int);
67 68
68 69 enum {
69 70 M_SYSRET = 0x07, /* after M_ESC */
70 71 M_ESC = 0x0f,
71 72 M_SYSEXIT = 0x35, /* after M_ESC */
72 73 M_REX_LO = 0x40, /* first REX prefix */
73 74 M_REX_HI = 0x4f, /* last REX prefix */
74 75 M_PUSHF = 0x9c, /* pushfl and pushfq */
75 76 M_POPF = 0x9d, /* popfl and popfq */
76 77 M_INT3 = 0xcc,
77 78 M_INTX = 0xcd,
78 79 M_INTO = 0xce,
79 80 M_IRET = 0xcf,
80 81 M_CLI = 0xfa,
81 82 M_STI = 0xfb
82 83 };
83 84
84 85 #define KAIF_BREAKPOINT_INSTR M_INT3
85 86
86 87 #define KAIF_WPPRIV2ID(wp) (int)(uintptr_t)((wp)->wp_priv)
87 88
88 89 #ifdef __amd64
89 90 #define FLAGS_REG_NAME "rflags"
90 91 #else
91 92 #define FLAGS_REG_NAME "eflags"
92 93 #endif
93 94
94 95 /*
95 96 * Called during normal debugger operation and during debugger faults.
96 97 */
97 98 static void
98 99 kaif_enter_mon(void)
99 100 {
100 101 char c;
101 102
102 103 for (;;) {
103 104 mdb_iob_printf(mdb.m_out,
104 105 "%s: Do you really want to reboot? (y/n) ",
105 106 mdb.m_pname);
106 107 mdb_iob_flush(mdb.m_out);
107 108 mdb_iob_clearlines(mdb.m_out);
108 109
109 110 c = kmdb_getchar();
110 111
111 112 if (c == 'n' || c == 'N' || c == CTRL('c'))
112 113 return;
113 114 else if (c == 'y' || c == 'Y') {
114 115 mdb_iob_printf(mdb.m_out, "Rebooting...\n");
115 116
116 117 kmdb_dpi_reboot();
117 118 }
118 119 }
119 120 }
120 121
121 122 static kaif_cpusave_t *
122 123 kaif_cpuid2save(int cpuid)
123 124 {
124 125 kaif_cpusave_t *save;
125 126
126 127 if (cpuid == DPI_MASTER_CPUID)
127 128 return (&kaif_cpusave[kaif_master_cpuid]);
128 129
129 130 if (cpuid < 0 || cpuid >= kaif_ncpusave) {
130 131 (void) set_errno(EINVAL);
131 132 return (NULL);
132 133 }
133 134
134 135 save = &kaif_cpusave[cpuid];
135 136
136 137 if (save->krs_cpu_state != KAIF_CPU_STATE_MASTER &&
137 138 save->krs_cpu_state != KAIF_CPU_STATE_SLAVE) {
138 139 (void) set_errno(EINVAL);
139 140 return (NULL);
140 141 }
141 142
142 143 return (save);
143 144 }
144 145
145 146 static int
146 147 kaif_get_cpu_state(int cpuid)
147 148 {
148 149 kaif_cpusave_t *save;
149 150
150 151 if ((save = kaif_cpuid2save(cpuid)) == NULL)
151 152 return (-1); /* errno is set for us */
152 153
153 154 switch (save->krs_cpu_state) {
154 155 case KAIF_CPU_STATE_MASTER:
155 156 return (DPI_CPU_STATE_MASTER);
156 157 case KAIF_CPU_STATE_SLAVE:
157 158 return (DPI_CPU_STATE_SLAVE);
158 159 default:
159 160 return (set_errno(EINVAL));
160 161 }
161 162 }
162 163
163 164 static int
164 165 kaif_get_master_cpuid(void)
165 166 {
166 167 return (kaif_master_cpuid);
167 168 }
168 169
169 170 static mdb_tgt_gregset_t *
170 171 kaif_kdi_to_gregs(int cpuid)
171 172 {
172 173 kaif_cpusave_t *save;
173 174
174 175 if ((save = kaif_cpuid2save(cpuid)) == NULL)
175 176 return (NULL); /* errno is set for us */
176 177
177 178 /*
178 179 * The saved registers are actually identical to an mdb_tgt_gregset,
179 180 * so we can directly cast here.
180 181 */
181 182 return ((mdb_tgt_gregset_t *)save->krs_gregs);
182 183 }
183 184
184 185 static const mdb_tgt_gregset_t *
185 186 kaif_get_gregs(int cpuid)
186 187 {
187 188 return (kaif_kdi_to_gregs(cpuid));
188 189 }
189 190
190 191 typedef struct kaif_reg_synonyms {
191 192 const char *rs_syn;
192 193 const char *rs_name;
193 194 } kaif_reg_synonyms_t;
194 195
195 196 static kreg_t *
196 197 kaif_find_regp(const char *regname)
197 198 {
198 199 static const kaif_reg_synonyms_t synonyms[] = {
199 200 #ifdef __amd64
200 201 { "pc", "rip" },
201 202 { "sp", "rsp" },
202 203 { "fp", "rbp" },
203 204 #else
204 205 { "pc", "eip" },
205 206 { "sp", "esp" },
206 207 { "fp", "ebp" },
207 208 #endif
208 209 { "tt", "trapno" }
209 210 };
210 211 mdb_tgt_gregset_t *regs;
211 212 int i;
212 213
213 214 if ((regs = kaif_kdi_to_gregs(DPI_MASTER_CPUID)) == NULL)
214 215 return (NULL);
215 216
216 217 for (i = 0; i < sizeof (synonyms) / sizeof (synonyms[0]); i++) {
217 218 if (strcmp(synonyms[i].rs_syn, regname) == 0)
218 219 regname = synonyms[i].rs_name;
219 220 }
220 221
221 222 for (i = 0; mdb_isa_kregs[i].rd_name != NULL; i++) {
222 223 const mdb_tgt_regdesc_t *rd = &mdb_isa_kregs[i];
223 224
224 225 if (strcmp(rd->rd_name, regname) == 0)
225 226 return (®s->kregs[rd->rd_num]);
226 227 }
227 228
228 229 (void) set_errno(ENOENT);
229 230 return (NULL);
230 231 }
231 232
232 233 /*ARGSUSED*/
233 234 static int
234 235 kaif_get_register(const char *regname, kreg_t *valp)
235 236 {
236 237 kreg_t *regp;
237 238
238 239 if ((regp = kaif_find_regp(regname)) == NULL)
239 240 return (-1);
240 241
241 242 *valp = *regp;
242 243
243 244 return (0);
244 245 }
245 246
246 247 static int
247 248 kaif_set_register(const char *regname, kreg_t val)
248 249 {
↓ open down ↓ |
186 lines elided |
↑ open up ↑ |
249 250 kreg_t *regp;
250 251
251 252 if ((regp = kaif_find_regp(regname)) == NULL)
252 253 return (-1);
253 254
254 255 *regp = val;
255 256
256 257 return (0);
257 258 }
258 259
260 +/*
261 + * Refuse to single-step or break within any stub that loads a user %cr3 value.
262 + * As the KDI traps are not careful to restore such a %cr3, this can all go
263 + * wrong, both spectacularly and subtly.
264 + */
265 +static boolean_t
266 +kaif_toxic_text(uintptr_t addr)
267 +{
268 + static GElf_Sym toxic_syms[2] = { 0, };
269 + size_t i;
270 +
271 + if (toxic_syms[0].st_name == NULL) {
272 + if (mdb_tgt_lookup_by_name(mdb.m_target, MDB_TGT_OBJ_EXEC,
273 + "tr_iret_user", &toxic_syms[0], NULL) != 0)
274 + warn("couldn't find tr_iret_user\n");
275 + if (mdb_tgt_lookup_by_name(mdb.m_target, MDB_TGT_OBJ_EXEC,
276 + "tr_mmu_flush_user_range", &toxic_syms[1], NULL) != 0)
277 + warn("couldn't find tr_mmu_flush_user_range\n");
278 + }
279 +
280 + for (i = 0; i < ARRAY_SIZE(toxic_syms); i++) {
281 + if (addr >= toxic_syms[i].st_value &&
282 + addr - toxic_syms[i].st_value < toxic_syms[i].st_size)
283 + return (B_TRUE);
284 + }
285 +
286 + return (B_FALSE);
287 +}
288 +
259 289 static int
260 290 kaif_brkpt_arm(uintptr_t addr, mdb_instr_t *instrp)
261 291 {
262 292 mdb_instr_t bkpt = KAIF_BREAKPOINT_INSTR;
263 293
294 + if (kaif_toxic_text(addr)) {
295 + warn("%a cannot be a breakpoint target\n", addr);
296 + return (set_errno(EMDB_TGTNOTSUP));
297 + }
298 +
264 299 if (mdb_tgt_vread(mdb.m_target, instrp, sizeof (mdb_instr_t), addr) !=
265 300 sizeof (mdb_instr_t))
266 301 return (-1); /* errno is set for us */
267 302
268 303 if (mdb_tgt_vwrite(mdb.m_target, &bkpt, sizeof (mdb_instr_t), addr) !=
269 304 sizeof (mdb_instr_t))
270 305 return (-1); /* errno is set for us */
271 306
272 307 return (0);
273 308 }
274 309
275 310 static int
276 311 kaif_brkpt_disarm(uintptr_t addr, mdb_instr_t instrp)
277 312 {
278 313 if (mdb_tgt_vwrite(mdb.m_target, &instrp, sizeof (mdb_instr_t), addr) !=
279 314 sizeof (mdb_instr_t))
280 315 return (-1); /* errno is set for us */
281 316
282 317 return (0);
283 318 }
284 319
285 320 /*
286 321 * Intel watchpoints are even more fun than SPARC ones. The Intel architecture
287 322 * manuals refer to watchpoints as breakpoints. For consistency with the
288 323 * terminology used in other portions of kmdb, we will, however, refer to them
289 324 * as watchpoints.
290 325 *
291 326 * Execute, data write, I/O read/write, and data read/write watchpoints are
292 327 * supported by the hardware. Execute watchpoints must be one byte in length,
293 328 * and must be placed on the first byte of the instruction to be watched.
294 329 * Lengths of other watchpoints are more varied.
295 330 *
296 331 * Given that we already have a breakpoint facility, and given the restrictions
297 332 * placed on execute watchpoints, we're going to disallow the creation of
298 333 * execute watchpoints. The others will be fully supported. See the Debugging
299 334 * chapter in both the IA32 and AMD64 System Programming books for more details.
300 335 */
301 336
302 337 #ifdef __amd64
303 338 #define WAPT_DATA_MAX_SIZE 8
304 339 #define WAPT_DATA_SIZES_MSG "1, 2, 4, or 8"
305 340 #else
306 341 #define WAPT_DATA_MAX_SIZE 4
307 342 #define WAPT_DATA_SIZES_MSG "1, 2, or 4"
308 343 #endif
309 344
310 345 static int
311 346 kaif_wapt_validate(kmdb_wapt_t *wp)
312 347 {
313 348 if (wp->wp_type == DPI_WAPT_TYPE_IO) {
314 349 if (wp->wp_wflags != (MDB_TGT_WA_R | MDB_TGT_WA_W)) {
315 350 warn("I/O port watchpoints must be read/write\n");
316 351 return (set_errno(EINVAL));
317 352 }
318 353
319 354 if (wp->wp_size != 1 && wp->wp_size != 2 && wp->wp_size != 4) {
320 355 warn("I/O watchpoint size must be 1, 2, or 4 bytes\n");
321 356 return (set_errno(EINVAL));
322 357 }
323 358
324 359 } else if (wp->wp_type == DPI_WAPT_TYPE_PHYS) {
325 360 warn("physical address watchpoints are not supported on this "
326 361 "platform\n");
327 362 return (set_errno(EMDB_TGTHWNOTSUP));
328 363
329 364 } else {
330 365 if (wp->wp_wflags != (MDB_TGT_WA_R | MDB_TGT_WA_W) &&
331 366 wp->wp_wflags != MDB_TGT_WA_W) {
332 367 warn("watchpoints must be read/write or write-only\n");
333 368 return (set_errno(EINVAL));
334 369 }
335 370
336 371 if ((wp->wp_size & -(wp->wp_size)) != wp->wp_size ||
337 372 wp->wp_size > WAPT_DATA_MAX_SIZE) {
338 373 warn("data watchpoint size must be " WAPT_DATA_SIZES_MSG
339 374 " bytes\n");
340 375 return (set_errno(EINVAL));
341 376 }
342 377
343 378 }
344 379
345 380 if (wp->wp_addr & (wp->wp_size - 1)) {
346 381 warn("%lu-byte watchpoints must be %lu-byte aligned\n",
347 382 (ulong_t)wp->wp_size, (ulong_t)wp->wp_size);
348 383 return (set_errno(EINVAL));
349 384 }
350 385
351 386 return (0);
352 387 }
353 388
354 389 static int
355 390 kaif_wapt_reserve(kmdb_wapt_t *wp)
356 391 {
357 392 int id;
358 393
359 394 for (id = 0; id <= KDI_MAXWPIDX; id++) {
360 395 if (!BT_TEST(&kaif_waptmap, id)) {
361 396 /* found one */
362 397 BT_SET(&kaif_waptmap, id);
363 398 wp->wp_priv = (void *)(uintptr_t)id;
364 399 return (0);
365 400 }
366 401 }
367 402
368 403 return (set_errno(EMDB_WPTOOMANY));
369 404 }
370 405
371 406 static void
372 407 kaif_wapt_release(kmdb_wapt_t *wp)
373 408 {
374 409 int id = KAIF_WPPRIV2ID(wp);
375 410
376 411 ASSERT(BT_TEST(&kaif_waptmap, id));
377 412 BT_CLEAR(&kaif_waptmap, id);
378 413 }
379 414
380 415 /*ARGSUSED*/
381 416 static void
382 417 kaif_wapt_arm(kmdb_wapt_t *wp)
383 418 {
384 419 uint_t rw;
385 420 int hwid = KAIF_WPPRIV2ID(wp);
386 421
387 422 ASSERT(BT_TEST(&kaif_waptmap, hwid));
388 423
389 424 if (wp->wp_type == DPI_WAPT_TYPE_IO)
390 425 rw = KREG_DRCTL_WP_IORW;
391 426 else if (wp->wp_wflags & MDB_TGT_WA_R)
392 427 rw = KREG_DRCTL_WP_RW;
393 428 else if (wp->wp_wflags & MDB_TGT_WA_X)
394 429 rw = KREG_DRCTL_WP_EXEC;
395 430 else
396 431 rw = KREG_DRCTL_WP_WONLY;
397 432
398 433 kaif_drreg.dr_addr[hwid] = wp->wp_addr;
399 434
400 435 kaif_drreg.dr_ctl &= ~KREG_DRCTL_WP_MASK(hwid);
401 436 kaif_drreg.dr_ctl |= KREG_DRCTL_WP_LENRW(hwid, wp->wp_size - 1, rw);
402 437 kaif_drreg.dr_ctl |= KREG_DRCTL_WPEN(hwid);
403 438 kmdb_kdi_update_drreg(&kaif_drreg);
404 439 }
405 440
406 441 /*ARGSUSED*/
407 442 static void
408 443 kaif_wapt_disarm(kmdb_wapt_t *wp)
409 444 {
410 445 int hwid = KAIF_WPPRIV2ID(wp);
411 446
412 447 ASSERT(BT_TEST(&kaif_waptmap, hwid));
413 448
414 449 kaif_drreg.dr_addr[hwid] = 0;
415 450 kaif_drreg.dr_ctl &= ~(KREG_DRCTL_WP_MASK(hwid) |
416 451 KREG_DRCTL_WPEN_MASK(hwid));
417 452 kmdb_kdi_update_drreg(&kaif_drreg);
418 453 }
419 454
420 455 /*ARGSUSED*/
421 456 static int
422 457 kaif_wapt_match(kmdb_wapt_t *wp)
423 458 {
424 459 int hwid = KAIF_WPPRIV2ID(wp);
425 460 uint32_t mask = KREG_DRSTAT_WP_MASK(hwid);
426 461 int n = 0;
427 462 int i;
428 463
429 464 ASSERT(BT_TEST(&kaif_waptmap, hwid));
430 465
431 466 for (i = 0; i < kaif_ncpusave; i++)
432 467 n += (kaif_cpusave[i].krs_dr.dr_stat & mask) != 0;
433 468
434 469 return (n);
435 470 }
436 471
437 472 static int
↓ open down ↓ |
164 lines elided |
↑ open up ↑ |
438 473 kaif_step(void)
439 474 {
440 475 kreg_t pc, fl, oldfl, newfl, sp;
441 476 mdb_tgt_addr_t npc;
442 477 mdb_instr_t instr;
443 478 int emulated = 0, rchk = 0;
444 479 size_t pcoff = 0;
445 480
446 481 (void) kmdb_dpi_get_register("pc", &pc);
447 482
483 + if (kaif_toxic_text(pc)) {
484 + warn("%a cannot be stepped\n", pc);
485 + return (set_errno(EMDB_TGTNOTSUP));
486 + }
487 +
448 488 if ((npc = mdb_dis_nextins(mdb.m_disasm, mdb.m_target,
449 489 MDB_TGT_AS_VIRT, pc)) == pc) {
450 490 warn("failed to decode instruction at %a for step\n", pc);
451 491 return (set_errno(EINVAL));
452 492 }
453 493
454 494 /*
455 495 * Stepping behavior depends on the type of instruction. It does not
456 496 * depend on the presence of a REX prefix, as the action we take for a
457 497 * given instruction doesn't currently vary for 32-bit instructions
458 498 * versus their 64-bit counterparts.
459 499 */
460 500 do {
461 501 if (mdb_tgt_vread(mdb.m_target, &instr, sizeof (mdb_instr_t),
462 502 pc + pcoff) != sizeof (mdb_instr_t)) {
463 503 warn("failed to read at %p for step",
464 504 (void *)(pc + pcoff));
465 505 return (-1);
466 506 }
467 507 } while (pcoff++, (instr >= M_REX_LO && instr <= M_REX_HI && !rchk++));
468 508
469 509 switch (instr) {
470 510 case M_IRET:
471 511 warn("iret cannot be stepped\n");
472 512 return (set_errno(EMDB_TGTNOTSUP));
473 513
474 514 case M_INT3:
475 515 case M_INTX:
476 516 case M_INTO:
477 517 warn("int cannot be stepped\n");
478 518 return (set_errno(EMDB_TGTNOTSUP));
479 519
480 520 case M_ESC:
481 521 if (mdb_tgt_vread(mdb.m_target, &instr, sizeof (mdb_instr_t),
482 522 pc + pcoff) != sizeof (mdb_instr_t)) {
483 523 warn("failed to read at %p for step",
484 524 (void *)(pc + pcoff));
485 525 return (-1);
486 526 }
487 527
488 528 switch (instr) {
489 529 case M_SYSRET:
490 530 warn("sysret cannot be stepped\n");
491 531 return (set_errno(EMDB_TGTNOTSUP));
492 532 case M_SYSEXIT:
493 533 warn("sysexit cannot be stepped\n");
494 534 return (set_errno(EMDB_TGTNOTSUP));
495 535 }
496 536 break;
497 537
498 538 /*
499 539 * Some instructions need to be emulated. We need to prevent direct
500 540 * manipulations of EFLAGS, so we'll emulate cli, sti. pushfl and
501 541 * popfl also receive special handling, as they manipulate both EFLAGS
502 542 * and %esp.
503 543 */
504 544 case M_CLI:
505 545 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
506 546 fl &= ~KREG_EFLAGS_IF_MASK;
507 547 (void) kmdb_dpi_set_register(FLAGS_REG_NAME, fl);
508 548
509 549 emulated = 1;
510 550 break;
511 551
512 552 case M_STI:
513 553 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
514 554 fl |= (1 << KREG_EFLAGS_IF_SHIFT);
515 555 (void) kmdb_dpi_set_register(FLAGS_REG_NAME, fl);
516 556
517 557 emulated = 1;
518 558 break;
519 559
520 560 case M_POPF:
521 561 /*
522 562 * popfl will restore a pushed EFLAGS from the stack, and could
523 563 * in so doing cause IF to be turned on, if only for a brief
524 564 * period. To avoid this, we'll secretly replace the stack's
525 565 * EFLAGS with our decaffeinated brand. We'll then manually
526 566 * load our EFLAGS copy with the real verion after the step.
527 567 */
528 568 (void) kmdb_dpi_get_register("sp", &sp);
529 569 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
530 570
531 571 if (mdb_tgt_vread(mdb.m_target, &newfl, sizeof (kreg_t),
532 572 sp) != sizeof (kreg_t)) {
533 573 warn("failed to read " FLAGS_REG_NAME
534 574 " at %p for popfl step\n", (void *)sp);
535 575 return (set_errno(EMDB_TGTNOTSUP)); /* XXX ? */
536 576 }
537 577
538 578 fl = (fl & ~KREG_EFLAGS_IF_MASK) | KREG_EFLAGS_TF_MASK;
539 579
540 580 if (mdb_tgt_vwrite(mdb.m_target, &fl, sizeof (kreg_t),
541 581 sp) != sizeof (kreg_t)) {
542 582 warn("failed to update " FLAGS_REG_NAME
543 583 " at %p for popfl step\n", (void *)sp);
544 584 return (set_errno(EMDB_TGTNOTSUP)); /* XXX ? */
545 585 }
546 586 break;
547 587 }
548 588
549 589 if (emulated) {
550 590 (void) kmdb_dpi_set_register("pc", npc);
551 591 return (0);
552 592 }
553 593
554 594 /* Do the step with IF off, and TF (step) on */
555 595 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &oldfl);
556 596 (void) kmdb_dpi_set_register(FLAGS_REG_NAME,
557 597 ((oldfl | (1 << KREG_EFLAGS_TF_SHIFT)) & ~KREG_EFLAGS_IF_MASK));
558 598
559 599 kmdb_dpi_resume_master(); /* ... there and back again ... */
560 600
561 601 /* EFLAGS has now changed, and may require tuning */
562 602
563 603 switch (instr) {
564 604 case M_POPF:
565 605 /*
566 606 * Use the EFLAGS we grabbed before the pop - see the pre-step
567 607 * M_POPFL comment.
568 608 */
569 609 (void) kmdb_dpi_set_register(FLAGS_REG_NAME, newfl);
570 610 return (0);
571 611
572 612 case M_PUSHF:
573 613 /*
574 614 * We pushed our modified EFLAGS (with IF and TF turned off)
575 615 * onto the stack. Replace the pushed version with our
576 616 * unmodified one.
577 617 */
578 618 (void) kmdb_dpi_get_register("sp", &sp);
579 619
580 620 if (mdb_tgt_vwrite(mdb.m_target, &oldfl, sizeof (kreg_t),
581 621 sp) != sizeof (kreg_t)) {
582 622 warn("failed to update pushed " FLAGS_REG_NAME
583 623 " at %p after pushfl step\n", (void *)sp);
584 624 return (set_errno(EMDB_TGTNOTSUP)); /* XXX ? */
585 625 }
586 626
587 627 /* Go back to using the EFLAGS we were using before the step */
588 628 (void) kmdb_dpi_set_register(FLAGS_REG_NAME, oldfl);
589 629 return (0);
590 630
591 631 default:
592 632 /*
593 633 * The stepped instruction may have altered EFLAGS. We only
594 634 * really care about the value of IF, and we know the stepped
595 635 * instruction didn't alter it, so we can simply copy the
↓ open down ↓ |
138 lines elided |
↑ open up ↑ |
596 636 * pre-step value. We'll also need to turn TF back off.
597 637 */
598 638 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
599 639 (void) kmdb_dpi_set_register(FLAGS_REG_NAME,
600 640 ((fl & ~(KREG_EFLAGS_TF_MASK|KREG_EFLAGS_IF_MASK)) |
601 641 (oldfl & KREG_EFLAGS_IF_MASK)));
602 642 return (0);
603 643 }
604 644 }
605 645
606 -/*
607 - * The target has already configured the chip for branch step, leaving us to
608 - * actually make the machine go. Due to a number of issues involving
609 - * the potential alteration of system state via instructions like sti, cli,
610 - * pushfl, and popfl, we're going to treat this like a normal system resume.
611 - * All CPUs will be released, on the kernel's IDT. Our primary concern is
612 - * the alteration/storage of our TF'd EFLAGS via pushfl and popfl. There's no
613 - * real workaround - we don't have opcode breakpoints - so the best we can do is
614 - * to ensure that the world won't end if someone does bad things to EFLAGS.
615 - *
616 - * Two things can happen:
617 - * 1. EFLAGS.TF may be cleared, either maliciously or via a popfl from saved
618 - * state. The CPU will continue execution beyond the branch, and will not
619 - * reenter the debugger unless brought/sent in by other means.
620 - * 2. Someone may pushlf the TF'd EFLAGS, and may stash a copy of it somewhere.
621 - * When the saved version is popfl'd back into place, the debugger will be
622 - * re-entered on a single-step trap.
623 - */
624 -static void
625 -kaif_step_branch(void)
626 -{
627 - kreg_t fl;
628 -
629 - (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
630 - (void) kmdb_dpi_set_register(FLAGS_REG_NAME,
631 - (fl | (1 << KREG_EFLAGS_TF_SHIFT)));
632 -
633 - kmdb_dpi_resume_master();
634 -
635 - (void) kmdb_dpi_set_register(FLAGS_REG_NAME, fl);
636 -}
637 -
638 646 /*ARGSUSED*/
639 647 static uintptr_t
640 648 kaif_call(uintptr_t funcva, uint_t argc, const uintptr_t argv[])
641 649 {
642 650 return (kaif_invoke(funcva, argc, argv));
643 651 }
644 652
645 653 static void
646 654 dump_crumb(kdi_crumb_t *krmp)
647 655 {
648 656 kdi_crumb_t krm;
649 657
650 658 if (mdb_vread(&krm, sizeof (kdi_crumb_t), (uintptr_t)krmp) !=
651 659 sizeof (kdi_crumb_t)) {
652 660 warn("failed to read crumb at %p", krmp);
653 661 return;
654 662 }
655 663
656 664 mdb_printf("state: ");
657 665 switch (krm.krm_cpu_state) {
658 666 case KAIF_CPU_STATE_MASTER:
659 667 mdb_printf("M");
660 668 break;
661 669 case KAIF_CPU_STATE_SLAVE:
662 670 mdb_printf("S");
663 671 break;
664 672 default:
665 673 mdb_printf("%d", krm.krm_cpu_state);
666 674 }
667 675
668 676 mdb_printf(" trapno %3d sp %08x flag %d pc %p %A\n",
669 677 krm.krm_trapno, krm.krm_sp, krm.krm_flag, krm.krm_pc, krm.krm_pc);
670 678 }
671 679
672 680 static void
673 681 dump_crumbs(kaif_cpusave_t *save)
674 682 {
675 683 int i;
676 684
677 685 for (i = KDI_NCRUMBS; i > 0; i--) {
678 686 uint_t idx = (save->krs_curcrumbidx + i) % KDI_NCRUMBS;
679 687 dump_crumb(&save->krs_crumbs[idx]);
680 688 }
681 689 }
682 690
683 691 static void
684 692 kaif_dump_crumbs(uintptr_t addr, int cpuid)
685 693 {
686 694 int i;
687 695
688 696 if (addr != NULL) {
689 697 /* dump_crumb will protect us against bogus addresses */
690 698 dump_crumb((kdi_crumb_t *)addr);
691 699
692 700 } else if (cpuid != -1) {
693 701 if (cpuid < 0 || cpuid >= kaif_ncpusave)
694 702 return;
695 703
696 704 dump_crumbs(&kaif_cpusave[cpuid]);
697 705
698 706 } else {
699 707 for (i = 0; i < kaif_ncpusave; i++) {
700 708 kaif_cpusave_t *save = &kaif_cpusave[i];
701 709
702 710 if (save->krs_cpu_state == KAIF_CPU_STATE_NONE)
703 711 continue;
704 712
705 713 mdb_printf("%sCPU %d crumbs: (curidx %d)\n",
706 714 (i == 0 ? "" : "\n"), i, save->krs_curcrumbidx);
707 715
708 716 dump_crumbs(save);
709 717 }
710 718 }
711 719 }
712 720
713 721 static void
714 722 kaif_modchg_register(void (*func)(struct modctl *, int))
715 723 {
716 724 kaif_modchg_cb = func;
↓ open down ↓ |
69 lines elided |
↑ open up ↑ |
717 725 }
718 726
719 727 static void
720 728 kaif_modchg_cancel(void)
721 729 {
722 730 ASSERT(kaif_modchg_cb != NULL);
723 731
724 732 kaif_modchg_cb = NULL;
725 733 }
726 734
727 -static void
728 -kaif_msr_add(const kdi_msr_t *msrs)
729 -{
730 - kdi_msr_t *save;
731 - size_t nr_msrs = 0;
732 - size_t i;
733 -
734 - while (msrs[nr_msrs].msr_num != 0)
735 - nr_msrs++;
736 - /* we want to copy the terminating kdi_msr_t too */
737 - nr_msrs++;
738 -
739 - save = mdb_zalloc(sizeof (kdi_msr_t) * nr_msrs * kaif_ncpusave,
740 - UM_SLEEP);
741 -
742 - for (i = 0; i < kaif_ncpusave; i++)
743 - bcopy(msrs, &save[nr_msrs * i], sizeof (kdi_msr_t) * nr_msrs);
744 -
745 - kmdb_kdi_set_debug_msrs(save);
746 -}
747 -
748 -static uint64_t
749 -kaif_msr_get(int cpuid, uint_t num)
750 -{
751 - kdi_cpusave_t *save;
752 - kdi_msr_t *msr;
753 - int i;
754 -
755 - if ((save = kaif_cpuid2save(cpuid)) == NULL)
756 - return (-1); /* errno is set for us */
757 -
758 - msr = save->krs_msr;
759 -
760 - for (i = 0; msr[i].msr_num != 0; i++) {
761 - if (msr[i].msr_num == num && (msr[i].msr_type & KDI_MSR_READ))
762 - return (msr[i].kdi_msr_val);
763 - }
764 -
765 - return (0);
766 -}
767 -
768 735 void
769 736 kaif_trap_set_debugger(void)
770 737 {
771 738 kmdb_kdi_idt_switch(NULL);
772 739 }
773 740
774 741 void
775 742 kaif_trap_set_saved(kaif_cpusave_t *cpusave)
776 743 {
777 744 kmdb_kdi_idt_switch(cpusave);
778 745 }
779 746
780 747 static void
781 748 kaif_vmready(void)
782 749 {
783 750 }
784 751
785 752 void
786 753 kaif_memavail(caddr_t base, size_t len)
787 754 {
788 755 int ret;
789 756 /*
790 757 * In the unlikely event that someone is stepping through this routine,
791 758 * we need to make sure that the KDI knows about the new range before
792 759 * umem gets it. That way the entry code can recognize stacks
793 760 * allocated from the new region.
794 761 */
795 762 kmdb_kdi_memrange_add(base, len);
796 763 ret = mdb_umem_add(base, len);
797 764 ASSERT(ret == 0);
798 765 }
799 766
800 767 void
801 768 kaif_mod_loaded(struct modctl *modp)
802 769 {
803 770 if (kaif_modchg_cb != NULL)
804 771 kaif_modchg_cb(modp, 1);
805 772 }
806 773
807 774 void
808 775 kaif_mod_unloading(struct modctl *modp)
809 776 {
810 777 if (kaif_modchg_cb != NULL)
811 778 kaif_modchg_cb(modp, 0);
812 779 }
813 780
814 781 void
815 782 kaif_handle_fault(greg_t trapno, greg_t pc, greg_t sp, int cpuid)
816 783 {
817 784 kmdb_dpi_handle_fault((kreg_t)trapno, (kreg_t)pc,
818 785 (kreg_t)sp, cpuid);
819 786 }
820 787
821 788 static kdi_debugvec_t kaif_dvec = {
822 789 NULL, /* dv_kctl_vmready */
823 790 NULL, /* dv_kctl_memavail */
824 791 NULL, /* dv_kctl_modavail */
825 792 NULL, /* dv_kctl_thravail */
826 793 kaif_vmready,
827 794 kaif_memavail,
828 795 kaif_mod_loaded,
829 796 kaif_mod_unloading,
830 797 kaif_handle_fault
831 798 };
832 799
833 800 void
834 801 kaif_kdi_entry(kdi_cpusave_t *cpusave)
835 802 {
836 803 int ret = kaif_main_loop(cpusave);
837 804 ASSERT(ret == KAIF_CPU_CMD_RESUME ||
838 805 ret == KAIF_CPU_CMD_RESUME_MASTER);
839 806 }
840 807
841 808 /*ARGSUSED*/
842 809 void
843 810 kaif_activate(kdi_debugvec_t **dvecp, uint_t flags)
844 811 {
845 812 kmdb_kdi_activate(kaif_kdi_entry, kaif_cpusave, kaif_ncpusave);
846 813 *dvecp = &kaif_dvec;
847 814 }
848 815
849 816 static int
850 817 kaif_init(kmdb_auxv_t *kav)
851 818 {
852 819 /* Allocate the per-CPU save areas */
853 820 kaif_cpusave = mdb_zalloc(sizeof (kaif_cpusave_t) * kav->kav_ncpu,
854 821 UM_SLEEP);
855 822 kaif_ncpusave = kav->kav_ncpu;
856 823
857 824 kaif_modchg_cb = NULL;
858 825
859 826 kaif_waptmap = 0;
860 827
861 828 kaif_trap_switch = (kav->kav_flags & KMDB_AUXV_FL_NOTRPSWTCH) == 0;
862 829
863 830 return (0);
864 831 }
865 832
866 833 dpi_ops_t kmdb_dpi_ops = {
867 834 kaif_init,
868 835 kaif_activate,
869 836 kmdb_kdi_deactivate,
870 837 kaif_enter_mon,
871 838 kaif_modchg_register,
872 839 kaif_modchg_cancel,
873 840 kaif_get_cpu_state,
874 841 kaif_get_master_cpuid,
875 842 kaif_get_gregs,
876 843 kaif_get_register,
↓ open down ↓ |
99 lines elided |
↑ open up ↑ |
877 844 kaif_set_register,
878 845 kaif_brkpt_arm,
879 846 kaif_brkpt_disarm,
880 847 kaif_wapt_validate,
881 848 kaif_wapt_reserve,
882 849 kaif_wapt_release,
883 850 kaif_wapt_arm,
884 851 kaif_wapt_disarm,
885 852 kaif_wapt_match,
886 853 kaif_step,
887 - kaif_step_branch,
888 854 kaif_call,
889 855 kaif_dump_crumbs,
890 - kaif_msr_add,
891 - kaif_msr_get,
892 856 };
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX