4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * isa-dependent portions of the kmdb target
30 */
31
32 #include <kmdb/kvm.h>
33 #include <kmdb/kvm_cpu.h>
34 #include <kmdb/kmdb_kdi.h>
35 #include <kmdb/kmdb_asmutil.h>
36 #include <mdb/mdb_debug.h>
37 #include <mdb/mdb_err.h>
38 #include <mdb/mdb_list.h>
39 #include <mdb/mdb_target_impl.h>
40 #include <mdb/mdb_isautil.h>
41 #include <mdb/mdb_kreg_impl.h>
42 #include <mdb/mdb.h>
43
44 #include <sys/types.h>
45 #include <sys/frame.h>
46 #include <sys/trap.h>
47 #include <sys/bitmap.h>
48 #include <sys/pci_impl.h>
49
50 /* Higher than the highest trap number for which we have a defined specifier */
51 #define KMT_MAXTRAPNO 0x20
52
53 #define IOPORTLIMIT 0xffff /* XXX find a new home for this */
84 int
85 kmt_step_out(mdb_tgt_t *t, uintptr_t *p)
86 {
87 mdb_instr_t instr;
88 kreg_t pc, sp, fp;
89
90 (void) kmdb_dpi_get_register("pc", &pc);
91 (void) kmdb_dpi_get_register("sp", &sp);
92 (void) kmdb_dpi_get_register("fp", &fp);
93
94 if (mdb_tgt_vread(t, &instr, sizeof (mdb_instr_t), pc) !=
95 sizeof (mdb_instr_t))
96 return (-1); /* errno is set for us */
97
98 if (!kmt_step_out_validate(t, pc))
99 return (set_errno(EMDB_TGTNOTSUP));
100
101 return (mdb_isa_step_out(t, p, pc, fp, sp, instr));
102 }
103
104 int
105 kmt_step_branch(mdb_tgt_t *t)
106 {
107 kmt_data_t *kmt = t->t_data;
108
109 return (kmt_cpu_step_branch(t, kmt->kmt_cpu));
110 }
111
112 /*
113 * Return the address of the next instruction following a call, or return -1
114 * and set errno to EAGAIN if the target should just single-step.
115 */
116 int
117 kmt_next(mdb_tgt_t *t, uintptr_t *p)
118 {
119 kreg_t pc;
120 mdb_instr_t instr;
121
122 (void) kmdb_dpi_get_register("pc", &pc);
123
124 if (mdb_tgt_vread(t, &instr, sizeof (mdb_instr_t), pc) !=
125 sizeof (mdb_instr_t))
126 return (-1); /* errno is set for us */
127
128 return (mdb_isa_next(t, p, pc, instr));
129 }
130
131 /*ARGSUSED*/
339
340 /*ARGSUSED*/
341 int
342 kmt_wrmsr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
343 {
344 uint64_t val;
345
346 if (!(flags & DCMD_ADDRSPEC) || argc != 1)
347 return (DCMD_USAGE);
348
349 val = kmt_numarg(argv);
350
351 if (kmt_rwmsr(addr, &val, wrmsr)) {
352 warn("wrmsr failed");
353 return (DCMD_ERR);
354 }
355
356 return (DCMD_OK);
357 }
358
359 int
360 kmt_msr_validate(const kdi_msr_t *msr)
361 {
362 uint64_t val;
363
364 for (/* */; msr->msr_num != 0; msr++) {
365 if (kmt_rwmsr(msr->msr_num, &val, rdmsr) < 0)
366 return (0);
367 }
368
369 return (1);
370 }
371
372 /*ARGSUSED*/
373 ssize_t
374 kmt_write(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
375 {
376 if (!(t->t_flags & MDB_TGT_F_ALLOWIO) &&
377 (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 1)) == 0)
378 return (set_errno(EMDB_NOMAP));
379
380 /*
381 * No writes to user space are allowed. If we were to allow it, we'd
382 * be in the unfortunate situation where kmdb could place a breakpoint
383 * on a userspace executable page; this dirty page would end up being
384 * flushed back to disk, incurring sadness when it's next executed.
385 * Besides, we can't allow trapping in from userspace anyway.
386 */
387 if (addr < kmdb_kdi_get_userlimit())
388 return (set_errno(EMDB_TGTNOTSUP));
389
390 return (kmt_rw(t, (void *)buf, nbytes, addr, kmt_writer));
391 }
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2018 Joyent, Inc.
26 */
27
28 /*
29 * isa-dependent portions of the kmdb target
30 */
31
32 #include <kmdb/kvm.h>
33 #include <kmdb/kmdb_kdi.h>
34 #include <kmdb/kmdb_asmutil.h>
35 #include <mdb/mdb_debug.h>
36 #include <mdb/mdb_err.h>
37 #include <mdb/mdb_list.h>
38 #include <mdb/mdb_target_impl.h>
39 #include <mdb/mdb_isautil.h>
40 #include <mdb/mdb_kreg_impl.h>
41 #include <mdb/mdb.h>
42
43 #include <sys/types.h>
44 #include <sys/frame.h>
45 #include <sys/trap.h>
46 #include <sys/bitmap.h>
47 #include <sys/pci_impl.h>
48
49 /* Higher than the highest trap number for which we have a defined specifier */
50 #define KMT_MAXTRAPNO 0x20
51
52 #define IOPORTLIMIT 0xffff /* XXX find a new home for this */
83 int
84 kmt_step_out(mdb_tgt_t *t, uintptr_t *p)
85 {
86 mdb_instr_t instr;
87 kreg_t pc, sp, fp;
88
89 (void) kmdb_dpi_get_register("pc", &pc);
90 (void) kmdb_dpi_get_register("sp", &sp);
91 (void) kmdb_dpi_get_register("fp", &fp);
92
93 if (mdb_tgt_vread(t, &instr, sizeof (mdb_instr_t), pc) !=
94 sizeof (mdb_instr_t))
95 return (-1); /* errno is set for us */
96
97 if (!kmt_step_out_validate(t, pc))
98 return (set_errno(EMDB_TGTNOTSUP));
99
100 return (mdb_isa_step_out(t, p, pc, fp, sp, instr));
101 }
102
103 /*
104 * Return the address of the next instruction following a call, or return -1
105 * and set errno to EAGAIN if the target should just single-step.
106 */
107 int
108 kmt_next(mdb_tgt_t *t, uintptr_t *p)
109 {
110 kreg_t pc;
111 mdb_instr_t instr;
112
113 (void) kmdb_dpi_get_register("pc", &pc);
114
115 if (mdb_tgt_vread(t, &instr, sizeof (mdb_instr_t), pc) !=
116 sizeof (mdb_instr_t))
117 return (-1); /* errno is set for us */
118
119 return (mdb_isa_next(t, p, pc, instr));
120 }
121
122 /*ARGSUSED*/
330
331 /*ARGSUSED*/
332 int
333 kmt_wrmsr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
334 {
335 uint64_t val;
336
337 if (!(flags & DCMD_ADDRSPEC) || argc != 1)
338 return (DCMD_USAGE);
339
340 val = kmt_numarg(argv);
341
342 if (kmt_rwmsr(addr, &val, wrmsr)) {
343 warn("wrmsr failed");
344 return (DCMD_ERR);
345 }
346
347 return (DCMD_OK);
348 }
349
350 /*ARGSUSED*/
351 ssize_t
352 kmt_write(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
353 {
354 if (!(t->t_flags & MDB_TGT_F_ALLOWIO) &&
355 (nbytes = kmdb_kdi_range_is_nontoxic(addr, nbytes, 1)) == 0)
356 return (set_errno(EMDB_NOMAP));
357
358 /*
359 * No writes to user space are allowed. If we were to allow it, we'd
360 * be in the unfortunate situation where kmdb could place a breakpoint
361 * on a userspace executable page; this dirty page would end up being
362 * flushed back to disk, incurring sadness when it's next executed.
363 * Besides, we can't allow trapping in from userspace anyway.
364 */
365 if (addr < kmdb_kdi_get_userlimit())
366 return (set_errno(EMDB_TGTNOTSUP));
367
368 return (kmt_rw(t, (void *)buf, nbytes, addr, kmt_writer));
369 }
|