diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2026-06-30 10:16:00 +0200 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2026-06-30 10:16:00 +0200 |
| commit | 827b9aabd3ea3e96d5e48abed9f44dbd1e550d4e (patch) | |
| tree | 845a97a83f20fe0585840a66d9eed8fcf1286772 /drivers/accel | |
| parent | 3b3bce4a692ac60d9f4a341e6b597dd1fd0a28f9 (diff) | |
| parent | dc59e4fea9d83f03bad6bddf3fa2e52491777482 (diff) | |
| download | linux-next-827b9aabd3ea3e96d5e48abed9f44dbd1e550d4e.tar.gz linux-next-827b9aabd3ea3e96d5e48abed9f44dbd1e550d4e.zip | |
Merge drm/drm-next into drm-misc-next
Backmerging to get drm-misc-next to v7.2-rc1.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'drivers/accel')
| -rw-r--r-- | drivers/accel/amdxdna/aie2_ctx.c | 19 | ||||
| -rw-r--r-- | drivers/accel/amdxdna/aie2_pci.c | 5 | ||||
| -rw-r--r-- | drivers/accel/amdxdna/amdxdna_gem.c | 7 | ||||
| -rw-r--r-- | drivers/accel/amdxdna/amdxdna_pci_drv.c | 9 | ||||
| -rw-r--r-- | drivers/accel/ethosu/ethosu_gem.c | 35 | ||||
| -rw-r--r-- | drivers/accel/ivpu/ivpu_debugfs.c | 2 | ||||
| -rw-r--r-- | drivers/accel/ivpu/ivpu_fw.c | 16 | ||||
| -rw-r--r-- | drivers/accel/ivpu/ivpu_fw_log.c | 5 | ||||
| -rw-r--r-- | drivers/accel/ivpu/ivpu_ipc.c | 2 | ||||
| -rw-r--r-- | drivers/accel/ivpu/ivpu_job.c | 10 | ||||
| -rw-r--r-- | drivers/accel/ivpu/ivpu_ms.c | 7 | ||||
| -rw-r--r-- | drivers/accel/rocket/rocket_gem.c | 17 |
12 files changed, 101 insertions, 33 deletions
diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c index 658a5fb1fda6..e9fbd8c14364 100644 --- a/drivers/accel/amdxdna/aie2_ctx.c +++ b/drivers/accel/amdxdna/aie2_ctx.c @@ -305,17 +305,13 @@ aie2_sched_drvcmd_resp_handler(void *handle, void __iomem *data, size_t size) struct amdxdna_sched_job *job = handle; int ret = 0; - if (unlikely(!data)) - goto out; - - if (unlikely(size != sizeof(u32))) { + if (unlikely(!data || size != sizeof(u32))) { + job->drv_cmd->result = U32_MAX; ret = -EINVAL; - goto out; + } else { + job->drv_cmd->result = readl(data); } - job->drv_cmd->result = readl(data); - -out: aie2_sched_notify(job); return ret; } @@ -437,8 +433,9 @@ static void aie2_sched_job_free(struct drm_sched_job *sched_job) struct amdxdna_sched_job *job = drm_job_to_xdna_job(sched_job); struct amdxdna_hwctx *hwctx = job->hwctx; + /* job->drv_cmd could be freed, so use DEFAULT_IO */ trace_xdna_job(sched_job, hwctx->name, "job free", - job->seq, job->drv_cmd ? job->drv_cmd->opcode : DEFAULT_IO); + job->seq, DEFAULT_IO); if (!job->job_done) up(&hwctx->priv->job_sem); @@ -939,6 +936,7 @@ static int aie2_hwctx_cfg_debug_bo(struct amdxdna_hwctx *hwctx, u32 bo_hdl, aie2_cmd_wait(hwctx, seq); if (cmd.result) { XDNA_ERR(xdna, "Response failure 0x%x", cmd.result); + ret = -EINVAL; goto put_obj; } @@ -1045,6 +1043,7 @@ again: if (ret == -EBUSY) { amdxdna_umap_put(mapp); + mmput(mm); goto again; } @@ -1055,11 +1054,13 @@ again: if (mmu_interval_read_retry(&mapp->notifier, mapp->range.notifier_seq)) { up_write(&xdna->notifier_lock); amdxdna_umap_put(mapp); + mmput(mm); goto again; } mapp->invalid = false; up_write(&xdna->notifier_lock); amdxdna_umap_put(mapp); + mmput(mm); goto again; put_mm: diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c index c4d345d4c76b..22f66c7f534d 100644 --- a/drivers/accel/amdxdna/aie2_pci.c +++ b/drivers/accel/amdxdna/aie2_pci.c @@ -490,6 +490,11 @@ static int aie2_init(struct amdxdna_dev *xdna) return -EINVAL; } + if (!xdna->group) { + XDNA_ERR(xdna, "Running without IOMMU not supported"); + return -EINVAL; + } + ndev = drmm_kzalloc(&xdna->ddev, sizeof(*ndev), GFP_KERNEL); if (!ndev) return -ENOMEM; diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c index 77e5fad08ae5..1f190b319bb6 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.c +++ b/drivers/accel/amdxdna/amdxdna_gem.c @@ -349,8 +349,11 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, u32 nr_pages; int ret; - if (!amdxdna_pasid_on(abo->client)) + if (!amdxdna_pasid_on(abo->client)) { + /* Need to set uva for heap uva validation */ + abo->mem.uva = addr; return 0; + } mapp = kzalloc_obj(*mapp); if (!mapp) @@ -1303,7 +1306,7 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev, args->handle, args->offset, args->size); if (args->direction == SYNC_DIRECT_FROM_DEVICE) - ret = amdxdna_hwctx_sync_debug_bo(abo->client, args->handle); + ret = amdxdna_hwctx_sync_debug_bo(client, args->handle); put_obj: drm_gem_object_put(gobj); diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c index c677293c1ae7..65489bb3f2b0 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c @@ -87,6 +87,7 @@ static int amdxdna_sva_init(struct amdxdna_client *client) client->pasid = iommu_sva_get_pasid(client->sva); if (client->pasid == IOMMU_PASID_INVALID) { iommu_sva_unbind_device(client->sva); + client->sva = NULL; XDNA_ERR(xdna, "SVA get pasid failed"); return -ENODEV; } @@ -120,8 +121,14 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp) if (!amdxdna_iova_on(xdna)) { /* No need to fail open since user may use pa + carveout later. */ - if (amdxdna_sva_init(client)) + if (amdxdna_sva_init(client)) { XDNA_WARN(xdna, "PASID not available for pid %d", client->pid); + if (!amdxdna_use_carveout(xdna)) { + XDNA_ERR(xdna, "PASID unavailable and carveout not configured"); + kfree(client); + return -EINVAL; + } + } } mmgrab(client->mm); init_srcu_struct(&client->hwctx_srcu); diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c index 7994e7073903..3401883e207f 100644 --- a/drivers/accel/ethosu/ethosu_gem.c +++ b/drivers/accel/ethosu/ethosu_gem.c @@ -2,6 +2,7 @@ /* Copyright 2025 Arm, Ltd. */ #include <linux/err.h> +#include <linux/overflow.h> #include <linux/slab.h> #include <drm/ethosu_accel.h> @@ -163,17 +164,30 @@ static u64 dma_length(struct ethosu_validated_cmdstream_info *info, s8 mode = dma_st->mode; u64 len = dma->len; + if (len == U64_MAX) + return U64_MAX; + if (mode >= 1) { + if (dma->stride[0] < 0 && (u64)(-dma->stride[0]) > len) + return U64_MAX; len += dma->stride[0]; - len *= dma_st->size0; + if (check_mul_overflow(len, (u64)dma_st->size0, &len)) + return U64_MAX; } if (mode == 2) { + if (dma->stride[1] < 0 && (u64)(-dma->stride[1]) > len) + return U64_MAX; len += dma->stride[1]; - len *= dma_st->size1; + if (check_mul_overflow(len, (u64)dma_st->size1, &len)) + return U64_MAX; + } + if (dma->region >= 0) { + u64 end; + + if (check_add_overflow(len, dma->offset, &end)) + return U64_MAX; + info->region_size[dma->region] = max(info->region_size[dma->region], end); } - if (dma->region >= 0) - info->region_size[dma->region] = max(info->region_size[dma->region], - len + dma->offset); return len; } @@ -387,6 +401,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, return -EFAULT; i++; + if (i >= size / 4) + return -EINVAL; bocmds[i] = cmds[1]; addr = cmd_to_addr(cmds); } @@ -395,6 +411,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, case NPU_OP_DMA_START: srclen = dma_length(info, &st.dma, &st.dma.src); dstlen = dma_length(info, &st.dma, &st.dma.dst); + if (srclen == U64_MAX || dstlen == U64_MAX) + return -EINVAL; if (st.dma.dst.region >= 0) info->output_region[st.dma.dst.region] = true; @@ -431,8 +449,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, return ret; break; case NPU_OP_RESIZE: // U85 only - WARN_ON(1); // TODO - break; + return -EINVAL; case NPU_SET_KERNEL_WIDTH_M1: st.ifm.width = param; break; @@ -464,7 +481,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, st.ifm.broadcast = param; break; case NPU_SET_IFM_REGION: - st.ifm.region = param & 0x7f; + st.ifm.region = param & 0x7; break; case NPU_SET_IFM_WIDTH0_M1: st.ifm.width0 = param; @@ -599,7 +616,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, if (ethosu_is_u65(edev)) st.scale[1].length = cmds[1]; else - st.weight[1].length = cmds[1]; + st.weight[2].length = cmds[1]; break; case NPU_SET_WEIGHT3_BASE: st.weight[3].base = addr; diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c index 189dbe94cf14..dc20bc73c6ed 100644 --- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -450,7 +450,7 @@ priority_bands_fops_write(struct file *file, const char __user *user_buf, size_t u32 band; int ret; - if (size >= sizeof(buf)) + if (*pos != 0 || size >= sizeof(buf)) return -EINVAL; ret = simple_write_to_buffer(buf, sizeof(buf) - 1, pos, user_buf, size); diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index 7db199e04f7c..5a8f7dfb54e6 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -259,6 +259,22 @@ static int ivpu_fw_parse(struct ivpu_device *vdev) return -EINVAL; } + if (!PAGE_ALIGNED(runtime_addr)) { + ivpu_err(vdev, "Runtime address 0x%llx not page aligned\n", runtime_addr); + return -EINVAL; + } + + if (!PAGE_ALIGNED(runtime_size)) { + ivpu_err(vdev, "Runtime size %llu not page aligned\n", runtime_size); + return -EINVAL; + } + + if (runtime_size < image_size) { + ivpu_err(vdev, "Runtime size too small: %llu, image size: %llu\n", + runtime_size, image_size); + return -EINVAL; + } + if (!ivpu_is_within_range(image_load_addr, image_size, &vdev->hw->ranges.runtime)) { ivpu_err(vdev, "Invalid firmware load address: 0x%llx and size %llu\n", image_load_addr, image_size); diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 337c906b0210..275baf844b56 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -98,6 +98,11 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0; u32 log_end = READ_ONCE(log->write_index); + if (log_start >= data_size) + log_start = 0; + if (log_end > data_size) + log_end = data_size; + if (log->wrap_count == log->read_wrap_count) { if (log_end <= log_start) { drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name); diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index c5f11be86c8c..62607ec8ca8f 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -280,7 +280,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, if (ipc_buf) memcpy(ipc_buf, rx_msg->ipc_hdr, sizeof(*ipc_buf)); if (rx_msg->jsm_msg) { - u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); + u32 size = min(rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) { ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 7320c9776283..ebb2c865b09a 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -208,9 +208,9 @@ static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->id, priority); if (ret) - return ret; + ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id); - return 0; + return ret; } static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) @@ -281,10 +281,10 @@ static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq } ret = ivpu_register_db(file_priv, cmdq); - if (ret) - return ret; + if (ret && vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id); - return 0; + return ret; } static int ivpu_cmdq_unregister(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index be43851f5f32..cd176e77b9a0 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -291,6 +291,13 @@ int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file * if (ret) goto unlock; + if (info_size > ivpu_bo_size(bo)) { + ivpu_warn_ratelimited(vdev, "MS info overflow: %#llx > %#zx\n", + info_size, ivpu_bo_size(bo)); + ret = -EOVERFLOW; + goto unlock; + } + if (args->buffer_size < info_size) { ret = -ENOSPC; goto unlock; diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c index c8084719208a..a5fffa51ff35 100644 --- a/drivers/accel/rocket/rocket_gem.c +++ b/drivers/accel/rocket/rocket_gem.c @@ -79,11 +79,6 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * rkt_obj->size = args->size; rkt_obj->offset = 0; - ret = drm_gem_handle_create(file, gem_obj, &args->handle); - drm_gem_object_put(gem_obj); - if (ret) - goto err; - sgt = drm_gem_shmem_get_pages_sgt(shmem_obj); if (IS_ERR(sgt)) { ret = PTR_ERR(sgt); @@ -95,6 +90,8 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * rkt_obj->size, PAGE_SIZE, 0, 0); mutex_unlock(&rocket_priv->mm_lock); + if (ret) + goto err; ret = iommu_map_sgtable(rocket_priv->domain->domain, rkt_obj->mm.start, @@ -112,8 +109,18 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file * args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); args->dma_address = rkt_obj->mm.start; + ret = drm_gem_handle_create(file, gem_obj, &args->handle); + if (ret) + goto err_unmap; + + drm_gem_object_put(gem_obj); + return 0; +err_unmap: + iommu_unmap(rocket_priv->domain->domain, + rkt_obj->mm.start, rkt_obj->size); + err_remove_node: mutex_lock(&rocket_priv->mm_lock); drm_mm_remove_node(&rkt_obj->mm); |
