<html>
<head>
<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;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.hoenzb
        {mso-style-name:hoenzb;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@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>
<div style="color: black;">
<div style="color: black;">
<p style="margin: 0 0 1em 0; color: black;">In either case, please either map in both or pread/write in both.</p>
</div>
<div style="color: black;">
<p style="color: black; font-size: 10pt; font-family: Arial, sans-serif; margin: 10pt 0;">On January 26, 2018 10:01:07 Jason Ekstrand <jason@jlekstrand.net> wrote:</p>
<blockquote type="cite" class="gmail_quote" style="margin: 0 0 0 0.75ex; border-left: 1px solid #808080; padding-left: 0.75ex;">
<div style="color: black;">
<div style="color: black;">
<p style="margin: 0 0 1em 0; color: black;">I wasn't suggesting that you use pread *instead* of stalling.  But once you've stalled, nothing will be touching it.  There is the possibility of another context or process of it's shared but mapping won't protect you from that either.  I don't know what Chris was getting at.</p>
</div>
<div style="color: black;">
<p style="color: black; font-size: 10pt; font-family: Arial, sans-serif; margin: 10pt 0;">On January 26, 2018 03:51:36 "Rogovin, Kevin" <kevin.rogovin@intel.com> wrote:</p>
<blockquote type="cite" class="gmail_quote" style="margin: 0 0 0 0.75ex; border-left: 1px solid #808080; padding-left: 0.75ex;">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US">Hi,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US">The main reason I went with map and invalidate is because the kernel on pread will only wait on execbuffer2 calls that
 declare they are going to write to the given GEM; <a name="_MailEndCompose"> there is the off-chance that a wild write might hit the padding of a GEM and the function contract is to check the padding. This is following the review comments from Chris Wilson.<o:p></o:p></a></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US">-Kevin<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><a name="_____replyseparator"></a><b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Jason Ekstrand [mailto:jason@jlekstrand.net]
<br>
<b>Sent:</b> Friday, January 26, 2018 12:13 PM<br>
<b>To:</b> Rogovin, Kevin <kevin.rogovin@intel.com><br>
<b>Cc:</b> ML mesa-dev <mesa-dev@lists.freedesktop.org><br>
<b>Subject:</b> Re: [Mesa-dev] [PATCH v3 2/3] i965: add noise padding to buffer object and function to check if noise is correct<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<div>
<div>
<div>
<p class="MsoNormal">On Fri, Jan 26, 2018 at 12:56 AM, <<a href="mailto:kevin.rogovin@intel.com" target="_blank">kevin.rogovin@intel.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">From: Kevin Rogovin <<a href="mailto:kevin.rogovin@intel.com">kevin.rogovin@intel.com</a>><br>
<br>
Signed-off-by: Kevin Rogovin <<a href="mailto:kevin.rogovin@intel.com">kevin.rogovin@intel.com</a>><br>
Reviewed-by: Chris Wilson <<a href="mailto:chris@chris-wilson.co.uk">chris@chris-wilson.co.uk</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_bufmgr.c | 115 ++++++++++++++++++++++++++++++++-<br>
 src/mesa/drivers/dri/i965/brw_bufmgr.h |  13 ++++<br>
 2 files changed, 127 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c<br>
index fb180289a0..7e50ba512e 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c<br>
@@ -220,6 +220,39 @@ bucket_for_size(struct brw_bufmgr *bufmgr, uint64_t size)<br>
           &bufmgr->cache_bucket[index] : NULL;<br>
 }<br>
