AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support
@ 2025-10-09  3:30 Ellen Pan
  0 siblings, 0 replies; 15+ messages in thread
From: Ellen Pan @ 2025-10-09  3:30 UTC (permalink / raw)
  To: amd-gfx; +Cc: Alexander.Deucher, Christian.Koenig, Shravankumar.Gande,
	Ellen Pan

1. Added enum amd_sriov_crit_region_version to support multi versions
2. Added logic in SRIOV mailbox to regonize crit_region version during
   req_gpu_init_data

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    |  4 ++++
 drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  5 +++++
 drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c       | 23 ++++++++++++++-------
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index e95adf0407a0..3a6b0e1084d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -150,7 +150,8 @@ void amdgpu_virt_request_init_data(struct amdgpu_device *adev)
 		virt->ops->req_init_data(adev);
 
 	if (adev->virt.req_init_data_ver > 0)
-		DRM_INFO("host supports REQ_INIT_DATA handshake\n");
+		DRM_INFO("host supports REQ_INIT_DATA handshake of critical_region_version %d\n",
+				 adev->virt.req_init_data_ver);
 	else
 		DRM_WARN("host doesn't support REQ_INIT_DATA handshake\n");
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index d1172c8e58c4..2a0627596bd2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -289,6 +289,10 @@ struct amdgpu_virt {
 	bool ras_init_done;
 	uint32_t reg_access;
 
+	/* critical regions v2 */
+	uint32_t init_data_header_offset;
+	uint32_t init_data_header_size_kb;
+
 	/* vf2pf message */
 	struct delayed_work vf2pf_work;
 	uint32_t vf2pf_update_interval_ms;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
index 3b35154e2df6..b53caab5b706 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
@@ -65,6 +65,11 @@
 	(AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1 + AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1 + \
 	 AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1)
 
+enum amd_sriov_crit_region_version {
+	GPU_CRIT_REGION_V1 = 1,
+	GPU_CRIT_REGION_V2 = 2,
+};
+
 /*
  * PF2VF history log:
  * v1 defined in amdgim
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
index e5282a5d05d9..5f7ae3763b60 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
@@ -222,12 +222,20 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
 				adev->virt.req_init_data_ver = 0;
 		} else {
 			if (req == IDH_REQ_GPU_INIT_DATA) {
-				adev->virt.req_init_data_ver =
-					RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
-
-				/* assume V1 in case host doesn't set version number */
-				if (adev->virt.req_init_data_ver < 1)
-					adev->virt.req_init_data_ver = 1;
+				switch (RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1)) {
+				case GPU_CRIT_REGION_V2:
+					adev->virt.req_init_data_ver = GPU_CRIT_REGION_V2;
+					adev->virt.init_data_header_offset =
+						RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
+					adev->virt.init_data_header_size_kb =
+						RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW3);
+					break;
+				default:
+					adev->virt.req_init_data_ver = GPU_CRIT_REGION_V1;
+					adev->virt.init_data_header_offset = -1;
+					adev->virt.init_data_header_size_kb = 0;
+					break;
+				}
 			}
 		}
 
@@ -285,7 +293,8 @@ static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
 
 static int xgpu_nv_request_init_data(struct amdgpu_device *adev)
 {
-	return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
+	return xgpu_nv_send_access_requests_with_param(adev, IDH_REQ_GPU_INIT_DATA,
+			0, GPU_CRIT_REGION_V2, 0);
 }
 
 static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,
-- 
2.34.1


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

