Hi Rahul,

> On 6 Sep 2022, at 10:55, Rahul Singh <rahul.si...@arm.com> wrote:
> 
> From: Zhou Wang <wangzh...@hisilicon.com>
> 
> Backport Linux commit a76a37777f2c. Introduce __iomb() in the smmu-v3.c
> file with other Linux compatibility definitions.
> 
> Reading the 'prod' MMIO register in order to determine whether or
> not there is valid data beyond 'cons' for a given queue does not
> provide sufficient dependency ordering, as the resulting access is
> address dependent only on 'cons' and can therefore be speculated
> ahead of time, potentially allowing stale data to be read by the
> CPU.
> 
> Use readl() instead of readl_relaxed() when updating the shadow copy
> of the 'prod' pointer, so that all speculated memory reads from the
> corresponding queue can occur only from valid slots.
> 
> Signed-off-by: Zhou Wang <wangzh...@hisilicon.com>
> Link: 
> https://lore.kernel.org/r/1601281922-117296-1-git-send-email-wangzh...@hisilicon.com
> [will: Use readl() instead of explicit barrier. Update 'cons' side to match.]
> Signed-off-by: Will Deacon <w...@kernel.org>
> Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
> a76a37777f2c
> Signed-off-by: Rahul Singh <rahul.si...@arm.com>

Reviewed-by: Bertrand Marquis <bertrand.marq...@arm.com>

Cheers
Bertrand

> ---
> Changes in v4:
> - rename iomb() to __iomb()
> Changes in v3:
> - rename __iomb() to iomb() and also move it from common file to
>   smmu-v3.c file
> Changes in v2:
> - fix commit msg
> - add __iomb changes also from the origin patch
> ---
> xen/drivers/passthrough/arm/smmu-v3.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/drivers/passthrough/arm/smmu-v3.c 
> b/xen/drivers/passthrough/arm/smmu-v3.c
> index 64d39bb4d3..229b9a4b0d 100644
> --- a/xen/drivers/passthrough/arm/smmu-v3.c
> +++ b/xen/drivers/passthrough/arm/smmu-v3.c
> @@ -107,6 +107,8 @@ typedef paddr_t           dma_addr_t;
> typedef paddr_t               phys_addr_t;
> typedef unsigned int          gfp_t;
> 
> +#define __iomb()             dmb(osh)
> +
> #define platform_device               device
> 
> #define GFP_KERNEL            0
> @@ -951,7 +953,7 @@ static void queue_sync_cons_out(struct arm_smmu_queue *q)
>        * Ensure that all CPU accesses (reads and writes) to the queue
>        * are complete before we update the cons pointer.
>        */
> -     mb();
> +     __iomb();
>       writel_relaxed(q->llq.cons, q->cons_reg);
> }
> 
> @@ -963,8 +965,15 @@ static void queue_inc_cons(struct arm_smmu_ll_queue *q)
> 
> static int queue_sync_prod_in(struct arm_smmu_queue *q)
> {
> +     u32 prod;
>       int ret = 0;
> -     u32 prod = readl_relaxed(q->prod_reg);
> +
> +     /*
> +      * We can't use the _relaxed() variant here, as we must prevent
> +      * speculative reads of the queue before we have determined that
> +      * prod has indeed moved.
> +      */
> +     prod = readl(q->prod_reg);
> 
>       if (Q_OVF(prod) != Q_OVF(q->llq.prod))
>               ret = -EOVERFLOW;
> -- 
> 2.25.1
> 


Reply via email to