diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2024-08-08 18:58:45 +0200 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2024-08-08 18:58:46 +0200 |
| commit | 91dae758bdb854367bf0811d97acb84e791764d9 (patch) | |
| tree | 127bead858c1321276754befd3fb385e55df70de /drivers/gpu/drm/v3d/v3d_submit.c | |
| parent | a4172af3040cdc207f1b60efffcdd219156093c9 (diff) | |
| parent | d97e71e449373efbd2403f1d7a32d416599f32ac (diff) | |
Merge tag 'drm-misc-next-2024-08-01' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next
drm-misc-next for v6.12:
UAPI Changes:
virtio:
- Define DRM capset
Cross-subsystem Changes:
dma-buf:
- heaps: Clean up documentation
printk:
- Pass description to kmsg_dump()
Core Changes:
CI:
- Update IGT tests
- Point upstream repo to GitLab instance
modesetting:
- Introduce Power Saving Policy property for connectors
- Add might_fault() to drm_modeset_lock priming
- Add dynamic per-crtc vblank configuration support
panic:
- Avoid build-time interference with framebuffer console
docs:
- Document Colorspace property
scheduler:
- Remove full_recover from drm_sched_start
TTM:
- Make LRU walk restartable after dropping locks
- Allow direct reclaim to allocate local memory
Driver Changes:
amdgpu:
- Support Power Saving Policy connector property
ast:
- astdp: Support AST2600 with VGA; Clean up HPD
bridge:
- Silence error message on -EPROBE_DEFER
- analogix: Clean aup
- bridge-connector: Fix double free
- lt6505: Disable interrupt when powered off
- tc358767: Make default DP port preemphasis configurable
gma500:
- Update i2c terminology
ivpu:
- Add MODULE_FIRMWARE()
lcdif:
- Fix pixel clock
loongson:
- Use GEM refcount over TTM's
mgag200:
- Improve BMC handling
- Support VBLANK intterupts
nouveau:
- Refactor and clean up internals
- Use GEM refcount over TTM's
panel:
- Shutdown fixes plus documentation
- Refactor several drivers for better code sharing
- boe-th101mb31ig002: Support for starry-er88577 MIPI-DSI panel plus
DT; Fix porch parameter
- edp: Support AOU B116XTN02.3, AUO B116XAN06.1, AOU B116XAT04.1,
BOE NV140WUM-N41, BOE NV133WUM-N63, BOE NV116WHM-A4D, CMN N116BCA-EA2,
CMN N116BCP-EA2, CSW MNB601LS1-4
- himax-hx8394: Support Microchip AC40T08A MIPI Display panel plus DT
- ilitek-ili9806e: Support Densitron DMT028VGHMCMI-1D TFT plus DT
- jd9365da: Support Melfas lmfbx101117480 MIPI-DSI panel plus DT; Refactor
for code sharing
sti:
- Fix module owner
stm:
- Avoid UAF wih managed plane and CRTC helpers
- Fix module owner
- Fix error handling in probe
- Depend on COMMON_CLK
- ltdc: Fix transparency after disabling plane; Remove unused interrupt
tegra:
- Call drm_atomic_helper_shutdown()
v3d:
- Clean up perfmon
vkms:
- Clean up
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20240801121406.GA102996@linux.fritz.box
Diffstat (limited to 'drivers/gpu/drm/v3d/v3d_submit.c')
| -rw-r--r-- | drivers/gpu/drm/v3d/v3d_submit.c | 255 |
1 files changed, 127 insertions, 128 deletions
diff --git a/drivers/gpu/drm/v3d/v3d_submit.c b/drivers/gpu/drm/v3d/v3d_submit.c index 4cdfabbf4964..d607aa9c4ec2 100644 --- a/drivers/gpu/drm/v3d/v3d_submit.c +++ b/drivers/gpu/drm/v3d/v3d_submit.c @@ -452,6 +452,7 @@ v3d_get_cpu_timestamp_query_params(struct drm_file *file_priv, { u32 __user *offsets, *syncs; struct drm_v3d_timestamp_query timestamp; + struct v3d_timestamp_query_info *query_info = &job->timestamp_query; unsigned int i; int err; @@ -473,10 +474,10 @@ v3d_get_cpu_timestamp_query_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_TIMESTAMP_QUERY; - job->timestamp_query.queries = kvmalloc_array(timestamp.count, - sizeof(struct v3d_timestamp_query), - GFP_KERNEL); - if (!job->timestamp_query.queries) + query_info->queries = kvmalloc_array(timestamp.count, + sizeof(struct v3d_timestamp_query), + GFP_KERNEL); + if (!query_info->queries) return -ENOMEM; offsets = u64_to_user_ptr(timestamp.offsets); @@ -485,25 +486,26 @@ v3d_get_cpu_timestamp_query_params(struct drm_file *file_priv, for (i = 0; i < timestamp.count; i++) { u32 offset, sync; - if (copy_from_user(&offset, offsets++, sizeof(offset))) { + if (get_user(offset, offsets++)) { err = -EFAULT; goto error; } - job->timestamp_query.queries[i].offset = offset; + query_info->queries[i].offset = offset; - if (copy_from_user(&sync, syncs++, sizeof(sync))) { + if (get_user(sync, syncs++)) { err = -EFAULT; goto error; } - job->timestamp_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync); - if (!job->timestamp_query.queries[i].syncobj) { + query_info->queries[i].syncobj = drm_syncobj_find(file_priv, + sync); + if (!query_info->queries[i].syncobj) { err = -ENOENT; goto error; } } - job->timestamp_query.count = timestamp.count; + query_info->count = timestamp.count; return 0; @@ -519,6 +521,7 @@ v3d_get_cpu_reset_timestamp_params(struct drm_file *file_priv, { u32 __user *syncs; struct drm_v3d_reset_timestamp_query reset; + struct v3d_timestamp_query_info *query_info = &job->timestamp_query; unsigned int i; int err; @@ -537,10 +540,10 @@ v3d_get_cpu_reset_timestamp_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_RESET_TIMESTAMP_QUERY; - job->timestamp_query.queries = kvmalloc_array(reset.count, - sizeof(struct v3d_timestamp_query), - GFP_KERNEL); - if (!job->timestamp_query.queries) + query_info->queries = kvmalloc_array(reset.count, + sizeof(struct v3d_timestamp_query), + GFP_KERNEL); + if (!query_info->queries) return -ENOMEM; syncs = u64_to_user_ptr(reset.syncs); @@ -548,20 +551,21 @@ v3d_get_cpu_reset_timestamp_params(struct drm_file *file_priv, for (i = 0; i < reset.count; i++) { u32 sync; - job->timestamp_query.queries[i].offset = reset.offset + 8 * i; + query_info->queries[i].offset = reset.offset + 8 * i; - if (copy_from_user(&sync, syncs++, sizeof(sync))) { + if (get_user(sync, syncs++)) { err = -EFAULT; goto error; } - job->timestamp_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync); - if (!job->timestamp_query.queries[i].syncobj) { + query_info->queries[i].syncobj = drm_syncobj_find(file_priv, + sync); + if (!query_info->queries[i].syncobj) { err = -ENOENT; goto error; } } - job->timestamp_query.count = reset.count; + query_info->count = reset.count; return 0; @@ -578,6 +582,7 @@ v3d_get_cpu_copy_query_results_params(struct drm_file *file_priv, { u32 __user *offsets, *syncs; struct drm_v3d_copy_timestamp_query copy; + struct v3d_timestamp_query_info *query_info = &job->timestamp_query; unsigned int i; int err; @@ -599,10 +604,10 @@ v3d_get_cpu_copy_query_results_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_COPY_TIMESTAMP_QUERY; - job->timestamp_query.queries = kvmalloc_array(copy.count, - sizeof(struct v3d_timestamp_query), - GFP_KERNEL); - if (!job->timestamp_query.queries) + query_info->queries = kvmalloc_array(copy.count, + sizeof(struct v3d_timestamp_query), + GFP_KERNEL); + if (!query_info->queries) return -ENOMEM; offsets = u64_to_user_ptr(copy.offsets); @@ -611,25 +616,26 @@ v3d_get_cpu_copy_query_results_params(struct drm_file *file_priv, for (i = 0; i < copy.count; i++) { u32 offset, sync; - if (copy_from_user(&offset, offsets++, sizeof(offset))) { + if (get_user(offset, offsets++)) { err = -EFAULT; goto error; } - job->timestamp_query.queries[i].offset = offset; + query_info->queries[i].offset = offset; - if (copy_from_user(&sync, syncs++, sizeof(sync))) { + if (get_user(sync, syncs++)) { err = -EFAULT; goto error; } - job->timestamp_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync); - if (!job->timestamp_query.queries[i].syncobj) { + query_info->queries[i].syncobj = drm_syncobj_find(file_priv, + sync); + if (!query_info->queries[i].syncobj) { err = -ENOENT; goto error; } } - job->timestamp_query.count = copy.count; + query_info->count = copy.count; job->copy.do_64bit = copy.do_64bit; job->copy.do_partial = copy.do_partial; @@ -645,95 +651,121 @@ error: } static int -v3d_get_cpu_reset_performance_params(struct drm_file *file_priv, - struct drm_v3d_extension __user *ext, - struct v3d_cpu_job *job) +v3d_copy_query_info(struct v3d_performance_query_info *query_info, + unsigned int count, + unsigned int nperfmons, + u32 __user *syncs, + u64 __user *kperfmon_ids, + struct drm_file *file_priv) { - u32 __user *syncs; - u64 __user *kperfmon_ids; - struct drm_v3d_reset_performance_query reset; unsigned int i, j; int err; - if (!job) { - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); - return -EINVAL; - } - - if (job->job_type) { - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); - return -EINVAL; - } - - if (copy_from_user(&reset, ext, sizeof(reset))) - return -EFAULT; - - if (reset.nperfmons > V3D_MAX_PERFMONS) - return -EINVAL; - - job->job_type = V3D_CPU_JOB_TYPE_RESET_PERFORMANCE_QUERY; - - job->performance_query.queries = kvmalloc_array(reset.count, - sizeof(struct v3d_performance_query), - GFP_KERNEL); - if (!job->performance_query.queries) - return -ENOMEM; - - syncs = u64_to_user_ptr(reset.syncs); - kperfmon_ids = u64_to_user_ptr(reset.kperfmon_ids); - - for (i = 0; i < reset.count; i++) { - u32 sync; - u64 ids; + for (i = 0; i < count; i++) { + struct v3d_performance_query *query = &query_info->queries[i]; u32 __user *ids_pointer; - u32 id; + u32 sync, id; + u64 ids; - if (copy_from_user(&sync, syncs++, sizeof(sync))) { + if (get_user(sync, syncs++)) { err = -EFAULT; goto error; } - if (copy_from_user(&ids, kperfmon_ids++, sizeof(ids))) { + if (get_user(ids, kperfmon_ids++)) { err = -EFAULT; goto error; } + query->kperfmon_ids = + kvmalloc_array(nperfmons, + sizeof(struct v3d_performance_query *), + GFP_KERNEL); + if (!query->kperfmon_ids) { + err = -ENOMEM; + goto error; + } + ids_pointer = u64_to_user_ptr(ids); - for (j = 0; j < reset.nperfmons; j++) { - if (copy_from_user(&id, ids_pointer++, sizeof(id))) { + for (j = 0; j < nperfmons; j++) { + if (get_user(id, ids_pointer++)) { + kvfree(query->kperfmon_ids); err = -EFAULT; goto error; } - job->performance_query.queries[i].kperfmon_ids[j] = id; + query->kperfmon_ids[j] = id; } - job->performance_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync); - if (!job->performance_query.queries[i].syncobj) { + query->syncobj = drm_syncobj_find(file_priv, sync); + if (!query->syncobj) { + kvfree(query->kperfmon_ids); err = -ENOENT; goto error; } } - job->performance_query.count = reset.count; - job->performance_query.nperfmons = reset.nperfmons; return 0; error: - v3d_performance_query_info_free(&job->performance_query, i); + v3d_performance_query_info_free(query_info, i); return err; } static int +v3d_get_cpu_reset_performance_params(struct drm_file *file_priv, + struct drm_v3d_extension __user *ext, + struct v3d_cpu_job *job) +{ + struct v3d_performance_query_info *query_info = &job->performance_query; + struct drm_v3d_reset_performance_query reset; + int err; + + if (!job) { + DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); + return -EINVAL; + } + + if (job->job_type) { + DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); + return -EINVAL; + } + + if (copy_from_user(&reset, ext, sizeof(reset))) + return -EFAULT; + + job->job_type = V3D_CPU_JOB_TYPE_RESET_PERFORMANCE_QUERY; + + query_info->queries = + kvmalloc_array(reset.count, + sizeof(struct v3d_performance_query), + GFP_KERNEL); + if (!query_info->queries) + return -ENOMEM; + + err = v3d_copy_query_info(query_info, + reset.count, + reset.nperfmons, + u64_to_user_ptr(reset.syncs), + u64_to_user_ptr(reset.kperfmon_ids), + file_priv); + if (err) + return err; + + query_info->count = reset.count; + query_info->nperfmons = reset.nperfmons; + + return 0; +} + +static int v3d_get_cpu_copy_performance_query_params(struct drm_file *file_priv, struct drm_v3d_extension __user *ext, struct v3d_cpu_job *job) { - u32 __user *syncs; - u64 __user *kperfmon_ids; + struct v3d_performance_query_info *query_info = &job->performance_query; struct drm_v3d_copy_performance_query copy; - unsigned int i, j; int err; if (!job) { @@ -752,56 +784,27 @@ v3d_get_cpu_copy_performance_query_params(struct drm_file *file_priv, if (copy.pad) return -EINVAL; - if (copy.nperfmons > V3D_MAX_PERFMONS) - return -EINVAL; - job->job_type = V3D_CPU_JOB_TYPE_COPY_PERFORMANCE_QUERY; - job->performance_query.queries = kvmalloc_array(copy.count, - sizeof(struct v3d_performance_query), - GFP_KERNEL); - if (!job->performance_query.queries) + query_info->queries = + kvmalloc_array(copy.count, + sizeof(struct v3d_performance_query), + GFP_KERNEL); + if (!query_info->queries) return -ENOMEM; - syncs = u64_to_user_ptr(copy.syncs); - kperfmon_ids = u64_to_user_ptr(copy.kperfmon_ids); + err = v3d_copy_query_info(query_info, + copy.count, + copy.nperfmons, + u64_to_user_ptr(copy.syncs), + u64_to_user_ptr(copy.kperfmon_ids), + file_priv); + if (err) + return err; - for (i = 0; i < copy.count; i++) { - u32 sync; - u64 ids; - u32 __user *ids_pointer; - u32 id; - - if (copy_from_user(&sync, syncs++, sizeof(sync))) { - err = -EFAULT; - goto error; - } - - if (copy_from_user(&ids, kperfmon_ids++, sizeof(ids))) { - err = -EFAULT; - goto error; - } - - ids_pointer = u64_to_user_ptr(ids); - - for (j = 0; j < copy.nperfmons; j++) { - if (copy_from_user(&id, ids_pointer++, sizeof(id))) { - err = -EFAULT; - goto error; - } - - job->performance_query.queries[i].kperfmon_ids[j] = id; - } - - job->performance_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync); - if (!job->performance_query.queries[i].syncobj) { - err = -ENOENT; - goto error; - } - } - job->performance_query.count = copy.count; - job->performance_query.nperfmons = copy.nperfmons; - job->performance_query.ncounters = copy.ncounters; + query_info->count = copy.count; + query_info->nperfmons = copy.nperfmons; + query_info->ncounters = copy.ncounters; job->copy.do_64bit = copy.do_64bit; job->copy.do_partial = copy.do_partial; @@ -810,10 +813,6 @@ v3d_get_cpu_copy_performance_query_params(struct drm_file *file_priv, job->copy.stride = copy.stride; return 0; - -error: - v3d_performance_query_info_free(&job->performance_query, i); - return err; } /* Whenever userspace sets ioctl extensions, v3d_get_extensions parses data |