drivers/platform/x86/intel/ifs/load.c

Source file repositories/reference/linux-study-clean/drivers/platform/x86/intel/ifs/load.c

File Facts

System
Linux kernel
Corpus path
drivers/platform/x86/intel/ifs/load.c
Extension
.c
Size
12850 bytes
Lines
439
Domain
Driver Families
Bucket
drivers/platform
Inferred role
Driver Families: implementation source
Status
source 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

struct metadata_header {
	unsigned int		type;
	unsigned int		blk_size;
};

static struct metadata_header *find_meta_data(void *ucode, unsigned int meta_type)
{
	struct microcode_header_intel *hdr = &((struct microcode_intel *)ucode)->hdr;
	struct metadata_header *meta_header;
	unsigned long data_size, total_meta;
	unsigned long meta_size = 0;

	data_size = intel_microcode_get_datasize(hdr);
	total_meta = hdr->metasize;
	if (!total_meta)
		return NULL;

	meta_header = (ucode + MC_HEADER_SIZE + data_size) - total_meta;

	while (meta_header->type != MC_HEADER_META_TYPE_END &&
	       meta_header->blk_size &&
	       meta_size < total_meta) {
		meta_size += meta_header->blk_size;
		if (meta_header->type == meta_type)
			return meta_header;

		meta_header = (void *)meta_header + meta_header->blk_size;
	}
	return NULL;
}

static void hashcopy_err_message(struct device *dev, u32 err_code)
{
	if (err_code >= ARRAY_SIZE(scan_hash_status))
		dev_err(dev, "invalid error code 0x%x for hash copy\n", err_code);
	else
		dev_err(dev, "Hash copy error : %s\n", scan_hash_status[err_code]);
}

static void auth_err_message(struct device *dev, u32 err_code)
{
	if (err_code >= ARRAY_SIZE(scan_authentication_status))
		dev_err(dev, "invalid error code 0x%x for authentication\n", err_code);
	else
		dev_err(dev, "Chunk authentication error : %s\n",
			scan_authentication_status[err_code]);
}

/*
 * To copy scan hashes and authenticate test chunks, the initiating cpu must point
 * to the EDX:EAX to the test image in linear address.
 * Run wrmsr(MSR_COPY_SCAN_HASHES) for scan hash copy and run wrmsr(MSR_AUTHENTICATE_AND_COPY_CHUNK)
 * for scan hash copy and test chunk authentication.
 */
static void copy_hashes_authenticate_chunks(struct work_struct *work)
{
	struct ifs_work *local_work = container_of(work, struct ifs_work, w);
	union ifs_scan_hashes_status hashes_status;
	union ifs_chunks_auth_status chunk_status;
	struct device *dev = local_work->dev;
	const struct ifs_test_msrs *msrs;
	int i, num_chunks, chunk_size;
	struct ifs_data *ifsd;
	u64 linear_addr, base;
	u32 err_code;

	ifsd = ifs_get_data(dev);
	msrs = ifs_get_test_msrs(dev);
	/* run scan hash copy */
	wrmsrq(msrs->copy_hashes, ifs_hash_ptr);
	rdmsrq(msrs->copy_hashes_status, hashes_status.data);

	/* enumerate the scan image information */
	num_chunks = hashes_status.num_chunks;
	chunk_size = hashes_status.chunk_size * 1024;
	err_code = hashes_status.error_code;

	if (!hashes_status.valid) {
		ifsd->loading_error = true;
		hashcopy_err_message(dev, err_code);
		goto done;
	}

	/* base linear address to the scan data */
	base = ifs_test_image_ptr;

	/* scan data authentication and copy chunks to secured memory */
	for (i = 0; i < num_chunks; i++) {
		linear_addr = base + i * chunk_size;
		linear_addr |= i;

Annotation

Implementation Notes