spi: remove some spidev oops-on-rmmod paths

Somehow the spidev code forgot to include a critical mechanism: when the
underlying device is removed (e.g. spi_master rmmod), open file
descriptors must be prevented from issuing new I/O requests to that
device. On penalty of the oopsing reported by Sebastian Siewior
<bigeasy@tglx.de> ...

This is a partial fix, adding handshaking between the lower level (SPI
messaging) and the file operations using the spi_dev. (It also fixes an
issue where reads and writes didn't return the number of bytes sent or
received.)

There's still a refcounting issue to be addressed (separately).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Reported-by: Sebastian Siewior <bigeasy@tglx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by David Brownell and committed by Linus Torvalds 25d5cb4b 5c02b575

+89 -13
+89 -13
drivers/spi/spidev.c
··· 68 69 struct spidev_data { 70 struct device dev; 71 struct spi_device *spi; 72 struct list_head device_entry; 73 ··· 86 87 /*-------------------------------------------------------------------------*/ 88 89 /* Read-only message with current device setup */ 90 static ssize_t 91 spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) 92 { 93 struct spidev_data *spidev; 94 - struct spi_device *spi; 95 ssize_t status = 0; 96 97 /* chipselect only toggles at start or end of operation */ ··· 162 return -EMSGSIZE; 163 164 spidev = filp->private_data; 165 - spi = spidev->spi; 166 167 mutex_lock(&spidev->buf_lock); 168 - status = spi_read(spi, spidev->buffer, count); 169 if (status == 0) { 170 unsigned long missing; 171 ··· 185 size_t count, loff_t *f_pos) 186 { 187 struct spidev_data *spidev; 188 - struct spi_device *spi; 189 ssize_t status = 0; 190 unsigned long missing; 191 ··· 193 return -EMSGSIZE; 194 195 spidev = filp->private_data; 196 - spi = spidev->spi; 197 198 mutex_lock(&spidev->buf_lock); 199 missing = copy_from_user(spidev->buffer, buf, count); 200 if (missing == 0) { 201 - status = spi_write(spi, spidev->buffer, count); 202 if (status == 0) 203 status = count; 204 } else ··· 214 struct spi_transfer *k_xfers; 215 struct spi_transfer *k_tmp; 216 struct spi_ioc_transfer *u_tmp; 217 - struct spi_device *spi = spidev->spi; 218 unsigned n, total; 219 u8 *buf; 220 int status = -EFAULT; ··· 275 spi_message_add_tail(k_tmp, &msg); 276 } 277 278 - status = spi_sync(spi, &msg); 279 if (status < 0) 280 goto done; 281 ··· 329 if (err) 330 return -EFAULT; 331 332 spidev = filp->private_data; 333 - spi = spidev->spi; 334 335 switch (cmd) { 336 /* read requests */ ··· 424 default: 425 /* segmented and/or full-duplex I/O request */ 426 if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) 427 - || _IOC_DIR(cmd) != _IOC_WRITE) 428 - return -ENOTTY; 429 430 tmp = _IOC_SIZE(cmd); 431 if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { ··· 455 kfree(ioc); 456 break; 457 } 458 return retval; 459 } 460 ··· 559 560 /* Initialize the driver data */ 561 spidev->spi = spi; 562 mutex_init(&spidev->buf_lock); 563 564 INIT_LIST_HEAD(&spidev->device_entry); ··· 598 { 599 struct spidev_data *spidev = dev_get_drvdata(&spi->dev); 600 601 - mutex_lock(&device_list_lock); 602 603 list_del(&spidev->device_entry); 604 dev_set_drvdata(&spi->dev, NULL); 605 clear_bit(MINOR(spidev->dev.devt), minors); 606 device_unregister(&spidev->dev); 607 - 608 mutex_unlock(&device_list_lock); 609 610 return 0;
··· 68 69 struct spidev_data { 70 struct device dev; 71 + spinlock_t spi_lock; 72 struct spi_device *spi; 73 struct list_head device_entry; 74 ··· 85 86 /*-------------------------------------------------------------------------*/ 87 88 + /* 89 + * We can't use the standard synchronous wrappers for file I/O; we 90 + * need to protect against async removal of the underlying spi_device. 91 + */ 92 + static void spidev_complete(void *arg) 93 + { 94 + complete(arg); 95 + } 96 + 97 + static ssize_t 98 + spidev_sync(struct spidev_data *spidev, struct spi_message *message) 99 + { 100 + DECLARE_COMPLETION_ONSTACK(done); 101 + int status; 102 + 103 + message->complete = spidev_complete; 104 + message->context = &done; 105 + 106 + spin_lock_irq(&spidev->spi_lock); 107 + if (spidev->spi == NULL) 108 + status = -ESHUTDOWN; 109 + else 110 + status = spi_async(spidev->spi, message); 111 + spin_unlock_irq(&spidev->spi_lock); 112 + 113 + if (status == 0) { 114 + wait_for_completion(&done); 115 + status = message->status; 116 + if (status == 0) 117 + status = message->actual_length; 118 + } 119 + return status; 120 + } 121 + 122 + static inline ssize_t 123 + spidev_sync_write(struct spidev_data *spidev, size_t len) 124 + { 125 + struct spi_transfer t = { 126 + .tx_buf = spidev->buffer, 127 + .len = len, 128 + }; 129 + struct spi_message m; 130 + 131 + spi_message_init(&m); 132 + spi_message_add_tail(&t, &m); 133 + return spidev_sync(spidev, &m); 134 + } 135 + 136 + static inline ssize_t 137 + spidev_sync_read(struct spidev_data *spidev, size_t len) 138 + { 139 + struct spi_transfer t = { 140 + .rx_buf = spidev->buffer, 141 + .len = len, 142 + }; 143 + struct spi_message m; 144 + 145 + spi_message_init(&m); 146 + spi_message_add_tail(&t, &m); 147 + return spidev_sync(spidev, &m); 148 + } 149 + 150 + /*-------------------------------------------------------------------------*/ 151 + 152 /* Read-only message with current device setup */ 153 static ssize_t 154 spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) 155 { 156 struct spidev_data *spidev; 157 ssize_t status = 0; 158 159 /* chipselect only toggles at start or end of operation */ ··· 98 return -EMSGSIZE; 99 100 spidev = filp->private_data; 101 102 mutex_lock(&spidev->buf_lock); 103 + status = spidev_sync_read(spidev, count); 104 if (status == 0) { 105 unsigned long missing; 106 ··· 122 size_t count, loff_t *f_pos) 123 { 124 struct spidev_data *spidev; 125 ssize_t status = 0; 126 unsigned long missing; 127 ··· 131 return -EMSGSIZE; 132 133 spidev = filp->private_data; 134 135 mutex_lock(&spidev->buf_lock); 136 missing = copy_from_user(spidev->buffer, buf, count); 137 if (missing == 0) { 138 + status = spidev_sync_write(spidev, count); 139 if (status == 0) 140 status = count; 141 } else ··· 153 struct spi_transfer *k_xfers; 154 struct spi_transfer *k_tmp; 155 struct spi_ioc_transfer *u_tmp; 156 unsigned n, total; 157 u8 *buf; 158 int status = -EFAULT; ··· 215 spi_message_add_tail(k_tmp, &msg); 216 } 217 218 + status = spidev_sync(spidev, &msg); 219 if (status < 0) 220 goto done; 221 ··· 269 if (err) 270 return -EFAULT; 271 272 + /* guard against device removal before, or while, 273 + * we issue this ioctl. 274 + */ 275 spidev = filp->private_data; 276 + spin_lock_irq(&spidev->spi_lock); 277 + spi = spi_dev_get(spidev->spi); 278 + spin_unlock_irq(&spidev->spi_lock); 279 + 280 + if (spi == NULL) 281 + return -ESHUTDOWN; 282 283 switch (cmd) { 284 /* read requests */ ··· 356 default: 357 /* segmented and/or full-duplex I/O request */ 358 if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) 359 + || _IOC_DIR(cmd) != _IOC_WRITE) { 360 + retval = -ENOTTY; 361 + break; 362 + } 363 364 tmp = _IOC_SIZE(cmd); 365 if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { ··· 385 kfree(ioc); 386 break; 387 } 388 + spi_dev_put(spi); 389 return retval; 390 } 391 ··· 488 489 /* Initialize the driver data */ 490 spidev->spi = spi; 491 + spin_lock_init(&spidev->spi_lock); 492 mutex_init(&spidev->buf_lock); 493 494 INIT_LIST_HEAD(&spidev->device_entry); ··· 526 { 527 struct spidev_data *spidev = dev_get_drvdata(&spi->dev); 528 529 + /* make sure ops on existing fds can abort cleanly */ 530 + spin_lock_irq(&spidev->spi_lock); 531 + spidev->spi = NULL; 532 + spin_unlock_irq(&spidev->spi_lock); 533 534 + /* prevent new opens */ 535 + mutex_lock(&device_list_lock); 536 list_del(&spidev->device_entry); 537 dev_set_drvdata(&spi->dev, NULL); 538 clear_bit(MINOR(spidev->dev.devt), minors); 539 device_unregister(&spidev->dev); 540 mutex_unlock(&device_list_lock); 541 542 return 0;