mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset
@ 2025-11-26  5:26 ankita
  2025-11-26  5:26 ` [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function ankita
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

NVIDIA's Grace based system have large GPU device memory. The device
memory is mapped as VM_PFNMAP in the VMM VMA. The nvgrace-gpu
module could make use of the huge PFNMAP support added in mm [1].

To achieve this, nvgrace-gpu module is updated to implement huge_fault ops.
The implementation establishes mapping according to the order request.
Note that if the PFN or the VMA address is unaligned to the order, the
mapping fallbacks to the PTE level.

Secondly, it is expected that the mapping not be re-established until
the GPU is ready post reset. Presence of the mappings during that time
could potentially leads to harmless corrected RAS events to be logged if
the CPU attempts to do speculative reads on the GPU memory on the Grace
systems.

It can take several seconds for the GPU to be ready. So it is desirable
that the time overlaps as much of the VM startup as possible to reduce
impact on the VM bootup time. The GPU readiness state is thus checked
on the first fault/huge_fault request which amortizes the GPU readiness
time. The GPU readiness is checked through BAR0 registers as is done
at the device probe.

Patch 1 Refactor vfio_pci_mmap_huge_fault and export the code to map
at the various levels.

Patch 2 implements support for huge pfnmap.

Patch 3 vfio_pci_core_mmap cleanup.

Patch 4 split the code to check the device readiness.

Patch 5 reset_done handler implementation

Patch 6 Ensures that the GPU is ready before re-establishing the mapping
after reset.

Applied over 6.18-rc6.

Link: https://lore.kernel.org/all/20240826204353.2228736-1-peterx@redhat.com/ [1]

Changelog:
[v7]
- Code cleanup to use ALIGN functions and move the mapping sanity check
  to the vfio header file. (Thanks Alex Williamson, Zhi Wang)
- Added comments for reset_done implementation. (Thanks Alex Williamson)
- Collected Reviewed-by. (Thanks Zhi Wang)
- Miscellaneous cleanup (Thanks Alex Williamson, Zhi Wang)
Link: https://lore.kernel.org/all/20251125173013.39511-1-ankita@nvidia.com/ [v6]
- Updated the vfio_pci_vmf_insert_pfn function to add more common code.
  (Thanks Shameer Kolothum)
- Added missing userspace offset for pgoff calculation for huge pfnmap.
  (Thanks Shameer Kolothum)
- Removed alignment for GPU memory. (Thanks Jason Gunthorpe)
- Collected Reviewed-by. (Thanks Shameer Kolothum)
- Miscellaneous cleanup, log messages fixup
  (Thanks Alex Williamson, Jason Gunthorpe, Shameer Kolothum)
Link: https://lore.kernel.org/all/20251124115926.119027-1-ankita@nvidia.com/ [v5]
- Updated gpu_mem_mapped with reset_done flag for clearer semantics. (6/7)
  (Thanks Alex Williamson)
- Renamed vfio_pci_map_pfn to vfio_pci_vmf_insert_pfn. (2/7)
  (Thanks Alex Williamson)
- Updated to hold memory_lock across the vmf_insert_pfn and the
  read/write access of the device. (7/7) (Thanks Alex Williamson)
- Used scoped_guard to simplify critical region. (1/7, 7/7)
[v4]
- Implemented reset_done handler to set gpu_mem_mapped flag. Cleaned up
  FLR detection path (Thanks Alex Williamson)
- Moved the premap check of the device readiness to a new function.
  Added locking to avoid races. (Thanks Alex Williamson)
- vfio_pci_core_mmap cleanup.
- Added ioremap to BAR0 during open.
Link: https://lore.kernel.org/all/20251121141141.3175-1-ankita@nvidia.com/ [v3]
- Moved the code for BAR mapping to a separate function.
- Added BAR0 mapping during open. Ensures BAR0 is mapped when registers
  are checked. (Thanks Alex Williamson, Jason Gunthorpe for suggestion)
- Added check for GPU readiness on nvgrace_gpu_map_device_mem. (Thanks
  Alex Williamson for the suggestion.
Link: https://lore.kernel.org/all/20251118074422.58081-1-ankita@nvidia.com/ [v2]
- Fixed build kernel warning
- subject text changes
- Rebased to 6.18-rc6.
Link: https://lore.kernel.org/all/20251117124159.3560-1-ankita@nvidia.com/ [v1]

Signed-off-by: Ankit Agrawal <ankita@nvidia.com>

Ankit Agrawal (6):
  vfio: refactor vfio_pci_mmap_huge_fault function
  vfio/nvgrace-gpu: Add support for huge pfnmap
  vfio: use vfio_pci_core_setup_barmap to map bar in mmap
  vfio/nvgrace-gpu: split the code to wait for GPU ready
  vfio/nvgrace-gpu: Inform devmem unmapped after reset
  vfio/nvgrace-gpu: wait for the GPU mem to be ready

 drivers/vfio/pci/nvgrace-gpu/main.c | 215 ++++++++++++++++++++++------
 drivers/vfio/pci/vfio_pci_core.c    |  69 +++++----
 include/linux/vfio_pci_core.h       |  16 +++
 3 files changed, 222 insertions(+), 78 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function
  2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
@ 2025-11-26  5:26 ` ankita
  2025-11-26 15:22   ` Alex Williamson
  2025-11-26  5:26 ` [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap ankita
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

Refactor vfio_pci_mmap_huge_fault to take out the implementation
to map the VMA to the PTE/PMD/PUD as a separate function.

Export the new function to be used by nvgrace-gpu module.

No functional change is intended.

Cc: Shameer Kolothum <skolothumtho@nvidia.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 54 +++++++++++++++++---------------
 include/linux/vfio_pci_core.h    | 16 ++++++++++
 2 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 7dcf5439dedc..52e3a10d776b 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1640,48 +1640,52 @@ static unsigned long vma_to_pfn(struct vm_area_struct *vma)
 	return (pci_resource_start(vdev->pdev, index) >> PAGE_SHIFT) + pgoff;
 }
 
-static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
-					   unsigned int order)
+vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
+				   struct vm_fault *vmf,
+				   unsigned long pfn,
+				   unsigned int order)
 {
-	struct vm_area_struct *vma = vmf->vma;
-	struct vfio_pci_core_device *vdev = vma->vm_private_data;
-	unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
-	unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
-	unsigned long pfn = vma_to_pfn(vma) + pgoff;
-	vm_fault_t ret = VM_FAULT_SIGBUS;
-
-	if (order && (addr < vma->vm_start ||
-		      addr + (PAGE_SIZE << order) > vma->vm_end ||
-		      pfn & ((1 << order) - 1))) {
-		ret = VM_FAULT_FALLBACK;
-		goto out;
-	}
-
-	down_read(&vdev->memory_lock);
+	lockdep_assert_held_read(&vdev->memory_lock);
 
 	if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev))
-		goto out_unlock;
+		return VM_FAULT_SIGBUS;
 
 	switch (order) {
 	case 0:
-		ret = vmf_insert_pfn(vma, vmf->address, pfn);
-		break;
+		return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
 	case PMD_ORDER:
-		ret = vmf_insert_pfn_pmd(vmf, pfn, false);
-		break;
+		return vmf_insert_pfn_pmd(vmf, pfn, false);
 #endif
 #ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
 	case PUD_ORDER:
-		ret = vmf_insert_pfn_pud(vmf, pfn, false);
+		return vmf_insert_pfn_pud(vmf, pfn, false);
 		break;
 #endif
 	default:
+		return VM_FAULT_FALLBACK;
+	}
+}
+EXPORT_SYMBOL_GPL(vfio_pci_vmf_insert_pfn);
+
+static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
+					   unsigned int order)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	struct vfio_pci_core_device *vdev = vma->vm_private_data;
+	unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
+	unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
+	unsigned long pfn = vma_to_pfn(vma) + pgoff;
+	vm_fault_t ret;
+
+	if (unmappable_for_order(vma, addr, pfn, order)) {
 		ret = VM_FAULT_FALLBACK;
+		goto out;
 	}
 
-out_unlock:
-	up_read(&vdev->memory_lock);
+	scoped_guard(rwsem_read, &vdev->memory_lock)
+		ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
+
 out:
 	dev_dbg_ratelimited(&vdev->pdev->dev,
 			   "%s(,order = %d) BAR %ld page offset 0x%lx: 0x%x\n",
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index f541044e42a2..1d457216ce4d 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -119,6 +119,9 @@ ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf,
 		size_t count, loff_t *ppos);
 ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf,
 		size_t count, loff_t *ppos);
+vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
+				   struct vm_fault *vmf, unsigned long pfn,
+				   unsigned int order);
 int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma);
 void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count);
 int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf);
@@ -161,4 +164,17 @@ VFIO_IOREAD_DECLARATION(32)
 VFIO_IOREAD_DECLARATION(64)
 #endif
 
