xref: /titanic_51/usr/src/uts/intel/kdi/kdi_idt.c (revision f34a71784df3fbc5d1227a7b6201fd318ad1667e)
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