Re: [PATCH V3 5/9] dax/fsdev: use __va(phys) for kaddr in direct_access

2026-06-02 Thread Alison Schofield
On Sat, May 30, 2026 at 04:51:04PM +, John Groves wrote:
> From: John Groves 
> 
> Use __va(phys) instead of virt_addr + linear_offset for the kaddr
> return in __fsdev_dax_direct_access(). The previous code added a
> device-linear byte offset to virt_addr (which is __va of ranges[0]),
> but for multi-range devices with physical gaps between ranges, this
> linear arithmetic crosses the gap and produces a wrong kernel virtual
> address. Using __va(phys) where phys comes from dax_pgoff_to_phys()
> is correct for any range layout because the direct map translates
> each physical address independently.
> 
> Fixes: 759455848df0b ("dax: Save the kva from memremap")
> Signed-off-by: John Groves 
> ---

Reviewed-by: Alison Schofield 



Re: [PATCH V3 5/9] dax/fsdev: use __va(phys) for kaddr in direct_access

2026-06-01 Thread Dave Jiang



On 5/30/26 9:51 AM, John Groves wrote:
> From: John Groves 
> 
> Use __va(phys) instead of virt_addr + linear_offset for the kaddr
> return in __fsdev_dax_direct_access(). The previous code added a
> device-linear byte offset to virt_addr (which is __va of ranges[0]),
> but for multi-range devices with physical gaps between ranges, this
> linear arithmetic crosses the gap and produces a wrong kernel virtual
> address. Using __va(phys) where phys comes from dax_pgoff_to_phys()
> is correct for any range layout because the direct map translates
> each physical address independently.
> 
> Fixes: 759455848df0b ("dax: Save the kva from memremap")
> Signed-off-by: John Groves 

Reviewed-by: Dave Jiang 

one comment below

> ---
>  drivers/dax/fsdev.c | 7 ++-
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dax/fsdev.c b/drivers/dax/fsdev.c
> index 42aac7e952516..a2d2eb20fb4d0 100644
> --- a/drivers/dax/fsdev.c
> +++ b/drivers/dax/fsdev.c
> @@ -51,9 +51,7 @@ static long __fsdev_dax_direct_access(struct dax_device 
> *dax_dev, pgoff_t pgoff,
>   struct dev_dax *dev_dax = dax_get_private(dax_dev);
>   size_t size = nr_pages << PAGE_SHIFT;
>   size_t offset = pgoff << PAGE_SHIFT;
> - void *virt_addr = dev_dax->virt_addr + offset;

With this change, there's no more dev_dax->virt_addr usage? Should that be 
removed?

DJ

>   phys_addr_t phys;
> - unsigned long local_pfn;
>  
>   phys = dax_pgoff_to_phys(dev_dax, pgoff, size);
>   if (phys == -1) {
> @@ -63,11 +61,10 @@ static long __fsdev_dax_direct_access(struct dax_device 
> *dax_dev, pgoff_t pgoff,
>   }
>  
>   if (kaddr)
> - *kaddr = virt_addr;
> + *kaddr = __va(phys);
>  
> - local_pfn = PHYS_PFN(phys);
>   if (pfn)
> - *pfn = local_pfn;
> + *pfn = PHYS_PFN(phys);
>  
>   /*
>* Use cached_size which was computed at probe time. The size cannot