Module: Mesa
Branch: staging/22.2
Commit: cc504c9887e2f2e4c5d23aa754aa1ea08bd2805d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=cc504c9887e2f2e4c5d23aa754aa1ea08bd2805d

Author: Chia-I Wu <[email protected]>
Date:   Fri Aug 12 13:02:30 2022 -0700

turnip: fix a use-after-free in autotune

When removing old histories, check against gpu fence.  Otherwise,
pending_results could have dangling pointers to the removed histories.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7055
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18040>
(cherry picked from commit b8a916fd0cd589c621c6d1ed1c4b4fd01fd7bf5d)

---

 .pick_status.json                  |  2 +-
 src/freedreno/vulkan/tu_autotune.c | 21 +++++++++++++++------
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index dcf3e7f5b47..5af8cc090d5 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -445,7 +445,7 @@
         "description": "turnip: fix a use-after-free in autotune",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/freedreno/vulkan/tu_autotune.c 
b/src/freedreno/vulkan/tu_autotune.c
index 0c4b44111c0..cd37c15f7b5 100644
--- a/src/freedreno/vulkan/tu_autotune.c
+++ b/src/freedreno/vulkan/tu_autotune.c
@@ -83,6 +83,13 @@ struct tu_submission_data {
    uint32_t buffers_count;
 };
 
+static uint32_t
+get_autotune_fence(struct tu_autotune *at)
+{
+   const struct tu6_global *global = at->device->global_bo->map;
+   return global->autotune_fence;
+}
+
 static struct tu_submission_data *
 create_submission_data(struct tu_device *dev, struct tu_autotune *at)
 {
@@ -230,11 +237,9 @@ history_add_result(struct tu_device *dev, struct 
tu_renderpass_history *history,
 }
 
 static void
-process_results(struct tu_autotune *at)
+process_results(struct tu_autotune *at, uint32_t current_fence)
 {
    struct tu_device *dev = at->device;
-   struct tu6_global *global = dev->global_bo->map;
-   uint32_t current_fence = global->autotune_fence;
 
    list_for_each_entry_safe(struct tu_renderpass_result, result,
                             &at->pending_results, node) {
@@ -288,7 +293,9 @@ tu_autotune_on_submit(struct tu_device *dev,
 {
    /* We are single-threaded here */
 
-   process_results(at);
+   const uint32_t gpu_fence = get_autotune_fence(at);
+
+   process_results(at, gpu_fence);
 
    /* pre-increment so zero isn't valid fence */
    uint32_t new_fence = ++at->fence_counter;
@@ -349,7 +356,8 @@ tu_autotune_on_submit(struct tu_device *dev,
    hash_table_foreach(at->ht, entry) {
       struct tu_renderpass_history *history = entry->data;
       if (history->last_fence == 0 ||
-          (new_fence - history->last_fence) <= MAX_HISTORY_LIFETIME)
+          gpu_fence < history->last_fence ||
+          (gpu_fence - history->last_fence) <= MAX_HISTORY_LIFETIME)
          continue;
 
       if (TU_AUTOTUNE_DEBUG_LOG)
@@ -400,7 +408,8 @@ tu_autotune_fini(struct tu_autotune *at, struct tu_device 
*dev)
 {
    if (TU_AUTOTUNE_LOG_AT_FINISH) {
       while (!list_is_empty(&at->pending_results)) {
-         process_results(at);
+         const uint32_t gpu_fence = get_autotune_fence(at);
+         process_results(at, gpu_fence);
       }
 
       hash_table_foreach(at->ht, entry) {

Reply via email to