Skip to content

Commit 9b984a7

Browse files
committed
Merge tag 'drm-misc-fixes-2024-11-08' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
Short summary of fixes pull: imagination: - Track PVR context per file - Break ref-counting cycle panel-orientation-quirks: - Fix matching Lenovo Yoga Tab 3 X90F panthor: - Lock VM array - Be strict about I/O mapping flags Signed-off-by: Dave Airlie <[email protected]> From: Thomas Zimmermann <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents fd836e8 + f432a16 commit 9b984a7

File tree

9 files changed

+92
-5
lines changed

9 files changed

+92
-5
lines changed

drivers/gpu/drm/drm_panel_orientation_quirks.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,6 @@ static const struct dmi_system_id orientation_data[] = {
403403
}, { /* Lenovo Yoga Tab 3 X90F */
404404
.matches = {
405405
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
406-
DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
407406
DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
408407
},
409408
.driver_data = (void *)&lcd1600x2560_rightside_up,

drivers/gpu/drm/imagination/pvr_context.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717

1818
#include <drm/drm_auth.h>
1919
#include <drm/drm_managed.h>
20+
21+
#include <linux/bug.h>
2022
#include <linux/errno.h>
2123
#include <linux/kernel.h>
24+
#include <linux/list.h>
2225
#include <linux/sched.h>
2326
#include <linux/slab.h>
27+
#include <linux/spinlock.h>
2428
#include <linux/string.h>
2529
#include <linux/types.h>
2630
#include <linux/xarray.h>
@@ -354,6 +358,10 @@ int pvr_context_create(struct pvr_file *pvr_file, struct drm_pvr_ioctl_create_co
354358
return err;
355359
}
356360

361+
spin_lock(&pvr_dev->ctx_list_lock);
362+
list_add_tail(&ctx->file_link, &pvr_file->contexts);
363+
spin_unlock(&pvr_dev->ctx_list_lock);
364+
357365
return 0;
358366

359367
err_destroy_fw_obj:
@@ -380,6 +388,11 @@ pvr_context_release(struct kref *ref_count)
380388
container_of(ref_count, struct pvr_context, ref_count);
381389
struct pvr_device *pvr_dev = ctx->pvr_dev;
382390

391+
WARN_ON(in_interrupt());
392+
spin_lock(&pvr_dev->ctx_list_lock);
393+
list_del(&ctx->file_link);
394+
spin_unlock(&pvr_dev->ctx_list_lock);
395+
383396
xa_erase(&pvr_dev->ctx_ids, ctx->ctx_id);
384397
pvr_context_destroy_queues(ctx);
385398
pvr_fw_object_destroy(ctx->fw_obj);
@@ -437,11 +450,30 @@ pvr_context_destroy(struct pvr_file *pvr_file, u32 handle)
437450
*/
438451
void pvr_destroy_contexts_for_file(struct pvr_file *pvr_file)
439452
{
453+
struct pvr_device *pvr_dev = pvr_file->pvr_dev;
440454
struct pvr_context *ctx;
441455
unsigned long handle;
442456

443457
xa_for_each(&pvr_file->ctx_handles, handle, ctx)
444458
pvr_context_destroy(pvr_file, handle);
459+
460+
spin_lock(&pvr_dev->ctx_list_lock);
461+
ctx = list_first_entry(&pvr_file->contexts, struct pvr_context, file_link);
462+
463+
while (!list_entry_is_head(ctx, &pvr_file->contexts, file_link)) {
464+
list_del_init(&ctx->file_link);
465+
466+
if (pvr_context_get_if_referenced(ctx)) {
467+
spin_unlock(&pvr_dev->ctx_list_lock);
468+
469+
pvr_vm_unmap_all(ctx->vm_ctx);
470+
471+
pvr_context_put(ctx);
472+
spin_lock(&pvr_dev->ctx_list_lock);
473+
}
474+
ctx = list_first_entry(&pvr_file->contexts, struct pvr_context, file_link);
475+
}
476+
spin_unlock(&pvr_dev->ctx_list_lock);
445477
}
446478

447479
/**
@@ -451,6 +483,7 @@ void pvr_destroy_contexts_for_file(struct pvr_file *pvr_file)
451483
void pvr_context_device_init(struct pvr_device *pvr_dev)
452484
{
453485
xa_init_flags(&pvr_dev->ctx_ids, XA_FLAGS_ALLOC1);
486+
spin_lock_init(&pvr_dev->ctx_list_lock);
454487
}
455488

456489
/**

drivers/gpu/drm/imagination/pvr_context.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ struct pvr_context {
8585
/** @compute: Transfer queue. */
8686
struct pvr_queue *transfer;
8787
} queues;
88+
89+
/** @file_link: pvr_file PVR context list link. */
90+
struct list_head file_link;
8891
};
8992

9093
static __always_inline struct pvr_queue *
@@ -123,6 +126,24 @@ pvr_context_get(struct pvr_context *ctx)
123126
return ctx;
124127
}
125128

