1 // SPDX-License-Identifier: MIT
3 * Copyright © 2020 Intel Corporation
7 #include <linux/pagemap.h>
8 #include <linux/shmem_fs.h>
10 #include "gem/i915_gem_object.h"
11 #include "shmem_utils.h"
13 struct file
*shmem_create_from_data(const char *name
, void *data
, size_t len
)
18 file
= shmem_file_setup(name
, PAGE_ALIGN(len
), VM_NORESERVE
);
22 err
= shmem_write(file
, 0, data
, len
);
31 struct file
*shmem_create_from_object(struct drm_i915_gem_object
*obj
)
36 if (obj
->ops
== &i915_gem_shmem_ops
) {
37 file
= obj
->base
.filp
;
38 atomic_long_inc(&file
->f_count
);
42 ptr
= i915_gem_object_pin_map(obj
, I915_MAP_WB
);
46 file
= shmem_create_from_data("", ptr
, obj
->base
.size
);
47 i915_gem_object_unpin_map(obj
);
52 void *shmem_pin_map(struct file
*file
)
58 n_pages
= file
->f_mapping
->host
->i_size
>> PAGE_SHIFT
;
59 pages
= kvmalloc_array(n_pages
, sizeof(*pages
), GFP_KERNEL
);
63 for (i
= 0; i
< n_pages
; i
++) {
64 pages
[i
] = shmem_read_mapping_page_gfp(file
->f_mapping
, i
,
70 vaddr
= vmap(pages
, n_pages
, VM_MAP_PUT_PAGES
, PAGE_KERNEL
);
73 mapping_set_unevictable(file
->f_mapping
);
82 void shmem_unpin_map(struct file
*file
, void *ptr
)
84 mapping_clear_unevictable(file
->f_mapping
);
88 static int __shmem_rw(struct file
*file
, loff_t off
,
89 void *ptr
, size_t len
,
94 for (pfn
= off
>> PAGE_SHIFT
; len
; pfn
++) {
96 min_t(size_t, PAGE_SIZE
- offset_in_page(off
), len
);
100 page
= shmem_read_mapping_page_gfp(file
->f_mapping
, pfn
,
103 return PTR_ERR(page
);
107 memcpy(vaddr
+ offset_in_page(off
), ptr
, this);
108 set_page_dirty(page
);
110 memcpy(ptr
, vaddr
+ offset_in_page(off
), this);
112 mark_page_accessed(page
);
124 int shmem_read(struct file
*file
, loff_t off
, void *dst
, size_t len
)
126 return __shmem_rw(file
, off
, dst
, len
, false);
129 int shmem_write(struct file
*file
, loff_t off
, void *src
, size_t len
)
131 return __shmem_rw(file
, off
, src
, len
, true);
134 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
135 #include "st_shmem_utils.c"