#include <asm/setup.h>
 #include <asm/desc.h>
 
-#undef memcpy                  /* Use memcpy from misc.c */
-
+#include "../string.h"
 #include "eboot.h"
 
 static efi_system_table_t *sys_table;
 
  * we just keep it from happening
  */
 #undef CONFIG_PARAVIRT
+#undef CONFIG_KASAN
 #ifdef CONFIG_X86_32
 #define _ASM_X86_DESC_H 1
 #endif
 
    function. */
 
 #define __HAVE_ARCH_MEMCPY 1
+extern void *__memcpy(void *to, const void *from, size_t len);
+
 #ifndef CONFIG_KMEMCHECK
 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
 extern void *memcpy(void *to, const void *from, size_t len);
 #else
-extern void *__memcpy(void *to, const void *from, size_t len);
 #define memcpy(dst, src, len)                                  \
 ({                                                             \
        size_t __len = (len);                                   \
 
 #define __HAVE_ARCH_MEMSET
 void *memset(void *s, int c, size_t n);
+void *__memset(void *s, int c, size_t n);
 
 #define __HAVE_ARCH_MEMMOVE
 void *memmove(void *dest, const void *src, size_t count);
+void *__memmove(void *dest, const void *src, size_t count);
 
 int memcmp(const void *cs, const void *ct, size_t count);
 size_t strlen(const char *s);
 char *strcat(char *dest, const char *src);
 int strcmp(const char *cs, const char *ct);
 
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+
+/*
+ * For files that not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+
+#undef memcpy
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_X86_STRING_64_H */
 
 #undef memset
 #undef memmove
 
+extern void *__memset(void *, int, __kernel_size_t);
+extern void *__memcpy(void *, const void *, __kernel_size_t);
+extern void *__memmove(void *, const void *, __kernel_size_t);
 extern void *memset(void *, int, __kernel_size_t);
 extern void *memcpy(void *, const void *, __kernel_size_t);
-extern void *__memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+EXPORT_SYMBOL(__memset);
+EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(__memmove);
 
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(memmove);
 
 #ifndef CONFIG_DEBUG_VIRTUAL
 
 .Lmemcpy_e_e:
        .previous
 
+.weak memcpy
+
 ENTRY(__memcpy)
 ENTRY(memcpy)
        CFI_STARTPROC
         * only outcome...
         */
        .section .altinstructions, "a"
-       altinstruction_entry memcpy,.Lmemcpy_c,X86_FEATURE_REP_GOOD,\
+       altinstruction_entry __memcpy,.Lmemcpy_c,X86_FEATURE_REP_GOOD,\
                             .Lmemcpy_e-.Lmemcpy_c,.Lmemcpy_e-.Lmemcpy_c
-       altinstruction_entry memcpy,.Lmemcpy_c_e,X86_FEATURE_ERMS, \
+       altinstruction_entry __memcpy,.Lmemcpy_c_e,X86_FEATURE_ERMS, \
                             .Lmemcpy_e_e-.Lmemcpy_c_e,.Lmemcpy_e_e-.Lmemcpy_c_e
        .previous
 
  * Output:
  * rax: dest
  */
+.weak memmove
+
 ENTRY(memmove)
+ENTRY(__memmove)
        CFI_STARTPROC
 
        /* Handle more 32 bytes in loop */
                .Lmemmove_end_forward-.Lmemmove_begin_forward,  \
                .Lmemmove_end_forward_efs-.Lmemmove_begin_forward_efs
        .previous
+ENDPROC(__memmove)
 ENDPROC(memmove)
 
 .Lmemset_e_e:
        .previous
 
+.weak memset
+
 ENTRY(memset)
 ENTRY(__memset)
        CFI_STARTPROC
          * feature to implement the right patch order.
         */
        .section .altinstructions,"a"
-       altinstruction_entry memset,.Lmemset_c,X86_FEATURE_REP_GOOD,\
-                            .Lfinal-memset,.Lmemset_e-.Lmemset_c
-       altinstruction_entry memset,.Lmemset_c_e,X86_FEATURE_ERMS, \
-                            .Lfinal-memset,.Lmemset_e_e-.Lmemset_c_e
+       altinstruction_entry __memset,.Lmemset_c,X86_FEATURE_REP_GOOD,\
+                            .Lfinal-__memset,.Lmemset_e-.Lmemset_c
+       altinstruction_entry __memset,.Lmemset_c_e,X86_FEATURE_ERMS, \
+                            .Lfinal-__memset,.Lmemset_e_e-.Lmemset_c_e
        .previous
 
 /* error code which can't be mistaken for valid address */
 #define EFI_ERROR      (~0UL)
 
+#undef memcpy
+#undef memset
+#undef memmove
+
 void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
 
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
 
        kasan_report(addr, size, write, _RET_IP_);
 }
 
+void __asan_loadN(unsigned long addr, size_t size);
+void __asan_storeN(unsigned long addr, size_t size);
+
+#undef memset
+void *memset(void *addr, int c, size_t len)
+{
+       __asan_storeN((unsigned long)addr, len);
+
+       return __memset(addr, c, len);
+}
+
+#undef memmove
+void *memmove(void *dest, const void *src, size_t len)
+{
+       __asan_loadN((unsigned long)src, len);
+       __asan_storeN((unsigned long)dest, len);
+
+       return __memmove(dest, src, len);
+}
+
+#undef memcpy
+void *memcpy(void *dest, const void *src, size_t len)
+{
+       __asan_loadN((unsigned long)src, len);
+       __asan_storeN((unsigned long)dest, len);
+
+       return __memcpy(dest, src, len);
+}
+
 void kasan_alloc_pages(struct page *page, unsigned int order)
 {
        if (likely(!PageHighMem(page)))