On Mon, Sep 01, 2025 at 09:55:47PM -0700, Amirreza Zarrabi wrote:
> This patch series introduces a Trusted Execution Environment (TEE)
> driver for Qualcomm TEE (QTEE). QTEE enables Trusted Applications (TAs)
> and services to run securely. It uses an object-based interface, where
> each service is an object with sets of operations. Clients can invoke
> these operations on objects, which can generate results, including other
> objects. For example, an object can load a TA and return another object
> that represents the loaded TA, allowing access to its services.
>
> Kernel and userspace services are also available to QTEE through a
> similar approach. QTEE makes callback requests that are converted into
> object invocations. These objects can represent services within the
> kernel or userspace process.
>
> Note: This patch series focuses on QTEE objects and userspace services.
>
> Linux already provides a TEE subsystem, which is described in [1]. The
> tee subsystem provides a generic ioctl interface, TEE_IOC_INVOKE, which
> can be used by userspace to talk to a TEE backend driver. We extend the
> Linux TEE subsystem to understand object parameters and an ioctl call so
> client can invoke objects in QTEE:
>
> - TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_*
> - TEE_IOC_OBJECT_INVOKE
>
> The existing ioctl calls TEE_IOC_SUPPL_RECV and TEE_IOC_SUPPL_SEND are
> used for invoking services in the userspace process by QTEE.
>
> The TEE backend driver uses the QTEE Transport Message to communicate
> with QTEE. Interactions through the object INVOKE interface are
> translated into QTEE messages. Likewise, object invocations from QTEE
> for userspace objects are converted into SEND/RECV ioctl calls to
> supplicants.
>
> The details of QTEE Transport Message to communicate with QTEE is
> available in [PATCH 12/12] Documentation: tee: Add Qualcomm TEE driver.
>
> You can run basic tests with following steps:
> git clone https://github.com/quic/quic-teec.git
> cd quic-teec
> mkdir build
> cmake .. -DCMAKE_TOOLCHAIN_FILE=CMakeToolchain.txt -DBUILD_UNITTEST=ON
>
> https://github.com/quic/quic-teec/blob/main/README.md lists dependencies
> needed to build the above.
>
> More comprehensive tests are availabe at
> https://github.com/qualcomm/minkipc.
>
> root@qcom-armv8a:~# qtee_supplicant &
> root@qcom-armv8a:~# qtee_supplicant: process entry PPID = 378
> Total listener services to start = 4
> Opening CRequestTABuffer_open
> Path /data/
> register_service ::Opening CRegisterTABufCBO_UID
> Calling TAbufCBO Register
> QTEE_SUPPLICANT RUNNING
>
> root@qcom-armv8a:~# smcinvoke_client -c /data 1
> Run callback obj test...
> Load /data/tzecotestapp.mbn, size 52192, buf 0x1e44ba0.
> System Time: 2024-02-27 17:26:31
> PASSED - Callback tests with Buffer inputs.
> PASSED - Callback tests with Remote and Callback object inputs.
> PASSED - Callback tests with Memory Object inputs.
> TEST PASSED!
> root@qcom-armv8a:~#
> root@qcom-armv8a:~# smcinvoke_client -m /data 1
> Run memory obj test...
> Load /data/tzecotestapp.mbn, size 52192, buf 0x26cafba0.
> System Time: 2024-02-27 17:26:39
> PASSED - Single Memory Object access Test.
> PASSED - Two Memory Object access Test.
> TEST PASSED!
>
> This series has been tested for QTEE object invocations, including
> loading a TA, requesting services from the TA, memory sharing, and
> handling callback requests to a supplicant.
>
> Tested platforms: sm8650-mtp, sm8550-qrd, sm8650-qrd, sm8650-hdk
>
> [1] https://www.kernel.org/doc/Documentation/tee.txt
>
> Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi(a)oss.qualcomm.com>
>
> Changes in v9:
> - Remove unnecessary logging in qcom_scm_probe().
> - Replace the platform_device_alloc()/add() sequence with
> platform_device_register_data().
> - Fixed sparse warning.
> - Fixed documentation typo.
> - Link to v8:
> https://lore.kernel.org/r/20250820-qcom-tee-using-tee-ss-without-mem-obj-v8…
>
> Changes in v8:
> - Check if arguments to qcom_scm_qtee_invoke_smc() and
> qcom_scm_qtee_callback_response() are NULL.
> - Add CPU_BIG_ENDIAN as a dependency to Kconfig.
> - Fixed kernel bot errors.
> - Link to v7:
> https://lore.kernel.org/r/20250812-qcom-tee-using-tee-ss-without-mem-obj-v7…
>
> Changes in v7:
> - Updated copyrights.
> - Updated Acked-by: tags.
> - Fixed kernel bot errors.
> - Link to v6:
> https://lore.kernel.org/r/20250713-qcom-tee-using-tee-ss-without-mem-obj-v6…
>
> Changes in v6:
> - Relocate QTEE version into the driver's main service structure.
> - Simplfies qcomtee_objref_to_arg() and qcomtee_objref_from_arg().
> - Enhanced the return logic of qcomtee_object_do_invoke_internal().
> - Improve comments and remove redundant checks.
> - Improve helpers in qcomtee_msh.h to use GENMASK() and FIELD_GET().
> - updated Tested-by:, Acked-by:, and Reviewed-by: tags
> - Link to v5:
> https://lore.kernel.org/r/20250526-qcom-tee-using-tee-ss-without-mem-obj-v5…
>
> Changes in v5:
> - Remove references to kernel services and public APIs.
> - Support auto detection for failing devices (e.g., RB1, RB4).
> - Add helpers for obtaining client environment and service objects.
> - Query the QTEE version and print it.
> - Move remaining static variables, including the object table, to struct
> qcomtee.
> - Update TEE_MAX_ARG_SIZE to 4096.
> - Add a dependancy to QCOM_TZMEM_MODE_SHMBRIDGE in Kconfig
> - Reorganize code by removing release.c and qcom_scm.c.
> - Add more error messages and improve comments.
> - updated Tested-by:, Acked-by:, and Reviewed-by: tags
> - Link to v4: https://lore.kernel.org/r/20250428-qcom-tee-using-tee-ss-without-mem-obj-v4…
>
> Changes in v4:
> - Move teedev_ctx_get/put and tee_device_get/put to tee_core.h.
> - Rename object to id in struct tee_ioctl_object_invoke_arg.
> - Replace spinlock with mutex for qtee_objects_idr.
> - Move qcomtee_object_get to qcomtee_user/memobj_param_to_object.
> - More code cleanup following the comments.
> - Cleanup documentations.
> - Update MAINTAINERS file.
> - Link to v3: https://lore.kernel.org/r/20250327-qcom-tee-using-tee-ss-without-mem-obj-v3…
>
> Changes in v3:
> - Export shm_bridge create/delete APIs.
> - Enable support for QTEE memory objects.
> - Update the memory management code to use the TEE subsystem for all
> allocations using the pool.
> - Move all driver states into the driver's main service struct.
> - Add more documentations.
> - Link to v2: https://lore.kernel.org/r/20250202-qcom-tee-using-tee-ss-without-mem-obj-v2…
>
> Changes in v2:
> - Clean up commit messages and comments.
> - Use better names such as ubuf instead of membuf or QCOMTEE prefix
> instead of QCOM_TEE, or names that are more consistent with other
> TEE-backend drivers such as qcomtee_context_data instead of
> qcom_tee_context.
> - Drop the DTS patch and instantiate the device from the scm driver.
> - Use a single structure for all driver's internal states.
> - Drop srcu primitives and use the existing mutex for synchronization
> between the supplicant and QTEE.
> - Directly use tee_context to track the lifetime of qcomtee_context_data.
> - Add close_context() to be called when the user closes the tee_context.
> - Link to v1: https://lore.kernel.org/r/20241202-qcom-tee-using-tee-ss-without-mem-obj-v1…
>
> Changes in v1:
> - It is a complete rewrite to utilize the TEE subsystem.
> - Link to RFC: https://lore.kernel.org/all/20240702-qcom-tee-object-and-ioctls-v1-0-633c3d…
>
> ---
> Amirreza Zarrabi (11):
> tee: allow a driver to allocate a tee_device without a pool
> tee: add close_context to TEE driver operation
> tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
> tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
> tee: increase TEE_MAX_ARG_SIZE to 4096
> firmware: qcom: scm: add support for object invocation
> firmware: qcom: tzmem: export shm_bridge create/delete
These two patches are for code maintained by me, the rest by Jens. So we
will have to dance to get this merged.
Is there are reason why these two are in the middle of the series? Do
they need to come after the first 5 but before the next 3?
Regards,
Bjorn
> tee: add Qualcomm TEE driver
> tee: qcom: add primordial object
> tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl
> Documentation: tee: Add Qualcomm TEE driver
>
> Documentation/tee/index.rst | 1 +
> Documentation/tee/qtee.rst | 96 ++++
> MAINTAINERS | 7 +
> drivers/firmware/qcom/qcom_scm.c | 124 +++++
> drivers/firmware/qcom/qcom_scm.h | 7 +
> drivers/firmware/qcom/qcom_tzmem.c | 63 ++-
> drivers/tee/Kconfig | 1 +
> drivers/tee/Makefile | 1 +
> drivers/tee/qcomtee/Kconfig | 12 +
> drivers/tee/qcomtee/Makefile | 9 +
> drivers/tee/qcomtee/async.c | 182 ++++++
> drivers/tee/qcomtee/call.c | 820 +++++++++++++++++++++++++++
> drivers/tee/qcomtee/core.c | 915 +++++++++++++++++++++++++++++++
> drivers/tee/qcomtee/mem_obj.c | 169 ++++++
> drivers/tee/qcomtee/primordial_obj.c | 113 ++++
> drivers/tee/qcomtee/qcomtee.h | 185 +++++++
> drivers/tee/qcomtee/qcomtee_msg.h | 304 ++++++++++
> drivers/tee/qcomtee/qcomtee_object.h | 316 +++++++++++
> drivers/tee/qcomtee/shm.c | 150 +++++
> drivers/tee/qcomtee/user_obj.c | 692 +++++++++++++++++++++++
> drivers/tee/tee_core.c | 127 ++++-
> drivers/tee/tee_private.h | 6 -
> include/linux/firmware/qcom/qcom_scm.h | 6 +
> include/linux/firmware/qcom/qcom_tzmem.h | 15 +
> include/linux/tee_core.h | 54 +-
> include/linux/tee_drv.h | 12 +
> include/uapi/linux/tee.h | 56 +-
> 27 files changed, 4415 insertions(+), 28 deletions(-)
> ---
> base-commit: 33bcf93b9a6b028758105680f8b538a31bc563cf
> change-id: 20241202-qcom-tee-using-tee-ss-without-mem-obj-362c66340527
>
> Best regards,
> --
> Amirreza Zarrabi <amirreza.zarrabi(a)oss.qualcomm.com>
>
On Tue, Sep 9, 2025 at 6:34 AM Sumit Garg <sumit.garg(a)kernel.org> wrote:
>
> On Tue, Aug 12, 2025 at 05:35:29PM -0700, Amirreza Zarrabi wrote:
> > This patch series introduces a Trusted Execution Environment (TEE)
> > driver for Qualcomm TEE (QTEE). QTEE enables Trusted Applications (TAs)
> > and services to run securely. It uses an object-based interface, where
> > each service is an object with sets of operations. Clients can invoke
> > these operations on objects, which can generate results, including other
> > objects. For example, an object can load a TA and return another object
> > that represents the loaded TA, allowing access to its services.
> >
> > Kernel and userspace services are also available to QTEE through a
> > similar approach. QTEE makes callback requests that are converted into
> > object invocations. These objects can represent services within the
> > kernel or userspace process.
> >
> > Note: This patch series focuses on QTEE objects and userspace services.
> >
> > Linux already provides a TEE subsystem, which is described in [1]. The
> > tee subsystem provides a generic ioctl interface, TEE_IOC_INVOKE, which
> > can be used by userspace to talk to a TEE backend driver. We extend the
> > Linux TEE subsystem to understand object parameters and an ioctl call so
> > client can invoke objects in QTEE:
> >
> > - TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_*
> > - TEE_IOC_OBJECT_INVOKE
> >
> > The existing ioctl calls TEE_IOC_SUPPL_RECV and TEE_IOC_SUPPL_SEND are
> > used for invoking services in the userspace process by QTEE.
> >
> > The TEE backend driver uses the QTEE Transport Message to communicate
> > with QTEE. Interactions through the object INVOKE interface are
> > translated into QTEE messages. Likewise, object invocations from QTEE
> > for userspace objects are converted into SEND/RECV ioctl calls to
> > supplicants.
> >
> > The details of QTEE Transport Message to communicate with QTEE is
> > available in [PATCH 12/12] Documentation: tee: Add Qualcomm TEE driver.
> >
> > You can run basic tests with following steps:
> > git clone https://github.com/quic/quic-teec.git
> > cd quic-teec
> > mkdir build
> > cmake .. -DCMAKE_TOOLCHAIN_FILE=CMakeToolchain.txt -DBUILD_UNITTEST=ON
> >
> > https://github.com/quic/quic-teec/blob/main/README.md lists dependencies
> > needed to build the above.
> >
> > More comprehensive tests are availabe at
> > https://github.com/qualcomm/minkipc.
> >
> > root@qcom-armv8a:~# qtee_supplicant &
> > root@qcom-armv8a:~# qtee_supplicant: process entry PPID = 378
> > Total listener services to start = 4
> > Opening CRequestTABuffer_open
> > Path /data/
> > register_service ::Opening CRegisterTABufCBO_UID
> > Calling TAbufCBO Register
> > QTEE_SUPPLICANT RUNNING
> >
> > root@qcom-armv8a:~# smcinvoke_client -c /data 1
> > Run callback obj test...
> > Load /data/tzecotestapp.mbn, size 52192, buf 0x1e44ba0.
> > System Time: 2024-02-27 17:26:31
> > PASSED - Callback tests with Buffer inputs.
> > PASSED - Callback tests with Remote and Callback object inputs.
> > PASSED - Callback tests with Memory Object inputs.
> > TEST PASSED!
> > root@qcom-armv8a:~#
> > root@qcom-armv8a:~# smcinvoke_client -m /data 1
> > Run memory obj test...
> > Load /data/tzecotestapp.mbn, size 52192, buf 0x26cafba0.
> > System Time: 2024-02-27 17:26:39
> > PASSED - Single Memory Object access Test.
> > PASSED - Two Memory Object access Test.
> > TEST PASSED!
> >
> > This series has been tested for QTEE object invocations, including
> > loading a TA, requesting services from the TA, memory sharing, and
> > handling callback requests to a supplicant.
> >
> > Tested platforms: sm8650-mtp, sm8550-qrd, sm8650-qrd, sm8650-hdk
> >
> > [1] https://www.kernel.org/doc/Documentation/tee.txt
> >
> > Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi(a)oss.qualcomm.com>
> >
>
> At this point, I think this series is ready to be applied to linux-next.
There are still some warnings in "[PATCH v9 06/11] firmware: qcom:
scm: add support for object invocation"
/Jens
>
> > Changes in v7:
> > - Updated copyrights.
> > - Updated Acked-by: tags.
> > - Fixed kernel bot errors.
> > - Link to v6:
> > https://lore.kernel.org/r/20250713-qcom-tee-using-tee-ss-without-mem-obj-v6…
> >
> > Changes in v6:
> > - Relocate QTEE version into the driver's main service structure.
> > - Simplfies qcomtee_objref_to_arg() and qcomtee_objref_from_arg().
> > - Enhanced the return logic of qcomtee_object_do_invoke_internal().
> > - Improve comments and remove redundant checks.
> > - Improve helpers in qcomtee_msh.h to use GENMASK() and FIELD_GET().
> > - updated Tested-by:, Acked-by:, and Reviewed-by: tags
> > - Link to v5:
> > https://lore.kernel.org/r/20250526-qcom-tee-using-tee-ss-without-mem-obj-v5…
> >
> > Changes in v5:
> > - Remove references to kernel services and public APIs.
> > - Support auto detection for failing devices (e.g., RB1, RB4).
> > - Add helpers for obtaining client environment and service objects.
> > - Query the QTEE version and print it.
> > - Move remaining static variables, including the object table, to struct
> > qcomtee.
> > - Update TEE_MAX_ARG_SIZE to 4096.
> > - Add a dependancy to QCOM_TZMEM_MODE_SHMBRIDGE in Kconfig
> > - Reorganize code by removing release.c and qcom_scm.c.
> > - Add more error messages and improve comments.
> > - updated Tested-by:, Acked-by:, and Reviewed-by: tags
> > - Link to v4: https://lore.kernel.org/r/20250428-qcom-tee-using-tee-ss-without-mem-obj-v4…
> >
> > Changes in v4:
> > - Move teedev_ctx_get/put and tee_device_get/put to tee_core.h.
> > - Rename object to id in struct tee_ioctl_object_invoke_arg.
> > - Replace spinlock with mutex for qtee_objects_idr.
> > - Move qcomtee_object_get to qcomtee_user/memobj_param_to_object.
> > - More code cleanup following the comments.
> > - Cleanup documentations.
> > - Update MAINTAINERS file.
> > - Link to v3: https://lore.kernel.org/r/20250327-qcom-tee-using-tee-ss-without-mem-obj-v3…
> >
> > Changes in v3:
> > - Export shm_bridge create/delete APIs.
> > - Enable support for QTEE memory objects.
> > - Update the memory management code to use the TEE subsystem for all
> > allocations using the pool.
> > - Move all driver states into the driver's main service struct.
> > - Add more documentations.
> > - Link to v2: https://lore.kernel.org/r/20250202-qcom-tee-using-tee-ss-without-mem-obj-v2…
> >
> > Changes in v2:
> > - Clean up commit messages and comments.
> > - Use better names such as ubuf instead of membuf or QCOMTEE prefix
> > instead of QCOM_TEE, or names that are more consistent with other
> > TEE-backend drivers such as qcomtee_context_data instead of
> > qcom_tee_context.
> > - Drop the DTS patch and instantiate the device from the scm driver.
> > - Use a single structure for all driver's internal states.
> > - Drop srcu primitives and use the existing mutex for synchronization
> > between the supplicant and QTEE.
> > - Directly use tee_context to track the lifetime of qcomtee_context_data.
> > - Add close_context() to be called when the user closes the tee_context.
> > - Link to v1: https://lore.kernel.org/r/20241202-qcom-tee-using-tee-ss-without-mem-obj-v1…
> >
> > Changes in v1:
> > - It is a complete rewrite to utilize the TEE subsystem.
> > - Link to RFC: https://lore.kernel.org/all/20240702-qcom-tee-object-and-ioctls-v1-0-633c3d…
> >
> > ---
> > Amirreza Zarrabi (11):
> > tee: allow a driver to allocate a tee_device without a pool
> > tee: add close_context to TEE driver operation
> > tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
> > tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
> > tee: increase TEE_MAX_ARG_SIZE to 4096
>
> > firmware: qcom: scm: add support for object invocation
> > firmware: qcom: tzmem: export shm_bridge create/delete
>
> Bjorn/Konrad,
>
> Since majority of this series belong to TEE subsystem, are you folks
> fine to ack these patches for Jens to pick them up for next?
>
> -Sumit
>
> > tee: add Qualcomm TEE driver
> > qcomtee: add primordial object
> > qcomtee: enable TEE_IOC_SHM_ALLOC ioctl
> > Documentation: tee: Add Qualcomm TEE driver
>
>
>
> >
> > Documentation/tee/index.rst | 1 +
> > Documentation/tee/qtee.rst | 96 ++++
> > MAINTAINERS | 7 +
> > drivers/firmware/qcom/qcom_scm.c | 128 +++++
> > drivers/firmware/qcom/qcom_scm.h | 7 +
> > drivers/firmware/qcom/qcom_tzmem.c | 63 ++-
> > drivers/tee/Kconfig | 1 +
> > drivers/tee/Makefile | 1 +
> > drivers/tee/qcomtee/Kconfig | 11 +
> > drivers/tee/qcomtee/Makefile | 9 +
> > drivers/tee/qcomtee/async.c | 183 ++++++
> > drivers/tee/qcomtee/call.c | 820 +++++++++++++++++++++++++++
> > drivers/tee/qcomtee/core.c | 920 +++++++++++++++++++++++++++++++
> > drivers/tee/qcomtee/mem_obj.c | 169 ++++++
> > drivers/tee/qcomtee/primordial_obj.c | 116 ++++
> > drivers/tee/qcomtee/qcomtee.h | 185 +++++++
> > drivers/tee/qcomtee/qcomtee_msg.h | 300 ++++++++++
> > drivers/tee/qcomtee/qcomtee_object.h | 316 +++++++++++
> > drivers/tee/qcomtee/shm.c | 150 +++++
> > drivers/tee/qcomtee/user_obj.c | 692 +++++++++++++++++++++++
> > drivers/tee/tee_core.c | 127 ++++-
> > drivers/tee/tee_private.h | 6 -
> > include/linux/firmware/qcom/qcom_scm.h | 6 +
> > include/linux/firmware/qcom/qcom_tzmem.h | 15 +
> > include/linux/tee_core.h | 54 +-
> > include/linux/tee_drv.h | 12 +
> > include/uapi/linux/tee.h | 56 +-
> > 27 files changed, 4423 insertions(+), 28 deletions(-)
> > ---
> > base-commit: 2674d1eadaa2fd3a918dfcdb6d0bb49efe8a8bb9
> > change-id: 20241202-qcom-tee-using-tee-ss-without-mem-obj-362c66340527
> >
> > Best regards,
> > --
> > Amirreza Zarrabi <amirreza.zarrabi(a)oss.qualcomm.com>
> >
> >
Hi Jyothi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on vkoul-dmaengine/next]
[also build test WARNING on andi-shyti/i2c/i2c-host linus/master v6.17-rc4 next-20250905]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jyothi-Kumar-Seerapu/dmaengi…
base: https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next
patch link: https://lore.kernel.org/r/20250903073059.2151837-3-quic_jseerapu%40quicinc.…
patch subject: [PATCH v7 2/2] i2c: i2c-qcom-geni: Add Block event interrupt support
config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20250906/202509062008.lSOdhd4U-lkp@…)
compiler: gcc-13 (Debian 13.3.0-16) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250906/202509062008.lSOdhd4U-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509062008.lSOdhd4U-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/i2c/busses/i2c-qcom-geni.c: In function 'geni_i2c_gpi_multi_desc_unmap':
>> drivers/i2c/busses/i2c-qcom-geni.c:576:42: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
576 | NULL, (dma_addr_t)NULL);
| ^
vim +576 drivers/i2c/busses/i2c-qcom-geni.c
555
556 /**
557 * geni_i2c_gpi_multi_desc_unmap() - Unmaps DMA buffers post multi message TX transfers
558 * @gi2c: I2C dev handle
559 * @msgs: Array of I2C messages
560 * @peripheral: Pointer to gpi_i2c_config
561 */
562 static void geni_i2c_gpi_multi_desc_unmap(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[],
563 struct gpi_i2c_config *peripheral)
564 {
565 u32 msg_xfer_cnt, wr_idx = 0;
566 struct geni_i2c_gpi_multi_desc_xfer *tx_multi_xfer = &gi2c->i2c_multi_desc_config;
567
568 msg_xfer_cnt = gi2c->err ? tx_multi_xfer->msg_idx_cnt : tx_multi_xfer->irq_cnt;
569
570 /* Unmap the processed DMA buffers based on the received interrupt count */
571 for (; tx_multi_xfer->unmap_msg_cnt < msg_xfer_cnt; tx_multi_xfer->unmap_msg_cnt++) {
572 wr_idx = tx_multi_xfer->unmap_msg_cnt;
573 geni_i2c_gpi_unmap(gi2c, &msgs[wr_idx],
574 tx_multi_xfer->dma_buf[wr_idx],
575 tx_multi_xfer->dma_addr[wr_idx],
> 576 NULL, (dma_addr_t)NULL);
577
578 if (tx_multi_xfer->unmap_msg_cnt == gi2c->num_msgs - 1) {
579 kfree(tx_multi_xfer->dma_buf);
580 kfree(tx_multi_xfer->dma_addr);
581 break;
582 }
583 }
584 }
585
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
From: Thierry Reding <treding(a)nvidia.com>
Hi,
This series adds support for the video protection region (VPR) used on
Tegra SoC devices. It's a special region of memory that is protected
from accesses by the CPU and used to store DRM protected content (both
decrypted stream data as well as decoded video frames).
Patches 1 and 2 add DT binding documentation for the VPR and add the VPR
to the list of memory-region items for display and host1x.
Patch 3 introduces new APIs needed by the Tegra VPR implementation that
allow CMA areas to be dynamically created at runtime rather than using
the fixed, system-wide list. This is used in this driver specifically
because it can use an arbitrary number of these areas (though they are
currently limited to 4).
Patch 4 adds some infrastructure for DMA heap implementations to provide
information through debugfs.
The Tegra VPR implementation is added in patch 5. See its commit message
for more details about the specifics of this implementation.
Finally, patches 6-9 add the VPR placeholder node on Tegra234 and hook
it up to the host1x and GPU nodes so that they can make use of this
region.
Thierry
Thierry Reding (9):
dt-bindings: reserved-memory: Document Tegra VPR
dt-bindings: display: tegra: Document memory regions
mm/cma: Allow dynamically creating CMA areas
dma-buf: heaps: Add debugfs support
dma-buf: heaps: Add support for Tegra VPR
arm64: tegra: Add VPR placeholder node on Tegra234
arm64: tegra: Add GPU node on Tegra234
arm64: tegra: Hook up VPR to host1x
arm64: tegra: Hook up VPR to the GPU
.../display/tegra/nvidia,tegra186-dc.yaml | 10 +
.../display/tegra/nvidia,tegra20-dc.yaml | 10 +-
.../display/tegra/nvidia,tegra20-host1x.yaml | 7 +
.../nvidia,tegra-video-protection-region.yaml | 55 ++
arch/arm64/boot/dts/nvidia/tegra234.dtsi | 57 ++
drivers/dma-buf/dma-heap.c | 56 ++
drivers/dma-buf/heaps/Kconfig | 7 +
drivers/dma-buf/heaps/Makefile | 1 +
drivers/dma-buf/heaps/tegra-vpr.c | 831 ++++++++++++++++++
include/linux/cma.h | 16 +
include/linux/dma-heap.h | 2 +
include/trace/events/tegra_vpr.h | 57 ++
mm/cma.c | 89 +-
13 files changed, 1175 insertions(+), 23 deletions(-)
create mode 100644 Documentation/devicetree/bindings/reserved-memory/nvidia,tegra-video-protection-region.yaml
create mode 100644 drivers/dma-buf/heaps/tegra-vpr.c
create mode 100644 include/trace/events/tegra_vpr.h
--
2.50.0
On Wed, Sep 03, 2025 at 09:41:18AM -0700, Frank van der Linden wrote:
> On Wed, Sep 3, 2025 at 9:05 AM Thierry Reding <thierry.reding(a)gmail.com> wrote:
> >
> > On Tue, Sep 02, 2025 at 10:27:01AM -0700, Frank van der Linden wrote:
> > > On Tue, Sep 2, 2025 at 8:46 AM Thierry Reding <thierry.reding(a)gmail.com> wrote:
> > > >
> > > > From: Thierry Reding <treding(a)nvidia.com>
> > > >
> > > > There is no technical reason why there should be a limited number of CMA
> > > > regions, so extract some code into helpers and use them to create extra
> > > > functions (cma_create() and cma_free()) that allow creating and freeing,
> > > > respectively, CMA regions dynamically at runtime.
> > > >
> > > > Note that these dynamically created CMA areas are treated specially and
> > > > do not contribute to the number of total CMA pages so that this count
> > > > still only applies to the fixed number of CMA areas.
> > > >
> > > > Signed-off-by: Thierry Reding <treding(a)nvidia.com>
> > > > ---
> > > > include/linux/cma.h | 16 ++++++++
> > > > mm/cma.c | 89 ++++++++++++++++++++++++++++++++++-----------
> > > > 2 files changed, 83 insertions(+), 22 deletions(-)
> > [...]
> > > I agree that supporting dynamic CMA areas would be good. However, by
> > > doing it like this, these CMA areas are invisible to the rest of the
> > > system. E.g. cma_for_each_area() does not know about them. It seems a
> > > bit inconsistent that there will now be some areas that are globally
> > > known, and some that are not.
> >
> > That was kind of the point of this experiment. When I started on this I
> > ran into the case where I was running out of predefined CMA areas and as
> > I went looking for ways on how to fix this, I realized that there's not
> > much reason to keep a global list of these areas. And even less reason
> > to limit the number of CMA areas to this predefined list. Very little
> > code outside of the core CMA code even uses this.
> >
> > There's one instance of cma_for_each_area() that I don't grok. There's
> > another early MMU fixup for CMA areas in 32-bit ARM that. Other than
> > that there's a few places where the total CMA page count is shown for
> > informational purposes and I don't know how useful that really is
> > because totalcma_pages doesn't really track how many pages are used for
> > CMA, but pages that could potentially be used for CMA.
> >
> > And that's about it.
> >
> > It seems like there are cases where we might really need to globally
> > know about some of these areas, specifically ones that are allocated
> > very early during boot and then used for very specific purposes.
> >
> > However, it seems to me like CMA is more universally useful than just
> > for these cases and I don't see the usefulness of tracking these more
> > generic uses.
> >
> > > I am being somewhat selfish here, as I have some WIP code that needs
> > > the global list :-) But I think the inconsistency is a more general
> > > point than just what I want (and the s390 code does use
> > > cma_for_each_area()). Maybe you could keep maintaining a global
> > > structure containing all areas?
> >
> > If it's really useful to be able to access all CMA areas, then we could
> > easily just add them all to a global linked list upon activation (we may
> > still want/need to keep the predefined list around for all those early
> > allocation cases). That way we'd get the best of both worlds.
> >
> > > What do you think are the chances of running out of the global count
> > > of areas?
> >
> > Well, I did run out of CMA areas during the early VPR testing because I
> > was initially testing with 16 areas and a different allocation scheme
> > that turned out to cause too many resizes in common cases.
> >
> > However, given that the default is 8 on normal systems (20 on NUMA) and
> > is configurable, it means that even with restricting this to 4 for VPR
> > doesn't always guarantee that all 4 are available. Again, yes, we could
> > keep bumping that number, but why not turn this into something a bit
> > more robust where nobody has to know or care about how many there are?
> >
> > > Also, you say that "these are treated specially and do not contribute
> > > to the number of total CMA pages". But, if I'm reading this right, you
> > > do call cma_activate_area(), which will do
> > > init_cma_reserved_pageblock() for each pageblock in it. Which adjusts
> > > the CMA counters for the zone they are in. But your change does not
> > > adjust totalcma_pages for dynamically created areas. That seems
> > > inconsistent, too.
> >
> > I was referring to just totalcma_pages that isn't impacted by these
> > dynamically allocated regions. This is, again, because I don't see why
> > that information would be useful. It's a fairly easy change to update
> > that value, so if people prefer that, I can add that.
> >
> > I don't see an immediate connection between totalcma_pages and
> > init_cma_reserved_pageblock(). I thought the latter was primarily useful
> > for making sure that the CMA pages can be migrated, which is still
> > critical for this use-case.
>
> My comment was about statistics, they would be inconsistent after your
> change. E.g. currently, totalcma_pages is equal to the sum of CMA
> pages in each zone. But that would no longer be true, and applications
> / administrators looking at those statistics might see the
> inconsistency (between meminfo and vmstat) and wonder what's going on.
> It seems best to keep those numbers in sync.
>
> In general, I think it's fine to support dynamic allocation, and I
> agree with your arguments that it doesn't seem right to set the number
> of CMA areas via a config option. I would just like there to be a
> canonical way to find all CMA areas.
Okay, so judging by your and David's feedback, it sounds like I should
add a bit of code to track dynamically allocated areas within a global
list, along with the existing predefined regions and keep totalcma_pages
updated so that the global view is consistent.
I'll look into that. Thanks for the feedback.
Thierry
On Mon, 1 Sep 2025 15:32:22 +0530 Meghana Malladi wrote:
> if (!emac->xdpi.prog && !prog)
> return 0;
>
> - WRITE_ONCE(emac->xdp_prog, prog);
> + if (netif_running(emac->ndev)) {
> + prueth_destroy_txq(emac);
> + prueth_destroy_rxq(emac);
> + }
> +
> + old_prog = xchg(&emac->xdp_prog, prog);
> + if (old_prog)
> + bpf_prog_put(old_prog);
> +
> + if (netif_running(emac->ndev)) {
> + ret = prueth_create_rxq(emac);
shutting the device down and freeing all rx memory for reconfig is not
okay. If the system is low on memory the Rx buffer allocations may fail
and system may drop off the network. You must either pre-allocate or
avoid freeing the memory, and just restart the queues.
> + if (ret) {
> + netdev_err(emac->ndev, "Failed to create RX queue: %d\n", ret);
> + return ret;
> + }
> +
> + ret = prueth_create_txq(emac);
> + if (ret) {
> + netdev_err(emac->ndev, "Failed to create TX queue: %d\n", ret);
> + prueth_destroy_rxq(emac);
> + emac->xdp_prog = NULL;
> + return ret;
> + }
> + }
>
> xdp_attachment_setup(&emac->xdpi, bpf);
On Sat, Aug 30, 2025 at 4:58 PM Barry Song <21cnbao(a)gmail.com> wrote:
>
> From: Barry Song <v-songbaohua(a)oppo.com>
>
> We can allocate high-order pages, but mapping them one by
> one is inefficient. This patch changes the code to map
> as large a chunk as possible. The code looks somewhat
> complicated mainly because supporting mmap with a
> non-zero offset is a bit tricky.
>
> Using the micro-benchmark below, we see that mmap becomes
> 3.5X faster:
...
It's been awhile since I've done mm things, so take it with a pinch of
salt, but this seems reasonable to me.
Though, one thought below...
> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> index bbe7881f1360..4c782fe33fd4 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -186,20 +186,35 @@ static int system_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
> struct system_heap_buffer *buffer = dmabuf->priv;
> struct sg_table *table = &buffer->sg_table;
> unsigned long addr = vma->vm_start;
> - struct sg_page_iter piter;
> - int ret;
> + unsigned long pgoff = vma->vm_pgoff;
> + struct scatterlist *sg;
> + int i, ret;
> +
> + for_each_sgtable_sg(table, sg, i) {
> + unsigned long n = sg->length >> PAGE_SHIFT;
>
> - for_each_sgtable_page(table, &piter, vma->vm_pgoff) {
> - struct page *page = sg_page_iter_page(&piter);
> + if (pgoff < n)
> + break;
> + pgoff -= n;
> + }
> +
> + for (; sg && addr < vma->vm_end; sg = sg_next(sg)) {
> + unsigned long n = (sg->length >> PAGE_SHIFT) - pgoff;
> + struct page *page = sg_page(sg) + pgoff;
> + unsigned long size = n << PAGE_SHIFT;
> +
> + if (addr + size > vma->vm_end)
> + size = vma->vm_end - addr;
>
> - ret = remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE,
> - vma->vm_page_prot);
> + ret = remap_pfn_range(vma, addr, page_to_pfn(page),
> + size, vma->vm_page_prot);
It feels like this sort of mapping loop for higher order pages
wouldn't be a unique pattern to just this code. Would this be better
worked into a helper so it would be more generally usable?
Otherwise,
Acked-by: John Stultz <jstultz(a)google.com>
thanks
-john
>> +>> +struct cma *__init cma_create(phys_addr_t base, phys_addr_t size,
>> + unsigned int order_per_bit, const char *name)
>> +{
>> + struct cma *cma;
>> + int ret;
>> +
>> + ret = cma_check_memory(base, size);
>> + if (ret < 0)
>> + return ERR_PTR(ret);
>> +
>> + cma = kzalloc(sizeof(*cma), GFP_KERNEL);
>> + if (!cma)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + cma_init_area(cma, name, size, order_per_bit);
>> + cma->ranges[0].base_pfn = PFN_DOWN(base);
>> + cma->ranges[0].early_pfn = PFN_DOWN(base);
>> + cma->ranges[0].count = cma->count;
>> + cma->nranges = 1;
>> +
>> + cma_activate_area(cma);
>> +
>> + return cma;
>> +}
>> +
>> +void cma_free(struct cma *cma)
>> +{
>> + kfree(cma);
>> +}
>> --
>> 2.50.0
>
>
> I agree that supporting dynamic CMA areas would be good. However, by
> doing it like this, these CMA areas are invisible to the rest of the
> system. E.g. cma_for_each_area() does not know about them. It seems a
> bit inconsistent that there will now be some areas that are globally
> known, and some that are not.
Yeah, I'm not a fan of that.
What is the big problem we are trying to solve here? Why do they have to
be dynamic, why do they even have to support freeing?
--
Cheers
David / dhildenb
On Tue, Sep 02, 2025 at 10:27:01AM -0700, Frank van der Linden wrote:
> On Tue, Sep 2, 2025 at 8:46 AM Thierry Reding <thierry.reding(a)gmail.com> wrote:
> >
> > From: Thierry Reding <treding(a)nvidia.com>
> >
> > There is no technical reason why there should be a limited number of CMA
> > regions, so extract some code into helpers and use them to create extra
> > functions (cma_create() and cma_free()) that allow creating and freeing,
> > respectively, CMA regions dynamically at runtime.
> >
> > Note that these dynamically created CMA areas are treated specially and
> > do not contribute to the number of total CMA pages so that this count
> > still only applies to the fixed number of CMA areas.
> >
> > Signed-off-by: Thierry Reding <treding(a)nvidia.com>
> > ---
> > include/linux/cma.h | 16 ++++++++
> > mm/cma.c | 89 ++++++++++++++++++++++++++++++++++-----------
> > 2 files changed, 83 insertions(+), 22 deletions(-)
[...]
> I agree that supporting dynamic CMA areas would be good. However, by
> doing it like this, these CMA areas are invisible to the rest of the
> system. E.g. cma_for_each_area() does not know about them. It seems a
> bit inconsistent that there will now be some areas that are globally
> known, and some that are not.
That was kind of the point of this experiment. When I started on this I
ran into the case where I was running out of predefined CMA areas and as
I went looking for ways on how to fix this, I realized that there's not
much reason to keep a global list of these areas. And even less reason
to limit the number of CMA areas to this predefined list. Very little
code outside of the core CMA code even uses this.
There's one instance of cma_for_each_area() that I don't grok. There's
another early MMU fixup for CMA areas in 32-bit ARM that. Other than
that there's a few places where the total CMA page count is shown for
informational purposes and I don't know how useful that really is
because totalcma_pages doesn't really track how many pages are used for
CMA, but pages that could potentially be used for CMA.
And that's about it.
It seems like there are cases where we might really need to globally
know about some of these areas, specifically ones that are allocated
very early during boot and then used for very specific purposes.
However, it seems to me like CMA is more universally useful than just
for these cases and I don't see the usefulness of tracking these more
generic uses.
> I am being somewhat selfish here, as I have some WIP code that needs
> the global list :-) But I think the inconsistency is a more general
> point than just what I want (and the s390 code does use
> cma_for_each_area()). Maybe you could keep maintaining a global
> structure containing all areas?
If it's really useful to be able to access all CMA areas, then we could
easily just add them all to a global linked list upon activation (we may
still want/need to keep the predefined list around for all those early
allocation cases). That way we'd get the best of both worlds.
> What do you think are the chances of running out of the global count
> of areas?
Well, I did run out of CMA areas during the early VPR testing because I
was initially testing with 16 areas and a different allocation scheme
that turned out to cause too many resizes in common cases.
However, given that the default is 8 on normal systems (20 on NUMA) and
is configurable, it means that even with restricting this to 4 for VPR
doesn't always guarantee that all 4 are available. Again, yes, we could
keep bumping that number, but why not turn this into something a bit
more robust where nobody has to know or care about how many there are?
> Also, you say that "these are treated specially and do not contribute
> to the number of total CMA pages". But, if I'm reading this right, you
> do call cma_activate_area(), which will do
> init_cma_reserved_pageblock() for each pageblock in it. Which adjusts
> the CMA counters for the zone they are in. But your change does not
> adjust totalcma_pages for dynamically created areas. That seems
> inconsistent, too.
I was referring to just totalcma_pages that isn't impacted by these
dynamically allocated regions. This is, again, because I don't see why
that information would be useful. It's a fairly easy change to update
that value, so if people prefer that, I can add that.
I don't see an immediate connection between totalcma_pages and
init_cma_reserved_pageblock(). I thought the latter was primarily useful
for making sure that the CMA pages can be migrated, which is still
critical for this use-case.
Thierry
Hi Amirreza,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 33bcf93b9a6b028758105680f8b538a31bc563cf]
url: https://github.com/intel-lab-lkp/linux/commits/Amirreza-Zarrabi/tee-allow-a…
base: 33bcf93b9a6b028758105680f8b538a31bc563cf
patch link: https://lore.kernel.org/r/20250901-qcom-tee-using-tee-ss-without-mem-obj-v9…
patch subject: [PATCH v9 06/11] firmware: qcom: scm: add support for object invocation
config: i386-buildonly-randconfig-001-20250903 (https://download.01.org/0day-ci/archive/20250903/202509030554.WR3MNpCE-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250903/202509030554.WR3MNpCE-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509030554.WR3MNpCE-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/device.h:15,
from include/linux/dma-mapping.h:5,
from drivers/firmware/qcom/qcom_scm.c:13:
drivers/firmware/qcom/qcom_scm.c: In function 'qcom_scm_qtee_init':
>> drivers/firmware/qcom/qcom_scm.c:2208:35: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long int' [-Wformat=]
2208 | dev_err(scm->dev, "qcomtee: register failed: %d\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap'
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~
include/linux/dev_printk.h:154:56: note: in expansion of macro 'dev_fmt'
154 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~
drivers/firmware/qcom/qcom_scm.c:2208:17: note: in expansion of macro 'dev_err'
2208 | dev_err(scm->dev, "qcomtee: register failed: %d\n",
| ^~~~~~~
drivers/firmware/qcom/qcom_scm.c:2208:63: note: format string is defined here
2208 | dev_err(scm->dev, "qcomtee: register failed: %d\n",
| ~^
| |
| int
| %ld
vim +2208 drivers/firmware/qcom/qcom_scm.c
2188
2189 static void qcom_scm_qtee_init(struct qcom_scm *scm)
2190 {
2191 struct platform_device *qtee_dev;
2192 u64 result, response_type;
2193 int ret;
2194
2195 /*
2196 * Probe for smcinvoke support. This will fail due to invalid buffers,
2197 * but first, it checks whether the call is supported in QTEE syscall
2198 * handler. If it is not supported, -EIO is returned.
2199 */
2200 ret = qcom_scm_qtee_invoke_smc(0, 0, 0, 0, &result, &response_type);
2201 if (ret == -EIO)
2202 return;
2203
2204 /* Setup QTEE interface device. */
2205 qtee_dev = platform_device_register_data(scm->dev, "qcomtee",
2206 PLATFORM_DEVID_NONE, NULL, 0);
2207 if (IS_ERR(qtee_dev)) {
> 2208 dev_err(scm->dev, "qcomtee: register failed: %d\n",
2209 PTR_ERR(qtee_dev));
2210 return;
2211 }
2212
2213 ret = devm_add_action_or_reset(scm->dev, qcom_scm_qtee_free, qtee_dev);
2214 if (ret)
2215 dev_err(scm->dev, "qcomtee: add action failed: %d\n", ret);
2216 }
2217
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Changelog:
v1:
* Changed commit messages.
* Reused DMA_ATTR_MMIO attribute.
* Returned support for multiple DMA ranges per-dMABUF.
v0: https://lore.kernel.org/all/cover.1753274085.git.leonro@nvidia.com
---------------------------------------------------------------------------
Based on "[PATCH v1 00/16] dma-mapping: migrate to physical address-based API"
https://lore.kernel.org/all/cover.1754292567.git.leon@kernel.org series.
---------------------------------------------------------------------------
This series extends the VFIO PCI subsystem to support exporting MMIO regions
from PCI device BARs as dma-buf objects, enabling safe sharing of non-struct
page memory with controlled lifetime management. This allows RDMA and other
subsystems to import dma-buf FDs and build them into memory regions for PCI
P2P operations.
The series supports a use case for SPDK where a NVMe device will be owned
by SPDK through VFIO but interacting with a RDMA device. The RDMA device
may directly access the NVMe CMB or directly manipulate the NVMe device's
doorbell using PCI P2P.
However, as a general mechanism, it can support many other scenarios with
VFIO. This dmabuf approach can be usable by iommufd as well for generic
and safe P2P mappings.
In addition to the SPDK use-case mentioned above, the capability added
in this patch series can also be useful when a buffer (located in device
memory such as VRAM) needs to be shared between any two dGPU devices or
instances (assuming one of them is bound to VFIO PCI) as long as they
are P2P DMA compatible.
The implementation provides a revocable attachment mechanism using dma-buf
move operations. MMIO regions are normally pinned as BARs don't change
physical addresses, but access is revoked when the VFIO device is closed
or a PCI reset is issued. This ensures kernel self-defense against
potentially hostile userspace.
The series includes significant refactoring of the PCI P2PDMA subsystem
to separate core P2P functionality from memory allocation features,
making it more modular and suitable for VFIO use cases that don't need
struct page support.
-----------------------------------------------------------------------
The series is based originally on
https://lore.kernel.org/all/20250307052248.405803-1-vivek.kasireddy@intel.c…
but heavily rewritten to be based on DMA physical API.
-----------------------------------------------------------------------
The WIP branch can be found here:
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/log/?h=…
Thanks
Leon Romanovsky (8):
PCI/P2PDMA: Remove redundant bus_offset from map state
PCI/P2PDMA: Separate the mmap() support from the core logic
PCI/P2PDMA: Simplify bus address mapping API
PCI/P2PDMA: Refactor to separate core P2P functionality from memory
allocation
PCI/P2PDMA: Export pci_p2pdma_map_type() function
types: move phys_vec definition to common header
vfio/pci: Enable peer-to-peer DMA transactions by default
vfio/pci: Add dma-buf export support for MMIO regions
Vivek Kasireddy (2):
vfio: Export vfio device get and put registration helpers
vfio/pci: Share the core device pointer while invoking feature
functions
block/blk-mq-dma.c | 7 +-
drivers/iommu/dma-iommu.c | 4 +-
drivers/pci/p2pdma.c | 154 ++++++++----
drivers/vfio/pci/Kconfig | 20 ++
drivers/vfio/pci/Makefile | 2 +
drivers/vfio/pci/vfio_pci_config.c | 22 +-
drivers/vfio/pci/vfio_pci_core.c | 59 +++--
drivers/vfio/pci/vfio_pci_dmabuf.c | 390 +++++++++++++++++++++++++++++
drivers/vfio/pci/vfio_pci_priv.h | 23 ++
drivers/vfio/vfio_main.c | 2 +
include/linux/dma-buf.h | 1 +
include/linux/pci-p2pdma.h | 114 +++++----
include/linux/types.h | 5 +
include/linux/vfio.h | 2 +
include/linux/vfio_pci_core.h | 4 +
include/uapi/linux/vfio.h | 25 ++
kernel/dma/direct.c | 4 +-
mm/hmm.c | 2 +-
18 files changed, 715 insertions(+), 125 deletions(-)
create mode 100644 drivers/vfio/pci/vfio_pci_dmabuf.c
--
2.50.1
Hi,
This patch set allocates the protected DMA-bufs from a DMA-heap
instantiated from the TEE subsystem.
The TEE subsystem handles the DMA-buf allocations since it is the TEE
(OP-TEE, AMD-TEE, TS-TEE, or perhaps a future QTEE) which sets up the
protection for the memory used for the DMA-bufs.
The DMA-heap uses a protected memory pool provided by the backend TEE
driver, allowing it to choose how to allocate the protected physical
memory.
The allocated DMA-bufs must be imported with a new TEE_IOC_SHM_REGISTER_FD
before they can be passed as arguments when requesting services from the
secure world.
Three use-cases (Secure Video Playback, Trusted UI, and Secure Video
Recording) have been identified so far to serve as examples of what can be
expected. The use-cases have predefined DMA-heap names,
"protected,secure-video", "protected,trusted-ui", and
"protected,secure-video-record". The backend driver registers protected
memory pools for the use-cases it supports.
Each use-case has its own protected memory pool since different use-cases
require isolation from different parts of the system. A protected memory
pool can be based on a static carveout instantiated while probing the TEE
backend driver, or dynamically allocated from CMA (dma_alloc_pages()) and
made protected as needed by the TEE.
This can be tested on a RockPi 4B+ with the following steps:
repo init -u https://github.com/jenswi-linaro/manifest.git -m rockpi4.xml \
-b prototype/sdp-v11
repo sync -j8
cd build
make toolchains -j$(nproc)
make all -j$(nproc)
# Copy ../out/rockpi4.img to an SD card and boot the RockPi from that
# Connect a monitor to the RockPi
# login and at the prompt:
gst-launch-1.0 videotestsrc ! \
aesenc key=1f9423681beb9a79215820f6bda73d0f \
iv=e9aa8e834d8d70b7e0d254ff670dd718 serialize-iv=true ! \
aesdec key=1f9423681beb9a79215820f6bda73d0f ! \
kmssink
The aesdec module has been hacked to use an OP-TEE TA to decrypt the stream
into protected DMA-bufs which are consumed by the kmssink.
The primitive QEMU tests from previous patch sets can be tested on RockPi
in the same way using:
xtest --sdp-basic
The primitive tests are tested on QEMU with the following steps:
repo init -u https://github.com/jenswi-linaro/manifest.git -m qemu_v8.xml \
-b prototype/sdp-v11
repo sync -j8
cd build
make toolchains -j$(nproc)
make SPMC_AT_EL=1 all -j$(nproc)
make SPMC_AT_EL=1 run-only
# login and at the prompt:
xtest --sdp-basic
The SPMC_AT_EL=1 parameter configures the build with FF-A and an SPMC at
S-EL1 inside OP-TEE. The parameter can be changed to SPMC_AT_EL=n to test
without FF-A using the original SMC ABI instead. Please remember to do
%make arm-tf-clean
for TF-A to be rebuilt properly using the new configuration.
https://optee.readthedocs.io/en/latest/building/prerequisites.html
list dependencies required to build the above.
The primitive tests are pretty basic, mostly checking that a Trusted
Application in the secure world can access and manipulate the memory. There
are also some negative tests for out of bounds buffers, etc.
Thanks,
Jens
Changes since V10:
* Changed the new ABI OPTEE_MSG_CMD_GET_PROTMEM_CONFIG to report a list
of u32 memory attributes instead of u16 endpoints to make room for both
endpoint and access permissions in each entry.
* In "tee: new ioctl to a register tee_shm from a dmabuf file descriptor",
remove the unused path for DMA-bufs allocated by other means than the on
in the TEE SS.
* In "tee: implement protected DMA-heap", handle unloading of the
backend driver module implementing the heap. The heap is reference
counted and also calls tee_device_get() to guarantee that the module
remains available while the heap is instantiated.
* In "optee: support protected memory allocation", use
dma_coerce_mask_and_coherent() instead of open-coding the function.
* Added Sumit's R-B to
- "optee: smc abi: dynamic protected memory allocation"
- "optee: FF-A: dynamic protected memory allocation"
- "optee: support protected memory allocation"
- "tee: implement protected DMA-heap"
- "dma-buf: dma-heap: export declared functions"
Changes since V9:
* Adding Sumit's R-B to "optee: sync secure world ABI headers"
* Update commit message as requested for "dma-buf: dma-heap: export
declared functions".
* In "tee: implement protected DMA-heap":
- add the hidden config option TEE_DMABUF_HEAPS to tell if the TEE
subsystem can support DMA heaps
- add a pfn_valid() to check that the passed physical address can be
used by __pfn_to_page() and friends
- remove the memremap() call, the caller is should do that instead if
needed
* In "tee: add tee_shm_alloc_dma_mem()" guard the calls to
dma_alloc_pages() and dma_free_pages() with TEE_DMABUF_HEAPS to avoid
linking errors in some configurations
* In "optee: support protected memory allocation":
- add the hidden config option OPTEE_STATIC_PROTMEM_POOL to tell if the
driver can support a static protected memory pool
- optee_protmem_pool_init() is slightly refactored to make the patches
that follow easier
- Call devm_memremap() before calling tee_protmem_static_pool_alloc()
Changes since V8:
* Using dma_alloc_pages() instead of cma_alloc() so the direct dependency on
CMA can be removed together with the patches
"cma: export cma_alloc() and cma_release()" and
"dma-contiguous: export dma_contiguous_default_area". The patch
* Renaming the patch "tee: add tee_shm_alloc_cma_phys_mem()" to
"tee: add tee_shm_alloc_dma_mem()"
* Setting DMA mask for the OP-TEE TEE device based on input from the secure
world instead of relying on the parent device so following patches are
removed: "tee: tee_device_alloc(): copy dma_mask from parent device" and
"optee: pass parent device to tee_device_alloc()".
* Adding Sumit Garg's R-B to "tee: refactor params_from_user()"
* In the patch "tee: implement protected DMA-heap", map the physical memory
passed to tee_protmem_static_pool_alloc().
Changes since V7:
* Adding "dma-buf: dma-heap: export declared functions",
"cma: export cma_alloc() and cma_release()", and
"dma-contiguous: export dma_contiguous_default_area" to export the symbols
needed to keep the TEE subsystem as a load module.
* Removing CONFIG_TEE_DMABUF_HEAP and CONFIG_TEE_CMA since they aren't
needed any longer.
* Addressing review comments in "optee: sync secure world ABI headers"
* Better align protected memory pool initialization between the smc-abi and
ffa-abi parts of the optee driver.
* Removing the patch "optee: account for direction while converting parameters"
Changes since V6:
* Restricted memory is now known as protected memory since to use the same
term as https://docs.vulkan.org/guide/latest/protected.html. Update all
patches to consistently use protected memory.
* In "tee: implement protected DMA-heap" add the hidden config option
TEE_DMABUF_HEAP to tell if the DMABUF_HEAPS functions are available
for the TEE subsystem
* Adding "tee: refactor params_from_user()", broken out from the patch
"tee: new ioctl to a register tee_shm from a dmabuf file descriptor"
* For "tee: new ioctl to a register tee_shm from a dmabuf file descriptor":
- Update commit message to mention protected memory
- Remove and open code tee_shm_get_parent_shm() in param_from_user_memref()
* In "tee: add tee_shm_alloc_cma_phys_mem" add the hidden config option
TEE_CMA to tell if the CMA functions are available for the TEE subsystem
* For "tee: tee_device_alloc(): copy dma_mask from parent device" and
"optee: pass parent device to tee_device_alloc", added
Reviewed-by: Sumit Garg <sumit.garg(a)kernel.org>
Changes since V5:
* Removing "tee: add restricted memory allocation" and
"tee: add TEE_IOC_RSTMEM_FD_INFO"
* Adding "tee: implement restricted DMA-heap",
"tee: new ioctl to a register tee_shm from a dmabuf file descriptor",
"tee: add tee_shm_alloc_cma_phys_mem()",
"optee: pass parent device to tee_device_alloc()", and
"tee: tee_device_alloc(): copy dma_mask from parent device"
* The two TEE driver OPs "rstmem_alloc()" and "rstmem_free()" are replaced
with a struct tee_rstmem_pool abstraction.
* Replaced the the TEE_IOC_RSTMEM_ALLOC user space API with the DMA-heap API
Changes since V4:
* Adding the patch "tee: add TEE_IOC_RSTMEM_FD_INFO" needed by the
GStreamer demo
* Removing the dummy CPU access and mmap functions from the dma_buf_ops
* Fixing a compile error in "optee: FF-A: dynamic restricted memory allocation"
reported by kernel test robot <lkp(a)intel.com>
Changes since V3:
* Make the use_case and flags field in struct tee_shm u32's instead of
u16's
* Add more description for TEE_IOC_RSTMEM_ALLOC in the header file
* Import namespace DMA_BUF in module tee, reported by lkp(a)intel.com
* Added a note in the commit message for "optee: account for direction
while converting parameters" why it's needed
* Factor out dynamic restricted memory allocation from
"optee: support restricted memory allocation" into two new commits
"optee: FF-A: dynamic restricted memory allocation" and
"optee: smc abi: dynamic restricted memory allocation"
* Guard CMA usage with #ifdef CONFIG_CMA, effectively disabling dynamic
restricted memory allocate if CMA isn't configured
Changes since the V2 RFC:
* Based on v6.12
* Replaced the flags for SVP and Trusted UID memory with a u32 field with
unique id for each use case
* Added dynamic allocation of restricted memory pools
* Added OP-TEE ABI both with and without FF-A for dynamic restricted memory
* Added support for FF-A with FFA_LEND
Changes since the V1 RFC:
* Based on v6.11
* Complete rewrite, replacing the restricted heap with TEE_IOC_RSTMEM_ALLOC
Changes since Olivier's post [2]:
* Based on Yong Wu's post [1] where much of dma-buf handling is done in
the generic restricted heap
* Simplifications and cleanup
* New commit message for "dma-buf: heaps: add Linaro restricted dmabuf heap
support"
* Replaced the word "secure" with "restricted" where applicable
Etienne Carriere (1):
tee: new ioctl to a register tee_shm from a dmabuf file descriptor
Jens Wiklander (8):
optee: sync secure world ABI headers
dma-buf: dma-heap: export declared functions
tee: implement protected DMA-heap
tee: refactor params_from_user()
tee: add tee_shm_alloc_dma_mem()
optee: support protected memory allocation
optee: FF-A: dynamic protected memory allocation
optee: smc abi: dynamic protected memory allocation
drivers/dma-buf/dma-heap.c | 3 +
drivers/tee/Kconfig | 5 +
drivers/tee/Makefile | 1 +
drivers/tee/optee/Kconfig | 5 +
drivers/tee/optee/Makefile | 1 +
drivers/tee/optee/core.c | 7 +
drivers/tee/optee/ffa_abi.c | 146 ++++++++-
drivers/tee/optee/optee_ffa.h | 27 +-
drivers/tee/optee/optee_msg.h | 84 ++++-
drivers/tee/optee/optee_private.h | 15 +-
drivers/tee/optee/optee_smc.h | 37 ++-
drivers/tee/optee/protmem.c | 335 ++++++++++++++++++++
drivers/tee/optee/smc_abi.c | 141 ++++++++-
drivers/tee/tee_core.c | 157 +++++++---
drivers/tee/tee_heap.c | 500 ++++++++++++++++++++++++++++++
drivers/tee/tee_private.h | 14 +
drivers/tee/tee_shm.c | 157 +++++++++-
include/linux/tee_core.h | 59 ++++
include/linux/tee_drv.h | 10 +
include/uapi/linux/tee.h | 31 ++
20 files changed, 1668 insertions(+), 67 deletions(-)
create mode 100644 drivers/tee/optee/protmem.c
create mode 100644 drivers/tee/tee_heap.c
base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f
--
2.43.0
On Wed, Aug 20, 2025 at 04:38:53PM -0700, Amirreza Zarrabi wrote:
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
[..]
> +static void qcom_scm_qtee_free(void *data)
> +{
> + struct platform_device *qtee_dev = data;
> +
> + platform_device_unregister(qtee_dev);
> +}
> +
> +static int qcom_scm_qtee_init(struct qcom_scm *scm)
> +{
> + struct platform_device *qtee_dev;
> + u64 result, response_type;
> + int ret;
> +
> + /*
> + * Check if QTEE supports smcinvoke:
> + * This will fail due to invalid buffers, but first, it checks whether
> + * the call is supported in QTEE syscall handler.
> + * If not supported, -EIO is returned.
> + */
> + ret = qcom_scm_qtee_invoke_smc(0, 0, 0, 0, &result, &response_type);
> + if (ret == -EIO)
> + return -EIO;
> +
> + /* Setup QTEE interface device. */
> + qtee_dev = platform_device_alloc("qcomtee", -1);
> + if (!qtee_dev)
> + return -ENOMEM;
> +
> + qtee_dev->dev.parent = scm->dev;
> +
> + ret = platform_device_add(qtee_dev);
> + if (ret) {
> + platform_device_put(qtee_dev);
> + return ret;
> + }
Wouldn't this work instead of the alloc + parent + add?
qtee_dev = platform_device_alloc_data(scm->dev, "qcomtee", -1, NULL, 0);
if (IS_ERR(qtee_dev))
return PTR_ERR(qtee_dev);
> +
> + return devm_add_action_or_reset(scm->dev, qcom_scm_qtee_free, qtee_dev);
> +}
> +
> /**
> * qcom_scm_is_available() - Checks if SCM is available
> */
> @@ -2326,6 +2450,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> ret = qcom_scm_qseecom_init(scm);
> WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
>
> + /*
> + * Initialize the QTEE object interface.
> + *
> + * This only represents the availability for QTEE object invocation
> + * and callback support. On failure, ignore the result. Any subsystem
> + * depending on it may fail if it tries to access this interface.
> + */
> + ret = qcom_scm_qtee_init(scm);
> + dev_warn_probe(scm->dev, ret, "Failed to initialize qcomtee\n");
A successful boot of db410c (APQ8016) now has the following in the log:
[ 0.161437] qcom_scm firmware:scm: error -EIO: Failed to initialize qcomtee
If the target doesn't implement qtee, I'd expect that you tell me that -
or preferably stay silent.
Looking at the other error conditions, we find -ENOMEM, for which you
should also avoid printing. In fact, I believe all other error paths of
qcom_scm_qtee_init() will have printed an error already (if not, please
move the error print to the place(s) where it's needed).
As you're ignoring the return value, please then also change the return
type of the function to void.
Regards,
Bjorn
> +
> return 0;
> }
Current dma-buf vmap semantics require that the mapped buffer remains
in place until the corresponding vunmap has completed.
For GEM-SHMEM, this used to be guaranteed by a pin operation while creating
an S/G table in import. GEM-SHMEN can now import dma-buf objects without
creating the S/G table, so the pin is missing. Leads to page-fault errors,
such as the one shown below.
[ 102.101726] BUG: unable to handle page fault for address: ffffc90127000000
[...]
[ 102.157102] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
[...]
[ 102.243250] Call Trace:
[ 102.245695] <TASK>
[ 102.2477V95] ? validate_chain+0x24e/0x5e0
[ 102.251805] ? __lock_acquire+0x568/0xae0
[ 102.255807] udl_render_hline+0x165/0x341 [udl]
[ 102.260338] ? __pfx_udl_render_hline+0x10/0x10 [udl]
[ 102.265379] ? local_clock_noinstr+0xb/0x100
[ 102.269642] ? __lock_release.isra.0+0x16c/0x2e0
[ 102.274246] ? mark_held_locks+0x40/0x70
[ 102.278177] udl_primary_plane_helper_atomic_update+0x43e/0x680 [udl]
[ 102.284606] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
[ 102.291551] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
[ 102.297208] ? lockdep_hardirqs_on+0x88/0x130
[ 102.301554] ? _raw_spin_unlock_irq+0x24/0x50
[ 102.305901] ? wait_for_completion_timeout+0x2bb/0x3a0
[ 102.311028] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
[ 102.317714] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 102.323279] drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 102.328664] drm_atomic_helper_commit_tail+0x41/0xb0
[ 102.333622] commit_tail+0x204/0x330
[...]
[ 102.529946] ---[ end trace 0000000000000000 ]---
[ 102.651980] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
In this stack strace, udl (based on GEM-SHMEM) imported and vmap'ed a
dma-buf from amdgpu. Amdgpu relocated the buffer, thereby invalidating the
mapping.
Provide a custom dma-buf vmap method in amdgpu that pins the object before
mapping it's buffer's pages into kernel address space. Do the opposite in
vunmap.
Note that dma-buf vmap differs from GEM vmap in how it handles relocation.
While dma-buf vmap keeps the buffer in place, GEM vmap requires the caller
to keep the buffer in place. Hence, this fix is in amdgpu's dma-buf code
instead of its GEM code.
A discussion of various approaches to solving the problem is available
at [1].
v3:
- try (GTT | VRAM); drop CPU domain (Christian)
v2:
- only use mapable domains (Christian)
- try pinning to domains in preferred order
Signed-off-by: Thomas Zimmermann <tzimmermann(a)suse.de>
Fixes: 660cd44659a0 ("drm/shmem-helper: Import dmabuf without mapping its sg_table")
Reported-by: Thomas Zimmermann <tzimmermann(a)suse.de>
Closes: https://lore.kernel.org/dri-devel/ba1bdfb8-dbf7-4372-bdcb-df7e0511c702@suse…
Cc: Shixiong Ou <oushixiong(a)kylinos.cn>
Cc: Thomas Zimmermann <tzimmermann(a)suse.de>
Cc: Maarten Lankhorst <maarten.lankhorst(a)linux.intel.com>
Cc: Maxime Ripard <mripard(a)kernel.org>
Cc: David Airlie <airlied(a)gmail.com>
Cc: Simona Vetter <simona(a)ffwll.ch>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: "Christian König" <christian.koenig(a)amd.com>
Cc: dri-devel(a)lists.freedesktop.org
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Link: https://lore.kernel.org/dri-devel/9792c6c3-a2b8-4b2b-b5ba-fba19b153e21@suse… # [1]
---
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 34 +++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 5743ebb2f1b7..ce27cb5bb05e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -285,6 +285,36 @@ static int amdgpu_dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
return ret;
}
+static int amdgpu_dma_buf_vmap(struct dma_buf *dma_buf, struct iosys_map *map)
+{
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+ int ret;
+
+ /*
+ * Pin to keep buffer in place while it's vmap'ed. The actual
+ * domain is not that important as long as it's mapable. Using
+ * GTT and VRAM should be compatible with most use cases.
+ */
+ ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_VRAM);
+ if (ret)
+ return ret;
+ ret = drm_gem_dmabuf_vmap(dma_buf, map);
+ if (ret)
+ amdgpu_bo_unpin(bo);
+
+ return ret;
+}
+
+static void amdgpu_dma_buf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map)
+{
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+
+ drm_gem_dmabuf_vunmap(dma_buf, map);
+ amdgpu_bo_unpin(bo);
+}
+
const struct dma_buf_ops amdgpu_dmabuf_ops = {
.attach = amdgpu_dma_buf_attach,
.pin = amdgpu_dma_buf_pin,
@@ -294,8 +324,8 @@ const struct dma_buf_ops amdgpu_dmabuf_ops = {
.release = drm_gem_dmabuf_release,
.begin_cpu_access = amdgpu_dma_buf_begin_cpu_access,
.mmap = drm_gem_dmabuf_mmap,
- .vmap = drm_gem_dmabuf_vmap,
- .vunmap = drm_gem_dmabuf_vunmap,
+ .vmap = amdgpu_dma_buf_vmap,
+ .vunmap = amdgpu_dma_buf_vunmap,
};
/**
--
2.50.1
Hi,
This series is the follow-up of the discussion that John and I had some
time ago here:
https://lore.kernel.org/all/CANDhNCquJn6bH3KxKf65BWiTYLVqSd9892-xtFDHHqqyrr…
The initial problem we were discussing was that I'm currently working on
a platform which has a memory layout with ECC enabled. However, enabling
the ECC has a number of drawbacks on that platform: lower performance,
increased memory usage, etc. So for things like framebuffers, the
trade-off isn't great and thus there's a memory region with ECC disabled
to allocate from for such use cases.
After a suggestion from John, I chose to first start using heap
allocations flags to allow for userspace to ask for a particular ECC
setup. This is then backed by a new heap type that runs from reserved
memory chunks flagged as such, and the existing DT properties to specify
the ECC properties.
After further discussion, it was considered that flags were not the
right solution, and relying on the names of the heaps would be enough to
let userspace know the kind of buffer it deals with.
Thus, even though the uAPI part of it has been dropped in this second
version, we still need a driver to create heaps out of carved-out memory
regions. In addition to the original usecase, a similar driver can be
found in BSPs from most vendors, so I believe it would be a useful
addition to the kernel.
Let me know what you think,
Maxime
Signed-off-by: Maxime Ripard <mripard(a)kernel.org>
---
Changes in v5:
- Rebased on 6.16-rc2
- Switch from property to dedicated binding
- Link to v4: https://lore.kernel.org/r/20250520-dma-buf-ecc-heap-v4-1-bd2e1f1bb42c@kerne…
Changes in v4:
- Rebased on 6.15-rc7
- Map buffers only when map is actually called, not at allocation time
- Deal with restricted-dma-pool and shared-dma-pool
- Reword Kconfig options
- Properly report dma_map_sgtable failures
- Link to v3: https://lore.kernel.org/r/20250407-dma-buf-ecc-heap-v3-0-97cdd36a5f29@kerne…
Changes in v3:
- Reworked global variable patch
- Link to v2: https://lore.kernel.org/r/20250401-dma-buf-ecc-heap-v2-0-043fd006a1af@kerne…
Changes in v2:
- Add vmap/vunmap operations
- Drop ECC flags uapi
- Rebase on top of 6.14
- Link to v1: https://lore.kernel.org/r/20240515-dma-buf-ecc-heap-v1-0-54cbbd049511@kerne…
---
Maxime Ripard (2):
dt-bindings: reserved-memory: Introduce carved-out memory region binding
dma-buf: heaps: Introduce a new heap for reserved memory
.../bindings/reserved-memory/carved-out.yaml | 49 +++
drivers/dma-buf/heaps/Kconfig | 8 +
drivers/dma-buf/heaps/Makefile | 1 +
drivers/dma-buf/heaps/carveout_heap.c | 362 +++++++++++++++++++++
4 files changed, 420 insertions(+)
---
base-commit: d076bed8cb108ba2236d4d49c92303fda4036893
change-id: 20240515-dma-buf-ecc-heap-28a311d2c94e
Best regards,
--
Maxime Ripard <mripard(a)kernel.org>
Current dma-buf vmap semantics require that the mapped buffer remains
in place until the corresponding vunmap has completed.
For GEM-SHMEM, this used to be guaranteed by a pin operation while creating
an S/G table in import. GEM-SHMEN can now import dma-buf objects without
creating the S/G table, so the pin is missing. Leads to page-fault errors,
such as the one shown below.
[ 102.101726] BUG: unable to handle page fault for address: ffffc90127000000
[...]
[ 102.157102] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
[...]
[ 102.243250] Call Trace:
[ 102.245695] <TASK>
[ 102.2477V95] ? validate_chain+0x24e/0x5e0
[ 102.251805] ? __lock_acquire+0x568/0xae0
[ 102.255807] udl_render_hline+0x165/0x341 [udl]
[ 102.260338] ? __pfx_udl_render_hline+0x10/0x10 [udl]
[ 102.265379] ? local_clock_noinstr+0xb/0x100
[ 102.269642] ? __lock_release.isra.0+0x16c/0x2e0
[ 102.274246] ? mark_held_locks+0x40/0x70
[ 102.278177] udl_primary_plane_helper_atomic_update+0x43e/0x680 [udl]
[ 102.284606] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
[ 102.291551] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
[ 102.297208] ? lockdep_hardirqs_on+0x88/0x130
[ 102.301554] ? _raw_spin_unlock_irq+0x24/0x50
[ 102.305901] ? wait_for_completion_timeout+0x2bb/0x3a0
[ 102.311028] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
[ 102.317714] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 102.323279] drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 102.328664] drm_atomic_helper_commit_tail+0x41/0xb0
[ 102.333622] commit_tail+0x204/0x330
[...]
[ 102.529946] ---[ end trace 0000000000000000 ]---
[ 102.651980] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
In this stack strace, udl (based on GEM-SHMEM) imported and vmap'ed a
dma-buf from amdgpu. Amdgpu relocated the buffer, thereby invalidating the
mapping.
Provide a custom dma-buf vmap method in amdgpu that pins the object before
mapping it's buffer's pages into kernel address space. Do the opposite in
vunmap.
Note that dma-buf vmap differs from GEM vmap in how it handles relocation.
While dma-buf vmap keeps the buffer in place, GEM vmap requires the caller
to keep the buffer in place. Hence, this fix is in amdgpu's dma-buf code
instead of its GEM code.
A discussion of various approaches to solving the problem is available
at [1].
v2:
- only use mapable domains (Christian)
- try pinning to domains in prefered order
Signed-off-by: Thomas Zimmermann <tzimmermann(a)suse.de>
Fixes: 660cd44659a0 ("drm/shmem-helper: Import dmabuf without mapping its sg_table")
Reported-by: Thomas Zimmermann <tzimmermann(a)suse.de>
Closes: https://lore.kernel.org/dri-devel/ba1bdfb8-dbf7-4372-bdcb-df7e0511c702@suse…
Cc: Shixiong Ou <oushixiong(a)kylinos.cn>
Cc: Thomas Zimmermann <tzimmermann(a)suse.de>
Cc: Maarten Lankhorst <maarten.lankhorst(a)linux.intel.com>
Cc: Maxime Ripard <mripard(a)kernel.org>
Cc: David Airlie <airlied(a)gmail.com>
Cc: Simona Vetter <simona(a)ffwll.ch>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: "Christian König" <christian.koenig(a)amd.com>
Cc: dri-devel(a)lists.freedesktop.org
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Link: https://lore.kernel.org/dri-devel/9792c6c3-a2b8-4b2b-b5ba-fba19b153e21@suse… # [1]
Signed-off-by: Thomas Zimmermann <tzimmermann(a)suse.de>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 41 ++++++++++++++++++++-
1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 5743ebb2f1b7..471b41bd3e29 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -285,6 +285,43 @@ static int amdgpu_dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
return ret;
}
+static int amdgpu_dma_buf_vmap(struct dma_buf *dma_buf, struct iosys_map *map)
+{
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+ int ret;
+
+ /*
+ * Pin to keep buffer in place while it's vmap'ed. The actual
+ * domain is not that important as long as it's mapable. Using
+ * GTT should be compatible with most use cases. VRAM and CPU
+ * are the fallbacks if the buffer has already been pinned there.
+ */
+ ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
+ if (ret) {
+ ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_VRAM);
+ if (ret) {
+ ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_CPU);
+ if (ret)
+ return ret;
+ }
+ }
+ ret = drm_gem_dmabuf_vmap(dma_buf, map);
+ if (ret)
+ amdgpu_bo_unpin(bo);
+
+ return ret;
+}
+
+static void amdgpu_dma_buf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map)
+{
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+
+ drm_gem_dmabuf_vunmap(dma_buf, map);
+ amdgpu_bo_unpin(bo);
+}
+
const struct dma_buf_ops amdgpu_dmabuf_ops = {
.attach = amdgpu_dma_buf_attach,
.pin = amdgpu_dma_buf_pin,
@@ -294,8 +331,8 @@ const struct dma_buf_ops amdgpu_dmabuf_ops = {
.release = drm_gem_dmabuf_release,
.begin_cpu_access = amdgpu_dma_buf_begin_cpu_access,
.mmap = drm_gem_dmabuf_mmap,
- .vmap = drm_gem_dmabuf_vmap,
- .vunmap = drm_gem_dmabuf_vunmap,
+ .vmap = amdgpu_dma_buf_vmap,
+ .vunmap = amdgpu_dma_buf_vunmap,
};
/**
--
2.50.1