Skip to content

Commit 98d4187

Browse files
Andrzej Kacprowskijlawryno
authored andcommitted
accel/ivpu: Fix FW API data alignment issues
FW API structures have been updated to fix misaligned structure members. Also changed JSM message header format to account for future improvements. Added explicit check for minimum supported JSM API version. Fixes: 5d7422c ("accel/ivpu: Add IPC driver and JSM messages") Signed-off-by: Andrzej Kacprowski <[email protected]> Signed-off-by: Stanislaw Gruszka <[email protected]> Reviewed-by: Jeffrey Hugo <[email protected]> Signed-off-by: Jacek Lawrynowicz <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 4ea1e50) Signed-off-by: Jacek Lawrynowicz <[email protected]>
1 parent 352683e commit 98d4187

File tree

3 files changed

+65
-44
lines changed

3 files changed

+65
-44
lines changed

drivers/accel/ivpu/ivpu_fw.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232

3333
#define ADDR_TO_L2_CACHE_CFG(addr) ((addr) >> 31)
3434

35-
#define IVPU_FW_CHECK_API(vdev, fw_hdr, name) ivpu_fw_check_api(vdev, fw_hdr, #name, \
36-
VPU_##name##_API_VER_INDEX, \
37-
VPU_##name##_API_VER_MAJOR, \
38-
VPU_##name##_API_VER_MINOR)
35+
#define IVPU_FW_CHECK_API(vdev, fw_hdr, name, min_major) \
36+
ivpu_fw_check_api(vdev, fw_hdr, #name, \
37+
VPU_##name##_API_VER_INDEX, \
38+
VPU_##name##_API_VER_MAJOR, \
39+
VPU_##name##_API_VER_MINOR, min_major)
3940

4041
static char *ivpu_firmware;
4142
module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644);
@@ -63,19 +64,27 @@ static int ivpu_fw_request(struct ivpu_device *vdev)
6364
return ret;
6465
}
6566

66-
static void
67+
static int
6768
ivpu_fw_check_api(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr,
68-
const char *str, int index, u16 expected_major, u16 expected_minor)
69+
const char *str, int index, u16 expected_major, u16 expected_minor,
70+
u16 min_major)
6971
{
7072
u16 major = (u16)(fw_hdr->api_version[index] >> 16);
7173
u16 minor = (u16)(fw_hdr->api_version[index]);
7274

75+
if (major < min_major) {
76+
ivpu_err(vdev, "Incompatible FW %s API version: %d.%d, required %d.0 or later\n",
77+
str, major, minor, min_major);
78+
return -EINVAL;
79+
}
7380
if (major != expected_major) {
74-
ivpu_warn(vdev, "Incompatible FW %s API version: %d.%d (expected %d.%d)\n",
81+
ivpu_warn(vdev, "Major FW %s API version different: %d.%d (expected %d.%d)\n",
7582
str, major, minor, expected_major, expected_minor);
7683
}
7784
ivpu_dbg(vdev, FW_BOOT, "FW %s API version: %d.%d (expected %d.%d)\n",
7885
str, major, minor, expected_major, expected_minor);
86+
87+
return 0;
7988
}
8089

8190
static int ivpu_fw_parse(struct ivpu_device *vdev)
@@ -131,6 +140,14 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
131140
ivpu_err(vdev, "Invalid entry point: 0x%llx\n", fw_hdr->entry_point);
132141
return -EINVAL;
133142
}
143+
ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n",
144+
fw_hdr->header_version, fw_hdr->image_format);
145+
ivpu_dbg(vdev, FW_BOOT, "FW version: %s\n", (char *)fw_hdr + VPU_FW_HEADER_SIZE);
146+
147+
if (IVPU_FW_CHECK_API(vdev, fw_hdr, BOOT, 3))
148+
return -EINVAL;
149+
if (IVPU_FW_CHECK_API(vdev, fw_hdr, JSM, 3))
150+
return -EINVAL;
134151

135152
fw->runtime_addr = runtime_addr;
136153
fw->runtime_size = runtime_size;
@@ -141,16 +158,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
141158
fw->cold_boot_entry_point = fw_hdr->entry_point;
142159
fw->entry_point = fw->cold_boot_entry_point;
143160

