anolis: crypto: ccp: fix The high priority queue changes cmd_id of the queued elements

ANBZ: #20925

Before issuing ringbuffer commands:
- Must set a valid cmd ID to prevent PSP reading invalid IDs from empty high-priority queue
- WARNING: Modifying head element's cmd ID without locking may race with enqueued elements

Alternative approach:
Initialize all cmd IDs in high-priority queue to valid values during ringbuffer init

Signed-off-by: xiongmengbiao <xiongmengbiao@hygon.cn>
Reviewed-by: Guixin Liu <kanie@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/5303
This commit is contained in:
xiongmengbiao 2025-04-23 20:39:39 +08:00 committed by 小龙
parent 4bb81556a7
commit 430ccbe970
2 changed files with 14 additions and 20 deletions

View File

@ -1103,9 +1103,10 @@ void psp_ringbuffer_dequeue(struct csv_ringbuffer_queue *ringbuffer,
static int __psp_ringbuffer_queue_init(struct csv_ringbuffer_queue *ring_buffer)
{
int ret = 0;
int ret = 0, i;
void *cmd_ptr_buffer = NULL;
void *stat_val_buffer = NULL;
struct csv_cmdptr_entry *cmd;
memset((void *)ring_buffer, 0, sizeof(struct csv_ringbuffer_queue));
@ -1114,6 +1115,17 @@ static int __psp_ringbuffer_queue_init(struct csv_ringbuffer_queue *ring_buffer)
return -ENOMEM;
csv_queue_init(&ring_buffer->cmd_ptr, cmd_ptr_buffer,
CSV_RING_BUFFER_SIZE, CSV_RING_BUFFER_ESIZE);
/**
* For high-priority queue: initialize all commands with a valid cmd_id
* to prevent PSP from reading invalid cmd_id.
*
* Low-priority queue never
* attempts to read commands from empty queue.
*/
cmd = (struct csv_cmdptr_entry *)ring_buffer->cmd_ptr.data_align;
for (i = 0; i < CSV_RING_BUFFER_ELEMENT_NUM; ++i)
cmd[i].cmd_id = TKM_PSP_CMDID;
stat_val_buffer = kzalloc(CSV_RING_BUFFER_LEN, GFP_KERNEL);
if (!stat_val_buffer) {
ret = -ENOMEM;
@ -1231,8 +1243,6 @@ static int __psp_do_ringbuffer_cmds_locked(struct csv_ringbuffer_queue *ring_buf
struct psp_device *psp = psp_master;
unsigned int rb_tail, rb_head;
unsigned int reg, rb_ctl, ret = 0;
struct csv_queue *queue;
struct csv_cmdptr_entry *first_cmd;
struct csv_ringbuffer_queue *hi_rb, *low_rb;
if (!psp)
@ -1260,23 +1270,6 @@ static int __psp_do_ringbuffer_cmds_locked(struct csv_ringbuffer_queue *ring_buf
rb_head |= csv_cmd_queue_head(&low_rb->cmd_ptr);
iowrite32(rb_head, psp->io_regs + psp->vdata->sev->cmdbuff_addr_lo_reg);
/**
* In some PSP firmware, even if the high priority queue is empty,
* it will still try to read the element at the head of the queue and try to process it.
* When the element at the head of the queue happens to be an illegal cmd id,
* PSP returns the PSP_RBHEAD_QPAUSE_INT_STAT error.
*
* Therefore, now we need to manually set the head element of the queue to
* the default tkm cmd id before sending the ringbuffer each time when
* the high priority queue is empty.
*
* The low priority queue has no such bug, and future PSP firmware should fix it.
*/
if (csv_cmd_queue_size(&hi_rb->cmd_ptr) == 0) {
queue = &hi_rb->cmd_ptr;
first_cmd = (struct csv_cmdptr_entry *)queue->data_align;
first_cmd[queue->head & queue->mask].cmd_id = TKM_PSP_CMDID;
}
pr_debug("ringbuffer launch rb_head %x, rb_tail %x\n", rb_head, rb_tail);
if (psp_worker_notify)

View File

@ -119,6 +119,7 @@ enum csv_cmd {
#define CSV_RING_BUFFER_LEN (CSV_RING_BUFFER_SIZE + CSV_RING_BUFFER_ALIGN)
#define CSV_RING_BUFFER_ESIZE 16
#define PSP_RING_BUFFER_OVERCOMMIT_SIZE 1024
#define CSV_RING_BUFFER_ELEMENT_NUM (CSV_RING_BUFFER_SIZE / CSV_RING_BUFFER_ESIZE)
/**
* struct sev_data_init - INIT command parameters