129+
/**
130+
* pvr_context_get_if_referenced() - Take an additional reference on a still
131+
* referenced context.
132+
* @ctx: Context pointer.
133+
*
134+
* Call pvr_context_put() to release.
135+
*
136+
* Returns:
137+
* * True on success, or
138+
* * false if no context pointer passed, or the context wasn't still
139+
* * referenced.
140+
*/
141+
static __always_inline bool
142+
pvr_context_get_if_referenced(struct pvr_context *ctx)
143+
{
144+
return ctx != NULL && kref_get_unless_zero(&ctx->ref_count) != 0;
145+
}
146+
126147
/**
127148
* pvr_context_lookup() - Lookup context pointer from handle and file.
128149
* @pvr_file: Pointer to pvr_file structure.

drivers/gpu/drm/imagination/pvr_device.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/kernel.h>
2424
#include <linux/math.h>
2525
#include <linux/mutex.h>
26+
#include <linux/spinlock_types.h>
2627
#include <linux/timer.h>
2728
#include <linux/types.h>
2829
#include <linux/wait.h>
@@ -293,6 +294,12 @@ struct pvr_device {
293294

294295
/** @sched_wq: Workqueue for schedulers. */
295296
struct workqueue_struct *sched_wq;
297+
298+
/**
299+
* @ctx_list_lock: Lock to be held when accessing the context list in
300+
* struct pvr_file.
301+
*/
302+
spinlock_t ctx_list_lock;
296303
};
297304

298305
/**
@@ -344,6 +351,9 @@ struct pvr_file {
344351
* This array is used to allocate handles returned to userspace.
345352
*/
346353
struct xarray vm_ctx_handles;
354+
355+
/** @contexts: PVR context list. */
356+
struct list_head contexts;
347357
};
348358

349359
/**

drivers/gpu/drm/imagination/pvr_drv.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/export.h>
2929
#include <linux/fs.h>
3030
#include <linux/kernel.h>
31+
#include <linux/list.h>
3132
#include <linux/mod_devicetable.h>
3233
#include <linux/module.h>
3334
#include <linux/moduleparam.h>
@@ -1326,6 +1327,8 @@ pvr_drm_driver_open(struct drm_device *drm_dev, struct drm_file *file)
13261327
*/
13271328
pvr_file->pvr_dev = pvr_dev;
13281329

1330+
INIT_LIST_HEAD(&pvr_file->contexts);
1331+
13291332
xa_init_flags(&pvr_file->ctx_handles, XA_FLAGS_ALLOC1);
13301333
xa_init_flags(&pvr_file->free_list_handles, XA_FLAGS_ALLOC1);
13311334
xa_init_flags(&pvr_file->hwrt_handles, XA_FLAGS_ALLOC1);

drivers/gpu/drm/imagination/pvr_vm.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <drm/drm_gem.h>
1515
#include <drm/drm_gpuvm.h>
1616

17+
#include <linux/bug.h>
1718
#include <linux/container_of.h>
1819
#include <linux/err.h>
1920
#include <linux/errno.h>
@@ -597,12 +598,26 @@ pvr_vm_create_context(struct pvr_device *pvr_dev, bool is_userspace_context)
597598
}
598599

599600
/**
600-
* pvr_vm_context_release() - Teardown a VM context.
601-
* @ref_count: Pointer to reference counter of the VM context.
601+
* pvr_vm_unmap_all() - Unmap all mappings associated with a VM context.
602+
* @vm_ctx: Target VM context.
602603
*
603604
* This function ensures that no mappings are left dangling by unmapping them
604605
* all in order of ascending device-virtual address.
605606
*/
607+
void
608+
pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx)
609+
{
610+
WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start,
611+
vm_ctx->gpuvm_mgr.mm_range));
612+
}
613+
614+
/**
615+
* pvr_vm_context_release() - Teardown a VM context.
616+
* @ref_count: Pointer to reference counter of the VM context.
617+
*
618+
* This function also ensures that no mappings are left dangling by calling
619+
* pvr_vm_unmap_all.
620+
*/
606621
static void
607622
pvr_vm_context_release(struct kref *ref_count)
608623
{
@@ -612,8 +627,7 @@ pvr_vm_context_release(struct kref *ref_count)
612627
if (vm_ctx->fw_mem_ctx_obj)
613628
pvr_fw_object_destroy(vm_ctx->fw_mem_ctx_obj);
614629

615-
WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start,
616-
vm_ctx->gpuvm_mgr.mm_range));
630+
pvr_vm_unmap_all(vm_ctx);
617631

618632
pvr_mmu_context_destroy(vm_ctx->mmu_ctx);
619633
drm_gem_private_object_fini(&vm_ctx->dummy_gem);

drivers/gpu/drm/imagination/pvr_vm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ int pvr_vm_map(struct pvr_vm_context *vm_ctx,
3939
struct pvr_gem_object *pvr_obj, u64 pvr_obj_offset,
4040
u64 device_addr, u64 size);
4141
int pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size);
42+
void pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx);
4243

4344
dma_addr_t pvr_vm_get_page_table_root_addr(struct pvr_vm_context *vm_ctx);
4445
struct dma_resv *pvr_vm_get_dma_resv(struct pvr_vm_context *vm_ctx);

drivers/gpu/drm/panthor/panthor_device.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,15 @@ int panthor_device_mmap_io(struct panthor_device *ptdev, struct vm_area_struct *
390390
{
391391
u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT;
392392

393+
if ((vma->vm_flags & VM_SHARED) == 0)
394+
return -EINVAL;
395+
393396
switch (offset) {
394397
case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET:
395398
if (vma->vm_end - vma->vm_start != PAGE_SIZE ||
396399
(vma->vm_flags & (VM_WRITE | VM_EXEC)))
397400
return -EINVAL;
401+
vm_flags_clear(vma, VM_MAYWRITE);
398402

399403
break;
400404

drivers/gpu/drm/panthor/panthor_mmu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,9 @@ panthor_vm_pool_get_vm(struct panthor_vm_pool *pool, u32 handle)
15801580
{
15811581
struct panthor_vm *vm;
15821582

1583+
xa_lock(&pool->xa);
15831584
vm = panthor_vm_get(xa_load(&pool->xa, handle));
1585+
xa_unlock(&pool->xa);
15841586

15851587
return vm;
15861588
}

0 commit comments

Comments
 (0)