}
 EXPORT_SYMBOL(vm_mmap);
 
+static gfp_t kmalloc_gfp_adjust(gfp_t flags, size_t size)
+{
+       /*
+        * We want to attempt a large physically contiguous block first because
+        * it is less likely to fragment multiple larger blocks and therefore
+        * contribute to a long term fragmentation less than vmalloc fallback.
+        * However make sure that larger requests are not too disruptive - no
+        * OOM killer and no allocation failure warnings as we have a fallback.
+        */
+       if (size > PAGE_SIZE) {
+               flags |= __GFP_NOWARN;
+
+               if (!(flags & __GFP_RETRY_MAYFAIL))
+                       flags |= __GFP_NORETRY;
+
+               /* nofail semantic is implemented by the vmalloc fallback */
+               flags &= ~__GFP_NOFAIL;
+       }
+
+       return flags;
+}
+
 /**
  * __kvmalloc_node - attempt to allocate physically contiguous memory, but upon
  * failure, fall back to non-contiguous (vmalloc) allocation.
  */
 void *__kvmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node)
 {
-       gfp_t kmalloc_flags = flags;
        void *ret;
 
-       /*
-        * We want to attempt a large physically contiguous block first because
-        * it is less likely to fragment multiple larger blocks and therefore
-        * contribute to a long term fragmentation less than vmalloc fallback.
-        * However make sure that larger requests are not too disruptive - no
-        * OOM killer and no allocation failure warnings as we have a fallback.
-        */
-       if (size > PAGE_SIZE) {
-               kmalloc_flags |= __GFP_NOWARN;
-
-               if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL))
-                       kmalloc_flags |= __GFP_NORETRY;
-
-               /* nofail semantic is implemented by the vmalloc fallback */
-               kmalloc_flags &= ~__GFP_NOFAIL;
-       }
-
-       ret = __kmalloc_node_noprof(PASS_BUCKET_PARAMS(size, b), kmalloc_flags, node);
-
        /*
         * It doesn't really make sense to fallback to vmalloc for sub page
         * requests
         */
+       ret = __kmalloc_node_noprof(PASS_BUCKET_PARAMS(size, b),
+                                   kmalloc_gfp_adjust(flags, size),
+                                   node);
        if (ret || size <= PAGE_SIZE)
                return ret;
 
 }
 EXPORT_SYMBOL(kvfree_sensitive);
 
-void *kvrealloc_noprof(const void *p, size_t oldsize, size_t newsize, gfp_t flags)
+/**
+ * kvrealloc - reallocate memory; contents remain unchanged
+ * @p: object to reallocate memory for
+ * @size: the size to reallocate
+ * @flags: the flags for the page level allocator
+ *
+ * If @p is %NULL, kvrealloc() behaves exactly like kvmalloc(). If @size is 0
+ * and @p is not a %NULL pointer, the object pointed to is freed.
+ *
+ * If __GFP_ZERO logic is requested, callers must ensure that, starting with the
+ * initial memory allocation, every subsequent call to this API for the same
+ * memory allocation is flagged with __GFP_ZERO. Otherwise, it is possible that
+ * __GFP_ZERO is not fully honored by this API.
+ *
+ * In any case, the contents of the object pointed to are preserved up to the
+ * lesser of the new and old sizes.
+ *
+ * This function must not be called concurrently with itself or kvfree() for the
+ * same memory allocation.
+ *
+ * Return: pointer to the allocated memory or %NULL in case of error
+ */
+void *kvrealloc_noprof(const void *p, size_t size, gfp_t flags)
 {
-       void *newp;
+       void *n;
 
-       if (oldsize >= newsize)
-               return (void *)p;
-       newp = kvmalloc_noprof(newsize, flags);
-       if (!newp)
-               return NULL;
-       memcpy(newp, p, oldsize);
-       kvfree(p);
-       return newp;
+       if (is_vmalloc_addr(p))
+               return vrealloc_noprof(p, size, flags);
+
+       n = krealloc_noprof(p, size, kmalloc_gfp_adjust(flags, size));
+       if (!n) {
+               /* We failed to krealloc(), fall back to kvmalloc(). */
+               n = kvmalloc_noprof(size, flags);
+               if (!n)
+                       return NULL;
+
+               if (p) {
+                       /* We already know that `p` is not a vmalloc address. */
+                       kasan_disable_current();
+                       memcpy(n, kasan_reset_tag(p), ksize(p));
+                       kasan_enable_current();
+
+                       kfree(p);
+               }
+       }
+
+       return n;
 }
 EXPORT_SYMBOL(kvrealloc_noprof);