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 /*
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2025 Oxide Computer Company
25 */
26
27 #include <stdio.h>
28 #include <sys/mdb_modapi.h>
29 #include <sys/modctl.h>
30 #include <sys/types.h>
31 #include <sys/crypto/api.h>
32 #include <sys/crypto/common.h>
33 #include <sys/crypto/api.h>
34 #include <sys/crypto/sched_impl.h>
35 #include "crypto_cmds.h"
36
37 static void
prt_an_state(int state)38 prt_an_state(int state)
39 {
40 switch (state) {
41 case REQ_ALLOCATED:
42 mdb_printf("REQ_ALLOCATED ");
43 break;
44 case REQ_WAITING:
45 mdb_printf("REQ_WAITING ");
46 break;
47 case REQ_INPROGRESS:
48 mdb_printf("REQ_INPROGRESS ");
49 break;
50 case REQ_DONE:
51 mdb_printf("REQ_DONE ");
52 break;
53 case REQ_CANCELED:
54 mdb_printf("REQ_CANCELED ");
55 break;
56 default:
57 mdb_printf("? %d ?? ", state);
58 break;
59 }
60 }
61
62
63 static const mdb_bitmask_t call_flags[] = {
64 { "CRYPTO_ALWAYS_QUEUE", CRYPTO_ALWAYS_QUEUE, CRYPTO_ALWAYS_QUEUE },
65 { "CRYPTO_NOTIFY_OPDONE", CRYPTO_NOTIFY_OPDONE, CRYPTO_NOTIFY_OPDONE },
66 { "CRYPTO_SKIP_REQID", CRYPTO_SKIP_REQID, CRYPTO_SKIP_REQID },
67 { NULL, 0, 0 }
68 };
69
70 /*ARGSUSED*/
71 static int
kcf_areq_node_simple(kcf_areq_node_t * areqn)72 kcf_areq_node_simple(kcf_areq_node_t *areqn)
73 {
74 mdb_printf("\nan_type: ");
75 if (areqn->an_type != CRYPTO_ASYNCH)
76 mdb_printf("%-8d ", areqn->an_type);
77 else
78 mdb_printf("CRYPTO_ASYNCH");
79
80 mdb_printf("\nan_state: ");
81 prt_an_state(areqn->an_state);
82
83 mdb_printf("\nan_context: %-16p\t", areqn->an_context);
84 mdb_printf("an_is_my_turn: %s\t ", areqn->an_is_my_turn == B_FALSE ?
85 "B_FALSE" : "B_TRUE");
86
87 mdb_printf("\ncr_reqid: %lx\n", areqn->an_reqarg.cr_reqid);
88 return (DCMD_OK);
89 }
90 /*
91 * Verbose print of kcf_areq_node_t
92 */
93 static int
v_kcf_areq_node(kcf_areq_node_t * areqn)94 v_kcf_areq_node(kcf_areq_node_t *areqn)
95 {
96
97 /* contents only -- the address is printed elsewhere */
98 /* First column */
99
100 mdb_printf("\n%16s: ", "an_type");
101 if (areqn->an_type != CRYPTO_ASYNCH)
102 mdb_printf("%-8d ", areqn->an_type);
103 else
104 mdb_printf("CRYPTO_ASYNCH");
105
106 /* Second column */
107 mdb_printf("\t\t%16s: %p\n", "an_lock", areqn->an_lock);
108
109 /* First column */
110 mdb_printf("%16s: ", "an_state");
111 prt_an_state(areqn->an_state);
112
113 /* Second column */
114 mdb_printf("%14s: next 4 items\n", "an_reqarg");
115
116 /* First column again */
117 mdb_printf("%16s: '%16b'", "cr_flag", areqn->an_reqarg.cr_flag,
118 call_flags);
119
120 /* Second column */
121 mdb_printf("\t%16s: %p\n", "cr_callback_func",
122 areqn->an_reqarg.cr_callback_func);
123
124 /* First column again */
125 mdb_printf("%16s: %-16p", "cr_callback_arg",
126 areqn->an_reqarg.cr_callback_arg);
127
128 /* Second column */
129 mdb_printf("\t%16s: %lx\n", "cr_reqid",
130 (ulong_t)areqn->an_reqarg.cr_reqid);
131
132 /* First column again */
133 mdb_printf("%16s: %d", "an_params.rp_opgrp",
134 areqn->an_params.rp_opgrp);
135
136 /* Second column */
137 mdb_printf("\t%16s: %d\n", "an_params.rp_optype",
138 areqn->an_params.rp_optype);
139
140 /* First column again */
141 mdb_printf("%16s: %-16p", "an_context",
142 areqn->an_context);
143
144 /* Second column */
145 mdb_printf("\t%16s: %p\n", "an_ctxchain_next",
146 areqn->an_ctxchain_next);
147
148 /* First column again */
149 mdb_printf("%16s: %s", "an_is_my_turn",
150 areqn->an_is_my_turn == B_FALSE ? "B_FALSE" : "B_TRUE");
151
152 /* Second column */
153 mdb_printf("\t\t%16s: %s\n", "an_isdual",
154 areqn->an_isdual == B_FALSE ? "B_FALSE" : "B_TRUE");
155
156 /* First column again */
157 mdb_printf("%16s: %p", "an_next",
158 areqn->an_next);
159
160 /* Second column */
161 mdb_printf("\t\t%16s: %p\n", "an_prev", areqn->an_prev);
162
163 /* First column again */
164 mdb_printf("%16s: %p", "an_provider",
165 areqn->an_provider);
166
167 /* Second column */
168 mdb_printf("\t\t%16s: %p\n", "an_idnext", areqn->an_idnext);
169
170 /* First column again */
171 mdb_printf("%16s: %p", "an_idprev",
172 areqn->an_idprev);
173
174 /* Second column */
175 mdb_printf("\t\t%16s: %hx\n", "an_done", areqn->an_done);
176
177 /* First column again */
178 mdb_printf("%16s: %d\n", "an_refcnt",
179 areqn->an_refcnt);
180
181 return (DCMD_OK);
182 }
183 /*ARGSUSED*/
184 int
kcf_areq_node(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)185 kcf_areq_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
186 {
187 kcf_areq_node_t areqn;
188 uint_t opt_v = FALSE;
189
190
191 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &opt_v,
192 NULL) != argc)
193 return (DCMD_USAGE);
194
195 /*
196 * read even if we're looping, because the cbdata design does not
197 * apply to mdb_pwalk_dcmd
198 */
199 if (mdb_vread(&areqn, sizeof (kcf_areq_node_t), addr) == -1) {
200 mdb_warn("cannot read %p", addr);
201 return (DCMD_ERR);
202 }
203 if (opt_v) /* verbose */
204 return (v_kcf_areq_node(&areqn));
205 else
206 return (kcf_areq_node_simple(&areqn));
207 }
208
209 /*ARGSUSED*/
210 int
kcf_global_swq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)211 kcf_global_swq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
212 {
213 kcf_global_swq_t swq;
214 kcf_global_swq_t *ptr;
215
216 if (!(flags & DCMD_ADDRSPEC)) {
217 if (mdb_readsym(&ptr, sizeof (uintptr_t), "gswq")
218 == -1) {
219 mdb_warn("cannot read gswq");
220 return (DCMD_ERR);
221 }
222 }
223 else
224 ptr = (kcf_global_swq_t *)addr;
225
226 if (mdb_vread(&swq, sizeof (kcf_global_swq_t), (uintptr_t)ptr) == -1) {
227 mdb_warn("cannot read %p", ptr);
228 return (DCMD_ERR);
229 }
230 mdb_printf("gs_lock (mutex):\t%p\n", swq.gs_lock);
231 mdb_printf("gs_cv:\t%hx\n", swq.gs_cv._opaque);
232 mdb_printf("gs_njobs:\t%u\n", swq.gs_njobs);
233 mdb_printf("gs_maxjobs:\t%u\n", swq.gs_maxjobs);
234 mdb_printf("gs_first:\t%p\n", swq.gs_first);
235 mdb_printf("gs_last:\t%p\n", swq.gs_last);
236 return (mdb_pwalk_dcmd("an_next", "kcf_areq_node", argc,
237 argv, (uintptr_t)swq.gs_first));
238 }
239
240 static int
areq_walk_init_common(mdb_walk_state_t * wsp,boolean_t use_first)241 areq_walk_init_common(mdb_walk_state_t *wsp, boolean_t use_first)
242 {
243 kcf_global_swq_t gswq_copy;
244 uintptr_t gswq_ptr;
245
246 if (mdb_readsym(&gswq_ptr, sizeof (gswq_ptr), "gswq") == -1) {
247 mdb_warn("failed to read 'gswq'");
248 return (WALK_ERR);
249 }
250 if (mdb_vread(&gswq_copy, sizeof (gswq_copy), gswq_ptr) == -1) {
251 mdb_warn("cannot read %p", gswq_ptr);
252 return (WALK_ERR);
253 }
254 if ((wsp->walk_addr = (use_first ? (uintptr_t)gswq_copy.gs_first :
255 (uintptr_t)gswq_copy.gs_last)) == 0) {
256 mdb_printf("Global swq is empty\n");
257 return (WALK_DONE);
258 }
259 wsp->walk_data = mdb_alloc(sizeof (kcf_areq_node_t), UM_SLEEP);
260 return (WALK_NEXT);
261 }
262
263 int
areq_first_walk_init(mdb_walk_state_t * wsp)264 areq_first_walk_init(mdb_walk_state_t *wsp)
265 {
266 return (areq_walk_init_common(wsp, B_TRUE));
267 }
268
269 int
areq_last_walk_init(mdb_walk_state_t * wsp)270 areq_last_walk_init(mdb_walk_state_t *wsp)
271 {
272 return (areq_walk_init_common(wsp, B_FALSE));
273 }
274
275 typedef enum idwalk_type {
276 IDNEXT, /* an_idnext */
277 IDPREV, /* an_idprev */
278 CTXCHAIN /* an_ctxchain_next */
279 } idwalk_type_t;
280
281 static int
an_id_walk_init(mdb_walk_state_t * wsp,idwalk_type_t type)282 an_id_walk_init(mdb_walk_state_t *wsp, idwalk_type_t type)
283 {
284 kcf_areq_node_t *adn;
285
286 if (wsp->walk_addr == 0) {
287 mdb_warn("must give kcf_areq_node address\n");
288 return (WALK_ERR);
289 }
290 adn = wsp->walk_data = mdb_alloc(sizeof (kcf_areq_node_t), UM_SLEEP);
291
292 if (mdb_vread(adn, sizeof (kcf_areq_node_t), wsp->walk_addr) == -1) {
293 mdb_warn("cannot read %p", wsp->walk_addr);
294 return (WALK_ERR);
295 }
296
297 switch (type) {
298 case IDNEXT:
299 wsp->walk_addr = (uintptr_t)adn->an_idnext;
300 break;
301 case IDPREV:
302 wsp->walk_addr = (uintptr_t)adn->an_idprev;
303 break;
304 case CTXCHAIN:
305 wsp->walk_addr = (uintptr_t)adn->an_ctxchain_next;
306 break;
307 default:
308 mdb_warn("Bad structure member in walk_init\n");
309 return (WALK_ERR);
310 }
311 return (WALK_NEXT);
312 }
313 int
an_idnext_walk_init(mdb_walk_state_t * wsp)314 an_idnext_walk_init(mdb_walk_state_t *wsp)
315 {
316 return (an_id_walk_init(wsp, IDNEXT));
317 }
318 int
an_idprev_walk_init(mdb_walk_state_t * wsp)319 an_idprev_walk_init(mdb_walk_state_t *wsp)
320 {
321 return (an_id_walk_init(wsp, IDPREV));
322 }
323 int
an_ctxchain_walk_init(mdb_walk_state_t * wsp)324 an_ctxchain_walk_init(mdb_walk_state_t *wsp)
325 {
326 return (an_id_walk_init(wsp, CTXCHAIN));
327 }
328 /*
329 * At each step, read a kcf_areq_node_t into our private storage, then invoke
330 * the callback function. We terminate when we reach a NULL type pointer.
331 */
332 static int
an_id_walk_step(mdb_walk_state_t * wsp,idwalk_type_t type)333 an_id_walk_step(mdb_walk_state_t *wsp, idwalk_type_t type)
334 {
335 int status;
336 kcf_areq_node_t *ptr;
337
338 if (wsp->walk_addr == 0) /* then we're done */
339 return (WALK_DONE);
340
341 ptr = wsp->walk_data;
342
343 if (mdb_vread(wsp->walk_data, sizeof (kcf_areq_node_t),
344 wsp->walk_addr) == -1) {
345 mdb_warn("cannot read %p", wsp->walk_addr);
346 return (WALK_ERR);
347 }
348
349 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
350 wsp->walk_cbdata);
351
352 switch (type) {
353 case IDNEXT:
354 if ((wsp->walk_addr =
355 (uintptr_t)ptr->an_idnext) == 0)
356 return (WALK_DONE);
357 break;
358
359 case IDPREV:
360 if ((wsp->walk_addr =
361 (uintptr_t)ptr->an_idprev) == 0)
362 return (WALK_DONE);
363 break;
364
365 case CTXCHAIN:
366 if ((wsp->walk_addr =
367 (uintptr_t)ptr->an_ctxchain_next) == 0)
368 return (WALK_DONE);
369 break;
370
371 default:
372 mdb_warn("Bad structure member in walk_step\n");
373 return (WALK_ERR);
374 }
375 return (status);
376 }
377 int
an_idnext_walk_step(mdb_walk_state_t * wsp)378 an_idnext_walk_step(mdb_walk_state_t *wsp)
379 {
380 return (an_id_walk_step(wsp, IDNEXT));
381 }
382 int
an_idprev_walk_step(mdb_walk_state_t * wsp)383 an_idprev_walk_step(mdb_walk_state_t *wsp)
384 {
385 return (an_id_walk_step(wsp, IDPREV));
386 }
387 int
an_ctxchain_walk_step(mdb_walk_state_t * wsp)388 an_ctxchain_walk_step(mdb_walk_state_t *wsp)
389 {
390 return (an_id_walk_step(wsp, CTXCHAIN));
391 }
392
393 /*
394 * The walker's fini function is invoked at the end of each walk. Since we
395 * dynamically allocated a kcf_areq_node_t in areq_walk_init,
396 * we must free it now.
397 */
398 void
areq_walk_fini(mdb_walk_state_t * wsp)399 areq_walk_fini(mdb_walk_state_t *wsp)
400 {
401 #ifdef DEBUG
402 mdb_printf("...end of kcf_areq_node walk\n");
403 #endif
404 mdb_free(wsp->walk_data, sizeof (kcf_areq_node_t));
405 }
406
407 /*
408 * At each step, read a kcf_areq_node_t into our private storage, then invoke
409 * the callback function. We terminate when we reach a NULL an_next pointer
410 * or a NULL an_prev pointer. use_next flag indicates which one to check.
411 */
412 static int
an_walk_step_common(mdb_walk_state_t * wsp,boolean_t use_next)413 an_walk_step_common(mdb_walk_state_t *wsp, boolean_t use_next)
414 {
415 int status;
416 kcf_areq_node_t *ptr;
417
418 ptr = (kcf_areq_node_t *)wsp->walk_data;
419
420 if (mdb_vread(wsp->walk_data, sizeof (kcf_areq_node_t),
421 wsp->walk_addr) == -1) {
422 mdb_warn("failed to read kcf_areq_node at %p", wsp->walk_addr);
423 return (WALK_DONE);
424 }
425 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
426 wsp->walk_cbdata);
427
428 if ((wsp->walk_addr = (use_next ? (uintptr_t)ptr->an_next :
429 (uintptr_t)ptr->an_prev)) == 0)
430 return (WALK_DONE);
431
432 return (status);
433 }
434
435 int
an_next_walk_step(mdb_walk_state_t * wsp)436 an_next_walk_step(mdb_walk_state_t *wsp)
437 {
438 return (an_walk_step_common(wsp, B_TRUE));
439 }
440
441 int
an_prev_walk_step(mdb_walk_state_t * wsp)442 an_prev_walk_step(mdb_walk_state_t *wsp)
443 {
444 return (an_walk_step_common(wsp, B_FALSE));
445 }
446
447 /*
448 * Walker data for reqid_table walking
449 */
450 typedef struct reqid_data {
451 kcf_reqid_table_t rd_table;
452 kcf_reqid_table_t *rd_tbl_ptrs[REQID_TABLES];
453 int rd_cur_index;
454 } reqid_data_t;
455
456 typedef struct reqid_cb_data {
457 crypto_req_id_t cb_reqid;
458 int verbose;
459 int found;
460 } reqid_cb_data_t;
461
462 extern int crypto_pr_reqid(uintptr_t, reqid_data_t *, reqid_cb_data_t *);
463
464
465 int
reqid_table_walk_init(mdb_walk_state_t * wsp)466 reqid_table_walk_init(mdb_walk_state_t *wsp)
467 {
468 reqid_data_t *wdata;
469 reqid_cb_data_t *cbdata;
470
471 wsp->walk_callback = (mdb_walk_cb_t)crypto_pr_reqid;
472
473 wsp->walk_data = mdb_alloc(sizeof (reqid_data_t), UM_SLEEP);
474
475 /* see if the walker was called from the command line or mdb_pwalk */
476 if (wsp->walk_cbdata == NULL) { /* command line */
477 if ((wsp->walk_cbdata = mdb_zalloc(sizeof (reqid_cb_data_t),
478 UM_SLEEP)) == NULL) {
479 mdb_warn("couldn't get cb memory for "
480 "reqid_table_walker");
481 return (WALK_ERR);
482 }
483 /* initialize for a simple walk, as opposed to a reqid search */
484 cbdata = wsp->walk_cbdata;
485 cbdata->verbose = TRUE;
486 cbdata->cb_reqid = 0;
487 }
488
489 wdata = (reqid_data_t *)wsp->walk_data;
490
491 if (mdb_readsym(wdata->rd_tbl_ptrs, sizeof (wdata->rd_tbl_ptrs),
492 "kcf_reqid_table") == -1) {
493 mdb_warn("failed to read 'kcf_reqid_table'");
494 return (WALK_ERR);
495
496 }
497 wdata->rd_cur_index = 0;
498 wsp->walk_addr = (uintptr_t)wdata->rd_tbl_ptrs[wdata->rd_cur_index];
499
500
501 return (WALK_NEXT);
502 }
503
504 /*
505 * At each step, read a kcf_reqid_table_t into our private storage, then invoke
506 * the callback function. We terminate when we reach a
507 */
508 int
reqid_table_walk_step(mdb_walk_state_t * wsp)509 reqid_table_walk_step(mdb_walk_state_t *wsp)
510 {
511 int status;
512 reqid_data_t *wdata;
513
514
515 wdata = wsp->walk_data;
516 wsp->walk_addr = (uintptr_t)wdata->rd_tbl_ptrs[wdata->rd_cur_index];
517
518 #ifdef DEBUG
519 mdb_printf(
520 "DEBUG: kcf_reqid_table at %p, sizeof kcf_reqid_table_t = %d\n",
521 wsp->walk_addr, sizeof (kcf_reqid_table_t));
522 #endif
523
524 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
525 wsp->walk_cbdata);
526
527 /* get ready for next call */
528 wdata->rd_cur_index++;
529 if (wdata->rd_cur_index >= REQID_TABLES)
530 return (WALK_DONE);
531 return (status);
532 }
533
534 /*
535 * The walker's fini function is invoked at the end of each walk. Since we
536 * dynamically allocated a reqid_data_t in areq_walk_init,
537 * we must free it now.
538 */
539 void
reqid_table_walk_fini(mdb_walk_state_t * wsp)540 reqid_table_walk_fini(mdb_walk_state_t *wsp)
541 {
542 #ifdef DEBUG
543 mdb_printf("...end of kcf_reqid walk\n");
544 #endif
545 mdb_free(wsp->walk_data, sizeof (reqid_data_t));
546 }
547
548 /*
549 * If there's an argument beyond -v, then we're looking for a specific
550 * reqid, otherwise, print any non-null kcf_areq things we run across.
551 */
552
553 int
crypto_pr_reqid(uintptr_t addr,reqid_data_t * data,reqid_cb_data_t * cbdata)554 crypto_pr_reqid(uintptr_t addr, reqid_data_t *data, reqid_cb_data_t *cbdata)
555 {
556 kcf_areq_node_t node;
557 int i;
558 int needhdr = TRUE;
559
560 if (addr == 0) {
561 mdb_printf("kcf_reqid_table[%d] = NULL\n", data->rd_cur_index);
562 return (WALK_NEXT);
563 }
564
565 if (mdb_vread(&(data->rd_table), sizeof (kcf_reqid_table_t),
566 addr) == -1) {
567 mdb_warn("failed to read kcf_reqid_table at %p",
568 addr);
569 return (WALK_ERR);
570 }
571
572 /* Loop over all rt_idhash's */
573 for (i = 0; i < REQID_BUCKETS; i++) {
574 uint_t number_in_chain = 0;
575 uintptr_t node_addr;
576
577 /* follow the an_idnext chains for each bucket */
578 do {
579 /* read kcf_areq_node */
580 if (number_in_chain == 0)
581 node_addr = (uintptr_t)data->rd_table.rt_idhash[i];
582 else
583 /*LINTED*/
584 node_addr = (uintptr_t)node.an_idnext;
585 #ifdef DEBUG
586 mdb_printf("DEBUG: node_addr = %p\n", node_addr);
587 #endif
588
589 if (node_addr == 0)
590 break; /* skip */
591
592 if (mdb_vread(&node, sizeof (kcf_areq_node_t), node_addr)
593 == -1) {
594 if (cbdata->verbose == TRUE)
595 mdb_printf(
596 "cannot read rt_idhash %d an_idnext %d\n",
597 i, number_in_chain);
598 break;
599 }
600 /* see if we want to print it */
601 if ((cbdata->cb_reqid == 0) ||
602 (node.an_reqarg.cr_reqid == cbdata->cb_reqid)) {
603 cbdata->found = TRUE; /* printed if false || reqid */
604 /* is this the first rd_idhash found for this table? */
605 if (needhdr == TRUE) {
606 /* print both indices in bold */
607 mdb_printf("%<b>kcf_reqid_table[%lu] at %p:%</b>\n",
608 data->rd_cur_index, addr);
609 mdb_printf("\trt_lock: %p\trt_curid: %llx\n",
610 data->rd_table.rt_lock,
611 data->rd_table.rt_curid);
612 needhdr = FALSE;
613 }
614 /* print kcf_areq_node */
615 if (number_in_chain < 1)
616 mdb_printf(
617 " %<b>rt_idhash[%lu%]%</b> = %<b>%p:%</b>\n",
618 i, node_addr);
619 else
620 mdb_printf(
621 " rt_idhash[%lu%]"
622 " an_idnext %d = %<b>%p:%</b>\n",
623 i, number_in_chain, node_addr);
624 mdb_inc_indent(8);
625
626 /* if we're looking for one and only one reqid */
627 /* do it REALLY verbose */
628 if ((node.an_reqarg.cr_reqid == cbdata->cb_reqid) &&
629 (cbdata->cb_reqid != 0))
630 v_kcf_areq_node(&node);
631 else if (cbdata->verbose == TRUE)
632 /*
633 * verbose for this walker means non-verbose for
634 * the kcf_areq_node details
635 */
636 kcf_areq_node_simple(&node);
637 mdb_dec_indent(8);
638 }
639 /* if we only wanted one reqid, quit now */
640 if (node.an_reqarg.cr_reqid == cbdata->cb_reqid) {
641 return (WALK_DONE);
642 }
643
644 number_in_chain++;
645
646 } while (node.an_idnext != NULL); /* follow chain in same bucket */
647
648 } /* for each REQID_BUCKETS */
649
650 if ((needhdr == TRUE) && (cbdata->cb_reqid == 0)) {
651 mdb_printf("%kcf_reqid_table[%lu]: %p\n",
652 data->rd_cur_index, addr);
653 }
654 return (WALK_NEXT);
655 }
656
657 /*ARGSUSED*/
658 int
crypto_find_reqid(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)659 crypto_find_reqid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
660 {
661 const mdb_arg_t *argp = NULL;
662 reqid_cb_data_t cbdata;
663 int i, status;
664
665 cbdata.cb_reqid = 0L;
666 cbdata.verbose = FALSE;
667 cbdata.found = FALSE;
668
669 if (flags & DCMD_ADDRSPEC) {
670 mdb_printf("use addr ::kcf_reqid_table\n");
671 return (DCMD_USAGE);
672 }
673 if ((i = mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE,
674 &cbdata.verbose, NULL)) != argc) {
675 if (argc - i > 1)
676 return (DCMD_USAGE);
677 }
678
679 if (argc > i)
680 argp = &argv[i];
681
682 if ((argp != NULL))
683 cbdata.cb_reqid = (crypto_req_id_t)mdb_argtoull(argp);
684 status = mdb_pwalk("kcf_reqid_table", (mdb_walk_cb_t)crypto_pr_reqid,
685 &cbdata, addr);
686
687 if ((cbdata.cb_reqid != 0L) && (cbdata.found == FALSE))
688 mdb_printf("ID 0x%lx not found\n", cbdata.cb_reqid);
689 #ifdef DEBUG
690 else
691 mdb_printf("DEBUG: cbdata.db_reqid = %lx, cbdata.found = %d\n",
692 cbdata.cb_reqid, cbdata.found);
693 #endif
694
695 return (status);
696 }
697
698 int
kcf_reqid_table_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)699 kcf_reqid_table_dcmd(uintptr_t addr, uint_t flags, int argc,
700 const mdb_arg_t *argv)
701 {
702 reqid_data_t wdata;
703 reqid_cb_data_t cbdata;
704
705 if (!(flags & DCMD_ADDRSPEC))
706 return (DCMD_USAGE);
707
708 memset(&wdata, 0, sizeof (wdata));
709 memset(&cbdata, 0, sizeof (cbdata));
710
711 if ((mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE,
712 &cbdata.verbose, NULL)) != argc) {
713 return (DCMD_USAGE);
714 }
715 crypto_pr_reqid(addr, &wdata, &cbdata);
716 return (DCMD_OK);
717 }
718