<br>
+/* Our goal is not to have noise good enough for cryto,<br>
+ * but instead values that are unique-ish enough that<br>
+ * it is incredibly unlikely that a buffer overwrite<br>
+ * will produce the exact same values.<br>
+ */<br>
+static uint8_t<br>
+next_noise_value(uint8_t prev_noise)<br>
+{<br>
+   uint32_t v = prev_noise;<br>
+   return (v * 103u + 227u) & 0xFF;<br>
+}<br>
+<br>
+static void<br>
+fill_noise_buffer(uint8_t *dst, uint8_t start, uint32_t length)<br>
+{<br>
+   for(uint32_t i = 0; i < length; ++i) {<br>
+      dst[i] = start;<br>
+      start = next_noise_value(start);<br>
+   }<br>
+}<br>
+<br>
+static uint8_t*<br>
+generate_noise_buffer(uint8_t start, uint32_t length)<br>
+{<br>
+   uint8_t *return_value;<br>
+   return_value = malloc(length);<br>
+   if (return_value) {<br>
+      fill_noise_buffer(return_value, start, length);<br>
+   }<br>
+<br>
+   return return_value;<br>
+}<br>
+<br>
 int<br>
 brw_bo_busy(struct brw_bo *bo)<br>
 {<br>
@@ -367,7 +400,18 @@ retry:<br>
       bo->size = bo_size;<br>
       bo->idle = true;<br>
<br>
-      struct drm_i915_gem_create create = { .size = bo_size };<br>
+      bo->padding_size = 0;<br>
+      if (unlikely(INTEL_DEBUG & DEBUG_OUT_OF_BOUND_CHK)) {<br>
+         /* TODO: we want to make sure that the padding forces<br>
+          * the BO to take another page on the (PP)GTT; 4KB<br>
+          * may or may not be the page size for the GEM. Indeed,<br>
+          * depending on generation, kernel version and GEM size,<br>
+          * the page size can be one of 4KB, 64KB or 2M.<br>
+          */<br>
+         bo->padding_size = 4096;<br>
+      }<br>
+<br>
+      struct drm_i915_gem_create create = { .size = bo_size + bo->padding_size };<br>
<br>
       /* All new BOs we get from the kernel are zeroed, so we don't need to<br>
        * worry about that here.<br>
@@ -378,6 +422,27 @@ retry:<br>
          goto err;<br>
       }<br>
<br>
+      if (unlikely(bo->padding_size > 0)) {<br>
+         uint8_t *noise_values;<br>
+         struct drm_i915_gem_pwrite pwrite;<br>
+<br>
+         noise_values = generate_noise_buffer(create.handle, bo->padding_size);<br>
+         if (!noise_values)<br>
+            goto err_free;<br>
+<br>
+         pwrite.handle = create.handle;<br>
+         pwrite.pad = 0;<br>
+         pwrite.offset = bo_size;<br>
+         pwrite.size = bo->padding_size;<br>
+         pwrite.data_ptr = (__u64) (uintptr_t) noise_values;<br>
+<br>
+         ret = drmIoctl(bufmgr->fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite);<br>
+         free(noise_values);<br>
+<br>
+         if (ret != 0)<br>
+            goto err_free;<br>
+      }<br>
+<br>
       bo->gem_handle = create.handle;<br>
<br>
       bo->bufmgr = bufmgr;<br>
@@ -424,6 +489,53 @@ err:<br>
    return NULL;<br>
 }<br>
<br>
+bool<br>
+brw_bo_padding_is_good(struct brw_bo *bo)<br>
+{<br>
+   if (bo->padding_size > 0) {<br>
+      struct drm_i915_gem_mmap mmap_arg = {<br>
+         .handle = bo->gem_handle,<br>
+         .offset = bo->size,<br>
+         .size = bo->padding_size,<br>
+         .flags = 0,<br>
+      };<br>
+      uint8_t *mapped;<br>
+      int ret;<br>
+      uint8_t expected_value;<br>
+<br>
+      /* We cannot use brw_bo_map() because it maps precisely the range<br>
+       * [0, bo->size) and we wish to map the range of the padding which<br>
+       * is [bo->size, bo->size + bo->pading_size)<br>
+       */<br>
+      ret = drmIoctl(bo->bufmgr->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg);<br>
+      if (ret != 0) {<br>
+         DBG("Unable to map mapping buffer %d (%s) buffer for pad checking.\n",<br>
+             bo->gem_handle, bo->name);<br>
+         return false;<br>
+      }<br>
+<br>
+      mapped = (uint8_t*) (uintptr_t) mmap_arg.addr_ptr;<br>
+      /* bah-humbug, we need to see the latest contents and<br>
+       * if the bo is not cache coherent we likely need to<br>
+       * invalidate the cache lines to get it.<br>
+       */<br>
+      if (!bo->cache_coherent && !bo->bufmgr->has_llc) {<br>
+         gen_invalidate_range(mapped, bo->padding_size);<br>
+      }<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">You used pwrite before.  Why not just use pread and save yourself the hassle?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">+<br>
+      expected_value = bo->gem_handle & 0xFF;<br>
+      for (uint32_t i = 0; i < bo->padding_size; ++i) {<br>
+         if (expected_value != mapped[i]) {<br>
+            drm_munmap(mapped, bo->padding_size);<br>
+            return false;<br>
+         }<br>
+         expected_value = next_noise_value(expected_value);<br>
+      }<br>
+      drm_munmap(mapped, bo->padding_size);<br>
+   }<br>
+   return true;<br>
+}<br>
+<br>
 struct brw_bo *<br>
 brw_bo_alloc(struct brw_bufmgr *bufmgr,<br>
              const char *name, uint64_t size, uint64_t alignment)<br>
@@ -1157,6 +1269,7 @@ brw_bo_gem_create_from_prime_internal(struct brw_bufmgr *bufmgr, int prime_fd,<br>
    bo->name = "prime";<br>
    bo->reusable = false;<br>
    bo->external = true;<br>
+   bo->padding_size = 0;<br>
<br>
    if (tiling_mode < 0) {<br>
       struct drm_i915_gem_get_tiling get_tiling = { .handle = bo->gem_handle };<br>
diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h<br>
index a3745d6667..fcfd2a9f75 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h<br>
@@ -165,6 +165,12 @@ struct brw_bo {<br>
     * Boolean of whether this buffer is cache coherent<br>
     */<br>
    bool cache_coherent;<br>
+<br>
+   /**<br>
+    * Padding size of weak pseudo-random values; used to check for out of<br>
+    * bounds buffer writing.<br>
+    */<br>
+   uint32_t padding_size;<br>
 };<br>
<br>
 #define BO_ALLOC_BUSY       (1<<0)<br>
@@ -346,6 +352,13 @@ uint32_t brw_bo_export_gem_handle(struct brw_bo *bo);<br>
 int brw_reg_read(struct brw_bufmgr *bufmgr, uint32_t offset,<br>
                  uint64_t *result);<br>
<br>
+/* maps the padding of the brw_bo and returns true if and only if the<br>
+ * padding is the correct noise values. The caller must make sure that<br>
+ * the GPU is not going write to the BO; the best way to do that is to<br>
+ * call brw_bo_wait_rendering() on the batchbuffer.<br>
+ */<br>
+bool brw_bo_padding_is_good(struct brw_bo *bo);<br>
+<br>
 /** @{ */<br>
<br>
 #if defined(__cplusplus)<br>
<span class="hoenzb"><span style="color:#888888">--</span></span><span style="color:#888888"><br>
<span class="hoenzb">2.15.1</span><br>
<br>
<span class="hoenzb">_______________________________________________</span><br>
<span class="hoenzb">mesa-dev mailing list</span><br>
<span class="hoenzb"><a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a></span><br>
<span class="hoenzb"><a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></span></span><o:p></o:p></p>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</div>
</body>
</html>