dma_alloc_coherent() can return memory in the vmalloc range. virt_to_page() cannot handle such addresses and crashes. This patch detects such cases and obtains the struct page * using vmalloc_to_page() instead.
Signed-off-by: Alexandre Courbot acourbot@nvidia.com --- This patch is a follow-up of the following discussion:
https://www.marc.info/?l=dri-devel&m=141579595431254&w=3
It works for me on both 32-bit and 64-bit Tegra, so I am not convinced that Thierry's initial change from virt_to_page() to phys_to_page() is still required - Thierry, can you confirm whether your patch is still relevant after this one?
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 01e1d27eb078..3077f1554099 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -342,9 +342,12 @@ static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool) d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size, &d_page->dma, pool->gfp_flags); - if (d_page->vaddr) - d_page->p = virt_to_page(d_page->vaddr); - else { + if (d_page->vaddr) { + if (is_vmalloc_addr(d_page->vaddr)) + d_page->p = vmalloc_to_page(d_page->vaddr); + else + d_page->p = virt_to_page(d_page->vaddr); + } else { kfree(d_page); d_page = NULL; }
On Fri, May 15, 2015 at 04:09:54PM +0900, Alexandre Courbot wrote:
dma_alloc_coherent() can return memory in the vmalloc range. virt_to_page() cannot handle such addresses and crashes. This patch detects such cases and obtains the struct page * using vmalloc_to_page() instead.
Signed-off-by: Alexandre Courbot acourbot@nvidia.com
This patch is a follow-up of the following discussion:
https://www.marc.info/?l=dri-devel&m=141579595431254&w=3
It works for me on both 32-bit and 64-bit Tegra, so I am not convinced that Thierry's initial change from virt_to_page() to phys_to_page() is still required - Thierry, can you confirm whether your patch is still relevant after this one?
If this works for you on both 32-bit and 64-bit Tegra I don't think the earlier patch is still relevant and this looks indeed like a much more appropriate solution.
Thierry
2015-05-15 15:09 GMT+08:00 Alexandre Courbot acourbot@nvidia.com:
dma_alloc_coherent() can return memory in the vmalloc range. virt_to_page() cannot handle such addresses and crashes. This patch detects such cases and obtains the struct page * using vmalloc_to_page() instead.
Signed-off-by: Alexandre Courbot acourbot@nvidia.com
This patch is a follow-up of the following discussion:
https://www.marc.info/?l=dri-devel&m=141579595431254&w=3
It works for me on both 32-bit and 64-bit Tegra, so I am not convinced that Thierry's initial change from virt_to_page() to phys_to_page() is still required - Thierry, can you confirm whether your patch is still relevant after this one?
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 01e1d27eb078..3077f1554099 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -342,9 +342,12 @@ static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool) d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size, &d_page->dma, pool->gfp_flags);
if (d_page->vaddr)
d_page->p = virt_to_page(d_page->vaddr);
else {
if (d_page->vaddr) {
if (is_vmalloc_addr(d_page->vaddr))
d_page->p = vmalloc_to_page(d_page->vaddr);
else
d_page->p = virt_to_page(d_page->vaddr);
} else { kfree(d_page); d_page = NULL; }
-- 2.4.0
-- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
for safe , i think we can add this patch:
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index f800d45..3463f4f 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -77,7 +77,8 @@ * private definitions which should NOT be used outside memory.h * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. */ -#define __virt_to_phys(x) (((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET)) +#define __virt_to_phys(x) ({BUG_ON(x < PAGE_OFFSET);\ + (phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET;}) #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))
/*
BRs Yalin
On Fri, May 15, 2015 at 04:09:54PM +0900, Alexandre Courbot wrote:
dma_alloc_coherent() can return memory in the vmalloc range. virt_to_page() cannot handle such addresses and crashes. This patch detects such cases and obtains the struct page * using vmalloc_to_page() instead.
Signed-off-by: Alexandre Courbot acourbot@nvidia.com
This patch is a follow-up of the following discussion:
https://www.marc.info/?l=dri-devel&m=141579595431254&w=3
It works for me on both 32-bit and 64-bit Tegra, so I am not convinced that Thierry's initial change from virt_to_page() to phys_to_page() is still required - Thierry, can you confirm whether your patch is still relevant after this one?
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 01e1d27eb078..3077f1554099 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -342,9 +342,12 @@ static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool) d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size, &d_page->dma, pool->gfp_flags);
- if (d_page->vaddr)
d_page->p = virt_to_page(d_page->vaddr);
- else {
- if (d_page->vaddr) {
if (is_vmalloc_addr(d_page->vaddr))
d_page->p = vmalloc_to_page(d_page->vaddr);
else
d_page->p = virt_to_page(d_page->vaddr);
- } else {
Looks OK to me.
kfree(d_page); d_page = NULL;
}
2.4.0
On 05/16/2015 04:55 AM, Konrad Rzeszutek Wilk wrote:
On Fri, May 15, 2015 at 04:09:54PM +0900, Alexandre Courbot wrote:
dma_alloc_coherent() can return memory in the vmalloc range. virt_to_page() cannot handle such addresses and crashes. This patch detects such cases and obtains the struct page * using vmalloc_to_page() instead.
Signed-off-by: Alexandre Courbot acourbot@nvidia.com
This patch is a follow-up of the following discussion:
https://www.marc.info/?l=dri-devel&m=141579595431254&w=3
It works for me on both 32-bit and 64-bit Tegra, so I am not convinced that Thierry's initial change from virt_to_page() to phys_to_page() is still required - Thierry, can you confirm whether your patch is still relevant after this one?
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 01e1d27eb078..3077f1554099 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -342,9 +342,12 @@ static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool) d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size, &d_page->dma, pool->gfp_flags);
- if (d_page->vaddr)
d_page->p = virt_to_page(d_page->vaddr);
- else {
- if (d_page->vaddr) {
if (is_vmalloc_addr(d_page->vaddr))
d_page->p = vmalloc_to_page(d_page->vaddr);
else
d_page->p = virt_to_page(d_page->vaddr);
- } else {
Looks OK to me.
Thanks guys. Could we translate these approvals into Acked-bys/Reviewed-bys so Dave (?) can merge this patch?
On Tue, May 19, 2015 at 08:33:59PM +0900, Alexandre Courbot wrote:
On 05/16/2015 04:55 AM, Konrad Rzeszutek Wilk wrote:
On Fri, May 15, 2015 at 04:09:54PM +0900, Alexandre Courbot wrote:
dma_alloc_coherent() can return memory in the vmalloc range. virt_to_page() cannot handle such addresses and crashes. This patch detects such cases and obtains the struct page * using vmalloc_to_page() instead.
Signed-off-by: Alexandre Courbot acourbot@nvidia.com
This patch is a follow-up of the following discussion:
https://www.marc.info/?l=dri-devel&m=141579595431254&w=3
It works for me on both 32-bit and 64-bit Tegra, so I am not convinced that Thierry's initial change from virt_to_page() to phys_to_page() is still required - Thierry, can you confirm whether your patch is still relevant after this one?
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 01e1d27eb078..3077f1554099 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c @@ -342,9 +342,12 @@ static struct dma_page *__ttm_dma_alloc_page(struct dma_pool *pool) d_page->vaddr = dma_alloc_coherent(pool->dev, pool->size, &d_page->dma, pool->gfp_flags);
- if (d_page->vaddr)
d_page->p = virt_to_page(d_page->vaddr);
- else {
- if (d_page->vaddr) {
if (is_vmalloc_addr(d_page->vaddr))
d_page->p = vmalloc_to_page(d_page->vaddr);
else
d_page->p = virt_to_page(d_page->vaddr);
- } else {
Looks OK to me.
Thanks guys. Could we translate these approvals into Acked-bys/Reviewed-bys so Dave (?) can merge this patch?
Acked-by: Konrad Rzeszutek Wilk konrad.wilk@oracle.com
dri-devel@lists.freedesktop.org