Message ID | 1601281922-117296-1-git-send-email-wangzhou1@hisilicon.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | iommu/arm-smmu-v3: Add rmb after reading event queue prod_reg | expand |
On Mon, 28 Sep 2020 16:32:02 +0800, Zhou Wang wrote: > In arm_smmu_evtq_thread, reading event queue is from consumer pointer, > which has no address dependency on producer pointer, prog_reg(MMIO) and > event queue memory(Normal memory) can disorder. So the load for event queue > can be done before the load of prod_reg, then perhaps wrong event entry > value will be got. > > Add rmb to make sure to get correct event queue entry value. Applied to will (for-joerg/arm-smmu/updates), thanks! [1/1] iommu/arm-smmu-v3: Add rmb after reading event queue prod_reg https://git.kernel.org/will/c/a76a37777f2c (please note that I changed the patch to use readl() instead of an rmb() in conjunction with the _relaxed() accessor, and then adjusted the cons side to match in terms of DMB vs DSB). Cheers,
On 2020/9/29 6:13, Will Deacon wrote: > On Mon, 28 Sep 2020 16:32:02 +0800, Zhou Wang wrote: >> In arm_smmu_evtq_thread, reading event queue is from consumer pointer, >> which has no address dependency on producer pointer, prog_reg(MMIO) and >> event queue memory(Normal memory) can disorder. So the load for event queue >> can be done before the load of prod_reg, then perhaps wrong event entry >> value will be got. >> >> Add rmb to make sure to get correct event queue entry value. > > Applied to will (for-joerg/arm-smmu/updates), thanks! > > [1/1] iommu/arm-smmu-v3: Add rmb after reading event queue prod_reg > https://git.kernel.org/will/c/a76a37777f2c > > (please note that I changed the patch to use readl() instead of an rmb() > in conjunction with the _relaxed() accessor, and then adjusted the cons > side to match in terms of DMB vs DSB). Thanks for taking this patch! Best, Zhou > > Cheers, >
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index c192544..93c9077 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -819,6 +819,9 @@ static int queue_sync_prod_in(struct arm_smmu_queue *q) int ret = 0; u32 prod = readl_relaxed(q->prod_reg); + /* Ensure that reading event queue is after reading prod_reg */ + rmb(); + if (Q_OVF(prod) != Q_OVF(q->llq.prod)) ret = -EOVERFLOW;
In arm_smmu_evtq_thread, reading event queue is from consumer pointer, which has no address dependency on producer pointer, prog_reg(MMIO) and event queue memory(Normal memory) can disorder. So the load for event queue can be done before the load of prod_reg, then perhaps wrong event entry value will be got. Add rmb to make sure to get correct event queue entry value. Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 +++ 1 file changed, 3 insertions(+)