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