Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: hisilicon/qm - obtain the mailbox configuration at one time

The malibox needs to be triggered by a 128bit atomic operation.
The reason is that the PF and VFs of the device share the mmio memory
of the mailbox, and the mutex cannot lock mailbox operations in
different functions, especially when passing through VFs to
virtual machines.

Currently, the write operation to the mailbox is already a 128-bit
atomic write. The read operation also needs to be modified to a
128-bit atomic read. Since there is no general 128-bit IO memory
access API in the current ARM64 architecture, and the stp and ldp
instructions do not guarantee atomic access to device memory, they
cannot be extracted as a general API. Therefore, the 128-bit atomic
read and write operations need to be implemented in the driver.

Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Weili Qian and committed by
Herbert Xu
3296992f fc8ae11b

+89 -49
+88 -49
drivers/crypto/hisilicon/qm.c
··· 31 31 /* mailbox */ 32 32 #define QM_MB_PING_ALL_VFS 0xffff 33 33 #define QM_MB_STATUS_MASK GENMASK(12, 9) 34 + #define QM_MB_BUSY_MASK BIT(13) 34 35 35 36 /* sqc shift */ 36 37 #define QM_SQ_HOP_NUM_SHIFT 0 ··· 583 582 mailbox->rsvd = 0; 584 583 } 585 584 586 - /* return 0 mailbox ready, -ETIMEDOUT hardware timeout */ 587 - int hisi_qm_wait_mb_ready(struct hisi_qm *qm) 585 + /* 586 + * The mailbox is 128 bits and requires a single read/write operation. 587 + * Since there is no general 128-bit IO memory access API in the current 588 + * ARM64 architecture, this needs to be implemented in the driver. 589 + */ 590 + static struct qm_mailbox qm_mb_read(struct hisi_qm *qm) 588 591 { 589 - u32 val; 592 + struct qm_mailbox mailbox = {0}; 590 593 591 - return readl_relaxed_poll_timeout(qm->io_base + QM_MB_CMD_SEND_BASE, 592 - val, !((val >> QM_MB_BUSY_SHIFT) & 593 - 0x1), POLL_PERIOD, POLL_TIMEOUT); 594 + #if IS_ENABLED(CONFIG_ARM64) 595 + const void __iomem *fun_base = qm->io_base + QM_MB_CMD_SEND_BASE; 596 + unsigned long tmp0, tmp1; 597 + 598 + asm volatile("ldp %0, %1, %3\n" 599 + "stp %0, %1, %2\n" 600 + : "=&r" (tmp0), 601 + "=&r" (tmp1), 602 + "+Q" (mailbox) 603 + : "Q" (*((char __iomem *)fun_base)) 604 + : "memory"); 605 + #endif 606 + 607 + return mailbox; 594 608 } 595 - EXPORT_SYMBOL_GPL(hisi_qm_wait_mb_ready); 596 609 597 610 /* 128 bit should be written to hardware at one time to trigger a mailbox */ 598 611 static void qm_mb_write(struct hisi_qm *qm, const void *src) ··· 629 614 #endif 630 615 } 631 616 632 - static int qm_mb_nolock(struct hisi_qm *qm, struct qm_mailbox *mailbox) 617 + int hisi_qm_wait_mb_ready(struct hisi_qm *qm) 633 618 { 619 + struct qm_mailbox mailbox = {0}; 634 620 int ret; 635 - u32 val; 636 621 637 - if (unlikely(hisi_qm_wait_mb_ready(qm))) { 622 + ret = read_poll_timeout(qm_mb_read, mailbox, 623 + !(le16_to_cpu(mailbox.w0) & QM_MB_BUSY_MASK), 624 + POLL_PERIOD, POLL_TIMEOUT, 625 + true, qm); 626 + if (ret) 638 627 dev_err(&qm->pdev->dev, "QM mailbox is busy to start!\n"); 639 - ret = -EBUSY; 640 - goto mb_busy; 628 + 629 + return ret; 630 + } 631 + EXPORT_SYMBOL_GPL(hisi_qm_wait_mb_ready); 632 + 633 + static int qm_wait_mb_finish(struct hisi_qm *qm, struct qm_mailbox *mailbox) 634 + { 635 + struct device *dev = &qm->pdev->dev; 636 + int ret; 637 + 638 + ret = read_poll_timeout(qm_mb_read, *mailbox, 639 + !(le16_to_cpu(mailbox->w0) & QM_MB_BUSY_MASK), 640 + POLL_PERIOD, POLL_TIMEOUT, 641 + true, qm); 642 + if (ret) { 643 + dev_err(dev, "QM mailbox operation timeout!\n"); 644 + return ret; 641 645 } 642 646 643 - qm_mb_write(qm, mailbox); 644 - 645 - if (unlikely(hisi_qm_wait_mb_ready(qm))) { 646 - dev_err(&qm->pdev->dev, "QM mailbox operation timeout!\n"); 647 - ret = -ETIMEDOUT; 648 - goto mb_busy; 649 - } 650 - 651 - val = readl(qm->io_base + QM_MB_CMD_SEND_BASE); 652 - if (val & QM_MB_STATUS_MASK) { 653 - dev_err(&qm->pdev->dev, "QM mailbox operation failed!\n"); 654 - ret = -EIO; 655 - goto mb_busy; 647 + if (le16_to_cpu(mailbox->w0) & QM_MB_STATUS_MASK) { 648 + dev_err(dev, "QM mailbox operation failed!\n"); 649 + return -EIO; 656 650 } 657 651 658 652 return 0; 653 + } 659 654 660 - mb_busy: 655 + static int qm_mb_nolock(struct hisi_qm *qm, struct qm_mailbox *mailbox) 656 + { 657 + int ret; 658 + 659 + ret = hisi_qm_wait_mb_ready(qm); 660 + if (ret) 661 + goto mb_err_cnt_increase; 662 + 663 + qm_mb_write(qm, mailbox); 664 + 665 + ret = qm_wait_mb_finish(qm, mailbox); 666 + if (ret) 667 + goto mb_err_cnt_increase; 668 + 669 + return 0; 670 + 671 + mb_err_cnt_increase: 661 672 atomic64_inc(&qm->debug.dfx.mb_err_cnt); 662 673 return ret; 663 674 } ··· 703 662 return ret; 704 663 } 705 664 EXPORT_SYMBOL_GPL(hisi_qm_mb); 665 + 666 + int hisi_qm_mb_read(struct hisi_qm *qm, u64 *base, u8 cmd, u16 queue) 667 + { 668 + struct qm_mailbox mailbox; 669 + int ret; 670 + 671 + qm_mb_pre_init(&mailbox, cmd, 0, queue, 1); 672 + mutex_lock(&qm->mailbox_lock); 673 + ret = qm_mb_nolock(qm, &mailbox); 674 + mutex_unlock(&qm->mailbox_lock); 675 + if (ret) 676 + return ret; 677 + 678 + *base = le32_to_cpu(mailbox.base_l) | 679 + ((u64)le32_to_cpu(mailbox.base_h) << 32); 680 + 681 + return 0; 682 + } 683 + EXPORT_SYMBOL_GPL(hisi_qm_mb_read); 706 684 707 685 /* op 0: set xqc information to hardware, 1: get xqc information from hardware. */ 708 686 int qm_set_and_get_xqc(struct hisi_qm *qm, u8 cmd, void *xqc, u32 qp_id, bool op) ··· 1439 1379 u64 sqc_vft; 1440 1380 int ret; 1441 1381 1442 - ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1); 1382 + ret = hisi_qm_mb_read(qm, &sqc_vft, QM_MB_CMD_SQC_VFT_V2, 0); 1443 1383 if (ret) 1444 1384 return ret; 1445 1385 1446 - sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) | 1447 - ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32); 1448 1386 *base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2); 1449 1387 *number = (QM_SQC_VFT_NUM_MASK_V2 & 1450 1388 (sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1; ··· 1580 1522 } 1581 1523 1582 1524 return ACC_ERR_RECOVERED; 1583 - } 1584 - 1585 - static int qm_get_mb_cmd(struct hisi_qm *qm, u64 *msg, u16 fun_num) 1586 - { 1587 - struct qm_mailbox mailbox; 1588 - int ret; 1589 - 1590 - qm_mb_pre_init(&mailbox, QM_MB_CMD_DST, 0, fun_num, 0); 1591 - mutex_lock(&qm->mailbox_lock); 1592 - ret = qm_mb_nolock(qm, &mailbox); 1593 - if (ret) 1594 - goto err_unlock; 1595 - 1596 - *msg = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) | 1597 - ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32); 1598 - 1599 - err_unlock: 1600 - mutex_unlock(&qm->mailbox_lock); 1601 - return ret; 1602 1525 } 1603 1526 1604 1527 static void qm_clear_cmd_interrupt(struct hisi_qm *qm, u64 vf_mask) ··· 1910 1871 u64 msg; 1911 1872 int ret; 1912 1873 1913 - ret = qm_get_mb_cmd(qm, &msg, fun_num); 1874 + ret = hisi_qm_mb_read(qm, &msg, QM_MB_CMD_DST, fun_num); 1914 1875 if (ret) 1915 1876 return ret; 1916 1877
+1
include/linux/hisi_acc_qm.h
··· 571 571 int hisi_qm_wait_mb_ready(struct hisi_qm *qm); 572 572 int hisi_qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue, 573 573 bool op); 574 + int hisi_qm_mb_read(struct hisi_qm *qm, u64 *base, u8 cmd, u16 queue); 574 575 575 576 struct hisi_acc_sgl_pool; 576 577 struct hisi_acc_hw_sgl *hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,