Merge tag 'amd-drm-next-5.19-2022-04-29' of https://gitlab.freedesktop.org/agd5f...
[linux-2.6-microblaze.git] / mm / kasan / shadow.c
index 94136f8..a4f07de 100644 (file)
@@ -345,27 +345,6 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
        return 0;
 }
 
-/*
- * Poison the shadow for a vmalloc region. Called as part of the
- * freeing process at the time the region is freed.
- */
-void kasan_poison_vmalloc(const void *start, unsigned long size)
-{
-       if (!is_vmalloc_or_module_addr(start))
-               return;
-
-       size = round_up(size, KASAN_GRANULE_SIZE);
-       kasan_poison(start, size, KASAN_VMALLOC_INVALID, false);
-}
-
-void kasan_unpoison_vmalloc(const void *start, unsigned long size)
-{
-       if (!is_vmalloc_or_module_addr(start))
-               return;
-
-       kasan_unpoison(start, size, false);
-}
-
 static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
                                        void *unused)
 {
@@ -496,9 +475,48 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
        }
 }
 
+void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+                              kasan_vmalloc_flags_t flags)
+{
+       /*
+        * Software KASAN modes unpoison both VM_ALLOC and non-VM_ALLOC
+        * mappings, so the KASAN_VMALLOC_VM_ALLOC flag is ignored.
+        * Software KASAN modes can't optimize zeroing memory by combining it
+        * with setting memory tags, so the KASAN_VMALLOC_INIT flag is ignored.
+        */
+
+       if (!is_vmalloc_or_module_addr(start))
+               return (void *)start;
+
+       /*
+        * Don't tag executable memory with the tag-based mode.
+        * The kernel doesn't tolerate having the PC register tagged.
+        */
+       if (IS_ENABLED(CONFIG_KASAN_SW_TAGS) &&
+           !(flags & KASAN_VMALLOC_PROT_NORMAL))
+               return (void *)start;
+
+       start = set_tag(start, kasan_random_tag());
+       kasan_unpoison(start, size, false);
+       return (void *)start;
+}
+
+/*
+ * Poison the shadow for a vmalloc region. Called as part of the
+ * freeing process at the time the region is freed.
+ */
+void __kasan_poison_vmalloc(const void *start, unsigned long size)
+{
+       if (!is_vmalloc_or_module_addr(start))
+               return;
+
+       size = round_up(size, KASAN_GRANULE_SIZE);
+       kasan_poison(start, size, KASAN_VMALLOC_INVALID, false);
+}
+
 #else /* CONFIG_KASAN_VMALLOC */
 
-int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask)
+int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask)
 {
        void *ret;
        size_t scaled_size;
@@ -534,7 +552,7 @@ int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask)
        return -ENOMEM;
 }
 
-void kasan_free_shadow(const struct vm_struct *vm)
+void kasan_free_module_shadow(const struct vm_struct *vm)
 {
        if (vm->flags & VM_KASAN)
                vfree(kasan_mem_to_shadow(vm->addr));