#include <linux/string.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/kmsan-checks.h>
 
 #define movs(type,to,from) \
        asm volatile("movs" type:"=&D" (to), "=&S" (from):"0" (to), "1" (from):"memory")
                n-=2;
        }
        rep_movs(to, (const void *)from, n);
+       /* KMSAN must treat values read from devices as initialized. */
+       kmsan_unpoison_memory(to, n);
 }
 
 static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
        if (unlikely(!n))
                return;
 
+       /* Make sure uninitialized memory isn't copied to devices. */
+       kmsan_check_memory(from, n);
        /* Align any unaligned destination IO */
        if (unlikely(1 & (unsigned long)to)) {
                movs("b", to, from);