drivers/s390/crypto/pkey_base.c

Source file repositories/reference/linux-study-clean/drivers/s390/crypto/pkey_base.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/crypto/pkey_base.c
Extension
.c
Size
8893 bytes
Lines
388
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (h == handler) {
			rcu_read_unlock();
			spin_unlock(&handler_list_write_lock);
			module_put(handler->module);
			return -EEXIST;
		}
	}
	rcu_read_unlock();

	list_add_rcu(&handler->list, &handler_list);
	spin_unlock(&handler_list_write_lock);
	/*
	 * Fast path to push the info about the updated list to the other
	 * CPUs. If removed, the other CPUs may get the updated list when the
	 * RCU context is synched. As this code is in general not performance
	 * critical and the list update mostly only occurs at the early time in
	 * system startup the focus is on concurrency versus performance.
	 */
	synchronize_rcu();

	module_put(handler->module);

	PKEY_DBF_INFO("%s pkey handler '%s' registered\n", __func__,
		      handler->name ?: "<no name>");

	return 0;
}
EXPORT_SYMBOL(pkey_handler_register);

int pkey_handler_unregister(struct pkey_handler *handler)
{
	spin_lock(&handler_list_write_lock);
	list_del_rcu(&handler->list);
	INIT_LIST_HEAD_RCU(&handler->list);
	spin_unlock(&handler_list_write_lock);
	synchronize_rcu();

	PKEY_DBF_INFO("%s pkey handler '%s' unregistered\n", __func__,
		      handler->name ?: "<no name>");

	return 0;
}
EXPORT_SYMBOL(pkey_handler_unregister);

/*
 * Handler invocation functions.
 */

const struct pkey_handler *pkey_handler_get_keybased(const u8 *key, u32 keylen)
{
	const struct pkey_handler *h;

	rcu_read_lock();
	list_for_each_entry_rcu(h, &handler_list, list) {
		if (!try_module_get(h->module))
			continue;
		if (h->is_supported_key(key, keylen)) {
			rcu_read_unlock();
			return h;
		}
		module_put(h->module);
	}
	rcu_read_unlock();

	return NULL;
}
EXPORT_SYMBOL(pkey_handler_get_keybased);

const struct pkey_handler *pkey_handler_get_keytypebased(enum pkey_key_type kt)
{
	const struct pkey_handler *h;

	rcu_read_lock();
	list_for_each_entry_rcu(h, &handler_list, list) {
		if (!try_module_get(h->module))
			continue;
		if (h->is_supported_keytype(kt)) {
			rcu_read_unlock();
			return h;
		}
		module_put(h->module);
	}
	rcu_read_unlock();

	return NULL;
}
EXPORT_SYMBOL(pkey_handler_get_keytypebased);

void pkey_handler_put(const struct pkey_handler *handler)
{

Annotation

Implementation Notes