pan/decode: Make mapped memory read-only while decoding
authorIcecream95 <ixn@keemail.me>
Mon, 22 Jun 2020 10:49:53 +0000 (22:49 +1200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 7 Jul 2020 02:29:52 +0000 (02:29 +0000)
This will help catch any bugs where descriptors are accidentally
modified.

v2: Use a dynarray of ro memory mappings rather than iterating through
    the mmap hash table.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5590>

src/panfrost/pandecode/common.c
src/panfrost/pandecode/decode.c
src/panfrost/pandecode/decode.h

index 65890e44955a11ec2d80574a0f33ffe2aec90a7c..ba825cf10b63a797256e3929f73d154dff8b9be4 100644 (file)
 #include <assert.h>
 #include <stdint.h>
 #include <string.h>
+#include <sys/mman.h>
 
 #include "decode.h"
 #include "util/macros.h"
 #include "util/u_debug.h"
+#include "util/u_dynarray.h"
 #include "util/hash_table.h"
 
 /* Memory handling */
 
 static struct hash_table_u64 *mmap_table;
 
+static struct util_dynarray ro_mappings;
+
+static struct pandecode_mapped_memory *
+pandecode_find_mapped_gpu_mem_containing_rw(uint64_t addr)
+{
+        return _mesa_hash_table_u64_search(mmap_table, addr & ~(4096 - 1));
+}
+
 struct pandecode_mapped_memory *
 pandecode_find_mapped_gpu_mem_containing(uint64_t addr)
 {
-        return _mesa_hash_table_u64_search(mmap_table, addr & ~(4096 - 1));
+        struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing_rw(addr);
+
+        if (mem && mem->addr && !mem->ro) {
+                mprotect(mem->addr, mem->length, PROT_READ);
+                mem->ro = true;
+                util_dynarray_append(&ro_mappings, struct pandecode_mapped_memory *, mem);
+        }
+
+        return mem;
+}
+
+void
+pandecode_map_read_write(void)
+{
+        util_dynarray_foreach(&ro_mappings, struct pandecode_mapped_memory *, mem) {
+                (*mem)->ro = false;
+                mprotect((*mem)->addr, (*mem)->length, PROT_READ | PROT_WRITE);
+        }
+        util_dynarray_clear(&ro_mappings);
 }
 
 static void
@@ -64,7 +92,7 @@ pandecode_inject_mmap(uint64_t gpu_va, void *cpu, unsigned sz, const char *name)
         /* First, search if we already mapped this and are just updating an address */
 
         struct pandecode_mapped_memory *existing =
-                pandecode_find_mapped_gpu_mem_containing(gpu_va);
+                pandecode_find_mapped_gpu_mem_containing_rw(gpu_va);
 
         if (existing && existing->gpu_va == gpu_va) {
                 existing->length = sz;
@@ -97,7 +125,7 @@ pointer_as_memory_reference(uint64_t ptr)
 
         /* Try to find the corresponding mapped zone */
 
-        mapped = pandecode_find_mapped_gpu_mem_containing(ptr);
+        mapped = pandecode_find_mapped_gpu_mem_containing_rw(ptr);
 
         if (mapped) {
                 snprintf(out, 128, "%s + %d", mapped->name, (int) (ptr - mapped->gpu_va));
@@ -150,6 +178,7 @@ void
 pandecode_initialize(bool to_stderr)
 {
         mmap_table = _mesa_hash_table_u64_create(NULL);
+        util_dynarray_init(&ro_mappings, NULL);
         pandecode_dump_file_open(to_stderr);
 }
 
@@ -165,5 +194,6 @@ void
 pandecode_close(void)
 {
         _mesa_hash_table_u64_destroy(mmap_table, NULL);
+        util_dynarray_fini(&ro_mappings);
         pandecode_dump_file_close();
 }
index c64fc4e55934b7df7274585b2f52dbabfc73c0c5..b659614467ead34c83a60943a6abec8d99690aee 100644 (file)
@@ -3281,4 +3281,6 @@ pandecode_jc(mali_ptr jc_gpu_va, bool bifrost, unsigned gpu_id, bool minimal)
                         break;
                 }
         } while ((jc_gpu_va = h->next_job));
+
+        pandecode_map_read_write();
 }
index 48a914987df766aaa69f0e952a0489d9f685c8a8..0c0ea10404a0de3f8b23149186e9fc5269c168d9 100644 (file)
@@ -35,6 +35,7 @@ struct pandecode_mapped_memory {
         size_t length;
         void *addr;
         uint64_t gpu_va;
+        bool ro;
         char name[32];
 };
 
@@ -42,6 +43,8 @@ char *pointer_as_memory_reference(uint64_t ptr);
 
 struct pandecode_mapped_memory *pandecode_find_mapped_gpu_mem_containing(uint64_t addr);
 
+void pandecode_map_read_write(void);
+
 static inline void *
 __pandecode_fetch_gpu_mem(const struct pandecode_mapped_memory *mem,
                           uint64_t gpu_va, size_t size,