1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * mdb dcmds for selected structures from
31*0Sstevel@tonic-gate  * usr/src/uts/common/sys/crypto/impl.h
32*0Sstevel@tonic-gate  */
33*0Sstevel@tonic-gate #include <stdio.h>
34*0Sstevel@tonic-gate #include <sys/mdb_modapi.h>
35*0Sstevel@tonic-gate #include <sys/modctl.h>
36*0Sstevel@tonic-gate #include <sys/types.h>
37*0Sstevel@tonic-gate #include <sys/crypto/api.h>
38*0Sstevel@tonic-gate #include <sys/crypto/common.h>
39*0Sstevel@tonic-gate #include <sys/crypto/impl.h>
40*0Sstevel@tonic-gate #include "crypto_cmds.h"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate int
43*0Sstevel@tonic-gate kcf_sched_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
44*0Sstevel@tonic-gate {
45*0Sstevel@tonic-gate 	kcf_sched_info_t sched;
46*0Sstevel@tonic-gate 	kcf_sched_info_t *sinfo = &sched;
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
49*0Sstevel@tonic-gate 		if ((argc == 1) && (argv->a_type == MDB_TYPE_IMMEDIATE))
50*0Sstevel@tonic-gate 			sinfo = (kcf_sched_info_t *)(uintptr_t)argv->a_un.a_val;
51*0Sstevel@tonic-gate 		else
52*0Sstevel@tonic-gate 			return (DCMD_USAGE);
53*0Sstevel@tonic-gate 	} else if (addr == NULL)	/* not allowed with DCMD_ADDRSPEC */
54*0Sstevel@tonic-gate 		return (DCMD_USAGE);
55*0Sstevel@tonic-gate 	else {
56*0Sstevel@tonic-gate 		if (mdb_vread(sinfo, sizeof (kcf_sched_info_t), addr) == -1) {
57*0Sstevel@tonic-gate 			mdb_warn("cannot read %p", addr);
58*0Sstevel@tonic-gate 			return (DCMD_ERR);
59*0Sstevel@tonic-gate 		}
60*0Sstevel@tonic-gate 	}
61*0Sstevel@tonic-gate 	mdb_printf("ks_ndispatches:\t%llu\n", sinfo->ks_ndispatches);
62*0Sstevel@tonic-gate 	mdb_printf("ks_nfails:\t%llu\n", sinfo->ks_nfails);
63*0Sstevel@tonic-gate 	mdb_printf("ks_nbusy_rval:\t%llu\n", sinfo->ks_nbusy_rval);
64*0Sstevel@tonic-gate 	mdb_printf("ks_ntaskq:\t%p\n", sinfo->ks_taskq);
65*0Sstevel@tonic-gate 	return (DCMD_OK);
66*0Sstevel@tonic-gate }
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate static const char *prov_states[] = {
69*0Sstevel@tonic-gate 	"none",
70*0Sstevel@tonic-gate 	"KCF_PROV_ALLOCATED",
71*0Sstevel@tonic-gate 	"KCF_PROV_UNVERIFIED",
72*0Sstevel@tonic-gate 	"KCF_PROV_READY",
73*0Sstevel@tonic-gate 	"KCF_PROV_BUSY",
74*0Sstevel@tonic-gate 	"KCF_PROV_FAILED",
75*0Sstevel@tonic-gate 	"KCF_PROV_DISABLED",
76*0Sstevel@tonic-gate 	"KCF_PROV_REMOVED",
77*0Sstevel@tonic-gate 	"KCF_PROV_FREED"
78*0Sstevel@tonic-gate };
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate static void
81*0Sstevel@tonic-gate pr_kstat_named(kstat_named_t *ks)
82*0Sstevel@tonic-gate {
83*0Sstevel@tonic-gate 	mdb_inc_indent(4);
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate 	mdb_printf("name = %s\n", ks->name);
86*0Sstevel@tonic-gate 	mdb_printf("value = ");
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 	/*
89*0Sstevel@tonic-gate 	 * The only data type used for the provider kstats is uint64.
90*0Sstevel@tonic-gate 	 */
91*0Sstevel@tonic-gate 	switch (ks->data_type) {
92*0Sstevel@tonic-gate 	case KSTAT_DATA_UINT64:
93*0Sstevel@tonic-gate #if defined(_LP64) || defined(_LONGLONG_TYPE)
94*0Sstevel@tonic-gate 		mdb_printf("%llu\n", ks->value.ui64);
95*0Sstevel@tonic-gate #endif
96*0Sstevel@tonic-gate 		break;
97*0Sstevel@tonic-gate 	default:
98*0Sstevel@tonic-gate 		mdb_warn("Incorrect data type for kstat.\n");
99*0Sstevel@tonic-gate 	}
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	mdb_dec_indent(4);
102*0Sstevel@tonic-gate }
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate /*ARGSUSED*/
105*0Sstevel@tonic-gate int
106*0Sstevel@tonic-gate kcf_provider_desc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
107*0Sstevel@tonic-gate {
108*0Sstevel@tonic-gate 	kcf_provider_desc_t desc;
109*0Sstevel@tonic-gate 	kcf_provider_desc_t *ptr;
110*0Sstevel@tonic-gate 	char string[MAXNAMELEN + 1];
111*0Sstevel@tonic-gate 	int i, j;
112*0Sstevel@tonic-gate 	crypto_mech_info_t *mech_pointer;
113*0Sstevel@tonic-gate 	mdb_arg_t arg;
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) != DCMD_ADDRSPEC)
116*0Sstevel@tonic-gate 		return (DCMD_USAGE);
117*0Sstevel@tonic-gate 	ptr = (kcf_provider_desc_t *)addr;
118*0Sstevel@tonic-gate 
119*0Sstevel@tonic-gate #ifdef DEBUG
120*0Sstevel@tonic-gate 	mdb_printf("DEBUG: reading kcf_provider_desc at %p\n", ptr);
121*0Sstevel@tonic-gate #endif
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 	if (mdb_vread(&desc, sizeof (kcf_provider_desc_t), (uintptr_t)ptr)
124*0Sstevel@tonic-gate 	    == -1) {
125*0Sstevel@tonic-gate 		    mdb_warn("cannot read at address %p", (uintptr_t)ptr);
126*0Sstevel@tonic-gate 		    return (DCMD_ERR);
127*0Sstevel@tonic-gate 	}
128*0Sstevel@tonic-gate 	mdb_printf("%<b>kcf_provider_desc at %p%</b>\n", ptr);
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate 	switch (desc.pd_prov_type) {
131*0Sstevel@tonic-gate 	case CRYPTO_HW_PROVIDER:
132*0Sstevel@tonic-gate 		mdb_printf("pd_prov_type:\t\tCRYPTO_HW_PROVIDER\n");
133*0Sstevel@tonic-gate 		break;
134*0Sstevel@tonic-gate 	case CRYPTO_SW_PROVIDER:
135*0Sstevel@tonic-gate 		mdb_printf("pd_prov_type:\t\tCRYPTO_SW_PROVIDER\n");
136*0Sstevel@tonic-gate 		break;
137*0Sstevel@tonic-gate 	case CRYPTO_LOGICAL_PROVIDER:
138*0Sstevel@tonic-gate 		mdb_printf("pd_prov_type:\t\tCRYPTO_LOGICAL_PROVIDER\n");
139*0Sstevel@tonic-gate 		break;
140*0Sstevel@tonic-gate 	default:
141*0Sstevel@tonic-gate 		mdb_printf("bad pd_prov_type:\t%d\n", desc.pd_prov_type);
142*0Sstevel@tonic-gate 	}
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate 	mdb_printf("pd_prov_handle:\t\t%p\n", desc.pd_prov_handle);
145*0Sstevel@tonic-gate 	mdb_printf("pd_kcf_prov_handle:\t%u\n", desc.pd_kcf_prov_handle);
146*0Sstevel@tonic-gate 	mdb_printf("pd_prov_id:\t\t%u\n", desc.pd_prov_id);
147*0Sstevel@tonic-gate 	if (desc.pd_description == NULL)
148*0Sstevel@tonic-gate 		mdb_printf("pd_description:\t\tNULL\n");
149*0Sstevel@tonic-gate 	else if (mdb_readstr(string, MAXNAMELEN + 1,
150*0Sstevel@tonic-gate 		    (uintptr_t)desc.pd_description) == -1) {
151*0Sstevel@tonic-gate 		mdb_warn("cannot read %p", desc.pd_description);
152*0Sstevel@tonic-gate 	} else
153*0Sstevel@tonic-gate 	    mdb_printf("pd_description:\t\t%s\n", string);
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	mdb_printf("pd_ops_vector:\t\t%p\n", desc.pd_ops_vector);
156*0Sstevel@tonic-gate 	mdb_printf("pd_mech_list_count:\t%u\n", desc.pd_mech_list_count);
157*0Sstevel@tonic-gate 	/* mechanisms */
158*0Sstevel@tonic-gate 	mdb_inc_indent(4);
159*0Sstevel@tonic-gate 	for (i = 0; i < desc.pd_mech_list_count; i++) {
160*0Sstevel@tonic-gate 		mech_pointer = desc.pd_mechanisms + i;
161*0Sstevel@tonic-gate 		mdb_call_dcmd("crypto_mech_info",
162*0Sstevel@tonic-gate 			(uintptr_t)mech_pointer, DCMD_ADDRSPEC, 0, NULL);
163*0Sstevel@tonic-gate 	}
164*0Sstevel@tonic-gate 	mdb_dec_indent(4);
165*0Sstevel@tonic-gate 	mdb_printf("pd_map_mechnums:\n");
166*0Sstevel@tonic-gate 	mdb_inc_indent(8);
167*0Sstevel@tonic-gate 	for (i = 0; i < KCF_OPS_CLASSSIZE; i++) {
168*0Sstevel@tonic-gate 	    for (j = 0; j < KCF_MAXMECHTAB; j++) {
169*0Sstevel@tonic-gate 		mdb_printf("%llu ",
170*0Sstevel@tonic-gate 		    desc.pd_map_mechnums[i][j]);
171*0Sstevel@tonic-gate 	    }
172*0Sstevel@tonic-gate 	    mdb_printf("\n");
173*0Sstevel@tonic-gate 	}
174*0Sstevel@tonic-gate 	mdb_dec_indent(8);
175*0Sstevel@tonic-gate 	mdb_printf("pd_stats:\t\t%p\n", desc.pd_stats);
176*0Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_total:\n", desc.pd_ks_data.ps_ops_total);
177*0Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_total);
178*0Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_passed:\n",
179*0Sstevel@tonic-gate 	    desc.pd_ks_data.ps_ops_passed);
180*0Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_passed);
181*0Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_failed:\n",
182*0Sstevel@tonic-gate 	    desc.pd_ks_data.ps_ops_failed);
183*0Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_failed);
184*0Sstevel@tonic-gate 	mdb_printf("pd_ks_data.ps_ops_busy_rval:\n",
185*0Sstevel@tonic-gate 	    desc.pd_ks_data.ps_ops_busy_rval);
186*0Sstevel@tonic-gate 	pr_kstat_named(&desc.pd_ks_data.ps_ops_busy_rval);
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate 	mdb_printf("pd_kstat:\t\t%p\n", desc.pd_kstat);
189*0Sstevel@tonic-gate 	mdb_printf("kcf_sched_info:\n");
190*0Sstevel@tonic-gate 	/* print pd_sched_info via existing function */
191*0Sstevel@tonic-gate 	mdb_inc_indent(8);
192*0Sstevel@tonic-gate 	arg.a_type = MDB_TYPE_IMMEDIATE;
193*0Sstevel@tonic-gate 	arg.a_un.a_val = (uintmax_t)(uintptr_t)&desc.pd_sched_info;
194*0Sstevel@tonic-gate 	mdb_call_dcmd("kcf_sched_info", (uintptr_t)NULL, 0, 1, &arg);
195*0Sstevel@tonic-gate 	mdb_dec_indent(8);
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	mdb_printf("pd_refcnt:\t\t%u\n", desc.pd_refcnt);
198*0Sstevel@tonic-gate 	if (desc.pd_name == NULL)
199*0Sstevel@tonic-gate 	    mdb_printf("pd_name:\t\t NULL\n");
200*0Sstevel@tonic-gate 	else if (mdb_readstr(string, MAXNAMELEN + 1, (uintptr_t)desc.pd_name)
201*0Sstevel@tonic-gate 		== -1)
202*0Sstevel@tonic-gate 		mdb_warn("could not read pd_name from %X\n", desc.pd_name);
203*0Sstevel@tonic-gate 	else
204*0Sstevel@tonic-gate 	    mdb_printf("pd_name:\t\t%s\n", string);
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	mdb_printf("pd_instance:\t\t%u\n", desc.pd_instance);
207*0Sstevel@tonic-gate 	mdb_printf("pd_module_id:\t\t%d\n", desc.pd_module_id);
208*0Sstevel@tonic-gate 	mdb_printf("pd_mctlp:\t\t%p\n", desc.pd_mctlp);
209*0Sstevel@tonic-gate 	mdb_printf("pd_sid:\t\t\t%u\n", desc.pd_sid);
210*0Sstevel@tonic-gate 	mdb_printf("pd_lock:\t\t%p\n", desc.pd_lock);
211*0Sstevel@tonic-gate 	if (desc.pd_state < KCF_PROV_ALLOCATED ||
212*0Sstevel@tonic-gate 	    desc.pd_state > KCF_PROV_FREED)
213*0Sstevel@tonic-gate 		mdb_printf("pd_state is invalid:\t%d\n", desc.pd_state);
214*0Sstevel@tonic-gate 	else
215*0Sstevel@tonic-gate 		mdb_printf("pd_state:\t%s\n", prov_states[desc.pd_state]);
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate 	mdb_printf("pd_resume_cv:\t\t%hd\n", desc.pd_resume_cv._opaque);
218*0Sstevel@tonic-gate 	mdb_printf("pd_remove_cv:\t\t%hd\n", desc.pd_remove_cv._opaque);
219*0Sstevel@tonic-gate 	mdb_printf("pd_restricted:\t\t%s\n",
220*0Sstevel@tonic-gate 	    desc.pd_restricted == B_FALSE ? "B_FALSE" : "B_TRUE");
221*0Sstevel@tonic-gate 	mdb_printf("pd_provider_list:\t%p\n", desc.pd_provider_list);
222*0Sstevel@tonic-gate 	return (DCMD_OK);
223*0Sstevel@tonic-gate }
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate #define	GOT_NONE	(-2)
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate /*ARGSUSED*/
228*0Sstevel@tonic-gate int
229*0Sstevel@tonic-gate prov_tab(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
230*0Sstevel@tonic-gate {
231*0Sstevel@tonic-gate 	kcf_provider_desc_t **tab;
232*0Sstevel@tonic-gate 	kcf_provider_desc_t desc;
233*0Sstevel@tonic-gate 	kcf_provider_desc_t *ptr;
234*0Sstevel@tonic-gate 	uint_t prov_tab_max;
235*0Sstevel@tonic-gate 	int i;
236*0Sstevel@tonic-gate 	int gotzero = GOT_NONE;
237*0Sstevel@tonic-gate 	char string[MAXNAMELEN + 1];
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == DCMD_ADDRSPEC) {
240*0Sstevel@tonic-gate 		return (DCMD_USAGE);
241*0Sstevel@tonic-gate 	} else if (mdb_readsym(&ptr, sizeof (void *), "prov_tab")
242*0Sstevel@tonic-gate 	    == -1) {
243*0Sstevel@tonic-gate 		mdb_warn("cannot read prov_tab");
244*0Sstevel@tonic-gate 		return (DCMD_ERR);
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 	} else if (mdb_readvar(&prov_tab_max, "prov_tab_max") == -1) {
247*0Sstevel@tonic-gate 		mdb_warn("cannot read prov_tab_max");
248*0Sstevel@tonic-gate 		return (DCMD_ERR);
249*0Sstevel@tonic-gate 	}
250*0Sstevel@tonic-gate 	mdb_printf("%<b>prov_tab = %p%</b>\n", ptr);
251*0Sstevel@tonic-gate 	tab = mdb_zalloc(prov_tab_max * sizeof (kcf_provider_desc_t *),
252*0Sstevel@tonic-gate 	    UM_SLEEP| UM_GC);
253*0Sstevel@tonic-gate 
254*0Sstevel@tonic-gate #ifdef DEBUG
255*0Sstevel@tonic-gate 	mdb_printf("DEBUG: tab = %p, prov_tab_max = %d\n", tab, prov_tab_max);
256*0Sstevel@tonic-gate #endif
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate 	if (mdb_vread(tab, prov_tab_max * sizeof (kcf_provider_desc_t *),
259*0Sstevel@tonic-gate 	    (uintptr_t)ptr) == -1) {
260*0Sstevel@tonic-gate 		mdb_warn("cannot read prov_tab");
261*0Sstevel@tonic-gate 		return (DCMD_ERR);
262*0Sstevel@tonic-gate 	}
263*0Sstevel@tonic-gate #ifdef DEBUG
264*0Sstevel@tonic-gate 	mdb_printf("DEBUG: got past mdb_vread of tab\n");
265*0Sstevel@tonic-gate 	mdb_printf("DEBUG: *tab = %p\n", *tab);
266*0Sstevel@tonic-gate #endif
267*0Sstevel@tonic-gate 	for (i = 0;  i <  prov_tab_max; i++) {
268*0Sstevel@tonic-gate 		/* save space, only print range for long list of nulls */
269*0Sstevel@tonic-gate 		if (tab[i] == NULL) {
270*0Sstevel@tonic-gate 			if (gotzero == GOT_NONE) {
271*0Sstevel@tonic-gate 			    mdb_printf("prov_tab[%d", i);
272*0Sstevel@tonic-gate 			    gotzero = i;
273*0Sstevel@tonic-gate 			}
274*0Sstevel@tonic-gate 		} else {
275*0Sstevel@tonic-gate 			/* first non-null in awhile, print index of prev null */
276*0Sstevel@tonic-gate 			if (gotzero != GOT_NONE) {
277*0Sstevel@tonic-gate 				if (gotzero == (i - 1))
278*0Sstevel@tonic-gate 					mdb_printf("] = NULL\n", i - 1);
279*0Sstevel@tonic-gate 				else
280*0Sstevel@tonic-gate 					mdb_printf(" - %d] = NULL\n", i - 1);
281*0Sstevel@tonic-gate 				gotzero = GOT_NONE;
282*0Sstevel@tonic-gate 			}
283*0Sstevel@tonic-gate 			/* interesting value, print it */
284*0Sstevel@tonic-gate 			mdb_printf("prov_tab[%d] = %p ", i, tab[i]);
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate 			if (mdb_vread(&desc, sizeof (kcf_provider_desc_t),
287*0Sstevel@tonic-gate 			    (uintptr_t)tab[i]) == -1) {
288*0Sstevel@tonic-gate 				mdb_warn("cannot read at address %p",
289*0Sstevel@tonic-gate 				    (uintptr_t)tab[i]);
290*0Sstevel@tonic-gate 				return (DCMD_ERR);
291*0Sstevel@tonic-gate 			}
292*0Sstevel@tonic-gate 
293*0Sstevel@tonic-gate 			(void) mdb_readstr(string, MAXNAMELEN + 1,
294*0Sstevel@tonic-gate 			    (uintptr_t)desc.pd_name);
295*0Sstevel@tonic-gate 			mdb_printf("(%s\t%s)\n", string,
296*0Sstevel@tonic-gate 			    prov_states[desc.pd_state]);
297*0Sstevel@tonic-gate 		}
298*0Sstevel@tonic-gate 	}
299*0Sstevel@tonic-gate 	/* if we've printed the first of many nulls but left the brace open */
300*0Sstevel@tonic-gate 	if ((i > 0) && (tab[i-1] == NULL)) {
301*0Sstevel@tonic-gate 		if (gotzero == GOT_NONE)
302*0Sstevel@tonic-gate 			mdb_printf("] = NULL\n");
303*0Sstevel@tonic-gate 		else
304*0Sstevel@tonic-gate 			mdb_printf(" - %d] = NULL\n", i - 1);
305*0Sstevel@tonic-gate 	}
306*0Sstevel@tonic-gate 
307*0Sstevel@tonic-gate 	return (DCMD_OK);
308*0Sstevel@tonic-gate }
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate /*ARGSUSED*/
311*0Sstevel@tonic-gate int
312*0Sstevel@tonic-gate policy_tab(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
313*0Sstevel@tonic-gate {
314*0Sstevel@tonic-gate 	kcf_policy_desc_t **tab;
315*0Sstevel@tonic-gate 	kcf_policy_desc_t *ptr;
316*0Sstevel@tonic-gate 	uint_t policy_tab_max;
317*0Sstevel@tonic-gate 	int num, i;
318*0Sstevel@tonic-gate 	int gotzero = GOT_NONE;
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == DCMD_ADDRSPEC) {
321*0Sstevel@tonic-gate 		return (DCMD_USAGE);
322*0Sstevel@tonic-gate 	} else if (mdb_readsym(&ptr, sizeof (void *), "policy_tab")
323*0Sstevel@tonic-gate 	    == -1) {
324*0Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab");
325*0Sstevel@tonic-gate 		return (DCMD_ERR);
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate 	} else if (mdb_readvar(&policy_tab_max, "policy_tab_max") == -1) {
328*0Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab_max");
329*0Sstevel@tonic-gate 		return (DCMD_ERR);
330*0Sstevel@tonic-gate 	}
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 	/* get the current number of descriptors in the table */
333*0Sstevel@tonic-gate 	if (mdb_readvar(&num, "policy_tab_num") == -1) {
334*0Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab_num");
335*0Sstevel@tonic-gate 		return (DCMD_ERR);
336*0Sstevel@tonic-gate 	}
337*0Sstevel@tonic-gate 	mdb_printf("%<b>policy_tab = %p%</b> \tpolicy_tab_num = %d\n",
338*0Sstevel@tonic-gate 	    ptr, num);
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate 	tab = mdb_zalloc(policy_tab_max * sizeof (kcf_policy_desc_t *),
341*0Sstevel@tonic-gate 	    UM_SLEEP| UM_GC);
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate 	if (mdb_vread(tab, policy_tab_max * sizeof (kcf_policy_desc_t *),
344*0Sstevel@tonic-gate 	    (uintptr_t)ptr) == -1) {
345*0Sstevel@tonic-gate 		mdb_warn("cannot read policy_tab");
346*0Sstevel@tonic-gate 		return (DCMD_ERR);
347*0Sstevel@tonic-gate 	}
348*0Sstevel@tonic-gate #ifdef DEBUG
349*0Sstevel@tonic-gate 	mdb_printf("DEBUG: got past mdb_vread of tab\n");
350*0Sstevel@tonic-gate 	mdb_printf("DEBUG: *tab = %p\n", *tab);
351*0Sstevel@tonic-gate #endif
352*0Sstevel@tonic-gate 	for (i = 0;  i < policy_tab_max; i++) {
353*0Sstevel@tonic-gate 		/* save space, only print range for long list of nulls */
354*0Sstevel@tonic-gate 		if (tab[i] == NULL) {
355*0Sstevel@tonic-gate 			if (gotzero == GOT_NONE) {
356*0Sstevel@tonic-gate 			    mdb_printf("policy_tab[%d", i);
357*0Sstevel@tonic-gate 			    gotzero = i;
358*0Sstevel@tonic-gate 			}
359*0Sstevel@tonic-gate 		} else {
360*0Sstevel@tonic-gate 			/* first non-null in awhile, print index of prev null */
361*0Sstevel@tonic-gate 			if (gotzero != GOT_NONE) {
362*0Sstevel@tonic-gate 				if (gotzero == (i - 1))
363*0Sstevel@tonic-gate 					mdb_printf("] = NULL\n", i - 1);
364*0Sstevel@tonic-gate 				else
365*0Sstevel@tonic-gate 					mdb_printf(" - %d] = NULL\n", i - 1);
366*0Sstevel@tonic-gate 				gotzero = GOT_NONE;
367*0Sstevel@tonic-gate 			}
368*0Sstevel@tonic-gate 			/* interesting value, print it */
369*0Sstevel@tonic-gate 			mdb_printf("policy_tab[%d] = %p\n", i, tab[i]);
370*0Sstevel@tonic-gate 		}
371*0Sstevel@tonic-gate 	}
372*0Sstevel@tonic-gate 	/* if we've printed the first of many nulls but left the brace open */
373*0Sstevel@tonic-gate 	if ((i > 0) && (tab[i-1] == NULL)) {
374*0Sstevel@tonic-gate 		if (gotzero == GOT_NONE)
375*0Sstevel@tonic-gate 			mdb_printf("] = NULL\n");
376*0Sstevel@tonic-gate 		else
377*0Sstevel@tonic-gate 			mdb_printf(" - %d] = NULL\n", i - 1);
378*0Sstevel@tonic-gate 	}
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate 	return (DCMD_OK);
381*0Sstevel@tonic-gate }
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate static void
384*0Sstevel@tonic-gate prt_mechs(int count, crypto_mech_name_t *mechs)
385*0Sstevel@tonic-gate {
386*0Sstevel@tonic-gate 	int i;
387*0Sstevel@tonic-gate 	char name[CRYPTO_MAX_MECH_NAME + 1];
388*0Sstevel@tonic-gate 	char name2[CRYPTO_MAX_MECH_NAME + 3];
389*0Sstevel@tonic-gate 
390*0Sstevel@tonic-gate 	for (i = 0; i < count; i++) {
391*0Sstevel@tonic-gate 		if (mdb_readstr(name, CRYPTO_MAX_MECH_NAME,
392*0Sstevel@tonic-gate 		    (uintptr_t)((char *)mechs)) == -1)
393*0Sstevel@tonic-gate 			continue;
394*0Sstevel@tonic-gate 		/* put in quotes */
395*0Sstevel@tonic-gate 		(void) mdb_snprintf(name2, sizeof (name2), "\"%s\"", name);
396*0Sstevel@tonic-gate 		/* yes, length is 32, but then it will wrap */
397*0Sstevel@tonic-gate 		/* this shorter size formats nicely for most cases */
398*0Sstevel@tonic-gate 		mdb_printf("mechs[%d]=%-28s", i, name2);
399*0Sstevel@tonic-gate 		mdb_printf("%s", i%2 ? "\n" : "  "); /* 2-columns */
400*0Sstevel@tonic-gate 		mechs++;
401*0Sstevel@tonic-gate 	}
402*0Sstevel@tonic-gate }
403*0Sstevel@tonic-gate 
404*0Sstevel@tonic-gate /* ARGSUSED2 */
405*0Sstevel@tonic-gate static int
406*0Sstevel@tonic-gate prt_soft_conf_entry(kcf_soft_conf_entry_t *addr, kcf_soft_conf_entry_t *entry,
407*0Sstevel@tonic-gate     void *cbdata)
408*0Sstevel@tonic-gate {
409*0Sstevel@tonic-gate 	char name[MAXNAMELEN + 1];
410*0Sstevel@tonic-gate 
411*0Sstevel@tonic-gate 	mdb_printf("\n%<b>kcf_soft_conf_entry_t at %p:%</b>\n", addr);
412*0Sstevel@tonic-gate 	mdb_printf("ce_next: %p", entry->ce_next);
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 	if (entry->ce_name == NULL)
415*0Sstevel@tonic-gate 		    mdb_printf("\tce_name: NULL\n");
416*0Sstevel@tonic-gate 	else if (mdb_readstr(name, MAXNAMELEN, (uintptr_t)entry->ce_name)
417*0Sstevel@tonic-gate 		    == -1)
418*0Sstevel@tonic-gate 		mdb_printf("could not read ce_name from %p\n",
419*0Sstevel@tonic-gate 			entry->ce_name);
420*0Sstevel@tonic-gate 	else
421*0Sstevel@tonic-gate 		mdb_printf("\tce_name: %s\n", name);
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate 	mdb_printf("ce_count: %d\n", entry->ce_count);
424*0Sstevel@tonic-gate 	prt_mechs(entry->ce_count, entry->ce_mechs);
425*0Sstevel@tonic-gate 	return (WALK_NEXT);
426*0Sstevel@tonic-gate }
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate int
429*0Sstevel@tonic-gate soft_conf_walk_init(mdb_walk_state_t *wsp)
430*0Sstevel@tonic-gate {
431*0Sstevel@tonic-gate 	uintptr_t *soft;
432*0Sstevel@tonic-gate 
433*0Sstevel@tonic-gate 	if (mdb_readsym(&soft, sizeof (kcf_soft_conf_entry_t *),
434*0Sstevel@tonic-gate 	    "soft_config_list") == -1) {
435*0Sstevel@tonic-gate 		mdb_warn("failed to find 'soft_config_list'");
436*0Sstevel@tonic-gate 		return (WALK_ERR);
437*0Sstevel@tonic-gate 	}
438*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)soft;
439*0Sstevel@tonic-gate 	wsp->walk_data = mdb_alloc(sizeof (kcf_soft_conf_entry_t), UM_SLEEP);
440*0Sstevel@tonic-gate 	wsp->walk_callback = (mdb_walk_cb_t)prt_soft_conf_entry;
441*0Sstevel@tonic-gate 	return (WALK_NEXT);
442*0Sstevel@tonic-gate }
443*0Sstevel@tonic-gate 
444*0Sstevel@tonic-gate /*
445*0Sstevel@tonic-gate  * At each step, read a kcf_soft_conf_entry_t into our private storage, then
446*0Sstevel@tonic-gate  * invoke the callback function.  We terminate when we reach a NULL ce_next
447*0Sstevel@tonic-gate  * pointer.
448*0Sstevel@tonic-gate  */
449*0Sstevel@tonic-gate int
450*0Sstevel@tonic-gate soft_conf_walk_step(mdb_walk_state_t *wsp)
451*0Sstevel@tonic-gate {
452*0Sstevel@tonic-gate 	int status;
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)	/* then we're done */
455*0Sstevel@tonic-gate 		return (WALK_DONE);
456*0Sstevel@tonic-gate #ifdef DEBUG
457*0Sstevel@tonic-gate 	else
458*0Sstevel@tonic-gate 	    mdb_printf("DEBUG: wsp->walk_addr == %p\n", wsp->walk_addr);
459*0Sstevel@tonic-gate #endif
460*0Sstevel@tonic-gate 
461*0Sstevel@tonic-gate 	if (mdb_vread(wsp->walk_data, sizeof (kcf_soft_conf_entry_t),
462*0Sstevel@tonic-gate 	    wsp->walk_addr) == -1) {
463*0Sstevel@tonic-gate 		mdb_warn("failed to read kcf_soft_conf_entry at %p",
464*0Sstevel@tonic-gate 		    wsp->walk_addr);
465*0Sstevel@tonic-gate 		return (WALK_DONE);
466*0Sstevel@tonic-gate 	}
467*0Sstevel@tonic-gate 
468*0Sstevel@tonic-gate 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
469*0Sstevel@tonic-gate 	    wsp->walk_cbdata);
470*0Sstevel@tonic-gate 
471*0Sstevel@tonic-gate 	wsp->walk_addr =
472*0Sstevel@tonic-gate 	    (uintptr_t)(((kcf_soft_conf_entry_t *)wsp->walk_data)->ce_next);
473*0Sstevel@tonic-gate 	return (status);
474*0Sstevel@tonic-gate }
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate /*
477*0Sstevel@tonic-gate  * The walker's fini function is invoked at the end of each walk.  Since we
478*0Sstevel@tonic-gate  * dynamically allocated a kcf_soft_conf_entry_t in soft_conf_walk_init,
479*0Sstevel@tonic-gate  * we must free it now.
480*0Sstevel@tonic-gate  */
481*0Sstevel@tonic-gate void
482*0Sstevel@tonic-gate soft_conf_walk_fini(mdb_walk_state_t *wsp)
483*0Sstevel@tonic-gate {
484*0Sstevel@tonic-gate #ifdef	DEBUG
485*0Sstevel@tonic-gate 	mdb_printf("...end of kcf_soft_conf_entry walk\n");
486*0Sstevel@tonic-gate #endif
487*0Sstevel@tonic-gate 	mdb_free(wsp->walk_data, sizeof (kcf_soft_conf_entry_t));
488*0Sstevel@tonic-gate }
489*0Sstevel@tonic-gate /* ARGSUSED2 */
490*0Sstevel@tonic-gate int
491*0Sstevel@tonic-gate kcf_soft_conf_entry(uintptr_t addr, uint_t flags, int argc,
492*0Sstevel@tonic-gate     const mdb_arg_t *argv)
493*0Sstevel@tonic-gate {
494*0Sstevel@tonic-gate 	kcf_soft_conf_entry_t entry;
495*0Sstevel@tonic-gate 	kcf_soft_conf_entry_t *ptr;
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == DCMD_ADDRSPEC) {
498*0Sstevel@tonic-gate 		if (addr == NULL) 	/* not allowed with DCMD_ADDRSPEC */
499*0Sstevel@tonic-gate 			return (DCMD_USAGE);
500*0Sstevel@tonic-gate 		else
501*0Sstevel@tonic-gate 			ptr = (kcf_soft_conf_entry_t *)addr;
502*0Sstevel@tonic-gate 	} else if (mdb_readsym(&ptr, sizeof (void *), "soft_config_list")
503*0Sstevel@tonic-gate 		    == -1) {
504*0Sstevel@tonic-gate 			mdb_warn("cannot read soft_config_list");
505*0Sstevel@tonic-gate 			return (DCMD_ERR);
506*0Sstevel@tonic-gate 	} else
507*0Sstevel@tonic-gate 		mdb_printf("soft_config_list = %p\n", ptr);
508*0Sstevel@tonic-gate 
509*0Sstevel@tonic-gate 	if (ptr == NULL)
510*0Sstevel@tonic-gate 		return (DCMD_OK);
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate 	if (mdb_vread(&entry, sizeof (kcf_soft_conf_entry_t), (uintptr_t)ptr)
513*0Sstevel@tonic-gate 	    == -1) {
514*0Sstevel@tonic-gate 		    mdb_warn("cannot read at address %p", (uintptr_t)ptr);
515*0Sstevel@tonic-gate 		    return (DCMD_ERR);
516*0Sstevel@tonic-gate 	}
517*0Sstevel@tonic-gate 
518*0Sstevel@tonic-gate 	/* this could change in the future to have more than one ret val */
519*0Sstevel@tonic-gate 	if (prt_soft_conf_entry(ptr, &entry, NULL) != WALK_ERR)
520*0Sstevel@tonic-gate 		return (DCMD_OK);
521*0Sstevel@tonic-gate 	return (DCMD_ERR);
522*0Sstevel@tonic-gate }
523*0Sstevel@tonic-gate 
524*0Sstevel@tonic-gate /* ARGSUSED1 */
525*0Sstevel@tonic-gate int
526*0Sstevel@tonic-gate kcf_policy_desc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
527*0Sstevel@tonic-gate {
528*0Sstevel@tonic-gate 	kcf_policy_desc_t  desc;
529*0Sstevel@tonic-gate 	char name[MAXNAMELEN + 1];
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate 
532*0Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) != DCMD_ADDRSPEC)
533*0Sstevel@tonic-gate 		return (DCMD_USAGE);
534*0Sstevel@tonic-gate 
535*0Sstevel@tonic-gate 	if (mdb_vread(&desc, sizeof (kcf_policy_desc_t), (uintptr_t)addr)
536*0Sstevel@tonic-gate 	    == -1) {
537*0Sstevel@tonic-gate 		mdb_warn("Could not read kcf_policy_desc_t at %p\n", addr);
538*0Sstevel@tonic-gate 		return (DCMD_ERR);
539*0Sstevel@tonic-gate 	}
540*0Sstevel@tonic-gate 	mdb_printf("pd_prov_type:  %s",
541*0Sstevel@tonic-gate 	    desc.pd_prov_type == CRYPTO_HW_PROVIDER ? "CRYPTO_HW_PROVIDER"
542*0Sstevel@tonic-gate 		: "CRYPTO_SW_PROVIDER");
543*0Sstevel@tonic-gate 
544*0Sstevel@tonic-gate 	if (desc.pd_name == NULL)
545*0Sstevel@tonic-gate 		mdb_printf("\tpd_name: NULL\n");
546*0Sstevel@tonic-gate 	else if (mdb_readstr(name, MAXNAMELEN, (uintptr_t)desc.pd_name)
547*0Sstevel@tonic-gate 	    == -1)
548*0Sstevel@tonic-gate 		mdb_printf("could not read pd_name from %p\n",
549*0Sstevel@tonic-gate 		    desc.pd_name);
550*0Sstevel@tonic-gate 	else
551*0Sstevel@tonic-gate 		mdb_printf("\tpd_name: %s\n", name);
552*0Sstevel@tonic-gate 
553*0Sstevel@tonic-gate 	mdb_printf("pd_instance: %d ", desc.pd_instance);
554*0Sstevel@tonic-gate 	mdb_printf("\t\tpd_refcnt: %d\n", desc.pd_refcnt);
555*0Sstevel@tonic-gate 	mdb_printf("pd_mutex: %p", desc.pd_mutex);
556*0Sstevel@tonic-gate 	mdb_printf("\t\tpd_disabled_count: %d", desc.pd_disabled_count);
557*0Sstevel@tonic-gate 	mdb_printf("\npd_disabled_mechs:\n");
558*0Sstevel@tonic-gate 	mdb_inc_indent(4);
559*0Sstevel@tonic-gate 	prt_mechs(desc.pd_disabled_count, desc.pd_disabled_mechs);
560*0Sstevel@tonic-gate 	mdb_dec_indent(4);
561*0Sstevel@tonic-gate 	return (DCMD_OK);
562*0Sstevel@tonic-gate }
563