+static inline bool unmappable_for_order(struct vm_area_struct *vma,
+					unsigned long addr,
+					unsigned long pfn,
+					unsigned int order)
+{
+	if (order && (addr < vma->vm_start ||
+		      addr + (PAGE_SIZE << order) > vma->vm_end ||
+		      !IS_ALIGNED(pfn, 1 << order)))
+		return true;
+
+	return false;
+}
+
 #endif /* VFIO_PCI_CORE_H */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap
  2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
  2025-11-26  5:26 ` [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function ankita
@ 2025-11-26  5:26 ` ankita
  2025-11-26  8:59   ` Shameer Kolothum
  2025-11-26 15:22   ` Alex Williamson
  2025-11-26  5:26 ` [PATCH v7 3/6] vfio: use vfio_pci_core_setup_barmap to map bar in mmap ankita
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

NVIDIA's Grace based systems have large device memory. The device
memory is mapped as VM_PFNMAP in the VMM VMA. The nvgrace-gpu
module could make use of the huge PFNMAP support added in mm [1].

To make use of the huge pfnmap support, fault/huge_fault ops
based mapping mechanism needs to be implemented. Currently nvgrace-gpu
module relies on remap_pfn_range to do the mapping during VM bootup.
Replace it to instead rely on fault and use vfio_pci_vmf_insert_pfn
to setup the mapping.

Moreover to enable huge pfnmap, nvgrace-gpu module is updated by
adding huge_fault ops implementation. The implementation establishes
mapping according to the order request. Note that if the PFN or the
VMA address is unaligned to the order, the mapping fallbacks to
the PTE level.

Link: https://lore.kernel.org/all/20240826204353.2228736-1-peterx@redhat.com/ [1]

Cc: Shameer Kolothum <skolothumtho@nvidia.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Vikram Sethi <vsethi@nvidia.com>
Reviewed-by: Zhi Wang <zhiw@nvidia.com>
Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/nvgrace-gpu/main.c | 85 +++++++++++++++++++++--------
 1 file changed, 63 insertions(+), 22 deletions(-)

diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
index e346392b72f6..ac9551b9e4b6 100644
--- a/drivers/vfio/pci/nvgrace-gpu/main.c
+++ b/drivers/vfio/pci/nvgrace-gpu/main.c
@@ -130,6 +130,63 @@ static void nvgrace_gpu_close_device(struct vfio_device *core_vdev)
 	vfio_pci_core_close_device(core_vdev);
 }
 
+static unsigned long addr_to_pgoff(struct vm_area_struct *vma,
+				   unsigned long addr)
+{
+	u64 pgoff = vma->vm_pgoff &
+		((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
+
+	return ((addr - vma->vm_start) >> PAGE_SHIFT) + pgoff;
+}
+
+static vm_fault_t nvgrace_gpu_vfio_pci_huge_fault(struct vm_fault *vmf,
+						  unsigned int order)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	struct nvgrace_gpu_pci_core_device *nvdev = vma->vm_private_data;
+	struct vfio_pci_core_device *vdev = &nvdev->core_device;
+	unsigned int index =
+		vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
+	vm_fault_t ret = VM_FAULT_SIGBUS;
+	struct mem_region *memregion;
+	unsigned long pfn, addr;
+
+	memregion = nvgrace_gpu_memregion(index, nvdev);
+	if (!memregion)
+		return ret;
+
+	addr = ALIGN_DOWN(vmf->address, PAGE_SIZE << order);
+	pfn = PHYS_PFN(memregion->memphys) + addr_to_pgoff(vma, addr);
+
+	if (unmappable_for_order(vma, addr, pfn, order)) {
+		ret = VM_FAULT_FALLBACK;
+		goto out;
+	}
+
+	scoped_guard(rwsem_read, &vdev->memory_lock)
+		ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
+
+out:
+	dev_dbg_ratelimited(&vdev->pdev->dev,
+			    "%s order = %d pfn 0x%lx: 0x%x\n",
+			    __func__, order, pfn,
+			    (unsigned int)ret);
+
+	return ret;
+}
+
+static vm_fault_t nvgrace_gpu_vfio_pci_fault(struct vm_fault *vmf)
+{
+	return nvgrace_gpu_vfio_pci_huge_fault(vmf, 0);
+}
+
+static const struct vm_operations_struct nvgrace_gpu_vfio_pci_mmap_ops = {
+	.fault = nvgrace_gpu_vfio_pci_fault,
+#ifdef CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP
+	.huge_fault = nvgrace_gpu_vfio_pci_huge_fault,
+#endif
+};
+
 static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
 			    struct vm_area_struct *vma)
 {
@@ -137,10 +194,8 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
 		container_of(core_vdev, struct nvgrace_gpu_pci_core_device,
 			     core_device.vdev);
 	struct mem_region *memregion;
-	unsigned long start_pfn;
 	u64 req_len, pgoff, end;
 	unsigned int index;
-	int ret = 0;
 
 	index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
 
@@ -157,17 +212,18 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
 		((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
 
 	if (check_sub_overflow(vma->vm_end, vma->vm_start, &req_len) ||
-	    check_add_overflow(PHYS_PFN(memregion->memphys), pgoff, &start_pfn) ||
 	    check_add_overflow(PFN_PHYS(pgoff), req_len, &end))
 		return -EOVERFLOW;
 
 	/*
-	 * Check that the mapping request does not go beyond available device
-	 * memory size
+	 * Check that the mapping request does not go beyond the exposed
+	 * device memory size.
 	 */
 	if (end > memregion->memlength)
 		return -EINVAL;
 
+	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+
 	/*
 	 * The carved out region of the device memory needs the NORMAL_NC
 	 * property. Communicate as such to the hypervisor.
@@ -184,23 +240,8 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
 		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 	}
 
-	/*
-	 * Perform a PFN map to the memory and back the device BAR by the
-	 * GPU memory.
-	 *
-	 * The available GPU memory size may not be power-of-2 aligned. The
-	 * remainder is only backed by vfio_device_ops read/write handlers.
-	 *
-	 * During device reset, the GPU is safely disconnected to the CPU
-	 * and access to the BAR will be immediately returned preventing
-	 * machine check.
-	 */
-	ret = remap_pfn_range(vma, vma->vm_start, start_pfn,
-			      req_len, vma->vm_page_prot);
-	if (ret)
-		return ret;
-
-	vma->vm_pgoff = start_pfn;
+	vma->vm_ops = &nvgrace_gpu_vfio_pci_mmap_ops;
+	vma->vm_private_data = nvdev;
 
 	return 0;
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 3/6] vfio: use vfio_pci_core_setup_barmap to map bar in mmap
  2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
  2025-11-26  5:26 ` [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function ankita
  2025-11-26  5:26 ` [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap ankita
@ 2025-11-26  5:26 ` ankita
  2025-11-26  5:26 ` [PATCH v7 4/6] vfio/nvgrace-gpu: split the code to wait for GPU ready ankita
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

Remove code duplication in vfio_pci_core_mmap by calling
vfio_pci_core_setup_barmap to perform the bar mapping.

No functional change is intended.

Cc: Donald Dutile <ddutile@redhat.com>
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
Reviewed-by: Zhi Wang <zhiw@nvidia.com>
Suggested-by: Alex Williamson <alex@shazbot.org>
Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/vfio_pci_core.c | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 52e3a10d776b..020bf3aa22e9 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1753,18 +1753,9 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
 	 * Even though we don't make use of the barmap for the mmap,
 	 * we need to request the region and the barmap tracks that.
 	 */
-	if (!vdev->barmap[index]) {
-		ret = pci_request_selected_regions(pdev,
-						   1 << index, "vfio-pci");
-		if (ret)
-			return ret;
-
-		vdev->barmap[index] = pci_iomap(pdev, index, 0);
-		if (!vdev->barmap[index]) {
-			pci_release_selected_regions(pdev, 1 << index);
-			return -ENOMEM;
-		}
-	}
+	ret = vfio_pci_core_setup_barmap(vdev, index);
+	if (ret)
+		return ret;
 
 	vma->vm_private_data = vdev;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 4/6] vfio/nvgrace-gpu: split the code to wait for GPU ready
  2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
                   ` (2 preceding siblings ...)
  2025-11-26  5:26 ` [PATCH v7 3/6] vfio: use vfio_pci_core_setup_barmap to map bar in mmap ankita
@ 2025-11-26  5:26 ` ankita
  2025-11-26 15:22   ` Alex Williamson
  2025-11-26  5:26 ` [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset ankita
  2025-11-26  5:26 ` [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready ankita
  5 siblings, 1 reply; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

Split the function that check for the GPU device being ready on
the probe.

Move the code to wait for the GPU to be ready through BAR0 register
reads to a separate function. This would help reuse the code.

This also fixes a bug where the return status in case of timeout
gets overridden by return from pci_enable_device. With the fix,
a timeout generate an error as initially intended.

Fixes: d85f69d520e6 ("vfio/nvgrace-gpu: Check the HBM training and C2C link status")

Reviewed-by: Zhi Wang <zhiw@nvidia.com>
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/nvgrace-gpu/main.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
index ac9551b9e4b6..f691deb8e43c 100644
--- a/drivers/vfio/pci/nvgrace-gpu/main.c
+++ b/drivers/vfio/pci/nvgrace-gpu/main.c
@@ -130,6 +130,20 @@ static void nvgrace_gpu_close_device(struct vfio_device *core_vdev)
 	vfio_pci_core_close_device(core_vdev);
 }
 
+static int nvgrace_gpu_wait_device_ready(void __iomem *io)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(POLL_TIMEOUT_MS);
+
+	do {
+		if ((ioread32(io + C2C_LINK_BAR0_OFFSET) == STATUS_READY) &&
+		    (ioread32(io + HBM_TRAINING_BAR0_OFFSET) == STATUS_READY))
+			return 0;
+		msleep(POLL_QUANTUM_MS);
+	} while (!time_after(jiffies, timeout));
+
+	return -ETIME;
+}
+
 static unsigned long addr_to_pgoff(struct vm_area_struct *vma,
 				   unsigned long addr)
 {
@@ -934,9 +948,8 @@ static bool nvgrace_gpu_has_mig_hw_bug(struct pci_dev *pdev)
  * Ensure that the BAR0 region is enabled before accessing the
  * registers.
  */
-static int nvgrace_gpu_wait_device_ready(struct pci_dev *pdev)
+static int nvgrace_gpu_probe_check_device_ready(struct pci_dev *pdev)
 {
-	unsigned long timeout = jiffies + msecs_to_jiffies(POLL_TIMEOUT_MS);
 	void __iomem *io;
 	int ret = -ETIME;
 
@@ -954,16 +967,8 @@ static int nvgrace_gpu_wait_device_ready(struct pci_dev *pdev)
 		goto iomap_exit;
 	}
 
-	do {
-		if ((ioread32(io + C2C_LINK_BAR0_OFFSET) == STATUS_READY) &&
-		    (ioread32(io + HBM_TRAINING_BAR0_OFFSET) == STATUS_READY)) {
-			ret = 0;
-			goto reg_check_exit;
-		}
-		msleep(POLL_QUANTUM_MS);
-	} while (!time_after(jiffies, timeout));
+	ret = nvgrace_gpu_wait_device_ready(io);
 
-reg_check_exit:
 	pci_iounmap(pdev, io);
 iomap_exit:
 	pci_release_selected_regions(pdev, 1 << 0);
@@ -980,7 +985,7 @@ static int nvgrace_gpu_probe(struct pci_dev *pdev,
 	u64 memphys, memlength;
 	int ret;
 
-	ret = nvgrace_gpu_wait_device_ready(pdev);
+	ret = nvgrace_gpu_probe_check_device_ready(pdev);
 	if (ret)
 		return ret;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset
  2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
                   ` (3 preceding siblings ...)
  2025-11-26  5:26 ` [PATCH v7 4/6] vfio/nvgrace-gpu: split the code to wait for GPU ready ankita
@ 2025-11-26  5:26 ` ankita
  2025-11-26  9:00   ` Shameer Kolothum
  2025-11-26 15:23   ` Alex Williamson
  2025-11-26  5:26 ` [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready ankita
  5 siblings, 2 replies; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

Introduce a new flag reset_done to notify that the GPU has just
been reset and the mapping to the GPU memory is zapped.

Implement the reset_done handler to set this new variable. It
will be used later in the patches to wait for the GPU memory
to be ready before doing any mapping or access.

Cc: Jason Gunthorpe <jgg@ziepe.ca>
Suggested-by: Alex Williamson <alex@shazbot.org>
Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/nvgrace-gpu/main.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
index f691deb8e43c..b46984e76be7 100644
--- a/drivers/vfio/pci/nvgrace-gpu/main.c
+++ b/drivers/vfio/pci/nvgrace-gpu/main.c
@@ -58,6 +58,8 @@ struct nvgrace_gpu_pci_core_device {
 	/* Lock to control device memory kernel mapping */
 	struct mutex remap_lock;
 	bool has_mig_hw_bug;
+	/* GPU has just been reset */
+	bool reset_done;
 };
 
 static void nvgrace_gpu_init_fake_bar_emu_regs(struct vfio_device *core_vdev)
@@ -1048,12 +1050,34 @@ static const struct pci_device_id nvgrace_gpu_vfio_pci_table[] = {
 
 MODULE_DEVICE_TABLE(pci, nvgrace_gpu_vfio_pci_table);
 
+/*
+ * The GPU reset is required to be serialized against the *first* mapping
+ * faults and read/writes accesses to prevent potential RAS events logging.
+ *
+ * The reset_done implementation is triggered on every reset and is used
+ * set the reset_done variable that assists in achieving the serialization.
+ */
+static void nvgrace_gpu_vfio_pci_reset_done(struct pci_dev *pdev)
+{
+	struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
+	struct nvgrace_gpu_pci_core_device *nvdev =
+		container_of(core_device, struct nvgrace_gpu_pci_core_device,
+			     core_device);
+
+	nvdev->reset_done = true;
+}
+
+static const struct pci_error_handlers nvgrace_gpu_vfio_pci_err_handlers = {
+	.reset_done = nvgrace_gpu_vfio_pci_reset_done,
+	.error_detected = vfio_pci_core_aer_err_detected,
+};
+
 static struct pci_driver nvgrace_gpu_vfio_pci_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = nvgrace_gpu_vfio_pci_table,
 	.probe = nvgrace_gpu_probe,
 	.remove = nvgrace_gpu_remove,
-	.err_handler = &vfio_pci_core_err_handlers,
+	.err_handler = &nvgrace_gpu_vfio_pci_err_handlers,
 	.driver_managed_dma = true,
 };
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready
  2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
                   ` (4 preceding siblings ...)
  2025-11-26  5:26 ` [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset ankita
@ 2025-11-26  5:26 ` ankita
  2025-11-26  9:03   ` Shameer Kolothum
  2025-11-26 15:23   ` Alex Williamson
  5 siblings, 2 replies; 17+ messages in thread
From: ankita @ 2025-11-26  5:26 UTC (permalink / raw)
  To: ankita, jgg, yishaih, skolothumtho, kevin.tian, alex, aniketa,
	vsethi, mochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

From: Ankit Agrawal <ankita@nvidia.com>

Speculative prefetches from CPU to GPU memory until the GPU is
ready after reset can cause harmless corrected RAS events to
be logged on Grace systems. It is thus preferred that the
mapping not be re-established until the GPU is ready post reset.

The GPU readiness can be checked through BAR0 registers similar
to the checking at the time of device probe.

It can take several seconds for the GPU to be ready. So it is
desirable that the time overlaps as much of the VM startup as
possible to reduce impact on the VM bootup time. The GPU
readiness state is thus checked on the first fault/huge_fault
request or read/write access which amortizes the GPU readiness
time.

The first fault and read/write checks the GPU state when the
reset_done flag - which denotes whether the GPU has just been
reset. The memory_lock is taken across map/access to avoid
races with GPU reset.

Cc: Shameer Kolothum <skolothumtho@nvidia.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Vikram Sethi <vsethi@nvidia.com>
Suggested-by: Alex Williamson <alex@shazbot.org>
Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/nvgrace-gpu/main.c | 81 +++++++++++++++++++++++++----
 1 file changed, 72 insertions(+), 9 deletions(-)

diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
index b46984e76be7..3064f8aca858 100644
--- a/drivers/vfio/pci/nvgrace-gpu/main.c
+++ b/drivers/vfio/pci/nvgrace-gpu/main.c
@@ -104,6 +104,17 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
 		mutex_init(&nvdev->remap_lock);
 	}
 
+	/*
+	 * GPU readiness is checked by reading the BAR0 registers.
+	 *
+	 * ioremap BAR0 to ensure that the BAR0 mapping is present before
+	 * register reads on first fault before establishing any GPU
+	 * memory mapping.
+	 */
+	ret = vfio_pci_core_setup_barmap(vdev, 0);
+	if (ret)
+		return ret;
+
 	vfio_pci_core_finish_enable(vdev);
 
 	return 0;
@@ -146,6 +157,31 @@ static int nvgrace_gpu_wait_device_ready(void __iomem *io)
 	return -ETIME;
 }
 
