Skip to content

Commit 0eb0feb

Browse files
icklerodrigovivi
authored andcommitted
drm/i915/gem: Pull phys pread/pwrite implementations to the backend
Move the specialised interactions with the physical GEM object from the pread/pwrite ioctl handler into the phys backend. Currently, if one is able to exhaust the entire aperture and then try to pwrite into an object not backed by struct page, we accidentally invoked the phys pwrite handler on a non-phys object; calamitous. Fixes: c6790dc ("drm/i915: Wean off drm_pci_alloc/drm_pci_free") Testcase: igt/gem_pwrite/exhaustion Signed-off-by: Chris Wilson <[email protected]> Reviewed-by: Matthew Auld <[email protected]> Cc: [email protected] Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 852e1b3) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent 0a1db6f commit 0eb0feb

File tree

2 files changed

+55
-26
lines changed

2 files changed

+55
-26
lines changed

drivers/gpu/drm/i915/gem/i915_gem_phys.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,58 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
134134
vaddr, dma);
135135
}
136136

137+
static int
138+
phys_pwrite(struct drm_i915_gem_object *obj,
139+
const struct drm_i915_gem_pwrite *args)
140+
{
141+
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
142+
char __user *user_data = u64_to_user_ptr(args->data_ptr);
143+
int err;
144+
145+
err = i915_gem_object_wait(obj,
146+
I915_WAIT_INTERRUPTIBLE |
147+
I915_WAIT_ALL,
148+
MAX_SCHEDULE_TIMEOUT);
149+
if (err)
150+
return err;
151+
152+
/*
153+
* We manually control the domain here and pretend that it
154+
* remains coherent i.e. in the GTT domain, like shmem_pwrite.
155+
*/
156+
i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
157+
158+
if (copy_from_user(vaddr, user_data, args->size))
159+
return -EFAULT;
160+
161+
drm_clflush_virt_range(vaddr, args->size);
162+
intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
163+
164+
i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
165+
return 0;
166+
}
167+
168+
static int
169+
phys_pread(struct drm_i915_gem_object *obj,
170+
const struct drm_i915_gem_pread *args)
171+
{
172+
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
173+
char __user *user_data = u64_to_user_ptr(args->data_ptr);
174+
int err;
175+
176+
err = i915_gem_object_wait(obj,
177+
I915_WAIT_INTERRUPTIBLE,
178+
MAX_SCHEDULE_TIMEOUT);
179+
if (err)
180+
return err;
181+
182+
drm_clflush_virt_range(vaddr, args->size);
183+
if (copy_to_user(user_data, vaddr, args->size))
184+
return -EFAULT;
185+
186+
return 0;
187+
}
188+
137189
static void phys_release(struct drm_i915_gem_object *obj)
138190
{
139191
fput(obj->base.filp);
@@ -144,6 +196,9 @@ static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
144196
.get_pages = i915_gem_object_get_pages_phys,
145197
.put_pages = i915_gem_object_put_pages_phys,
146198

199+
.pread = phys_pread,
200+
.pwrite = phys_pwrite,
201+
147202
.release = phys_release,
148203
};
149204

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -179,30 +179,6 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
179179
return ret;
180180
}
181181

182-
static int
183-
i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
184-
struct drm_i915_gem_pwrite *args,
185-
struct drm_file *file)
186-
{
187-
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
188-
char __user *user_data = u64_to_user_ptr(args->data_ptr);
189-
190-
/*
191-
* We manually control the domain here and pretend that it
192-
* remains coherent i.e. in the GTT domain, like shmem_pwrite.
193-
*/
194-
i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
195-
196-
if (copy_from_user(vaddr, user_data, args->size))
197-
return -EFAULT;
198-
199-
drm_clflush_virt_range(vaddr, args->size);
200-
intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
201-
202-
i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
203-
return 0;
204-
}
205-
206182
static int
207183
i915_gem_create(struct drm_file *file,
208184
struct intel_memory_region *mr,
@@ -872,8 +848,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
872848
if (ret == -EFAULT || ret == -ENOSPC) {
873849
if (i915_gem_object_has_struct_page(obj))
874850
ret = i915_gem_shmem_pwrite(obj, args);
875-
else
876-
ret = i915_gem_phys_pwrite(obj, args, file);
877851
}
878852

879853
i915_gem_object_unpin_pages(obj);

0 commit comments

Comments
 (0)