[PATCH v2 18/26] drm/xe/pf: Add helpers for VF MMIO migration data handling

Michał Winiarski posted 26 patches 3 months, 2 weeks ago
There is a newer version of this series
[PATCH v2 18/26] drm/xe/pf: Add helpers for VF MMIO migration data handling
Posted by Michał Winiarski 3 months, 2 weeks ago
In an upcoming change, the VF MMIO migration data will be handled as
part of VF control state machine. Add the necessary helpers to allow the
migration data transfer to/from the VF MMIO registers.

Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
---
 drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 88 +++++++++++++++++++++++++++++
 drivers/gpu/drm/xe/xe_gt_sriov_pf.h |  6 ++
 2 files changed, 94 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
index c4dda87b47cc8..31ee86166dfd0 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
@@ -194,6 +194,94 @@ static void pf_clear_vf_scratch_regs(struct xe_gt *gt, unsigned int vfid)
 	}
 }
 
+/**
+ * xe_gt_sriov_pf_mmio_vf_size - Get the size of VF MMIO register data.
+ * @gt: the &xe_gt
+ * @vfid: VF identifier
+ *
+ * Return: size in bytes.
+ */
+size_t xe_gt_sriov_pf_mmio_vf_size(struct xe_gt *gt, unsigned int vfid)
+{
+	if (xe_gt_is_media_type(gt))
+		return MED_VF_SW_FLAG_COUNT * sizeof(u32);
+	else
+		return VF_SW_FLAG_COUNT * sizeof(u32);
+}
+
+/**
+ * xe_gt_sriov_pf_mmio_vf_save - Save VF MMIO register values to a buffer.
+ * @gt: the &xe_gt
+ * @vfid: VF identifier
+ * @buf: destination buffer
+ * @size: destination buffer size in bytes
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int xe_gt_sriov_pf_mmio_vf_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size)
+{
+	u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt));
+	struct xe_reg scratch;
+	u32 *regs = buf;
+	int n, count;
+
+	if (size != xe_gt_sriov_pf_mmio_vf_size(gt, vfid))
+		return -EINVAL;
+
+	if (xe_gt_is_media_type(gt)) {
+		count = MED_VF_SW_FLAG_COUNT;
+		for (n = 0; n < count; n++) {
+			scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride);
+			regs[n] = xe_mmio_read32(&gt->mmio, scratch);
+		}
+	} else {
+		count = VF_SW_FLAG_COUNT;
+		for (n = 0; n < count; n++) {
+			scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride);
+			regs[n] = xe_mmio_read32(&gt->mmio, scratch);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * xe_gt_sriov_pf_mmio_vf_restore - Restore VF MMIO register values from a buffer.
+ * @gt: the &xe_gt
+ * @vfid: VF identifier
+ * @buf: source buffer
+ * @size: source buffer size in bytes
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int xe_gt_sriov_pf_mmio_vf_restore(struct xe_gt *gt, unsigned int vfid,
+				   const void *buf, size_t size)
+{
+	u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt));
+	const u32 *regs = buf;
+	struct xe_reg scratch;
+	int n, count;
+
+	if (size != xe_gt_sriov_pf_mmio_vf_size(gt, vfid))
+		return -EINVAL;
+
+	if (xe_gt_is_media_type(gt)) {
+		count = MED_VF_SW_FLAG_COUNT;
+		for (n = 0; n < count; n++) {
+			scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride);
+			xe_mmio_write32(&gt->mmio, scratch, regs[n]);
+		}
+	} else {
+		count = VF_SW_FLAG_COUNT;
+		for (n = 0; n < count; n++) {
+			scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride);
+			xe_mmio_write32(&gt->mmio, scratch, regs[n]);
+		}
+	}
+
+	return 0;
+}
+
 /**
  * xe_gt_sriov_pf_sanitize_hw() - Reset hardware state related to a VF.
  * @gt: the &xe_gt
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
index e7fde3f9937af..7f4f1fda5f77a 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
@@ -6,6 +6,8 @@
 #ifndef _XE_GT_SRIOV_PF_H_
 #define _XE_GT_SRIOV_PF_H_
 
+#include <linux/types.h>
+
 struct xe_gt;
 
 #ifdef CONFIG_PCI_IOV
@@ -16,6 +18,10 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt);
 void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid);
 void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt);
 void xe_gt_sriov_pf_restart(struct xe_gt *gt);
+size_t xe_gt_sriov_pf_mmio_vf_size(struct xe_gt *gt, unsigned int vfid);
+int xe_gt_sriov_pf_mmio_vf_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size);
+int xe_gt_sriov_pf_mmio_vf_restore(struct xe_gt *gt, unsigned int vfid,
+				   const void *buf, size_t size);
 #else
 static inline int xe_gt_sriov_pf_init_early(struct xe_gt *gt)
 {
-- 
2.50.1

Re: [PATCH v2 18/26] drm/xe/pf: Add helpers for VF MMIO migration data handling
Posted by Michal Wajdeczko 3 months, 2 weeks ago

On 10/22/2025 12:41 AM, Michał Winiarski wrote:
> In an upcoming change, the VF MMIO migration data will be handled as
> part of VF control state machine. Add the necessary helpers to allow the
> migration data transfer to/from the VF MMIO registers.
> 
> Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
> ---
>  drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 88 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/xe/xe_gt_sriov_pf.h |  6 ++

wrong place for those helpers

just promote xe_reg_vf_to_pf()

or maybe it can be done like this:

	void xe_mmio_init_vf(struct xe_mmio *vf, const struct xe_mmio *pf, vfid);

then

	struct xe_mmio mmio_vf;

	xe_mmio_init_vf(&mmio_vf, &gt->mmio, vfid);
	val = xe_mmio_read32(&mmio_vf, REG);
	xe_mmio_write32(&mmio_vf, val, REG);

let me try check this out


>  2 files changed, 94 insertions(+)
> 
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
> index c4dda87b47cc8..31ee86166dfd0 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
> @@ -194,6 +194,94 @@ static void pf_clear_vf_scratch_regs(struct xe_gt *gt, unsigned int vfid)
>  	}
>  }
>  
> +/**
> + * xe_gt_sriov_pf_mmio_vf_size - Get the size of VF MMIO register data.
> + * @gt: the &xe_gt
> + * @vfid: VF identifier
> + *
> + * Return: size in bytes.
> + */
> +size_t xe_gt_sriov_pf_mmio_vf_size(struct xe_gt *gt, unsigned int vfid)
> +{
> +	if (xe_gt_is_media_type(gt))
> +		return MED_VF_SW_FLAG_COUNT * sizeof(u32);
> +	else
> +		return VF_SW_FLAG_COUNT * sizeof(u32);
> +}
> +
> +/**
> + * xe_gt_sriov_pf_mmio_vf_save - Save VF MMIO register values to a buffer.
> + * @gt: the &xe_gt
> + * @vfid: VF identifier
> + * @buf: destination buffer
> + * @size: destination buffer size in bytes
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_mmio_vf_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size)
> +{
> +	u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt));
> +	struct xe_reg scratch;
> +	u32 *regs = buf;
> +	int n, count;
> +
> +	if (size != xe_gt_sriov_pf_mmio_vf_size(gt, vfid))
> +		return -EINVAL;
> +
> +	if (xe_gt_is_media_type(gt)) {
> +		count = MED_VF_SW_FLAG_COUNT;
> +		for (n = 0; n < count; n++) {
> +			scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride);
> +			regs[n] = xe_mmio_read32(&gt->mmio, scratch);
> +		}
> +	} else {
> +		count = VF_SW_FLAG_COUNT;
> +		for (n = 0; n < count; n++) {
> +			scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride);
> +			regs[n] = xe_mmio_read32(&gt->mmio, scratch);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * xe_gt_sriov_pf_mmio_vf_restore - Restore VF MMIO register values from a buffer.
> + * @gt: the &xe_gt
> + * @vfid: VF identifier
> + * @buf: source buffer
> + * @size: source buffer size in bytes
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_mmio_vf_restore(struct xe_gt *gt, unsigned int vfid,
> +				   const void *buf, size_t size)
> +{
> +	u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt));
> +	const u32 *regs = buf;
> +	struct xe_reg scratch;
> +	int n, count;
> +
> +	if (size != xe_gt_sriov_pf_mmio_vf_size(gt, vfid))
> +		return -EINVAL;
> +
> +	if (xe_gt_is_media_type(gt)) {
> +		count = MED_VF_SW_FLAG_COUNT;
> +		for (n = 0; n < count; n++) {
> +			scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride);
> +			xe_mmio_write32(&gt->mmio, scratch, regs[n]);
> +		}
> +	} else {
> +		count = VF_SW_FLAG_COUNT;
> +		for (n = 0; n < count; n++) {
> +			scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride);
> +			xe_mmio_write32(&gt->mmio, scratch, regs[n]);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * xe_gt_sriov_pf_sanitize_hw() - Reset hardware state related to a VF.
>   * @gt: the &xe_gt
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
> index e7fde3f9937af..7f4f1fda5f77a 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
> @@ -6,6 +6,8 @@
>  #ifndef _XE_GT_SRIOV_PF_H_
>  #define _XE_GT_SRIOV_PF_H_
>  
> +#include <linux/types.h>
> +
>  struct xe_gt;
>  
>  #ifdef CONFIG_PCI_IOV
> @@ -16,6 +18,10 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt);
>  void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid);
>  void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt);
>  void xe_gt_sriov_pf_restart(struct xe_gt *gt);
> +size_t xe_gt_sriov_pf_mmio_vf_size(struct xe_gt *gt, unsigned int vfid);
> +int xe_gt_sriov_pf_mmio_vf_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size);
> +int xe_gt_sriov_pf_mmio_vf_restore(struct xe_gt *gt, unsigned int vfid,
> +				   const void *buf, size_t size);
>  #else
>  static inline int xe_gt_sriov_pf_init_early(struct xe_gt *gt)
>  {

Re: [PATCH v2 18/26] drm/xe/pf: Add helpers for VF MMIO migration data handling
Posted by Michał Winiarski 3 months, 1 week ago
On Fri, Oct 24, 2025 at 12:10:31AM +0200, Michal Wajdeczko wrote:
> 
> 
> On 10/22/2025 12:41 AM, Michał Winiarski wrote:
> > In an upcoming change, the VF MMIO migration data will be handled as
> > part of VF control state machine. Add the necessary helpers to allow the
> > migration data transfer to/from the VF MMIO registers.
> > 
> > Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
> > ---
> >  drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 88 +++++++++++++++++++++++++++++
> >  drivers/gpu/drm/xe/xe_gt_sriov_pf.h |  6 ++
> 
> wrong place for those helpers
> 
> just promote xe_reg_vf_to_pf()
> 
> or maybe it can be done like this:
> 
> 	void xe_mmio_init_vf(struct xe_mmio *vf, const struct xe_mmio *pf, vfid);
> 
> then
> 
> 	struct xe_mmio mmio_vf;
> 
> 	xe_mmio_init_vf(&mmio_vf, &gt->mmio, vfid);
> 	val = xe_mmio_read32(&mmio_vf, REG);
> 	xe_mmio_write32(&mmio_vf, val, REG);
> 
> let me try check this out

With:
4504e78068924 ("drm/xe/pf: Access VF's register using dedicated MMIO view")

The helpers are somewhat no longer necessary.
I'll move the logic to xe_gt_sriov_pf_migration.c and drop this patch
completely, moving everything into:
drm/xe/pf: Handle MMIO migration data as part of PF control

Thanks,
-Michał

> 
> 
> >  2 files changed, 94 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
> > index c4dda87b47cc8..31ee86166dfd0 100644
> > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
> > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c
> > @@ -194,6 +194,94 @@ static void pf_clear_vf_scratch_regs(struct xe_gt *gt, unsigned int vfid)
> >  	}
> >  }
> >  
> > +/**
> > + * xe_gt_sriov_pf_mmio_vf_size - Get the size of VF MMIO register data.
> > + * @gt: the &xe_gt
> > + * @vfid: VF identifier
> > + *
> > + * Return: size in bytes.
> > + */
> > +size_t xe_gt_sriov_pf_mmio_vf_size(struct xe_gt *gt, unsigned int vfid)
> > +{
> > +	if (xe_gt_is_media_type(gt))
> > +		return MED_VF_SW_FLAG_COUNT * sizeof(u32);
> > +	else
> > +		return VF_SW_FLAG_COUNT * sizeof(u32);
> > +}
> > +
> > +/**
> > + * xe_gt_sriov_pf_mmio_vf_save - Save VF MMIO register values to a buffer.
> > + * @gt: the &xe_gt
> > + * @vfid: VF identifier
> > + * @buf: destination buffer
> > + * @size: destination buffer size in bytes
> > + *
> > + * Return: 0 on success or a negative error code on failure.
> > + */
> > +int xe_gt_sriov_pf_mmio_vf_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size)
> > +{
> > +	u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt));
> > +	struct xe_reg scratch;
> > +	u32 *regs = buf;
> > +	int n, count;
> > +
> > +	if (size != xe_gt_sriov_pf_mmio_vf_size(gt, vfid))
> > +		return -EINVAL;
> > +
> > +	if (xe_gt_is_media_type(gt)) {
> > +		count = MED_VF_SW_FLAG_COUNT;
> > +		for (n = 0; n < count; n++) {
> > +			scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride);
> > +			regs[n] = xe_mmio_read32(&gt->mmio, scratch);
> > +		}
> > +	} else {
> > +		count = VF_SW_FLAG_COUNT;
> > +		for (n = 0; n < count; n++) {
> > +			scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride);
> > +			regs[n] = xe_mmio_read32(&gt->mmio, scratch);
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * xe_gt_sriov_pf_mmio_vf_restore - Restore VF MMIO register values from a buffer.
> > + * @gt: the &xe_gt
> > + * @vfid: VF identifier
> > + * @buf: source buffer
> > + * @size: source buffer size in bytes
> > + *
> > + * Return: 0 on success or a negative error code on failure.
> > + */
> > +int xe_gt_sriov_pf_mmio_vf_restore(struct xe_gt *gt, unsigned int vfid,
> > +				   const void *buf, size_t size)
> > +{
> > +	u32 stride = pf_get_vf_regs_stride(gt_to_xe(gt));
> > +	const u32 *regs = buf;
> > +	struct xe_reg scratch;
> > +	int n, count;
> > +
> > +	if (size != xe_gt_sriov_pf_mmio_vf_size(gt, vfid))
> > +		return -EINVAL;
> > +
> > +	if (xe_gt_is_media_type(gt)) {
> > +		count = MED_VF_SW_FLAG_COUNT;
> > +		for (n = 0; n < count; n++) {
> > +			scratch = xe_reg_vf_to_pf(MED_VF_SW_FLAG(n), vfid, stride);
> > +			xe_mmio_write32(&gt->mmio, scratch, regs[n]);
> > +		}
> > +	} else {
> > +		count = VF_SW_FLAG_COUNT;
> > +		for (n = 0; n < count; n++) {
> > +			scratch = xe_reg_vf_to_pf(VF_SW_FLAG(n), vfid, stride);
> > +			xe_mmio_write32(&gt->mmio, scratch, regs[n]);
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * xe_gt_sriov_pf_sanitize_hw() - Reset hardware state related to a VF.
> >   * @gt: the &xe_gt
> > diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
> > index e7fde3f9937af..7f4f1fda5f77a 100644
> > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
> > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h
> > @@ -6,6 +6,8 @@
> >  #ifndef _XE_GT_SRIOV_PF_H_
> >  #define _XE_GT_SRIOV_PF_H_
> >  
> > +#include <linux/types.h>
> > +
> >  struct xe_gt;
> >  
> >  #ifdef CONFIG_PCI_IOV
> > @@ -16,6 +18,10 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt);
> >  void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid);
> >  void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt);
> >  void xe_gt_sriov_pf_restart(struct xe_gt *gt);
> > +size_t xe_gt_sriov_pf_mmio_vf_size(struct xe_gt *gt, unsigned int vfid);
> > +int xe_gt_sriov_pf_mmio_vf_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size);
> > +int xe_gt_sriov_pf_mmio_vf_restore(struct xe_gt *gt, unsigned int vfid,
> > +				   const void *buf, size_t size);
> >  #else
> >  static inline int xe_gt_sriov_pf_init_early(struct xe_gt *gt)
> >  {
>