10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53708Skrishna  * Common Development and Distribution License (the "License").
63708Skrishna  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*8384SBhargava.Yenduri@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * mdb dcmds for selected structures from
280Sstevel@tonic-gate  * usr/src/uts/common/sys/crypto/impl.h
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <sys/mdb_modapi.h>
320Sstevel@tonic-gate #include <sys/modctl.h>
330Sstevel@tonic-gate #include <sys/types.h>
340Sstevel@tonic-gate #include <sys/crypto/api.h>
350Sstevel@tonic-gate #include <sys/crypto/common.h>
360Sstevel@tonic-gate #include <sys/crypto/impl.h>
370Sstevel@tonic-gate #include "crypto_cmds.h"
380Sstevel@tonic-gate 
390Sstevel@tonic-gate int
400Sstevel@tonic-gate kcf_sched_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
410Sstevel@tonic-gate {
420Sstevel@tonic-gate 	kcf_sched_info_t sched;
430Sstevel@tonic-gate 	kcf_sched_info_t *sinfo = &sched;
440Sstevel@tonic-gate 
450Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
460Sstevel@tonic-gate 		if ((argc == 1) && (argv->a_type == MDB_TYPE_IMMEDIATE))
470Sstevel@tonic-gate 			sinfo = (kcf_sched_info_t *)(uintptr_t)argv->a_un.a_val;
480Sstevel@tonic-gate 		else
490Sstevel@tonic-gate 			return (DCMD_USAGE);
500Sstevel@tonic-gate 	} else if (addr == NULL)	/* not allowed with DCMD_ADDRSPEC */
510Sstevel@tonic-gate 		return (DCMD_USAGE);
520Sstevel@tonic-gate 	else {
530Sstevel@tonic-gate 		if (mdb_vread(sinfo, sizeof (kcf_sched_info_t), addr) == -1) {
540Sstevel@tonic-gate 			mdb_warn("cannot read %p", addr);
550Sstevel@tonic-gate 			return (DCMD_ERR);
560Sstevel@tonic-gate 		}
570Sstevel@tonic-gate 	}
580Sstevel@tonic-gate 	mdb_printf("ks_ndispatches:\t%llu\n", sinfo->ks_ndispatches);
590Sstevel@tonic-gate 	mdb_printf("ks_nfails:\t%llu\n", sinfo->ks_nfails);
600Sstevel@tonic-gate 	mdb_printf("ks_nbusy_rval:\t%llu\n", sinfo->ks_nbusy_rval);
610Sstevel@tonic-gate 	mdb_printf("ks_ntaskq:\t%p\n", sinfo->ks_taskq);
620Sstevel@tonic-gate 	return (DCMD_OK);
630Sstevel@tonic-gate }
640Sstevel@tonic-gate 
650Sstevel@tonic-gate static const char *prov_states[] = {
660Sstevel@tonic-gate 	"none",
670Sstevel@tonic-gate 	"KCF_PROV_ALLOCATED",
680Sstevel@tonic-gate 	"KCF_PROV_UNVERIFIED",
694373Skrishna 	"KCF_PROV_VERIFICATION_FAILED",
700Sstevel@tonic-gate 	"KCF_PROV_READY",
710Sstevel@tonic-gate 	"KCF_PROV_BUSY",
720Sstevel@tonic-gate 	"KCF_PROV_FAILED",
730Sstevel@tonic-gate 	"KCF_PROV_DISABLED",
740Sstevel@tonic-gate 	"KCF_PROV_REMOVED",
750Sstevel@tonic-gate 	"KCF_PROV_FREED"
760Sstevel@tonic-gate };
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static void
790Sstevel@tonic-gate pr_kstat_named(kstat_named_t *ks)
800Sstevel@tonic-gate {
810Sstevel@tonic-gate 	mdb_inc_indent(4);
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	mdb_printf("name = %s\n", ks->name);
840Sstevel@tonic-gate 	mdb_printf("value = ");
850Sstevel@tonic-gate 
860Sstevel@tonic-gate 	/*
870Sstevel@tonic-gate 	 * The only data type used for the provider kstats is uint64.
880Sstevel@tonic-gate 	 */
890Sstevel@tonic-gate 	switch (ks->data_type) {
900Sstevel@tonic-gate 	case KSTAT_DATA_UINT64:
910Sstevel@tonic-gate #if defined(_LP64) || defined(_LONGLONG_TYPE)
920Sstevel@tonic-gate 		mdb_printf("%llu\n", ks->value.ui64);
930Sstevel@tonic-gate #endif
940Sstevel@tonic-gate 		break;
950Sstevel@tonic-gate 	default:
960Sstevel@tonic-gate 		mdb_warn("Incorrect data type for kstat.\n");
970Sstevel@tonic-gate 	}
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 	mdb_dec_indent(4);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate /*ARGSUSED*/
1030Sstevel@tonic-gate int
1040Sstevel@tonic-gate kcf_provider_desc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1050Sstevel@tonic-gate {
1060Sstevel@tonic-gate 	kcf_provider_desc_t desc;
1070Sstevel@tonic-gate 	kcf_provider_desc_t *ptr;
1080Sstevel@tonic-gate 	char string[MAXNAMELEN + 1];
1090Sstevel@tonic-gate 	int i, j;
1100Sstevel@tonic-gate 	crypto_mech_info_t *mech_pointer;
1110Sstevel@tonic-gate 	mdb_arg_t arg;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) != DCMD_ADDRSPEC)
1140Sstevel@tonic-gate 		return (DCMD_USAGE);
1150Sstevel@tonic-gate 	ptr = (kcf_provider_desc_t *)addr;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate #ifdef DEBUG
1180Sstevel@tonic-gate 	mdb_printf("DEBUG: reading kcf_provider_desc at %p\n", ptr);
1190Sstevel@tonic-gate #endif
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	if (mdb_vread(&desc, sizeof (kcf_provider_desc_t), (uintptr_t)ptr)
1220Sstevel@tonic-gate 	    == -1) {
123*8384SBhargava.Yenduri@Sun.COM 		mdb_warn("cannot read at address %p", (uintptr_t)ptr);
124*8384SBhargava.Yenduri@Sun.COM 		return (DCMD_ERR);
1250Sstevel@tonic-gate 	}
1260Sstevel@tonic-gate 	mdb_printf("%<b>kcf_provider_desc at %p%</b>\n", ptr);
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate 	switch (desc.pd_prov_type) {
1290Sstevel@tonic-gate 	case CRYPTO_HW_PROVIDER:
1300Sstevel@tonic-gate 		mdb_printf("pd_prov_type:\t\tCRYPTO_HW_PROVIDER\n");
1310Sstevel@tonic-gate 		break;
1320Sstevel@tonic-gate 	case CRYPTO_SW_PROVIDER:
1330Sstevel@tonic-gate 		mdb_printf("pd_prov_type:\t\tCRYPTO_SW_PROVIDER\n");
1340Sstevel@tonic-gate 		break;
1350Sstevel@tonic-gate 	case CRYPTO_LOGICAL_PROVIDER:
1360Sstevel@tonic-gate 		mdb_printf("pd_prov_type:\t\tCRYPTO_LOGICAL_PROVIDER\n");
1370Sstevel@tonic-gate 		break;
1380Sstevel@tonic-gate 	default:
1390Sstevel@tonic-gate 		mdb_printf("bad pd_prov_type:\t%d\n", desc.pd_prov_type);
1400Sstevel@tonic-gate 	}
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	mdb_printf("pd_prov_handle:\t\t%p\n", desc.pd_prov_handle);
1430Sstevel@tonic-gate 	mdb_printf("pd_kcf_prov_handle:\t%u\n", desc.pd_kcf_prov_handle);
1440Sstevel@tonic-gate 	mdb_printf("pd_prov_id:\t\t%u\n", desc.pd_prov_id);
1450Sstevel@tonic-gate 	if (desc.pd_description == NULL)
1460Sstevel@tonic-gate 		mdb_printf("pd_description:\t\tNULL\n");
1470Sstevel@tonic-gate 	else if (mdb_readstr(string, MAXNAMELEN + 1,
148*8384SBhargava.Yenduri@Sun.COM 	    (uintptr_t)desc.pd_description) == -1) {
1490Sstevel@tonic-gate 		mdb_warn("cannot read %p", desc.pd_description);
1500Sstevel@tonic-gate 	} else
151*8384SBhargava.Yenduri@Sun.COM 		mdb_printf("pd_description:\t\t%s\n", string);
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	mdb_printf("pd_ops_vector:\t\t%p\n", desc.pd_ops_vector);
1540Sstevel@tonic-gate 	mdb_printf("pd_mech_list_count:\t%u\n", desc.pd_mech_list_count);
1550Sstevel@tonic-gate 	/* mechanisms */
1560Sstevel@tonic-gate 	mdb_inc_indent(4);
1570Sstevel@tonic-gate 	for (i = 0; i < desc.pd_mech_list_count; i++) {
1580Sstevel@tonic-gate 		mech_pointer = desc.pd_mechanisms + i;
1590Sstevel@tonic-gate 		mdb_call_dcmd("crypto_mech_info",
160*8384SBhargava.Yenduri@Sun.COM 		    (uintptr_t)mech_pointer, DCMD_ADDRSPEC, 0, NULL);
1610Sstevel@tonic-gate 	}
1620Sstevel@tonic-gate 	mdb_dec_indent(4);
1633708Skrishna 	mdb_printf("pd_mech_indx:\n");
1640Sstevel@tonic-gate 	mdb_inc_indent(8);
1650Sstevel@tonic-gate 	for (i = 0; i < KCF_OPS_CLASSSIZE; i++) {
166*8384SBhargava.Yenduri@Sun.COM 		for (j = 0; j < KCF_MAXMECHTAB; j++) {
167*8384SBhargava.Yenduri@Sun.COM 			if (desc.pd_mech_indx[i][j] == KCF_INVALID_INDX)
168*8384SBhargava.Yenduri@Sun.COM 				mdb_printf("N ");
169*8384SBhargava.Yenduri@Sun.COM 			else
170*8384SBhargava.Yenduri@Sun.COM 				mdb_printf("%u ", desc.pd_mech_indx[i][j]);
171*8384SBhargava.Yenduri@Sun.COM 		}
172*8384SBhargava.Yenduri@Sun.COM 		mdb_printf("\n");
1730Sstevel@tonic-gate 	}
1740Sstevel@tonic-gate 	mdb_dec_indent(8);
1750Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_total:\n", desc.pd_ks_data.ps_ops_total);
1760Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_total);
1770Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_passed:\n",
1780Sstevel@tonic-gate 	    desc.pd_ks_data.ps_ops_passed);
1790Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_passed);
1800Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_failed:\n",
1810Sstevel@tonic-gate 	    desc.pd_ks_data.ps_ops_failed);
1820Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_failed);
1830Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_busy_rval:\n",
1840Sstevel@tonic-gate 	    desc.pd_ks_data.ps_ops_busy_rval);
1850Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_busy_rval);
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	mdb_printf("pd_kstat:\t\t%p\n", desc.pd_kstat);
1880Sstevel@tonic-gate 	mdb_printf("kcf_sched_info:\n");
1890Sstevel@tonic-gate 	/* print pd_sched_info via existing function */
1900Sstevel@tonic-gate 	mdb_inc_indent(8);
1910Sstevel@tonic-gate 	arg.a_type = MDB_TYPE_IMMEDIATE;
1920Sstevel@tonic-gate 	arg.a_un.a_val = (uintmax_t)(uintptr_t)&desc.pd_sched_info;
1930Sstevel@tonic-gate 	mdb_call_dcmd("kcf_sched_info", (uintptr_t)NULL, 0, 1, &arg);
1940Sstevel@tonic-gate 	mdb_dec_indent(8);
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 	mdb_printf("pd_refcnt:\t\t%u\n", desc.pd_refcnt);
1970Sstevel@tonic-gate 	if (desc.pd_name == NULL)
198*8384SBhargava.Yenduri@Sun.COM 		mdb_printf("pd_name:\t\t NULL\n");
1990Sstevel@tonic-gate 	else if (mdb_readstr(string, MAXNAMELEN + 1, (uintptr_t)desc.pd_name)
200*8384SBhargava.Yenduri@Sun.COM 	    == -1)
2010Sstevel@tonic-gate 		mdb_warn("could not read pd_name from %X\n", desc.pd_name);
2020Sstevel@tonic-gate 	else
203*8384SBhargava.Yenduri@Sun.COM 		mdb_printf("pd_name:\t\t%s\n", string);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	mdb_printf("pd_instance:\t\t%u\n", desc.pd_instance);
2060Sstevel@tonic-gate 	mdb_printf("pd_module_id:\t\t%d\n", desc.pd_module_id);
2070Sstevel@tonic-gate 	mdb_printf("pd_mctlp:\t\t%p\n", desc.pd_mctlp);
2080Sstevel@tonic-gate 	mdb_printf("pd_sid:\t\t\t%u\n", desc.pd_sid);
2090Sstevel@tonic-gate 	mdb_printf("pd_lock:\t\t%p\n", desc.pd_lock);
2100Sstevel@tonic-gate 	if (desc.pd_state < KCF_PROV_ALLOCATED ||
2110Sstevel@tonic-gate 	    desc.pd_state > KCF_PROV_FREED)
2120Sstevel@tonic-gate 		mdb_printf("pd_state is invalid:\t%d\n", desc.pd_state);
2130Sstevel@tonic-gate 	else
2140Sstevel@tonic-gate 		mdb_printf("pd_state:\t%s\n", prov_states[desc.pd_state]);
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate 	mdb_printf("pd_resume_cv:\t\t%hd\n", desc.pd_resume_cv._opaque);
2170Sstevel@tonic-gate 	mdb_printf("pd_remove_cv:\t\t%hd\n", desc.pd_remove_cv._opaque);
218*8384SBhargava.Yenduri@Sun.COM 	mdb_printf("pd_flags:\t\t%s %s %s %s %s\n",
2193708Skrishna 	    (desc.pd_flags & CRYPTO_HIDE_PROVIDER) ?
220*8384SBhargava.Yenduri@Sun.COM 	    "CRYPTO_HIDE_PROVIDER" : " ",
2214072Skrishna 	    (desc.pd_flags & CRYPTO_HASH_NO_UPDATE) ?
222*8384SBhargava.Yenduri@Sun.COM 	    "CRYPTO_HASH_NO_UPDATE" : " ",
223*8384SBhargava.Yenduri@Sun.COM 	    (desc.pd_flags & CRYPTO_SYNCHRONOUS) ?
224*8384SBhargava.Yenduri@Sun.COM 	    "CRYPTO_SYNCHRONOUS" : " ",
2253708Skrishna 	    (desc.pd_flags & KCF_LPROV_MEMBER) ?
226*8384SBhargava.Yenduri@Sun.COM 	    "KCF_LPROV_MEMBER" : " ",
2273708Skrishna 	    (desc.pd_flags & KCF_PROV_RESTRICTED) ?
228*8384SBhargava.Yenduri@Sun.COM 	    "KCF_PROV_RESTRICTED" : " ");
2294072Skrishna 	if (desc.pd_flags & CRYPTO_HASH_NO_UPDATE)
2304072Skrishna 		mdb_printf("pd_hash_limit:\t\t%u\n", desc.pd_hash_limit);
2310Sstevel@tonic-gate 	mdb_printf("pd_provider_list:\t%p\n", desc.pd_provider_list);
2320Sstevel@tonic-gate 	return (DCMD_OK);
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate #define	GOT_NONE	(-2)
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate /*ARGSUSED*/
2380Sstevel@tonic-gate int
2390Sstevel@tonic-gate prov_tab(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2400Sstevel@tonic-gate {
2410Sstevel@tonic-gate 	kcf_provider_desc_t **tab;
2420Sstevel@tonic-gate 	kcf_provider_desc_t desc;
2430Sstevel@tonic-gate 	kcf_provider_desc_t *ptr;
2440Sstevel@tonic-gate 	uint_t prov_tab_max;
2450Sstevel@tonic-gate 	int i;
2460Sstevel@tonic-gate 	int gotzero = GOT_NONE;
2470Sstevel@tonic-gate 	char string[MAXNAMELEN + 1];
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == DCMD_ADDRSPEC) {
2500Sstevel@tonic-gate 		return (DCMD_USAGE);
2510Sstevel@tonic-gate 	} else if (mdb_readsym(&ptr, sizeof (void *), "prov_tab")
2520Sstevel@tonic-gate 	    == -1) {
2530Sstevel@tonic-gate 		mdb_warn("cannot read prov_tab");
2540Sstevel@tonic-gate 		return (DCMD_ERR);
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	} else if (mdb_readvar(&prov_tab_max, "prov_tab_max") == -1) {
2570Sstevel@tonic-gate 		mdb_warn("cannot read prov_tab_max");
2580Sstevel@tonic-gate 		return (DCMD_ERR);
2590Sstevel@tonic-gate 	}
2600Sstevel@tonic-gate 	mdb_printf("%<b>prov_tab = %p%</b>\n", ptr);
2610Sstevel@tonic-gate 	tab = mdb_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
2620Sstevel@tonic-gate 	    UM_SLEEP| UM_GC);
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate #ifdef DEBUG
2650Sstevel@tonic-gate 	mdb_printf("DEBUG: tab = %p, prov_tab_max = %d\n", tab, prov_tab_max);
2660Sstevel@tonic-gate #endif
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	if (mdb_vread(tab, prov_tab_max * sizeof (kcf_provider_desc_t *),
2690Sstevel@tonic-gate 	    (uintptr_t)ptr) == -1) {
2700Sstevel@tonic-gate 		mdb_warn("cannot read prov_tab");
2710Sstevel@tonic-gate 		return (DCMD_ERR);
2720Sstevel@tonic-gate 	}
2730Sstevel@tonic-gate #ifdef DEBUG
2740Sstevel@tonic-gate 	mdb_printf("DEBUG: got past mdb_vread of tab\n");
2750Sstevel@tonic-gate 	mdb_printf("DEBUG: *tab = %p\n", *tab);
2760Sstevel@tonic-gate #endif
2770Sstevel@tonic-gate 	for (i = 0;  i <  prov_tab_max; i++) {
2780Sstevel@tonic-gate 		/* save space, only print range for long list of nulls */
2790Sstevel@tonic-gate 		if (tab[i] == NULL) {
2800Sstevel@tonic-gate 			if (gotzero == GOT_NONE) {
281*8384SBhargava.Yenduri@Sun.COM 				mdb_printf("prov_tab[%d", i);
282*8384SBhargava.Yenduri@Sun.COM 				gotzero = i;
2830Sstevel@tonic-gate 			}
2840Sstevel@tonic-gate 		} else {
2850Sstevel@tonic-gate 			/* first non-null in awhile, print index of prev null */
2860Sstevel@tonic-gate 			if (gotzero != GOT_NONE) {
2870Sstevel@tonic-gate 				if (gotzero == (i - 1))
2880Sstevel@tonic-gate 					mdb_printf("] = NULL\n", i - 1);
2890Sstevel@tonic-gate 				else
2900Sstevel@tonic-gate 					mdb_printf(" - %d] = NULL\n", i - 1);
2910Sstevel@tonic-gate 				gotzero = GOT_NONE;
2920Sstevel@tonic-gate 			}
2930Sstevel@tonic-gate 			/* interesting value, print it */
2940Sstevel@tonic-gate 			mdb_printf("prov_tab[%d] = %p ", i, tab[i]);
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 			if (mdb_vread(&desc, sizeof (kcf_provider_desc_t),
2970Sstevel@tonic-gate 			    (uintptr_t)tab[i]) == -1) {
2980Sstevel@tonic-gate 				mdb_warn("cannot read at address %p",
2990Sstevel@tonic-gate 				    (uintptr_t)tab[i]);
3000Sstevel@tonic-gate 				return (DCMD_ERR);
3010Sstevel@tonic-gate 			}
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 			(void) mdb_readstr(string, MAXNAMELEN + 1,
3040Sstevel@tonic-gate 			    (uintptr_t)desc.pd_name);
3050Sstevel@tonic-gate 			mdb_printf("(%s\t%s)\n", string,
3060Sstevel@tonic-gate 			    prov_states[desc.pd_state]);
3070Sstevel@tonic-gate 		}
3080Sstevel@tonic-gate 	}
3090Sstevel@tonic-gate 	/* if we've printed the first of many nulls but left the brace open */
3100Sstevel@tonic-gate 	if ((i > 0) && (tab[i-1] == NULL)) {
3110Sstevel@tonic-gate 		if (gotzero == GOT_NONE)
3120Sstevel@tonic-gate 			mdb_printf("] = NULL\n");
3130Sstevel@tonic-gate 		else
3140Sstevel@tonic-gate 			mdb_printf(" - %d] = NULL\n", i - 1);
3150Sstevel@tonic-gate 	}
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate 	return (DCMD_OK);
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate /*ARGSUSED*/
3210Sstevel@tonic-gate int
3220Sstevel@tonic-gate policy_tab(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate 	kcf_policy_desc_t **tab;
3250Sstevel@tonic-gate 	kcf_policy_desc_t *ptr;
3260Sstevel@tonic-gate 	uint_t policy_tab_max;
3270Sstevel@tonic-gate 	int num, i;
3280Sstevel@tonic-gate 	int gotzero = GOT_NONE;
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == DCMD_ADDRSPEC) {
3310Sstevel@tonic-gate 		return (DCMD_USAGE);
3320Sstevel@tonic-gate 	} else if (mdb_readsym(&ptr, sizeof (void *), "policy_tab")
3330Sstevel@tonic-gate 	    == -1) {
3340Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab");
3350Sstevel@tonic-gate 		return (DCMD_ERR);
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 	} else if (mdb_readvar(&policy_tab_max, "policy_tab_max") == -1) {
3380Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab_max");
3390Sstevel@tonic-gate 		return (DCMD_ERR);
3400Sstevel@tonic-gate 	}
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	/* get the current number of descriptors in the table */
3430Sstevel@tonic-gate 	if (mdb_readvar(&num, "policy_tab_num") == -1) {
3440Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab_num");
3450Sstevel@tonic-gate 		return (DCMD_ERR);
3460Sstevel@tonic-gate 	}
3470Sstevel@tonic-gate 	mdb_printf("%<b>policy_tab = %p%</b> \tpolicy_tab_num = %d\n",
3480Sstevel@tonic-gate 	    ptr, num);
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	tab = mdb_zalloc(policy_tab_max * sizeof (kcf_policy_desc_t *),
3510Sstevel@tonic-gate 	    UM_SLEEP| UM_GC);
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	if (mdb_vread(tab, policy_tab_max * sizeof (kcf_policy_desc_t *),
3540Sstevel@tonic-gate 	    (uintptr_t)ptr) == -1) {
3550Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab");
3560Sstevel@tonic-gate 		return (DCMD_ERR);
3570Sstevel@tonic-gate 	}
3580Sstevel@tonic-gate #ifdef DEBUG
3590Sstevel@tonic-gate 	mdb_printf("DEBUG: got past mdb_vread of tab\n");
3600Sstevel@tonic-gate 	mdb_printf("DEBUG: *tab = %p\n", *tab);
3610Sstevel@tonic-gate #endif
3620Sstevel@tonic-gate 	for (i = 0;  i < policy_tab_max; i++) {
3630Sstevel@tonic-gate 		/* save space, only print range for long list of nulls */
3640Sstevel@tonic-gate 		if (tab[i] == NULL) {
3650Sstevel@tonic-gate 			if (gotzero == GOT_NONE) {
366*8384SBhargava.Yenduri@Sun.COM 				mdb_printf("policy_tab[%d", i);
367*8384SBhargava.Yenduri@Sun.COM 				gotzero = i;
3680Sstevel@tonic-gate 			}
3690Sstevel@tonic-gate 		} else {
3700Sstevel@tonic-gate 			/* first non-null in awhile, print index of prev null */
3710Sstevel@tonic-gate 			if (gotzero != GOT_NONE) {
3720Sstevel@tonic-gate 				if (gotzero == (i - 1))
3730Sstevel@tonic-gate 					mdb_printf("] = NULL\n", i - 1);
3740Sstevel@tonic-gate 				else
3750Sstevel@tonic-gate 					mdb_printf(" - %d] = NULL\n", i - 1);
3760Sstevel@tonic-gate 				gotzero = GOT_NONE;
3770Sstevel@tonic-gate 			}
3780Sstevel@tonic-gate 			/* interesting value, print it */
3790Sstevel@tonic-gate 			mdb_printf("policy_tab[%d] = %p\n", i, tab[i]);
3800Sstevel@tonic-gate 		}
3810Sstevel@tonic-gate 	}
3820Sstevel@tonic-gate 	/* if we've printed the first of many nulls but left the brace open */
3830Sstevel@tonic-gate 	if ((i > 0) && (tab[i-1] == NULL)) {
3840Sstevel@tonic-gate 		if (gotzero == GOT_NONE)
3850Sstevel@tonic-gate 			mdb_printf("] = NULL\n");
3860Sstevel@tonic-gate 		else
3870Sstevel@tonic-gate 			mdb_printf(" - %d] = NULL\n", i - 1);
3880Sstevel@tonic-gate 	}
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	return (DCMD_OK);
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate static void
3940Sstevel@tonic-gate prt_mechs(int count, crypto_mech_name_t *mechs)
3950Sstevel@tonic-gate {
3960Sstevel@tonic-gate 	int i;
3970Sstevel@tonic-gate 	char name[CRYPTO_MAX_MECH_NAME + 1];
3980Sstevel@tonic-gate 	char name2[CRYPTO_MAX_MECH_NAME + 3];
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
4010Sstevel@tonic-gate 		if (mdb_readstr(name, CRYPTO_MAX_MECH_NAME,
4020Sstevel@tonic-gate 		    (uintptr_t)((char *)mechs)) == -1)
4030Sstevel@tonic-gate 			continue;
4040Sstevel@tonic-gate 		/* put in quotes */
4050Sstevel@tonic-gate 		(void) mdb_snprintf(name2, sizeof (name2), "\"%s\"", name);
4060Sstevel@tonic-gate 		/* yes, length is 32, but then it will wrap */
4070Sstevel@tonic-gate 		/* this shorter size formats nicely for most cases */
4080Sstevel@tonic-gate 		mdb_printf("mechs[%d]=%-28s", i, name2);
4090Sstevel@tonic-gate 		mdb_printf("%s", i%2 ? "\n" : "  "); /* 2-columns */
4100Sstevel@tonic-gate 		mechs++;
4110Sstevel@tonic-gate 	}
4120Sstevel@tonic-gate }
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate /* ARGSUSED2 */
4150Sstevel@tonic-gate static int
4160Sstevel@tonic-gate prt_soft_conf_entry(kcf_soft_conf_entry_t *addr, kcf_soft_conf_entry_t *entry,
4170Sstevel@tonic-gate     void *cbdata)
4180Sstevel@tonic-gate {
4190Sstevel@tonic-gate 	char name[MAXNAMELEN + 1];
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 	mdb_printf("\n%<b>kcf_soft_conf_entry_t at %p:%</b>\n", addr);
4220Sstevel@tonic-gate 	mdb_printf("ce_next: %p", entry->ce_next);
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 	if (entry->ce_name == NULL)
425*8384SBhargava.Yenduri@Sun.COM 		mdb_printf("\tce_name: NULL\n");
4260Sstevel@tonic-gate 	else if (mdb_readstr(name, MAXNAMELEN, (uintptr_t)entry->ce_name)
427*8384SBhargava.Yenduri@Sun.COM 	    == -1)
4280Sstevel@tonic-gate 		mdb_printf("could not read ce_name from %p\n",
429*8384SBhargava.Yenduri@Sun.COM 		    entry->ce_name);
4300Sstevel@tonic-gate 	else
4310Sstevel@tonic-gate 		mdb_printf("\tce_name: %s\n", name);
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 	mdb_printf("ce_count: %d\n", entry->ce_count);
4340Sstevel@tonic-gate 	prt_mechs(entry->ce_count, entry->ce_mechs);
4350Sstevel@tonic-gate 	return (WALK_NEXT);
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate int
4390Sstevel@tonic-gate soft_conf_walk_init(mdb_walk_state_t *wsp)
4400Sstevel@tonic-gate {
4410Sstevel@tonic-gate 	uintptr_t *soft;
4420Sstevel@tonic-gate 
4430Sstevel@tonic-gate 	if (mdb_readsym(&soft, sizeof (kcf_soft_conf_entry_t *),
4440Sstevel@tonic-gate 	    "soft_config_list") == -1) {
4450Sstevel@tonic-gate 		mdb_warn("failed to find 'soft_config_list'");
4460Sstevel@tonic-gate 		return (WALK_ERR);
4470Sstevel@tonic-gate 	}
4480Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)soft;
4490Sstevel@tonic-gate 	wsp->walk_data = mdb_alloc(sizeof (kcf_soft_conf_entry_t), UM_SLEEP);
4500Sstevel@tonic-gate 	wsp->walk_callback = (mdb_walk_cb_t)prt_soft_conf_entry;
4510Sstevel@tonic-gate 	return (WALK_NEXT);
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate /*
4550Sstevel@tonic-gate  * At each step, read a kcf_soft_conf_entry_t into our private storage, then
4560Sstevel@tonic-gate  * invoke the callback function.  We terminate when we reach a NULL ce_next
4570Sstevel@tonic-gate  * pointer.
4580Sstevel@tonic-gate  */
4590Sstevel@tonic-gate int
4600Sstevel@tonic-gate soft_conf_walk_step(mdb_walk_state_t *wsp)
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate 	int status;
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)	/* then we're done */
4650Sstevel@tonic-gate 		return (WALK_DONE);
4660Sstevel@tonic-gate #ifdef DEBUG
4670Sstevel@tonic-gate 	else
468*8384SBhargava.Yenduri@Sun.COM 		mdb_printf("DEBUG: wsp->walk_addr == %p\n", wsp->walk_addr);
4690Sstevel@tonic-gate #endif
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	if (mdb_vread(wsp->walk_data, sizeof (kcf_soft_conf_entry_t),
4720Sstevel@tonic-gate 	    wsp->walk_addr) == -1) {
4730Sstevel@tonic-gate 		mdb_warn("failed to read kcf_soft_conf_entry at %p",
4740Sstevel@tonic-gate 		    wsp->walk_addr);
4750Sstevel@tonic-gate 		return (WALK_DONE);
4760Sstevel@tonic-gate 	}
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
4790Sstevel@tonic-gate 	    wsp->walk_cbdata);
4800Sstevel@tonic-gate 
4810Sstevel@tonic-gate 	wsp->walk_addr =
4820Sstevel@tonic-gate 	    (uintptr_t)(((kcf_soft_conf_entry_t *)wsp->walk_data)->ce_next);
4830Sstevel@tonic-gate 	return (status);
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate /*
4870Sstevel@tonic-gate  * The walker's fini function is invoked at the end of each walk.  Since we
4880Sstevel@tonic-gate  * dynamically allocated a kcf_soft_conf_entry_t in soft_conf_walk_init,
4890Sstevel@tonic-gate  * we must free it now.
4900Sstevel@tonic-gate  */
4910Sstevel@tonic-gate void
4920Sstevel@tonic-gate soft_conf_walk_fini(mdb_walk_state_t *wsp)
4930Sstevel@tonic-gate {
4940Sstevel@tonic-gate #ifdef	DEBUG
4950Sstevel@tonic-gate 	mdb_printf("...end of kcf_soft_conf_entry walk\n");
4960Sstevel@tonic-gate #endif
4970Sstevel@tonic-gate 	mdb_free(wsp->walk_data, sizeof (kcf_soft_conf_entry_t));
4980Sstevel@tonic-gate }
4990Sstevel@tonic-gate /* ARGSUSED2 */
5000Sstevel@tonic-gate int
5010Sstevel@tonic-gate kcf_soft_conf_entry(uintptr_t addr, uint_t flags, int argc,
5020Sstevel@tonic-gate     const mdb_arg_t *argv)
5030Sstevel@tonic-gate {
5040Sstevel@tonic-gate 	kcf_soft_conf_entry_t entry;
5050Sstevel@tonic-gate 	kcf_soft_conf_entry_t *ptr;
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == DCMD_ADDRSPEC) {
5080Sstevel@tonic-gate 		if (addr == NULL) 	/* not allowed with DCMD_ADDRSPEC */
5090Sstevel@tonic-gate 			return (DCMD_USAGE);
5100Sstevel@tonic-gate 		else
5110Sstevel@tonic-gate 			ptr = (kcf_soft_conf_entry_t *)addr;
5120Sstevel@tonic-gate 	} else if (mdb_readsym(&ptr, sizeof (void *), "soft_config_list")
513*8384SBhargava.Yenduri@Sun.COM 	    == -1) {
514*8384SBhargava.Yenduri@Sun.COM 		mdb_warn("cannot read soft_config_list");
515*8384SBhargava.Yenduri@Sun.COM 		return (DCMD_ERR);
5160Sstevel@tonic-gate 	} else
5170Sstevel@tonic-gate 		mdb_printf("soft_config_list = %p\n", ptr);
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate 	if (ptr == NULL)
5200Sstevel@tonic-gate 		return (DCMD_OK);
5210Sstevel@tonic-gate 
5220Sstevel@tonic-gate 	if (mdb_vread(&entry, sizeof (kcf_soft_conf_entry_t), (uintptr_t)ptr)
5230Sstevel@tonic-gate 	    == -1) {
524*8384SBhargava.Yenduri@Sun.COM 		mdb_warn("cannot read at address %p", (uintptr_t)ptr);
525*8384SBhargava.Yenduri@Sun.COM 		return (DCMD_ERR);
5260Sstevel@tonic-gate 	}
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	/* this could change in the future to have more than one ret val */
5290Sstevel@tonic-gate 	if (prt_soft_conf_entry(ptr, &entry, NULL) != WALK_ERR)
5300Sstevel@tonic-gate 		return (DCMD_OK);
5310Sstevel@tonic-gate 	return (DCMD_ERR);
5320Sstevel@tonic-gate }
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate /* ARGSUSED1 */
5350Sstevel@tonic-gate int
5360Sstevel@tonic-gate kcf_policy_desc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5370Sstevel@tonic-gate {
5380Sstevel@tonic-gate 	kcf_policy_desc_t  desc;
5390Sstevel@tonic-gate 	char name[MAXNAMELEN + 1];
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) != DCMD_ADDRSPEC)
5430Sstevel@tonic-gate 		return (DCMD_USAGE);
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	if (mdb_vread(&desc, sizeof (kcf_policy_desc_t), (uintptr_t)addr)
5460Sstevel@tonic-gate 	    == -1) {
5470Sstevel@tonic-gate 		mdb_warn("Could not read kcf_policy_desc_t at %p\n", addr);
5480Sstevel@tonic-gate 		return (DCMD_ERR);
5490Sstevel@tonic-gate 	}
5500Sstevel@tonic-gate 	mdb_printf("pd_prov_type:  %s",
551*8384SBhargava.Yenduri@Sun.COM 	    desc.pd_prov_type == CRYPTO_HW_PROVIDER ? "CRYPTO_HW_PROVIDER" :
552*8384SBhargava.Yenduri@Sun.COM 	    "CRYPTO_SW_PROVIDER");
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 	if (desc.pd_name == NULL)
5550Sstevel@tonic-gate 		mdb_printf("\tpd_name: NULL\n");
5560Sstevel@tonic-gate 	else if (mdb_readstr(name, MAXNAMELEN, (uintptr_t)desc.pd_name)
5570Sstevel@tonic-gate 	    == -1)
5580Sstevel@tonic-gate 		mdb_printf("could not read pd_name from %p\n",
5590Sstevel@tonic-gate 		    desc.pd_name);
5600Sstevel@tonic-gate 	else
5610Sstevel@tonic-gate 		mdb_printf("\tpd_name: %s\n", name);
5620Sstevel@tonic-gate 
5630Sstevel@tonic-gate 	mdb_printf("pd_instance: %d ", desc.pd_instance);
5640Sstevel@tonic-gate 	mdb_printf("\t\tpd_refcnt: %d\n", desc.pd_refcnt);
5650Sstevel@tonic-gate 	mdb_printf("pd_mutex: %p", desc.pd_mutex);
5660Sstevel@tonic-gate 	mdb_printf("\t\tpd_disabled_count: %d", desc.pd_disabled_count);
5670Sstevel@tonic-gate 	mdb_printf("\npd_disabled_mechs:\n");
5680Sstevel@tonic-gate 	mdb_inc_indent(4);
5690Sstevel@tonic-gate 	prt_mechs(desc.pd_disabled_count, desc.pd_disabled_mechs);
5700Sstevel@tonic-gate 	mdb_dec_indent(4);
5710Sstevel@tonic-gate 	return (DCMD_OK);
5720Sstevel@tonic-gate }
573