2 * SPDX-License-Identifier: MIT
4 * Copyright © 2014-2016 Intel Corporation
7 #include <linux/highmem.h>
8 #include <linux/shmem_fs.h>
9 #include <linux/swap.h>
11 #include <drm/drm.h> /* for drm_legacy.h! */
12 #include <drm/drm_cache.h>
14 #include "gt/intel_gt.h"
16 #include "i915_gem_object.h"
17 #include "i915_gem_region.h"
18 #include "i915_scatterlist.h"
20 static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object
*obj
)
22 struct address_space
*mapping
= obj
->base
.filp
->f_mapping
;
23 struct scatterlist
*sg
;
30 if (GEM_WARN_ON(i915_gem_object_needs_bit17_swizzle(obj
)))
34 * Always aligning to the object size, allows a single allocation
35 * to handle all possible callers, and given typical object sizes,
36 * the alignment of the buddy allocation will naturally match.
38 vaddr
= dma_alloc_coherent(&obj
->base
.dev
->pdev
->dev
,
39 roundup_pow_of_two(obj
->base
.size
),
44 st
= kmalloc(sizeof(*st
), GFP_KERNEL
);
48 if (sg_alloc_table(st
, 1, GFP_KERNEL
))
53 sg
->length
= obj
->base
.size
;
55 sg_assign_page(sg
, (struct page
*)vaddr
);
56 sg_dma_address(sg
) = dma
;
57 sg_dma_len(sg
) = obj
->base
.size
;
60 for (i
= 0; i
< obj
->base
.size
/ PAGE_SIZE
; i
++) {
64 page
= shmem_read_mapping_page(mapping
, i
);
68 src
= kmap_atomic(page
);
69 memcpy(dst
, src
, PAGE_SIZE
);
70 drm_clflush_virt_range(dst
, PAGE_SIZE
);
77 intel_gt_chipset_flush(&to_i915(obj
->base
.dev
)->gt
);
79 __i915_gem_object_set_pages(obj
, st
, sg
->length
);
86 dma_free_coherent(&obj
->base
.dev
->pdev
->dev
,
87 roundup_pow_of_two(obj
->base
.size
),
93 i915_gem_object_put_pages_phys(struct drm_i915_gem_object
*obj
,
94 struct sg_table
*pages
)
96 dma_addr_t dma
= sg_dma_address(pages
->sgl
);
97 void *vaddr
= sg_page(pages
->sgl
);
99 __i915_gem_object_release_shmem(obj
, pages
, false);
102 struct address_space
*mapping
= obj
->base
.filp
->f_mapping
;
106 for (i
= 0; i
< obj
->base
.size
/ PAGE_SIZE
; i
++) {
110 page
= shmem_read_mapping_page(mapping
, i
);
114 dst
= kmap_atomic(page
);
115 drm_clflush_virt_range(src
, PAGE_SIZE
);
116 memcpy(dst
, src
, PAGE_SIZE
);
119 set_page_dirty(page
);
120 if (obj
->mm
.madv
== I915_MADV_WILLNEED
)
121 mark_page_accessed(page
);
126 obj
->mm
.dirty
= false;
129 sg_free_table(pages
);
132 dma_free_coherent(&obj
->base
.dev
->pdev
->dev
,
133 roundup_pow_of_two(obj
->base
.size
),
138 phys_pwrite(struct drm_i915_gem_object
*obj
,
139 const struct drm_i915_gem_pwrite
*args
)
141 void *vaddr
= sg_page(obj
->mm
.pages
->sgl
) + args
->offset
;
142 char __user
*user_data
= u64_to_user_ptr(args
->data_ptr
);
145 err
= i915_gem_object_wait(obj
,
146 I915_WAIT_INTERRUPTIBLE
|
148 MAX_SCHEDULE_TIMEOUT
);
153 * We manually control the domain here and pretend that it
154 * remains coherent i.e. in the GTT domain, like shmem_pwrite.
156 i915_gem_object_invalidate_frontbuffer(obj
, ORIGIN_CPU
);
158 if (copy_from_user(vaddr
, user_data
, args
->size
))
161 drm_clflush_virt_range(vaddr
, args
->size
);
162 intel_gt_chipset_flush(&to_i915(obj
->base
.dev
)->gt
);
164 i915_gem_object_flush_frontbuffer(obj
, ORIGIN_CPU
);
169 phys_pread(struct drm_i915_gem_object
*obj
,
170 const struct drm_i915_gem_pread
*args
)
172 void *vaddr
= sg_page(obj
->mm
.pages
->sgl
) + args
->offset
;
173 char __user
*user_data
= u64_to_user_ptr(args
->data_ptr
);
176 err
= i915_gem_object_wait(obj
,
177 I915_WAIT_INTERRUPTIBLE
,
178 MAX_SCHEDULE_TIMEOUT
);
182 drm_clflush_virt_range(vaddr
, args
->size
);
183 if (copy_to_user(user_data
, vaddr
, args
->size
))
189 static void phys_release(struct drm_i915_gem_object
*obj
)
191 fput(obj
->base
.filp
);
194 static const struct drm_i915_gem_object_ops i915_gem_phys_ops
= {
195 .name
= "i915_gem_object_phys",
196 .get_pages
= i915_gem_object_get_pages_phys
,
197 .put_pages
= i915_gem_object_put_pages_phys
,
200 .pwrite
= phys_pwrite
,
202 .release
= phys_release
,
205 int i915_gem_object_attach_phys(struct drm_i915_gem_object
*obj
, int align
)
207 struct sg_table
*pages
;
210 if (align
> obj
->base
.size
)
213 if (obj
->ops
== &i915_gem_phys_ops
)
216 if (obj
->ops
!= &i915_gem_shmem_ops
)
219 err
= i915_gem_object_unbind(obj
, I915_GEM_OBJECT_UNBIND_ACTIVE
);
223 mutex_lock_nested(&obj
->mm
.lock
, I915_MM_GET_PAGES
);
225 if (obj
->mm
.madv
!= I915_MADV_WILLNEED
) {
230 if (obj
->mm
.quirked
) {
235 if (obj
->mm
.mapping
) {
240 pages
= __i915_gem_object_unset_pages(obj
);
242 obj
->ops
= &i915_gem_phys_ops
;
244 err
= ____i915_gem_object_get_pages(obj
);
248 /* Perma-pin (until release) the physical set of pages */
249 __i915_gem_object_pin_pages(obj
);
251 if (!IS_ERR_OR_NULL(pages
))
252 i915_gem_shmem_ops
.put_pages(obj
, pages
);
254 i915_gem_object_release_memory_region(obj
);
256 mutex_unlock(&obj
->mm
.lock
);
260 obj
->ops
= &i915_gem_shmem_ops
;
261 if (!IS_ERR_OR_NULL(pages
)) {
262 unsigned int sg_page_sizes
= i915_sg_page_sizes(pages
->sgl
);
264 __i915_gem_object_set_pages(obj
, pages
, sg_page_sizes
);
267 mutex_unlock(&obj
->mm
.lock
);
271 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
272 #include "selftests/i915_gem_phys.c"