|
Torsten Duwe |
d02d7f |
From c690c7f6312ce69b426af08ae1da2b9e48a0246f Mon Sep 17 00:00:00 2001
|
|
Torsten Duwe |
d02d7f |
From: Marco Chiappero <marco.chiappero@intel.com>
|
|
Torsten Duwe |
d02d7f |
Date: Thu, 7 Apr 2022 17:54:51 +0100
|
|
Torsten Duwe |
d02d7f |
Subject: [PATCH] crypto: qat - rework the VF2PF interrupt handling logic
|
|
Torsten Duwe |
d02d7f |
Git-commit: c690c7f6312ce69b426af08ae1da2b9e48a0246f
|
|
Torsten Duwe |
d02d7f |
Patch-mainline: v5.19-rc1
|
|
Torsten Duwe |
d02d7f |
References: jsc#PED-1073
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
Change the VF2PF interrupt handler in the PF ISR and the definition of
|
|
Torsten Duwe |
d02d7f |
the internal PFVF API to correct the current implementation, which can
|
|
Torsten Duwe |
d02d7f |
result in missed interrupts.
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
More specifically, current HW generations consider a write to the mask
|
|
Torsten Duwe |
d02d7f |
register, regardless of the value, as an acknowledge of any pending
|
|
Torsten Duwe |
d02d7f |
VF2PF interrupt. Therefore, if there is an interrupt between the source
|
|
Torsten Duwe |
d02d7f |
register read and the mask register write, such interrupt will not be
|
|
Torsten Duwe |
d02d7f |
delivered and silently acknowledged, resulting in a lost VF2PF message.
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
To work around the problem, rather than disabling specific interrupts,
|
|
Torsten Duwe |
d02d7f |
disable all the interrupts and re-enable only the ones that we are not
|
|
Torsten Duwe |
d02d7f |
serving (excluding the already disabled ones too). This will force any
|
|
Torsten Duwe |
d02d7f |
other pending interrupt to be triggered and be serviced by a subsequent
|
|
Torsten Duwe |
d02d7f |
ISR.
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
This new approach requires, however, changes to the interrupt related
|
|
Torsten Duwe |
d02d7f |
pfvf_ops functions. In particular, get_vf2pf_sources() has now been
|
|
Torsten Duwe |
d02d7f |
removed in favor of disable_pending_vf2pf_interrupts(), which not only
|
|
Torsten Duwe |
d02d7f |
retrieves and returns the pending (and enabled) sources, but also
|
|
Torsten Duwe |
d02d7f |
disables them.
|
|
Torsten Duwe |
d02d7f |
As a consequence, introduce the adf_disable_pending_vf2pf_interrupts()
|
|
Torsten Duwe |
d02d7f |
utility in place of adf_disable_vf2pf_interrupts_irq(), which is no
|
|
Torsten Duwe |
d02d7f |
longer needed.
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
Cc: stable@vger.kernel.org
|
|
Torsten Duwe |
d02d7f |
Fixes: 993161d ("crypto: qat - fix handling of VF to PF interrupts")
|
|
Torsten Duwe |
d02d7f |
Signed-off-by: Marco Chiappero <marco.chiappero@intel.com>
|
|
Torsten Duwe |
d02d7f |
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
|
|
Torsten Duwe |
d02d7f |
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
|
|
Torsten Duwe |
d02d7f |
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
|
Torsten Duwe |
d02d7f |
Signed-off-by: Torsten Duwe <duwe@suse.de>
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
---
|
|
Torsten Duwe |
d02d7f |
.../crypto/qat/qat_common/adf_accel_devices.h | 2 +-
|
|
Torsten Duwe |
d02d7f |
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 58 +++++++++-----
|
|
Torsten Duwe |
d02d7f |
drivers/crypto/qat/qat_common/adf_gen4_pfvf.c | 44 ++++++++---
|
|
Torsten Duwe |
d02d7f |
drivers/crypto/qat/qat_common/adf_isr.c | 17 ++---
|
|
Torsten Duwe |
d02d7f |
.../qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 76 +++++++++++++------
|
|
Torsten Duwe |
d02d7f |
5 files changed, 132 insertions(+), 65 deletions(-)
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
|
|
Torsten Duwe |
d02d7f |
index a03c6cf723312..dfa7ee41c5e9c 100644
|
|
Torsten Duwe |
d02d7f |
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
|
|
Torsten Duwe |
d02d7f |
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
|
|
Torsten Duwe |
d02d7f |
@@ -152,9 +152,9 @@ struct adf_pfvf_ops {
|
|
Torsten Duwe |
d02d7f |
int (*enable_comms)(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
d02d7f |
u32 (*get_pf2vf_offset)(u32 i);
|
|
Torsten Duwe |
d02d7f |
u32 (*get_vf2pf_offset)(u32 i);
|
|
Torsten Duwe |
d02d7f |
- u32 (*get_vf2pf_sources)(void __iomem *pmisc_addr);
|
|
Torsten Duwe |
d02d7f |
void (*enable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask);
|
|
Torsten Duwe |
d02d7f |
void (*disable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask);
|
|
Torsten Duwe |
d02d7f |
+ u32 (*disable_pending_vf2pf_interrupts)(void __iomem *pmisc_addr);
|
|
Torsten Duwe |
d02d7f |
int (*send_msg)(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
|
|
Torsten Duwe |
d02d7f |
u32 pfvf_offset, struct mutex *csr_lock);
|
|
Torsten Duwe |
d02d7f |
struct pfvf_message (*recv_msg)(struct adf_accel_dev *accel_dev,
|
|
Torsten Duwe |
d02d7f |
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
|
|
Torsten Duwe |
d02d7f |
index 1a9072aac2ca9..def4cc8e1039a 100644
|
|
Torsten Duwe |
d02d7f |
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
|
|
Torsten Duwe |
d02d7f |
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
|
|
Torsten Duwe |
d02d7f |
@@ -13,6 +13,7 @@
|
|
Torsten Duwe |
d02d7f |
#include "adf_pfvf_utils.h"
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
/* VF2PF interrupts */
|
|
Torsten Duwe |
d02d7f |
+#define ADF_GEN2_VF_MSK 0xFFFF
|
|
Torsten Duwe |
d02d7f |
#define ADF_GEN2_ERR_REG_VF2PF(vf_src) (((vf_src) & 0x01FFFE00) >> 9)
|
|
Torsten Duwe |
d02d7f |
#define ADF_GEN2_ERR_MSK_VF2PF(vf_mask) (((vf_mask) & 0xFFFF) << 9)
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
@@ -50,23 +51,6 @@ static u32 adf_gen2_vf_get_pfvf_offset(u32 i)
|
|
Torsten Duwe |
d02d7f |
return ADF_GEN2_VF_PF2VF_OFFSET;
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
-static u32 adf_gen2_get_vf2pf_sources(void __iomem *pmisc_addr)
|
|
Torsten Duwe |
d02d7f |
-{
|
|
Torsten Duwe |
d02d7f |
- u32 errsou3, errmsk3, vf_int_mask;
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- /* Get the interrupt sources triggered by VFs */
|
|
Torsten Duwe |
d02d7f |
- errsou3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU3);
|
|
Torsten Duwe |
d02d7f |
- vf_int_mask = ADF_GEN2_ERR_REG_VF2PF(errsou3);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- /* To avoid adding duplicate entries to work queue, clear
|
|
Torsten Duwe |
d02d7f |
- * vf_int_mask_sets bits that are already masked in ERRMSK register.
|
|
Torsten Duwe |
d02d7f |
- */
|
|
Torsten Duwe |
d02d7f |
- errmsk3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3);
|
|
Torsten Duwe |
d02d7f |
- vf_int_mask &= ~ADF_GEN2_ERR_REG_VF2PF(errmsk3);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- return vf_int_mask;
|
|
Torsten Duwe |
d02d7f |
-}
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
static void adf_gen2_enable_vf2pf_interrupts(void __iomem *pmisc_addr,
|
|
Torsten Duwe |
d02d7f |
u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
@@ -89,6 +73,44 @@ static void adf_gen2_disable_vf2pf_interrupts(void __iomem *pmisc_addr,
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
+static u32 adf_gen2_disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr)
|
|
Torsten Duwe |
d02d7f |
+{
|
|
Torsten Duwe |
d02d7f |
+ u32 sources, disabled, pending;
|
|
Torsten Duwe |
d02d7f |
+ u32 errsou3, errmsk3;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Get the interrupt sources triggered by VFs */
|
|
Torsten Duwe |
d02d7f |
+ errsou3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU3);
|
|
Torsten Duwe |
d02d7f |
+ sources = ADF_GEN2_ERR_REG_VF2PF(errsou3);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ if (!sources)
|
|
Torsten Duwe |
d02d7f |
+ return 0;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Get the already disabled interrupts */
|
|
Torsten Duwe |
d02d7f |
+ errmsk3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3);
|
|
Torsten Duwe |
d02d7f |
+ disabled = ADF_GEN2_ERR_REG_VF2PF(errmsk3);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ pending = sources & ~disabled;
|
|
Torsten Duwe |
d02d7f |
+ if (!pending)
|
|
Torsten Duwe |
d02d7f |
+ return 0;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Due to HW limitations, when disabling the interrupts, we can't
|
|
Torsten Duwe |
d02d7f |
+ * just disable the requested sources, as this would lead to missed
|
|
Torsten Duwe |
d02d7f |
+ * interrupts if ERRSOU3 changes just before writing to ERRMSK3.
|
|
Torsten Duwe |
d02d7f |
+ * To work around it, disable all and re-enable only the sources that
|
|
Torsten Duwe |
d02d7f |
+ * are not in vf_mask and were not already disabled. Re-enabling will
|
|
Torsten Duwe |
d02d7f |
+ * trigger a new interrupt for the sources that have changed in the
|
|
Torsten Duwe |
d02d7f |
+ * meantime, if any.
|
|
Torsten Duwe |
d02d7f |
+ */
|
|
Torsten Duwe |
d02d7f |
+ errmsk3 |= ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ errmsk3 &= ADF_GEN2_ERR_MSK_VF2PF(sources | disabled);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Return the sources of the (new) interrupt(s) */
|
|
Torsten Duwe |
d02d7f |
+ return pending;
|
|
Torsten Duwe |
d02d7f |
+}
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
static u32 gen2_csr_get_int_bit(enum gen2_csr_pos offset)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
return ADF_PFVF_INT << offset;
|
|
Torsten Duwe |
d02d7f |
@@ -362,9 +384,9 @@ void adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->enable_comms = adf_enable_pf2vf_comms;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->get_pf2vf_offset = adf_gen2_pf_get_pfvf_offset;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->get_vf2pf_offset = adf_gen2_pf_get_pfvf_offset;
|
|
Torsten Duwe |
d02d7f |
- pfvf_ops->get_vf2pf_sources = adf_gen2_get_vf2pf_sources;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->enable_vf2pf_interrupts = adf_gen2_enable_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->disable_vf2pf_interrupts = adf_gen2_disable_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
+ pfvf_ops->disable_pending_vf2pf_interrupts = adf_gen2_disable_pending_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->send_msg = adf_gen2_pf2vf_send;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->recv_msg = adf_gen2_vf2pf_recv;
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
|
|
Torsten Duwe |
d02d7f |
index f7860bf612da9..4061725b926df 100644
|
|
Torsten Duwe |
d02d7f |
--- a/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
|
|
Torsten Duwe |
d02d7f |
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
|
|
Torsten Duwe |
d02d7f |
@@ -15,6 +15,7 @@
|
|
Torsten Duwe |
d02d7f |
/* VF2PF interrupt source registers */
|
|
Torsten Duwe |
d02d7f |
#define ADF_4XXX_VM2PF_SOU 0x41A180
|
|
Torsten Duwe |
d02d7f |
#define ADF_4XXX_VM2PF_MSK 0x41A1C0
|
|
Torsten Duwe |
d02d7f |
+#define ADF_GEN4_VF_MSK 0xFFFF
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
#define ADF_PFVF_GEN4_MSGTYPE_SHIFT 2
|
|
Torsten Duwe |
d02d7f |
#define ADF_PFVF_GEN4_MSGTYPE_MASK 0x3F
|
|
Torsten Duwe |
d02d7f |
@@ -36,16 +37,6 @@ static u32 adf_gen4_pf_get_vf2pf_offset(u32 i)
|
|
Torsten Duwe |
d02d7f |
return ADF_4XXX_VM2PF_OFFSET(i);
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
-static u32 adf_gen4_get_vf2pf_sources(void __iomem *pmisc_addr)
|
|
Torsten Duwe |
d02d7f |
-{
|
|
Torsten Duwe |
d02d7f |
- u32 sou, mask;
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- sou = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_SOU);
|
|
Torsten Duwe |
d02d7f |
- mask = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- return sou & ~mask;
|
|
Torsten Duwe |
d02d7f |
-}
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
static void adf_gen4_enable_vf2pf_interrupts(void __iomem *pmisc_addr,
|
|
Torsten Duwe |
d02d7f |
u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
@@ -64,6 +55,37 @@ static void adf_gen4_disable_vf2pf_interrupts(void __iomem *pmisc_addr,
|
|
Torsten Duwe |
d02d7f |
ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, val);
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
+static u32 adf_gen4_disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr)
|
|
Torsten Duwe |
d02d7f |
+{
|
|
Torsten Duwe |
d02d7f |
+ u32 sources, disabled, pending;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Get the interrupt sources triggered by VFs */
|
|
Torsten Duwe |
d02d7f |
+ sources = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_SOU);
|
|
Torsten Duwe |
d02d7f |
+ if (!sources)
|
|
Torsten Duwe |
d02d7f |
+ return 0;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Get the already disabled interrupts */
|
|
Torsten Duwe |
d02d7f |
+ disabled = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ pending = sources & ~disabled;
|
|
Torsten Duwe |
d02d7f |
+ if (!pending)
|
|
Torsten Duwe |
d02d7f |
+ return 0;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Due to HW limitations, when disabling the interrupts, we can't
|
|
Torsten Duwe |
d02d7f |
+ * just disable the requested sources, as this would lead to missed
|
|
Torsten Duwe |
d02d7f |
+ * interrupts if VM2PF_SOU changes just before writing to VM2PF_MSK.
|
|
Torsten Duwe |
d02d7f |
+ * To work around it, disable all and re-enable only the sources that
|
|
Torsten Duwe |
d02d7f |
+ * are not in vf_mask and were not already disabled. Re-enabling will
|
|
Torsten Duwe |
d02d7f |
+ * trigger a new interrupt for the sources that have changed in the
|
|
Torsten Duwe |
d02d7f |
+ * meantime, if any.
|
|
Torsten Duwe |
d02d7f |
+ */
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, ADF_GEN4_VF_MSK);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, disabled | sources);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Return the sources of the (new) interrupt(s) */
|
|
Torsten Duwe |
d02d7f |
+ return pending;
|
|
Torsten Duwe |
d02d7f |
+}
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
static int adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev,
|
|
Torsten Duwe |
d02d7f |
struct pfvf_message msg, u32 pfvf_offset,
|
|
Torsten Duwe |
d02d7f |
struct mutex *csr_lock)
|
|
Torsten Duwe |
d02d7f |
@@ -121,9 +143,9 @@ void adf_gen4_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->enable_comms = adf_enable_pf2vf_comms;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->get_pf2vf_offset = adf_gen4_pf_get_pf2vf_offset;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->get_vf2pf_offset = adf_gen4_pf_get_vf2pf_offset;
|
|
Torsten Duwe |
d02d7f |
- pfvf_ops->get_vf2pf_sources = adf_gen4_get_vf2pf_sources;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->enable_vf2pf_interrupts = adf_gen4_enable_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->disable_vf2pf_interrupts = adf_gen4_disable_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
+ pfvf_ops->disable_pending_vf2pf_interrupts = adf_gen4_disable_pending_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->send_msg = adf_gen4_pfvf_send;
|
|
Torsten Duwe |
d02d7f |
pfvf_ops->recv_msg = adf_gen4_pfvf_recv;
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c
|
|
Torsten Duwe |
d02d7f |
index a35149f8bf1ee..23f7fff32c642 100644
|
|
Torsten Duwe |
d02d7f |
--- a/drivers/crypto/qat/qat_common/adf_isr.c
|
|
Torsten Duwe |
d02d7f |
+++ b/drivers/crypto/qat/qat_common/adf_isr.c
|
|
Torsten Duwe |
d02d7f |
@@ -76,32 +76,29 @@ void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
-static void adf_disable_vf2pf_interrupts_irq(struct adf_accel_dev *accel_dev,
|
|
Torsten Duwe |
d02d7f |
- u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
+static u32 adf_disable_pending_vf2pf_interrupts(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
|
|
Torsten Duwe |
d02d7f |
+ u32 pending;
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
spin_lock(&accel_dev->pf.vf2pf_ints_lock);
|
|
Torsten Duwe |
d02d7f |
- GET_PFVF_OPS(accel_dev)->disable_vf2pf_interrupts(pmisc_addr, vf_mask);
|
|
Torsten Duwe |
d02d7f |
+ pending = GET_PFVF_OPS(accel_dev)->disable_pending_vf2pf_interrupts(pmisc_addr);
|
|
Torsten Duwe |
d02d7f |
spin_unlock(&accel_dev->pf.vf2pf_ints_lock);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ return pending;
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
static bool adf_handle_vf2pf_int(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
- void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
|
|
Torsten Duwe |
d02d7f |
bool irq_handled = false;
|
|
Torsten Duwe |
d02d7f |
unsigned long vf_mask;
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
- /* Get the interrupt sources triggered by VFs */
|
|
Torsten Duwe |
d02d7f |
- vf_mask = GET_PFVF_OPS(accel_dev)->get_vf2pf_sources(pmisc_addr);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
+ /* Get the interrupt sources triggered by VFs, except for those already disabled */
|
|
Torsten Duwe |
d02d7f |
+ vf_mask = adf_disable_pending_vf2pf_interrupts(accel_dev);
|
|
Torsten Duwe |
d02d7f |
if (vf_mask) {
|
|
Torsten Duwe |
d02d7f |
struct adf_accel_vf_info *vf_info;
|
|
Torsten Duwe |
d02d7f |
int i;
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
- /* Disable VF2PF interrupts for VFs with pending ints */
|
|
Torsten Duwe |
d02d7f |
- adf_disable_vf2pf_interrupts_irq(accel_dev, vf_mask);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
/*
|
|
Torsten Duwe |
d02d7f |
* Handle VF2PF interrupt unless the VF is malicious and
|
|
Torsten Duwe |
d02d7f |
* is attempting to flood the host OS with VF2PF interrupts.
|
|
Torsten Duwe |
d02d7f |
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
|
|
Torsten Duwe |
d02d7f |
index 7375436ac1b83..86187671893c4 100644
|
|
Torsten Duwe |
d02d7f |
--- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
|
|
Torsten Duwe |
d02d7f |
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
|
|
Torsten Duwe |
d02d7f |
@@ -7,6 +7,8 @@
|
|
Torsten Duwe |
d02d7f |
#include "adf_dh895xcc_hw_data.h"
|
|
Torsten Duwe |
d02d7f |
#include "icp_qat_hw.h"
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
+#define ADF_DH895XCC_VF_MSK 0xFFFFFFFF
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
/* Worker thread to service arbiter mappings */
|
|
Torsten Duwe |
d02d7f |
static const u32 thrd_to_arb_map[ADF_DH895XCC_MAX_ACCELENGINES] = {
|
|
Torsten Duwe |
d02d7f |
0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666,
|
|
Torsten Duwe |
d02d7f |
@@ -107,29 +109,6 @@ static const u32 *adf_get_arbiter_mapping(void)
|
|
Torsten Duwe |
d02d7f |
return thrd_to_arb_map;
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
-static u32 get_vf2pf_sources(void __iomem *pmisc_bar)
|
|
Torsten Duwe |
d02d7f |
-{
|
|
Torsten Duwe |
d02d7f |
- u32 errsou3, errmsk3, errsou5, errmsk5, vf_int_mask;
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- /* Get the interrupt sources triggered by VFs */
|
|
Torsten Duwe |
d02d7f |
- errsou3 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRSOU3);
|
|
Torsten Duwe |
d02d7f |
- vf_int_mask = ADF_DH895XCC_ERR_REG_VF2PF_L(errsou3);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- /* To avoid adding duplicate entries to work queue, clear
|
|
Torsten Duwe |
d02d7f |
- * vf_int_mask_sets bits that are already masked in ERRMSK register.
|
|
Torsten Duwe |
d02d7f |
- */
|
|
Torsten Duwe |
d02d7f |
- errmsk3 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRMSK3);
|
|
Torsten Duwe |
d02d7f |
- vf_int_mask &= ~ADF_DH895XCC_ERR_REG_VF2PF_L(errmsk3);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- /* Do the same for ERRSOU5 */
|
|
Torsten Duwe |
d02d7f |
- errsou5 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRSOU5);
|
|
Torsten Duwe |
d02d7f |
- errmsk5 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRMSK5);
|
|
Torsten Duwe |
d02d7f |
- vf_int_mask |= ADF_DH895XCC_ERR_REG_VF2PF_U(errsou5);
|
|
Torsten Duwe |
d02d7f |
- vf_int_mask &= ~ADF_DH895XCC_ERR_REG_VF2PF_U(errmsk5);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
- return vf_int_mask;
|
|
Torsten Duwe |
d02d7f |
-}
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
static void enable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
/* Enable VF2PF Messaging Ints - VFs 0 through 15 per vf_mask[15:0] */
|
|
Torsten Duwe |
d02d7f |
@@ -143,7 +122,6 @@ static void enable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
if (vf_mask >> 16) {
|
|
Torsten Duwe |
d02d7f |
u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5)
|
|
Torsten Duwe |
d02d7f |
& ~ADF_DH895XCC_ERR_MSK_VF2PF_U(vf_mask);
|
|
Torsten Duwe |
d02d7f |
-
|
|
Torsten Duwe |
d02d7f |
ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, val);
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
@@ -166,6 +144,54 @@ static void disable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask)
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
+static u32 disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr)
|
|
Torsten Duwe |
d02d7f |
+{
|
|
Torsten Duwe |
d02d7f |
+ u32 sources, pending, disabled;
|
|
Torsten Duwe |
d02d7f |
+ u32 errsou3, errmsk3;
|
|
Torsten Duwe |
d02d7f |
+ u32 errsou5, errmsk5;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Get the interrupt sources triggered by VFs */
|
|
Torsten Duwe |
d02d7f |
+ errsou3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU3);
|
|
Torsten Duwe |
d02d7f |
+ errsou5 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU5);
|
|
Torsten Duwe |
d02d7f |
+ sources = ADF_DH895XCC_ERR_REG_VF2PF_L(errsou3)
|
|
Torsten Duwe |
d02d7f |
+ | ADF_DH895XCC_ERR_REG_VF2PF_U(errsou5);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ if (!sources)
|
|
Torsten Duwe |
d02d7f |
+ return 0;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Get the already disabled interrupts */
|
|
Torsten Duwe |
d02d7f |
+ errmsk3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3);
|
|
Torsten Duwe |
d02d7f |
+ errmsk5 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5);
|
|
Torsten Duwe |
d02d7f |
+ disabled = ADF_DH895XCC_ERR_REG_VF2PF_L(errmsk3)
|
|
Torsten Duwe |
d02d7f |
+ | ADF_DH895XCC_ERR_REG_VF2PF_U(errmsk5);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ pending = sources & ~disabled;
|
|
Torsten Duwe |
d02d7f |
+ if (!pending)
|
|
Torsten Duwe |
d02d7f |
+ return 0;
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Due to HW limitations, when disabling the interrupts, we can't
|
|
Torsten Duwe |
d02d7f |
+ * just disable the requested sources, as this would lead to missed
|
|
Torsten Duwe |
d02d7f |
+ * interrupts if sources changes just before writing to ERRMSK3 and
|
|
Torsten Duwe |
d02d7f |
+ * ERRMSK5.
|
|
Torsten Duwe |
d02d7f |
+ * To work around it, disable all and re-enable only the sources that
|
|
Torsten Duwe |
d02d7f |
+ * are not in vf_mask and were not already disabled. Re-enabling will
|
|
Torsten Duwe |
d02d7f |
+ * trigger a new interrupt for the sources that have changed in the
|
|
Torsten Duwe |
d02d7f |
+ * meantime, if any.
|
|
Torsten Duwe |
d02d7f |
+ */
|
|
Torsten Duwe |
d02d7f |
+ errmsk3 |= ADF_DH895XCC_ERR_MSK_VF2PF_L(ADF_DH895XCC_VF_MSK);
|
|
Torsten Duwe |
d02d7f |
+ errmsk5 |= ADF_DH895XCC_ERR_MSK_VF2PF_U(ADF_DH895XCC_VF_MSK);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ errmsk3 &= ADF_DH895XCC_ERR_MSK_VF2PF_L(sources | disabled);
|
|
Torsten Duwe |
d02d7f |
+ errmsk5 &= ADF_DH895XCC_ERR_MSK_VF2PF_U(sources | disabled);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
|
|
Torsten Duwe |
d02d7f |
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5);
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
+ /* Return the sources of the (new) interrupt(s) */
|
|
Torsten Duwe |
d02d7f |
+ return pending;
|
|
Torsten Duwe |
d02d7f |
+}
|
|
Torsten Duwe |
d02d7f |
+
|
|
Torsten Duwe |
d02d7f |
static void configure_iov_threads(struct adf_accel_dev *accel_dev, bool enable)
|
|
Torsten Duwe |
d02d7f |
{
|
|
Torsten Duwe |
d02d7f |
adf_gen2_cfg_iov_thds(accel_dev, enable,
|
|
Torsten Duwe |
d02d7f |
@@ -213,9 +239,9 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
|
|
Torsten Duwe |
d02d7f |
hw_data->disable_iov = adf_disable_sriov;
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
adf_gen2_init_pf_pfvf_ops(&hw_data->pfvf_ops);
|
|
Torsten Duwe |
d02d7f |
- hw_data->pfvf_ops.get_vf2pf_sources = get_vf2pf_sources;
|
|
Torsten Duwe |
d02d7f |
hw_data->pfvf_ops.enable_vf2pf_interrupts = enable_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
hw_data->pfvf_ops.disable_vf2pf_interrupts = disable_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
+ hw_data->pfvf_ops.disable_pending_vf2pf_interrupts = disable_pending_vf2pf_interrupts;
|
|
Torsten Duwe |
d02d7f |
adf_gen2_init_hw_csr_ops(&hw_data->csr_ops);
|
|
Torsten Duwe |
d02d7f |
}
|
|
Torsten Duwe |
d02d7f |
|
|
Torsten Duwe |
d02d7f |
--
|
|
Torsten Duwe |
d02d7f |
2.35.3
|
|
Torsten Duwe |
d02d7f |
|