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#include <sys/zfs_context.h> 27#include <sys/crypto/common.h> 28#include <sys/crypto/api.h> 29#include <sys/crypto/impl.h> 30#include <sys/crypto/sched_impl.h> 31 32/* 33 * All event subscribers are put on a list. kcf_notify_list_lock 34 * protects changes to this list. 35 * 36 * The following locking order is maintained in the code - The 37 * global kcf_notify_list_lock followed by the individual lock 38 * in a kcf_ntfy_elem structure (kn_lock). 39 */ 40kmutex_t ntfy_list_lock; 41kcondvar_t ntfy_list_cv; /* cv the service thread waits on */ 42static kcf_ntfy_elem_t *ntfy_list_head; 43 44/* 45 * crypto_mech2id() 46 * 47 * Arguments: 48 * . mechname: A null-terminated string identifying the mechanism name. 49 * 50 * Description: 51 * Walks the mechanisms tables, looking for an entry that matches the 52 * mechname. Once it find it, it builds the 64-bit mech_type and returns 53 * it. If there are no hardware or software providers for the mechanism, 54 * but there is an unloaded software provider, this routine will attempt 55 * to load it. 56 * 57 * Context: 58 * Process and interruption. 59 * 60 * Returns: 61 * The unique mechanism identified by 'mechname', if found. 62 * CRYPTO_MECH_INVALID otherwise. 63 */ 64crypto_mech_type_t 65crypto_mech2id(char *mechname) 66{ 67 return (crypto_mech2id_common(mechname, B_TRUE)); 68} 69 70/* 71 * We walk the notification list and do the callbacks. 72 */ 73void 74kcf_walk_ntfylist(uint32_t event, void *event_arg) 75{ 76 kcf_ntfy_elem_t *nep; 77 int nelem = 0; 78 79 mutex_enter(&ntfy_list_lock); 80 81 /* 82 * Count how many clients are on the notification list. We need 83 * this count to ensure that clients which joined the list after we 84 * have started this walk, are not wrongly notified. 85 */ 86 for (nep = ntfy_list_head; nep != NULL; nep = nep->kn_next) 87 nelem++; 88 89 for (nep = ntfy_list_head; (nep != NULL && nelem); nep = nep->kn_next) { 90 nelem--; 91 92 /* 93 * Check if this client is interested in the 94 * event. 95 */ 96 if (!(nep->kn_event_mask & event)) 97 continue; 98 99 mutex_enter(&nep->kn_lock); 100 nep->kn_state = NTFY_RUNNING; 101 mutex_exit(&nep->kn_lock); 102 mutex_exit(&ntfy_list_lock); 103 104 /* 105 * We invoke the callback routine with no locks held. Another 106 * client could have joined the list meanwhile. This is fine 107 * as we maintain nelem as stated above. The NULL check in the 108 * for loop guards against shrinkage. Also, any callers of 109 * crypto_unnotify_events() at this point cv_wait till kn_state 110 * changes to NTFY_WAITING. Hence, nep is assured to be valid. 111 */ 112 (*nep->kn_func)(event, event_arg); 113 114 mutex_enter(&nep->kn_lock); 115 nep->kn_state = NTFY_WAITING; 116 cv_broadcast(&nep->kn_cv); 117 mutex_exit(&nep->kn_lock); 118 119 mutex_enter(&ntfy_list_lock); 120 } 121 122 mutex_exit(&ntfy_list_lock); 123} 124 125#if defined(_KERNEL) 126EXPORT_SYMBOL(crypto_mech2id); 127#endif 128