drivers/gpu/drm/xe/xe_sriov_packet.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_sriov_packet.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_sriov_packet.c
Extension
.c
Size
12468 bytes
Lines
522
Domain
Driver Families
Bucket
drivers/gpu
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

if (ret) {
			xe_sriov_packet_free(*data);
			*data = NULL;

			return ret;
		}

		*data = NULL;
	}

	return copied;
}

#define MIGRATION_KLV_DEVICE_DEVID_KEY	0xf001u
#define MIGRATION_KLV_DEVICE_DEVID_LEN	1u
#define MIGRATION_KLV_DEVICE_REVID_KEY	0xf002u
#define MIGRATION_KLV_DEVICE_REVID_LEN	1u

#define MIGRATION_DESCRIPTOR_DWORDS	(GUC_KLV_LEN_MIN + MIGRATION_KLV_DEVICE_DEVID_LEN + \
					 GUC_KLV_LEN_MIN + MIGRATION_KLV_DEVICE_REVID_LEN)
static int pf_descriptor_init(struct xe_device *xe, unsigned int vfid)
{
	struct xe_sriov_packet **desc = pf_pick_descriptor(xe, vfid);
	struct xe_sriov_packet *data;
	unsigned int len = 0;
	u32 *klvs;
	int ret;

	data = xe_sriov_packet_alloc(xe);
	if (!data)
		return -ENOMEM;

	ret = xe_sriov_packet_init(data, 0, 0, XE_SRIOV_PACKET_TYPE_DESCRIPTOR,
				   0, MIGRATION_DESCRIPTOR_DWORDS * sizeof(u32));
	if (ret) {
		xe_sriov_packet_free(data);
		return ret;
	}

	klvs = data->vaddr;
	klvs[len++] = PREP_GUC_KLV_CONST(MIGRATION_KLV_DEVICE_DEVID_KEY,
					 MIGRATION_KLV_DEVICE_DEVID_LEN);
	klvs[len++] = xe->info.devid;
	klvs[len++] = PREP_GUC_KLV_CONST(MIGRATION_KLV_DEVICE_REVID_KEY,
					 MIGRATION_KLV_DEVICE_REVID_LEN);
	klvs[len++] = xe->info.revid;

	xe_assert(xe, len == MIGRATION_DESCRIPTOR_DWORDS);

	*desc = data;

	return 0;
}

/**
 * xe_sriov_packet_process_descriptor() - Process migration data descriptor packet.
 * @xe: the &xe_device
 * @vfid: the VF identifier
 * @data: the &xe_sriov_packet containing the descriptor
 *
 * The descriptor uses the same KLV format as GuC, and contains metadata used for
 * checking migration data compatibility.
 *
 * Return: 0 on success, -errno on failure.
 */
int xe_sriov_packet_process_descriptor(struct xe_device *xe, unsigned int vfid,
				       struct xe_sriov_packet *data)
{
	u32 num_dwords = data->hdr.size / sizeof(u32);
	u32 *klvs = data->vaddr;

	xe_assert(xe, data->hdr.type == XE_SRIOV_PACKET_TYPE_DESCRIPTOR);

	if (data->hdr.size % sizeof(u32)) {
		xe_sriov_warn(xe, "Aborting migration, descriptor not in KLV format (size=%llu)\n",
			      data->hdr.size);
		return -EINVAL;
	}

	while (num_dwords >= GUC_KLV_LEN_MIN) {
		u32 key = FIELD_GET(GUC_KLV_0_KEY, klvs[0]);
		u32 len = FIELD_GET(GUC_KLV_0_LEN, klvs[0]);

		klvs += GUC_KLV_LEN_MIN;
		num_dwords -= GUC_KLV_LEN_MIN;

		if (len > num_dwords) {
			xe_sriov_warn(xe, "Aborting migration, truncated KLV %#x, len %u\n",
				      key, len);
			return -EINVAL;

Annotation

Implementation Notes