From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794064268; b=gD5ZhPvx0WxQ/vqz3cSKT61cg1r1M5SSbQrytpRiYUiqj31TZu19DXfz19eQfFq6hiXd 6SUOBG2W22nBYIlCgZ+Ti1bz19xpYdb7PyETKUXqXbX77Vb6ZUHJY8NicwsFAs5a2YcZz eKrmn5crG7pfayZB7dWsKYv35Gl1LRer12flY7/GxwfsB2HoIsR90ldOq3eH4eBWCEsSc T1MDA9G/WYJ0Kvln1Uqc9ceh7BVW2IshnPfRBNxSxwQgX0767bIXLAOkdAVKWYNW/Nw8z cQevlgoFZ/VLtboVubk6vJehncPq4zHSXZl9hXb0F+RCHDFlQqmoBLYRnpCpUDdSMCA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794064268; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=PMql6kROziOyIRPBHsJgkX9yEg31lmiYVXf25gbvyik=; b=Rd6u2uH+kLg2k2pSJ8TumiL/9BgBY1dI91u74v0cVIPZFpx5Pbop4vIA0It9TXz0HFL6 sR6b/6tUXw6VM6vAE2vY1ZeDbfT+cc5BSWrtk3uhsIzWquIHomM5L4ZL+yPrpX7U8lvFK BdFt7lZwVVRB41NlBo70XB50B9EXvtwXW0+n+McTbLAYB7v5nWUNjsNJNk8KUBhFhu3Ep 366/c99htT82olmvEYFATSKzbo2vOC/yqdx1EHs9caWiiQJ2uUgcYo19MGIIkk+RU+hXb 72+Z4efn5JecKgVBc14o/nrBwJxB1DcLHkK8RlVC2ss58HZL5kRyVzbkiTeO0WnwhhA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=QezjCNRs; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 01140606A334; Sat, 7 Nov 2026 15:11:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=QezjCNRs Received: by smtp.kernel.org (Postfix) with ESMTPSA id A18CE1F0089F; Sat, 7 Nov 2026 15:11:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794064267; bh=PMql6kROziOyIRPBHsJgkX9yEg31lmiYVXf25gbvyik=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=QezjCNRsJGjlGU/0BDIE7r4cNNwFadO76elHF/CZJywb/EmOG1YbHCxuvyuAX2rZ2 nBD5LeA1oQJwgQDSauZvq0echFhF+qs/R7gHPQBRT9jQTZqqJTQf9IABsAZAURDM6F Hnqk9cX9Eim+qBSJFn1Cd6oZ/6sKSpRzJY4nnymI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Vikash Garodia , Dmitry Baryshkov , Vishnu Reddy , Bryan ODonoghue , Sasha Levin Subject: [PATCH 7.3 0365/1257] media: iris: Fix iova allocation from restrict region Date: Sat, 7 Nov 2026 08:44:21 -0500 Message-ID: <20261107134949.661594933@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134939.434104957@linuxfoundation.org> References: <20261107134939.434104957@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Vishnu Reddy [ Upstream commit 200473c198b201c308dfb916fb3233074d9407fa ] The VPU issues DMA through several SMMU streams, and the hardware does not give every stream the same addressable range. The non-pixel stream cannot address the low 600MB of IOVA space, while the pixel stream can address the full range: +-----------------------------------------------------------+ | non-pixel stream addressable range (600 MB - 3.5 GB) | | 0x25800000 - 0xe0000000 | +-----------------------------------------------------------+ | pixel stream addressable range (0 - 3.5 GB) | | 0x00000000 - 0xe0000000 | +-----------------------------------------------------------+ A single "iommus" property on the video-codec node puts every stream in one IOMMU domain sharing one IOVA space, so nothing stops a non-pixel buffer from landing below 600MB. Once an allocation lands below that boundary the hardware faults, which shows up as unhandled SMMU page faults and spontaneous reboots. https://gitlab.freedesktop.org/drm/msm/-/work_items/100 Fix this by reserving the 0-600MB range, below the boundary the non-pixel stream cannot address, using dma_iova_try_alloc() so the IOMMU-DMA core never hands that range out to a real DMA mapping. This reserves only IOVA space, it does not allocate any physical memory. Since sub-nodes for non-pixel, pixel, and secure streams do not exist yet and only a single device is available, the restriction is applied to both non-pixel and pixel stream IDs. Fixes: d7378f84e94e ("media: iris: introduce iris core state management with shared queues") Cc: stable@vger.kernel.org Reviewed-by: Vikash Garodia Reviewed-by: Dmitry Baryshkov Signed-off-by: Vishnu Reddy Signed-off-by: Bryan O'Donoghue Signed-off-by: Sasha Levin --- drivers/media/platform/qcom/iris/iris_core.h | 6 ++ drivers/media/platform/qcom/iris/iris_probe.c | 62 ++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index 24da60448cf24..3e4cf652bf39a 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -7,6 +7,7 @@ #define __IRIS_CORE_H__ #include +#include #include #include @@ -25,6 +26,9 @@ struct icc_info { #define IRIS_FW_VERSION_LENGTH 128 #define IFACEQ_CORE_PKT_SIZE (1024 * 4) +#define IRIS_NP_RESERVE_IOVA_START 0x0 +#define IRIS_NP_RESERVE_IOVA_SIZE 0x25800000 + enum domain_type { ENCODER = BIT(0), DECODER = BIT(1), @@ -77,6 +81,7 @@ struct qcom_ubwc_cfg_data; * @instances: a list_head of all instances * @inst_fw_caps_dec: an array of supported instance capabilities by decoder * @inst_fw_caps_enc: an array of supported instance capabilities by encoder + * @iova_state: a pointer to an array of dma_iova_state entries reserved for restricted IOVA region */ struct iris_core { @@ -123,6 +128,7 @@ struct iris_core { /* encoder and decoder have overlapping caps, so two different arrays are required */ struct platform_inst_fw_cap inst_fw_caps_dec[INST_FW_CAP_MAX]; struct platform_inst_fw_cap inst_fw_caps_enc[INST_FW_CAP_MAX]; + struct dma_iova_state *iova_state; }; int iris_core_init(struct iris_core *core); diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index e4acf4a74f944..6581a969fe3fb 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -150,6 +150,57 @@ static int iris_init_resources(struct iris_core *core) return iris_init_resets(core); } +static void iris_unreserve_iova_region(struct device *dev, struct dma_iova_state *iova_state) +{ + unsigned int i; + + for (i = 0; dma_iova_size(&iova_state[i]); i++) + dma_iova_free(dev, &iova_state[i]); +} + +static int iris_reserve_iova_region(struct device *dev, struct dma_iova_state **iova_state, + unsigned long start, unsigned long size) +{ + unsigned long dma_limit = dev->bus_dma_limit; + unsigned long end, rem, chunk; + struct dma_iova_state *state; + unsigned int count = 0; + int ret = -ENOMEM; + + state = devm_kcalloc(dev, BITS_PER_TYPE(dma_addr_t) + 1, sizeof(*state), GFP_KERNEL); + if (!state) + return ret; + + end = start + size; + rem = end - max(start, PAGE_SIZE); + dev->bus_dma_limit = end - 1; + + while (rem) { + chunk = min(end & -end, (u64)1 << (fls64(rem) - 1)); + + if (!dma_iova_try_alloc(dev, &state[count], 0, chunk)) + goto err_free_iova; + + if (state[count].addr != end - chunk || state[count].__size != chunk) + goto err_free_iova; + + rem -= chunk; + end -= chunk; + count++; + } + + *iova_state = state; + dev->bus_dma_limit = dma_limit; + + return 0; + +err_free_iova: + iris_unreserve_iova_region(dev, state); + dev->bus_dma_limit = dma_limit; + + return ret; +} + static int iris_register_video_device(struct iris_core *core, enum domain_type type) { struct video_device *vdev; @@ -207,6 +258,8 @@ static void iris_remove(struct platform_device *pdev) v4l2_device_unregister(&core->v4l2_dev); + iris_unreserve_iova_region(core->dev, core->iova_state); + mutex_destroy(&core->lock); } @@ -269,10 +322,15 @@ static int iris_probe(struct platform_device *pdev) if (ret) return ret; - ret = v4l2_device_register(dev, &core->v4l2_dev); + ret = iris_reserve_iova_region(dev, &core->iova_state, IRIS_NP_RESERVE_IOVA_START, + IRIS_NP_RESERVE_IOVA_SIZE); if (ret) return ret; + ret = v4l2_device_register(dev, &core->v4l2_dev); + if (ret) + goto err_unresv_iova_region; + ret = iris_register_video_device(core, DECODER); if (ret) goto err_v4l2_unreg; @@ -306,6 +364,8 @@ static int iris_probe(struct platform_device *pdev) video_unregister_device(core->vdev_dec); err_v4l2_unreg: v4l2_device_unregister(&core->v4l2_dev); +err_unresv_iova_region: + iris_unreserve_iova_region(dev, core->iova_state); return ret; } -- 2.53.0