Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: core: Add memory copy helpers between iov_iter and iomem

Add two more helpers for copying memory between iov_iter and iomem,
which will be used by the new PCM copy ops in a few drivers.
The existing helpers became wrappers of those now.

Note that copy_from/to_iter() returns the copied bytes, hence the
error condition is adjusted accordingly.

Link: https://lore.kernel.org/r/20230815190136.8987-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+53 -8
+5
include/sound/pcm.h
··· 1559 1559 #define pcm_dbg(pcm, fmt, args...) \ 1560 1560 dev_dbg((pcm)->card->dev, fmt, ##args) 1561 1561 1562 + /* helpers for copying between iov_iter and iomem */ 1563 + int copy_to_iter_fromio(struct iov_iter *itert, const void __iomem *src, 1564 + size_t count); 1565 + int copy_from_iter_toio(void __iomem *dst, struct iov_iter *iter, size_t count); 1566 + 1562 1567 struct snd_pcm_status64 { 1563 1568 snd_pcm_state_t state; /* stream state */ 1564 1569 u8 rsvd[4];
+48 -8
sound/core/memory.c
··· 9 9 #include <linux/io.h> 10 10 #include <linux/uaccess.h> 11 11 #include <sound/core.h> 12 + #include <sound/pcm.h> 12 13 13 14 /** 14 15 * copy_to_user_fromio - copy data from mmio-space to user-space ··· 23 22 */ 24 23 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count) 25 24 { 25 + struct iov_iter iter; 26 + 27 + if (import_ubuf(ITER_DEST, dst, count, &iter)) 28 + return -EFAULT; 29 + return copy_to_iter_fromio(&iter, (const void __iomem *)src, count); 30 + } 31 + EXPORT_SYMBOL(copy_to_user_fromio); 32 + 33 + /** 34 + * copy_to_iter_fromio - copy data from mmio-space to iov_iter 35 + * @dst: the destination iov_iter 36 + * @src: the source pointer on mmio 37 + * @count: the data size to copy in bytes 38 + * 39 + * Copies the data from mmio-space to iov_iter. 40 + * 41 + * Return: Zero if successful, or non-zero on failure. 42 + */ 43 + int copy_to_iter_fromio(struct iov_iter *dst, const void __iomem *src, 44 + size_t count) 45 + { 26 46 #if defined(__i386__) || defined(CONFIG_SPARC32) 27 - return copy_to_user(dst, (const void __force*)src, count) ? -EFAULT : 0; 47 + return copy_to_iter((const void __force *)src, count, dst) == count ? 0 : -EFAULT; 28 48 #else 29 49 char buf[256]; 30 50 while (count) { ··· 53 31 if (c > sizeof(buf)) 54 32 c = sizeof(buf); 55 33 memcpy_fromio(buf, (void __iomem *)src, c); 56 - if (copy_to_user(dst, buf, c)) 34 + if (copy_to_iter(buf, c, dst) != c) 57 35 return -EFAULT; 58 36 count -= c; 59 - dst += c; 60 37 src += c; 61 38 } 62 39 return 0; 63 40 #endif 64 41 } 65 - EXPORT_SYMBOL(copy_to_user_fromio); 42 + EXPORT_SYMBOL(copy_to_iter_fromio); 66 43 67 44 /** 68 45 * copy_from_user_toio - copy data from user-space to mmio-space ··· 75 54 */ 76 55 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count) 77 56 { 57 + struct iov_iter iter; 58 + 59 + if (import_ubuf(ITER_SOURCE, (void __user *)src, count, &iter)) 60 + return -EFAULT; 61 + return copy_from_iter_toio((void __iomem *)dst, &iter, count); 62 + } 63 + EXPORT_SYMBOL(copy_from_user_toio); 64 + 65 + /** 66 + * copy_from_iter_toio - copy data from iov_iter to mmio-space 67 + * @dst: the destination pointer on mmio-space 68 + * @src: the source iov_iter 69 + * @count: the data size to copy in bytes 70 + * 71 + * Copies the data from iov_iter to mmio-space. 72 + * 73 + * Return: Zero if successful, or non-zero on failure. 74 + */ 75 + int copy_from_iter_toio(void __iomem *dst, struct iov_iter *src, size_t count) 76 + { 78 77 #if defined(__i386__) || defined(CONFIG_SPARC32) 79 - return copy_from_user((void __force *)dst, src, count) ? -EFAULT : 0; 78 + return copy_from_iter((void __force *)dst, count, src) == count ? 0 : -EFAULT; 80 79 #else 81 80 char buf[256]; 82 81 while (count) { 83 82 size_t c = count; 84 83 if (c > sizeof(buf)) 85 84 c = sizeof(buf); 86 - if (copy_from_user(buf, src, c)) 85 + if (copy_from_iter(buf, c, src) != c) 87 86 return -EFAULT; 88 87 memcpy_toio(dst, buf, c); 89 88 count -= c; 90 89 dst += c; 91 - src += c; 92 90 } 93 91 return 0; 94 92 #endif 95 93 } 96 - EXPORT_SYMBOL(copy_from_user_toio); 94 + EXPORT_SYMBOL(copy_from_iter_toio);