From 1d065a7520f39e880d93df5fde7a4fef7fb2c805 Mon Sep 17 00:00:00 2001 From: Mingqiang Ling Date: Wed, 24 Apr 2019 18:08:42 +0800 Subject: [PATCH] arm64: Support independence of Warpdrive on page size driver inclusion category: bugfix bugzilla: 13683 CVE: NA ------------------------------------------------- Support independence of Warpdrive on page size The 'qfrs_pg_start' which was showed for user space is updated as 'qfrs_offset'. Secondly, try to mmap 2 pages in MMIO region as PAGE_SIZE is 4k. As a result, user space warpdrive need no page size any longer. Signed-off-by: xuzaibo Reviewed-by: wangzhou Signed-off-by: Mingqiang Ling Reviewed-by: Xie XiuQi Signed-off-by: Yang Yingliang --- drivers/crypto/hisilicon/qm.c | 40 +++++++++++++++++----------- drivers/crypto/hisilicon/qm_usr_if.h | 5 ++-- drivers/uacce/uacce.c | 25 ++++++++++------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index ab8309dff7dd..fb71859c04a6 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -1446,24 +1446,28 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q, size_t sz = vma->vm_end - vma->vm_start; struct pci_dev *pdev = qm->pdev; struct device *dev = &pdev->dev; - unsigned long long mmio_base; unsigned long vm_pgoff; int ret; switch (qfr->type) { case UACCE_QFRT_MMIO: - WARN_ON(sz > PAGE_SIZE); - vma->vm_flags |= VM_IO; - if (qm->ver == QM_HW_V1) - mmio_base = qm->phys_base; + + /* Try to mmap corresponding pages size region */ + if (qm->ver == QM_HW_V2) + WARN_ON(sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + + QM_V2_DOORBELL_OFFSET / PAGE_SIZE)); else - mmio_base = qm->phys_base + QM_V2_BASE_OFFSET; + WARN_ON(sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR); + + vma->vm_flags |= VM_IO; + /* - * Warning: This is not safe as multiple queues use the same - * doorbell, v1 hardware interface problem. will fix it in v2 + * Warning: This is not safe as multiple processes use the same + * doorbell, v1/v2 hardware interface problem. It will be fixed + * it in next version. */ return remap_pfn_range(vma, vma->vm_start, - mmio_base >> PAGE_SHIFT, + qm->phys_base >> PAGE_SHIFT, sz, pgprot_noncached(vma->vm_page_prot)); case UACCE_QFRT_DUS: if (qm->use_dma_api) { @@ -2009,6 +2013,7 @@ int hisi_qm_start(struct hisi_qm *qm) struct uacce_ops *ops = qm->uacce.ops; unsigned long dus_page_nr = 0; unsigned long dko_page_nr = 0; + unsigned long mmio_page_nr; if (qm->use_uacce) { dus_page_nr = (PAGE_SIZE - 1 + qm->sqe_size * QM_Q_DEPTH + @@ -2032,18 +2037,21 @@ int hisi_qm_start(struct hisi_qm *qm) /* reset qfr definition */ #ifdef CONFIG_CRYPTO_QM_UACCE + if (qm->ver == QM_HW_V2) + mmio_page_nr = QM_DOORBELL_PAGE_NR + + QM_V2_DOORBELL_OFFSET / PAGE_SIZE; + else + mmio_page_nr = QM_DOORBELL_PAGE_NR; if (qm->use_uacce && qm->use_dma_api) { ops->qf_pg_start[UACCE_QFRT_MMIO] = 0; ops->qf_pg_start[UACCE_QFRT_DKO] = UACCE_QFR_NA; - ops->qf_pg_start[UACCE_QFRT_DUS] = QM_DOORBELL_PAGE_NR; - ops->qf_pg_start[UACCE_QFRT_SS] = QM_DOORBELL_PAGE_NR + - dus_page_nr; + ops->qf_pg_start[UACCE_QFRT_DUS] = mmio_page_nr; + ops->qf_pg_start[UACCE_QFRT_SS] = mmio_page_nr + dus_page_nr; } else if (qm->use_uacce) { ops->qf_pg_start[UACCE_QFRT_MMIO] = 0; - ops->qf_pg_start[UACCE_QFRT_DKO] = QM_DOORBELL_PAGE_NR; - ops->qf_pg_start[UACCE_QFRT_DUS] = QM_DOORBELL_PAGE_NR + - dko_page_nr; - ops->qf_pg_start[UACCE_QFRT_SS] = QM_DOORBELL_PAGE_NR + + ops->qf_pg_start[UACCE_QFRT_DKO] = mmio_page_nr; + ops->qf_pg_start[UACCE_QFRT_DUS] = mmio_page_nr + dko_page_nr; + ops->qf_pg_start[UACCE_QFRT_SS] = mmio_page_nr + dko_page_nr + dus_page_nr; } diff --git a/drivers/crypto/hisilicon/qm_usr_if.h b/drivers/crypto/hisilicon/qm_usr_if.h index ca88e6d8dd7a..a8086ae0f3b8 100644 --- a/drivers/crypto/hisilicon/qm_usr_if.h +++ b/drivers/crypto/hisilicon/qm_usr_if.h @@ -8,10 +8,11 @@ #define QM_Q_DEPTH 1024 /* page number for queue file region */ -#define QM_DOORBELL_PAGE_NR 1 +#define QM_DOORBELL_PAGE_NR 1 -#define QM_DOORBELL_OFFSET 0x340 +#define QM_DOORBELL_OFFSET 0x340 +#define QM_V2_DOORBELL_OFFSET 0x1000 struct cqe { __le32 rsvd0; diff --git a/drivers/uacce/uacce.c b/drivers/uacce/uacce.c index 00d252100073..df8d0a81fcc2 100644 --- a/drivers/uacce/uacce.c +++ b/drivers/uacce/uacce.c @@ -920,22 +920,27 @@ uacce_dev_show_algorithms(struct device *dev, static DEVICE_ATTR(algorithms, S_IRUGO, uacce_dev_show_algorithms, NULL); -static ssize_t -uacce_dev_show_qfrs_pg_start(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t uacce_dev_show_qfrs_offset(struct device *dev, + struct device_attribute *attr, + char *buf) { struct uacce *uacce = UACCE_FROM_CDEV_ATTR(dev); int i, ret; + unsigned long offset; - for (i = 0, ret = 0; i < UACCE_QFRT_MAX - 1; i++) - ret += sprintf(buf + ret, "%lu\t", uacce->ops->qf_pg_start[i]); - - ret += sprintf(buf + ret, "%lu\n", uacce->ops->qf_pg_start[i]); + for (i = 0, ret = 0; i < UACCE_QFRT_MAX; i++) { + offset = uacce->ops->qf_pg_start[i]; + if (offset != UACCE_QFR_NA) + offset = offset << PAGE_SHIFT; + if (i == UACCE_QFRT_SS) + break; + ret += sprintf(buf + ret, "%lu\t", offset); + } + ret += sprintf(buf + ret, "%lu\n", offset); return ret; } - -static DEVICE_ATTR(qfrs_pg_start, S_IRUGO, uacce_dev_show_qfrs_pg_start, NULL); +static DEVICE_ATTR(qfrs_offset, S_IRUGO, uacce_dev_show_qfrs_offset, NULL); static struct attribute *uacce_dev_attrs[] = { &dev_attr_id.attr, @@ -945,7 +950,7 @@ static struct attribute *uacce_dev_attrs[] = { &dev_attr_flags.attr, &dev_attr_available_instances.attr, &dev_attr_algorithms.attr, - &dev_attr_qfrs_pg_start.attr, + &dev_attr_qfrs_offset.attr, NULL, }; -- GitLab