Skip to content

Commit d807132

Browse files
davejiangvinodkoul
authored andcommitted
dmaengine: idxd: fix setting up priv mode for dwq
DSA spec says WQ priv bit is 0 if the Privileged Mode Enable field of the PCI Express PASID capability is 0 and pasid is enabled. Make sure that the WQCFG priv field is set correctly according to usage type. Reject config if setting up kernel WQ type and no support. Also add the correct priv setup for a descriptor. Fixes: 484f910 ("dmaengine: idxd: fix wq config registers offset programming") Cc: Ramesh Thomas <[email protected]> Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/162939084657.903168.14160019185148244596.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <[email protected]>
1 parent aac6c0f commit d807132

File tree

4 files changed

+35
-2
lines changed

4 files changed

+35
-2
lines changed

drivers/dma/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ config INTEL_IDXD
285285
tristate "Intel Data Accelerators support"
286286
depends on PCI && X86_64 && !UML
287287
depends on PCI_MSI
288+
depends on PCI_PASID
288289
depends on SBITMAP
289290
select DMA_ENGINE
290291
help

drivers/dma/idxd/device.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,15 @@ static int idxd_groups_config_write(struct idxd_device *idxd)
818818
return 0;
819819
}
820820

821+
static bool idxd_device_pasid_priv_enabled(struct idxd_device *idxd)
822+
{
823+
struct pci_dev *pdev = idxd->pdev;
824+
825+
if (pdev->pasid_enabled && (pdev->pasid_features & PCI_PASID_CAP_PRIV))
826+
return true;
827+
return false;
828+
}
829+
821830
static int idxd_wq_config_write(struct idxd_wq *wq)
822831
{
823832
struct idxd_device *idxd = wq->idxd;
@@ -850,7 +859,6 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
850859
wq->wqcfg->wq_thresh = wq->threshold;
851860

852861
/* byte 8-11 */
853-
wq->wqcfg->priv = !!(wq->type == IDXD_WQT_KERNEL);
854862
if (wq_dedicated(wq))
855863
wq->wqcfg->mode = 1;
856864

@@ -860,6 +868,25 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
860868
wq->wqcfg->pasid = idxd->pasid;
861869
}
862870

871+
/*
872+
* Here the priv bit is set depending on the WQ type. priv = 1 if the
873+
* WQ type is kernel to indicate privileged access. This setting only
874+
* matters for dedicated WQ. According to the DSA spec:
875+
* If the WQ is in dedicated mode, WQ PASID Enable is 1, and the
876+
* Privileged Mode Enable field of the PCI Express PASID capability
877+
* is 0, this field must be 0.
878+
*
879+
* In the case of a dedicated kernel WQ that is not able to support
880+
* the PASID cap, then the configuration will be rejected.
881+
*/
882+
wq->wqcfg->priv = !!(wq->type == IDXD_WQT_KERNEL);
883+
if (wq_dedicated(wq) && wq->wqcfg->pasid_en &&
884+
!idxd_device_pasid_priv_enabled(idxd) &&
885+
wq->type == IDXD_WQT_KERNEL) {
886+
idxd->cmd_status = IDXD_SCMD_WQ_NO_PRIV;
887+
return -EOPNOTSUPP;
888+
}
889+
863890
wq->wqcfg->priority = wq->priority;
864891

865892
if (idxd->hw.gen_cap.block_on_fault &&

drivers/dma/idxd/dma.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ static inline void idxd_prep_desc_common(struct idxd_wq *wq,
6969
hw->src_addr = addr_f1;
7070
hw->dst_addr = addr_f2;
7171
hw->xfer_size = len;
72-
hw->priv = !!(wq->type == IDXD_WQT_KERNEL);
72+
/*
73+
* For dedicated WQ, this field is ignored and HW will use the WQCFG.priv
74+
* field instead. This field should be set to 1 for kernel descriptors.
75+
*/
76+
hw->priv = 1;
7377
hw->completion_addr = compl;
7478
}
7579

include/uapi/linux/idxd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ enum idxd_scmd_stat {
2727
IDXD_SCMD_WQ_NO_SWQ_SUPPORT = 0x800c0000,
2828
IDXD_SCMD_WQ_NONE_CONFIGURED = 0x800d0000,
2929
IDXD_SCMD_WQ_NO_SIZE = 0x800e0000,
30+
IDXD_SCMD_WQ_NO_PRIV = 0x800f0000,
3031
};
3132

3233
#define IDXD_SCMD_SOFTERR_MASK 0x80000000

0 commit comments

Comments
 (0)