<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
  </head>
  <body>
    <font size="+1"><tt>Thank you Felix. Now I understand the problem of
        global client ID is leaking a hole for potential attackers. I
        didn't take that into consideration. I'll change that following
        your advice below.<br>
        <br>
        Hi Alex,<br>
        <br>
        Thank you for the link. It's helpful. I have a question
        regarding the versioning. One topic in the article talks about
        how the userspace can figure out if the new ioctl is supported
        in a given kernel. Is it correct that with dkms driver, we use
        the driver version coming from AMDGPU_VERSION in amdgpu_drv.c,
        and in upstream kernel we use the kernel version?<br>
        <br>
        Thanks.<br>
        <br>
        Amber<br>
      </tt></font><br>
    <div class="moz-cite-prefix">On 2020-04-14 11:03 p.m., Deucher,
      Alexander wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:MN2PR12MB4488B378A20AB052F3A93564F7DB0@MN2PR12MB4488.namprd12.prod.outlook.com">
      
      <style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
      <p style="font-family:Arial;font-size:10pt;color:#317100;margin:15pt;" align="Left">
        [AMD Public Use]<br>
      </p>
      <br>
      <div>
        <div style="font-family: Calibri, Arial, Helvetica, sans-serif;
          font-size: 12pt; color: rgb(0, 0, 0);">
          Some good advice on getting ioctls right:</div>
        <div style="font-family: Calibri, Arial, Helvetica, sans-serif;
          font-size: 12pt; color: rgb(0, 0, 0);">
          <a href="https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.html" id="LPNoLP568680" moz-do-not-send="true">https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.html</a></div>
        <div style="font-family: Calibri, Arial, Helvetica, sans-serif;
          font-size: 12pt; color: rgb(0, 0, 0);">
          <br>
        </div>
        <div style="font-family: Calibri, Arial, Helvetica, sans-serif;
          font-size: 12pt; color: rgb(0, 0, 0);">
          Alex<br>
        </div>
        <div style="font-family: Calibri, Arial, Helvetica, sans-serif;
          font-size: 12pt; color: rgb(0, 0, 0);">
          <br>
        </div>
        <hr style="display:inline-block;width:98%" tabindex="-1">
        <div id="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b>
            amd-gfx <a class="moz-txt-link-rfc2396E" href="mailto:amd-gfx-bounces@lists.freedesktop.org"><amd-gfx-bounces@lists.freedesktop.org></a> on
            behalf of Felix Kuehling <a class="moz-txt-link-rfc2396E" href="mailto:felix.kuehling@amd.com"><felix.kuehling@amd.com></a><br>
            <b>Sent:</b> Tuesday, April 14, 2020 10:40 PM<br>
            <b>To:</b> Lin, Amber <a class="moz-txt-link-rfc2396E" href="mailto:Amber.Lin@amd.com"><Amber.Lin@amd.com></a>;
            <a class="moz-txt-link-abbreviated" href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a>
            <a class="moz-txt-link-rfc2396E" href="mailto:amd-gfx@lists.freedesktop.org"><amd-gfx@lists.freedesktop.org></a><br>
            <b>Subject:</b> Re: [PATCH v4] drm/amdkfd: Provide SMI
            events watch</font>
          <div> </div>
        </div>
        <div>
          <p>Hi Amber,</p>
          <p>I understand that different processes can get the same FD.
            My statement about FD being unique is relative to one
            process.</p>
          <p>The main problem with the global client ID is, that it
            allows process A to change the event mask of process B just
            by specifying process B's client ID. That can lead to denial
            of service attacks where process A can cause events not to
            be delivered to B or can flood process B with frequent
            events that it's not prepared to handle.</p>
          <p>Therefore you must make the lookup of the client from the
            client ID not from a global list, but from a per-process
            list. That way process A can only change event masks of
            process A clients, and not those of any other process.</p>
          <p>But if the client list is process-specific, you can use the
            FD as a unique identifier of the client within the process,
            so you don't need a separate client ID.</p>
          <p>Regards,<br>
              Felix<br>
          </p>
          <div class="x_moz-cite-prefix">Am 2020-04-14 um 8:09 p.m.
            schrieb Lin, Amber:<br>
          </div>
          <blockquote type="cite">
            <meta name="Generator" content="Microsoft Word 15 (filtered
              medium)">
            <style>
<!--
@font-face
        {font-family:PMingLiU}
@font-face
        {font-family:"Cambria Math"}
@font-face
        {font-family:Calibri}
@font-face
        {font-family:Consolas}
@font-face
        {}
p.x_MsoNormal, li.x_MsoNormal, div.x_MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif}
a:link, span.x_MsoHyperlink
        {color:blue;
        text-decoration:underline}
pre
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New"}
span.x_HTMLPreformattedChar
        {font-family:Consolas}
p.x_msipheader4d0fcdd7, li.x_msipheader4d0fcdd7, div.x_msipheader4d0fcdd7
        {margin-right:0in;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif}
