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

drm/ttm: Remove the struct ttm_backup abstraction

The abstraction was previously added to support separate
ttm_backup implementations.

However with the current implementation casting from a
struct file to a struct ttm_backup, we run into trouble since
struct file may have randomized the layout and gcc complains.

Remove the struct ttm_backup abstraction

Cc: dri-devel@lists.freedesktop.org
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Reported-by: Kees Cook <kees@kernel.org>
Closes: https://lore.kernel.org/dri-devel/9c8dbbafdaf9f3f089da2cde5a772d69579b3795.camel@linux.intel.com/T/#mb153ab9216cb813b92bdeb36f391ad4808c2ba29
Suggested-by: Christian König <christian.koenig@amd.com>
Fixes: 70d645deac98 ("drm/ttm: Add helpers for shrinking")
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/r/20250502130014.3156-1-thomas.hellstrom@linux.intel.com

+21 -43
+11 -31
drivers/gpu/drm/ttm/ttm_backup.c
··· 8 8 #include <linux/swap.h> 9 9 10 10 /* 11 - * Casting from randomized struct file * to struct ttm_backup * is fine since 12 - * struct ttm_backup is never defined nor dereferenced. 13 - */ 14 - static struct file *ttm_backup_to_file(struct ttm_backup *backup) 15 - { 16 - return (void *)backup; 17 - } 18 - 19 - static struct ttm_backup *ttm_file_to_backup(struct file *file) 20 - { 21 - return (void *)file; 22 - } 23 - 24 - /* 25 11 * Need to map shmem indices to handle since a handle value 26 12 * of 0 means error, following the swp_entry_t convention. 27 13 */ ··· 26 40 * @backup: The struct backup pointer used to obtain the handle 27 41 * @handle: The handle obtained from the @backup_page function. 28 42 */ 29 - void ttm_backup_drop(struct ttm_backup *backup, pgoff_t handle) 43 + void ttm_backup_drop(struct file *backup, pgoff_t handle) 30 44 { 31 45 loff_t start = ttm_backup_handle_to_shmem_idx(handle); 32 46 33 47 start <<= PAGE_SHIFT; 34 - shmem_truncate_range(file_inode(ttm_backup_to_file(backup)), start, 48 + shmem_truncate_range(file_inode(backup), start, 35 49 start + PAGE_SIZE - 1); 36 50 } 37 51 ··· 46 60 * Return: 0 on success, Negative error code on failure, notably 47 61 * -EINTR if @intr was set to true and a signal is pending. 48 62 */ 49 - int ttm_backup_copy_page(struct ttm_backup *backup, struct page *dst, 63 + int ttm_backup_copy_page(struct file *backup, struct page *dst, 50 64 pgoff_t handle, bool intr) 51 65 { 52 - struct file *filp = ttm_backup_to_file(backup); 53 - struct address_space *mapping = filp->f_mapping; 66 + struct address_space *mapping = backup->f_mapping; 54 67 struct folio *from_folio; 55 68 pgoff_t idx = ttm_backup_handle_to_shmem_idx(handle); 56 69 ··· 91 106 * the folio size- and usage. 92 107 */ 93 108 s64 94 - ttm_backup_backup_page(struct ttm_backup *backup, struct page *page, 109 + ttm_backup_backup_page(struct file *backup, struct page *page, 95 110 bool writeback, pgoff_t idx, gfp_t page_gfp, 96 111 gfp_t alloc_gfp) 97 112 { 98 - struct file *filp = ttm_backup_to_file(backup); 99 - struct address_space *mapping = filp->f_mapping; 113 + struct address_space *mapping = backup->f_mapping; 100 114 unsigned long handle = 0; 101 115 struct folio *to_folio; 102 116 int ret; ··· 145 161 * 146 162 * After a call to this function, it's illegal to use the @backup pointer. 147 163 */ 148 - void ttm_backup_fini(struct ttm_backup *backup) 164 + void ttm_backup_fini(struct file *backup) 149 165 { 150 - fput(ttm_backup_to_file(backup)); 166 + fput(backup); 151 167 } 152 168 153 169 /** ··· 178 194 * 179 195 * Create a backup utilizing shmem objects. 180 196 * 181 - * Return: A pointer to a struct ttm_backup on success, 197 + * Return: A pointer to a struct file on success, 182 198 * an error pointer on error. 183 199 */ 184 - struct ttm_backup *ttm_backup_shmem_create(loff_t size) 200 + struct file *ttm_backup_shmem_create(loff_t size) 185 201 { 186 - struct file *filp; 187 - 188 - filp = shmem_file_setup("ttm shmem backup", size, 0); 189 - 190 - return ttm_file_to_backup(filp); 202 + return shmem_file_setup("ttm shmem backup", size, 0); 191 203 }
+3 -3
drivers/gpu/drm/ttm/ttm_pool.c
··· 506 506 * if successful, populate the page-table and dma-address arrays. 507 507 */ 508 508 static int ttm_pool_restore_commit(struct ttm_pool_tt_restore *restore, 509 - struct ttm_backup *backup, 509 + struct file *backup, 510 510 const struct ttm_operation_ctx *ctx, 511 511 struct ttm_pool_alloc_state *alloc) 512 512 ··· 655 655 pgoff_t start_page, pgoff_t end_page) 656 656 { 657 657 struct page **pages = &tt->pages[start_page]; 658 - struct ttm_backup *backup = tt->backup; 658 + struct file *backup = tt->backup; 659 659 pgoff_t i, nr; 660 660 661 661 for (i = start_page; i < end_page; i += nr, pages += nr) { ··· 963 963 long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt, 964 964 const struct ttm_backup_flags *flags) 965 965 { 966 - struct ttm_backup *backup = tt->backup; 966 + struct file *backup = tt->backup; 967 967 struct page *page; 968 968 unsigned long handle; 969 969 gfp_t alloc_gfp;
+1 -1
drivers/gpu/drm/ttm/ttm_tt.c
··· 544 544 */ 545 545 int ttm_tt_setup_backup(struct ttm_tt *tt) 546 546 { 547 - struct ttm_backup *backup = 547 + struct file *backup = 548 548 ttm_backup_shmem_create(((loff_t)tt->num_pages) << PAGE_SHIFT); 549 549 550 550 if (WARN_ON_ONCE(!(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE)))
+5 -7
include/drm/ttm/ttm_backup.h
··· 9 9 #include <linux/mm_types.h> 10 10 #include <linux/shmem_fs.h> 11 11 12 - struct ttm_backup; 13 - 14 12 /** 15 13 * ttm_backup_handle_to_page_ptr() - Convert handle to struct page pointer 16 14 * @handle: The handle to convert. ··· 53 55 return (unsigned long)page >> 1; 54 56 } 55 57 56 - void ttm_backup_drop(struct ttm_backup *backup, pgoff_t handle); 58 + void ttm_backup_drop(struct file *backup, pgoff_t handle); 57 59 58 - int ttm_backup_copy_page(struct ttm_backup *backup, struct page *dst, 60 + int ttm_backup_copy_page(struct file *backup, struct page *dst, 59 61 pgoff_t handle, bool intr); 60 62 61 63 s64 62 - ttm_backup_backup_page(struct ttm_backup *backup, struct page *page, 64 + ttm_backup_backup_page(struct file *backup, struct page *page, 63 65 bool writeback, pgoff_t idx, gfp_t page_gfp, 64 66 gfp_t alloc_gfp); 65 67 66 - void ttm_backup_fini(struct ttm_backup *backup); 68 + void ttm_backup_fini(struct file *backup); 67 69 68 70 u64 ttm_backup_bytes_avail(void); 69 71 70 - struct ttm_backup *ttm_backup_shmem_create(loff_t size); 72 + struct file *ttm_backup_shmem_create(loff_t size); 71 73 72 74 #endif
+1 -1
include/drm/ttm/ttm_tt.h
··· 118 118 * ttm_tt_create() callback is responsible for assigning 119 119 * this field. 120 120 */ 121 - struct ttm_backup *backup; 121 + struct file *backup; 122 122 /** 123 123 * @caching: The current caching state of the pages, see enum 124 124 * ttm_caching.