Skip to content

Commit ef7efa6

Browse files
zackrgregkh
authored andcommitted
drm/ttm: Make sure the mapped tt pages are decrypted when needed
commit 71ce046327cfd3aef3f93d1c44e091395eb03f8f upstream. Some drivers require the mapped tt pages to be decrypted. In an ideal world this would have been handled by the dma layer, but the TTM page fault handling would have to be rewritten to able to do that. A side-effect of the TTM page fault handling is using a dma allocation per order (via ttm_pool_alloc_page) which makes it impossible to just trivially use dma_mmap_attrs. As a result ttm has to be very careful about trying to make its pgprot for the mapped tt pages match what the dma layer thinks it is. At the ttm layer it's possible to deduce the requirement to have tt pages decrypted by checking whether coherent dma allocations have been requested and the system is running with confidential computing technologies. This approach isn't ideal but keeping TTM matching DMAs expectations for the page properties is in general fragile, unfortunately proper fix would require a rewrite of TTM's page fault handling. Fixes vmwgfx with SEV enabled. v2: Explicitly include cc_platform.h v3: Use CC_ATTR_GUEST_MEM_ENCRYPT instead of CC_ATTR_MEM_ENCRYPT to limit the scope to guests and log when memory decryption is enabled. Signed-off-by: Zack Rusin <[email protected]> Fixes: 3bf3710 ("drm/ttm: Add a generic TTM memcpy move for page-based iomem") Reviewed-by: Thomas Hellström <[email protected]> Acked-by: Christian König <[email protected]> Cc: Huang Rui <[email protected]> Cc: [email protected] Cc: [email protected] Cc: <[email protected]> # v5.14+ Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Ye Li <[email protected]> Signed-off-by: Ajay Kaher <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 7ca7b66 commit ef7efa6

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

drivers/gpu/drm/ttm/ttm_bo_util.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,13 @@ pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res,
274274
enum ttm_caching caching;
275275

276276
man = ttm_manager_type(bo->bdev, res->mem_type);
277-
caching = man->use_tt ? bo->ttm->caching : res->bus.caching;
277+
if (man->use_tt) {
278+
caching = bo->ttm->caching;
279+
if (bo->ttm->page_flags & TTM_TT_FLAG_DECRYPTED)
280+
tmp = pgprot_decrypted(tmp);
281+
} else {
282+
caching = res->bus.caching;
283+
}
278284

279285
return ttm_prot_from_caching(caching, tmp);
280286
}
@@ -317,6 +323,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
317323
.no_wait_gpu = false
318324
};
319325
struct ttm_tt *ttm = bo->ttm;
326+
struct ttm_resource_manager *man =
327+
ttm_manager_type(bo->bdev, bo->resource->mem_type);
320328
pgprot_t prot;
321329
int ret;
322330

@@ -326,7 +334,8 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
326334
if (ret)
327335
return ret;
328336

329-
if (num_pages == 1 && ttm->caching == ttm_cached) {
337+
if (num_pages == 1 && ttm->caching == ttm_cached &&
338+
!(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) {
330339
/*
331340
* We're mapping a single page, and the desired
332341
* page protection is consistent with the bo.

drivers/gpu/drm/ttm/ttm_tt.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@
3131

3232
#define pr_fmt(fmt) "[TTM] " fmt
3333

34+
#include <linux/cc_platform.h>
3435
#include <linux/sched.h>
3536
#include <linux/shmem_fs.h>
3637
#include <linux/file.h>
3738
#include <linux/module.h>
3839
#include <drm/drm_cache.h>
40+
#include <drm/drm_device.h>
3941
#include <drm/ttm/ttm_bo_driver.h>
4042

4143
#include "ttm_module.h"
@@ -59,6 +61,7 @@ static atomic_long_t ttm_dma32_pages_allocated;
5961
int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc)
6062
{
6163
struct ttm_device *bdev = bo->bdev;
64+
struct drm_device *ddev = bo->base.dev;
6265
uint32_t page_flags = 0;
6366

6467
dma_resv_assert_held(bo->base.resv);
@@ -80,6 +83,15 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc)
8083
pr_err("Illegal buffer object type\n");
8184
return -EINVAL;
8285
}
86+
/*
87+
* When using dma_alloc_coherent with memory encryption the
88+
* mapped TT pages need to be decrypted or otherwise the drivers
89+
* will end up sending encrypted mem to the gpu.
90+
*/
91+
if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
92+
page_flags |= TTM_TT_FLAG_DECRYPTED;
93+
drm_info(ddev, "TT memory decryption enabled.");
94+
}
8395

8496
bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags);
8597
if (unlikely(bo->ttm == NULL))

include/drm/ttm/ttm_tt.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ struct ttm_tt {
7979
* page_flags = TTM_TT_FLAG_EXTERNAL |
8080
* TTM_TT_FLAG_EXTERNAL_MAPPABLE;
8181
*
82+
* TTM_TT_FLAG_DECRYPTED: The mapped ttm pages should be marked as
83+
* not encrypted. The framework will try to match what the dma layer
84+
* is doing, but note that it is a little fragile because ttm page
85+
* fault handling abuses the DMA api a bit and dma_map_attrs can't be
86+
* used to assure pgprot always matches.
87+
*
8288
* TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. This is
8389
* set by TTM after ttm_tt_populate() has successfully returned, and is
8490
* then unset when TTM calls ttm_tt_unpopulate().
@@ -87,6 +93,7 @@ struct ttm_tt {
8793
#define TTM_TT_FLAG_ZERO_ALLOC (1 << 1)
8894
#define TTM_TT_FLAG_EXTERNAL (1 << 2)
8995
#define TTM_TT_FLAG_EXTERNAL_MAPPABLE (1 << 3)
96+
#define TTM_TT_FLAG_DECRYPTED (1 << 4)
9097

9198
#define TTM_TT_FLAG_PRIV_POPULATED (1U << 31)
9299
uint32_t page_flags;

0 commit comments

Comments
 (0)