summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Wajdeczko <michal.wajdeczko@intel.com>2026-07-08 00:08:15 +0200
committerMichal Wajdeczko <michal.wajdeczko@intel.com>2026-07-11 16:15:35 +0200
commit068388c0cd225654e7369907670d4e77b8dd3744 (patch)
tree177511d9167347e388d78a8df3276b8a5a91d288
parent6d599b33d86e569269aa784f19c8c8f64c0a8b54 (diff)
downloadlinux-068388c0cd225654e7369907670d4e77b8dd3744.tar.gz
linux-068388c0cd225654e7369907670d4e77b8dd3744.zip
drm/xe/pf: Handle migration descriptor using KLV helpers
As we plan to add more KLVs to the migration descriptor packet, to simplify such extensions and avoid coding errors, start using our KLV helpers for packet preparing and parsing. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Reviewed-by: MichaƂ Winiarski <michal.winiarski@intel.com> Link: https://patch.msgid.link/20260707220816.677-14-michal.wajdeczko@intel.com
-rw-r--r--drivers/gpu/drm/xe/xe_sriov_packet.c104
1 files changed, 55 insertions, 49 deletions
diff --git a/drivers/gpu/drm/xe/xe_sriov_packet.c b/drivers/gpu/drm/xe/xe_sriov_packet.c
index 558a3697d639..e9ae9c9744ea 100644
--- a/drivers/gpu/drm/xe/xe_sriov_packet.c
+++ b/drivers/gpu/drm/xe/xe_sriov_packet.c
@@ -360,8 +360,7 @@ 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;
+ u32 *klvs, *end;
int ret;
data = xe_sriov_packet_alloc(xe);
@@ -376,20 +375,55 @@ static int pf_descriptor_init(struct xe_device *xe, unsigned int vfid)
}
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;
+ end = klvs + MIGRATION_DESCRIPTOR_DWORDS;
- xe_assert(xe, len == MIGRATION_DESCRIPTOR_DWORDS);
+ klvs = xe_guc_klv_encode_u32(klvs, end - klvs,
+ MIGRATION_KLV_DEVICE_DEVID_KEY,
+ xe->info.devid);
+ klvs = xe_guc_klv_encode_u32(klvs, end - klvs,
+ MIGRATION_KLV_DEVICE_REVID_KEY,
+ xe->info.revid);
+ xe_assert(xe, !IS_ERR(klvs));
+ xe_assert(xe, klvs == end);
*desc = data;
return 0;
}
+static int descriptor_decoder(void *arg, u16 key, u16 len, const u32 *value)
+{
+ struct xe_device *xe = arg;
+
+ xe_sriov_dbg_verbose(xe, "found KLV %#x %s\n", key, xe_guc_klv_key_to_string(key));
+
+ switch (key) {
+ case MIGRATION_KLV_DEVICE_DEVID_KEY:
+ if (*value != xe->info.devid) {
+ xe_sriov_warn(xe, "Aborting migration, devid mismatch %#06x!=%#06x\n",
+ *value, xe->info.devid);
+ return -ENODEV;
+ }
+ break;
+ case MIGRATION_KLV_DEVICE_REVID_KEY:
+ if (*value != xe->info.revid) {
+ xe_sriov_warn(xe, "Aborting migration, revid mismatch %#06x!=%#06x\n",
+ *value, xe->info.revid);
+ return -ENODEV;
+ }
+ break;
+ default:
+ if (IS_ENABLED(CONFIG_DRM_XE_DEBUG)) {
+ struct drm_printer p = xe_dbg_printer(xe);
+
+ xe_sriov_dbg(xe, "unexpected KLV %#x in descriptor!\n", key);
+ xe_guc_klv_print_one(key, len, value, &p);
+ }
+ return 0;
+ }
+ return 1;
+}
+
/**
* xe_sriov_packet_process_descriptor() - Process migration data descriptor packet.
* @xe: the &xe_device
@@ -406,6 +440,7 @@ int xe_sriov_packet_process_descriptor(struct xe_device *xe, unsigned int vfid,
{
u32 num_dwords = data->hdr.size / sizeof(u32);
u32 *klvs = data->vaddr;
+ int ret;
xe_assert(xe, data->hdr.type == XE_SRIOV_PACKET_TYPE_DESCRIPTOR);
@@ -415,47 +450,18 @@ int xe_sriov_packet_process_descriptor(struct xe_device *xe, unsigned int vfid,
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;
- }
-
- switch (key) {
- case MIGRATION_KLV_DEVICE_DEVID_KEY:
- if (*klvs != xe->info.devid) {
- xe_sriov_warn(xe,
- "Aborting migration, devid mismatch %#06x!=%#06x\n",
- *klvs, xe->info.devid);
- return -ENODEV;
- }
- break;
- case MIGRATION_KLV_DEVICE_REVID_KEY:
- if (*klvs != xe->info.revid) {
- xe_sriov_warn(xe,
- "Aborting migration, revid mismatch %#06x!=%#06x\n",
- *klvs, xe->info.revid);
- return -ENODEV;
- }
- break;
- default:
- xe_sriov_dbg(xe,
- "Skipping unknown migration KLV %#x, len=%u\n",
- key, len);
- print_hex_dump_bytes("desc: ", DUMP_PREFIX_OFFSET, klvs,
- min(SZ_64, len * sizeof(u32)));
- break;
- }
+ ret = xe_guc_klv_count(klvs, num_dwords);
+ if (ret < 0) {
+ xe_sriov_warn(xe, "Aborting migration, corrupted descriptor KLVs (%pe)\n",
+ ERR_PTR(ret));
+ return ret;
+ }
- klvs += len;
- num_dwords -= len;
+ ret = xe_guc_klv_parser(klvs, num_dwords, xe, descriptor_decoder);
+ if (ret < 0) {
+ xe_sriov_warn(xe, "Aborting migration, descriptor parsing failed (%pe)\n",
+ ERR_PTR(ret));
+ return ret;
}
return 0;