144-
ivpu_dbg(vdev, FW_BOOT, "Header version: 0x%x, format 0x%x\n",
145-
fw_hdr->header_version, fw_hdr->image_format);
146161
ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n",
147162
fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size);
148163
ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n",
149164
fw->runtime_addr, image_load_addr, fw->entry_point);
150-
ivpu_dbg(vdev, FW_BOOT, "FW version: %s\n", (char *)fw_hdr + VPU_FW_HEADER_SIZE);
151-
152-
IVPU_FW_CHECK_API(vdev, fw_hdr, BOOT);
153-
IVPU_FW_CHECK_API(vdev, fw_hdr, JSM);
154165

155166
return 0;
156167
}

drivers/accel/ivpu/ivpu_job.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,9 @@ static int ivpu_direct_job_submission(struct ivpu_job *job)
400400
if (ret)
401401
goto err_xa_erase;
402402

403-
ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d next %d\n",
404-
job->job_id, file_priv->ctx.id, job->engine_idx, cmdq->jobq->header.tail);
403+
ivpu_dbg(vdev, JOB, "Job submitted: id %3u addr 0x%llx ctx %2d engine %d next %d\n",
404+
job->job_id, job->cmd_buf_vpu_addr, file_priv->ctx.id,
405+
job->engine_idx, cmdq->jobq->header.tail);
405406

406407
if (ivpu_test_mode == IVPU_TEST_MODE_NULL_HW) {
407408
ivpu_job_done(vdev, job->job_id, VPU_JSM_STATUS_SUCCESS);

drivers/accel/ivpu/vpu_jsm_api.h

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
/*
1818
* Major version changes that break backward compatibility
1919
*/
20-
#define VPU_JSM_API_VER_MAJOR 2
20+
#define VPU_JSM_API_VER_MAJOR 3
2121

2222
/*
2323
* Minor version changes when API backward compatibility is preserved.
2424
*/
25-
#define VPU_JSM_API_VER_MINOR 10
25+
#define VPU_JSM_API_VER_MINOR 0
2626

2727
/*
2828
* API header changed (field names, documentation, formatting) but API itself has not been changed
@@ -103,10 +103,10 @@
103103
/*
104104
* Max length (including trailing NULL char) of a dyndbg command.
105105
*
106-
* NOTE: 112 is used so that the size of 'struct vpu_ipc_msg' in the JSM API is
106+
* NOTE: 96 is used so that the size of 'struct vpu_ipc_msg' in the JSM API is
107107
* 128 bytes (multiple of 64 bytes, the cache line size).
108108
*/
109-
#define VPU_DYNDBG_CMD_MAX_LEN 112
109+
#define VPU_DYNDBG_CMD_MAX_LEN 96
110110

111111
/*
112112
* Job format.
@@ -119,7 +119,7 @@ struct vpu_job_queue_entry {
119119
u64 root_page_table_update_counter; /**< Page tables update events counter */
120120
u64 preemption_buffer_address; /**< Address of the preemption buffer to use for this job */
121121
u64 preemption_buffer_size; /**< Size of the preemption buffer to use for this job */
122-
u8 reserved[VPU_JOB_RESERVED_BYTES];
122+
u8 reserved_0[VPU_JOB_RESERVED_BYTES];
123123
};
124124

125125
/*
@@ -129,7 +129,7 @@ struct vpu_job_queue_header {
129129
u32 engine_idx;
130130
u32 head;
131131
u32 tail;
132-
u8 reserved[VPU_JOB_QUEUE_RESERVED_BYTES];
132+
u8 reserved_0[VPU_JOB_QUEUE_RESERVED_BYTES];
133133
};
134134

135135
/*
@@ -319,6 +319,8 @@ enum vpu_ipc_msg_status { VPU_JSM_MSG_FREE, VPU_JSM_MSG_ALLOCATED };
319319
struct vpu_ipc_msg_payload_engine_reset {
320320
/* Engine to be reset. */
321321
u32 engine_idx;
322+
/* Reserved */
323+
u32 reserved_0;
322324
};
323325

