dmaengine: idxd: move wq pasid configuration until when needed
commit 098159e3d405124cbc2020d93f529dff0eb7869e Intel-BKC. The main issue is that when we program wq with pasid of 0 but pasid_en set for shared wq, it confuses the VDCM. Remove the WQ pasid setting during configuration programming of the device as the driver does not have enough information at that point to make that decision. Program the WQCFG pasid and pasid_en at the time when it is needed. Add support in VDCM to understand what pasid_en=1 and pasid=0 means. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Chen Zhuo <sagazchen@tencent.com> Signed-off-by: Xinghui Li <korantli@tencent.com>
This commit is contained in:
parent
2f7442edee
commit
589a7fc3bf
|
@ -443,6 +443,7 @@ static void __idxd_wq_set_priv_locked(struct idxd_wq *wq)
|
|||
spin_lock(&idxd->dev_lock);
|
||||
wqcfg.bits[WQCFG_PRIV_IDX] = ioread32(idxd->reg_base + offset);
|
||||
wqcfg.priv = 1;
|
||||
wq->wqcfg->bits[WQCFG_PRIV_IDX] = wqcfg.bits[WQCFG_PRIV_IDX];
|
||||
iowrite32(wqcfg.bits[WQCFG_PRIV_IDX], idxd->reg_base + offset);
|
||||
spin_unlock(&idxd->dev_lock);
|
||||
}
|
||||
|
@ -458,6 +459,7 @@ static void __idxd_wq_set_pasid_locked(struct idxd_wq *wq, int pasid)
|
|||
wqcfg.bits[WQCFG_PASID_IDX] = ioread32(idxd->reg_base + offset);
|
||||
wqcfg.pasid_en = 1;
|
||||
wqcfg.pasid = pasid;
|
||||
wq->wqcfg->bits[WQCFG_PASID_IDX] = wqcfg.bits[WQCFG_PASID_IDX];
|
||||
iowrite32(wqcfg.bits[WQCFG_PASID_IDX], idxd->reg_base + offset);
|
||||
spin_unlock(&idxd->dev_lock);
|
||||
}
|
||||
|
@ -987,7 +989,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
|
|||
*/
|
||||
for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
|
||||
wq_offset = WQCFG_OFFSET(idxd, wq->id, i);
|
||||
wq->wqcfg->bits[i] = ioread32(idxd->reg_base + wq_offset);
|
||||
wq->wqcfg->bits[i] |= ioread32(idxd->reg_base + wq_offset);
|
||||
}
|
||||
|
||||
if (wq->size == 0 && wq->type != IDXD_WQT_NONE)
|
||||
|
@ -1003,16 +1005,6 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
|
|||
if (wq_dedicated(wq))
|
||||
wq->wqcfg->mode = 1;
|
||||
|
||||
/*
|
||||
* Enable this for shared WQ. swq does not need to program the pasid field,
|
||||
* but pasid_en needs to be set. Programming here prevents swq being disabled
|
||||
* and re-enabled, which is something to avoid.
|
||||
*/
|
||||
if ((is_idxd_wq_kernel(wq) && device_pasid_enabled(idxd)) ||
|
||||
((is_idxd_wq_user(wq) || is_idxd_wq_mdev(wq)) &&
|
||||
device_user_pasid_enabled(idxd)))
|
||||
wq->wqcfg->pasid_en = 1;
|
||||
|
||||
/*
|
||||
* Here the priv bit is set depending on the WQ type. priv = 1 if the
|
||||
* WQ type is kernel to indicate privileged access. This setting only
|
||||
|
@ -1210,12 +1202,6 @@ static int idxd_wq_load_config(struct idxd_wq *wq)
|
|||
if (wq->wqcfg->bof)
|
||||
set_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
|
||||
|
||||
if (device_pasid_enabled(idxd) && wq->wqcfg->mode == 1) {
|
||||
wq->wqcfg->pasid_en = 1;
|
||||
wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PASID_IDX);
|
||||
iowrite32(wq->wqcfg->bits[WQCFG_PASID_IDX], idxd->reg_base + wqcfg_offset);
|
||||
}
|
||||
|
||||
if (wq->wqcfg->mode_support)
|
||||
set_bit(WQ_FLAG_MODE_1, &wq->flags);
|
||||
|
||||
|
@ -1471,11 +1457,27 @@ int __drv_enable_wq(struct idxd_wq *wq)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In the event that the WQ is configurable for pasid and priv bits.
|
||||
* For kernel wq, the driver should setup the pasid, pasid_en, and priv bit.
|
||||
* However, for non-kernel wq, the driver should only set the pasid_en bit for
|
||||
* shared wq. A dedicated wq will configure pasid and pasid_en later on so
|
||||
* there is no need to setup.
|
||||
*/
|
||||
if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags) ||
|
||||
test_bit(WQ_FLAG_MODE_1, &wq->flags)) {
|
||||
if (is_idxd_wq_kernel(wq)) {
|
||||
if (device_pasid_enabled(idxd)) {
|
||||
u32 pasid = wq_dedicated(wq) ? idxd->pasid : 0;
|
||||
|
||||
__idxd_wq_set_pasid_locked(wq, pasid);
|
||||
}
|
||||
__idxd_wq_set_priv_locked(wq);
|
||||
} else {
|
||||
if (device_user_pasid_enabled(idxd) && wq_shared(wq))
|
||||
__idxd_wq_set_pasid_locked(wq, 0);
|
||||
}
|
||||
|
||||
if (is_idxd_wq_kernel(wq)) {
|
||||
if (device_pasid_enabled(idxd) && wq_dedicated(wq))
|
||||
__idxd_wq_set_pasid_locked(wq, idxd->pasid);
|
||||
__idxd_wq_set_priv_locked(wq);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
|
|
@ -1191,8 +1191,15 @@ static void vidxd_wq_enable(struct vdcm_idxd *vidxd, int wq_id)
|
|||
|
||||
priv = vwqcfg->priv;
|
||||
gpasid = vwqcfg->pasid;
|
||||
rc = idxd_mdev_get_host_pasid(mdev, gpasid, &wq_pasid);
|
||||
dev_dbg(dev, "guest pasid enabled, translate gpasid: %d\n", gpasid);
|
||||
|
||||
if (gpasid == 0) {
|
||||
rc = idxd_mdev_get_pasid(mdev, &wq_pasid);
|
||||
dev_dbg(dev, "shared wq, pasid 0, use default host: %u\n",
|
||||
wq_pasid);
|
||||
} else {
|
||||
rc = idxd_mdev_get_host_pasid(mdev, gpasid, &wq_pasid);
|
||||
dev_dbg(dev, "guest pasid enabled, translate gpasid: %d\n", gpasid);
|
||||
}
|
||||
} else {
|
||||
priv = 1;
|
||||
rc = idxd_mdev_get_pasid(mdev, &wq_pasid);
|
||||
|
|
Loading…
Reference in New Issue