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>


   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  * The debugger/"PROM" interface layer
  30  *
  31  * It makes more sense on SPARC. In reality, these interfaces deal with three
  32  * things: setting break/watchpoints, stepping, and interfacing with the KDI to
  33  * set up kmdb's IDT handlers.
  34  */
  35 
  36 #include <kmdb/kmdb_dpi_impl.h>
  37 #include <kmdb/kmdb_kdi.h>
  38 #include <kmdb/kmdb_umemglue.h>
  39 #include <kmdb/kaif.h>
  40 #include <kmdb/kmdb_io.h>
  41 #include <kmdb/kaif_start.h>
  42 #include <mdb/mdb_err.h>
  43 #include <mdb/mdb_debug.h>
  44 #include <mdb/mdb_isautil.h>
  45 #include <mdb/mdb_io_impl.h>
  46 #include <mdb/mdb_kreg_impl.h>
  47 #include <mdb/mdb.h>


 586 
 587                 /* Go back to using the EFLAGS we were using before the step */
 588                 (void) kmdb_dpi_set_register(FLAGS_REG_NAME, oldfl);
 589                 return (0);
 590 
 591         default:
 592                 /*
 593                  * The stepped instruction may have altered EFLAGS.  We only
 594                  * really care about the value of IF, and we know the stepped
 595                  * instruction didn't alter it, so we can simply copy the
 596                  * pre-step value.  We'll also need to turn TF back off.
 597                  */
 598                 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
 599                 (void) kmdb_dpi_set_register(FLAGS_REG_NAME,
 600                     ((fl & ~(KREG_EFLAGS_TF_MASK|KREG_EFLAGS_IF_MASK)) |
 601                     (oldfl & KREG_EFLAGS_IF_MASK)));
 602                 return (0);
 603         }
 604 }
 605 
 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 /*ARGSUSED*/
 639 static uintptr_t
 640 kaif_call(uintptr_t funcva, uint_t argc, const uintptr_t argv[])
 641 {
 642         return (kaif_invoke(funcva, argc, argv));
 643 }
 644 
 645 static void
 646 dump_crumb(kdi_crumb_t *krmp)
 647 {
 648         kdi_crumb_t krm;
 649 
 650         if (mdb_vread(&krm, sizeof (kdi_crumb_t), (uintptr_t)krmp) !=
 651             sizeof (kdi_crumb_t)) {
 652                 warn("failed to read crumb at %p", krmp);
 653                 return;
 654         }
 655 
 656         mdb_printf("state: ");
 657         switch (krm.krm_cpu_state) {


 707 
 708                         dump_crumbs(save);
 709                 }
 710         }
 711 }
 712 
 713 static void
 714 kaif_modchg_register(void (*func)(struct modctl *, int))
 715 {
 716         kaif_modchg_cb = func;
 717 }
 718 
 719 static void
 720 kaif_modchg_cancel(void)
 721 {
 722         ASSERT(kaif_modchg_cb != NULL);
 723 
 724         kaif_modchg_cb = NULL;
 725 }
 726 
 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 void
 769 kaif_trap_set_debugger(void)
 770 {
 771         kmdb_kdi_idt_switch(NULL);
 772 }
 773 
 774 void
 775 kaif_trap_set_saved(kaif_cpusave_t *cpusave)
 776 {
 777         kmdb_kdi_idt_switch(cpusave);
 778 }
 779 
 780 static void
 781 kaif_vmready(void)
 782 {
 783 }
 784 
 785 void
 786 kaif_memavail(caddr_t base, size_t len)
 787 {


 867         kaif_init,
 868         kaif_activate,
 869         kmdb_kdi_deactivate,
 870         kaif_enter_mon,
 871         kaif_modchg_register,
 872         kaif_modchg_cancel,
 873         kaif_get_cpu_state,
 874         kaif_get_master_cpuid,
 875         kaif_get_gregs,
 876         kaif_get_register,
 877         kaif_set_register,
 878         kaif_brkpt_arm,
 879         kaif_brkpt_disarm,
 880         kaif_wapt_validate,
 881         kaif_wapt_reserve,
 882         kaif_wapt_release,
 883         kaif_wapt_arm,
 884         kaif_wapt_disarm,
 885         kaif_wapt_match,
 886         kaif_step,
 887         kaif_step_branch,
 888         kaif_call,
 889         kaif_dump_crumbs,
 890         kaif_msr_add,
 891         kaif_msr_get,
 892 };


   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  * The debugger/"PROM" interface layer
  30  *
  31  * It makes more sense on SPARC. In reality, these interfaces deal with three
  32  * things: setting break/watchpoints, stepping, and interfacing with the KDI to
  33  * set up kmdb's IDT handlers.
  34  */
  35 
  36 #include <kmdb/kmdb_dpi_impl.h>
  37 #include <kmdb/kmdb_kdi.h>
  38 #include <kmdb/kmdb_umemglue.h>
  39 #include <kmdb/kaif.h>
  40 #include <kmdb/kmdb_io.h>
  41 #include <kmdb/kaif_start.h>
  42 #include <mdb/mdb_err.h>
  43 #include <mdb/mdb_debug.h>
  44 #include <mdb/mdb_isautil.h>
  45 #include <mdb/mdb_io_impl.h>
  46 #include <mdb/mdb_kreg_impl.h>
  47 #include <mdb/mdb.h>


 586 
 587                 /* Go back to using the EFLAGS we were using before the step */
 588                 (void) kmdb_dpi_set_register(FLAGS_REG_NAME, oldfl);
 589                 return (0);
 590 
 591         default:
 592                 /*
 593                  * The stepped instruction may have altered EFLAGS.  We only
 594                  * really care about the value of IF, and we know the stepped
 595                  * instruction didn't alter it, so we can simply copy the
 596                  * pre-step value.  We'll also need to turn TF back off.
 597                  */
 598                 (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl);
 599                 (void) kmdb_dpi_set_register(FLAGS_REG_NAME,
 600                     ((fl & ~(KREG_EFLAGS_TF_MASK|KREG_EFLAGS_IF_MASK)) |
 601                     (oldfl & KREG_EFLAGS_IF_MASK)));
 602                 return (0);
 603         }
 604 }
 605 
































 606 /*ARGSUSED*/
 607 static uintptr_t
 608 kaif_call(uintptr_t funcva, uint_t argc, const uintptr_t argv[])
 609 {
 610         return (kaif_invoke(funcva, argc, argv));
 611 }
 612 
 613 static void
 614 dump_crumb(kdi_crumb_t *krmp)
 615 {
 616         kdi_crumb_t krm;
 617 
 618         if (mdb_vread(&krm, sizeof (kdi_crumb_t), (uintptr_t)krmp) !=
 619             sizeof (kdi_crumb_t)) {
 620                 warn("failed to read crumb at %p", krmp);
 621                 return;
 622         }
 623 
 624         mdb_printf("state: ");
 625         switch (krm.krm_cpu_state) {


 675 
 676                         dump_crumbs(save);
 677                 }
 678         }
 679 }
 680 
 681 static void
 682 kaif_modchg_register(void (*func)(struct modctl *, int))
 683 {
 684         kaif_modchg_cb = func;
 685 }
 686 
 687 static void
 688 kaif_modchg_cancel(void)
 689 {
 690         ASSERT(kaif_modchg_cb != NULL);
 691 
 692         kaif_modchg_cb = NULL;
 693 }
 694 









































 695 void
 696 kaif_trap_set_debugger(void)
 697 {
 698         kmdb_kdi_idt_switch(NULL);
 699 }
 700 
 701 void
 702 kaif_trap_set_saved(kaif_cpusave_t *cpusave)
 703 {
 704         kmdb_kdi_idt_switch(cpusave);
 705 }
 706 
 707 static void
 708 kaif_vmready(void)
 709 {
 710 }
 711 
 712 void
 713 kaif_memavail(caddr_t base, size_t len)
 714 {


 794         kaif_init,
 795         kaif_activate,
 796         kmdb_kdi_deactivate,
 797         kaif_enter_mon,
 798         kaif_modchg_register,
 799         kaif_modchg_cancel,
 800         kaif_get_cpu_state,
 801         kaif_get_master_cpuid,
 802         kaif_get_gregs,
 803         kaif_get_register,
 804         kaif_set_register,
 805         kaif_brkpt_arm,
 806         kaif_brkpt_disarm,
 807         kaif_wapt_validate,
 808         kaif_wapt_reserve,
 809         kaif_wapt_release,
 810         kaif_wapt_arm,
 811         kaif_wapt_disarm,
 812         kaif_wapt_match,
 813         kaif_step,

 814         kaif_call,
 815         kaif_dump_crumbs,


 816 };