xref: /titanic_41/usr/src/cmd/mdb/common/modules/crypto/impl.c (revision cde2885fdf538266ee2a3b08dee2d5075ce8fa2b)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * mdb dcmds for selected structures from
28  * usr/src/uts/common/sys/crypto/impl.h
29  */
30 #include <stdio.h>
31 #include <sys/mdb_modapi.h>
32 #include <sys/modctl.h>
33 #include <sys/types.h>
34 #include <sys/crypto/api.h>
35 #include <sys/crypto/common.h>
36 #include <sys/crypto/impl.h>
37 #include "crypto_cmds.h"
38 
39 int
40 kcf_sched_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
41 {
42 	kcf_sched_info_t sched;
43 	kcf_sched_info_t *sinfo = &sched;
44 
45 	if (!(flags & DCMD_ADDRSPEC)) {
46 		if ((argc == 1) && (argv->a_type == MDB_TYPE_IMMEDIATE))
47 			sinfo = (kcf_sched_info_t *)(uintptr_t)argv->a_un.a_val;
48 		else
49 			return (DCMD_USAGE);
50 	} else if (addr == NULL)	/* not allowed with DCMD_ADDRSPEC */
51 		return (DCMD_USAGE);
52 	else {
53 		if (mdb_vread(sinfo, sizeof (kcf_sched_info_t), addr) == -1) {
54 			mdb_warn("cannot read %p", addr);
55 			return (DCMD_ERR);
56 		}
57 	}
58 	mdb_printf("ks_ndispatches:\t%llu\n", sinfo->ks_ndispatches);
59 	mdb_printf("ks_nfails:\t%llu\n", sinfo->ks_nfails);
60 	mdb_printf("ks_nbusy_rval:\t%llu\n", sinfo->ks_nbusy_rval);
61 	mdb_printf("ks_ntaskq:\t%p\n", sinfo->ks_taskq);
62 	return (DCMD_OK);
63 }
64 
65 static const char *prov_states[] = {
66 	"none",
67 	"KCF_PROV_ALLOCATED",
68 	"KCF_PROV_UNVERIFIED",
69 	"KCF_PROV_VERIFICATION_FAILED",
70 	"KCF_PROV_READY",
71 	"KCF_PROV_BUSY",
72 	"KCF_PROV_FAILED",
73 	"KCF_PROV_DISABLED",
74 	"KCF_PROV_REMOVED",
75 	"KCF_PROV_FREED"
76 };
77 
78 static void
79 pr_kstat_named(kstat_named_t *ks)
80 {
81 	mdb_inc_indent(4);
82 
83 	mdb_printf("name = %s\n", ks->name);
84 	mdb_printf("value = ");
85 
86 	/*
87 	 * The only data type used for the provider kstats is uint64.
88 	 */
89 	switch (ks->data_type) {
90 	case KSTAT_DATA_UINT64:
91 #if defined(_LP64) || defined(_LONGLONG_TYPE)
92 		mdb_printf("%llu\n", ks->value.ui64);
93 #endif
94 		break;
95 	default:
96 		mdb_warn("Incorrect data type for kstat.\n");
97 	}
98 
99 	mdb_dec_indent(4);
100 }
101 
102 /*ARGSUSED*/
103 int
104 kcf_provider_desc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
105 {
106 	kcf_provider_desc_t desc;
107 	kcf_provider_desc_t *ptr;
108 	char string[MAXNAMELEN + 1];
109 	int i, j;
110 	crypto_mech_info_t *mech_pointer;
111 	mdb_arg_t arg;
112 
113 	if ((flags & DCMD_ADDRSPEC) != DCMD_ADDRSPEC)
114 		return (DCMD_USAGE);
115 	ptr = (kcf_provider_desc_t *)addr;
116 
117 #ifdef DEBUG
118 	mdb_printf("DEBUG: reading kcf_provider_desc at %p\n", ptr);
119 #endif
120 
121 	if (mdb_vread(&desc, sizeof (kcf_provider_desc_t), (uintptr_t)ptr)
122 	    == -1) {
123 		mdb_warn("cannot read at address %p", (uintptr_t)ptr);
124 		return (DCMD_ERR);
125 	}
126 	mdb_printf("%<b>kcf_provider_desc at %p%</b>\n", ptr);
127 
128 	switch (desc.pd_prov_type) {
129 	case CRYPTO_HW_PROVIDER:
130 		mdb_printf("pd_prov_type:\t\tCRYPTO_HW_PROVIDER\n");
131 		break;
132 	case CRYPTO_SW_PROVIDER:
133 		mdb_printf("pd_prov_type:\t\tCRYPTO_SW_PROVIDER\n");
134 		break;
135 	case CRYPTO_LOGICAL_PROVIDER:
136 		mdb_printf("pd_prov_type:\t\tCRYPTO_LOGICAL_PROVIDER\n");
137 		break;
138 	default:
139 		mdb_printf("bad pd_prov_type:\t%d\n", desc.pd_prov_type);
140 	}
141 
142 	mdb_printf("pd_prov_handle:\t\t%p\n", desc.pd_prov_handle);
143 	mdb_printf("pd_kcf_prov_handle:\t%u\n", desc.pd_kcf_prov_handle);
144 	mdb_printf("pd_prov_id:\t\t%u\n", desc.pd_prov_id);
145 	if (desc.pd_description == NULL)
146 		mdb_printf("pd_description:\t\tNULL\n");
147 	else if (mdb_readstr(string, MAXNAMELEN + 1,
148 	    (uintptr_t)desc.pd_description) == -1) {
149 		mdb_warn("cannot read %p", desc.pd_description);
150 	} else
151 		mdb_printf("pd_description:\t\t%s\n", string);
152 
153 	mdb_printf("pd_ops_vector:\t\t%p\n", desc.pd_ops_vector);
154 	mdb_printf("pd_mech_list_count:\t%u\n", desc.pd_mech_list_count);
155 	/* mechanisms */
156 	mdb_inc_indent(4);
157 	for (i = 0; i < desc.pd_mech_list_count; i++) {
158 		mech_pointer = desc.pd_mechanisms + i;
159 		mdb_call_dcmd("crypto_mech_info",
160 		    (uintptr_t)mech_pointer, DCMD_ADDRSPEC, 0, NULL);
161 	}
162 	mdb_dec_indent(4);
163 	mdb_printf("pd_mech_indx:\n");
164 	mdb_inc_indent(8);
165 	for (i = 0; i < KCF_OPS_CLASSSIZE; i++) {
166 		for (j = 0; j < KCF_MAXMECHTAB; j++) {
167 			if (desc.pd_mech_indx[i][j] == KCF_INVALID_INDX)
168 				mdb_printf("N ");
169 			else
170 				mdb_printf("%u ", desc.pd_mech_indx[i][j]);
171 		}
172 		mdb_printf("\n");
173 	}
174 	mdb_dec_indent(8);
175 	mdb_printf("pd_ks_data.ps_ops_total:\n", desc.pd_ks_data.ps_ops_total);
176 	pr_kstat_named(&desc.pd_ks_data.ps_ops_total);
177 	mdb_printf("pd_ks_data.ps_ops_passed:\n",
178 	    desc.pd_ks_data.ps_ops_passed);
179 	pr_kstat_named(&desc.pd_ks_data.ps_ops_passed);
180 	mdb_printf("pd_ks_data.ps_ops_failed:\n",
181 	    desc.pd_ks_data.ps_ops_failed);
182 	pr_kstat_named(&desc.pd_ks_data.ps_ops_failed);
183 	mdb_printf("pd_ks_data.ps_ops_busy_rval:\n",
184 	    desc.pd_ks_data.ps_ops_busy_rval);
185 	pr_kstat_named(&desc.pd_ks_data.ps_ops_busy_rval);
186 
187 	mdb_printf("pd_kstat:\t\t%p\n", desc.pd_kstat);
188 	mdb_printf("kcf_sched_info:\n");
189 	/* print pd_sched_info via existing function */
190 	mdb_inc_indent(8);
191 	arg.a_type = MDB_TYPE_IMMEDIATE;
192 	arg.a_un.a_val = (uintmax_t)(uintptr_t)&desc.pd_sched_info;
193 	mdb_call_dcmd("kcf_sched_info", (uintptr_t)NULL, 0, 1, &arg);
194 	mdb_dec_indent(8);
195 
196 	mdb_printf("pd_refcnt:\t\t%u\n", desc.pd_refcnt);
197 	if (desc.pd_name == NULL)
198 		mdb_printf("pd_name:\t\t NULL\n");
199 	else if (mdb_readstr(string, MAXNAMELEN + 1, (uintptr_t)desc.pd_name)
200 	    == -1)
201 		mdb_warn("could not read pd_name from %X\n", desc.pd_name);
202 	else
203 		mdb_printf("pd_name:\t\t%s\n", string);
204 
205 	mdb_printf("pd_instance:\t\t%u\n", desc.pd_instance);
206 	mdb_printf("pd_module_id:\t\t%d\n", desc.pd_module_id);
207 	mdb_printf("pd_mctlp:\t\t%p\n", desc.pd_mctlp);
208 	mdb_printf("pd_sid:\t\t\t%u\n", desc.pd_sid);
209 	mdb_printf("pd_lock:\t\t%p\n", desc.pd_lock);
210 	if (desc.pd_state < KCF_PROV_ALLOCATED ||
211 	    desc.pd_state > KCF_PROV_FREED)
212 		mdb_printf("pd_state is invalid:\t%d\n", desc.pd_state);
213 	else
214 		mdb_printf("pd_state:\t%s\n", prov_states[desc.pd_state]);
215 
216 	mdb_printf("pd_resume_cv:\t\t%hd\n", desc.pd_resume_cv._opaque);
217 	mdb_printf("pd_remove_cv:\t\t%hd\n", desc.pd_remove_cv._opaque);
218 	mdb_printf("pd_flags:\t\t%s %s %s %s %s\n",
219 	    (desc.pd_flags & CRYPTO_HIDE_PROVIDER) ?
220 	    "CRYPTO_HIDE_PROVIDER" : " ",
221 	    (desc.pd_flags & CRYPTO_HASH_NO_UPDATE) ?
222 	    "CRYPTO_HASH_NO_UPDATE" : " ",
223 	    (desc.pd_flags & CRYPTO_SYNCHRONOUS) ?
224 	    "CRYPTO_SYNCHRONOUS" : " ",
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