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