324326
struct vpu_ipc_msg_payload_engine_preempt {
@@ -336,6 +338,8 @@ struct vpu_ipc_msg_payload_engine_preempt {
336338
struct vpu_ipc_msg_payload_register_db {
337339
/* Index of the doorbell to register. */
338340
u32 db_idx;
341+
/* Reserved */
342+
u32 reserved_0;
339343
/* Virtual address in Global GTT pointing to the start of job queue. */
340344
u64 jobq_base;
341345
/* Size of the job queue in bytes. */
@@ -352,11 +356,15 @@ struct vpu_ipc_msg_payload_register_db {
352356
struct vpu_ipc_msg_payload_unregister_db {
353357
/* Index of the doorbell to unregister. */
354358
u32 db_idx;
359+
/* Reserved */
360+
u32 reserved_0;
355361
};
356362

357363
struct vpu_ipc_msg_payload_query_engine_hb {
358364
/* Engine to return heartbeat value. */
359365
u32 engine_idx;
366+
/* Reserved */
367+
u32 reserved_0;
360368
};
361369

362370
struct vpu_ipc_msg_payload_power_level {
@@ -371,11 +379,15 @@ struct vpu_ipc_msg_payload_power_level {
371379
* considered to be valid.
372380
*/
373381
u32 power_level;
382+
/* Reserved */
383+
u32 reserved_0;
374384
};
375385

376386
struct vpu_ipc_msg_payload_ssid_release {
377387
/* Host sub-stream ID for the context to be released. */
378388
u32 host_ssid;
389+
/* Reserved */
390+
u32 reserved_0;
379391
};
380392

381393
/**
@@ -425,9 +437,6 @@ struct vpu_jsm_metric_streamer_start {
425437
u64 next_buffer_size;
426438
};
427439

428-
static_assert(sizeof(struct vpu_jsm_metric_streamer_start) % 8 == 0,
429-
"vpu_jsm_metric_streamer_start is misaligned");
430-
431440
/**
432441
* @brief Metric streamer stop command structure.
433442
* @see VPU_JSM_MSG_METRIC_STREAMER_STOP
@@ -437,9 +446,6 @@ struct vpu_jsm_metric_streamer_stop {
437446
u64 metric_group_mask;
438447
};
439448

440-
static_assert(sizeof(struct vpu_jsm_metric_streamer_stop) % 8 == 0,
441-
"vpu_jsm_metric_streamer_stop is misaligned");
442-
443449
/**
444450
* Provide VPU FW with buffers to write metric data.
445451
* @see VPU_JSM_MSG_METRIC_STREAMER_UPDATE
@@ -471,9 +477,6 @@ struct vpu_jsm_metric_streamer_update {
471477
u64 next_buffer_size;
472478
};
473479

474-
static_assert(sizeof(struct vpu_jsm_metric_streamer_update) % 8 == 0,
475-
"vpu_jsm_metric_streamer_update is misaligned");
476-
477480
struct vpu_ipc_msg_payload_blob_deinit {
478481
/* 64-bit unique ID for the blob to be de-initialized. */
479482
u64 blob_id;
@@ -491,7 +494,7 @@ struct vpu_ipc_msg_payload_job_done {
491494
/* Host SSID */
492495
u32 host_ssid;
493496
/* Zero Padding */
494-
u32 reserved;
497+
u32 reserved_0;
495498
/* Command queue id */
496499
u64 cmdq_id;
497500
};
@@ -500,7 +503,7 @@ struct vpu_jsm_engine_reset_context {
500503
/* Host SSID */
501504
u32 host_ssid;
502505
/* Zero Padding */
503-
u32 reserved;
506+
u32 reserved_0;
504507
/* Command queue id */
505508
u64 cmdq_id;
506509
/* Flags: 0: cause of hang; 1: collateral damage of reset */
@@ -533,6 +536,8 @@ struct vpu_ipc_msg_payload_engine_preempt_done {
533536
struct vpu_ipc_msg_payload_register_db_done {
534537
/* Index of the registered doorbell. */
535538
u32 db_idx;
539+
/* Reserved */
540+
u32 reserved_0;
536541
};
537542

538543
/**
@@ -543,11 +548,15 @@ struct vpu_ipc_msg_payload_register_db_done {
543548
struct vpu_ipc_msg_payload_unregister_db_done {
544549
/* Index of the unregistered doorbell. */
545550
u32 db_idx;
551+
/* Reserved */
552+
u32 reserved_0;
546553
};
547554

548555
struct vpu_ipc_msg_payload_query_engine_hb_done {
549556
/* Engine returning heartbeat value. */
550557
u32 engine_idx;
558+
/* Reserved */
559+
u32 reserved_0;
551560
/* Heartbeat value. */
552561
u64 heartbeat;
553562
};
@@ -559,6 +568,8 @@ struct vpu_ipc_msg_payload_get_power_level_count_done {
559568
* implementations.
560569
*/
561570
u32 power_level_count;
571+
/* Reserved */
572+
u32 reserved_0;
562573
/**
563574
* Power consumption limit for each supported power level in
564575
* [0-100%] range relative to power level 0.
@@ -577,7 +588,7 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup {
577588
* Grace period in 100ns units when preempting another priority band for
578589
* this priority band
579590
*/
580-
u64 grace_period[VPU_HWS_NUM_PRIORITY_BANDS];
591+
u32 grace_period[VPU_HWS_NUM_PRIORITY_BANDS];
581592
/*
582593
* Default quantum in 100ns units for scheduling across processes
583594
* within a priority band
@@ -593,6 +604,8 @@ struct vpu_ipc_msg_payload_hws_priority_band_setup {
593604
* in situations when it's starved by the focus band.
594605
*/
595606
u32 normal_band_percentage;
607+
/* Reserved */
608+
u32 reserved_0;
596609
};
597610

598611
/* HWS create command queue request */
@@ -609,6 +622,8 @@ struct vpu_ipc_msg_payload_hws_create_cmdq {
609622
u64 cmdq_base;
610623
/* Command queue size */
611624
u32 cmdq_size;
625+
/* Reserved */
626+
u32 reserved_0;
612627
};
613628

614629
/* HWS create command queue response */
@@ -806,9 +821,6 @@ struct vpu_jsm_metric_streamer_done {
806821
u64 bytes_written;
807822
};
808823

809-
static_assert(sizeof(struct vpu_jsm_metric_streamer_done) % 8 == 0,
810-
"vpu_jsm_metric_streamer_done is misaligned");
811-
812824
/**
813825
* Metric group description placed in the metric buffer after successful completion
814826
* of the VPU_JSM_MSG_METRIC_STREAMER_INFO command. This is followed by one or more
@@ -848,16 +860,13 @@ struct vpu_jsm_metric_group_descriptor {
848860
u32 name_string_size;
849861
/** Counter description string size, @see name_string_size */
850862
u32 description_string_size;
851-
u32 reserved_0[2];
863+
u64 reserved_0;
852864
/**
853865
* Right after this structure, the VPU writes name and description of
854866
* the metric group.
855867
*/
856868
};
857869

858-
static_assert(sizeof(struct vpu_jsm_metric_group_descriptor) % 8 == 0,
859-
"vpu_jsm_metric_group_descriptor is misaligned");
860-
861870
/**
862871
* Metric counter description, placed in the buffer after vpu_jsm_metric_group_descriptor.
863872
* @see VPU_JSM_MSG_METRIC_STREAMER_INFO
@@ -894,16 +903,13 @@ struct vpu_jsm_metric_counter_descriptor {
894903
u32 component_string_size;
895904
/** Counter string size, @see name_string_size */
896905
u32 units_string_size;
897-
u32 reserved_0[2];
906+
u64 reserved_0;
898907
/**
899908
* Right after this structure, the VPU writes name, description
900909
* component and unit strings.
901910
*/
902911
};
903912

904-
static_assert(sizeof(struct vpu_jsm_metric_counter_descriptor) % 8 == 0,
905-
"vpu_jsm_metric_counter_descriptor is misaligned");
906-
907913
/**
908914
* Payload for VPU_JSM_MSG_DYNDBG_CONTROL requests.
909915
*
@@ -977,6 +983,8 @@ union vpu_ipc_msg_payload {
977983
* to allow proper handling of VPU cache operations.
978984
*/
979985
struct vpu_jsm_msg {
986+
/* Reserved */
987+
u64 reserved_0;
980988
/* Message type, see vpu_ipc_msg_type enum. */
981989
u32 type;
982990
/* Buffer status, see vpu_ipc_msg_status enum. */
@@ -988,6 +996,7 @@ struct vpu_jsm_msg {
988996
u32 request_id;
989997
/* Request return code set by the VPU, see VPU_JSM_STATUS_* defines. */
990998
u32 result;
999+
u64 reserved_1;
9911000
/* Message payload depending on message type, see vpu_ipc_msg_payload union. */
9921001
union vpu_ipc_msg_payload payload;
9931002
};

0 commit comments

Comments
 (0)