span.x_EmailStyle22
        {font-family:"Arial",sans-serif;
        color:#0078D7}
.x_MsoChpDefault
        {font-size:10.0pt}
@page WordSection1
        {margin:1.0in 1.0in 1.0in 1.0in}
div.x_WordSection1
        {}
ol
        {margin-bottom:0in}
ul
        {margin-bottom:0in}
-->
</style>
            <div class="x_WordSection1">
              <p class="x_msipheader4d0fcdd7" style="margin:0in;
                margin-bottom:.0001pt"><span style="font-size:10.0pt;
                  font-family:"Arial",sans-serif;
                  color:#0078D7">[AMD Official Use Only - Internal
                  Distribution Only]</span></p>
              <p class="x_MsoNormal"> </p>
              <p class="x_MsoNormal">Hi Felix,</p>
              <p class="x_MsoNormal"> </p>
              <p class="x_MsoNormal">That was my assumption too that
                each registration will get different file descriptor,
                but it turns out not. When I started two process and
                both register gpu0 and gpu1, they both got fd=15. If I
                have process A register gpu0+gpu1, and process B only
                register gpu0, process A gets fd=15 and process B gets
                fd=9. That’s why I added client ID.</p>
              <p class="x_MsoNormal"> </p>
              <p class="x_MsoNormal">By multiple clients, I mean
                multiple processes. The ask is users want to have
                multiple tools and those different tools can use rsmi
                lib to watch events at the same time. Due to the reason
                above that two processes can actually get the same fd
                and I need to add client ID to distinguish the
                registration, I don’t see the point of limiting one
                registration per process unless I use pid to distinguish
                the client instead, which was in my consideration too
                when I was writing the code. But second thought is why
                adding this restriction when client ID can allow the
                tool to watch different events on different devices if
                they want to. Maybe client ID is a bad term and it
                misleads you. I should call it register ID.</p>
              <p class="x_MsoNormal"> </p>
              <div>
                <p class="x_MsoNormal">Regards,</p>
                <p class="x_MsoNormal">Amber</p>
              </div>
              <p class="x_MsoNormal"> </p>
              <div>
                <div style="border:none; border-top:solid #E1E1E1 1.0pt;
                  padding:3.0pt 0in 0in 0in">
                  <p class="x_MsoNormal"><b>From:</b> Kuehling, Felix <a class="x_moz-txt-link-rfc2396E" href="mailto:Felix.Kuehling@amd.com" moz-do-not-send="true">
                      <Felix.Kuehling@amd.com></a> <br>
                    <b>Sent:</b> Tuesday, April 14, 2020 7:04 PM<br>
                    <b>To:</b> Lin, Amber <a class="x_moz-txt-link-rfc2396E" href="mailto:Amber.Lin@amd.com" moz-do-not-send="true">
                      <Amber.Lin@amd.com></a>; <a class="x_moz-txt-link-abbreviated" href="mailto:amd-gfx@lists.freedesktop.org" moz-do-not-send="true">
                      amd-gfx@lists.freedesktop.org</a><br>
                    <b>Subject:</b> Re: [PATCH v4] drm/amdkfd: Provide
                    SMI events watch</p>
                </div>
              </div>
              <p class="x_MsoNormal"> </p>
              <p>Hi Amber,</p>
              <p>Some general remarks about the multi-client support.
                You added a global client id that's separate from the
                file descriptor. That's problematic for two reasons:</p>
              <ol type="1" start="1">
                <li class="x_MsoNormal" style="">A process could change
                  a different process' event mask</li>
                <li class="x_MsoNormal" style="">The FD should already
                  be unique per process, no need to invent another ID</li>
              </ol>
              <p>If we want to allow one process to register for events
                multiple times (multiple FDs per process), then the list
                of clients should be per process. Each process should
                only be allowed to change the event masks of its own
                clients. The client could be identified by its FD. No
                need for another client ID.</p>
              <p>But you could also simplify it further by allowing only
                one event client per process. Then you don't need the
                client ID lookup at all. Just have a single event client
                in the kfd_process.</p>
              <p>Another approach would be to make enable/disable
                functions of the event FD, rather than the KFD FD ioctl.
                It could be an ioctl of the event FD, or even simpler,
                you could use the write file-operation to write an event
                mask (of arbitrary length if you want to enable growth
                in the future). That way everything would be neatly
                encapsulated in the event FD private data.</p>
              <p>Two more comments inline ...</p>
              <p> </p>
              <div>
                <p class="x_MsoNormal">Am 2020-04-14 um 5:30 p.m.
                  schrieb Amber Lin:</p>
              </div>
              <blockquote style="margin-top:5.0pt; margin-bottom:5.0pt">
                <pre>When the compute is malfunctioning or performance drops, the system admin</pre>
                <pre>will use SMI (System Management Interface) tool to monitor/diagnostic what</pre>
                <pre>went wrong. This patch provides an event watch interface for the user</pre>
                <pre>space to register devices and subscribe events they are interested. After</pre>
                <pre>registered, the user can use annoymous file descriptor's poll function</pre>
                <pre>with wait-time specified and wait for events to happen. Once an event</pre>
                <pre>happens, the user can use read() to retrieve information related to the</pre>
                <pre>event.</pre>
                <pre> </pre>
                <pre>VM fault event is done in this patch.</pre>
                <pre> </pre>
                <pre>v2: - remove UNREGISTER and add event ENABLE/DISABLE</pre>
                <pre>    - correct kfifo usage</pre>
                <pre>    - move event message API to kfd_ioctl.h</pre>
                <pre>v3: send the event msg in text than in binary</pre>
                <pre>v4: support multiple clients</pre>
                <pre> </pre>
                <pre>Signed-off-by: Amber Lin <a href="mailto:Amber.Lin@amd.com" moz-do-not-send="true"><Amber.Lin@amd.com></a></pre>
              </blockquote>
              <p>[snip]</p>
              <blockquote style="margin-top:5.0pt; margin-bottom:5.0pt">
                <pre>diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h</pre>
                <pre>index 4f66764..8146437 100644</pre>
                <pre>--- a/include/uapi/linux/kfd_ioctl.h</pre>
                <pre>+++ b/include/uapi/linux/kfd_ioctl.h</pre>
                <pre>@@ -442,6 +442,36 @@ struct kfd_ioctl_import_dmabuf_args {</pre>
                <pre>  __u32 dmabuf_fd;       /* to KFD */</pre>
                <pre> };</pre>
                <pre> </pre>
                <pre>+/*</pre>
                <pre>+ * KFD SMI(System Management Interface) events</pre>
                <pre>+ */</pre>
                <pre>+enum kfd_smi_events_op {</pre>
                <pre>+ KFD_SMI_EVENTS_REGISTER = 1,</pre>
                <pre>+ KFD_SMI_EVENTS_ENABLE,</pre>
                <pre>+ KFD_SMI_EVENTS_DISABLE</pre>
                <pre>+};</pre>
                <pre>+</pre>
                <pre>+/* Event type (defined by bitmask) */</pre>
                <pre>+#define KFD_SMI_EVENT_VMFAULT     0x0000000000000001</pre>
                <pre>+</pre>
                <pre>+struct kfd_ioctl_smi_events_args {</pre>
                <pre>+ __u32 op;              /* to KFD */</pre>
                <pre>+ __u64 events;          /* to KFD */</pre>
              </blockquote>
              <p>The binary layout of the ioctl args structure should be
                the same on 32/64-bit. That means the 64-bit members
                should be 64-bit aligned. The best way to ensure this is
                to put all the 64-bit members first.</p>
              <p class="x_MsoNormal" style="margin-bottom:12.0pt"> </p>
              <blockquote style="margin-top:5.0pt; margin-bottom:5.0pt">
                <pre> </pre>
                <pre>+ __u64 gpuids_array_ptr;        /* to KFD */</pre>
                <pre>+ __u32 num_gpuids;      /* to KFD */</pre>
                <pre>+ __u32 anon_fd;         /* from KFD */</pre>
                <pre>+ __u32 client_id;       /* to/from KFD */</pre>
                <pre>+};</pre>
                <pre>+</pre>
                <pre>+/* 1. All messages must start with (hex)uint64_event(16) + space(1) +</pre>
                <pre>+ *    (hex)gpuid(8) + space(1) =  26 bytes</pre>
                <pre>+ * 2. VmFault msg = (hex)uint32_pid(8) + space(1) + task name(16) = 25</pre>
                <pre>+ *    When a new event msg uses more memory, change the calculation here.</pre>
                <pre>+ * 3. End with \n(1)</pre>
                <pre>+ * 26 + 25 + 1 = 52</pre>
                <pre>+ */</pre>
                <pre>+#define KFD_SMI_MAX_EVENT_MSG 52</pre>
              </blockquote>
              <p>If you define the maximum message length here, clients
                may start depending on it, and it gets harder to change
                it later. I'd not define this in the API header. It's
                not necessary to write correct clients. And if used
                badly, it may encourage writing incorrect clients that
                break with longer messages in the future.</p>
              <p>Regards,<br>
                  Felix</p>
              <p> </p>
              <blockquote style="margin-top:5.0pt; margin-bottom:5.0pt">
                <pre> </pre>
                <pre>+</pre>
                <pre> /* Register offset inside the remapped mmio page</pre>
                <pre>  */</pre>
                <pre> enum kfd_mmio_remap {</pre>
                <pre>@@ -546,7 +576,10 @@ enum kfd_mmio_remap {</pre>
                <pre> #define AMDKFD_IOC_ALLOC_QUEUE_GWS            \</pre>
                <pre>         AMDKFD_IOWR(0x1E, struct kfd_ioctl_alloc_queue_gws_args)</pre>
                <pre> </pre>
                <pre>+#define AMDKFD_IOC_SMI_EVENTS                 \</pre>
                <pre>+        AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args)</pre>
                <pre>+</pre>
                <pre> #define AMDKFD_COMMAND_START           0x01</pre>
                <pre>-#define AMDKFD_COMMAND_END             0x1F</pre>
                <pre>+#define AMDKFD_COMMAND_END             0x20</pre>
                <pre> </pre>
                <pre> #endif</pre>
              </blockquote>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>