785 "as relative (via -r) or absolute (via -a).\n";
786
787 static void
788 scalehrtime_help(void)
789 {
790 mdb_printf("%s", scalehrtime_desc);
791 }
792
793 /*
794 * NSEC_SHIFT is replicated here (it is not defined in a header file),
795 * but for amusement, the reader is directed to the comment that explains
796 * the rationale for this particular value on x86. Spoiler: the value is
797 * selected to accommodate 60 MHz Pentiums! (And a confession: if the voice
798 * in that comment sounds too familiar, it's because your author also wrote
799 * that code -- some fifteen years prior to this writing in 2011...)
800 */
801 #define NSEC_SHIFT 5
802
803 /*ARGSUSED*/
804 static int
805 scalehrtime_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
806 {
807 uint32_t nsec_scale;
808 hrtime_t tsc = addr, hrt, tsc_last, base, mult = 1;
809 unsigned int *tscp = (unsigned int *)&tsc;
810 uintptr_t scalehrtimef;
811 uint64_t scale;
812 GElf_Sym sym;
813 int expected = !(flags & DCMD_ADDRSPEC);
814 uint_t absolute = FALSE, relative = FALSE;
815
816 if (mdb_getopts(argc, argv,
817 'a', MDB_OPT_SETBITS, TRUE, &absolute,
818 'r', MDB_OPT_SETBITS, TRUE, &relative, NULL) != argc - expected)
819 return (DCMD_USAGE);
820
821 if (absolute && relative) {
822 mdb_warn("can't specify both -a and -r\n");
823 return (DCMD_USAGE);
824 }
825
887 }
888
889 scale = (uint64_t)nsec_scale;
890
891 hrt = ((uint64_t)tscp[1] * scale) << NSEC_SHIFT;
892 hrt += ((uint64_t)tscp[0] * scale) >> (32 - NSEC_SHIFT);
893
894 mdb_printf("0x%llx\n", base + (hrt * mult));
895
896 return (DCMD_OK);
897 }
898
899 /*
900 * The x86 feature set is implemented as a bitmap array. That bitmap array is
901 * stored across a number of uchars based on the BT_SIZEOFMAP(NUM_X86_FEATURES)
902 * macro. We have the names for each of these features in unix's text segment
903 * so we do not have to duplicate them and instead just look them up.
904 */
905 /*ARGSUSED*/
906 static int
907 x86_featureset_cmd(uintptr_t addr, uint_t flags, int argc,
908 const mdb_arg_t *argv)
909 {
910 void *fset;
911 GElf_Sym sym;
912 uintptr_t nptr;
913 char name[128];
914 int ii;
915
916 size_t sz = sizeof (uchar_t) * BT_SIZEOFMAP(NUM_X86_FEATURES);
917
918 if (argc != 0)
919 return (DCMD_USAGE);
920
921 if (mdb_lookup_by_name("x86_feature_names", &sym) == -1) {
922 mdb_warn("couldn't find x86_feature_names");
923 return (DCMD_ERR);
924 }
925
926 fset = mdb_zalloc(sz, UM_NOSLEEP);
927 if (fset == NULL) {
1018 mdb_printf("%%cr0 = 0x%lx <%b>\n", cr0, cr0, cr0_flag_bits);
1019 mdb_printf("%%cr2 = 0x%lx <%a>\n", cr2, cr2);
1020
1021 if ((cr4 & CR4_PCIDE)) {
1022 mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx pcid:%lu>\n", cr3,
1023 cr3 >> MMU_PAGESHIFT, cr3 & MMU_PAGEOFFSET);
1024 } else {
1025 mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx flags:%b>\n", cr3,
1026 cr3 >> MMU_PAGESHIFT, cr3, cr3_flag_bits);
1027 }
1028
1029 mdb_printf("%%cr4 = 0x%lx <%b>\n", cr4, cr4, cr4_flag_bits);
1030
1031 mdb_printf("%%gdtr.base = 0x%lx, %%gdtr.limit = 0x%hx\n",
1032 gdtr.dtr_base, gdtr.dtr_limit);
1033
1034 return (DCMD_OK);
1035 }
1036 #endif
1037
1038 static const mdb_dcmd_t dcmds[] = {
1039 { "gate_desc", ":", "dump a gate descriptor", gate_desc },
1040 { "idt", ":[-v]", "dump an IDT", idt },
1041 { "ttrace", "[-x] [-t kthread]", "dump trap trace buffers", ttrace },
1042 { "vatopfn", ":[-a as]", "translate address to physical page",
1043 va2pfn_dcmd },
1044 { "report_maps", ":[-m]",
1045 "Given PFN, report mappings / page table usage",
1046 report_maps_dcmd, report_maps_help },
1047 { "htables", "", "Given hat_t *, lists all its htable_t * values",
1048 htables_dcmd, htables_help },
1049 { "ptable", ":[-lm]", "Given PFN, dump contents of a page table",
1050 ptable_dcmd, ptable_help },
1051 { "ptmap", ":", "Given a cr3 value, dump all mappings",
1052 ptmap_dcmd, ptmap_help },
1053 { "pte", ":[-l N]", "print human readable page table entry",
1054 pte_dcmd },
1055 { "pfntomfn", ":", "convert physical page to hypervisor machine page",
1056 pfntomfn_dcmd },
1057 { "mfntopfn", ":", "convert hypervisor machine page to physical page",
1058 mfntopfn_dcmd },
1059 { "memseg_list", ":", "show memseg list", memseg_list },
1060 { "scalehrtime", ":[-a|-r]", "scale an unscaled high-res time",
1061 scalehrtime_cmd, scalehrtime_help },
1062 { "x86_featureset", NULL, "dump the x86_featureset vector",
1063 x86_featureset_cmd },
1064 #ifdef _KMDB
1065 { "sysregs", NULL, "dump system registers", sysregs_dcmd },
1066 #endif
1067 { NULL }
1068 };
1069
1070 static const mdb_walker_t walkers[] = {
1071 { "ttrace", "walks trap trace buffers in reverse chronological order",
1072 ttrace_walk_init, ttrace_walk_step, ttrace_walk_fini },
1073 { "mutex_owner", "walks the owner of a mutex",
1074 mutex_owner_init, mutex_owner_step },
1075 { "memseg", "walk the memseg structures",
1076 memseg_walk_init, memseg_walk_step, memseg_walk_fini },
1077 { NULL }
1078 };
1079
1080 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
1081
1082 const mdb_modinfo_t *
1083 _mdb_init(void)
|
785 "as relative (via -r) or absolute (via -a).\n";
786
787 static void
788 scalehrtime_help(void)
789 {
790 mdb_printf("%s", scalehrtime_desc);
791 }
792
793 /*
794 * NSEC_SHIFT is replicated here (it is not defined in a header file),
795 * but for amusement, the reader is directed to the comment that explains
796 * the rationale for this particular value on x86. Spoiler: the value is
797 * selected to accommodate 60 MHz Pentiums! (And a confession: if the voice
798 * in that comment sounds too familiar, it's because your author also wrote
799 * that code -- some fifteen years prior to this writing in 2011...)
800 */
801 #define NSEC_SHIFT 5
802
803 /*ARGSUSED*/
804 static int
805 scalehrtime_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
806 {
807 uint32_t nsec_scale;
808 hrtime_t tsc = addr, hrt, tsc_last, base, mult = 1;
809 unsigned int *tscp = (unsigned int *)&tsc;
810 uintptr_t scalehrtimef;
811 uint64_t scale;
812 GElf_Sym sym;
813 int expected = !(flags & DCMD_ADDRSPEC);
814 uint_t absolute = FALSE, relative = FALSE;
815
816 if (mdb_getopts(argc, argv,
817 'a', MDB_OPT_SETBITS, TRUE, &absolute,
818 'r', MDB_OPT_SETBITS, TRUE, &relative, NULL) != argc - expected)
819 return (DCMD_USAGE);
820
821 if (absolute && relative) {
822 mdb_warn("can't specify both -a and -r\n");
823 return (DCMD_USAGE);
824 }
825
887 }
888
889 scale = (uint64_t)nsec_scale;
890
891 hrt = ((uint64_t)tscp[1] * scale) << NSEC_SHIFT;
892 hrt += ((uint64_t)tscp[0] * scale) >> (32 - NSEC_SHIFT);
893
894 mdb_printf("0x%llx\n", base + (hrt * mult));
895
896 return (DCMD_OK);
897 }
898
899 /*
900 * The x86 feature set is implemented as a bitmap array. That bitmap array is
901 * stored across a number of uchars based on the BT_SIZEOFMAP(NUM_X86_FEATURES)
902 * macro. We have the names for each of these features in unix's text segment
903 * so we do not have to duplicate them and instead just look them up.
904 */
905 /*ARGSUSED*/
906 static int
907 x86_featureset_dcmd(uintptr_t addr, uint_t flags, int argc,
908 const mdb_arg_t *argv)
909 {
910 void *fset;
911 GElf_Sym sym;
912 uintptr_t nptr;
913 char name[128];
914 int ii;
915
916 size_t sz = sizeof (uchar_t) * BT_SIZEOFMAP(NUM_X86_FEATURES);
917
918 if (argc != 0)
919 return (DCMD_USAGE);
920
921 if (mdb_lookup_by_name("x86_feature_names", &sym) == -1) {
922 mdb_warn("couldn't find x86_feature_names");
923 return (DCMD_ERR);
924 }
925
926 fset = mdb_zalloc(sz, UM_NOSLEEP);
927 if (fset == NULL) {
1018 mdb_printf("%%cr0 = 0x%lx <%b>\n", cr0, cr0, cr0_flag_bits);
1019 mdb_printf("%%cr2 = 0x%lx <%a>\n", cr2, cr2);
1020
1021 if ((cr4 & CR4_PCIDE)) {
1022 mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx pcid:%lu>\n", cr3,
1023 cr3 >> MMU_PAGESHIFT, cr3 & MMU_PAGEOFFSET);
1024 } else {
1025 mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx flags:%b>\n", cr3,
1026 cr3 >> MMU_PAGESHIFT, cr3, cr3_flag_bits);
1027 }
1028
1029 mdb_printf("%%cr4 = 0x%lx <%b>\n", cr4, cr4, cr4_flag_bits);
1030
1031 mdb_printf("%%gdtr.base = 0x%lx, %%gdtr.limit = 0x%hx\n",
1032 gdtr.dtr_base, gdtr.dtr_limit);
1033
1034 return (DCMD_OK);
1035 }
1036 #endif
1037
1038 extern void xcall_help(void);
1039 extern int xcall_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
1040
1041 static const mdb_dcmd_t dcmds[] = {
1042 { "gate_desc", ":", "dump a gate descriptor", gate_desc },
1043 { "idt", ":[-v]", "dump an IDT", idt },
1044 { "ttrace", "[-x] [-t kthread]", "dump trap trace buffers", ttrace },
1045 { "vatopfn", ":[-a as]", "translate address to physical page",
1046 va2pfn_dcmd },
1047 { "report_maps", ":[-m]",
1048 "Given PFN, report mappings / page table usage",
1049 report_maps_dcmd, report_maps_help },
1050 { "htables", "", "Given hat_t *, lists all its htable_t * values",
1051 htables_dcmd, htables_help },
1052 { "ptable", ":[-lm]", "Given PFN, dump contents of a page table",
1053 ptable_dcmd, ptable_help },
1054 { "ptmap", ":", "Given a cr3 value, dump all mappings",
1055 ptmap_dcmd, ptmap_help },
1056 { "pte", ":[-l N]", "print human readable page table entry",
1057 pte_dcmd },
1058 { "pfntomfn", ":", "convert physical page to hypervisor machine page",
1059 pfntomfn_dcmd },
1060 { "mfntopfn", ":", "convert hypervisor machine page to physical page",
1061 mfntopfn_dcmd },
1062 { "memseg_list", ":", "show memseg list", memseg_list },
1063 { "scalehrtime", ":[-a|-r]", "scale an unscaled high-res time",
1064 scalehrtime_dcmd, scalehrtime_help },
1065 { "x86_featureset", NULL, "dump the x86_featureset vector",
1066 x86_featureset_dcmd },
1067 { "xcall", ":", "print CPU cross-call state", xcall_dcmd, xcall_help },
1068 #ifdef _KMDB
1069 { "sysregs", NULL, "dump system registers", sysregs_dcmd },
1070 #endif
1071 { NULL }
1072 };
1073
1074 static const mdb_walker_t walkers[] = {
1075 { "ttrace", "walks trap trace buffers in reverse chronological order",
1076 ttrace_walk_init, ttrace_walk_step, ttrace_walk_fini },
1077 { "mutex_owner", "walks the owner of a mutex",
1078 mutex_owner_init, mutex_owner_step },
1079 { "memseg", "walk the memseg structures",
1080 memseg_walk_init, memseg_walk_step, memseg_walk_fini },
1081 { NULL }
1082 };
1083
1084 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
1085
1086 const mdb_modinfo_t *
1087 _mdb_init(void)
|