<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<hr style="display: inline-block; width: 98%;">
<div id="divRplyFwdMsg" dir="ltr"><span style="font-family: Calibri, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);"><b>From:</b> Cavitt, Jonathan <jonathan.cavitt@intel.com><br>
<b>Sent:</b> Tuesday, March 4, 2025 9:08 AM<br>
<b>To:</b> intel-xe@lists.freedesktop.org <intel-xe@lists.freedesktop.org><br>
<b>Cc:</b> Gupta, saurabhg <saurabhg.gupta@intel.com>; Zuo, Alex <alex.zuo@intel.com>; Cavitt, Jonathan <jonathan.cavitt@intel.com>; joonas.lahtinen@linux.intel.com <joonas.lahtinen@linux.intel.com>; Brost, Matthew <matthew.brost@intel.com>; Zhang, Jianxun
 <jianxun.zhang@intel.com>; Lin, Shuicheng <shuicheng.lin@intel.com>; dri-devel@lists.freedesktop.org <dri-devel@lists.freedesktop.org><br>
<b>Subject:</b> [PATCH v5 6/6] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl</span>
<div> </div>
</div>
<div class="elementToProof" style="font-size: 11pt;">Add support for userspace to request a list of observed failed<br>
pagefaults from a specified VM.<br>
<br>
v2:<br>
- Only allow querying of failed pagefaults (Matt Brost)<br>
<br>
v3:<br>
- Remove unnecessary size parameter from helper function, as it<br>
  is a property of the arguments. (jcavitt)<br>
- Remove unnecessary copy_from_user (Jainxun)<br>
- Set address_precision to 1 (Jainxun)<br>
- Report max size instead of dynamic size for memory allocation<br>
  purposes.  Total memory usage is reported separately.<br>
<br>
v4:<br>
- Return int from xe_vm_get_property_size (Shuicheng)<br>
- Fix memory leak (Shuicheng)<br>
- Remove unnecessary size variable (jcavitt)<br>
<br>
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com><br>
Suggested-by: Matthew Brost <matthew.brost@intel.com><br>
CC: Jainxun Zhang <jianxun.zhang@intel.com><br>
CC: Shuicheng Lin <shuicheng.lin@intel.com><br>
---<br>
 drivers/gpu/drm/xe/xe_device.c |  3 ++<br>
 drivers/gpu/drm/xe/xe_vm.c     | 75 ++++++++++++++++++++++++++++++++++<br>
 drivers/gpu/drm/xe/xe_vm.h     |  2 +<br>
 3 files changed, 80 insertions(+)<br>
<br>
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c<br>
index 9454b51f7ad8..43accae152ff 100644<br>
--- a/drivers/gpu/drm/xe/xe_device.c<br>
+++ b/drivers/gpu/drm/xe/xe_device.c<br>
@@ -193,6 +193,9 @@ static const struct drm_ioctl_desc xe_ioctls[] = {<br>
         DRM_IOCTL_DEF_DRV(XE_WAIT_USER_FENCE, xe_wait_user_fence_ioctl,<br>
                           DRM_RENDER_ALLOW),<br>
         DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),<br>
+       DRM_IOCTL_DEF_DRV(XE_VM_GET_PROPERTY, xe_vm_get_property_ioctl,<br>
+                         DRM_RENDER_ALLOW),<br>
+<br>
 };<br>
 <br>
 static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)<br>
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c<br>
index 6211b971bbbd..1e78103fb0f6 100644<br>
--- a/drivers/gpu/drm/xe/xe_vm.c<br>
+++ b/drivers/gpu/drm/xe/xe_vm.c<br>
@@ -3234,6 +3234,81 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)<br>
         return err;<br>
 }<br>
 <br>
