<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Aptos;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:12.0pt;
        font-family:"Aptos",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Aptos",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Zhang, Jianxun <jianxun.zhang@intel.com>
<br>
<b>Sent:</b> Monday, March 3, 2025 12:23 PM<br>
<b>To:</b> Cavitt, Jonathan <jonathan.cavitt@intel.com>; intel-xe@lists.freedesktop.org<br>
<b>Cc:</b> Gupta, saurabhg <saurabhg.gupta@intel.com>; Zuo, Alex <alex.zuo@intel.com>; joonas.lahtinen@linux.intel.com; Brost, Matthew <matthew.brost@intel.com>; dri-devel@lists.freedesktop.org<br>
<b>Subject:</b> Re: [PATCH v3 6/6] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl<o:p></o:p></span></p>
</div>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="98%" align="center">
</div>
<div id="divRplyFwdMsg">
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black"> Cavitt, Jonathan <</span><a href="mailto:jonathan.cavitt@intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">jonathan.cavitt@intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">><br>
<b>Sent:</b> Friday, February 28, 2025 10:21 AM<br>
<b>To:</b> </span><a href="mailto:intel-xe@lists.freedesktop.org"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">intel-xe@lists.freedesktop.org</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black"> <</span><a href="mailto:intel-xe@lists.freedesktop.org"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">intel-xe@lists.freedesktop.org</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">><br>
<b>Cc:</b> Gupta, saurabhg <</span><a href="mailto:saurabhg.gupta@intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">saurabhg.gupta@intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">>; Zuo,
 Alex <</span><a href="mailto:alex.zuo@intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">alex.zuo@intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">>; Cavitt, Jonathan <</span><a href="mailto:jonathan.cavitt@intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">jonathan.cavitt@intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">>;
</span><a href="mailto:joonas.lahtinen@linux.intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">joonas.lahtinen@linux.intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black"> <</span><a href="mailto:joonas.lahtinen@linux.intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">joonas.lahtinen@linux.intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">>;
 Brost, Matthew <</span><a href="mailto:matthew.brost@intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">matthew.brost@intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">>; Zhang, Jianxun
 <</span><a href="mailto:jianxun.zhang@intel.com"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">jianxun.zhang@intel.com</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">>;
</span><a href="mailto:dri-devel@lists.freedesktop.org"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">dri-devel@lists.freedesktop.org</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black"> <</span><a href="mailto:dri-devel@lists.freedesktop.org"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">dri-devel@lists.freedesktop.org</span></a><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">><br>
<b>Subject:</b> [PATCH v3 6/6] drm/xe/xe_vm: Implement xe_vm_get_property_ioctl</span>
<o:p></o:p></p>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">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>
Signed-off-by: Jonathan Cavitt <</span><a href="mailto:jonathan.cavitt@intel.com"><span style="font-size:11.0pt">jonathan.cavitt@intel.com</span></a><span style="font-size:11.0pt">><br>
Suggested-by: Matthew Brost <</span><a href="mailto:matthew.brost@intel.com"><span style="font-size:11.0pt">matthew.brost@intel.com</span></a><span style="font-size:11.0pt">><br>
---<br>
 drivers/gpu/drm/xe/xe_device.c |  3 ++<br>
 drivers/gpu/drm/xe/xe_vm.c     | 79 ++++++++++++++++++++++++++++++++++<br>
 drivers/gpu/drm/xe/xe_vm.h     |  2 +<br>
 3 files changed, 84 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..00d2c62ccf53 100644<br>
--- a/drivers/gpu/drm/xe/xe_vm.c<br>
+++ b/drivers/gpu/drm/xe/xe_vm.c<br>
@@ -3234,6 +3234,85 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)<br>
         return err;<br>
 }<br>
 <br>
+static u32 xe_vm_get_property_size(struct xe_vm *vm, u32 property)<br>
+{<br>
+       u32 size = 0;<br>
+<br>
+       switch (property) {<br>
+       case DRM_XE_VM_GET_PROPERTY_FAULTS:<br>
+               spin_lock(&vm->pfs.lock);<br>
+               size = vm->pfs.len * sizeof(struct drm_xe_pf);<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">+               spin_unlock(&vm->pfs.lock);<br>
+               return size;<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>
+                            u32 size)<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 i = 0;<br>
+<br>
+       if (copy_from_user(&fault_list, usr_ptr, size))<br>
+               return -EFAULT;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">> Why is copying from user space memory needed in this query ioctl?<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">> Does copy_from_<span style="color:black">user() automatically allocate kernel memory for fault_list?</span><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Hrmm… No, you have a point.  It probably isn’t necessary to copy the memory<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">from userspace if we don’t need to read anything from it.  Though I’m fairly certain<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">it does automatically allocate kernel memory for the fault_list, as we do similar<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">things in xe_query.c without allocating memory for first pointer.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">+<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 = SZ_4K;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">> If we can get the exact address, the precision should be 1, right?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">> (</span><a href="https://registry.khronos.org/vulkan/specs/latest/man/html/VkDeviceFaultAddressInfoEXT.html"><span style="font-size:11.0pt">https://registry.khronos.org/vulkan/specs/latest/man/html/VkDeviceFaultAddressInfoEXT.html</span></a><span style="font-size:11.0pt;color:black">)</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I… don’t know, actually.  That question would be better answered by Matthew Brost, I think.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I’ll change it to 1 for v3.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt"><br>
+       }<br>
+       spin_unlock(&vm->pfs.lock);<br>
+<br>
+       if (copy_to_user(usr_ptr, &fault_list, size))<br>
+               return -EFAULT;<br>
+<br>
+       return 0;<br>
+}<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>
+       u32 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;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">> <span style="color:black">If there is a change in the size of property between the first and the second calls, say, more faults added in this case, the 2<sup>nd</sup> call will fail unintendedly. </span><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I suppose the alternative would be to ask userspace to allocate memory for the maximum<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">possible number of pagefaults, then return the number of pagefaults in “value” while saving<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">the pagefaults to “*ptr”.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Hmm… Give me a moment to see what that would look like…<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">-Jonathan Cavitt<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">+               args->size = size;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:11.0pt;font-family:"Arial",sans-serif;color:black">​</span><span style="font-size:11.0pt;color:black">+               return 0;<br>
+       }<br>
+<br>
+       switch (args->property) {<br>
+       case DRM_XE_VM_GET_PROPERTY_FAULTS:<br>
+               return fill_property_pfs(vm, args, size);<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<o:p></o:p></span></p>
</div>
</div>
</body>
</html>