lib/pldmfw/pldmfw.c

Source file repositories/reference/linux-study-clean/lib/pldmfw/pldmfw.c

File Facts

System
Linux kernel
Corpus path
lib/pldmfw/pldmfw.c
Extension
.c
Size
24827 bytes
Lines
893
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pldmfw_priv {
	struct pldmfw *context;
	const struct firmware *fw;

	/* current offset of firmware image */
	size_t offset;

	struct list_head records;
	struct list_head components;

	/* PLDM Firmware Package Header */
	const struct __pldm_header *header;
	u16 total_header_size;

	/* length of the component bitmap */
	u16 component_bitmap_len;
	u16 bitmap_size;

	/* Start of the component image information */
	u16 component_count;
	const u8 *component_start;

	/* Start pf the firmware device id records */
	const u8 *record_start;
	u8 record_count;

	/* The CRC at the end of the package header */
	u32 header_crc;

	struct pldmfw_record *matching_record;
};

/**
 * pldm_check_fw_space - Verify that the firmware image has space left
 * @data: pointer to private data
 * @offset: offset to start from
 * @length: length to check for
 *
 * Verify that the firmware data can hold a chunk of bytes with the specified
 * offset and length.
 *
 * Returns: zero on success, or -EFAULT if the image does not have enough
 * space left to fit the expected length.
 */
static int
pldm_check_fw_space(struct pldmfw_priv *data, size_t offset, size_t length)
{
	size_t expected_size = offset + length;
	struct device *dev = data->context->dev;

	if (data->fw->size < expected_size) {
		dev_dbg(dev, "Firmware file size smaller than expected. Got %zu bytes, needed %zu bytes\n",
			data->fw->size, expected_size);
		return -EFAULT;
	}

	return 0;
}

/**
 * pldm_move_fw_offset - Move the current firmware offset forward
 * @data: pointer to private data
 * @bytes_to_move: number of bytes to move the offset forward by
 *
 * Check that there is enough space past the current offset, and then move the
 * offset forward by this amount.
 *
 * Returns: zero on success, or -EFAULT if the image is too small to fit the
 * expected length.
 */
static int
pldm_move_fw_offset(struct pldmfw_priv *data, size_t bytes_to_move)
{
	int err;

	err = pldm_check_fw_space(data, data->offset, bytes_to_move);
	if (err)
		return err;

	data->offset += bytes_to_move;

	return 0;
}

/**
 * pldm_parse_header - Validate and extract details about the PLDM header
 * @data: pointer to private data
 *
 * Performs initial basic verification of the PLDM image, up to the first
 * firmware record.

Annotation

Implementation Notes