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