drivers/infiniband/core/security.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/security.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/security.c
Extension
.c
Size
18424 bytes
Lines
751
Domain
Driver Families
Bucket
drivers/infiniband
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 (tmp_pkey->pkey_index == pp->pkey_index) {
			pkey = tmp_pkey;
			break;
		}
	}
	spin_unlock(&dev->port_data[pp->port_num].pkey_list_lock);
	return pkey;
}

static int get_pkey_and_subnet_prefix(struct ib_port_pkey *pp,
				      u16 *pkey,
				      u64 *subnet_prefix)
{
	struct ib_device *dev = pp->sec->dev;
	int ret;

	ret = ib_get_cached_pkey(dev, pp->port_num, pp->pkey_index, pkey);
	if (ret)
		return ret;

	ib_get_cached_subnet_prefix(dev, pp->port_num, subnet_prefix);

	return ret;
}

static int enforce_qp_pkey_security(u16 pkey,
				    u64 subnet_prefix,
				    struct ib_qp_security *qp_sec)
{
	struct ib_qp_security *shared_qp_sec;
	int ret;

	ret = security_ib_pkey_access(qp_sec->security, subnet_prefix, pkey);
	if (ret)
		return ret;

	list_for_each_entry(shared_qp_sec,
			    &qp_sec->shared_qp_list,
			    shared_qp_list) {
		ret = security_ib_pkey_access(shared_qp_sec->security,
					      subnet_prefix,
					      pkey);
		if (ret)
			return ret;
	}
	return 0;
}

/* The caller of this function must hold the QP security
 * mutex of the QP of the security structure in *pps.
 *
 * It takes separate ports_pkeys and security structure
 * because in some cases the pps will be for a new settings
 * or the pps will be for the real QP and security structure
 * will be for a shared QP.
 */
static int check_qp_port_pkey_settings(struct ib_ports_pkeys *pps,
				       struct ib_qp_security *sec)
{
	u64 subnet_prefix;
	u16 pkey;
	int ret = 0;

	if (!pps)
		return 0;

	if (pps->main.state != IB_PORT_PKEY_NOT_VALID) {
		ret = get_pkey_and_subnet_prefix(&pps->main,
						 &pkey,
						 &subnet_prefix);
		if (ret)
			return ret;

		ret = enforce_qp_pkey_security(pkey,
					       subnet_prefix,
					       sec);
		if (ret)
			return ret;
	}

	if (pps->alt.state != IB_PORT_PKEY_NOT_VALID) {
		ret = get_pkey_and_subnet_prefix(&pps->alt,
						 &pkey,
						 &subnet_prefix);
		if (ret)
			return ret;

		ret = enforce_qp_pkey_security(pkey,
					       subnet_prefix,
					       sec);

Annotation

Implementation Notes