On Mon, Aug 19, 2019 at 07:19:31PM +0100, Robin Murphy wrote:
> Now that callers are free to use a given table for TTBR1 if they wish
> (all they need do is shift the provided attributes when constructing
> their final TCR value), the only remaining impediment is the address
> validation on map/unmap. The fact that the LPAE address space split is
> symmetric makes this easy to accommodate - by simplifying the current
> range checks into explicit tests that address bits above IAS are all
> zero, it then follows straightforwardly to add the inverse test to
> allow the all-ones case as well.
> 
> Signed-off-by: Robin Murphy <robin.mur...@arm.com>
> ---
>  drivers/iommu/io-pgtable-arm.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 09cb20671fbb..f39c50356351 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -475,13 +475,13 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, 
> unsigned long iova,
>       arm_lpae_iopte *ptep = data->pgd;
>       int ret, lvl = ARM_LPAE_START_LVL(data);
>       arm_lpae_iopte prot;
> +     long iaext = (long)iova >> data->iop.cfg.ias;
>  
>       /* If no access, then nothing to do */
>       if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
>               return 0;
>  
> -     if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) ||
> -                 paddr >= (1ULL << data->iop.cfg.oas)))
> +     if (WARN_ON((iaext && ~iaext) || paddr >> data->iop.cfg.oas))
>               return -ERANGE;
>  
>       prot = arm_lpae_prot_to_pte(data, iommu_prot);

We'll want to cast away the sign extended bits before mapping the iova, this
might be a good patch for that too as long as we are calculating the iaext.

> @@ -647,8 +647,9 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, 
> unsigned long iova,
>       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
>       arm_lpae_iopte *ptep = data->pgd;
>       int lvl = ARM_LPAE_START_LVL(data);
> +     long iaext = (long)iova >> data->iop.cfg.ias;
>  
> -     if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
> +     if (WARN_ON(iaext && ~iaext))
>               return 0;
>  
>       return __arm_lpae_unmap(data, iova, size, lvl, ptep);

And here too.

Jordan

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to