+/*
+ * If the GPU memory is accessed by the CPU while the GPU is not ready
+ * after reset, it can cause harmless corrected RAS events to be logged.
+ * Make sure the GPU is ready before establishing the mappings.
+ */
+static int
+nvgrace_gpu_check_device_ready(struct nvgrace_gpu_pci_core_device *nvdev)
+{
+	struct vfio_pci_core_device *vdev = &nvdev->core_device;
+	int ret;
+
+	lockdep_assert_held_read(&vdev->memory_lock);
+
+	if (!nvdev->reset_done)
+		return 0;
+
+	ret = nvgrace_gpu_wait_device_ready(vdev->barmap[0]);
+	if (ret)
+		return ret;
+
+	nvdev->reset_done = false;
+
+	return 0;
+}
+
 static unsigned long addr_to_pgoff(struct vm_area_struct *vma,
 				   unsigned long addr)
 {
@@ -163,13 +199,13 @@ static vm_fault_t nvgrace_gpu_vfio_pci_huge_fault(struct vm_fault *vmf,
 	struct vfio_pci_core_device *vdev = &nvdev->core_device;
 	unsigned int index =
 		vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
-	vm_fault_t ret = VM_FAULT_SIGBUS;
+	vm_fault_t ret;
 	struct mem_region *memregion;
 	unsigned long pfn, addr;
 
 	memregion = nvgrace_gpu_memregion(index, nvdev);
 	if (!memregion)
-		return ret;
+		return VM_FAULT_SIGBUS;
 
 	addr = ALIGN_DOWN(vmf->address, PAGE_SIZE << order);
 	pfn = PHYS_PFN(memregion->memphys) + addr_to_pgoff(vma, addr);
@@ -179,8 +215,14 @@ static vm_fault_t nvgrace_gpu_vfio_pci_huge_fault(struct vm_fault *vmf,
 		goto out;
 	}
 
-	scoped_guard(rwsem_read, &vdev->memory_lock)
+	scoped_guard(rwsem_read, &vdev->memory_lock) {
+		if (nvgrace_gpu_check_device_ready(nvdev)) {
+			ret = VM_FAULT_SIGBUS;
+			goto out;
+		}
+
 		ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
+	}
 
 out:
 	dev_dbg_ratelimited(&vdev->pdev->dev,
@@ -593,9 +635,15 @@ nvgrace_gpu_read_mem(struct nvgrace_gpu_pci_core_device *nvdev,
 	else
 		mem_count = min(count, memregion->memlength - (size_t)offset);
 
-	ret = nvgrace_gpu_map_and_read(nvdev, buf, mem_count, ppos);
-	if (ret)
-		return ret;
+	scoped_guard(rwsem_read, &nvdev->core_device.memory_lock) {
+		ret = nvgrace_gpu_check_device_ready(nvdev);
+		if (ret)
+			return ret;
+
+		ret = nvgrace_gpu_map_and_read(nvdev, buf, mem_count, ppos);
+		if (ret)
+			return ret;
+	}
 
 	/*
 	 * Only the device memory present on the hardware is mapped, which may
@@ -713,9 +761,15 @@ nvgrace_gpu_write_mem(struct nvgrace_gpu_pci_core_device *nvdev,
 	 */
 	mem_count = min(count, memregion->memlength - (size_t)offset);
 
-	ret = nvgrace_gpu_map_and_write(nvdev, buf, mem_count, ppos);
-	if (ret)
-		return ret;
+	scoped_guard(rwsem_read, &nvdev->core_device.memory_lock) {
+		ret = nvgrace_gpu_check_device_ready(nvdev);
+		if (ret)
+			return ret;
+
+		ret = nvgrace_gpu_map_and_write(nvdev, buf, mem_count, ppos);
+		if (ret)
+			return ret;
+	}
 
 exitfn:
 	*ppos += count;
@@ -1056,6 +1110,15 @@ MODULE_DEVICE_TABLE(pci, nvgrace_gpu_vfio_pci_table);
  *
  * The reset_done implementation is triggered on every reset and is used
  * set the reset_done variable that assists in achieving the serialization.
+ *
+ * The writer memory_lock is held during reset through ioctl and FLR, while
+ * the reader is held in the fault and access code.
+ *
+ * The lock is however not taken during reset called through
+ * vfio_pci_core_enable during open. Whilst a serialization is not
+ * required at that early stage, it still prevents from putting
+ * lockdep_assert_held_write in this function.
+ *
  */
 static void nvgrace_gpu_vfio_pci_reset_done(struct pci_dev *pdev)
 {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap
  2025-11-26  5:26 ` [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap ankita
@ 2025-11-26  8:59   ` Shameer Kolothum
  2025-11-26 15:22   ` Alex Williamson
  1 sibling, 0 replies; 17+ messages in thread
From: Shameer Kolothum @ 2025-11-26  8:59 UTC (permalink / raw)
  To: Ankit Agrawal, jgg, Yishai Hadas, kevin.tian, alex,
	Aniket Agashe, Vikram Sethi, Matt Ochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, Avihai Horon, bhelgaas,
	peterx, pstanner, Alistair Popple, kvm, linux-kernel, Neo Jia,
	Kirti Wankhede, Tarun Gupta (SW-GPU),
	Zhi Wang, Dan Williams, Dheeraj Nigam, Krishnakant Jaju



> -----Original Message-----
> From: Ankit Agrawal <ankita@nvidia.com>
> Sent: 26 November 2025 05:26
> To: Ankit Agrawal <ankita@nvidia.com>; jgg@ziepe.ca; Yishai Hadas
> <yishaih@nvidia.com>; Shameer Kolothum <skolothumtho@nvidia.com>;
> kevin.tian@intel.com; alex@shazbot.org; Aniket Agashe
> <aniketa@nvidia.com>; Vikram Sethi <vsethi@nvidia.com>; Matt Ochs
> <mochs@nvidia.com>
> Cc: Yunxiang.Li@amd.com; yi.l.liu@intel.com;
> zhangdongdong@eswincomputing.com; Avihai Horon <avihaih@nvidia.com>;
> bhelgaas@google.com; peterx@redhat.com; pstanner@redhat.com; Alistair
> Popple <apopple@nvidia.com>; kvm@vger.kernel.org; linux-
> kernel@vger.kernel.org; Neo Jia <cjia@nvidia.com>; Kirti Wankhede
> <kwankhede@nvidia.com>; Tarun Gupta (SW-GPU) <targupta@nvidia.com>;
> Zhi Wang <zhiw@nvidia.com>; Dan Williams <danw@nvidia.com>; Dheeraj
> Nigam <dnigam@nvidia.com>; Krishnakant Jaju <kjaju@nvidia.com>
> Subject: [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap
> 
> From: Ankit Agrawal <ankita@nvidia.com>
> 
> NVIDIA's Grace based systems have large device memory. The device
> memory is mapped as VM_PFNMAP in the VMM VMA. The nvgrace-gpu
> module could make use of the huge PFNMAP support added in mm [1].
> 
> To make use of the huge pfnmap support, fault/huge_fault ops
> based mapping mechanism needs to be implemented. Currently nvgrace-gpu
> module relies on remap_pfn_range to do the mapping during VM bootup.
> Replace it to instead rely on fault and use vfio_pci_vmf_insert_pfn
> to setup the mapping.
> 
> Moreover to enable huge pfnmap, nvgrace-gpu module is updated by
> adding huge_fault ops implementation. The implementation establishes
> mapping according to the order request. Note that if the PFN or the
> VMA address is unaligned to the order, the mapping fallbacks to
> the PTE level.
> 
> Link: https://lore.kernel.org/all/20240826204353.2228736-1-
> peterx@redhat.com/ [1]
> 
> Cc: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Vikram Sethi <vsethi@nvidia.com>
> Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>

Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset
  2025-11-26  5:26 ` [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset ankita
@ 2025-11-26  9:00   ` Shameer Kolothum
  2025-11-26 15:23   ` Alex Williamson
  1 sibling, 0 replies; 17+ messages in thread
From: Shameer Kolothum @ 2025-11-26  9:00 UTC (permalink / raw)
  To: Ankit Agrawal, jgg, Yishai Hadas, kevin.tian, alex,
	Aniket Agashe, Vikram Sethi, Matt Ochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, Avihai Horon, bhelgaas,
	peterx, pstanner, Alistair Popple, kvm, linux-kernel, Neo Jia,
	Kirti Wankhede, Tarun Gupta (SW-GPU),
	Zhi Wang, Dan Williams, Dheeraj Nigam, Krishnakant Jaju



> -----Original Message-----
> From: Ankit Agrawal <ankita@nvidia.com>
> Sent: 26 November 2025 05:26
> To: Ankit Agrawal <ankita@nvidia.com>; jgg@ziepe.ca; Yishai Hadas
> <yishaih@nvidia.com>; Shameer Kolothum <skolothumtho@nvidia.com>;
> kevin.tian@intel.com; alex@shazbot.org; Aniket Agashe
> <aniketa@nvidia.com>; Vikram Sethi <vsethi@nvidia.com>; Matt Ochs
> <mochs@nvidia.com>
> Cc: Yunxiang.Li@amd.com; yi.l.liu@intel.com;
> zhangdongdong@eswincomputing.com; Avihai Horon <avihaih@nvidia.com>;
> bhelgaas@google.com; peterx@redhat.com; pstanner@redhat.com; Alistair
> Popple <apopple@nvidia.com>; kvm@vger.kernel.org; linux-
> kernel@vger.kernel.org; Neo Jia <cjia@nvidia.com>; Kirti Wankhede
> <kwankhede@nvidia.com>; Tarun Gupta (SW-GPU) <targupta@nvidia.com>;
> Zhi Wang <zhiw@nvidia.com>; Dan Williams <danw@nvidia.com>; Dheeraj
> Nigam <dnigam@nvidia.com>; Krishnakant Jaju <kjaju@nvidia.com>
> Subject: [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after
> reset
> 
> From: Ankit Agrawal <ankita@nvidia.com>
> 
> Introduce a new flag reset_done to notify that the GPU has just
> been reset and the mapping to the GPU memory is zapped.
> 
> Implement the reset_done handler to set this new variable. It
> will be used later in the patches to wait for the GPU memory
> to be ready before doing any mapping or access.
> 
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Suggested-by: Alex Williamson <alex@shazbot.org>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>

Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready
  2025-11-26  5:26 ` [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready ankita
@ 2025-11-26  9:03   ` Shameer Kolothum
  2025-11-26  9:49     ` Ankit Agrawal
  2025-11-26 15:23   ` Alex Williamson
  1 sibling, 1 reply; 17+ messages in thread
From: Shameer Kolothum @ 2025-11-26  9:03 UTC (permalink / raw)
  To: Ankit Agrawal, jgg, Yishai Hadas, kevin.tian, alex,
	Aniket Agashe, Vikram Sethi, Matt Ochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, Avihai Horon, bhelgaas,
	peterx, pstanner, Alistair Popple, kvm, linux-kernel, Neo Jia,
	Kirti Wankhede, Tarun Gupta (SW-GPU),
	Zhi Wang, Dan Williams, Dheeraj Nigam, Krishnakant Jaju



> -----Original Message-----
> From: Ankit Agrawal <ankita@nvidia.com>
> Sent: 26 November 2025 05:26
> To: Ankit Agrawal <ankita@nvidia.com>; jgg@ziepe.ca; Yishai Hadas
> <yishaih@nvidia.com>; Shameer Kolothum <skolothumtho@nvidia.com>;
> kevin.tian@intel.com; alex@shazbot.org; Aniket Agashe
> <aniketa@nvidia.com>; Vikram Sethi <vsethi@nvidia.com>; Matt Ochs
> <mochs@nvidia.com>
> Cc: Yunxiang.Li@amd.com; yi.l.liu@intel.com;
> zhangdongdong@eswincomputing.com; Avihai Horon <avihaih@nvidia.com>;
> bhelgaas@google.com; peterx@redhat.com; pstanner@redhat.com; Alistair
> Popple <apopple@nvidia.com>; kvm@vger.kernel.org; linux-
> kernel@vger.kernel.org; Neo Jia <cjia@nvidia.com>; Kirti Wankhede
> <kwankhede@nvidia.com>; Tarun Gupta (SW-GPU) <targupta@nvidia.com>;
> Zhi Wang <zhiw@nvidia.com>; Dan Williams <danw@nvidia.com>; Dheeraj
> Nigam <dnigam@nvidia.com>; Krishnakant Jaju <kjaju@nvidia.com>
> Subject: [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready
> 
> From: Ankit Agrawal <ankita@nvidia.com>
> 
> Speculative prefetches from CPU to GPU memory until the GPU is
> ready after reset can cause harmless corrected RAS events to
> be logged on Grace systems. It is thus preferred that the
> mapping not be re-established until the GPU is ready post reset.
> 
> The GPU readiness can be checked through BAR0 registers similar
> to the checking at the time of device probe.
> 
> It can take several seconds for the GPU to be ready. So it is
> desirable that the time overlaps as much of the VM startup as
> possible to reduce impact on the VM bootup time. The GPU
> readiness state is thus checked on the first fault/huge_fault
> request or read/write access which amortizes the GPU readiness
> time.
> 
> The first fault and read/write checks the GPU state when the
> reset_done flag - which denotes whether the GPU has just been
> reset. The memory_lock is taken across map/access to avoid
> races with GPU reset.
> 
> Cc: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Vikram Sethi <vsethi@nvidia.com>
> Suggested-by: Alex Williamson <alex@shazbot.org>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  drivers/vfio/pci/nvgrace-gpu/main.c | 81 +++++++++++++++++++++++++---
> -
>  1 file changed, 72 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-
> gpu/main.c
> index b46984e76be7..3064f8aca858 100644
> --- a/drivers/vfio/pci/nvgrace-gpu/main.c
> +++ b/drivers/vfio/pci/nvgrace-gpu/main.c
> @@ -104,6 +104,17 @@ static int nvgrace_gpu_open_device(struct
> vfio_device *core_vdev)
>  		mutex_init(&nvdev->remap_lock);
>  	}
> 
> +	/*
> +	 * GPU readiness is checked by reading the BAR0 registers.
> +	 *
> +	 * ioremap BAR0 to ensure that the BAR0 mapping is present before
> +	 * register reads on first fault before establishing any GPU
> +	 * memory mapping.
> +	 */
> +	ret = vfio_pci_core_setup_barmap(vdev, 0);
> +	if (ret)
> +		return ret;

Should make sure vfio_pci_core_disable() is called on err path above.

With that,
Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready
  2025-11-26  9:03   ` Shameer Kolothum
@ 2025-11-26  9:49     ` Ankit Agrawal
  2025-11-26 11:35       ` Ankit Agrawal
  0 siblings, 1 reply; 17+ messages in thread
From: Ankit Agrawal @ 2025-11-26  9:49 UTC (permalink / raw)
  To: Shameer Kolothum, jgg, Yishai Hadas, kevin.tian, alex,
	Aniket Agashe, Vikram Sethi, Matt Ochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, Avihai Horon, bhelgaas,
	peterx, pstanner, Alistair Popple, kvm, linux-kernel, Neo Jia,
	Kirti Wankhede, Tarun Gupta (SW-GPU),
	Zhi Wang, Dan Williams, Dheeraj Nigam, Krishnakant Jaju

>> +     ret = vfio_pci_core_setup_barmap(vdev, 0);
>> +     if (ret)
>> +             return ret;
>
> Should make sure vfio_pci_core_disable() is called on err path above.

Thanks Shameer for the review! Yeah, we should not have that if (ret)
check and let the flow fall to the vfio_pci_core_disable().

> With that,
> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>






^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready
  2025-11-26  9:49     ` Ankit Agrawal
@ 2025-11-26 11:35       ` Ankit Agrawal
  0 siblings, 0 replies; 17+ messages in thread
From: Ankit Agrawal @ 2025-11-26 11:35 UTC (permalink / raw)
  To: Shameer Kolothum, jgg, Yishai Hadas, kevin.tian, alex,
	Aniket Agashe, Vikram Sethi, Matt Ochs
  Cc: Yunxiang.Li, yi.l.liu, zhangdongdong, Avihai Horon, bhelgaas,
	peterx, pstanner, Alistair Popple, kvm, linux-kernel, Neo Jia,
	Kirti Wankhede, Tarun Gupta (SW-GPU),
	Zhi Wang, Dan Williams, Dheeraj Nigam, Krishnakant Jaju

>> +     ret = vfio_pci_core_setup_barmap(vdev, 0);
>> +     if (ret)
>> +             return ret;
>
> Should make sure vfio_pci_core_disable() is called on err path above.

Yes, will have to do the following.

@@ -112,8 +112,10 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
         * memory mapping.
         */
        ret = vfio_pci_core_setup_barmap(vdev, 0);
-       if (ret)
+       if (ret) {
+               vfio_pci_core_disable(vdev);
                return ret;
+       }

        vfio_pci_core_finish_enable(vdev);

> With that,
> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>














^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function
  2025-11-26  5:26 ` [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function ankita
@ 2025-11-26 15:22   ` Alex Williamson
  0 siblings, 0 replies; 17+ messages in thread
From: Alex Williamson @ 2025-11-26 15:22 UTC (permalink / raw)
  To: ankita
  Cc: jgg, yishaih, skolothumtho, kevin.tian, aniketa, vsethi, mochs,
	Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

On Wed, 26 Nov 2025 05:26:22 +0000
<ankita@nvidia.com> wrote:

> From: Ankit Agrawal <ankita@nvidia.com>
> 
> Refactor vfio_pci_mmap_huge_fault to take out the implementation
> to map the VMA to the PTE/PMD/PUD as a separate function.
> 
> Export the new function to be used by nvgrace-gpu module.
> 
> No functional change is intended.
> 
> Cc: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  drivers/vfio/pci/vfio_pci_core.c | 54 +++++++++++++++++---------------
>  include/linux/vfio_pci_core.h    | 16 ++++++++++
>  2 files changed, 45 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 7dcf5439dedc..52e3a10d776b 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1640,48 +1640,52 @@ static unsigned long vma_to_pfn(struct vm_area_struct *vma)
>  	return (pci_resource_start(vdev->pdev, index) >> PAGE_SHIFT) + pgoff;
>  }
>  
> -static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
> -					   unsigned int order)
> +vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
> +				   struct vm_fault *vmf,
> +				   unsigned long pfn,
> +				   unsigned int order)
>  {
> -	struct vm_area_struct *vma = vmf->vma;
> -	struct vfio_pci_core_device *vdev = vma->vm_private_data;
> -	unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
> -	unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
> -	unsigned long pfn = vma_to_pfn(vma) + pgoff;
> -	vm_fault_t ret = VM_FAULT_SIGBUS;
> -
> -	if (order && (addr < vma->vm_start ||
> -		      addr + (PAGE_SIZE << order) > vma->vm_end ||
> -		      pfn & ((1 << order) - 1))) {
> -		ret = VM_FAULT_FALLBACK;
> -		goto out;
> -	}
> -
> -	down_read(&vdev->memory_lock);
> +	lockdep_assert_held_read(&vdev->memory_lock);
>  
>  	if (vdev->pm_runtime_engaged || !__vfio_pci_memory_enabled(vdev))
> -		goto out_unlock;
> +		return VM_FAULT_SIGBUS;
>  
>  	switch (order) {
>  	case 0:
> -		ret = vmf_insert_pfn(vma, vmf->address, pfn);
> -		break;
> +		return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
>  #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
>  	case PMD_ORDER:
> -		ret = vmf_insert_pfn_pmd(vmf, pfn, false);
> -		break;
> +		return vmf_insert_pfn_pmd(vmf, pfn, false);
>  #endif
>  #ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
>  	case PUD_ORDER:
> -		ret = vmf_insert_pfn_pud(vmf, pfn, false);
> +		return vmf_insert_pfn_pud(vmf, pfn, false);
>  		break;
>  #endif
>  	default:
> +		return VM_FAULT_FALLBACK;
> +	}
> +}
> +EXPORT_SYMBOL_GPL(vfio_pci_vmf_insert_pfn);
> +
> +static vm_fault_t vfio_pci_mmap_huge_fault(struct vm_fault *vmf,
> +					   unsigned int order)
> +{
> +	struct vm_area_struct *vma = vmf->vma;
> +	struct vfio_pci_core_device *vdev = vma->vm_private_data;
> +	unsigned long addr = vmf->address & ~((PAGE_SIZE << order) - 1);
> +	unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
> +	unsigned long pfn = vma_to_pfn(vma) + pgoff;
> +	vm_fault_t ret;
> +
> +	if (unmappable_for_order(vma, addr, pfn, order)) {
>  		ret = VM_FAULT_FALLBACK;
> +		goto out;
>  	}
>  
> -out_unlock:
> -	up_read(&vdev->memory_lock);
> +	scoped_guard(rwsem_read, &vdev->memory_lock)
> +		ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
> +
>  out:

We really don't need a goto to jump over this tiny section of code.
With the naming/polarity change below this can just be:

	vm_fault_t ret = VM_FAULT_FALLBACK;

	if (is_aligned_for_order(vma, addr, pfn, order)) {
		scoped_guard(rwsem_read, &vdev->memory_lock)
			ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
	}


>  	dev_dbg_ratelimited(&vdev->pdev->dev,
>  			   "%s(,order = %d) BAR %ld page offset 0x%lx: 0x%x\n",
> diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
> index f541044e42a2..1d457216ce4d 100644
> --- a/include/linux/vfio_pci_core.h
> +++ b/include/linux/vfio_pci_core.h
> @@ -119,6 +119,9 @@ ssize_t vfio_pci_core_read(struct vfio_device *core_vdev, char __user *buf,
>  		size_t count, loff_t *ppos);
>  ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *buf,
>  		size_t count, loff_t *ppos);
> +vm_fault_t vfio_pci_vmf_insert_pfn(struct vfio_pci_core_device *vdev,
> +				   struct vm_fault *vmf, unsigned long pfn,
> +				   unsigned int order);
>  int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma);
>  void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count);
>  int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf);
> @@ -161,4 +164,17 @@ VFIO_IOREAD_DECLARATION(32)
>  VFIO_IOREAD_DECLARATION(64)
>  #endif
>  
> +static inline bool unmappable_for_order(struct vm_area_struct *vma,
> +					unsigned long addr,
> +					unsigned long pfn,
> +					unsigned int order)
> +{
> +	if (order && (addr < vma->vm_start ||
> +		      addr + (PAGE_SIZE << order) > vma->vm_end ||
> +		      !IS_ALIGNED(pfn, 1 << order)))
> +		return true;
> +
> +	return false;
> +}


Change polarity and rename to is_aligned_for_order()?  No need for
branched return.

	return !(order && (addr < vma->vm_start ||
			   addr + (PAGE_SIZE << order) > vma->vm_end ||
			   !IS_ALIGNED(pfn, 1 << order)));

Describe this change in the commit log.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap
  2025-11-26  5:26 ` [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap ankita
  2025-11-26  8:59   ` Shameer Kolothum
@ 2025-11-26 15:22   ` Alex Williamson
  1 sibling, 0 replies; 17+ messages in thread
From: Alex Williamson @ 2025-11-26 15:22 UTC (permalink / raw)
  To: ankita
  Cc: jgg, yishaih, skolothumtho, kevin.tian, aniketa, vsethi, mochs,
	Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

On Wed, 26 Nov 2025 05:26:23 +0000
<ankita@nvidia.com> wrote:

> From: Ankit Agrawal <ankita@nvidia.com>
> 
> NVIDIA's Grace based systems have large device memory. The device
> memory is mapped as VM_PFNMAP in the VMM VMA. The nvgrace-gpu
> module could make use of the huge PFNMAP support added in mm [1].
> 
> To make use of the huge pfnmap support, fault/huge_fault ops
> based mapping mechanism needs to be implemented. Currently nvgrace-gpu
> module relies on remap_pfn_range to do the mapping during VM bootup.
> Replace it to instead rely on fault and use vfio_pci_vmf_insert_pfn
> to setup the mapping.
> 
> Moreover to enable huge pfnmap, nvgrace-gpu module is updated by
> adding huge_fault ops implementation. The implementation establishes
> mapping according to the order request. Note that if the PFN or the
> VMA address is unaligned to the order, the mapping fallbacks to
> the PTE level.
> 
> Link: https://lore.kernel.org/all/20240826204353.2228736-1-peterx@redhat.com/ [1]
> 
> Cc: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Vikram Sethi <vsethi@nvidia.com>
> Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  drivers/vfio/pci/nvgrace-gpu/main.c | 85 +++++++++++++++++++++--------
>  1 file changed, 63 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
> index e346392b72f6..ac9551b9e4b6 100644
> --- a/drivers/vfio/pci/nvgrace-gpu/main.c
> +++ b/drivers/vfio/pci/nvgrace-gpu/main.c
> @@ -130,6 +130,63 @@ static void nvgrace_gpu_close_device(struct vfio_device *core_vdev)
>  	vfio_pci_core_close_device(core_vdev);
>  }
>  
> +static unsigned long addr_to_pgoff(struct vm_area_struct *vma,
> +				   unsigned long addr)
> +{
> +	u64 pgoff = vma->vm_pgoff &
> +		((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
> +
> +	return ((addr - vma->vm_start) >> PAGE_SHIFT) + pgoff;
> +}
> +
> +static vm_fault_t nvgrace_gpu_vfio_pci_huge_fault(struct vm_fault *vmf,
> +						  unsigned int order)
> +{
> +	struct vm_area_struct *vma = vmf->vma;
> +	struct nvgrace_gpu_pci_core_device *nvdev = vma->vm_private_data;
> +	struct vfio_pci_core_device *vdev = &nvdev->core_device;
> +	unsigned int index =
> +		vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
> +	vm_fault_t ret = VM_FAULT_SIGBUS;
> +	struct mem_region *memregion;
> +	unsigned long pfn, addr;
> +
> +	memregion = nvgrace_gpu_memregion(index, nvdev);
> +	if (!memregion)
> +		return ret;
> +
> +	addr = ALIGN_DOWN(vmf->address, PAGE_SIZE << order);
> +	pfn = PHYS_PFN(memregion->memphys) + addr_to_pgoff(vma, addr);
> +
> +	if (unmappable_for_order(vma, addr, pfn, order)) {
> +		ret = VM_FAULT_FALLBACK;
> +		goto out;
> +	}
> +
> +	scoped_guard(rwsem_read, &vdev->memory_lock)
> +		ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
> +
> +out:

Adopt same code flow as suggested in 1/, return SIGBUS directly for
!memregion, initialize ret to FALLBACK.  Thanks,

Alex

> +	dev_dbg_ratelimited(&vdev->pdev->dev,
> +			    "%s order = %d pfn 0x%lx: 0x%x\n",
> +			    __func__, order, pfn,
> +			    (unsigned int)ret);
> +
> +	return ret;
> +}
> +
> +static vm_fault_t nvgrace_gpu_vfio_pci_fault(struct vm_fault *vmf)
> +{
> +	return nvgrace_gpu_vfio_pci_huge_fault(vmf, 0);
> +}
> +
> +static const struct vm_operations_struct nvgrace_gpu_vfio_pci_mmap_ops = {
> +	.fault = nvgrace_gpu_vfio_pci_fault,
> +#ifdef CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP
> +	.huge_fault = nvgrace_gpu_vfio_pci_huge_fault,
> +#endif
> +};
> +
>  static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
>  			    struct vm_area_struct *vma)
>  {
> @@ -137,10 +194,8 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
>  		container_of(core_vdev, struct nvgrace_gpu_pci_core_device,
>  			     core_device.vdev);
>  	struct mem_region *memregion;
> -	unsigned long start_pfn;
>  	u64 req_len, pgoff, end;
>  	unsigned int index;
> -	int ret = 0;
>  
>  	index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
>  
> @@ -157,17 +212,18 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
>  		((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
>  
>  	if (check_sub_overflow(vma->vm_end, vma->vm_start, &req_len) ||
> -	    check_add_overflow(PHYS_PFN(memregion->memphys), pgoff, &start_pfn) ||
>  	    check_add_overflow(PFN_PHYS(pgoff), req_len, &end))
>  		return -EOVERFLOW;
>  
>  	/*
> -	 * Check that the mapping request does not go beyond available device
> -	 * memory size
> +	 * Check that the mapping request does not go beyond the exposed
> +	 * device memory size.
>  	 */
>  	if (end > memregion->memlength)
>  		return -EINVAL;
>  
> +	vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
> +
>  	/*
>  	 * The carved out region of the device memory needs the NORMAL_NC
>  	 * property. Communicate as such to the hypervisor.
> @@ -184,23 +240,8 @@ static int nvgrace_gpu_mmap(struct vfio_device *core_vdev,
>  		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
>  	}
>  
> -	/*
> -	 * Perform a PFN map to the memory and back the device BAR by the
> -	 * GPU memory.
> -	 *
> -	 * The available GPU memory size may not be power-of-2 aligned. The
> -	 * remainder is only backed by vfio_device_ops read/write handlers.
> -	 *
> -	 * During device reset, the GPU is safely disconnected to the CPU
> -	 * and access to the BAR will be immediately returned preventing
> -	 * machine check.
> -	 */
> -	ret = remap_pfn_range(vma, vma->vm_start, start_pfn,
> -			      req_len, vma->vm_page_prot);
> -	if (ret)
> -		return ret;
> -
> -	vma->vm_pgoff = start_pfn;
> +	vma->vm_ops = &nvgrace_gpu_vfio_pci_mmap_ops;
> +	vma->vm_private_data = nvdev;
>  
>  	return 0;
>  }


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 4/6] vfio/nvgrace-gpu: split the code to wait for GPU ready
  2025-11-26  5:26 ` [PATCH v7 4/6] vfio/nvgrace-gpu: split the code to wait for GPU ready ankita
@ 2025-11-26 15:22   ` Alex Williamson
  0 siblings, 0 replies; 17+ messages in thread
From: Alex Williamson @ 2025-11-26 15:22 UTC (permalink / raw)
  To: ankita
  Cc: jgg, yishaih, skolothumtho, kevin.tian, aniketa, vsethi, mochs,
	Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

On Wed, 26 Nov 2025 05:26:25 +0000
<ankita@nvidia.com> wrote:

> From: Ankit Agrawal <ankita@nvidia.com>
> 
> Split the function that check for the GPU device being ready on
> the probe.
> 
> Move the code to wait for the GPU to be ready through BAR0 register
> reads to a separate function. This would help reuse the code.
> 
> This also fixes a bug where the return status in case of timeout
> gets overridden by return from pci_enable_device. With the fix,
> a timeout generate an error as initially intended.
> 
> Fixes: d85f69d520e6 ("vfio/nvgrace-gpu: Check the HBM training and C2C link status")
> 
> Reviewed-by: Zhi Wang <zhiw@nvidia.com>
> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  drivers/vfio/pci/nvgrace-gpu/main.c | 29 +++++++++++++++++------------
>  1 file changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
> index ac9551b9e4b6..f691deb8e43c 100644
> --- a/drivers/vfio/pci/nvgrace-gpu/main.c
> +++ b/drivers/vfio/pci/nvgrace-gpu/main.c
> @@ -130,6 +130,20 @@ static void nvgrace_gpu_close_device(struct vfio_device *core_vdev)
>  	vfio_pci_core_close_device(core_vdev);
>  }
>  
> +static int nvgrace_gpu_wait_device_ready(void __iomem *io)
> +{
> +	unsigned long timeout = jiffies + msecs_to_jiffies(POLL_TIMEOUT_MS);
> +
> +	do {
> +		if ((ioread32(io + C2C_LINK_BAR0_OFFSET) == STATUS_READY) &&
> +		    (ioread32(io + HBM_TRAINING_BAR0_OFFSET) == STATUS_READY))
> +			return 0;
> +		msleep(POLL_QUANTUM_MS);
> +	} while (!time_after(jiffies, timeout));
> +
> +	return -ETIME;
> +}
> +
>  static unsigned long addr_to_pgoff(struct vm_area_struct *vma,
>  				   unsigned long addr)
>  {
> @@ -934,9 +948,8 @@ static bool nvgrace_gpu_has_mig_hw_bug(struct pci_dev *pdev)
>   * Ensure that the BAR0 region is enabled before accessing the
>   * registers.
>   */
> -static int nvgrace_gpu_wait_device_ready(struct pci_dev *pdev)
> +static int nvgrace_gpu_probe_check_device_ready(struct pci_dev *pdev)
>  {
> -	unsigned long timeout = jiffies + msecs_to_jiffies(POLL_TIMEOUT_MS);
>  	void __iomem *io;
>  	int ret = -ETIME;

ret initialization is not needed, it's immediately clobbered.  Thanks,

Alex


>  
> @@ -954,16 +967,8 @@ static int nvgrace_gpu_wait_device_ready(struct pci_dev *pdev)
>  		goto iomap_exit;
>  	}
>  
> -	do {
> -		if ((ioread32(io + C2C_LINK_BAR0_OFFSET) == STATUS_READY) &&
> -		    (ioread32(io + HBM_TRAINING_BAR0_OFFSET) == STATUS_READY)) {
> -			ret = 0;
> -			goto reg_check_exit;
> -		}
> -		msleep(POLL_QUANTUM_MS);
> -	} while (!time_after(jiffies, timeout));
> +	ret = nvgrace_gpu_wait_device_ready(io);
>  
> -reg_check_exit:
>  	pci_iounmap(pdev, io);
>  iomap_exit:
>  	pci_release_selected_regions(pdev, 1 << 0);
> @@ -980,7 +985,7 @@ static int nvgrace_gpu_probe(struct pci_dev *pdev,
>  	u64 memphys, memlength;
>  	int ret;
>  
> -	ret = nvgrace_gpu_wait_device_ready(pdev);
> +	ret = nvgrace_gpu_probe_check_device_ready(pdev);
>  	if (ret)
>  		return ret;
>  


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset
  2025-11-26  5:26 ` [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset ankita
  2025-11-26  9:00   ` Shameer Kolothum
@ 2025-11-26 15:23   ` Alex Williamson
  1 sibling, 0 replies; 17+ messages in thread
From: Alex Williamson @ 2025-11-26 15:23 UTC (permalink / raw)
  To: ankita
  Cc: jgg, yishaih, skolothumtho, kevin.tian, aniketa, vsethi, mochs,
	Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

On Wed, 26 Nov 2025 05:26:26 +0000
<ankita@nvidia.com> wrote:

> From: Ankit Agrawal <ankita@nvidia.com>
> 
> Introduce a new flag reset_done to notify that the GPU has just
> been reset and the mapping to the GPU memory is zapped.
> 
> Implement the reset_done handler to set this new variable. It
> will be used later in the patches to wait for the GPU memory
> to be ready before doing any mapping or access.
> 
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Suggested-by: Alex Williamson <alex@shazbot.org>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  drivers/vfio/pci/nvgrace-gpu/main.c | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
> index f691deb8e43c..b46984e76be7 100644
> --- a/drivers/vfio/pci/nvgrace-gpu/main.c
> +++ b/drivers/vfio/pci/nvgrace-gpu/main.c
> @@ -58,6 +58,8 @@ struct nvgrace_gpu_pci_core_device {
>  	/* Lock to control device memory kernel mapping */
>  	struct mutex remap_lock;
>  	bool has_mig_hw_bug;
> +	/* GPU has just been reset */
> +	bool reset_done;
>  };
>  
>  static void nvgrace_gpu_init_fake_bar_emu_regs(struct vfio_device *core_vdev)
> @@ -1048,12 +1050,34 @@ static const struct pci_device_id nvgrace_gpu_vfio_pci_table[] = {
>  
>  MODULE_DEVICE_TABLE(pci, nvgrace_gpu_vfio_pci_table);
>  
> +/*
> + * The GPU reset is required to be serialized against the *first* mapping
> + * faults and read/writes accesses to prevent potential RAS events logging.
> + *
> + * The reset_done implementation is triggered on every reset and is used
> + * set the reset_done variable that assists in achieving the serialization.

I can't parse this last sentence, "used _to_ set"?.  Maybe something as
simple as:

/*
 * First fault or access after a reset needs to poll device readiness,
 * flag that a reset has occurred.
 */

Thanks,
Alex

> + */
> +static void nvgrace_gpu_vfio_pci_reset_done(struct pci_dev *pdev)
> +{
> +	struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
> +	struct nvgrace_gpu_pci_core_device *nvdev =
> +		container_of(core_device, struct nvgrace_gpu_pci_core_device,
> +			     core_device);
> +
> +	nvdev->reset_done = true;
> +}
> +
> +static const struct pci_error_handlers nvgrace_gpu_vfio_pci_err_handlers = {
> +	.reset_done = nvgrace_gpu_vfio_pci_reset_done,
> +	.error_detected = vfio_pci_core_aer_err_detected,
> +};
> +
>  static struct pci_driver nvgrace_gpu_vfio_pci_driver = {
>  	.name = KBUILD_MODNAME,
>  	.id_table = nvgrace_gpu_vfio_pci_table,
>  	.probe = nvgrace_gpu_probe,
>  	.remove = nvgrace_gpu_remove,
> -	.err_handler = &vfio_pci_core_err_handlers,
> +	.err_handler = &nvgrace_gpu_vfio_pci_err_handlers,
>  	.driver_managed_dma = true,
>  };
>  


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready
  2025-11-26  5:26 ` [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready ankita
  2025-11-26  9:03   ` Shameer Kolothum
@ 2025-11-26 15:23   ` Alex Williamson
  1 sibling, 0 replies; 17+ messages in thread
From: Alex Williamson @ 2025-11-26 15:23 UTC (permalink / raw)
  To: ankita
  Cc: jgg, yishaih, skolothumtho, kevin.tian, aniketa, vsethi, mochs,
	Yunxiang.Li, yi.l.liu, zhangdongdong, avihaih, bhelgaas, peterx,
	pstanner, apopple, kvm, linux-kernel, cjia, kwankhede, targupta,
	zhiw, danw, dnigam, kjaju

On Wed, 26 Nov 2025 05:26:27 +0000
<ankita@nvidia.com> wrote:

> From: Ankit Agrawal <ankita@nvidia.com>
> 
> Speculative prefetches from CPU to GPU memory until the GPU is
> ready after reset can cause harmless corrected RAS events to
> be logged on Grace systems. It is thus preferred that the
> mapping not be re-established until the GPU is ready post reset.
> 
> The GPU readiness can be checked through BAR0 registers similar
> to the checking at the time of device probe.
> 
> It can take several seconds for the GPU to be ready. So it is
> desirable that the time overlaps as much of the VM startup as
> possible to reduce impact on the VM bootup time. The GPU
> readiness state is thus checked on the first fault/huge_fault
> request or read/write access which amortizes the GPU readiness
> time.
> 
> The first fault and read/write checks the GPU state when the
> reset_done flag - which denotes whether the GPU has just been
> reset. The memory_lock is taken across map/access to avoid
> races with GPU reset.
> 
> Cc: Shameer Kolothum <skolothumtho@nvidia.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Vikram Sethi <vsethi@nvidia.com>
> Suggested-by: Alex Williamson <alex@shazbot.org>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  drivers/vfio/pci/nvgrace-gpu/main.c | 81 +++++++++++++++++++++++++----
>  1 file changed, 72 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
> index b46984e76be7..3064f8aca858 100644
> --- a/drivers/vfio/pci/nvgrace-gpu/main.c
> +++ b/drivers/vfio/pci/nvgrace-gpu/main.c
> @@ -104,6 +104,17 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
>  		mutex_init(&nvdev->remap_lock);
>  	}
>  
> +	/*
> +	 * GPU readiness is checked by reading the BAR0 registers.
> +	 *
> +	 * ioremap BAR0 to ensure that the BAR0 mapping is present before
> +	 * register reads on first fault before establishing any GPU
> +	 * memory mapping.
> +	 */
> +	ret = vfio_pci_core_setup_barmap(vdev, 0);
> +	if (ret)
> +		return ret;
> +
>  	vfio_pci_core_finish_enable(vdev);
>  
>  	return 0;
> @@ -146,6 +157,31 @@ static int nvgrace_gpu_wait_device_ready(void __iomem *io)
>  	return -ETIME;
>  }
>  
> +/*
> + * If the GPU memory is accessed by the CPU while the GPU is not ready
> + * after reset, it can cause harmless corrected RAS events to be logged.
> + * Make sure the GPU is ready before establishing the mappings.
> + */
> +static int
> +nvgrace_gpu_check_device_ready(struct nvgrace_gpu_pci_core_device *nvdev)
> +{
> +	struct vfio_pci_core_device *vdev = &nvdev->core_device;
> +	int ret;
> +
> +	lockdep_assert_held_read(&vdev->memory_lock);
> +
> +	if (!nvdev->reset_done)
> +		return 0;
> +
> +	ret = nvgrace_gpu_wait_device_ready(vdev->barmap[0]);
> +	if (ret)
> +		return ret;
> +
> +	nvdev->reset_done = false;
> +
> +	return 0;
> +}
> +
>  static unsigned long addr_to_pgoff(struct vm_area_struct *vma,
>  				   unsigned long addr)
>  {
> @@ -163,13 +199,13 @@ static vm_fault_t nvgrace_gpu_vfio_pci_huge_fault(struct vm_fault *vmf,
>  	struct vfio_pci_core_device *vdev = &nvdev->core_device;
>  	unsigned int index =
>  		vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
> -	vm_fault_t ret = VM_FAULT_SIGBUS;
> +	vm_fault_t ret;
>  	struct mem_region *memregion;
>  	unsigned long pfn, addr;
>  
>  	memregion = nvgrace_gpu_memregion(index, nvdev);
>  	if (!memregion)
> -		return ret;
> +		return VM_FAULT_SIGBUS;
>  
>  	addr = ALIGN_DOWN(vmf->address, PAGE_SIZE << order);
>  	pfn = PHYS_PFN(memregion->memphys) + addr_to_pgoff(vma, addr);
> @@ -179,8 +215,14 @@ static vm_fault_t nvgrace_gpu_vfio_pci_huge_fault(struct vm_fault *vmf,
>  		goto out;
>  	}
>  
> -	scoped_guard(rwsem_read, &vdev->memory_lock)
> +	scoped_guard(rwsem_read, &vdev->memory_lock) {
> +		if (nvgrace_gpu_check_device_ready(nvdev)) {
> +			ret = VM_FAULT_SIGBUS;
> +			goto out;
> +		}
> +
>  		ret = vfio_pci_vmf_insert_pfn(vdev, vmf, pfn, order);
> +	}
>  
>  out:
>  	dev_dbg_ratelimited(&vdev->pdev->dev,
> @@ -593,9 +635,15 @@ nvgrace_gpu_read_mem(struct nvgrace_gpu_pci_core_device *nvdev,
>  	else
>  		mem_count = min(count, memregion->memlength - (size_t)offset);
>  
> -	ret = nvgrace_gpu_map_and_read(nvdev, buf, mem_count, ppos);
> -	if (ret)
> -		return ret;
> +	scoped_guard(rwsem_read, &nvdev->core_device.memory_lock) {
> +		ret = nvgrace_gpu_check_device_ready(nvdev);
> +		if (ret)
> +			return ret;
> +
> +		ret = nvgrace_gpu_map_and_read(nvdev, buf, mem_count, ppos);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	/*
>  	 * Only the device memory present on the hardware is mapped, which may
> @@ -713,9 +761,15 @@ nvgrace_gpu_write_mem(struct nvgrace_gpu_pci_core_device *nvdev,
>  	 */
>  	mem_count = min(count, memregion->memlength - (size_t)offset);
>  
> -	ret = nvgrace_gpu_map_and_write(nvdev, buf, mem_count, ppos);
> -	if (ret)
> -		return ret;
> +	scoped_guard(rwsem_read, &nvdev->core_device.memory_lock) {
> +		ret = nvgrace_gpu_check_device_ready(nvdev);
> +		if (ret)
> +			return ret;
> +
> +		ret = nvgrace_gpu_map_and_write(nvdev, buf, mem_count, ppos);
> +		if (ret)
> +			return ret;
> +	}
>  
>  exitfn:
>  	*ppos += count;
> @@ -1056,6 +1110,15 @@ MODULE_DEVICE_TABLE(pci, nvgrace_gpu_vfio_pci_table);
>   *
>   * The reset_done implementation is triggered on every reset and is used
>   * set the reset_done variable that assists in achieving the serialization.
> + *
> + * The writer memory_lock is held during reset through ioctl and FLR, while
> + * the reader is held in the fault and access code.
> + *
> + * The lock is however not taken during reset called through
> + * vfio_pci_core_enable during open. Whilst a serialization is not
> + * required at that early stage, it still prevents from putting
> + * lockdep_assert_held_write in this function.
> + *

I think the key point is that the readiness test is done holding the
memory_lock read lock and we expect all vfio-pci initiated resets to
hold the memory_lock write lock to avoid races.  However, .reset_done
extends beyond the scope of vfio-pci initiated resets therefore we
cannot assert this behavior.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2025-11-26 15:24 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-26  5:26 [PATCH v7 0/6] vfio/nvgrace-gpu: Support huge PFNMAP and wait for GPU ready post reset ankita
2025-11-26  5:26 ` [PATCH v7 1/6] vfio: refactor vfio_pci_mmap_huge_fault function ankita
2025-11-26 15:22   ` Alex Williamson
2025-11-26  5:26 ` [PATCH v7 2/6] vfio/nvgrace-gpu: Add support for huge pfnmap ankita
2025-11-26  8:59   ` Shameer Kolothum
2025-11-26 15:22   ` Alex Williamson
2025-11-26  5:26 ` [PATCH v7 3/6] vfio: use vfio_pci_core_setup_barmap to map bar in mmap ankita
2025-11-26  5:26 ` [PATCH v7 4/6] vfio/nvgrace-gpu: split the code to wait for GPU ready ankita
2025-11-26 15:22   ` Alex Williamson
2025-11-26  5:26 ` [PATCH v7 5/6] vfio/nvgrace-gpu: Inform devmem unmapped after reset ankita
2025-11-26  9:00   ` Shameer Kolothum
2025-11-26 15:23   ` Alex Williamson
2025-11-26  5:26 ` [PATCH v7 6/6] vfio/nvgrace-gpu: wait for the GPU mem to be ready ankita
2025-11-26  9:03   ` Shameer Kolothum
2025-11-26  9:49     ` Ankit Agrawal
2025-11-26 11:35       ` Ankit Agrawal
2025-11-26 15:23   ` Alex Williamson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®