Print this page
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>


   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 }