+static int xe_vm_get_property_size(struct xe_vm *vm, u32 property)<br>
+{<br>
+       switch (property) {<br>
+       case DRM_XE_VM_GET_PROPERTY_FAULTS:<br>
+               return MAX_PFS * sizeof(struct drm_xe_pf);</div>
<div class="elementToProof" style="font-size: 11pt;">I still think returning the number of faults back to user space is better and clearer. But the intention is to use this ioctl on any properties, so perhaps it is why a size in byte is chosen.</div>
<div class="elementToProof" style="font-size: 11pt;"><br>
</div>
<div class="elementToProof" style="font-size: 11pt;">But first of all, should we regard faults as a property?</div>
<div class="elementToProof" style="font-size: 11pt;"><br>
+       default:<br>
+               return -EINVAL;<br>
+       }<br>
+}<br>
+<br>
+static int fill_property_pfs(struct xe_vm *vm,<br>
+                            struct drm_xe_vm_get_property *args)<br>
+{<br>
+       struct drm_xe_pf __user *usr_ptr = u64_to_user_ptr(args->ptr);<br>
+       struct drm_xe_pf *fault_list;<br>
+       struct drm_xe_pf *fault;<br>
+       struct xe_vm_pf_entry *entry;<br>
+       int ret, i = 0;<br>
+<br>
+       fault_list = kzalloc(args->size, GFP_KERNEL);<br>
+       if (!fault_list)<br>
+               return -ENOMEM;<br>
+<br>
+       spin_lock(&vm->pfs.lock);<br>
+       list_for_each_entry(entry, &vm->pfs.list, list) {<br>
+               struct xe_pagefault *pf = entry->pf;<br>
+<br>
+               fault = &fault_list[i++];<br>
+               fault->address = pf->page_addr;<br>
+               fault->address_type = pf->address_type;<br>
+               fault->address_precision = 1;<br>
+       }<br>
+       args->value = vm->pfs.len;<br>
+       spin_unlock(&vm->pfs.lock);<br>
+<br>
+       ret = copy_to_user(usr_ptr, &fault_list, args->size);<br>
+       kfree(fault_list);<br>
+<br>
+       return ret ? -EFAULT : 0;<br>
+}</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
How about this to get rid of fault_list? The assumption is put_user is sufficient on types of data to return. It also deletes the copied data though KMD may still want to  keep them.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
This is Just an idea, It makes copied size is unclear so more refactor would be needed.)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
static int fill_property_pfs(struct xe_vm *vm,</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
                       struct drm_xe_vm_get_property *args)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
{</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      struct drm_xe_pf __user *usr_ptr = u64_to_user_ptr(args->ptr);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      struct xe_vm_pf_entry *entry;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      struct xe_vm_pf_entry *tmp_entry;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      int ret = 0;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      spin_lock(&vm->pfs.lock);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      list_for_each_entry_safe(entry, tmp_entry,  &vm->pfs.list, list)  {</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            ret = put_user(entry->pf->page_addr, &usr_ptr->address);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            if (ret)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
                  break;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            ret = put_user(entry->pf->address_type, &usr_ptr->address_type);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            if (ret)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
                  break;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            ret = put_user(1, &usr_ptr->address_precision);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            if (ret)</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
                  break;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            usr_ptr++;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
            list_del(entry->list);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      }</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      spin_unlock(&vm->pfs.lock);</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
      return ret;</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
}</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-size: 11pt;"><br>
+<br>
+int xe_vm_get_property_ioctl(struct drm_device *drm, void *data,<br>
+                            struct drm_file *file)<br>
+{<br>
+       struct xe_device *xe = to_xe_device(drm);<br>
+       struct xe_file *xef = to_xe_file(file);<br>
+       struct drm_xe_vm_get_property *args = data;<br>
+       struct xe_vm *vm;<br>
+       int size;<br>
+<br>
+       if (XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))<br>
+               return -EINVAL;<br>
+<br>
+       vm = xe_vm_lookup(xef, args->vm_id);<br>
+       if (XE_IOCTL_DBG(xe, !vm))<br>
+               return -ENOENT;<br>
+<br>
+       size = xe_vm_get_property_size(vm, args->property);<br>
+       if (size < 0) {<br>
+               return size;<br>
+       } else if (args->size != size) {<br>
+               if (args->size)<br>
+                       return -EINVAL;<br>
+               args->size = size;<br>
+               return 0;<br>
+       }<br>
+<br>
+       switch (args->property) {<br>
+       case DRM_XE_VM_GET_PROPERTY_FAULTS:<br>
+               return fill_property_pfs(vm, args);<br>
+       default:<br>
+               return -EINVAL;<br>
+       }<br>
+}<br>
+<br>
 /**<br>
  * xe_vm_bind_kernel_bo - bind a kernel BO to a VM<br>
  * @vm: VM to bind the BO to<br>
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h<br>
index 4d94ab5c8ea4..bf6604465aa3 100644<br>
--- a/drivers/gpu/drm/xe/xe_vm.h<br>
+++ b/drivers/gpu/drm/xe/xe_vm.h<br>
@@ -184,6 +184,8 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,<br>
                         struct drm_file *file);<br>
 int xe_vm_bind_ioctl(struct drm_device *dev, void *data,<br>
                      struct drm_file *file);<br>
+int xe_vm_get_property_ioctl(struct drm_device *dev, void *data,<br>
+                            struct drm_file *file);<br>
 <br>
 void xe_vm_close_and_put(struct xe_vm *vm);<br>
 <br>
--<br>
2.43.0<br>
<br>
</div>
</body>
</html>