Print this page
11584 ::xcall would be useful
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>


 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)