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

ALSA: Align the syntax of iov_iter helpers with standard ones

We introduced a couple of helpers for copying iomem over iov_iter, and
the functions were formed like the former copy_from/to_user(), and the
return value was adjusted to 0/-EFAULT, which made the code transition
a bit easier at that time.

OTOH, the standard copy_from/to_iter() functions have different
argument orders and the return value, and this difference can be
confusing. It's not only confusing but dangerous; actually I did
write a wrong code due to that once :-<

For reducing the confusion, this patch changes the syntax of those
helpers to align with the standard copy_from/to_iter(). The argument
order is changed and the return value is the size of copied bytes.
The callers of those functions are updated accordingly, too.

Link: https://patch.msgid.link/20241230114903.4959-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+56 -32
+4 -3
include/sound/pcm.h
··· 1532 1532 dev_dbg((pcm)->card->dev, fmt, ##args) 1533 1533 1534 1534 /* helpers for copying between iov_iter and iomem */ 1535 - int copy_to_iter_fromio(struct iov_iter *itert, const void __iomem *src, 1536 - size_t count); 1537 - int copy_from_iter_toio(void __iomem *dst, struct iov_iter *iter, size_t count); 1535 + size_t copy_to_iter_fromio(const void __iomem *src, size_t bytes, 1536 + struct iov_iter *iter) __must_check; 1537 + size_t copy_from_iter_toio(void __iomem *dst, size_t bytes, 1538 + struct iov_iter *iter) __must_check; 1538 1539 1539 1540 struct snd_pcm_status64 { 1540 1541 snd_pcm_state_t state; /* stream state */
+26 -15
sound/core/memory.c
··· 27 27 28 28 if (import_ubuf(ITER_DEST, dst, count, &iter)) 29 29 return -EFAULT; 30 - return copy_to_iter_fromio(&iter, (const void __iomem *)src, count); 30 + if (copy_to_iter_fromio((const void __iomem *)src, count, &iter) != count) 31 + return -EFAULT; 32 + return 0; 31 33 } 32 34 EXPORT_SYMBOL(copy_to_user_fromio); 33 35 34 36 /** 35 37 * copy_to_iter_fromio - copy data from mmio-space to iov_iter 36 - * @dst: the destination iov_iter 37 38 * @src: the source pointer on mmio 38 39 * @count: the data size to copy in bytes 40 + * @dst: the destination iov_iter 39 41 * 40 42 * Copies the data from mmio-space to iov_iter. 41 43 * 42 - * Return: Zero if successful, or non-zero on failure. 44 + * Return: number of bytes to be copied 43 45 */ 44 - int copy_to_iter_fromio(struct iov_iter *dst, const void __iomem *src, 45 - size_t count) 46 + size_t copy_to_iter_fromio(const void __iomem *src, size_t count, 47 + struct iov_iter *dst) 46 48 { 47 49 #if defined(__i386__) || defined(CONFIG_SPARC32) 48 - return copy_to_iter((const void __force *)src, count, dst) == count ? 0 : -EFAULT; 50 + return copy_to_iter((const void __force *)src, count, dst); 49 51 #else 50 52 char buf[256]; 53 + size_t res = 0; 54 + 51 55 while (count) { 52 56 size_t c = count; 53 57 if (c > sizeof(buf)) 54 58 c = sizeof(buf); 55 59 memcpy_fromio(buf, (void __iomem *)src, c); 56 60 if (copy_to_iter(buf, c, dst) != c) 57 - return -EFAULT; 61 + return res; 58 62 count -= c; 59 63 src += c; 64 + res += c; 60 65 } 61 - return 0; 66 + return res; 62 67 #endif 63 68 } 64 69 EXPORT_SYMBOL(copy_to_iter_fromio); ··· 84 79 85 80 if (import_ubuf(ITER_SOURCE, (void __user *)src, count, &iter)) 86 81 return -EFAULT; 87 - return copy_from_iter_toio((void __iomem *)dst, &iter, count); 82 + if (copy_from_iter_toio((void __iomem *)dst, count, &iter) != count) 83 + return -EFAULT; 84 + return 0; 88 85 } 89 86 EXPORT_SYMBOL(copy_from_user_toio); 90 87 91 88 /** 92 89 * copy_from_iter_toio - copy data from iov_iter to mmio-space 93 90 * @dst: the destination pointer on mmio-space 94 - * @src: the source iov_iter 95 91 * @count: the data size to copy in bytes 92 + * @src: the source iov_iter 96 93 * 97 94 * Copies the data from iov_iter to mmio-space. 98 95 * 99 - * Return: Zero if successful, or non-zero on failure. 96 + * Return: number of bytes to be copied 100 97 */ 101 - int copy_from_iter_toio(void __iomem *dst, struct iov_iter *src, size_t count) 98 + size_t copy_from_iter_toio(void __iomem *dst, size_t count, 99 + struct iov_iter *src) 102 100 { 103 101 #if defined(__i386__) || defined(CONFIG_SPARC32) 104 - return copy_from_iter((void __force *)dst, count, src) == count ? 0 : -EFAULT; 102 + return copy_from_iter((void __force *)dst, count, src); 105 103 #else 106 104 char buf[256]; 105 + size_t res = 0; 106 + 107 107 while (count) { 108 108 size_t c = count; 109 109 if (c > sizeof(buf)) 110 110 c = sizeof(buf); 111 111 if (copy_from_iter(buf, c, src) != c) 112 - return -EFAULT; 112 + return res; 113 113 memcpy_toio(dst, buf, c); 114 114 count -= c; 115 115 dst += c; 116 + res += c; 116 117 } 117 - return 0; 118 + return res; 118 119 #endif 119 120 } 120 121 EXPORT_SYMBOL(copy_from_iter_toio);
+6 -2
sound/pci/nm256/nm256.c
··· 696 696 struct snd_pcm_runtime *runtime = substream->runtime; 697 697 struct nm256_stream *s = runtime->private_data; 698 698 699 - return copy_from_iter_toio(s->bufptr + pos, src, count); 699 + if (copy_from_iter_toio(s->bufptr + pos, count, src) != count) 700 + return -EFAULT; 701 + return 0; 700 702 } 701 703 702 704 /* ··· 712 710 struct snd_pcm_runtime *runtime = substream->runtime; 713 711 struct nm256_stream *s = runtime->private_data; 714 712 715 - return copy_to_iter_fromio(dst, s->bufptr + pos, count); 713 + if (copy_to_iter_fromio(s->bufptr + pos, count, dst) != count) 714 + return -EFAULT; 715 + return 0; 716 716 } 717 717 718 718 #endif /* !__i386__ */
+8 -5
sound/pci/rme32.c
··· 256 256 { 257 257 struct rme32 *rme32 = snd_pcm_substream_chip(substream); 258 258 259 - return copy_from_iter_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 260 - src, count); 259 + if (copy_from_iter_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 260 + count, src) != count) 261 + return -EFAULT; 262 + return 0; 261 263 } 262 264 263 265 /* copy callback for halfduplex mode */ ··· 269 267 { 270 268 struct rme32 *rme32 = snd_pcm_substream_chip(substream); 271 269 272 - return copy_to_iter_fromio(dst, 273 - rme32->iobase + RME32_IO_DATA_BUFFER + pos, 274 - count); 270 + if (copy_to_iter_fromio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 271 + count, dst) != count) 272 + return -EFAULT; 273 + return 0; 275 274 } 276 275 277 276 /*
+8 -5
sound/pci/rme96.c
··· 322 322 { 323 323 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 324 324 325 - return copy_from_iter_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, 326 - src, count); 325 + if (copy_from_iter_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, 326 + count, src) != count) 327 + return -EFAULT; 328 + return 0; 327 329 } 328 330 329 331 static int ··· 335 333 { 336 334 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 337 335 338 - return copy_to_iter_fromio(dst, 339 - rme96->iobase + RME96_IO_REC_BUFFER + pos, 340 - count); 336 + if (copy_to_iter_fromio(rme96->iobase + RME96_IO_REC_BUFFER + pos, 337 + count, dst) != count) 338 + return -EFAULT; 339 + return 0; 341 340 } 342 341 343 342 /*
+4 -2
sound/soc/qcom/lpass-platform.c
··· 1232 1232 1233 1233 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1234 1234 if (is_cdc_dma_port(dai_id)) { 1235 - ret = copy_from_iter_toio(dma_buf, buf, bytes); 1235 + if (copy_from_iter_toio(dma_buf, bytes, buf) != bytes) 1236 + ret = -EFAULT; 1236 1237 } else { 1237 1238 if (copy_from_iter((void __force *)dma_buf, bytes, buf) != bytes) 1238 1239 ret = -EFAULT; 1239 1240 } 1240 1241 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 1241 1242 if (is_cdc_dma_port(dai_id)) { 1242 - ret = copy_to_iter_fromio(buf, dma_buf, bytes); 1243 + if (copy_to_iter_fromio(dma_buf, bytes, buf) != bytes) 1244 + ret = -EFAULT; 1243 1245 } else { 1244 1246 if (copy_to_iter((void __force *)dma_buf, bytes, buf) != bytes) 1245 1247 ret = -EFAULT;