| From c1aefbdd050e1fb15e92bcaf34d95b17ea952097 Mon Sep 17 00:00:00 2001 |
| From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> |
| Date: Mon, 17 Nov 2014 09:14:31 +0000 |
| Subject: spi: Fix mapping from vmalloc-ed buffer to scatter list |
| |
| From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> |
| |
| commit c1aefbdd050e1fb15e92bcaf34d95b17ea952097 upstream. |
| |
| We can only use page_address on memory that has been mapped using kmap, |
| when the buffer passed to the SPI has been allocated by vmalloc the page |
| has not necessarily been mapped through kmap. This means sometimes |
| page_address will return NULL causing the pointer we pass to sg_set_buf |
| to be invalid. |
| |
| As we only call page_address so that we can pass a virtual address to |
| sg_set_buf which will then immediately call virt_to_page on it, fix this |
| by calling sg_set_page directly rather then relying on the sg_set_buf |
| helper. |
| |
| Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/spi/spi.c | 6 +++--- |
| 1 file changed, 3 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/spi/spi.c |
| +++ b/drivers/spi/spi.c |
| @@ -609,13 +609,13 @@ static int spi_map_buf(struct spi_master |
| sg_free_table(sgt); |
| return -ENOMEM; |
| } |
| - sg_buf = page_address(vm_page) + |
| - ((size_t)buf & ~PAGE_MASK); |
| + sg_set_page(&sgt->sgl[i], vm_page, |
| + min, offset_in_page(buf)); |
| } else { |
| sg_buf = buf; |
| + sg_set_buf(&sgt->sgl[i], sg_buf, min); |
| } |
| |
| - sg_set_buf(&sgt->sgl[i], sg_buf, min); |
| |
| buf += min; |
| len -= min; |