Re: [PATCH v7 3/3] crypto: hisilicon - register zip engine to uacce

2019-11-11 Thread Jonathan Cameron
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

2019-11-05 Thread zhangfei

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

2019-10-31 Thread Jonathan Cameron
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

2019-10-29 Thread Zhangfei Gao
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;
+
+   /*