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

spi: rspi: avoid uninitialized variable access

The newly introduced rspi_pio_transfer_in_or_our() function must
take either a valid 'rx' or 'tx' pointer, and has undefined behavior
if both are NULL, as found by 'gcc -Wmaybe-unintialized':

drivers/spi/spi-rspi.c: In function 'rspi_pio_transfer_in_or_our':
drivers/spi/spi-rspi.c:558:5: error: 'len' may be used uninitialized in this function [-Werror=maybe-uninitialized]

The analysis of the function is correct in principle, but the code
is currently safe because both callers always pass exactly one
of the two pointers.

Looking closer at this function shows that having a combined
method for rx and tx here actually increases the complexity
and the size of the file. This simplifies it again by keeping
the two separate, which then ends up avoiding that warning.

Fixes: 3be09bec42a8 ("spi: rspi: supports 32bytes buffer for DUAL and QUAD")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Arnd Bergmann and committed by
Mark Brown
db300838 3be09bec

+45 -49
+45 -49
drivers/spi/spi-rspi.c
··· 515 515 return 0; 516 516 } 517 517 518 - static int rspi_pio_transfer_in_or_our(struct rspi_data *rspi, const u8 *tx, 519 - u8 *rx, unsigned int n) 520 - { 521 - unsigned int i, len; 522 - int ret; 523 - 524 - while (n > 0) { 525 - if (tx) { 526 - len = qspi_set_send_trigger(rspi, n); 527 - if (len == QSPI_BUFFER_SIZE) { 528 - ret = rspi_wait_for_tx_empty(rspi); 529 - if (ret < 0) { 530 - dev_err(&rspi->master->dev, "transmit timeout\n"); 531 - return ret; 532 - } 533 - for (i = 0; i < len; i++) 534 - rspi_write_data(rspi, *tx++); 535 - } else { 536 - ret = rspi_pio_transfer(rspi, tx, NULL, n); 537 - if (ret < 0) 538 - return ret; 539 - } 540 - } 541 - if (rx) { 542 - len = qspi_set_receive_trigger(rspi, n); 543 - if (len == QSPI_BUFFER_SIZE) { 544 - ret = rspi_wait_for_rx_full(rspi); 545 - if (ret < 0) { 546 - dev_err(&rspi->master->dev, "receive timeout\n"); 547 - return ret; 548 - } 549 - for (i = 0; i < len; i++) 550 - *rx++ = rspi_read_data(rspi); 551 - } else { 552 - ret = rspi_pio_transfer(rspi, NULL, rx, n); 553 - if (ret < 0) 554 - return ret; 555 - *rx++ = ret; 556 - } 557 - } 558 - n -= len; 559 - } 560 - return 0; 561 - } 562 - 563 518 static void rspi_dma_complete(void *arg) 564 519 { 565 520 struct rspi_data *rspi = arg; ··· 786 831 787 832 static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) 788 833 { 834 + const u8 *tx = xfer->tx_buf; 835 + unsigned int n = xfer->len; 836 + unsigned int i, len; 789 837 int ret; 790 838 791 839 if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { ··· 797 839 return ret; 798 840 } 799 841 800 - ret = rspi_pio_transfer_in_or_our(rspi, xfer->tx_buf, NULL, xfer->len); 801 - if (ret < 0) 802 - return ret; 842 + while (n > 0) { 843 + len = qspi_set_send_trigger(rspi, n); 844 + if (len == QSPI_BUFFER_SIZE) { 845 + ret = rspi_wait_for_tx_empty(rspi); 846 + if (ret < 0) { 847 + dev_err(&rspi->master->dev, "transmit timeout\n"); 848 + return ret; 849 + } 850 + for (i = 0; i < len; i++) 851 + rspi_write_data(rspi, *tx++); 852 + } else { 853 + ret = rspi_pio_transfer(rspi, tx, NULL, n); 854 + if (ret < 0) 855 + return ret; 856 + } 857 + n -= len; 858 + } 803 859 804 860 /* Wait for the last transmission */ 805 861 rspi_wait_for_tx_empty(rspi); ··· 823 851 824 852 static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) 825 853 { 854 + u8 *rx = xfer->rx_buf; 855 + unsigned int n = xfer->len; 856 + unsigned int i, len; 857 + int ret; 858 + 826 859 if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) { 827 860 int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg); 828 861 if (ret != -EAGAIN) 829 862 return ret; 830 863 } 831 864 832 - return rspi_pio_transfer_in_or_our(rspi, NULL, xfer->rx_buf, xfer->len); 865 + while (n > 0) { 866 + len = qspi_set_receive_trigger(rspi, n); 867 + if (len == QSPI_BUFFER_SIZE) { 868 + ret = rspi_wait_for_rx_full(rspi); 869 + if (ret < 0) { 870 + dev_err(&rspi->master->dev, "receive timeout\n"); 871 + return ret; 872 + } 873 + for (i = 0; i < len; i++) 874 + *rx++ = rspi_read_data(rspi); 875 + } else { 876 + ret = rspi_pio_transfer(rspi, NULL, rx, n); 877 + if (ret < 0) 878 + return ret; 879 + *rx++ = ret; 880 + } 881 + n -= len; 882 + } 883 + 884 + return 0; 833 885 } 834 886 835 887 static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,