All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/ttm: set TTM allocated pages as reserved
@ 2023-03-29 13:54 Christian König
  2023-03-29 14:28 ` Paolo Bonzini
  0 siblings, 1 reply; 13+ messages in thread
From: Christian König @ 2023-03-29 13:54 UTC (permalink / raw)
  To: dri-devel; +Cc: pbonzini, npiggin, Pierre-eric.Pelloux-prayer

KVM tries to grab references to pages in VMAs marked with VM_PFNMAP.

This is illegal and can cause data corruption with TTM pages because
only some of them are actually reference counted.

Mark all pages allocated by TTM as reserved, this way KVM handles the
PFNs like they would point to MMIO space.

This still results in a warning, but at least no other problem.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/ttm/ttm_pool.c | 62 ++++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index aa116a7bbae3..c665a8bf366a 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -82,6 +82,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
 	unsigned long attr = DMA_ATTR_FORCE_CONTIGUOUS;
 	struct ttm_pool_dma *dma;
 	struct page *p;
+	unsigned int i;
 	void *vaddr;
 
 	/* Don't set the __GFP_COMP flag for higher order allocations.
@@ -94,38 +95,43 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
 
 	if (!pool->use_dma_alloc) {
 		p = alloc_pages(gfp_flags, order);
-		if (p)
-			p->private = order;
-		return p;
-	}
+		if (!p)
+			return NULL;
 
-	dma = kmalloc(sizeof(*dma), GFP_KERNEL);
-	if (!dma)
-		return NULL;
+		p->private = order;
+	} else {
 
-	if (order)
-		attr |= DMA_ATTR_NO_WARN;
+		dma = kmalloc(sizeof(*dma), GFP_KERNEL);
+		if (!dma)
+			return NULL;
 
-	vaddr = dma_alloc_attrs(pool->dev, (1ULL << order) * PAGE_SIZE,
-				&dma->addr, gfp_flags, attr);
-	if (!vaddr)
-		goto error_free;
+		if (order)
+			attr |= DMA_ATTR_NO_WARN;
 
-	/* TODO: This is an illegal abuse of the DMA API, but we need to rework
-	 * TTM page fault handling and extend the DMA API to clean this up.
-	 */
-	if (is_vmalloc_addr(vaddr))
-		p = vmalloc_to_page(vaddr);
-	else
-		p = virt_to_page(vaddr);
+		vaddr = dma_alloc_attrs(pool->dev, (1ULL << order) * PAGE_SIZE,
+					&dma->addr, gfp_flags, attr);
+		if (!vaddr) {
+			kfree(dma);
+			return NULL;
+		}
 
-	dma->vaddr = (unsigned long)vaddr | order;
-	p->private = (unsigned long)dma;
-	return p;
+		/* TODO: This is an illegal abuse of the DMA API, but we need
+		 * to rework TTM page fault handling and extend the DMA API to
+		 * clean this up.
+		 */
+		if (is_vmalloc_addr(vaddr))
+			p = vmalloc_to_page(vaddr);
+		else
+			p = virt_to_page(vaddr);
 
-error_free:
-	kfree(dma);
-	return NULL;
+		dma->vaddr = (unsigned long)vaddr | order;
+		p->private = (unsigned long)dma;
+	}
+
+	for (i = 0; i < (1 << order); ++i)
+		SetPageReserved(&p[i]);
+
+	return p;
 }
 
 /* Reset the caching and pages of size 1 << order */
@@ -134,6 +140,7 @@ static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
 {
 	unsigned long attr = DMA_ATTR_FORCE_CONTIGUOUS;
 	struct ttm_pool_dma *dma;
+	unsigned int i;
 	void *vaddr;
 
 #ifdef CONFIG_X86
@@ -144,6 +151,9 @@ static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
 		set_pages_wb(p, 1 << order);
 #endif
 
+	for (i = 0; i < (1 << order); ++i)
+		ClearPageReserved(&p[i]);
+
 	if (!pool || !pool->use_dma_alloc) {
 		__free_pages(p, order);
 		return;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2023-03-30  9:41 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-29 13:54 [PATCH] drm/ttm: set TTM allocated pages as reserved Christian König
2023-03-29 14:28 ` Paolo Bonzini
2023-03-29 15:08   ` Paolo Bonzini
2023-03-29 15:29     ` Christian König
2023-03-29 15:51       ` Paolo Bonzini
2023-03-29 16:43         ` Christian König
2023-03-29 16:56           ` Paolo Bonzini
2023-03-29 17:22             ` Sean Christopherson
2023-03-29 17:31               ` Christian König
2023-03-29 17:39                 ` Sean Christopherson
2023-03-29 17:43                   ` Christian König
2023-03-29 18:40                     ` Sean Christopherson
2023-03-30  9:41               ` David Stevens

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.