Re: [PATCH v7 3/3] crypto: hisilicon - register zip engine to uacce
On Tue, 5 Nov 2019 16:34:48 +0800 zhangfei wrote: > Hi, Jonathan > > On 2019/11/1 上午1:53, Jonathan Cameron wrote: > > On Tue, 29 Oct 2019 14:40:16 +0800 > > Zhangfei Gao wrote: > > > >> Register qm to uacce framework for user crypto driver > >> > >> Signed-off-by: Zhangfei Gao > >> Signed-off-by: Zhou Wang > > Hi. > > > > This shows there is probably a race during setup that you should close. > > Userspace interface is exposed before the driver is ready to handle it. > > > > Few other bits inline. > > > > Thanks, > > > > Jonathan > > > >> --- > >> drivers/crypto/hisilicon/qm.c | 253 > >> ++-- > >> drivers/crypto/hisilicon/qm.h | 13 +- > >> drivers/crypto/hisilicon/zip/zip_main.c | 39 ++--- > >> include/uapi/misc/uacce/qm.h| 23 +++ > >> 4 files changed, 292 insertions(+), 36 deletions(-) > >> create mode 100644 include/uapi/misc/uacce/qm.h > >> > >> diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c > >> index a8ed6990..4b9cced 100644 > >> --- a/drivers/crypto/hisilicon/qm.c > >> +++ b/drivers/crypto/hisilicon/qm.c > >> @@ -9,6 +9,9 @@ > >> #include > >> #include > >> #include > >> +#include > >> +#include > >> +#include > >> #include "qm.h" > >> > >> /* eq/aeq irq enable */ > >> @@ -465,17 +468,22 @@ static void qm_cq_head_update(struct hisi_qp *qp) > >> > >> static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) > >> { > >> - struct qm_cqe *cqe = qp->cqe + qp->qp_status.cq_head; > >> - > >> - if (qp->req_cb) { > >> - while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { > >> - dma_rmb(); > >> - qp->req_cb(qp, qp->sqe + qm->sqe_size * cqe->sq_head); > >> - qm_cq_head_update(qp); > >> - cqe = qp->cqe + qp->qp_status.cq_head; > >> - qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, > >> -qp->qp_status.cq_head, 0); > >> - atomic_dec(>qp_status.used); > >> + struct qm_cqe *cqe; > >> + > >> + if (qp->event_cb) { > >> + qp->event_cb(qp); > >> + } else { > >> + cqe = qp->cqe + qp->qp_status.cq_head; > >> + > >> + if (qp->req_cb) { > >> + while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { > >> + dma_rmb(); > >> + qp->req_cb(qp, qp->sqe + qm->sqe_size * > >> + cqe->sq_head); > >> + qm_cq_head_update(qp); > >> + cqe = qp->cqe + qp->qp_status.cq_head; > >> + atomic_dec(>qp_status.used); > >> + } > >>} > >> > >>/* set c_flag */ > >> @@ -1397,6 +1405,220 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm) > >>} > >> } > >> > >> +static void qm_qp_event_notifier(struct hisi_qp *qp) > >> +{ > >> + wake_up_interruptible(>uacce_q->wait); > >> +} > >> + > >> +static int hisi_qm_get_available_instances(struct uacce_device *uacce) > >> +{ > >> + int i, ret; > >> + struct hisi_qm *qm = uacce->priv; > >> + > >> + read_lock(>qps_lock); > >> + for (i = 0, ret = 0; i < qm->qp_num; i++) > >> + if (!qm->qp_array[i]) > >> + ret++; > >> + read_unlock(>qps_lock); > >> + > >> + return ret; > >> +} > >> + > >> +static int hisi_qm_uacce_get_queue(struct uacce_device *uacce, > >> + unsigned long arg, > >> + struct uacce_queue *q) > >> +{ > >> + struct hisi_qm *qm = uacce->priv; > >> + struct hisi_qp *qp; > >> + u8 alg_type = 0; > >> + > >> + qp = hisi_qm_create_qp(qm, alg_type); > >> + if (IS_ERR(qp)) > >> + return PTR_ERR(qp); > >> + > >> + q->priv = qp; > >> + q->uacce = uacce; > >> + qp->uacce_q = q; > >> + qp->event_cb = qm_qp_event_notifier; > >> + qp->pasid = arg; > >> + > >> + return 0; > >> +} > >> + > >> +static void hisi_qm_uacce_put_queue(struct uacce_queue *q) > >> +{ > >> + struct hisi_qp *qp = q->priv; > >> + > >> + /* > >> + * As put_queue is only called in uacce_mode=1, and only one queue can > > We got rid of the modes I think so comment needs an update. > Yes > > > >> + * be used in this mode. we flush all sqc cache back in put queue. > >> + */ > >> + hisi_qm_cache_wb(qp->qm); > >> + > >> + /* need to stop hardware, but can not support in v1 */ > >> + hisi_qm_release_qp(qp); > > Should we just drop support for the v1 hardware if we can't do this? > > > >> +} > >> + > >> +/* map sq/cq/doorbell to user space */ > >> +static int hisi_qm_uacce_mmap(struct uacce_queue *q, > >> +struct vm_area_struct *vma, > >> +struct uacce_qfile_region *qfr) > >> +{ > >> + struct hisi_qp *qp = q->priv; > >> + struct hisi_qm *qm = qp->qm; > >> + size_t sz = vma->vm_end - vma->vm_start; > >> + struct pci_dev *pdev = qm->pdev; > >> +
Re: [PATCH v7 3/3] crypto: hisilicon - register zip engine to uacce
Hi, Jonathan On 2019/11/1 上午1:53, Jonathan Cameron wrote: On Tue, 29 Oct 2019 14:40:16 +0800 Zhangfei Gao wrote: Register qm to uacce framework for user crypto driver Signed-off-by: Zhangfei Gao Signed-off-by: Zhou Wang Hi. This shows there is probably a race during setup that you should close. Userspace interface is exposed before the driver is ready to handle it. Few other bits inline. Thanks, Jonathan --- drivers/crypto/hisilicon/qm.c | 253 ++-- drivers/crypto/hisilicon/qm.h | 13 +- drivers/crypto/hisilicon/zip/zip_main.c | 39 ++--- include/uapi/misc/uacce/qm.h| 23 +++ 4 files changed, 292 insertions(+), 36 deletions(-) create mode 100644 include/uapi/misc/uacce/qm.h diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index a8ed6990..4b9cced 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "qm.h" /* eq/aeq irq enable */ @@ -465,17 +468,22 @@ static void qm_cq_head_update(struct hisi_qp *qp) static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) { - struct qm_cqe *cqe = qp->cqe + qp->qp_status.cq_head; - - if (qp->req_cb) { - while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { - dma_rmb(); - qp->req_cb(qp, qp->sqe + qm->sqe_size * cqe->sq_head); - qm_cq_head_update(qp); - cqe = qp->cqe + qp->qp_status.cq_head; - qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, - qp->qp_status.cq_head, 0); - atomic_dec(>qp_status.used); + struct qm_cqe *cqe; + + if (qp->event_cb) { + qp->event_cb(qp); + } else { + cqe = qp->cqe + qp->qp_status.cq_head; + + if (qp->req_cb) { + while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { + dma_rmb(); + qp->req_cb(qp, qp->sqe + qm->sqe_size * + cqe->sq_head); + qm_cq_head_update(qp); + cqe = qp->cqe + qp->qp_status.cq_head; + atomic_dec(>qp_status.used); + } } /* set c_flag */ @@ -1397,6 +1405,220 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm) } } +static void qm_qp_event_notifier(struct hisi_qp *qp) +{ + wake_up_interruptible(>uacce_q->wait); +} + +static int hisi_qm_get_available_instances(struct uacce_device *uacce) +{ + int i, ret; + struct hisi_qm *qm = uacce->priv; + + read_lock(>qps_lock); + for (i = 0, ret = 0; i < qm->qp_num; i++) + if (!qm->qp_array[i]) + ret++; + read_unlock(>qps_lock); + + return ret; +} + +static int hisi_qm_uacce_get_queue(struct uacce_device *uacce, + unsigned long arg, + struct uacce_queue *q) +{ + struct hisi_qm *qm = uacce->priv; + struct hisi_qp *qp; + u8 alg_type = 0; + + qp = hisi_qm_create_qp(qm, alg_type); + if (IS_ERR(qp)) + return PTR_ERR(qp); + + q->priv = qp; + q->uacce = uacce; + qp->uacce_q = q; + qp->event_cb = qm_qp_event_notifier; + qp->pasid = arg; + + return 0; +} + +static void hisi_qm_uacce_put_queue(struct uacce_queue *q) +{ + struct hisi_qp *qp = q->priv; + + /* +* As put_queue is only called in uacce_mode=1, and only one queue can We got rid of the modes I think so comment needs an update. Yes +* be used in this mode. we flush all sqc cache back in put queue. +*/ + hisi_qm_cache_wb(qp->qm); + + /* need to stop hardware, but can not support in v1 */ + hisi_qm_release_qp(qp); Should we just drop support for the v1 hardware if we can't do this? +} + +/* map sq/cq/doorbell to user space */ +static int hisi_qm_uacce_mmap(struct uacce_queue *q, + struct vm_area_struct *vma, + struct uacce_qfile_region *qfr) +{ + struct hisi_qp *qp = q->priv; + struct hisi_qm *qm = qp->qm; + size_t sz = vma->vm_end - vma->vm_start; + struct pci_dev *pdev = qm->pdev; + struct device *dev = >dev; + unsigned long vm_pgoff; + int ret; + + switch (qfr->type) { + case UACCE_QFRT_MMIO: + if (qm->ver == QM_HW_V2) { + if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE)) + return -EINVAL; + } else { + if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR) +
Re: [PATCH v7 3/3] crypto: hisilicon - register zip engine to uacce
On Tue, 29 Oct 2019 14:40:16 +0800 Zhangfei Gao wrote: > Register qm to uacce framework for user crypto driver > > Signed-off-by: Zhangfei Gao > Signed-off-by: Zhou Wang Hi. This shows there is probably a race during setup that you should close. Userspace interface is exposed before the driver is ready to handle it. Few other bits inline. Thanks, Jonathan > --- > drivers/crypto/hisilicon/qm.c | 253 > ++-- > drivers/crypto/hisilicon/qm.h | 13 +- > drivers/crypto/hisilicon/zip/zip_main.c | 39 ++--- > include/uapi/misc/uacce/qm.h| 23 +++ > 4 files changed, 292 insertions(+), 36 deletions(-) > create mode 100644 include/uapi/misc/uacce/qm.h > > diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c > index a8ed6990..4b9cced 100644 > --- a/drivers/crypto/hisilicon/qm.c > +++ b/drivers/crypto/hisilicon/qm.c > @@ -9,6 +9,9 @@ > #include > #include > #include > +#include > +#include > +#include > #include "qm.h" > > /* eq/aeq irq enable */ > @@ -465,17 +468,22 @@ static void qm_cq_head_update(struct hisi_qp *qp) > > static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) > { > - struct qm_cqe *cqe = qp->cqe + qp->qp_status.cq_head; > - > - if (qp->req_cb) { > - while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { > - dma_rmb(); > - qp->req_cb(qp, qp->sqe + qm->sqe_size * cqe->sq_head); > - qm_cq_head_update(qp); > - cqe = qp->cqe + qp->qp_status.cq_head; > - qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, > - qp->qp_status.cq_head, 0); > - atomic_dec(>qp_status.used); > + struct qm_cqe *cqe; > + > + if (qp->event_cb) { > + qp->event_cb(qp); > + } else { > + cqe = qp->cqe + qp->qp_status.cq_head; > + > + if (qp->req_cb) { > + while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { > + dma_rmb(); > + qp->req_cb(qp, qp->sqe + qm->sqe_size * > +cqe->sq_head); > + qm_cq_head_update(qp); > + cqe = qp->cqe + qp->qp_status.cq_head; > + atomic_dec(>qp_status.used); > + } > } > > /* set c_flag */ > @@ -1397,6 +1405,220 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm) > } > } > > +static void qm_qp_event_notifier(struct hisi_qp *qp) > +{ > + wake_up_interruptible(>uacce_q->wait); > +} > + > +static int hisi_qm_get_available_instances(struct uacce_device *uacce) > +{ > + int i, ret; > + struct hisi_qm *qm = uacce->priv; > + > + read_lock(>qps_lock); > + for (i = 0, ret = 0; i < qm->qp_num; i++) > + if (!qm->qp_array[i]) > + ret++; > + read_unlock(>qps_lock); > + > + return ret; > +} > + > +static int hisi_qm_uacce_get_queue(struct uacce_device *uacce, > +unsigned long arg, > +struct uacce_queue *q) > +{ > + struct hisi_qm *qm = uacce->priv; > + struct hisi_qp *qp; > + u8 alg_type = 0; > + > + qp = hisi_qm_create_qp(qm, alg_type); > + if (IS_ERR(qp)) > + return PTR_ERR(qp); > + > + q->priv = qp; > + q->uacce = uacce; > + qp->uacce_q = q; > + qp->event_cb = qm_qp_event_notifier; > + qp->pasid = arg; > + > + return 0; > +} > + > +static void hisi_qm_uacce_put_queue(struct uacce_queue *q) > +{ > + struct hisi_qp *qp = q->priv; > + > + /* > + * As put_queue is only called in uacce_mode=1, and only one queue can We got rid of the modes I think so comment needs an update. > + * be used in this mode. we flush all sqc cache back in put queue. > + */ > + hisi_qm_cache_wb(qp->qm); > + > + /* need to stop hardware, but can not support in v1 */ > + hisi_qm_release_qp(qp); Should we just drop support for the v1 hardware if we can't do this? > +} > + > +/* map sq/cq/doorbell to user space */ > +static int hisi_qm_uacce_mmap(struct uacce_queue *q, > + struct vm_area_struct *vma, > + struct uacce_qfile_region *qfr) > +{ > + struct hisi_qp *qp = q->priv; > + struct hisi_qm *qm = qp->qm; > + size_t sz = vma->vm_end - vma->vm_start; > + struct pci_dev *pdev = qm->pdev; > + struct device *dev = >dev; > + unsigned long vm_pgoff; > + int ret; > + > + switch (qfr->type) { > + case UACCE_QFRT_MMIO: > + if (qm->ver == QM_HW_V2) { > + if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + > + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE)) > + return -EINVAL; > + } else { > +
[PATCH v7 3/3] crypto: hisilicon - register zip engine to uacce
Register qm to uacce framework for user crypto driver Signed-off-by: Zhangfei Gao Signed-off-by: Zhou Wang --- drivers/crypto/hisilicon/qm.c | 253 ++-- drivers/crypto/hisilicon/qm.h | 13 +- drivers/crypto/hisilicon/zip/zip_main.c | 39 ++--- include/uapi/misc/uacce/qm.h| 23 +++ 4 files changed, 292 insertions(+), 36 deletions(-) create mode 100644 include/uapi/misc/uacce/qm.h diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index a8ed6990..4b9cced 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "qm.h" /* eq/aeq irq enable */ @@ -465,17 +468,22 @@ static void qm_cq_head_update(struct hisi_qp *qp) static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) { - struct qm_cqe *cqe = qp->cqe + qp->qp_status.cq_head; - - if (qp->req_cb) { - while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { - dma_rmb(); - qp->req_cb(qp, qp->sqe + qm->sqe_size * cqe->sq_head); - qm_cq_head_update(qp); - cqe = qp->cqe + qp->qp_status.cq_head; - qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, - qp->qp_status.cq_head, 0); - atomic_dec(>qp_status.used); + struct qm_cqe *cqe; + + if (qp->event_cb) { + qp->event_cb(qp); + } else { + cqe = qp->cqe + qp->qp_status.cq_head; + + if (qp->req_cb) { + while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { + dma_rmb(); + qp->req_cb(qp, qp->sqe + qm->sqe_size * + cqe->sq_head); + qm_cq_head_update(qp); + cqe = qp->cqe + qp->qp_status.cq_head; + atomic_dec(>qp_status.used); + } } /* set c_flag */ @@ -1397,6 +1405,220 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm) } } +static void qm_qp_event_notifier(struct hisi_qp *qp) +{ + wake_up_interruptible(>uacce_q->wait); +} + +static int hisi_qm_get_available_instances(struct uacce_device *uacce) +{ + int i, ret; + struct hisi_qm *qm = uacce->priv; + + read_lock(>qps_lock); + for (i = 0, ret = 0; i < qm->qp_num; i++) + if (!qm->qp_array[i]) + ret++; + read_unlock(>qps_lock); + + return ret; +} + +static int hisi_qm_uacce_get_queue(struct uacce_device *uacce, + unsigned long arg, + struct uacce_queue *q) +{ + struct hisi_qm *qm = uacce->priv; + struct hisi_qp *qp; + u8 alg_type = 0; + + qp = hisi_qm_create_qp(qm, alg_type); + if (IS_ERR(qp)) + return PTR_ERR(qp); + + q->priv = qp; + q->uacce = uacce; + qp->uacce_q = q; + qp->event_cb = qm_qp_event_notifier; + qp->pasid = arg; + + return 0; +} + +static void hisi_qm_uacce_put_queue(struct uacce_queue *q) +{ + struct hisi_qp *qp = q->priv; + + /* +* As put_queue is only called in uacce_mode=1, and only one queue can +* be used in this mode. we flush all sqc cache back in put queue. +*/ + hisi_qm_cache_wb(qp->qm); + + /* need to stop hardware, but can not support in v1 */ + hisi_qm_release_qp(qp); +} + +/* map sq/cq/doorbell to user space */ +static int hisi_qm_uacce_mmap(struct uacce_queue *q, + struct vm_area_struct *vma, + struct uacce_qfile_region *qfr) +{ + struct hisi_qp *qp = q->priv; + struct hisi_qm *qm = qp->qm; + size_t sz = vma->vm_end - vma->vm_start; + struct pci_dev *pdev = qm->pdev; + struct device *dev = >dev; + unsigned long vm_pgoff; + int ret; + + switch (qfr->type) { + case UACCE_QFRT_MMIO: + if (qm->ver == QM_HW_V2) { + if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + + QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE)) + return -EINVAL; + } else { + if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR) + return -EINVAL; + } + + vma->vm_flags |= VM_IO; + + return remap_pfn_range(vma, vma->vm_start, + qm->phys_base >> PAGE_SHIFT, + sz, pgprot_noncached(vma->vm_page_prot)); + case UACCE_QFRT_DUS: + if (sz != qp->qdma.size) + return -EINVAL; + + /*