From 03a0d6449d8c31d1d5d057d1a22d1d4052e1322f Mon Sep 17 00:00:00 2001 From: xiongmengbiao Date: Wed, 23 Apr 2025 20:39:39 +0800 Subject: [PATCH] crypto: ccp: fix The high priority queue changes cmd_id of the queued elements hygon inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICCSI5 CVE: NA --------------------------- 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 Fixes: 5b43a3ca1195 ("crypto: ccp: Support vpsp ringbuffer overcommit") Signed-off-by: xiongmengbiao --- drivers/crypto/ccp/hygon/psp-dev.c | 33 ++++++++++++------------------ include/linux/psp-hygon.h | 1 + 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/crypto/ccp/hygon/psp-dev.c b/drivers/crypto/ccp/hygon/psp-dev.c index 039e3ed6ce53..dd15bd7ca726 100644 --- a/drivers/crypto/ccp/hygon/psp-dev.c +++ b/drivers/crypto/ccp/hygon/psp-dev.c @@ -720,9 +720,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)); @@ -731,6 +732,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; @@ -848,8 +860,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 || !hygon_psp_hooks.sev_dev_hooks_installed) @@ -880,23 +890,6 @@ static int __psp_do_ringbuffer_cmds_locked(struct csv_ringbuffer_queue *ring_buf rb_head |= 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 (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) diff --git a/include/linux/psp-hygon.h b/include/linux/psp-hygon.h index 4a26c4f7a131..181c046699f2 100644 --- a/include/linux/psp-hygon.h +++ b/include/linux/psp-hygon.h @@ -84,6 +84,7 @@ enum csv_comm_state { #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 csv_data_hgsc_cert_import - HGSC_CERT_IMPORT command parameters -- Gitee