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 };
|