* [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix
@ 2025-10-10  4:43 Ellen Pan
  2025-10-10  4:43 ` [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Ellen Pan @ 2025-10-10  4:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alexander.Deucher, Christian.Koenig, Lijo.Lazar, Jeffrey.Chan,
	Ellen Pan

 - This change prepares the later patches to intro  _v2 suffix to SRIOV critical regions

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    | 20 ++++----
 drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h | 57 ++++++++++++++-------
 2 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 3328ab63376b..e95adf0407a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -686,7 +686,7 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
 		/* got through this logic in early init stage to get necessary flags, e.g. rlcg_acc related*/
 		adev->virt.fw_reserve.p_pf2vf =
 			(struct amd_sriov_msg_pf2vf_info_header *)
-			(adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10));
+			(adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
 
 		amdgpu_virt_read_pf2vf_data(adev);
 	}
@@ -703,21 +703,21 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
 		if (adev->mman.fw_vram_usage_va) {
 			adev->virt.fw_reserve.p_pf2vf =
 				(struct amd_sriov_msg_pf2vf_info_header *)
-				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10));
+				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
 			adev->virt.fw_reserve.p_vf2pf =
 				(struct amd_sriov_msg_vf2pf_info_header *)
-				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB << 10));
+				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
 			adev->virt.fw_reserve.ras_telemetry =
-				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB << 10));
+				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
 		} else if (adev->mman.drv_vram_usage_va) {
 			adev->virt.fw_reserve.p_pf2vf =
 				(struct amd_sriov_msg_pf2vf_info_header *)
-				(adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10));
+				(adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
 			adev->virt.fw_reserve.p_vf2pf =
 				(struct amd_sriov_msg_vf2pf_info_header *)
-				(adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB << 10));
+				(adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
 			adev->virt.fw_reserve.ras_telemetry =
-				(adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB << 10));
+				(adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
 		}
 
 		amdgpu_virt_read_pf2vf_data(adev);
@@ -1304,7 +1304,7 @@ static int amdgpu_virt_cache_host_error_counts(struct amdgpu_device *adev,
 	checksum = host_telemetry->header.checksum;
 	used_size = host_telemetry->header.used_size;
 
-	if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))
+	if (used_size > (AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10))
 		return 0;
 
 	tmp = kmemdup(&host_telemetry->body.error_count, used_size, GFP_KERNEL);
@@ -1383,7 +1383,7 @@ amdgpu_virt_write_cpers_to_ring(struct amdgpu_device *adev,
 	checksum = host_telemetry->header.checksum;
 	used_size = host_telemetry->header.used_size;
 
-	if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))
+	if (used_size > (AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10))
 		return -EINVAL;
 
 	cper_dump = kmemdup(&host_telemetry->body.cper_dump, used_size, GFP_KERNEL);
@@ -1515,7 +1515,7 @@ static int amdgpu_virt_cache_chk_criti_hit(struct amdgpu_device *adev,
 	checksum = host_telemetry->header.checksum;
 	used_size = host_telemetry->header.used_size;
 
-	if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))
+	if (used_size > (AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10))
 		return 0;
 
 	tmp = kmemdup(&host_telemetry->body.chk_criti, used_size, GFP_KERNEL);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
index 3a79ed7d8031..3b35154e2df6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
@@ -23,26 +23,47 @@
 #ifndef AMDGV_SRIOV_MSG__H_
 #define AMDGV_SRIOV_MSG__H_
 
-/* unit in kilobytes */
-#define AMD_SRIOV_MSG_VBIOS_OFFSET	     0
-#define AMD_SRIOV_MSG_VBIOS_SIZE_KB	     64
-#define AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB AMD_SRIOV_MSG_VBIOS_SIZE_KB
-#define AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB   4
-#define AMD_SRIOV_MSG_TMR_OFFSET_KB	     2048
-#define AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB	     2
-#define AMD_SRIOV_RAS_TELEMETRY_SIZE_KB	     64
 /*
- * layout
+ * layout v1
  * 0           64KB        65KB        66KB           68KB                   132KB
  * |   VBIOS   |   PF2VF   |   VF2PF   |   Bad Page   | RAS Telemetry Region | ...
  * |   64KB    |   1KB     |   1KB     |   2KB        | 64KB                 | ...
  */
 
-#define AMD_SRIOV_MSG_SIZE_KB                   1
-#define AMD_SRIOV_MSG_PF2VF_OFFSET_KB           AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB
-#define AMD_SRIOV_MSG_VF2PF_OFFSET_KB           (AMD_SRIOV_MSG_PF2VF_OFFSET_KB + AMD_SRIOV_MSG_SIZE_KB)
-#define AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB        (AMD_SRIOV_MSG_VF2PF_OFFSET_KB + AMD_SRIOV_MSG_SIZE_KB)
-#define AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB   (AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB + AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB)
+/*
+ * layout v2 (offsets are dynamically allocated and the offsets below are examples)
+ * 0           1KB         64KB        65KB        66KB           68KB                   132KB
+ * |  INITD_H  |   VBIOS   |   PF2VF   |   VF2PF   |   Bad Page   | RAS Telemetry Region | ...
+ * |   1KB     |   64KB    |   1KB     |   1KB     |   2KB        | 64KB                 | ...
+ *
+ * Note: PF2VF + VF2PF + Bad Page = DataExchange region (allocated contiguously)
+ */
+
+/* v1 layout sizes */
+#define AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1			64
+#define AMD_SRIOV_MSG_PF2VF_SIZE_KB_V1			1
+#define AMD_SRIOV_MSG_VF2PF_SIZE_KB_V1			1
+#define AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB_V1		2
+#define AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1		64
+#define AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1		\
+	(AMD_SRIOV_MSG_PF2VF_SIZE_KB_V1 + AMD_SRIOV_MSG_VF2PF_SIZE_KB_V1 + \
+	 AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB_V1)
+
+/* v1 offsets */
+#define AMD_SRIOV_MSG_VBIOS_OFFSET_V1			0
+#define AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB_V1		AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1
+#define AMD_SRIOV_MSG_TMR_OFFSET_KB			2048
+#define AMD_SRIOV_MSG_SIZE_KB_V1			1
+#define AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1		AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB_V1
+#define AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1		\
+	(AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 + AMD_SRIOV_MSG_SIZE_KB_V1)
+#define AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB_V1		\
+	(AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 + AMD_SRIOV_MSG_SIZE_KB_V1)
+#define AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1	\
+	(AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB_V1 + AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB_V1)
+#define AMD_SRIOV_MSG_INIT_DATA_TOT_SIZE_KB_V1		\
+	(AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1 + AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1 + \
+	 AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1)
 
 /*
  * PF2VF history log:
@@ -436,12 +457,12 @@ unsigned int amd_sriov_msg_checksum(void *obj, unsigned long obj_size, unsigned
 #define _stringification(s) #s
 
 _Static_assert(
-	sizeof(struct amd_sriov_msg_vf2pf_info) == AMD_SRIOV_MSG_SIZE_KB << 10,
-	"amd_sriov_msg_vf2pf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB) " KB");
+	sizeof(struct amd_sriov_msg_vf2pf_info) == AMD_SRIOV_MSG_SIZE_KB_V1 << 10,
+	"amd_sriov_msg_vf2pf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB_V1) " KB");
 
 _Static_assert(
-	sizeof(struct amd_sriov_msg_pf2vf_info) == AMD_SRIOV_MSG_SIZE_KB << 10,
-	"amd_sriov_msg_pf2vf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB) " KB");
+	sizeof(struct amd_sriov_msg_pf2vf_info) == AMD_SRIOV_MSG_SIZE_KB_V1 << 10,
+	"amd_sriov_msg_pf2vf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB_V1) " KB");
 
 _Static_assert(AMD_SRIOV_MSG_RESERVE_UCODE % 4 == 0,
 	       "AMD_SRIOV_MSG_RESERVE_UCODE must be multiple of 4");
-- 
2.34.1


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

* [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support
  2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
@ 2025-10-10  4:43 ` Ellen Pan
  2025-10-10  8:32   ` Christian König
  2025-10-10 15:00   ` Alex Deucher
  2025-10-10  4:43 ` [PATCH 3/6] drm/amdgpu: Introduce SRIOV critical regions v2 during VF init Ellen Pan
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 15+ messages in thread
From: Ellen Pan @ 2025-10-10  4:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alexander.Deucher, Christian.Koenig, Lijo.Lazar, Jeffrey.Chan,
	Ellen Pan

1. Added enum amd_sriov_crit_region_version to support multi versions
2. Added logic in SRIOV mailbox to regonize crit_region version during
   req_gpu_init_data

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    |  8 +++++++
 drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  5 +++++
 drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c       | 23 ++++++++++++++-------
 4 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index e95adf0407a0..3a6b0e1084d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -150,7 +150,8 @@ void amdgpu_virt_request_init_data(struct amdgpu_device *adev)
 		virt->ops->req_init_data(adev);
 
 	if (adev->virt.req_init_data_ver > 0)
-		DRM_INFO("host supports REQ_INIT_DATA handshake\n");
+		DRM_INFO("host supports REQ_INIT_DATA handshake of critical_region_version %d\n",
+				 adev->virt.req_init_data_ver);
 	else
 		DRM_WARN("host doesn't support REQ_INIT_DATA handshake\n");
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index d1172c8e58c4..51ff73b1fcd5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -262,6 +262,11 @@ struct amdgpu_virt_ras {
 
 DECLARE_ATTR_CAP_CLASS(amdgpu_virt, AMDGPU_VIRT_CAPS_LIST);
 
+struct amdgpu_virt_region {
+	uint64_t offset;
+	uint64_t size_kb;
+};
+
 /* GPU virtualization */
 struct amdgpu_virt {
 	uint32_t			caps;
@@ -289,6 +294,9 @@ struct amdgpu_virt {
 	bool ras_init_done;
 	uint32_t reg_access;
 
+	/* dynamic(v2) critical regions */
+	struct amdgpu_virt_region init_data_header;
+
 	/* vf2pf message */
 	struct delayed_work vf2pf_work;
 	uint32_t vf2pf_update_interval_ms;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
index 3b35154e2df6..b53caab5b706 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
@@ -65,6 +65,11 @@
 	(AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1 + AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1 + \
 	 AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1)
 
+enum amd_sriov_crit_region_version {
+	GPU_CRIT_REGION_V1 = 1,
+	GPU_CRIT_REGION_V2 = 2,
+};
+
 /*
  * PF2VF history log:
  * v1 defined in amdgim
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
index e5282a5d05d9..cd5b2f07edb8 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
@@ -222,12 +222,20 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
 				adev->virt.req_init_data_ver = 0;
 		} else {
 			if (req == IDH_REQ_GPU_INIT_DATA) {
-				adev->virt.req_init_data_ver =
-					RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
-
-				/* assume V1 in case host doesn't set version number */
-				if (adev->virt.req_init_data_ver < 1)
-					adev->virt.req_init_data_ver = 1;
+				switch (RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1)) {
+				case GPU_CRIT_REGION_V2:
+					adev->virt.req_init_data_ver = GPU_CRIT_REGION_V2;
+					adev->virt.init_data_header.offset =
+						RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
+					adev->virt.init_data_header.size_kb =
+						RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW3);
+					break;
+				default:
+					adev->virt.req_init_data_ver = GPU_CRIT_REGION_V1;
+					adev->virt.init_data_header.offset = -1;
+					adev->virt.init_data_header.size_kb = 0;
+					break;
+				}
 			}
 		}
 
@@ -285,7 +293,8 @@ static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
 
 static int xgpu_nv_request_init_data(struct amdgpu_device *adev)
 {
-	return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
+	return xgpu_nv_send_access_requests_with_param(adev, IDH_REQ_GPU_INIT_DATA,
+			0, GPU_CRIT_REGION_V2, 0);
 }
 
 static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,
-- 
2.34.1


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

* [PATCH 3/6] drm/amdgpu: Introduce SRIOV critical regions v2 during VF init
  2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
  2025-10-10  4:43 ` [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan
@ 2025-10-10  4:43 ` Ellen Pan
  2025-10-10 15:04   ` Alex Deucher
  2025-10-10  4:43 ` [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV Ellen Pan
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Ellen Pan @ 2025-10-10  4:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alexander.Deucher, Christian.Koenig, Lijo.Lazar, Jeffrey.Chan,
	Ellen Pan

    1. Introduced amdgpu_virt_init_critical_region during VF init.
     - VFs use init_data_header_offset and init_data_header_size_kb
            transmitted via PF2VF mailbox to fetch the offset of
            critical regions' offsets/sizes in VRAM and save to
            adev->virt.crit_region_offsets and adev->virt.crit_region_sizes_kb.

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c  |   4 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    | 113 ++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    |   7 ++
 drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  31 ++++++
 4 files changed, 155 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 929936c8d87c..351cfe03a1aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2754,6 +2754,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
 		r = amdgpu_virt_request_full_gpu(adev, true);
 		if (r)
 			return r;
+
+		r = amdgpu_virt_init_critical_region(adev);
+		if (r)
+			return r;
 	}
 
 	switch (adev->asic_type) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 3a6b0e1084d7..6eca5e8a7375 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -843,6 +843,119 @@ static void amdgpu_virt_init_ras(struct amdgpu_device *adev)
 	adev->virt.ras.cper_rptr = 0;
 }
 
+static uint8_t amdgpu_virt_crit_region_calc_checksum(uint8_t *buf_start, uint8_t *buf_end)
+{
+	uint32_t sum = 0;
+
+	if (buf_start >= buf_end)
+		return 0;
+
+	for (; buf_start < buf_end; buf_start++)
+		sum += buf_start[0];
+
+	return 0xffffffff - sum;
+}
+
+int amdgpu_virt_init_critical_region(struct amdgpu_device *adev)
+{
+	struct amd_sriov_msg_init_data_header *init_data_hdr = NULL;
+	uint32_t init_hdr_offset = adev->virt.init_data_header.offset;
+	uint32_t init_hdr_size = adev->virt.init_data_header.size_kb << 10;
+	uint64_t pos = 0;
+	uint64_t vram_size;
+	int r = 0;
+	uint8_t checksum = 0;
+
+	/* Skip below init if critical region version != v2 */
+	if (adev->virt.req_init_data_ver != GPU_CRIT_REGION_V2)
+		return 0;
+
+	if (init_hdr_offset < 0) {
+		dev_err(adev->dev, "Invalid init header offset\n");
+		return -EINVAL;
+	}
+
+	vram_size = RREG32(mmRCC_CONFIG_MEMSIZE);
+	if (!vram_size || vram_size == U32_MAX)
+		return -EINVAL;
+	vram_size <<= 20;
+
+	if ((init_hdr_offset + init_hdr_size) > vram_size) {
+		dev_err(adev->dev, "init_data_header exceeds VRAM size, exiting\n");
+		return -EINVAL;
+	}
+
+	/* Allocate for init_data_hdr */
+	init_data_hdr = kzalloc(sizeof(struct amd_sriov_msg_init_data_header), GFP_KERNEL);
+	if (!init_data_hdr)
+		return -ENOMEM;
+
+	pos = (uint64_t)init_hdr_offset;
+	amdgpu_device_vram_access(adev, pos, (uint32_t *)init_data_hdr,
+					sizeof(struct amd_sriov_msg_init_data_header), false);
+
+	switch (init_data_hdr->version) {
+	case GPU_CRIT_REGION_V2:
+		if (strncmp(init_data_hdr->signature, "INDA", 4) != 0) {
+			dev_err(adev->dev, "Invalid init data signature: %.4s\n",
+					init_data_hdr->signature);
+			r = -EINVAL;
+			goto out;
+		}
+
+		checksum = amdgpu_virt_crit_region_calc_checksum(
+				(uint8_t *)&init_data_hdr->initdata_offset,
+				(uint8_t *)init_data_hdr +
+				sizeof(struct amd_sriov_msg_init_data_header));
+		if (checksum != init_data_hdr->checksum) {
+			dev_err(adev->dev, "Found unmatching checksum from calculation 0x%x and init_data 0x%x\n",
+					checksum, init_data_hdr->checksum);
+			r = -EINVAL;
+			goto out;
+		}
+
+		/* Initialize critical region offsets */
+		adev->virt.crit_regn.offset = init_data_hdr->initdata_offset;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].offset =
+			init_data_hdr->ip_discovery_offset;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].offset =
+			init_data_hdr->vbios_img_offset;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID].offset =
+			init_data_hdr->ras_tele_info_offset;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset =
+			init_data_hdr->dataexchange_offset;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].offset =
+			init_data_hdr->bad_page_info_offset;
+
+		/* Initialize critical region sizes */
+		adev->virt.crit_regn.size_kb = init_data_hdr->initdata_size_in_kb;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb =
+			init_data_hdr->ip_discovery_size_in_kb;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].size_kb =
+			init_data_hdr->vbios_img_size_in_kb;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID].size_kb =
+			init_data_hdr->ras_tele_info_size_in_kb;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].size_kb =
+			init_data_hdr->dataexchange_size_in_kb;
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].size_kb =
+			init_data_hdr->bad_page_size_in_kb;
+
+		adev->virt.is_dynamic_crit_regn_enabled = true;
+		break;
+	default:
+		dev_err(adev->dev, "Invalid init header version: %u\n",
+				init_data_hdr->version);
+		r = -EINVAL;
+		goto out;
+	}
+
+out:
+	kfree(init_data_hdr);
+	init_data_hdr = NULL;
+
+	return r;
+}
+
 void amdgpu_virt_init(struct amdgpu_device *adev)
 {
 	bool is_sriov = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index 51ff73b1fcd5..bc1fc1c6daba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -52,6 +52,8 @@
 /* tonga/fiji use this offset */
 #define mmBIF_IOV_FUNC_IDENTIFIER 0x1503
 
+#define mmRCC_CONFIG_MEMSIZE	0xde3
+
 #define AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT 2
 
 enum amdgpu_sriov_vf_mode {
@@ -296,6 +298,9 @@ struct amdgpu_virt {
 
 	/* dynamic(v2) critical regions */
 	struct amdgpu_virt_region init_data_header;
+	struct amdgpu_virt_region crit_regn;
+	struct amdgpu_virt_region crit_regn_tbl[AMD_SRIOV_MSG_MAX_TABLE_ID];
+	bool is_dynamic_crit_regn_enabled;
 
 	/* vf2pf message */
 	struct delayed_work vf2pf_work;
@@ -432,6 +437,8 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev);
 void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev);
 void amdgpu_virt_init(struct amdgpu_device *adev);
 
+int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
+
 bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
 int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
 void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
index b53caab5b706..d15c256f9abd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
@@ -70,6 +70,37 @@ enum amd_sriov_crit_region_version {
 	GPU_CRIT_REGION_V2 = 2,
 };
 
+/* v2 layout offset enum (in order of allocation) */
+enum amd_sriov_msg_table_id_enum {
+	AMD_SRIOV_MSG_IPD_TABLE_ID = 0,
+	AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID,
+	AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID,
+	AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID,
+	AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID,
+	AMD_SRIOV_MSG_INITD_H_TABLE_ID,
+	AMD_SRIOV_MSG_MAX_TABLE_ID,
+};
+
+struct amd_sriov_msg_init_data_header {
+	char     signature[4];  /* "INDA"  */
+	uint32_t version;
+	uint32_t checksum;
+	uint32_t initdata_offset; /* 0 */
+	uint32_t initdata_size_in_kb; /* 5MB */
+	uint32_t valid_tables;
+	uint32_t vbios_img_offset;
+	uint32_t vbios_img_size_in_kb;
+	uint32_t dataexchange_offset;
+	uint32_t dataexchange_size_in_kb;
+	uint32_t ras_tele_info_offset;
+	uint32_t ras_tele_info_size_in_kb;
+	uint32_t ip_discovery_offset;
+	uint32_t ip_discovery_size_in_kb;
+	uint32_t bad_page_info_offset;
+	uint32_t bad_page_size_in_kb;
+	uint32_t reserved[8];
+};
+
 /*
  * PF2VF history log:
  * v1 defined in amdgim
-- 
2.34.1


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

* [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV
  2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
  2025-10-10  4:43 ` [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan
  2025-10-10  4:43 ` [PATCH 3/6] drm/amdgpu: Introduce SRIOV critical regions v2 during VF init Ellen Pan
@ 2025-10-10  4:43 ` Ellen Pan
  2025-10-10 10:33   ` Lazar, Lijo
  2025-10-10 15:10   ` Alex Deucher
  2025-10-10  4:43 ` [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init from dynamic crit_region offsets Ellen Pan
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 15+ messages in thread
From: Ellen Pan @ 2025-10-10  4:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alexander.Deucher, Christian.Koenig, Lijo.Lazar, Jeffrey.Chan,
	Ellen Pan

- During guest driver init, asa VFs receive PF msg to
	init dynamic critical region(v2), VFs reuse fw_vram_usage_*
	 from ttm to store critical region tables in a 5MB chunk.

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c  | 29 ++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       | 33 +++++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      |  9 +++++
 3 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
index c7d32fb216e4..636385c80f64 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -181,19 +181,22 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
 	u8 frev, crev;
 	int usage_bytes = 0;
 
-	if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
-		if (frev == 2 && crev == 1) {
-			fw_usage_v2_1 =
-				(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
-			amdgpu_atomfirmware_allocate_fb_v2_1(adev,
-					fw_usage_v2_1,
-					&usage_bytes);
-		} else if (frev >= 2 && crev >= 2) {
-			fw_usage_v2_2 =
-				(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
-			amdgpu_atomfirmware_allocate_fb_v2_2(adev,
-					fw_usage_v2_2,
-					&usage_bytes);
+	/* Skip atomfirmware allocation for SRIOV VFs when dynamic crit regn is enabled */
+	if (!(amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled)) {
+		if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
+			if (frev == 2 && crev == 1) {
+				fw_usage_v2_1 =
+					(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
+				amdgpu_atomfirmware_allocate_fb_v2_1(adev,
+						fw_usage_v2_1,
+						&usage_bytes);
+			} else if (frev >= 2 && crev >= 2) {
+				fw_usage_v2_2 =
+					(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
+				amdgpu_atomfirmware_allocate_fb_v2_2(adev,
+						fw_usage_v2_2,
+						&usage_bytes);
+			}
 		}
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 96bd0185f936..c0810c53703c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1943,23 +1943,28 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 	if (r)
 		return r;
 
-	/*
-	 *The reserved vram for driver must be pinned to the specified
-	 *place on the VRAM, so reserve it early.
-	 */
-	r = amdgpu_ttm_drv_reserve_vram_init(adev);
-	if (r)
-		return r;
-
-	/*
-	 * only NAVI10 and onwards ASIC support for IP discovery.
-	 * If IP discovery enabled, a block of memory should be
-	 * reserved for IP discovey.
+	/* For VFs with dynamic critical regions (v2), fw_reserve_vram is already
+	 * reserved, so no additional memory reservation is required below.
 	 */
-	if (adev->mman.discovery_bin) {
-		r = amdgpu_ttm_reserve_tmr(adev);
+	if (!amdgpu_sriov_vf(adev) || (adev->virt.req_init_data_ver != GPU_CRIT_REGION_V2)) {
+		/*
+		 * The reserved VRAM for the driver must be pinned to a specific
+		 * location in VRAM, so reserve it early.
+		 */
+		r = amdgpu_ttm_drv_reserve_vram_init(adev);
 		if (r)
 			return r;
+
+		/*
+		 * only NAVI10 and later ASICs support IP discovery.
+		 * If IP discovery is enabled, a block of memory should be
+		 * reserved for it.
+		 */
+		if (adev->mman.discovery_bin) {
+			r = amdgpu_ttm_reserve_tmr(adev);
+			if (r)
+				return r;
+		}
 	}
 
 	/* allocate memory as required for VGA
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 6eca5e8a7375..461e83728594 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -940,6 +940,15 @@ int amdgpu_virt_init_critical_region(struct amdgpu_device *adev)
 		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].size_kb =
 			init_data_hdr->bad_page_size_in_kb;
 
+		/* reserved memory starts from crit region base offset with the size of 5MB */
+		adev->mman.fw_vram_usage_start_offset = adev->virt.crit_regn.offset;
+		adev->mman.fw_vram_usage_size = adev->virt.crit_regn.size_kb << 10;
+		dev_info(adev->dev,
+			"critical region v%d requested to reserve memory start at %08x with %d KB.\n",
+			  init_data_hdr->version,
+			  adev->mman.fw_vram_usage_start_offset,
+			  adev->mman.fw_vram_usage_size >> 10);
+
 		adev->virt.is_dynamic_crit_regn_enabled = true;
 		break;
 	default:
-- 
2.34.1


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

* [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init from dynamic crit_region offsets
  2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
                   ` (2 preceding siblings ...)
  2025-10-10  4:43 ` [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV Ellen Pan
@ 2025-10-10  4:43 ` Ellen Pan
  2025-10-10 10:46   ` Lazar, Lijo
  2025-10-10  4:43 ` [PATCH 6/6] drm/amdgpu: Add logic for VF data exchange region " Ellen Pan
  2025-10-10 14:51 ` [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Alex Deucher
  5 siblings, 1 reply; 15+ messages in thread
From: Ellen Pan @ 2025-10-10  4:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alexander.Deucher, Christian.Koenig, Lijo.Lazar, Jeffrey.Chan,
	Ellen Pan

1. Added VF logic in amdgpu_virt to init IP discovery using the offsets from dynamic(v2) critical regions;
2. Added VF logic in amdgpu_virt to init bios image using the offsets from dynamic(v2) critical regions;

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c      |  26 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c |  33 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      | 107 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h      |   2 +
 5 files changed, 142 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 2a0df4cabb99..d320118858bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -416,6 +416,7 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
 /*
  * BIOS.
  */
+bool amdgpu_check_atom_bios(struct amdgpu_device *adev, size_t size);
 bool amdgpu_get_bios(struct amdgpu_device *adev);
 bool amdgpu_read_bios(struct amdgpu_device *adev);
 bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 00e96419fcda..787584956214 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -47,7 +47,7 @@
 /* Check if current bios is an ATOM BIOS.
  * Return true if it is ATOM BIOS. Otherwise, return false.
  */
-static bool check_atom_bios(struct amdgpu_device *adev, size_t size)
+bool amdgpu_check_atom_bios(struct amdgpu_device *adev, size_t size)
 {
 	uint16_t tmp, bios_header_start;
 	uint8_t *bios = adev->bios;
@@ -96,7 +96,8 @@ void amdgpu_bios_release(struct amdgpu_device *adev)
  * part of the system bios.  On boot, the system bios puts a
  * copy of the igp rom at the start of vram if a discrete card is
  * present.
- * For SR-IOV, the vbios image is also put in VRAM in the VF.
+ * For SR-IOV, if dynamic critical region is not enabled,
+ * the vbios image is also put at the start of VRAM in the VF.
  */
 static bool amdgpu_read_bios_from_vram(struct amdgpu_device *adev)
 {
@@ -127,7 +128,7 @@ static bool amdgpu_read_bios_from_vram(struct amdgpu_device *adev)
 	memcpy_fromio(adev->bios, bios, size);
 	iounmap(bios);
 
-	if (!check_atom_bios(adev, size)) {
+	if (!amdgpu_check_atom_bios(adev, size)) {
 		amdgpu_bios_release(adev);
 		return false;
 	}
@@ -155,7 +156,7 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
 	memcpy_fromio(adev->bios, bios, size);
 	pci_unmap_rom(adev->pdev, bios);
 
-	if (!check_atom_bios(adev, size)) {
+	if (!amdgpu_check_atom_bios(adev, size)) {
 		amdgpu_bios_release(adev);
 		return false;
 	}
@@ -195,7 +196,7 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
 	/* read complete BIOS */
 	amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
 
-	if (!check_atom_bios(adev, len)) {
+	if (!amdgpu_check_atom_bios(adev, len)) {
 		amdgpu_bios_release(adev);
 		return false;
 	}
@@ -225,7 +226,7 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
 	memcpy_fromio(adev->bios, bios, romlen);
 	iounmap(bios);
 
-	if (!check_atom_bios(adev, romlen))
+	if (!amdgpu_check_atom_bios(adev, romlen))
 		goto free_bios;
 
 	adev->bios_size = romlen;
@@ -334,7 +335,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
 			break;
 	}
 
-	if (!check_atom_bios(adev, size)) {
+	if (!amdgpu_check_atom_bios(adev, size)) {
 		amdgpu_bios_release(adev);
 		return false;
 	}
@@ -399,7 +400,7 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
 					     vhdr->ImageLength,
 					     GFP_KERNEL);
 
-			if (!check_atom_bios(adev, vhdr->ImageLength)) {
+			if (!amdgpu_check_atom_bios(adev, vhdr->ImageLength)) {
 				amdgpu_bios_release(adev);
 				return false;
 			}
@@ -467,9 +468,14 @@ static bool amdgpu_get_bios_dgpu(struct amdgpu_device *adev)
 	}
 
 	/* this is required for SR-IOV */
-	if (amdgpu_read_bios_from_vram(adev)) {
-		dev_info(adev->dev, "Fetched VBIOS from VRAM BAR\n");
+	if (amdgpu_sriov_vf(adev) && amdgpu_virt_read_bios_from_vram(adev)) {
+		dev_info(adev->dev, "Fetched VBIOS from dynamic VRAM BAR\n");
 		goto success;
+	} else {
+		if (amdgpu_read_bios_from_vram(adev)) {
+			dev_info(adev->dev, "Fetched VBIOS from VRAM BAR\n");
+			goto success;
+		}
 	}
 
 	if (amdgpu_prefer_rom_resource(adev)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 73401f0aeb34..de8676d6ff9c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -275,21 +275,18 @@ static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,
 	int i, ret = 0;
 	u32 msg;
 
-	if (!amdgpu_sriov_vf(adev)) {
-		/* It can take up to two second for IFWI init to complete on some dGPUs,
-		 * but generally it should be in the 60-100ms range.  Normally this starts
-		 * as soon as the device gets power so by the time the OS loads this has long
-		 * completed.  However, when a card is hotplugged via e.g., USB4, we need to
-		 * wait for this to complete.  Once the C2PMSG is updated, we can
-		 * continue.
-		 */
-
-		for (i = 0; i < 2000; i++) {
-			msg = RREG32(mmMP0_SMN_C2PMSG_33);
-			if (msg & 0x80000000)
-				break;
-			msleep(1);
-		}
+	/* It can take up to two second for IFWI init to complete on some dGPUs,
+	 * but generally it should be in the 60-100ms range.  Normally this starts
+	 * as soon as the device gets power so by the time the OS loads this has long
+	 * completed.  However, when a card is hotplugged via e.g., USB4, we need to
+	 * wait for this to complete.  Once the C2PMSG is updated, we can
+	 * continue.
+	 */
+	for (i = 0; i < 2000; i++) {
+		msg = RREG32(mmMP0_SMN_C2PMSG_33);
+		if (msg & 0x80000000)
+			break;
+		msleep(1);
 	}
 
 	vram_size = RREG32(mmRCC_CONFIG_MEMSIZE);
@@ -467,8 +464,10 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
 			goto out;
 	} else {
 		drm_dbg(&adev->ddev, "use ip discovery information from memory");
-		r = amdgpu_discovery_read_binary_from_mem(
-			adev, adev->mman.discovery_bin);
+		if (amdgpu_sriov_vf(adev))
+			r = amdgpu_virt_init_discovery_from_mem(adev, adev->mman.discovery_bin);
+		else
+			r = amdgpu_discovery_read_binary_from_mem(adev, adev->mman.discovery_bin);
 		if (r)
 			goto out;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 461e83728594..67d5f15a72a1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -965,6 +965,113 @@ int amdgpu_virt_init_critical_region(struct amdgpu_device *adev)
 	return r;
 }
 
+int amdgpu_virt_init_discovery_from_mem(struct amdgpu_device *adev, uint8_t *binary)
+{
+	uint64_t vram_size;
+	uint32_t ip_discovery_offset, ip_discovery_size;
+	uint64_t pos = 0;
+
+	/* Get dynamic offset for IPD if dynamic critical region is enabled */
+	if (adev->virt.is_dynamic_crit_regn_enabled) {
+		ip_discovery_offset =
+			adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].offset;
+		ip_discovery_size =
+			adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb << 10;
+
+		dev_info(adev->dev,
+			"Got IPD info from dynamic crit_region at offset 0x%x with size of 0x%x bytes.\n",
+			ip_discovery_offset, ip_discovery_size);
+
+		if (!IS_ALIGNED(ip_discovery_offset, 4) || !IS_ALIGNED(ip_discovery_size, 4)) {
+			dev_err(adev->dev, "IP discovery data not aligned to 4 bytes\n");
+			return -EINVAL;
+		}
+
+		if (ip_discovery_size > DISCOVERY_TMR_SIZE) {
+			dev_err(adev->dev, "Invalid IP discovery size: 0x%x\n", ip_discovery_size);
+			return -EINVAL;
+		}
+
+		pos = (uint64_t)ip_discovery_offset;
+		amdgpu_device_vram_access(adev, pos, (uint32_t *)binary,
+					ip_discovery_size, false);
+	} else {
+		vram_size = RREG32(mmRCC_CONFIG_MEMSIZE);
+		if (!vram_size || vram_size == U32_MAX)
+			return -EINVAL;
+
+		vram_size <<= 20;
+
+		pos = vram_size - DISCOVERY_TMR_OFFSET;
+		amdgpu_device_vram_access(adev, pos, (uint32_t *)binary,
+					adev->mman.discovery_tmr_size, false);
+	}
+
+	return 0;
+}
+
+/* For SR-IOV, if dynamic critical region is enabled,
+ * the vbios image is put at a dynamic offset of VRAM in the VF.
+ * If dynamic critical region is disabled, exit early to proceed
+ * the same seq as on baremetal.
+ */
+bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev)
+{
+	uint8_t __iomem *bios;
+	resource_size_t vram_base;
+	resource_size_t size = 256 * 1024; /* ??? */
+	uint32_t vbios_offset = 0;
+	uint32_t vbios_size = 0;
+
+	/* Exit early if it's not initialized */
+	if (!adev->virt.is_dynamic_crit_regn_enabled)
+		return false;
+
+	if (amdgpu_device_need_post(adev))
+		return false;
+
+	/* FB BAR not enabled */
+	if (pci_resource_len(adev->pdev, 0) == 0)
+		return false;
+
+	adev->bios = NULL;
+	vram_base = pci_resource_start(adev->pdev, 0);
+
+	vbios_offset = adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].offset;
+	vbios_size =
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].size_kb << 10;
+	if (vbios_size > size) {
+		dev_err(adev->dev, "Invalid vbios size: 0x%x\n", vbios_size);
+		return false;
+	}
+
+	dev_info(adev->dev,
+		"Got bios info from dynamic crit_region_table at offset 0x%x with size of 0x%x bytes.\n",
+		vbios_offset, vbios_size);
+
+	size = vbios_size;
+
+	bios = ioremap_wc(vram_base + vbios_offset, size);
+	if (!bios)
+		return false;
+
+	adev->bios = kmalloc(size, GFP_KERNEL);
+	if (!adev->bios) {
+		iounmap(bios);
+		return false;
+	}
+	adev->bios_size = size;
+	memcpy_fromio(adev->bios, bios, size);
+	iounmap(bios);
+
+	if (!check_atom_bios(adev, size)) {
+		amdgpu_bios_release(adev);
+		return false;
+	}
+
+	return true;
+}
+
 void amdgpu_virt_init(struct amdgpu_device *adev)
 {
 	bool is_sriov = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index bc1fc1c6daba..f2aa306f4192 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -438,6 +438,8 @@ void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev);
 void amdgpu_virt_init(struct amdgpu_device *adev);
 
 int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
+int amdgpu_virt_init_discovery_from_mem(struct amdgpu_device *adev, uint8_t *binary);
+bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev);
 
 bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
 int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
-- 
2.34.1


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

* [PATCH 6/6] drm/amdgpu: Add logic for VF data exchange region to init from dynamic crit_region offsets
  2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
                   ` (3 preceding siblings ...)
  2025-10-10  4:43 ` [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init from dynamic crit_region offsets Ellen Pan
@ 2025-10-10  4:43 ` Ellen Pan
  2025-10-10 15:31   ` Alex Deucher
  2025-10-10 14:51 ` [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Alex Deucher
  5 siblings, 1 reply; 15+ messages in thread
From: Ellen Pan @ 2025-10-10  4:43 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alexander.Deucher, Christian.Koenig, Lijo.Lazar, Jeffrey.Chan,
	Ellen Pan

1. Added VF logic to init data exchange region using the offsets from dynamic(v2) critical regions;

Signed-off-by: Ellen Pan <yunru.pan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 88 ++++++++++++++++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h |  1 +
 2 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 67d5f15a72a1..f96382fb0070 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -670,6 +670,8 @@ void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev)
 
 void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
 {
+	uint32_t *pfvf_data = NULL;
+
 	adev->virt.fw_reserve.p_pf2vf = NULL;
 	adev->virt.fw_reserve.p_vf2pf = NULL;
 	adev->virt.vf2pf_update_interval_ms = 0;
@@ -685,11 +687,34 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
 		schedule_delayed_work(&(adev->virt.vf2pf_work), msecs_to_jiffies(adev->virt.vf2pf_update_interval_ms));
 	} else if (adev->bios != NULL) {
 		/* got through this logic in early init stage to get necessary flags, e.g. rlcg_acc related*/
-		adev->virt.fw_reserve.p_pf2vf =
-			(struct amd_sriov_msg_pf2vf_info_header *)
-			(adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
+		if (adev->virt.req_init_data_ver == GPU_CRIT_REGION_V2) {
+			pfvf_data =
+				kzalloc(adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].size_kb << 10,
+					GFP_KERNEL);
+			if (!pfvf_data) {
+				DRM_ERROR("Failed to allocate memory for pfvf_data\n");
+				return;
+			}
 
-		amdgpu_virt_read_pf2vf_data(adev);
+			if (amdgpu_virt_read_exchange_data_from_mem(adev, pfvf_data))
+				goto free_pfvf_data;
+
+			adev->virt.fw_reserve.p_pf2vf =
+				(struct amd_sriov_msg_pf2vf_info_header *)pfvf_data;
+
+			amdgpu_virt_read_pf2vf_data(adev);
+
+free_pfvf_data:
+			kfree(pfvf_data);
+			pfvf_data = NULL;
+			adev->virt.fw_reserve.p_pf2vf = NULL;
+		} else {
+			adev->virt.fw_reserve.p_pf2vf =
+				(struct amd_sriov_msg_pf2vf_info_header *)
+				(adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
+
+			amdgpu_virt_read_pf2vf_data(adev);
+		}
 	}
 }
 
@@ -702,14 +727,29 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
 
 	if (adev->mman.fw_vram_usage_va || adev->mman.drv_vram_usage_va) {
 		if (adev->mman.fw_vram_usage_va) {
-			adev->virt.fw_reserve.p_pf2vf =
-				(struct amd_sriov_msg_pf2vf_info_header *)
-				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
-			adev->virt.fw_reserve.p_vf2pf =
-				(struct amd_sriov_msg_vf2pf_info_header *)
-				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
-			adev->virt.fw_reserve.ras_telemetry =
-				(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
+			if (adev->virt.req_init_data_ver == GPU_CRIT_REGION_V2) {
+				adev->virt.fw_reserve.p_pf2vf =
+					(struct amd_sriov_msg_pf2vf_info_header *)
+					(adev->mman.fw_vram_usage_va +
+					adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset);
+				adev->virt.fw_reserve.p_vf2pf =
+					(struct amd_sriov_msg_vf2pf_info_header *)
+					(adev->mman.fw_vram_usage_va +
+					adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset +
+					(AMD_SRIOV_MSG_SIZE_KB_V1 << 10));
+				adev->virt.fw_reserve.ras_telemetry =
+					(adev->mman.fw_vram_usage_va +
+					adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID].offset);
+			} else {
+				adev->virt.fw_reserve.p_pf2vf =
+					(struct amd_sriov_msg_pf2vf_info_header *)
+					(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
+				adev->virt.fw_reserve.p_vf2pf =
+					(struct amd_sriov_msg_vf2pf_info_header *)
+					(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
+				adev->virt.fw_reserve.ras_telemetry =
+					(adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
+			}
 		} else if (adev->mman.drv_vram_usage_va) {
 			adev->virt.fw_reserve.p_pf2vf =
 				(struct amd_sriov_msg_pf2vf_info_header *)
@@ -1072,6 +1112,30 @@ bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev)
 	return true;
 }
 
+int amdgpu_virt_read_exchange_data_from_mem(struct amdgpu_device *adev, uint32_t *pfvf_data)
+{
+	uint32_t dataexchange_offset =
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset;
+	uint32_t dataexchange_size =
+		adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].size_kb << 10;
+	uint64_t pos = 0;
+
+	dev_info(adev->dev,
+			"Got data exchange info from dynamic crit_region_table at offset 0x%x with size of 0x%x bytes.\n",
+			dataexchange_offset, dataexchange_size);
+
+	if (!IS_ALIGNED(dataexchange_offset, 4) || !IS_ALIGNED(dataexchange_size, 4)) {
+		DRM_ERROR("Data exchange data not aligned to 4 bytes\n");
+		return -EINVAL;
+	}
+
+	pos = (uint64_t)dataexchange_offset;
+	amdgpu_device_vram_access(adev, pos, pfvf_data,
+					dataexchange_size, false);
+
+	return 0;
+}
+
 void amdgpu_virt_init(struct amdgpu_device *adev)
 {
 	bool is_sriov = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index f2aa306f4192..ae456bde6a5a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -440,6 +440,7 @@ void amdgpu_virt_init(struct amdgpu_device *adev);
 int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
 int amdgpu_virt_init_discovery_from_mem(struct amdgpu_device *adev, uint8_t *binary);
 bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev);
+int amdgpu_virt_read_exchange_data_from_mem(struct amdgpu_device *adev, uint32_t *pfvf_data);
 
 bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
 int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
-- 
2.34.1


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

* Re: [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support
  2025-10-10  4:43 ` [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan
@ 2025-10-10  8:32   ` Christian König
  2025-10-10 15:00   ` Alex Deucher
  1 sibling, 0 replies; 15+ messages in thread
From: Christian König @ 2025-10-10  8:32 UTC (permalink / raw)
  To: Ellen Pan, amd-gfx; +Cc: Alexander.Deucher, Lijo.Lazar, Jeffrey.Chan



On 10.10.25 06:43, Ellen Pan wrote:
> 1. Added enum amd_sriov_crit_region_version to support multi versions
> 2. Added logic in SRIOV mailbox to regonize crit_region version during
>    req_gpu_init_data
> 
> Signed-off-by: Ellen Pan <yunru.pan@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    |  8 +++++++
>  drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  5 +++++
>  drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c       | 23 ++++++++++++++-------
>  4 files changed, 31 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index e95adf0407a0..3a6b0e1084d7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -150,7 +150,8 @@ void amdgpu_virt_request_init_data(struct amdgpu_device *adev)
>  		virt->ops->req_init_data(adev);
>  
>  	if (adev->virt.req_init_data_ver > 0)
> -		DRM_INFO("host supports REQ_INIT_DATA handshake\n");
> +		DRM_INFO("host supports REQ_INIT_DATA handshake of critical_region_version %d\n",
> +				 adev->virt.req_init_data_ver);
>  	else
>  		DRM_WARN("host doesn't support REQ_INIT_DATA handshake\n");
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index d1172c8e58c4..51ff73b1fcd5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -262,6 +262,11 @@ struct amdgpu_virt_ras {
>  
>  DECLARE_ATTR_CAP_CLASS(amdgpu_virt, AMDGPU_VIRT_CAPS_LIST);
>  
> +struct amdgpu_virt_region {
> +	uint64_t offset;
> +	uint64_t size_kb;

Are those really 64bit values? You seem to read them from 32bit registers.

Apart from that looks good to me.

Regards,
Christian.

> +};
> +
>  /* GPU virtualization */
>  struct amdgpu_virt {
>  	uint32_t			caps;
> @@ -289,6 +294,9 @@ struct amdgpu_virt {
>  	bool ras_init_done;
>  	uint32_t reg_access;
>  
> +	/* dynamic(v2) critical regions */
> +	struct amdgpu_virt_region init_data_header;
> +
>  	/* vf2pf message */
>  	struct delayed_work vf2pf_work;
>  	uint32_t vf2pf_update_interval_ms;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> index 3b35154e2df6..b53caab5b706 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> @@ -65,6 +65,11 @@
>  	(AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1 + AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1 + \
>  	 AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1)
>  
> +enum amd_sriov_crit_region_version {
> +	GPU_CRIT_REGION_V1 = 1,
> +	GPU_CRIT_REGION_V2 = 2,
> +};
> +
>  /*
>   * PF2VF history log:
>   * v1 defined in amdgim
> diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
> index e5282a5d05d9..cd5b2f07edb8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
> @@ -222,12 +222,20 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
>  				adev->virt.req_init_data_ver = 0;
>  		} else {
>  			if (req == IDH_REQ_GPU_INIT_DATA) {
> -				adev->virt.req_init_data_ver =
> -					RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
> -
> -				/* assume V1 in case host doesn't set version number */
> -				if (adev->virt.req_init_data_ver < 1)
> -					adev->virt.req_init_data_ver = 1;
> +				switch (RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1)) {
> +				case GPU_CRIT_REGION_V2:
> +					adev->virt.req_init_data_ver = GPU_CRIT_REGION_V2;
> +					adev->virt.init_data_header.offset =
> +						RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
> +					adev->virt.init_data_header.size_kb =
> +						RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW3);
> +					break;
> +				default:
> +					adev->virt.req_init_data_ver = GPU_CRIT_REGION_V1;
> +					adev->virt.init_data_header.offset = -1;
> +					adev->virt.init_data_header.size_kb = 0;
> +					break;
> +				}
>  			}
>  		}
>  
> @@ -285,7 +293,8 @@ static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
>  
>  static int xgpu_nv_request_init_data(struct amdgpu_device *adev)
>  {
> -	return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
> +	return xgpu_nv_send_access_requests_with_param(adev, IDH_REQ_GPU_INIT_DATA,
> +			0, GPU_CRIT_REGION_V2, 0);
>  }
>  
>  static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,


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

* RE: [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV
  2025-10-10  4:43 ` [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV Ellen Pan
@ 2025-10-10 10:33   ` Lazar, Lijo
  2025-10-10 15:10   ` Alex Deucher
  1 sibling, 0 replies; 15+ messages in thread
From: Lazar, Lijo @ 2025-10-10 10:33 UTC (permalink / raw)
  To: Pan, Ellen, amd-gfx@lists.freedesktop.org
  Cc: Deucher, Alexander, Koenig, Christian, Chan, Hing Pong

[AMD Official Use Only - AMD Internal Distribution Only]

>-----Original Message-----
>From: Pan, Ellen <Yunru.Pan@amd.com>
>Sent: Friday, October 10, 2025 10:13 AM
>To: amd-gfx@lists.freedesktop.org
>Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Koenig, Christian
><Christian.Koenig@amd.com>; Lazar, Lijo <Lijo.Lazar@amd.com>; Chan, Hing
>Pong <Jeffrey.Chan@amd.com>; Pan, Ellen <Yunru.Pan@amd.com>
>Subject: [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical
>region in SRIOV
>
>- During guest driver init, asa VFs receive PF msg to
>       init dynamic critical region(v2), VFs reuse fw_vram_usage_*
>        from ttm to store critical region tables in a 5MB chunk.
>
>Signed-off-by: Ellen Pan <yunru.pan@amd.com>
>---
> .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c  | 29 ++++++++--------
> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       | 33 +++++++++++--------
> drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      |  9 +++++
> 3 files changed, 44 insertions(+), 27 deletions(-)
>
>diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
>index c7d32fb216e4..636385c80f64 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
>@@ -181,19 +181,22 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct
>amdgpu_device *adev)
>       u8 frev, crev;
>       int usage_bytes = 0;
>
>-      if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev,
>&data_offset)) {
>-              if (frev == 2 && crev == 1) {
>-                      fw_usage_v2_1 =
>-                              (struct vram_usagebyfirmware_v2_1 *)(ctx->bios
>+ data_offset);
>-                      amdgpu_atomfirmware_allocate_fb_v2_1(adev,
>-                                      fw_usage_v2_1,
>-                                      &usage_bytes);
>-              } else if (frev >= 2 && crev >= 2) {
>-                      fw_usage_v2_2 =
>-                              (struct vram_usagebyfirmware_v2_2 *)(ctx->bios
>+ data_offset);
>-                      amdgpu_atomfirmware_allocate_fb_v2_2(adev,
>-                                      fw_usage_v2_2,
>-                                      &usage_bytes);
>+      /* Skip atomfirmware allocation for SRIOV VFs when dynamic crit regn is
>enabled */
>+      if (!(amdgpu_sriov_vf(adev) && adev-
>>virt.is_dynamic_crit_regn_enabled)) {
>+              if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev,
>&crev, &data_offset)) {
>+                      if (frev == 2 && crev == 1) {
>+                              fw_usage_v2_1 =
>+                                      (struct vram_usagebyfirmware_v2_1
>*)(ctx->bios + data_offset);
>+                              amdgpu_atomfirmware_allocate_fb_v2_1(adev,
>+                                              fw_usage_v2_1,
>+                                              &usage_bytes);
>+                      } else if (frev >= 2 && crev >= 2) {
>+                              fw_usage_v2_2 =
>+                                      (struct vram_usagebyfirmware_v2_2
>*)(ctx->bios + data_offset);
>+                              amdgpu_atomfirmware_allocate_fb_v2_2(adev,
>+                                              fw_usage_v2_2,
>+                                              &usage_bytes);
>+                      }
>               }
>       }
>
>diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>index 96bd0185f936..c0810c53703c 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>@@ -1943,23 +1943,28 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>       if (r)
>               return r;
>
>-      /*
>-       *The reserved vram for driver must be pinned to the specified
>-       *place on the VRAM, so reserve it early.
>-       */
>-      r = amdgpu_ttm_drv_reserve_vram_init(adev);
>-      if (r)
>-              return r;
>-
>-      /*
>-       * only NAVI10 and onwards ASIC support for IP discovery.
>-       * If IP discovery enabled, a block of memory should be
>-       * reserved for IP discovey.
>+      /* For VFs with dynamic critical regions (v2), fw_reserve_vram is already
>+       * reserved, so no additional memory reservation is required below.
>        */
>-      if (adev->mman.discovery_bin) {
>-              r = amdgpu_ttm_reserve_tmr(adev);
>+      if (!amdgpu_sriov_vf(adev) || (adev->virt.req_init_data_ver !=
>GPU_CRIT_REGION_V2)) {
>+              /*
>+               * The reserved VRAM for the driver must be pinned to a specific
>+               * location in VRAM, so reserve it early.
>+               */
>+              r = amdgpu_ttm_drv_reserve_vram_init(adev);
>               if (r)
>                       return r;
[lijo]

Since you are skipping FW usage tables, isn't drv_vram_usage_size expected to be 0 anyway? The discovery one below will need a separate check though for now.

Thanks,
Lijo

>+
>+              /*
>+               * only NAVI10 and later ASICs support IP discovery.
>+               * If IP discovery is enabled, a block of memory should be
>+               * reserved for it.
>+               */
>+              if (adev->mman.discovery_bin) {
>+                      r = amdgpu_ttm_reserve_tmr(adev);
>+                      if (r)
>+                              return r;
>+              }
>       }
>
>       /* allocate memory as required for VGA diff --git
>a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>index 6eca5e8a7375..461e83728594 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>@@ -940,6 +940,15 @@ int amdgpu_virt_init_critical_region(struct
>amdgpu_device *adev)
>               adev-
>>virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].size_kb =
>                       init_data_hdr->bad_page_size_in_kb;
>
>+              /* reserved memory starts from crit region base offset with the
>size of 5MB */
>+              adev->mman.fw_vram_usage_start_offset = adev-
>>virt.crit_regn.offset;
>+              adev->mman.fw_vram_usage_size = adev->virt.crit_regn.size_kb
><< 10;
>+              dev_info(adev->dev,
>+                      "critical region v%d requested to reserve memory start at
>%08x with %d KB.\n",
>+                        init_data_hdr->version,
>+                        adev->mman.fw_vram_usage_start_offset,
>+                        adev->mman.fw_vram_usage_size >> 10);
>+
>               adev->virt.is_dynamic_crit_regn_enabled = true;
>               break;
>       default:
>--
>2.34.1


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

* RE: [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init from dynamic crit_region offsets
  2025-10-10  4:43 ` [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init from dynamic crit_region offsets Ellen Pan
@ 2025-10-10 10:46   ` Lazar, Lijo
  0 siblings, 0 replies; 15+ messages in thread
From: Lazar, Lijo @ 2025-10-10 10:46 UTC (permalink / raw)
  To: Pan, Ellen, amd-gfx@lists.freedesktop.org
  Cc: Deucher, Alexander, Koenig, Christian, Chan, Hing Pong

[AMD Official Use Only - AMD Internal Distribution Only]

>-----Original Message-----
>From: Pan, Ellen <Yunru.Pan@amd.com>
>Sent: Friday, October 10, 2025 10:13 AM
>To: amd-gfx@lists.freedesktop.org
>Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Koenig, Christian
><Christian.Koenig@amd.com>; Lazar, Lijo <Lijo.Lazar@amd.com>; Chan, Hing
>Pong <Jeffrey.Chan@amd.com>; Pan, Ellen <Yunru.Pan@amd.com>
>Subject: [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init
>from dynamic crit_region offsets
>
>1. Added VF logic in amdgpu_virt to init IP discovery using the offsets from
>dynamic(v2) critical regions; 2. Added VF logic in amdgpu_virt to init bios image
>using the offsets from dynamic(v2) critical regions;
>
>Signed-off-by: Ellen Pan <yunru.pan@amd.com>
>---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c      |  26 +++--
> drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c |  33 +++---
> drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      | 107
>++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h      |   2 +
> 5 files changed, 142 insertions(+), 27 deletions(-)
>
>diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>index 2a0df4cabb99..d320118858bc 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>@@ -416,6 +416,7 @@ int amdgpu_device_ip_block_add(struct
>amdgpu_device *adev,
> /*
>  * BIOS.
>  */
>+bool amdgpu_check_atom_bios(struct amdgpu_device *adev, size_t size);
> bool amdgpu_get_bios(struct amdgpu_device *adev);  bool
>amdgpu_read_bios(struct amdgpu_device *adev);  bool
>amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev, diff --git
>a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
>index 00e96419fcda..787584956214 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
>@@ -47,7 +47,7 @@
> /* Check if current bios is an ATOM BIOS.
>  * Return true if it is ATOM BIOS. Otherwise, return false.
>  */
>-static bool check_atom_bios(struct amdgpu_device *adev, size_t size)
>+bool amdgpu_check_atom_bios(struct amdgpu_device *adev, size_t size)
> {
>       uint16_t tmp, bios_header_start;
>       uint8_t *bios = adev->bios;
>@@ -96,7 +96,8 @@ void amdgpu_bios_release(struct amdgpu_device *adev)
>  * part of the system bios.  On boot, the system bios puts a
>  * copy of the igp rom at the start of vram if a discrete card is
>  * present.
>- * For SR-IOV, the vbios image is also put in VRAM in the VF.
>+ * For SR-IOV, if dynamic critical region is not enabled,
>+ * the vbios image is also put at the start of VRAM in the VF.
>  */
> static bool amdgpu_read_bios_from_vram(struct amdgpu_device *adev)  {
>@@ -127,7 +128,7 @@ static bool amdgpu_read_bios_from_vram(struct
>amdgpu_device *adev)
>       memcpy_fromio(adev->bios, bios, size);
>       iounmap(bios);
>
>-      if (!check_atom_bios(adev, size)) {
>+      if (!amdgpu_check_atom_bios(adev, size)) {
>               amdgpu_bios_release(adev);
>               return false;
>       }
>@@ -155,7 +156,7 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
>       memcpy_fromio(adev->bios, bios, size);
>       pci_unmap_rom(adev->pdev, bios);
>
>-      if (!check_atom_bios(adev, size)) {
>+      if (!amdgpu_check_atom_bios(adev, size)) {
>               amdgpu_bios_release(adev);
>               return false;
>       }
>@@ -195,7 +196,7 @@ static bool amdgpu_read_bios_from_rom(struct
>amdgpu_device *adev)
>       /* read complete BIOS */
>       amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
>
>-      if (!check_atom_bios(adev, len)) {
>+      if (!amdgpu_check_atom_bios(adev, len)) {
>               amdgpu_bios_release(adev);
>               return false;
>       }
>@@ -225,7 +226,7 @@ static bool amdgpu_read_platform_bios(struct
>amdgpu_device *adev)
>       memcpy_fromio(adev->bios, bios, romlen);
>       iounmap(bios);
>
>-      if (!check_atom_bios(adev, romlen))
>+      if (!amdgpu_check_atom_bios(adev, romlen))
>               goto free_bios;
>
>       adev->bios_size = romlen;
>@@ -334,7 +335,7 @@ static bool amdgpu_atrm_get_bios(struct
>amdgpu_device *adev)
>                       break;
>       }
>
>-      if (!check_atom_bios(adev, size)) {
>+      if (!amdgpu_check_atom_bios(adev, size)) {
>               amdgpu_bios_release(adev);
>               return false;
>       }
>@@ -399,7 +400,7 @@ static bool amdgpu_acpi_vfct_bios(struct
>amdgpu_device *adev)
>                                            vhdr->ImageLength,
>                                            GFP_KERNEL);
>
>-                      if (!check_atom_bios(adev, vhdr->ImageLength)) {
>+                      if (!amdgpu_check_atom_bios(adev, vhdr-
>>ImageLength)) {
>                               amdgpu_bios_release(adev);
>                               return false;
>                       }
>@@ -467,9 +468,14 @@ static bool amdgpu_get_bios_dgpu(struct
>amdgpu_device *adev)
>       }
>
>       /* this is required for SR-IOV */
>-      if (amdgpu_read_bios_from_vram(adev)) {
>-              dev_info(adev->dev, "Fetched VBIOS from VRAM BAR\n");
>+      if (amdgpu_sriov_vf(adev) &&
>amdgpu_virt_read_bios_from_vram(adev)) {
>+              dev_info(adev->dev, "Fetched VBIOS from dynamic VRAM
>BAR\n");
>               goto success;
>+      } else {
>+              if (amdgpu_read_bios_from_vram(adev)) {
>+                      dev_info(adev->dev, "Fetched VBIOS from VRAM
>BAR\n");
>+                      goto success;
>+              }
>       }
>
>       if (amdgpu_prefer_rom_resource(adev)) { diff --git
>a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
>index 73401f0aeb34..de8676d6ff9c 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
>@@ -275,21 +275,18 @@ static int
>amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,
>       int i, ret = 0;
>       u32 msg;
>
>-      if (!amdgpu_sriov_vf(adev)) {
>-              /* It can take up to two second for IFWI init to complete on
>some dGPUs,
>-               * but generally it should be in the 60-100ms range.  Normally
>this starts
>-               * as soon as the device gets power so by the time the OS loads
>this has long
>-               * completed.  However, when a card is hotplugged via e.g.,
>USB4, we need to
>-               * wait for this to complete.  Once the C2PMSG is updated, we
>can
>-               * continue.
>-               */
>-
>-              for (i = 0; i < 2000; i++) {
>-                      msg = RREG32(mmMP0_SMN_C2PMSG_33);
>-                      if (msg & 0x80000000)
>-                              break;
>-                      msleep(1);
>-              }
>+      /* It can take up to two second for IFWI init to complete on some
>dGPUs,
>+       * but generally it should be in the 60-100ms range.  Normally this
>starts
>+       * as soon as the device gets power so by the time the OS loads this has
>long
>+       * completed.  However, when a card is hotplugged via e.g., USB4, we
>need to
>+       * wait for this to complete.  Once the C2PMSG is updated, we can
>+       * continue.
>+       */
>+      for (i = 0; i < 2000; i++) {
>+              msg = RREG32(mmMP0_SMN_C2PMSG_33);
>+              if (msg & 0x80000000)
>+                      break;
>+              msleep(1);
>       }
>
>       vram_size = RREG32(mmRCC_CONFIG_MEMSIZE); @@ -467,8
>+464,10 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
>                       goto out;
>       } else {
>               drm_dbg(&adev->ddev, "use ip discovery information from
>memory");
>-              r = amdgpu_discovery_read_binary_from_mem(
>-                      adev, adev->mman.discovery_bin);
>+              if (amdgpu_sriov_vf(adev))
>+                      r = amdgpu_virt_init_discovery_from_mem(adev,
>adev->mman.discovery_bin);
>+              else
>+                      r = amdgpu_discovery_read_binary_from_mem(adev,
>+adev->mman.discovery_bin);
>               if (r)
>                       goto out;
>       }
>diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>index 461e83728594..67d5f15a72a1 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
>@@ -965,6 +965,113 @@ int amdgpu_virt_init_critical_region(struct
>amdgpu_device *adev)
>       return r;
> }
>
>+int amdgpu_virt_init_discovery_from_mem(struct amdgpu_device *adev,
>+uint8_t *binary) {
>+      uint64_t vram_size;
>+      uint32_t ip_discovery_offset, ip_discovery_size;
>+      uint64_t pos = 0;
>+
>+      /* Get dynamic offset for IPD if dynamic critical region is enabled */
>+      if (adev->virt.is_dynamic_crit_regn_enabled) {
>+              ip_discovery_offset =
>+                      adev-
>>virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].offset;
>+              ip_discovery_size =
>+                      adev-
>>virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb << 10;
>+
>+              dev_info(adev->dev,
>+                      "Got IPD info from dynamic crit_region at offset 0x%x
>with size of 0x%x bytes.\n",
>+                      ip_discovery_offset, ip_discovery_size);
>+
>+              if (!IS_ALIGNED(ip_discovery_offset, 4) ||
>!IS_ALIGNED(ip_discovery_size, 4)) {
>+                      dev_err(adev->dev, "IP discovery data not aligned to 4
>bytes\n");
>+                      return -EINVAL;
>+              }
>+
>+              if (ip_discovery_size > DISCOVERY_TMR_SIZE) {
>+                      dev_err(adev->dev, "Invalid IP discovery size: 0x%x\n",
>ip_discovery_size);
>+                      return -EINVAL;
>+              }
>+
>+              pos = (uint64_t)ip_discovery_offset;
>+              amdgpu_device_vram_access(adev, pos, (uint32_t *)binary,
>+                                      ip_discovery_size, false);
[lijo]

The intent of my comment to the earlier version is only to fetch the binary and the corresponding size.

u8      *bin;
u32     size;
r =amdgpu_virt_get_image(adev, BIOS, &bin, &size);

r = 0 // Pass
r = -EOPNOSUPP // Not supported
Anything else = some real issue.

Check BIOS etc. will be done inside amdgpu_bios file itself similar to how it is done for other methods.

On unsupported ones, it continues with the legacy path. Same for discovery image as well - amdgpu_virt_get_image(adev, DISCOVERY,  &bin, &size)

Thanks,
Lijo

>+      } else {
>+              vram_size = RREG32(mmRCC_CONFIG_MEMSIZE);
>+              if (!vram_size || vram_size == U32_MAX)
>+                      return -EINVAL;
>+
>+              vram_size <<= 20;
>+
>+              pos = vram_size - DISCOVERY_TMR_OFFSET;
>+              amdgpu_device_vram_access(adev, pos, (uint32_t *)binary,
>+                                      adev->mman.discovery_tmr_size,
>false);
>+      }
>+
>+      return 0;
>+}
>+
>+/* For SR-IOV, if dynamic critical region is enabled,
>+ * the vbios image is put at a dynamic offset of VRAM in the VF.
>+ * If dynamic critical region is disabled, exit early to proceed
>+ * the same seq as on baremetal.
>+ */
>+bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev) {
>+      uint8_t __iomem *bios;
>+      resource_size_t vram_base;
>+      resource_size_t size = 256 * 1024; /* ??? */
>+      uint32_t vbios_offset = 0;
>+      uint32_t vbios_size = 0;
>+
>+      /* Exit early if it's not initialized */
>+      if (!adev->virt.is_dynamic_crit_regn_enabled)
>+              return false;
>+
>+      if (amdgpu_device_need_post(adev))
>+              return false;
>+
>+      /* FB BAR not enabled */
>+      if (pci_resource_len(adev->pdev, 0) == 0)
>+              return false;
>+
>+      adev->bios = NULL;
>+      vram_base = pci_resource_start(adev->pdev, 0);
>+
>+      vbios_offset = adev-
>>virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].offset;
>+      vbios_size =
>+              adev-
>>virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].size_kb << 10;
>+      if (vbios_size > size) {
>+              dev_err(adev->dev, "Invalid vbios size: 0x%x\n", vbios_size);
>+              return false;
>+      }
>+
>+      dev_info(adev->dev,
>+              "Got bios info from dynamic crit_region_table at offset 0x%x
>with size of 0x%x bytes.\n",
>+              vbios_offset, vbios_size);
>+
>+      size = vbios_size;
>+
>+      bios = ioremap_wc(vram_base + vbios_offset, size);
>+      if (!bios)
>+              return false;
>+
>+      adev->bios = kmalloc(size, GFP_KERNEL);
>+      if (!adev->bios) {
>+              iounmap(bios);
>+              return false;
>+      }
>+      adev->bios_size = size;
>+      memcpy_fromio(adev->bios, bios, size);
>+      iounmap(bios);
>+
>+      if (!check_atom_bios(adev, size)) {
>+              amdgpu_bios_release(adev);
>+              return false;
>+      }
>+
>+      return true;
>+}
>+
> void amdgpu_virt_init(struct amdgpu_device *adev)  {
>       bool is_sriov = false;
>diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
>b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
>index bc1fc1c6daba..f2aa306f4192 100644
>--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
>+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
>@@ -438,6 +438,8 @@ void amdgpu_virt_fini_data_exchange(struct
>amdgpu_device *adev);  void amdgpu_virt_init(struct amdgpu_device *adev);
>
> int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
>+int amdgpu_virt_init_discovery_from_mem(struct amdgpu_device *adev,
>+uint8_t *binary); bool amdgpu_virt_read_bios_from_vram(struct
>+amdgpu_device *adev);
>
> bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);  int
>amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
>--
>2.34.1


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

* Re: [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix
  2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
                   ` (4 preceding siblings ...)
  2025-10-10  4:43 ` [PATCH 6/6] drm/amdgpu: Add logic for VF data exchange region " Ellen Pan
@ 2025-10-10 14:51 ` Alex Deucher
  5 siblings, 0 replies; 15+ messages in thread
From: Alex Deucher @ 2025-10-10 14:51 UTC (permalink / raw)
  To: Ellen Pan
  Cc: amd-gfx, Alexander.Deucher, Christian.Koenig, Lijo.Lazar,
	Jeffrey.Chan

On Fri, Oct 10, 2025 at 12:43 AM Ellen Pan <yunru.pan@amd.com> wrote:
>
>  - This change prepares the later patches to intro  _v2 suffix to SRIOV critical regions
>
> Signed-off-by: Ellen Pan <yunru.pan@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    | 20 ++++----
>  drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h | 57 ++++++++++++++-------
>  2 files changed, 49 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index 3328ab63376b..e95adf0407a0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -686,7 +686,7 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
>                 /* got through this logic in early init stage to get necessary flags, e.g. rlcg_acc related*/
>                 adev->virt.fw_reserve.p_pf2vf =
>                         (struct amd_sriov_msg_pf2vf_info_header *)
> -                       (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10));
> +                       (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
>
>                 amdgpu_virt_read_pf2vf_data(adev);
>         }
> @@ -703,21 +703,21 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
>                 if (adev->mman.fw_vram_usage_va) {
>                         adev->virt.fw_reserve.p_pf2vf =
>                                 (struct amd_sriov_msg_pf2vf_info_header *)
> -                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10));
> +                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
>                         adev->virt.fw_reserve.p_vf2pf =
>                                 (struct amd_sriov_msg_vf2pf_info_header *)
> -                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB << 10));
> +                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
>                         adev->virt.fw_reserve.ras_telemetry =
> -                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB << 10));
> +                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
>                 } else if (adev->mman.drv_vram_usage_va) {
>                         adev->virt.fw_reserve.p_pf2vf =
>                                 (struct amd_sriov_msg_pf2vf_info_header *)
> -                               (adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10));
> +                               (adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
>                         adev->virt.fw_reserve.p_vf2pf =
>                                 (struct amd_sriov_msg_vf2pf_info_header *)
> -                               (adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB << 10));
> +                               (adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
>                         adev->virt.fw_reserve.ras_telemetry =
> -                               (adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB << 10));
> +                               (adev->mman.drv_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
>                 }
>
>                 amdgpu_virt_read_pf2vf_data(adev);
> @@ -1304,7 +1304,7 @@ static int amdgpu_virt_cache_host_error_counts(struct amdgpu_device *adev,
>         checksum = host_telemetry->header.checksum;
>         used_size = host_telemetry->header.used_size;
>
> -       if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))
> +       if (used_size > (AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10))
>                 return 0;
>
>         tmp = kmemdup(&host_telemetry->body.error_count, used_size, GFP_KERNEL);
> @@ -1383,7 +1383,7 @@ amdgpu_virt_write_cpers_to_ring(struct amdgpu_device *adev,
>         checksum = host_telemetry->header.checksum;
>         used_size = host_telemetry->header.used_size;
>
> -       if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))
> +       if (used_size > (AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10))
>                 return -EINVAL;
>
>         cper_dump = kmemdup(&host_telemetry->body.cper_dump, used_size, GFP_KERNEL);
> @@ -1515,7 +1515,7 @@ static int amdgpu_virt_cache_chk_criti_hit(struct amdgpu_device *adev,
>         checksum = host_telemetry->header.checksum;
>         used_size = host_telemetry->header.used_size;
>
> -       if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))
> +       if (used_size > (AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1 << 10))
>                 return 0;
>
>         tmp = kmemdup(&host_telemetry->body.chk_criti, used_size, GFP_KERNEL);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> index 3a79ed7d8031..3b35154e2df6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> @@ -23,26 +23,47 @@
>  #ifndef AMDGV_SRIOV_MSG__H_
>  #define AMDGV_SRIOV_MSG__H_
>
> -/* unit in kilobytes */
> -#define AMD_SRIOV_MSG_VBIOS_OFFSET          0
> -#define AMD_SRIOV_MSG_VBIOS_SIZE_KB         64
> -#define AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB AMD_SRIOV_MSG_VBIOS_SIZE_KB
> -#define AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB   4
> -#define AMD_SRIOV_MSG_TMR_OFFSET_KB         2048
> -#define AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB      2
> -#define AMD_SRIOV_RAS_TELEMETRY_SIZE_KB             64
>  /*
> - * layout
> + * layout v1
>   * 0           64KB        65KB        66KB           68KB                   132KB
>   * |   VBIOS   |   PF2VF   |   VF2PF   |   Bad Page   | RAS Telemetry Region | ...
>   * |   64KB    |   1KB     |   1KB     |   2KB        | 64KB                 | ...
>   */
>
> -#define AMD_SRIOV_MSG_SIZE_KB                   1
> -#define AMD_SRIOV_MSG_PF2VF_OFFSET_KB           AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB
> -#define AMD_SRIOV_MSG_VF2PF_OFFSET_KB           (AMD_SRIOV_MSG_PF2VF_OFFSET_KB + AMD_SRIOV_MSG_SIZE_KB)
> -#define AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB        (AMD_SRIOV_MSG_VF2PF_OFFSET_KB + AMD_SRIOV_MSG_SIZE_KB)
> -#define AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB   (AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB + AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB)
> +/*
> + * layout v2 (offsets are dynamically allocated and the offsets below are examples)
> + * 0           1KB         64KB        65KB        66KB           68KB                   132KB
> + * |  INITD_H  |   VBIOS   |   PF2VF   |   VF2PF   |   Bad Page   | RAS Telemetry Region | ...
> + * |   1KB     |   64KB    |   1KB     |   1KB     |   2KB        | 64KB                 | ...
> + *
> + * Note: PF2VF + VF2PF + Bad Page = DataExchange region (allocated contiguously)
> + */
> +
> +/* v1 layout sizes */
> +#define AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1                 64
> +#define AMD_SRIOV_MSG_PF2VF_SIZE_KB_V1                 1
> +#define AMD_SRIOV_MSG_VF2PF_SIZE_KB_V1                 1
> +#define AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB_V1              2
> +#define AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1         64
> +#define AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1          \
> +       (AMD_SRIOV_MSG_PF2VF_SIZE_KB_V1 + AMD_SRIOV_MSG_VF2PF_SIZE_KB_V1 + \
> +        AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB_V1)
> +
> +/* v1 offsets */
> +#define AMD_SRIOV_MSG_VBIOS_OFFSET_V1                  0
> +#define AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB_V1                AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1
> +#define AMD_SRIOV_MSG_TMR_OFFSET_KB                    2048
> +#define AMD_SRIOV_MSG_SIZE_KB_V1                       1
> +#define AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1               AMD_SRIOV_MSG_DATAEXCHANGE_OFFSET_KB_V1
> +#define AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1               \
> +       (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 + AMD_SRIOV_MSG_SIZE_KB_V1)
> +#define AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB_V1            \
> +       (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 + AMD_SRIOV_MSG_SIZE_KB_V1)
> +#define AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1       \
> +       (AMD_SRIOV_MSG_BAD_PAGE_OFFSET_KB_V1 + AMD_SRIOV_MSG_BAD_PAGE_SIZE_KB_V1)
> +#define AMD_SRIOV_MSG_INIT_DATA_TOT_SIZE_KB_V1         \
> +       (AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1 + AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1 + \
> +        AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1)
>
>  /*
>   * PF2VF history log:
> @@ -436,12 +457,12 @@ unsigned int amd_sriov_msg_checksum(void *obj, unsigned long obj_size, unsigned
>  #define _stringification(s) #s
>
>  _Static_assert(
> -       sizeof(struct amd_sriov_msg_vf2pf_info) == AMD_SRIOV_MSG_SIZE_KB << 10,
> -       "amd_sriov_msg_vf2pf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB) " KB");
> +       sizeof(struct amd_sriov_msg_vf2pf_info) == AMD_SRIOV_MSG_SIZE_KB_V1 << 10,
> +       "amd_sriov_msg_vf2pf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB_V1) " KB");
>
>  _Static_assert(
> -       sizeof(struct amd_sriov_msg_pf2vf_info) == AMD_SRIOV_MSG_SIZE_KB << 10,
> -       "amd_sriov_msg_pf2vf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB) " KB");
> +       sizeof(struct amd_sriov_msg_pf2vf_info) == AMD_SRIOV_MSG_SIZE_KB_V1 << 10,
> +       "amd_sriov_msg_pf2vf_info must be " stringification(AMD_SRIOV_MSG_SIZE_KB_V1) " KB");
>
>  _Static_assert(AMD_SRIOV_MSG_RESERVE_UCODE % 4 == 0,
>                "AMD_SRIOV_MSG_RESERVE_UCODE must be multiple of 4");
> --
> 2.34.1
>

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

* Re: [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support
  2025-10-10  4:43 ` [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan
  2025-10-10  8:32   ` Christian König
@ 2025-10-10 15:00   ` Alex Deucher
  1 sibling, 0 replies; 15+ messages in thread
From: Alex Deucher @ 2025-10-10 15:00 UTC (permalink / raw)
  To: Ellen Pan
  Cc: amd-gfx, Alexander.Deucher, Christian.Koenig, Lijo.Lazar,
	Jeffrey.Chan

On Fri, Oct 10, 2025 at 12:43 AM Ellen Pan <yunru.pan@amd.com> wrote:
>
> 1. Added enum amd_sriov_crit_region_version to support multi versions
> 2. Added logic in SRIOV mailbox to regonize crit_region version during
>    req_gpu_init_data
>
> Signed-off-by: Ellen Pan <yunru.pan@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    |  8 +++++++
>  drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  5 +++++
>  drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c       | 23 ++++++++++++++-------
>  4 files changed, 31 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index e95adf0407a0..3a6b0e1084d7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -150,7 +150,8 @@ void amdgpu_virt_request_init_data(struct amdgpu_device *adev)
>                 virt->ops->req_init_data(adev);
>
>         if (adev->virt.req_init_data_ver > 0)
> -               DRM_INFO("host supports REQ_INIT_DATA handshake\n");
> +               DRM_INFO("host supports REQ_INIT_DATA handshake of critical_region_version %d\n",
> +                                adev->virt.req_init_data_ver);

dev_info() is preferred.

>         else
>                 DRM_WARN("host doesn't support REQ_INIT_DATA handshake\n");

Change this to dev_warn() while you are here.


>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index d1172c8e58c4..51ff73b1fcd5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -262,6 +262,11 @@ struct amdgpu_virt_ras {
>
>  DECLARE_ATTR_CAP_CLASS(amdgpu_virt, AMDGPU_VIRT_CAPS_LIST);
>
> +struct amdgpu_virt_region {
> +       uint64_t offset;
> +       uint64_t size_kb;
> +};
> +
>  /* GPU virtualization */
>  struct amdgpu_virt {
>         uint32_t                        caps;
> @@ -289,6 +294,9 @@ struct amdgpu_virt {
>         bool ras_init_done;
>         uint32_t reg_access;
>
> +       /* dynamic(v2) critical regions */
> +       struct amdgpu_virt_region init_data_header;
> +
>         /* vf2pf message */
>         struct delayed_work vf2pf_work;
>         uint32_t vf2pf_update_interval_ms;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> index 3b35154e2df6..b53caab5b706 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> @@ -65,6 +65,11 @@
>         (AMD_SRIOV_MSG_VBIOS_SIZE_KB_V1 + AMD_SRIOV_MSG_DATAEXCHANGE_SIZE_KB_V1 + \
>          AMD_SRIOV_MSG_RAS_TELEMETRY_SIZE_KB_V1)
>
> +enum amd_sriov_crit_region_version {
> +       GPU_CRIT_REGION_V1 = 1,
> +       GPU_CRIT_REGION_V2 = 2,
> +};
> +
>  /*
>   * PF2VF history log:
>   * v1 defined in amdgim
> diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
> index e5282a5d05d9..cd5b2f07edb8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
> @@ -222,12 +222,20 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
>                                 adev->virt.req_init_data_ver = 0;
>                 } else {
>                         if (req == IDH_REQ_GPU_INIT_DATA) {
> -                               adev->virt.req_init_data_ver =
> -                                       RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
> -
> -                               /* assume V1 in case host doesn't set version number */
> -                               if (adev->virt.req_init_data_ver < 1)
> -                                       adev->virt.req_init_data_ver = 1;
> +                               switch (RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1)) {
> +                               case GPU_CRIT_REGION_V2:
> +                                       adev->virt.req_init_data_ver = GPU_CRIT_REGION_V2;
> +                                       adev->virt.init_data_header.offset =
> +                                               RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
> +                                       adev->virt.init_data_header.size_kb =
> +                                               RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW3);
> +                                       break;
> +                               default:
> +                                       adev->virt.req_init_data_ver = GPU_CRIT_REGION_V1;
> +                                       adev->virt.init_data_header.offset = -1;
> +                                       adev->virt.init_data_header.size_kb = 0;
> +                                       break;
> +                               }
>                         }
>                 }
>
> @@ -285,7 +293,8 @@ static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
>
>  static int xgpu_nv_request_init_data(struct amdgpu_device *adev)
>  {
> -       return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
> +       return xgpu_nv_send_access_requests_with_param(adev, IDH_REQ_GPU_INIT_DATA,
> +                       0, GPU_CRIT_REGION_V2, 0);

What is this change for?  This parameter doesn't seem to be used.

Alex

>  }
>
>  static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,
> --
> 2.34.1
>

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

* Re: [PATCH 3/6] drm/amdgpu: Introduce SRIOV critical regions v2 during VF init
  2025-10-10  4:43 ` [PATCH 3/6] drm/amdgpu: Introduce SRIOV critical regions v2 during VF init Ellen Pan
@ 2025-10-10 15:04   ` Alex Deucher
  0 siblings, 0 replies; 15+ messages in thread
From: Alex Deucher @ 2025-10-10 15:04 UTC (permalink / raw)
  To: Ellen Pan
  Cc: amd-gfx, Alexander.Deucher, Christian.Koenig, Lijo.Lazar,
	Jeffrey.Chan

On Fri, Oct 10, 2025 at 12:43 AM Ellen Pan <yunru.pan@amd.com> wrote:
>
>     1. Introduced amdgpu_virt_init_critical_region during VF init.
>      - VFs use init_data_header_offset and init_data_header_size_kb
>             transmitted via PF2VF mailbox to fetch the offset of
>             critical regions' offsets/sizes in VRAM and save to
>             adev->virt.crit_region_offsets and adev->virt.crit_region_sizes_kb.
>
> Signed-off-by: Ellen Pan <yunru.pan@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c  |   4 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c    | 113 ++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h    |   7 ++
>  drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h |  31 ++++++
>  4 files changed, 155 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 929936c8d87c..351cfe03a1aa 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -2754,6 +2754,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
>                 r = amdgpu_virt_request_full_gpu(adev, true);
>                 if (r)
>                         return r;
> +
> +               r = amdgpu_virt_init_critical_region(adev);
> +               if (r)
> +                       return r;
>         }
>
>         switch (adev->asic_type) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index 3a6b0e1084d7..6eca5e8a7375 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -843,6 +843,119 @@ static void amdgpu_virt_init_ras(struct amdgpu_device *adev)
>         adev->virt.ras.cper_rptr = 0;
>  }
>
> +static uint8_t amdgpu_virt_crit_region_calc_checksum(uint8_t *buf_start, uint8_t *buf_end)
> +{
> +       uint32_t sum = 0;
> +
> +       if (buf_start >= buf_end)
> +               return 0;
> +
> +       for (; buf_start < buf_end; buf_start++)
> +               sum += buf_start[0];
> +
> +       return 0xffffffff - sum;
> +}
> +
> +int amdgpu_virt_init_critical_region(struct amdgpu_device *adev)
> +{
> +       struct amd_sriov_msg_init_data_header *init_data_hdr = NULL;
> +       uint32_t init_hdr_offset = adev->virt.init_data_header.offset;
> +       uint32_t init_hdr_size = adev->virt.init_data_header.size_kb << 10;
> +       uint64_t pos = 0;
> +       uint64_t vram_size;
> +       int r = 0;
> +       uint8_t checksum = 0;
> +
> +       /* Skip below init if critical region version != v2 */
> +       if (adev->virt.req_init_data_ver != GPU_CRIT_REGION_V2)
> +               return 0;
> +
> +       if (init_hdr_offset < 0) {
> +               dev_err(adev->dev, "Invalid init header offset\n");
> +               return -EINVAL;
> +       }
> +
> +       vram_size = RREG32(mmRCC_CONFIG_MEMSIZE);
> +       if (!vram_size || vram_size == U32_MAX)
> +               return -EINVAL;
> +       vram_size <<= 20;
> +
> +       if ((init_hdr_offset + init_hdr_size) > vram_size) {
> +               dev_err(adev->dev, "init_data_header exceeds VRAM size, exiting\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Allocate for init_data_hdr */
> +       init_data_hdr = kzalloc(sizeof(struct amd_sriov_msg_init_data_header), GFP_KERNEL);
> +       if (!init_data_hdr)
> +               return -ENOMEM;
> +
> +       pos = (uint64_t)init_hdr_offset;
> +       amdgpu_device_vram_access(adev, pos, (uint32_t *)init_data_hdr,
> +                                       sizeof(struct amd_sriov_msg_init_data_header), false);
> +
> +       switch (init_data_hdr->version) {
> +       case GPU_CRIT_REGION_V2:
> +               if (strncmp(init_data_hdr->signature, "INDA", 4) != 0) {
> +                       dev_err(adev->dev, "Invalid init data signature: %.4s\n",
> +                                       init_data_hdr->signature);
> +                       r = -EINVAL;
> +                       goto out;
> +               }
> +
> +               checksum = amdgpu_virt_crit_region_calc_checksum(
> +                               (uint8_t *)&init_data_hdr->initdata_offset,
> +                               (uint8_t *)init_data_hdr +
> +                               sizeof(struct amd_sriov_msg_init_data_header));
> +               if (checksum != init_data_hdr->checksum) {
> +                       dev_err(adev->dev, "Found unmatching checksum from calculation 0x%x and init_data 0x%x\n",
> +                                       checksum, init_data_hdr->checksum);
> +                       r = -EINVAL;
> +                       goto out;
> +               }
> +
> +               /* Initialize critical region offsets */
> +               adev->virt.crit_regn.offset = init_data_hdr->initdata_offset;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].offset =
> +                       init_data_hdr->ip_discovery_offset;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].offset =
> +                       init_data_hdr->vbios_img_offset;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID].offset =
> +                       init_data_hdr->ras_tele_info_offset;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset =
> +                       init_data_hdr->dataexchange_offset;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].offset =
> +                       init_data_hdr->bad_page_info_offset;
> +
> +               /* Initialize critical region sizes */
> +               adev->virt.crit_regn.size_kb = init_data_hdr->initdata_size_in_kb;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb =
> +                       init_data_hdr->ip_discovery_size_in_kb;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID].size_kb =
> +                       init_data_hdr->vbios_img_size_in_kb;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID].size_kb =
> +                       init_data_hdr->ras_tele_info_size_in_kb;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].size_kb =
> +                       init_data_hdr->dataexchange_size_in_kb;
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].size_kb =
> +                       init_data_hdr->bad_page_size_in_kb;
> +
> +               adev->virt.is_dynamic_crit_regn_enabled = true;
> +               break;
> +       default:
> +               dev_err(adev->dev, "Invalid init header version: %u\n",
> +                               init_data_hdr->version);
> +               r = -EINVAL;
> +               goto out;
> +       }
> +
> +out:
> +       kfree(init_data_hdr);
> +       init_data_hdr = NULL;
> +
> +       return r;
> +}
> +
>  void amdgpu_virt_init(struct amdgpu_device *adev)
>  {
>         bool is_sriov = false;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index 51ff73b1fcd5..bc1fc1c6daba 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -52,6 +52,8 @@
>  /* tonga/fiji use this offset */
>  #define mmBIF_IOV_FUNC_IDENTIFIER 0x1503
>
> +#define mmRCC_CONFIG_MEMSIZE   0xde3

Better to put this in amdgpu_virt.c where it is used so we don't get
conflicts if amdgpu_virt.h is included with a register header
somewhere.  With that fixed:
Acked-by: Alex Deucher <alexander.deucher@amd.com>

> +
>  #define AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT 2
>
>  enum amdgpu_sriov_vf_mode {
> @@ -296,6 +298,9 @@ struct amdgpu_virt {
>
>         /* dynamic(v2) critical regions */
>         struct amdgpu_virt_region init_data_header;
> +       struct amdgpu_virt_region crit_regn;
> +       struct amdgpu_virt_region crit_regn_tbl[AMD_SRIOV_MSG_MAX_TABLE_ID];
> +       bool is_dynamic_crit_regn_enabled;
>
>         /* vf2pf message */
>         struct delayed_work vf2pf_work;
> @@ -432,6 +437,8 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev);
>  void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev);
>  void amdgpu_virt_init(struct amdgpu_device *adev);
>
> +int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
> +
>  bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
>  int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
>  void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> index b53caab5b706..d15c256f9abd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
> @@ -70,6 +70,37 @@ enum amd_sriov_crit_region_version {
>         GPU_CRIT_REGION_V2 = 2,
>  };
>
> +/* v2 layout offset enum (in order of allocation) */
> +enum amd_sriov_msg_table_id_enum {
> +       AMD_SRIOV_MSG_IPD_TABLE_ID = 0,
> +       AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID,
> +       AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID,
> +       AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID,
> +       AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID,
> +       AMD_SRIOV_MSG_INITD_H_TABLE_ID,
> +       AMD_SRIOV_MSG_MAX_TABLE_ID,
> +};
> +
> +struct amd_sriov_msg_init_data_header {
> +       char     signature[4];  /* "INDA"  */
> +       uint32_t version;
> +       uint32_t checksum;
> +       uint32_t initdata_offset; /* 0 */
> +       uint32_t initdata_size_in_kb; /* 5MB */
> +       uint32_t valid_tables;
> +       uint32_t vbios_img_offset;
> +       uint32_t vbios_img_size_in_kb;
> +       uint32_t dataexchange_offset;
> +       uint32_t dataexchange_size_in_kb;
> +       uint32_t ras_tele_info_offset;
> +       uint32_t ras_tele_info_size_in_kb;
> +       uint32_t ip_discovery_offset;
> +       uint32_t ip_discovery_size_in_kb;
> +       uint32_t bad_page_info_offset;
> +       uint32_t bad_page_size_in_kb;
> +       uint32_t reserved[8];
> +};
> +
>  /*
>   * PF2VF history log:
>   * v1 defined in amdgim
> --
> 2.34.1
>

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

* Re: [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV
  2025-10-10  4:43 ` [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV Ellen Pan
  2025-10-10 10:33   ` Lazar, Lijo
@ 2025-10-10 15:10   ` Alex Deucher
  1 sibling, 0 replies; 15+ messages in thread
From: Alex Deucher @ 2025-10-10 15:10 UTC (permalink / raw)
  To: Ellen Pan
  Cc: amd-gfx, Alexander.Deucher, Christian.Koenig, Lijo.Lazar,
	Jeffrey.Chan

On Fri, Oct 10, 2025 at 1:21 AM Ellen Pan <yunru.pan@amd.com> wrote:
>
> - During guest driver init, asa VFs receive PF msg to
>         init dynamic critical region(v2), VFs reuse fw_vram_usage_*
>          from ttm to store critical region tables in a 5MB chunk.
>
> Signed-off-by: Ellen Pan <yunru.pan@amd.com>
> ---
>  .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c  | 29 ++++++++--------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       | 33 +++++++++++--------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      |  9 +++++
>  3 files changed, 44 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
> index c7d32fb216e4..636385c80f64 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
> @@ -181,19 +181,22 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
>         u8 frev, crev;
>         int usage_bytes = 0;
>
> -       if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
> -               if (frev == 2 && crev == 1) {
> -                       fw_usage_v2_1 =
> -                               (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
> -                       amdgpu_atomfirmware_allocate_fb_v2_1(adev,
> -                                       fw_usage_v2_1,
> -                                       &usage_bytes);
> -               } else if (frev >= 2 && crev >= 2) {
> -                       fw_usage_v2_2 =
> -                               (struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
> -                       amdgpu_atomfirmware_allocate_fb_v2_2(adev,
> -                                       fw_usage_v2_2,
> -                                       &usage_bytes);
> +       /* Skip atomfirmware allocation for SRIOV VFs when dynamic crit regn is enabled */
> +       if (!(amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled)) {
> +               if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {

Do these tables actually exist on a V2 setup?  If not or if the
version numbers are invalid, the current code should handle this
already and there is no need for an extra check here.

Alex

> +                       if (frev == 2 && crev == 1) {
> +                               fw_usage_v2_1 =
> +                                       (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
> +                               amdgpu_atomfirmware_allocate_fb_v2_1(adev,
> +                                               fw_usage_v2_1,
> +                                               &usage_bytes);
> +                       } else if (frev >= 2 && crev >= 2) {
> +                               fw_usage_v2_2 =
> +                                       (struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
> +                               amdgpu_atomfirmware_allocate_fb_v2_2(adev,
> +                                               fw_usage_v2_2,
> +                                               &usage_bytes);
> +                       }
>                 }
>         }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 96bd0185f936..c0810c53703c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1943,23 +1943,28 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>         if (r)
>                 return r;
>
> -       /*
> -        *The reserved vram for driver must be pinned to the specified
> -        *place on the VRAM, so reserve it early.
> -        */
> -       r = amdgpu_ttm_drv_reserve_vram_init(adev);
> -       if (r)
> -               return r;
> -
> -       /*
> -        * only NAVI10 and onwards ASIC support for IP discovery.
> -        * If IP discovery enabled, a block of memory should be
> -        * reserved for IP discovey.
> +       /* For VFs with dynamic critical regions (v2), fw_reserve_vram is already
> +        * reserved, so no additional memory reservation is required below.
>          */
> -       if (adev->mman.discovery_bin) {
> -               r = amdgpu_ttm_reserve_tmr(adev);
> +       if (!amdgpu_sriov_vf(adev) || (adev->virt.req_init_data_ver != GPU_CRIT_REGION_V2)) {
> +               /*
> +                * The reserved VRAM for the driver must be pinned to a specific
> +                * location in VRAM, so reserve it early.
> +                */
> +               r = amdgpu_ttm_drv_reserve_vram_init(adev);
>                 if (r)
>                         return r;
> +
> +               /*
> +                * only NAVI10 and later ASICs support IP discovery.
> +                * If IP discovery is enabled, a block of memory should be
> +                * reserved for it.
> +                */
> +               if (adev->mman.discovery_bin) {
> +                       r = amdgpu_ttm_reserve_tmr(adev);
> +                       if (r)
> +                               return r;
> +               }
>         }
>
>         /* allocate memory as required for VGA
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index 6eca5e8a7375..461e83728594 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -940,6 +940,15 @@ int amdgpu_virt_init_critical_region(struct amdgpu_device *adev)
>                 adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_BAD_PAGE_INFO_TABLE_ID].size_kb =
>                         init_data_hdr->bad_page_size_in_kb;
>
> +               /* reserved memory starts from crit region base offset with the size of 5MB */
> +               adev->mman.fw_vram_usage_start_offset = adev->virt.crit_regn.offset;
> +               adev->mman.fw_vram_usage_size = adev->virt.crit_regn.size_kb << 10;
> +               dev_info(adev->dev,
> +                       "critical region v%d requested to reserve memory start at %08x with %d KB.\n",
> +                         init_data_hdr->version,
> +                         adev->mman.fw_vram_usage_start_offset,
> +                         adev->mman.fw_vram_usage_size >> 10);
> +
>                 adev->virt.is_dynamic_crit_regn_enabled = true;
>                 break;
>         default:
> --
> 2.34.1
>

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

* Re: [PATCH 6/6] drm/amdgpu: Add logic for VF data exchange region to init from dynamic crit_region offsets
  2025-10-10  4:43 ` [PATCH 6/6] drm/amdgpu: Add logic for VF data exchange region " Ellen Pan
@ 2025-10-10 15:31   ` Alex Deucher
  0 siblings, 0 replies; 15+ messages in thread
From: Alex Deucher @ 2025-10-10 15:31 UTC (permalink / raw)
  To: Ellen Pan
  Cc: amd-gfx, Alexander.Deucher, Christian.Koenig, Lijo.Lazar,
	Jeffrey.Chan

On Fri, Oct 10, 2025 at 1:01 AM Ellen Pan <yunru.pan@amd.com> wrote:
>
> 1. Added VF logic to init data exchange region using the offsets from dynamic(v2) critical regions;
>
> Signed-off-by: Ellen Pan <yunru.pan@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 88 ++++++++++++++++++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h |  1 +
>  2 files changed, 77 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index 67d5f15a72a1..f96382fb0070 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -670,6 +670,8 @@ void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev)
>
>  void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
>  {
> +       uint32_t *pfvf_data = NULL;
> +
>         adev->virt.fw_reserve.p_pf2vf = NULL;
>         adev->virt.fw_reserve.p_vf2pf = NULL;
>         adev->virt.vf2pf_update_interval_ms = 0;
> @@ -685,11 +687,34 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
>                 schedule_delayed_work(&(adev->virt.vf2pf_work), msecs_to_jiffies(adev->virt.vf2pf_update_interval_ms));
>         } else if (adev->bios != NULL) {
>                 /* got through this logic in early init stage to get necessary flags, e.g. rlcg_acc related*/
> -               adev->virt.fw_reserve.p_pf2vf =
> -                       (struct amd_sriov_msg_pf2vf_info_header *)
> -                       (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
> +               if (adev->virt.req_init_data_ver == GPU_CRIT_REGION_V2) {
> +                       pfvf_data =
> +                               kzalloc(adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].size_kb << 10,
> +                                       GFP_KERNEL);
> +                       if (!pfvf_data) {
> +                               DRM_ERROR("Failed to allocate memory for pfvf_data\n");

dev_err()

> +                               return;
> +                       }
>
> -               amdgpu_virt_read_pf2vf_data(adev);
> +                       if (amdgpu_virt_read_exchange_data_from_mem(adev, pfvf_data))
> +                               goto free_pfvf_data;
> +
> +                       adev->virt.fw_reserve.p_pf2vf =
> +                               (struct amd_sriov_msg_pf2vf_info_header *)pfvf_data;
> +
> +                       amdgpu_virt_read_pf2vf_data(adev);
> +
> +free_pfvf_data:
> +                       kfree(pfvf_data);
> +                       pfvf_data = NULL;
> +                       adev->virt.fw_reserve.p_pf2vf = NULL;
> +               } else {
> +                       adev->virt.fw_reserve.p_pf2vf =
> +                               (struct amd_sriov_msg_pf2vf_info_header *)
> +                               (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
> +
> +                       amdgpu_virt_read_pf2vf_data(adev);
> +               }
>         }
>  }
>
> @@ -702,14 +727,29 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
>
>         if (adev->mman.fw_vram_usage_va || adev->mman.drv_vram_usage_va) {
>                 if (adev->mman.fw_vram_usage_va) {
> -                       adev->virt.fw_reserve.p_pf2vf =
> -                               (struct amd_sriov_msg_pf2vf_info_header *)
> -                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
> -                       adev->virt.fw_reserve.p_vf2pf =
> -                               (struct amd_sriov_msg_vf2pf_info_header *)
> -                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
> -                       adev->virt.fw_reserve.ras_telemetry =
> -                               (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
> +                       if (adev->virt.req_init_data_ver == GPU_CRIT_REGION_V2) {
> +                               adev->virt.fw_reserve.p_pf2vf =
> +                                       (struct amd_sriov_msg_pf2vf_info_header *)
> +                                       (adev->mman.fw_vram_usage_va +
> +                                       adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset);
> +                               adev->virt.fw_reserve.p_vf2pf =
> +                                       (struct amd_sriov_msg_vf2pf_info_header *)
> +                                       (adev->mman.fw_vram_usage_va +
> +                                       adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset +
> +                                       (AMD_SRIOV_MSG_SIZE_KB_V1 << 10));
> +                               adev->virt.fw_reserve.ras_telemetry =
> +                                       (adev->mman.fw_vram_usage_va +
> +                                       adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_RAS_TELEMETRY_TABLE_ID].offset);
> +                       } else {
> +                               adev->virt.fw_reserve.p_pf2vf =
> +                                       (struct amd_sriov_msg_pf2vf_info_header *)
> +                                       (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB_V1 << 10));
> +                               adev->virt.fw_reserve.p_vf2pf =
> +                                       (struct amd_sriov_msg_vf2pf_info_header *)
> +                                       (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_VF2PF_OFFSET_KB_V1 << 10));
> +                               adev->virt.fw_reserve.ras_telemetry =
> +                                       (adev->mman.fw_vram_usage_va + (AMD_SRIOV_MSG_RAS_TELEMETRY_OFFSET_KB_V1 << 10));
> +                       }
>                 } else if (adev->mman.drv_vram_usage_va) {
>                         adev->virt.fw_reserve.p_pf2vf =
>                                 (struct amd_sriov_msg_pf2vf_info_header *)
> @@ -1072,6 +1112,30 @@ bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev)
>         return true;
>  }
>
> +int amdgpu_virt_read_exchange_data_from_mem(struct amdgpu_device *adev, uint32_t *pfvf_data)

This can be static as it's not used outside this file.

> +{
> +       uint32_t dataexchange_offset =
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].offset;
> +       uint32_t dataexchange_size =
> +               adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_DATAEXCHANGE_TABLE_ID].size_kb << 10;
> +       uint64_t pos = 0;
> +
> +       dev_info(adev->dev,
> +                       "Got data exchange info from dynamic crit_region_table at offset 0x%x with size of 0x%x bytes.\n",
> +                       dataexchange_offset, dataexchange_size);
> +
> +       if (!IS_ALIGNED(dataexchange_offset, 4) || !IS_ALIGNED(dataexchange_size, 4)) {
> +               DRM_ERROR("Data exchange data not aligned to 4 bytes\n");

dev_err()

Alex

> +               return -EINVAL;
> +       }
> +
> +       pos = (uint64_t)dataexchange_offset;
> +       amdgpu_device_vram_access(adev, pos, pfvf_data,
> +                                       dataexchange_size, false);
> +
> +       return 0;
> +}
> +
>  void amdgpu_virt_init(struct amdgpu_device *adev)
>  {
>         bool is_sriov = false;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index f2aa306f4192..ae456bde6a5a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -440,6 +440,7 @@ void amdgpu_virt_init(struct amdgpu_device *adev);
>  int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
>  int amdgpu_virt_init_discovery_from_mem(struct amdgpu_device *adev, uint8_t *binary);
>  bool amdgpu_virt_read_bios_from_vram(struct amdgpu_device *adev);
> +int amdgpu_virt_read_exchange_data_from_mem(struct amdgpu_device *adev, uint32_t *pfvf_data);
>
>  bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
>  int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
> --
> 2.34.1
>

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

end of thread, other threads:[~2025-10-10 15:32 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-10  4:43 [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Ellen Pan
2025-10-10  4:43 ` [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan
2025-10-10  8:32   ` Christian König
2025-10-10 15:00   ` Alex Deucher
2025-10-10  4:43 ` [PATCH 3/6] drm/amdgpu: Introduce SRIOV critical regions v2 during VF init Ellen Pan
2025-10-10 15:04   ` Alex Deucher
2025-10-10  4:43 ` [PATCH 4/6] drm/amdgpu: Reuse fw_vram_usage_* for dynamic critical region in SRIOV Ellen Pan
2025-10-10 10:33   ` Lazar, Lijo
2025-10-10 15:10   ` Alex Deucher
2025-10-10  4:43 ` [PATCH 5/6] drm/amdgpu: Add logic for VF ipd and VF bios to init from dynamic crit_region offsets Ellen Pan
2025-10-10 10:46   ` Lazar, Lijo
2025-10-10  4:43 ` [PATCH 6/6] drm/amdgpu: Add logic for VF data exchange region " Ellen Pan
2025-10-10 15:31   ` Alex Deucher
2025-10-10 14:51 ` [PATCH 1/6] drm/amdgpu: Updated naming of SRIOV critical region offsets/sizes with _V1 suffix Alex Deucher
  -- strict thread matches above, loose matches on Subject: below --
2025-10-09  3:30 [PATCH 2/6] drm/amdgpu: Add SRIOV crit_region_version support Ellen Pan

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