All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
@ 2024-02-05 18:27 ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:27 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

We've established the need for using separate secured memory pools for
SCM and QSEECOM as well as the upcoming scminvoke driver.

It's also become clear that in order to be future-proof, the new
allocator must be an abstraction layer of a higher level as the SHM
Bridge will not be the only memory protection mechanism that we'll see
upstream. Hence the rename to TrustZone Memory rather than SCM Memory
allocator.

Also to that end: the new allocator is its own module now and provides a
Kconfig choice menu for selecting the mode of operation (currently
default and SHM Bridge).

Tested on sm8550 and sa8775p with the Inline Crypto Engine and
remoteproc.

v6 -> v7:
- fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR

v5 -> v6:
Fixed two issues reported by autobuilders:
- add a fix for memory leaks in the qseecom driver as the first patch for
  easier backporting to the v6.6.y branch
- explicitly cast the bus address stored in a variable of type dma_addr_t
  to phys_addr_t expected by the genpool API

v4 -> v5:
- fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
- remove a comment that's no longer useful
- collect tags

v3 -> v4:
- include linux/sizes.h for SZ_X macros
- use dedicated RCU APIs to dereference radix tree slots
- fix kerneldocs
- fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
  that creates the SHM bridge

v2 -> v3:
- restore pool management and use separate pools for different users
- don't use the new allocator in qcom_scm_pas_init_image() as the
  TrustZone will create an SHM bridge for us here
- rewrite the entire series again for most part

v1 -> v2:
- too many changes to list, it's a complete rewrite as explained above

Bartosz Golaszewski (12):
  firmware: qcom: add a dedicated TrustZone buffer allocator
  firmware: qcom: scm: enable the TZ mem allocator
  firmware: qcom: scm: smc: switch to using the SCM allocator
  firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
    allocator
  firmware: qcom: qseecom: convert to using the TZ allocator
  firmware: qcom: scm: add support for SHM bridge operations
  firmware: qcom: tzmem: enable SHM Bridge support
  firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  arm64: defconfig: enable SHM Bridge support for the TZ memory
    allocator

 MAINTAINERS                                   |   8 +
 arch/arm64/configs/defconfig                  |   1 +
 drivers/firmware/qcom/Kconfig                 |  31 ++
 drivers/firmware/qcom/Makefile                |   1 +
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
 drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
 drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
 drivers/firmware/qcom/qcom_scm.h              |   6 +
 drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h            |  13 +
 include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
 include/linux/firmware/qcom/qcom_scm.h        |   6 +
 include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
 13 files changed, 685 insertions(+), 268 deletions(-)
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
 create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h

-- 
2.40.1


^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
@ 2024-02-05 18:27 ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:27 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

We've established the need for using separate secured memory pools for
SCM and QSEECOM as well as the upcoming scminvoke driver.

It's also become clear that in order to be future-proof, the new
allocator must be an abstraction layer of a higher level as the SHM
Bridge will not be the only memory protection mechanism that we'll see
upstream. Hence the rename to TrustZone Memory rather than SCM Memory
allocator.

Also to that end: the new allocator is its own module now and provides a
Kconfig choice menu for selecting the mode of operation (currently
default and SHM Bridge).

Tested on sm8550 and sa8775p with the Inline Crypto Engine and
remoteproc.

v6 -> v7:
- fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR

v5 -> v6:
Fixed two issues reported by autobuilders:
- add a fix for memory leaks in the qseecom driver as the first patch for
  easier backporting to the v6.6.y branch
- explicitly cast the bus address stored in a variable of type dma_addr_t
  to phys_addr_t expected by the genpool API

v4 -> v5:
- fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
- remove a comment that's no longer useful
- collect tags

v3 -> v4:
- include linux/sizes.h for SZ_X macros
- use dedicated RCU APIs to dereference radix tree slots
- fix kerneldocs
- fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
  that creates the SHM bridge

v2 -> v3:
- restore pool management and use separate pools for different users
- don't use the new allocator in qcom_scm_pas_init_image() as the
  TrustZone will create an SHM bridge for us here
- rewrite the entire series again for most part

v1 -> v2:
- too many changes to list, it's a complete rewrite as explained above

Bartosz Golaszewski (12):
  firmware: qcom: add a dedicated TrustZone buffer allocator
  firmware: qcom: scm: enable the TZ mem allocator
  firmware: qcom: scm: smc: switch to using the SCM allocator
  firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
  firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
    allocator
  firmware: qcom: qseecom: convert to using the TZ allocator
  firmware: qcom: scm: add support for SHM bridge operations
  firmware: qcom: tzmem: enable SHM Bridge support
  firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  arm64: defconfig: enable SHM Bridge support for the TZ memory
    allocator

 MAINTAINERS                                   |   8 +
 arch/arm64/configs/defconfig                  |   1 +
 drivers/firmware/qcom/Kconfig                 |  31 ++
 drivers/firmware/qcom/Makefile                |   1 +
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
 drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
 drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
 drivers/firmware/qcom/qcom_scm.h              |   6 +
 drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h            |  13 +
 include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
 include/linux/firmware/qcom/qcom_scm.h        |   6 +
 include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
 13 files changed, 685 insertions(+), 268 deletions(-)
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
 create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h

-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:27   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:27 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

We have several SCM calls that require passing buffers to the TrustZone
on top of the SMC core which allocates memory for calls that require
more than 4 arguments.

Currently every user does their own thing which leads to code
duplication. Many users call dma_alloc_coherent() for every call which
is terribly unperformant (speed- and size-wise).

Provide a set of library functions for creating and managing pool of
memory which is suitable for sharing with the TrustZone, that is:
page-aligned, contiguous and non-cachable as well as provides a way of
mapping of kernel virtual addresses to physical space.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 MAINTAINERS                              |   8 +
 drivers/firmware/qcom/Kconfig            |  20 ++
 drivers/firmware/qcom/Makefile           |   1 +
 drivers/firmware/qcom/qcom_tzmem.c       | 302 +++++++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h       |  13 +
 include/linux/firmware/qcom/qcom_tzmem.h |  28 +++
 6 files changed, 372 insertions(+)
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
 create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ff059e870a44..0c82625de50d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18231,6 +18231,14 @@ L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 F:	drivers/firmware/qcom/qcom_qseecom.c
 
+QUALCOMM TRUST ZONE MEMORY ALLOCATOR
+M:	Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+L:	linux-arm-msm@vger.kernel.org
+S:	Maintained
+F:	drivers/firmware/qcom/qcom_tzmem.c
+F:	drivers/firmware/qcom/qcom_tzmem.h
+F:	include/linux/firmware/qcom/qcom_tzmem.h
+
 QUALCOMM QSEECOM UEFISECAPP DRIVER
 M:	Maximilian Luz <luzmaximilian@gmail.com>
 L:	linux-arm-msm@vger.kernel.org
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3f05d9854ddf..f18686edf415 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -9,6 +9,26 @@ menu "Qualcomm firmware drivers"
 config QCOM_SCM
 	tristate
 
+config QCOM_TZMEM
+	tristate
+	select GENERIC_ALLOCATOR
+
+choice
+	prompt "TrustZone interface memory allocator mode"
+	default QCOM_TZMEM_MODE_DEFAULT
+	help
+	  Selects the mode of the memory allocator providing memory buffers of
+	  suitable format for sharing with the TrustZone. If in doubt, select
+	  'Default'.
+
+config QCOM_TZMEM_MODE_DEFAULT
+	bool "Default"
+	help
+	  Use the default allocator mode. The memory is page-aligned, non-cachable
+	  and contiguous.
+
+endchoice
+
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
 	bool "Qualcomm download mode enabled by default"
 	depends on QCOM_SCM
diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
index c9f12ee8224a..0be40a1abc13 100644
--- a/drivers/firmware/qcom/Makefile
+++ b/drivers/firmware/qcom/Makefile
@@ -5,5 +5,6 @@
 
 obj-$(CONFIG_QCOM_SCM)		+= qcom-scm.o
 qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
+obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
 obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
 obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
new file mode 100644
index 000000000000..44a062f2abd4
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Memory allocator for buffers shared with the TrustZone.
+ *
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#include <linux/bug.h>
+#include <linux/cleanup.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/genalloc.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include <linux/radix-tree.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include "qcom_tzmem.h"
+
+struct qcom_tzmem_pool {
+	void *vbase;
+	dma_addr_t pbase;
+	size_t size;
+	struct gen_pool *pool;
+	void *priv;
+};
+
+struct qcom_tzmem_chunk {
+	phys_addr_t paddr;
+	size_t size;
+	struct qcom_tzmem_pool *owner;
+};
+
+static struct device *qcom_tzmem_dev;
+static RADIX_TREE(qcom_tzmem_chunks, GFP_ATOMIC);
+static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);
+
+#if IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_DEFAULT)
+
+static int qcom_tzmem_init(void)
+{
+	return 0;
+}
+
+static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
+{
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
+{
+
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
+
+/**
+ * qcom_tzmem_pool_new() - Create a new TZ memory pool.
+ * @size: Size of the new pool in bytes.
+ *
+ * Create a new pool of memory suitable for sharing with the TrustZone.
+ *
+ * Must not be used in atomic context.
+ *
+ * Returns:
+ * New memory pool address or ERR_PTR() on error.
+ */
+struct qcom_tzmem_pool *qcom_tzmem_pool_new(size_t size)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret = -ENOMEM;
+
+	if (!size)
+		return ERR_PTR(-EINVAL);
+
+	size = PAGE_ALIGN(size);
+
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->size = size;
+
+	pool->vbase = dma_alloc_coherent(qcom_tzmem_dev, size, &pool->pbase,
+					 GFP_KERNEL);
+	if (!pool->vbase)
+		goto err_kfree_pool;
+
+	pool->pool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool)
+		goto err_dma_free;
+
+	gen_pool_set_algo(pool->pool, gen_pool_best_fit, NULL);
+
+	ret = gen_pool_add_virt(pool->pool, (unsigned long)pool->vbase,
+				(phys_addr_t)pool->pbase, size, -1);
+	if (ret)
+		goto err_destroy_genpool;
+
+	ret = qcom_tzmem_init_pool(pool);
+	if (ret)
+		goto err_destroy_genpool;
+
+	return pool;
+
+err_destroy_genpool:
+	gen_pool_destroy(pool->pool);
+err_dma_free:
+	dma_free_coherent(qcom_tzmem_dev, size, pool->vbase, pool->pbase);
+err_kfree_pool:
+	kfree(pool);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_new);
+
+/**
+ * qcom_tzmem_pool_free() - Destroy a TZ memory pool and free all resources.
+ * @pool: Memory pool to free.
+ *
+ * Must not be called if any of the allocated chunks has not been freed.
+ * Must not be used in atomic context.
+ */
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool)
+{
+	struct qcom_tzmem_chunk *chunk;
+	struct radix_tree_iter iter;
+	bool non_empty = false;
+	void __rcu **slot;
+
+	if (!pool)
+		return;
+
+	qcom_tzmem_cleanup_pool(pool);
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		radix_tree_for_each_slot(slot, &qcom_tzmem_chunks, &iter, 0) {
+			chunk = radix_tree_deref_slot_protected(slot,
+						&qcom_tzmem_chunks_lock);
+
+			if (chunk->owner == pool)
+				non_empty = true;
+		}
+	}
+
+	WARN(non_empty, "Freeing TZ memory pool with memory still allocated");
+
+	gen_pool_destroy(pool->pool);
+	dma_free_coherent(qcom_tzmem_dev, pool->size, pool->vbase, pool->pbase);
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_free);
+
+static void devm_qcom_tzmem_pool_free(void *data)
+{
+	struct qcom_tzmem_pool *pool = data;
+
+	qcom_tzmem_pool_free(pool);
+}
+
+/**
+ * devm_qcom_tzmem_pool_new() - Managed variant of qcom_tzmem_pool_new().
+ * @dev: Device managing this resource.
+ * @size: Size of the pool in bytes.
+ *
+ * Must not be used in atomic context.
+ *
+ * Returns:
+ * Address of the managed pool or ERR_PTR() on failure.
+ */
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev, size_t size)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret;
+
+	pool = qcom_tzmem_pool_new(size);
+	if (IS_ERR(pool))
+		return pool;
+
+	ret = devm_add_action_or_reset(dev, devm_qcom_tzmem_pool_free, pool);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return pool;
+}
+
+/**
+ * qcom_tzmem_alloc() - Allocate a memory chunk suitable for sharing with TZ.
+ * @pool: TZ memory pool from which to allocate memory.
+ * @size: Number of bytes to allocate.
+ * @gfp: GFP flags.
+ *
+ * Can be used in any context.
+ *
+ * Returns:
+ * Address of the allocated buffer or NULL if no more memory can be allocated.
+ * The buffer must be released using qcom_tzmem_free().
+ */
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp)
+{
+	struct qcom_tzmem_chunk *chunk;
+	unsigned long vaddr;
+	int ret;
+
+	if (!size)
+		return NULL;
+
+	size = PAGE_ALIGN(size);
+
+	chunk = kzalloc(sizeof(*chunk), gfp);
+	if (!chunk)
+		return NULL;
+
+	vaddr = gen_pool_alloc(pool->pool, size);
+	if (!vaddr) {
+		kfree(chunk);
+		return NULL;
+	}
+
+	chunk->paddr = gen_pool_virt_to_phys(pool->pool, vaddr);
+	chunk->size = size;
+	chunk->owner = pool;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		ret = radix_tree_insert(&qcom_tzmem_chunks, vaddr, chunk);
+		if (ret) {
+			gen_pool_free(pool->pool, vaddr, size);
+			kfree(chunk);
+			return NULL;
+		}
+	}
+
+	return (void *)vaddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_alloc);
+
+/**
+ * qcom_tzmem_free() - Release a buffer allocated from a TZ memory pool.
+ * @vaddr: Virtual address of the buffer.
+ *
+ * Can be used in any context.
+ */
+void qcom_tzmem_free(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock)
+		chunk = radix_tree_delete_item(&qcom_tzmem_chunks,
+					       (unsigned long)vaddr, NULL);
+
+	if (!chunk) {
+		WARN(1, "Virtual address %p not owned by TZ memory allocator",
+		     vaddr);
+		return;
+	}
+
+	gen_pool_free(chunk->owner->pool, (unsigned long)vaddr, chunk->size);
+	kfree(chunk);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_free);
+
+/**
+ * qcom_tzmem_to_phys() - Map the virtual address of a TZ buffer to physical.
+ * @vaddr: Virtual address of the buffer allocated from a TZ memory pool.
+ *
+ * Can be used in any context. The address must have been returned by a call
+ * to qcom_tzmem_alloc().
+ *
+ * Returns:
+ * Physical address of the buffer.
+ */
+phys_addr_t qcom_tzmem_to_phys(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	guard(spinlock_irqsave)(&qcom_tzmem_chunks_lock);
+
+	chunk = radix_tree_lookup(&qcom_tzmem_chunks, (unsigned long)vaddr);
+	if (!chunk)
+		return 0;
+
+	return chunk->paddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_to_phys);
+
+int qcom_tzmem_enable(struct device *dev)
+{
+	if (qcom_tzmem_dev)
+		return -EBUSY;
+
+	qcom_tzmem_dev = dev;
+
+	return qcom_tzmem_init();
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
+
+MODULE_DESCRIPTION("TrustZone memory allocator for Qualcomm firmware drivers");
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/qcom/qcom_tzmem.h b/drivers/firmware/qcom/qcom_tzmem.h
new file mode 100644
index 000000000000..f82f5dc5b7b1
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_PRIV_H
+#define __QCOM_TZMEM_PRIV_H
+
+struct device;
+
+int qcom_tzmem_enable(struct device *dev);
+
+#endif /* __QCOM_TZMEM_PRIV_H */
diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h
new file mode 100644
index 000000000000..8e7fddab8cb4
--- /dev/null
+++ b/include/linux/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_H
+#define __QCOM_TZMEM_H
+
+#include <linux/cleanup.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+
+struct device;
+struct qcom_tzmem_pool;
+
+struct qcom_tzmem_pool *qcom_tzmem_pool_new(size_t size);
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool);
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev, size_t size);
+
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp);
+void qcom_tzmem_free(void *ptr);
+
+DEFINE_FREE(qcom_tzmem, void *, if (_T) qcom_tzmem_free(_T));
+
+phys_addr_t qcom_tzmem_to_phys(void *ptr);
+
+#endif /* __QCOM_TZMEM */
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
@ 2024-02-05 18:27   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:27 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

We have several SCM calls that require passing buffers to the TrustZone
on top of the SMC core which allocates memory for calls that require
more than 4 arguments.

Currently every user does their own thing which leads to code
duplication. Many users call dma_alloc_coherent() for every call which
is terribly unperformant (speed- and size-wise).

Provide a set of library functions for creating and managing pool of
memory which is suitable for sharing with the TrustZone, that is:
page-aligned, contiguous and non-cachable as well as provides a way of
mapping of kernel virtual addresses to physical space.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 MAINTAINERS                              |   8 +
 drivers/firmware/qcom/Kconfig            |  20 ++
 drivers/firmware/qcom/Makefile           |   1 +
 drivers/firmware/qcom/qcom_tzmem.c       | 302 +++++++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h       |  13 +
 include/linux/firmware/qcom/qcom_tzmem.h |  28 +++
 6 files changed, 372 insertions(+)
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
 create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
 create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ff059e870a44..0c82625de50d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18231,6 +18231,14 @@ L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 F:	drivers/firmware/qcom/qcom_qseecom.c
 
+QUALCOMM TRUST ZONE MEMORY ALLOCATOR
+M:	Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+L:	linux-arm-msm@vger.kernel.org
+S:	Maintained
+F:	drivers/firmware/qcom/qcom_tzmem.c
+F:	drivers/firmware/qcom/qcom_tzmem.h
+F:	include/linux/firmware/qcom/qcom_tzmem.h
+
 QUALCOMM QSEECOM UEFISECAPP DRIVER
 M:	Maximilian Luz <luzmaximilian@gmail.com>
 L:	linux-arm-msm@vger.kernel.org
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3f05d9854ddf..f18686edf415 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -9,6 +9,26 @@ menu "Qualcomm firmware drivers"
 config QCOM_SCM
 	tristate
 
+config QCOM_TZMEM
+	tristate
+	select GENERIC_ALLOCATOR
+
+choice
+	prompt "TrustZone interface memory allocator mode"
+	default QCOM_TZMEM_MODE_DEFAULT
+	help
+	  Selects the mode of the memory allocator providing memory buffers of
+	  suitable format for sharing with the TrustZone. If in doubt, select
+	  'Default'.
+
+config QCOM_TZMEM_MODE_DEFAULT
+	bool "Default"
+	help
+	  Use the default allocator mode. The memory is page-aligned, non-cachable
+	  and contiguous.
+
+endchoice
+
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
 	bool "Qualcomm download mode enabled by default"
 	depends on QCOM_SCM
diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
index c9f12ee8224a..0be40a1abc13 100644
--- a/drivers/firmware/qcom/Makefile
+++ b/drivers/firmware/qcom/Makefile
@@ -5,5 +5,6 @@
 
 obj-$(CONFIG_QCOM_SCM)		+= qcom-scm.o
 qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
+obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
 obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
 obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
new file mode 100644
index 000000000000..44a062f2abd4
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Memory allocator for buffers shared with the TrustZone.
+ *
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#include <linux/bug.h>
+#include <linux/cleanup.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/genalloc.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include <linux/radix-tree.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include "qcom_tzmem.h"
+
+struct qcom_tzmem_pool {
+	void *vbase;
+	dma_addr_t pbase;
+	size_t size;
+	struct gen_pool *pool;
+	void *priv;
+};
+
+struct qcom_tzmem_chunk {
+	phys_addr_t paddr;
+	size_t size;
+	struct qcom_tzmem_pool *owner;
+};
+
+static struct device *qcom_tzmem_dev;
+static RADIX_TREE(qcom_tzmem_chunks, GFP_ATOMIC);
+static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);
+
+#if IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_DEFAULT)
+
+static int qcom_tzmem_init(void)
+{
+	return 0;
+}
+
+static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
+{
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
+{
+
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
+
+/**
+ * qcom_tzmem_pool_new() - Create a new TZ memory pool.
+ * @size: Size of the new pool in bytes.
+ *
+ * Create a new pool of memory suitable for sharing with the TrustZone.
+ *
+ * Must not be used in atomic context.
+ *
+ * Returns:
+ * New memory pool address or ERR_PTR() on error.
+ */
+struct qcom_tzmem_pool *qcom_tzmem_pool_new(size_t size)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret = -ENOMEM;
+
+	if (!size)
+		return ERR_PTR(-EINVAL);
+
+	size = PAGE_ALIGN(size);
+
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->size = size;
+
+	pool->vbase = dma_alloc_coherent(qcom_tzmem_dev, size, &pool->pbase,
+					 GFP_KERNEL);
+	if (!pool->vbase)
+		goto err_kfree_pool;
+
+	pool->pool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool)
+		goto err_dma_free;
+
+	gen_pool_set_algo(pool->pool, gen_pool_best_fit, NULL);
+
+	ret = gen_pool_add_virt(pool->pool, (unsigned long)pool->vbase,
+				(phys_addr_t)pool->pbase, size, -1);
+	if (ret)
+		goto err_destroy_genpool;
+
+	ret = qcom_tzmem_init_pool(pool);
+	if (ret)
+		goto err_destroy_genpool;
+
+	return pool;
+
+err_destroy_genpool:
+	gen_pool_destroy(pool->pool);
+err_dma_free:
+	dma_free_coherent(qcom_tzmem_dev, size, pool->vbase, pool->pbase);
+err_kfree_pool:
+	kfree(pool);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_new);
+
+/**
+ * qcom_tzmem_pool_free() - Destroy a TZ memory pool and free all resources.
+ * @pool: Memory pool to free.
+ *
+ * Must not be called if any of the allocated chunks has not been freed.
+ * Must not be used in atomic context.
+ */
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool)
+{
+	struct qcom_tzmem_chunk *chunk;
+	struct radix_tree_iter iter;
+	bool non_empty = false;
+	void __rcu **slot;
+
+	if (!pool)
+		return;
+
+	qcom_tzmem_cleanup_pool(pool);
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		radix_tree_for_each_slot(slot, &qcom_tzmem_chunks, &iter, 0) {
+			chunk = radix_tree_deref_slot_protected(slot,
+						&qcom_tzmem_chunks_lock);
+
+			if (chunk->owner == pool)
+				non_empty = true;
+		}
+	}
+
+	WARN(non_empty, "Freeing TZ memory pool with memory still allocated");
+
+	gen_pool_destroy(pool->pool);
+	dma_free_coherent(qcom_tzmem_dev, pool->size, pool->vbase, pool->pbase);
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_free);
+
+static void devm_qcom_tzmem_pool_free(void *data)
+{
+	struct qcom_tzmem_pool *pool = data;
+
+	qcom_tzmem_pool_free(pool);
+}
+
+/**
+ * devm_qcom_tzmem_pool_new() - Managed variant of qcom_tzmem_pool_new().
+ * @dev: Device managing this resource.
+ * @size: Size of the pool in bytes.
+ *
+ * Must not be used in atomic context.
+ *
+ * Returns:
+ * Address of the managed pool or ERR_PTR() on failure.
+ */
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev, size_t size)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret;
+
+	pool = qcom_tzmem_pool_new(size);
+	if (IS_ERR(pool))
+		return pool;
+
+	ret = devm_add_action_or_reset(dev, devm_qcom_tzmem_pool_free, pool);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return pool;
+}
+
+/**
+ * qcom_tzmem_alloc() - Allocate a memory chunk suitable for sharing with TZ.
+ * @pool: TZ memory pool from which to allocate memory.
+ * @size: Number of bytes to allocate.
+ * @gfp: GFP flags.
+ *
+ * Can be used in any context.
+ *
+ * Returns:
+ * Address of the allocated buffer or NULL if no more memory can be allocated.
+ * The buffer must be released using qcom_tzmem_free().
+ */
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp)
+{
+	struct qcom_tzmem_chunk *chunk;
+	unsigned long vaddr;
+	int ret;
+
+	if (!size)
+		return NULL;
+
+	size = PAGE_ALIGN(size);
+
+	chunk = kzalloc(sizeof(*chunk), gfp);
+	if (!chunk)
+		return NULL;
+
+	vaddr = gen_pool_alloc(pool->pool, size);
+	if (!vaddr) {
+		kfree(chunk);
+		return NULL;
+	}
+
+	chunk->paddr = gen_pool_virt_to_phys(pool->pool, vaddr);
+	chunk->size = size;
+	chunk->owner = pool;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		ret = radix_tree_insert(&qcom_tzmem_chunks, vaddr, chunk);
+		if (ret) {
+			gen_pool_free(pool->pool, vaddr, size);
+			kfree(chunk);
+			return NULL;
+		}
+	}
+
+	return (void *)vaddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_alloc);
+
+/**
+ * qcom_tzmem_free() - Release a buffer allocated from a TZ memory pool.
+ * @vaddr: Virtual address of the buffer.
+ *
+ * Can be used in any context.
+ */
+void qcom_tzmem_free(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock)
+		chunk = radix_tree_delete_item(&qcom_tzmem_chunks,
+					       (unsigned long)vaddr, NULL);
+
+	if (!chunk) {
+		WARN(1, "Virtual address %p not owned by TZ memory allocator",
+		     vaddr);
+		return;
+	}
+
+	gen_pool_free(chunk->owner->pool, (unsigned long)vaddr, chunk->size);
+	kfree(chunk);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_free);
+
+/**
+ * qcom_tzmem_to_phys() - Map the virtual address of a TZ buffer to physical.
+ * @vaddr: Virtual address of the buffer allocated from a TZ memory pool.
+ *
+ * Can be used in any context. The address must have been returned by a call
+ * to qcom_tzmem_alloc().
+ *
+ * Returns:
+ * Physical address of the buffer.
+ */
+phys_addr_t qcom_tzmem_to_phys(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	guard(spinlock_irqsave)(&qcom_tzmem_chunks_lock);
+
+	chunk = radix_tree_lookup(&qcom_tzmem_chunks, (unsigned long)vaddr);
+	if (!chunk)
+		return 0;
+
+	return chunk->paddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_to_phys);
+
+int qcom_tzmem_enable(struct device *dev)
+{
+	if (qcom_tzmem_dev)
+		return -EBUSY;
+
+	qcom_tzmem_dev = dev;
+
+	return qcom_tzmem_init();
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
+
+MODULE_DESCRIPTION("TrustZone memory allocator for Qualcomm firmware drivers");
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/qcom/qcom_tzmem.h b/drivers/firmware/qcom/qcom_tzmem.h
new file mode 100644
index 000000000000..f82f5dc5b7b1
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_PRIV_H
+#define __QCOM_TZMEM_PRIV_H
+
+struct device;
+
+int qcom_tzmem_enable(struct device *dev);
+
+#endif /* __QCOM_TZMEM_PRIV_H */
diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h
new file mode 100644
index 000000000000..8e7fddab8cb4
--- /dev/null
+++ b/include/linux/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_H
+#define __QCOM_TZMEM_H
+
+#include <linux/cleanup.h>
+#include <linux/gfp.h>
+#include <linux/types.h>
+
+struct device;
+struct qcom_tzmem_pool;
+
+struct qcom_tzmem_pool *qcom_tzmem_pool_new(size_t size);
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool);
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev, size_t size);
+
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp);
+void qcom_tzmem_free(void *ptr);
+
+DEFINE_FREE(qcom_tzmem, void *, if (_T) qcom_tzmem_free(_T));
+
+phys_addr_t qcom_tzmem_to_phys(void *ptr);
+
+#endif /* __QCOM_TZMEM */
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Select the TrustZone memory allocator in Kconfig and create a pool of
memory shareable with the TrustZone when probing the SCM driver.

This will allow a gradual conversion of all relevant SCM calls to using
the dedicated allocator.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/Kconfig    |  1 +
 drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index f18686edf415..d24d83223867 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -7,6 +7,7 @@
 menu "Qualcomm firmware drivers"
 
 config QCOM_SCM
+	select QCOM_TZMEM
 	tristate
 
 config QCOM_TZMEM
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 520de9b5633a..0d4c028be0c1 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -8,8 +8,10 @@
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/export.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/init.h>
 #include <linux/interconnect.h>
 #include <linux/interrupt.h>
@@ -20,9 +22,11 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
+#include <linux/sizes.h>
 #include <linux/types.h>
 
 #include "qcom_scm.h"
+#include "qcom_tzmem.h"
 
 static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
 module_param(download_mode, bool, 0);
@@ -41,6 +45,8 @@ struct qcom_scm {
 	int scm_vote_count;
 
 	u64 dload_mode_addr;
+
+	struct qcom_tzmem_pool *mempool;
 };
 
 struct qcom_scm_current_perm_info {
@@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
 	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
 		qcom_scm_disable_sdi();
 
+	ret = qcom_tzmem_enable(__scm->dev);
+	if (ret)
+		return dev_err_probe(__scm->dev, ret,
+				     "Failed to enable the TrustZone memory allocator\n");
+
+	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
+	if (IS_ERR(__scm->mempool))
+		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
+				     "Failed to create the SCM memory pool\n");
+
 	/*
 	 * Initialize the QSEECOM interface.
 	 *
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Select the TrustZone memory allocator in Kconfig and create a pool of
memory shareable with the TrustZone when probing the SCM driver.

This will allow a gradual conversion of all relevant SCM calls to using
the dedicated allocator.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/Kconfig    |  1 +
 drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index f18686edf415..d24d83223867 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -7,6 +7,7 @@
 menu "Qualcomm firmware drivers"
 
 config QCOM_SCM
+	select QCOM_TZMEM
 	tristate
 
 config QCOM_TZMEM
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 520de9b5633a..0d4c028be0c1 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -8,8 +8,10 @@
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/export.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/init.h>
 #include <linux/interconnect.h>
 #include <linux/interrupt.h>
@@ -20,9 +22,11 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
+#include <linux/sizes.h>
 #include <linux/types.h>
 
 #include "qcom_scm.h"
+#include "qcom_tzmem.h"
 
 static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
 module_param(download_mode, bool, 0);
@@ -41,6 +45,8 @@ struct qcom_scm {
 	int scm_vote_count;
 
 	u64 dload_mode_addr;
+
+	struct qcom_tzmem_pool *mempool;
 };
 
 struct qcom_scm_current_perm_info {
@@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
 	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
 		qcom_scm_disable_sdi();
 
+	ret = qcom_tzmem_enable(__scm->dev);
+	if (ret)
+		return dev_err_probe(__scm->dev, ret,
+				     "Failed to enable the TrustZone memory allocator\n");
+
+	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
+	if (IS_ERR(__scm->mempool))
+		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
+				     "Failed to create the SCM memory pool\n");
+
 	/*
 	 * Initialize the QSEECOM interface.
 	 *
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 03/12] firmware: qcom: scm: smc: switch to using the SCM allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

We need to allocate, map and pass a buffer to the trustzone if we have
more than 4 arguments for a given SCM calls. Let's use the new TrustZone
allocator for that memory and shrink the code in process.

As this code lives in a different compilation unit than the rest of the
SCM code, we need to provide a helper in the form of
qcom_scm_get_tzmem_pool() that allows the SMC low-level routines to
access the SCM memory pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm-smc.c | 30 ++++++++--------------------
 drivers/firmware/qcom/qcom_scm.c     |  5 +++++
 drivers/firmware/qcom/qcom_scm.h     |  3 +++
 3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 16cf88acfa8e..dca5f3f1883b 100644
--- a/drivers/firmware/qcom/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
  */
 
+#include <linux/cleanup.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
@@ -9,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/arm-smccc.h>
 #include <linux/dma-mapping.h>
 
@@ -150,11 +152,10 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 		   enum qcom_scm_convention qcom_convention,
 		   struct qcom_scm_res *res, bool atomic)
 {
+	struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
 	int arglen = desc->arginfo & 0xf;
 	int i, ret;
-	dma_addr_t args_phys = 0;
-	void *args_virt = NULL;
-	size_t alloc_len;
+	void *args_virt __free(qcom_tzmem) = NULL;
 	gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
 	u32 qcom_smccc_convention = (qcom_convention == SMC_CONVENTION_ARM_32) ?
@@ -172,9 +173,9 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 		smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
 
 	if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
-		alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64);
-		args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
-
+		args_virt = qcom_tzmem_alloc(mempool,
+					     SCM_SMC_N_EXT_ARGS * sizeof(u64),
+					     flag);
 		if (!args_virt)
 			return -ENOMEM;
 
@@ -192,25 +193,10 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 						      SCM_SMC_FIRST_EXT_IDX]);
 		}
 
-		args_phys = dma_map_single(dev, args_virt, alloc_len,
-					   DMA_TO_DEVICE);
-
-		if (dma_mapping_error(dev, args_phys)) {
-			kfree(args_virt);
-			return -ENOMEM;
-		}
-
-		smc.args[SCM_SMC_LAST_REG_IDX] = args_phys;
+		smc.args[SCM_SMC_LAST_REG_IDX] = qcom_tzmem_to_phys(args_virt);
 	}
 
-	/* ret error check follows after args_virt cleanup*/
 	ret = __scm_smc_do(dev, &smc, &smc_res, atomic);
-
-	if (args_virt) {
-		dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
-		kfree(args_virt);
-	}
-
 	if (ret)
 		return ret;
 
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 0d4c028be0c1..71e98b666391 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -201,6 +201,11 @@ static void qcom_scm_bw_disable(void)
 enum qcom_scm_convention qcom_scm_convention = SMC_CONVENTION_UNKNOWN;
 static DEFINE_SPINLOCK(scm_query_lock);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)
+{
+	return __scm->mempool;
+}
+
 static enum qcom_scm_convention __get_convention(void)
 {
 	unsigned long flags;
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index 4532907e8489..aa7d06939f8e 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -5,6 +5,7 @@
 #define __QCOM_SCM_INT_H
 
 struct device;
+struct qcom_tzmem_pool;
 
 enum qcom_scm_convention {
 	SMC_CONVENTION_UNKNOWN,
@@ -78,6 +79,8 @@ int scm_legacy_call_atomic(struct device *dev, const struct qcom_scm_desc *desc,
 int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
 		    struct qcom_scm_res *res);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
+
 #define QCOM_SCM_SVC_BOOT		0x01
 #define QCOM_SCM_BOOT_SET_ADDR		0x01
 #define QCOM_SCM_BOOT_TERMINATE_PC	0x02
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 03/12] firmware: qcom: scm: smc: switch to using the SCM allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

We need to allocate, map and pass a buffer to the trustzone if we have
more than 4 arguments for a given SCM calls. Let's use the new TrustZone
allocator for that memory and shrink the code in process.

As this code lives in a different compilation unit than the rest of the
SCM code, we need to provide a helper in the form of
qcom_scm_get_tzmem_pool() that allows the SMC low-level routines to
access the SCM memory pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm-smc.c | 30 ++++++++--------------------
 drivers/firmware/qcom/qcom_scm.c     |  5 +++++
 drivers/firmware/qcom/qcom_scm.h     |  3 +++
 3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm-smc.c b/drivers/firmware/qcom/qcom_scm-smc.c
index 16cf88acfa8e..dca5f3f1883b 100644
--- a/drivers/firmware/qcom/qcom_scm-smc.c
+++ b/drivers/firmware/qcom/qcom_scm-smc.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
  */
 
+#include <linux/cleanup.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
@@ -9,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/arm-smccc.h>
 #include <linux/dma-mapping.h>
 
@@ -150,11 +152,10 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 		   enum qcom_scm_convention qcom_convention,
 		   struct qcom_scm_res *res, bool atomic)
 {
+	struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
 	int arglen = desc->arginfo & 0xf;
 	int i, ret;
-	dma_addr_t args_phys = 0;
-	void *args_virt = NULL;
-	size_t alloc_len;
+	void *args_virt __free(qcom_tzmem) = NULL;
 	gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
 	u32 qcom_smccc_convention = (qcom_convention == SMC_CONVENTION_ARM_32) ?
@@ -172,9 +173,9 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 		smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
 
 	if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
-		alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64);
-		args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
-
+		args_virt = qcom_tzmem_alloc(mempool,
+					     SCM_SMC_N_EXT_ARGS * sizeof(u64),
+					     flag);
 		if (!args_virt)
 			return -ENOMEM;
 
@@ -192,25 +193,10 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
 						      SCM_SMC_FIRST_EXT_IDX]);
 		}
 
-		args_phys = dma_map_single(dev, args_virt, alloc_len,
-					   DMA_TO_DEVICE);
-
-		if (dma_mapping_error(dev, args_phys)) {
-			kfree(args_virt);
-			return -ENOMEM;
-		}
-
-		smc.args[SCM_SMC_LAST_REG_IDX] = args_phys;
+		smc.args[SCM_SMC_LAST_REG_IDX] = qcom_tzmem_to_phys(args_virt);
 	}
 
-	/* ret error check follows after args_virt cleanup*/
 	ret = __scm_smc_do(dev, &smc, &smc_res, atomic);
-
-	if (args_virt) {
-		dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
-		kfree(args_virt);
-	}
-
 	if (ret)
 		return ret;
 
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 0d4c028be0c1..71e98b666391 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -201,6 +201,11 @@ static void qcom_scm_bw_disable(void)
 enum qcom_scm_convention qcom_scm_convention = SMC_CONVENTION_UNKNOWN;
 static DEFINE_SPINLOCK(scm_query_lock);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)
+{
+	return __scm->mempool;
+}
+
 static enum qcom_scm_convention __get_convention(void)
 {
 	unsigned long flags;
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index 4532907e8489..aa7d06939f8e 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -5,6 +5,7 @@
 #define __QCOM_SCM_INT_H
 
 struct device;
+struct qcom_tzmem_pool;
 
 enum qcom_scm_convention {
 	SMC_CONVENTION_UNKNOWN,
@@ -78,6 +79,8 @@ int scm_legacy_call_atomic(struct device *dev, const struct qcom_scm_desc *desc,
 int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
 		    struct qcom_scm_res *res);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
+
 #define QCOM_SCM_SVC_BOOT		0x01
 #define QCOM_SCM_BOOT_SET_ADDR		0x01
 #define QCOM_SCM_BOOT_TERMINATE_PC	0x02
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 04/12] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 71e98b666391..754f6056b99f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
@@ -998,14 +999,13 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 	struct qcom_scm_mem_map_info *mem_to_map;
 	phys_addr_t mem_to_map_phys;
 	phys_addr_t dest_phys;
-	dma_addr_t ptr_phys;
+	phys_addr_t ptr_phys;
 	size_t mem_to_map_sz;
 	size_t dest_sz;
 	size_t src_sz;
 	size_t ptr_sz;
 	int next_vm;
 	__le32 *src;
-	void *ptr;
 	int ret, i, b;
 	u64 srcvm_bits = *srcvm;
 
@@ -1015,10 +1015,13 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 	ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) +
 			ALIGN(dest_sz, SZ_64);
 
-	ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL);
+	void *ptr __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							ptr_sz, GFP_KERNEL);
 	if (!ptr)
 		return -ENOMEM;
 
+	ptr_phys = qcom_tzmem_to_phys(ptr);
+
 	/* Fill source vmid detail */
 	src = ptr;
 	i = 0;
@@ -1047,7 +1050,6 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 
 	ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz,
 				    ptr_phys, src_sz, dest_phys, dest_sz);
-	dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_phys);
 	if (ret) {
 		dev_err(__scm->dev,
 			"Assign memory protection call failed %d\n", ret);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 04/12] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 71e98b666391..754f6056b99f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
@@ -998,14 +999,13 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 	struct qcom_scm_mem_map_info *mem_to_map;
 	phys_addr_t mem_to_map_phys;
 	phys_addr_t dest_phys;
-	dma_addr_t ptr_phys;
+	phys_addr_t ptr_phys;
 	size_t mem_to_map_sz;
 	size_t dest_sz;
 	size_t src_sz;
 	size_t ptr_sz;
 	int next_vm;
 	__le32 *src;
-	void *ptr;
 	int ret, i, b;
 	u64 srcvm_bits = *srcvm;
 
@@ -1015,10 +1015,13 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 	ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) +
 			ALIGN(dest_sz, SZ_64);
 
-	ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL);
+	void *ptr __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							ptr_sz, GFP_KERNEL);
 	if (!ptr)
 		return -ENOMEM;
 
+	ptr_phys = qcom_tzmem_to_phys(ptr);
+
 	/* Fill source vmid detail */
 	src = ptr;
 	i = 0;
@@ -1047,7 +1050,6 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 
 	ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz,
 				    ptr_phys, src_sz, dest_phys, dest_sz);
-	dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_phys);
 	if (ret) {
 		dev_err(__scm->dev,
 			"Assign memory protection call failed %d\n", ret);
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 05/12] firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 754f6056b99f..31071a714cf1 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1197,32 +1197,21 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
 		.args[4] = data_unit_size,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
-	void *keybuf;
-	dma_addr_t key_phys;
+
 	int ret;
 
-	/*
-	 * 'key' may point to vmalloc()'ed memory, but we need to pass a
-	 * physical address that's been properly flushed.  The sanctioned way to
-	 * do this is by using the DMA API.  But as is best practice for crypto
-	 * keys, we also must wipe the key after use.  This makes kmemdup() +
-	 * dma_map_single() not clearly correct, since the DMA API can use
-	 * bounce buffers.  Instead, just use dma_alloc_coherent().  Programming
-	 * keys is normally rare and thus not performance-critical.
-	 */
-
-	keybuf = dma_alloc_coherent(__scm->dev, key_size, &key_phys,
-				    GFP_KERNEL);
+	void *keybuf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							   key_size,
+							   GFP_KERNEL);
 	if (!keybuf)
 		return -ENOMEM;
 	memcpy(keybuf, key, key_size);
-	desc.args[1] = key_phys;
+	desc.args[1] = qcom_tzmem_to_phys(keybuf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
 	memzero_explicit(keybuf, key_size);
 
-	dma_free_coherent(__scm->dev, key_size, keybuf, key_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 05/12] firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 754f6056b99f..31071a714cf1 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1197,32 +1197,21 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
 		.args[4] = data_unit_size,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
-	void *keybuf;
-	dma_addr_t key_phys;
+
 	int ret;
 
-	/*
-	 * 'key' may point to vmalloc()'ed memory, but we need to pass a
-	 * physical address that's been properly flushed.  The sanctioned way to
-	 * do this is by using the DMA API.  But as is best practice for crypto
-	 * keys, we also must wipe the key after use.  This makes kmemdup() +
-	 * dma_map_single() not clearly correct, since the DMA API can use
-	 * bounce buffers.  Instead, just use dma_alloc_coherent().  Programming
-	 * keys is normally rare and thus not performance-critical.
-	 */
-
-	keybuf = dma_alloc_coherent(__scm->dev, key_size, &key_phys,
-				    GFP_KERNEL);
+	void *keybuf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							   key_size,
+							   GFP_KERNEL);
 	if (!keybuf)
 		return -ENOMEM;
 	memcpy(keybuf, key, key_size);
-	desc.args[1] = key_phys;
+	desc.args[1] = qcom_tzmem_to_phys(keybuf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
 	memzero_explicit(keybuf, key_size);
 
-	dma_free_coherent(__scm->dev, key_size, keybuf, key_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key);
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 06/12] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 31071a714cf1..11638daa2fe5 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1340,8 +1340,6 @@ EXPORT_SYMBOL_GPL(qcom_scm_lmh_profile_change);
 int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		       u64 limit_node, u32 node_id, u64 version)
 {
-	dma_addr_t payload_phys;
-	u32 *payload_buf;
 	int ret, payload_size = 5 * sizeof(u32);
 
 	struct qcom_scm_desc desc = {
@@ -1356,7 +1354,9 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 
-	payload_buf = dma_alloc_coherent(__scm->dev, payload_size, &payload_phys, GFP_KERNEL);
+	u32 *payload_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       payload_size,
+							       GFP_KERNEL);
 	if (!payload_buf)
 		return -ENOMEM;
 
@@ -1366,11 +1366,10 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 	payload_buf[3] = 1;
 	payload_buf[4] = payload_val;
 
-	desc.args[0] = payload_phys;
+	desc.args[0] = qcom_tzmem_to_phys(payload_buf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
-	dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 06/12] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of using dma_alloc_coherent().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 31071a714cf1..11638daa2fe5 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1340,8 +1340,6 @@ EXPORT_SYMBOL_GPL(qcom_scm_lmh_profile_change);
 int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		       u64 limit_node, u32 node_id, u64 version)
 {
-	dma_addr_t payload_phys;
-	u32 *payload_buf;
 	int ret, payload_size = 5 * sizeof(u32);
 
 	struct qcom_scm_desc desc = {
@@ -1356,7 +1354,9 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 
-	payload_buf = dma_alloc_coherent(__scm->dev, payload_size, &payload_phys, GFP_KERNEL);
+	u32 *payload_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       payload_size,
+							       GFP_KERNEL);
 	if (!payload_buf)
 		return -ENOMEM;
 
@@ -1366,11 +1366,10 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 	payload_buf[3] = 1;
 	payload_buf[4] = payload_val;
 
-	desc.args[0] = payload_phys;
+	desc.args[0] = qcom_tzmem_to_phys(payload_buf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
-	dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 07/12] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of manually kmalloc()ing it and then mapping to physical space.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 11638daa2fe5..3a6cefb4eb2e 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1525,37 +1525,27 @@ int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id)
 	unsigned long app_name_len = strlen(app_name);
 	struct qcom_scm_desc desc = {};
 	struct qcom_scm_qseecom_resp res = {};
-	dma_addr_t name_buf_phys;
-	char *name_buf;
 	int status;
 
 	if (app_name_len >= name_buf_size)
 		return -EINVAL;
 
-	name_buf = kzalloc(name_buf_size, GFP_KERNEL);
+	char *name_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							     name_buf_size,
+							     GFP_KERNEL);
 	if (!name_buf)
 		return -ENOMEM;
 
 	memcpy(name_buf, app_name, app_name_len);
 
-	name_buf_phys = dma_map_single(__scm->dev, name_buf, name_buf_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, name_buf_phys);
-	if (status) {
-		kfree(name_buf);
-		dev_err(__scm->dev, "qseecom: failed to map dma address\n");
-		return status;
-	}
-
 	desc.owner = QSEECOM_TZ_OWNER_QSEE_OS;
 	desc.svc = QSEECOM_TZ_SVC_APP_MGR;
 	desc.cmd = QSEECOM_TZ_CMD_APP_LOOKUP;
 	desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL);
-	desc.args[0] = name_buf_phys;
+	desc.args[0] = qcom_tzmem_to_phys(name_buf);
 	desc.args[1] = app_name_len;
 
 	status = qcom_scm_qseecom_call(&desc, &res);
-	dma_unmap_single(__scm->dev, name_buf_phys, name_buf_size, DMA_TO_DEVICE);
-	kfree(name_buf);
 
 	if (status)
 		return status;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 07/12] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Let's use the new TZ memory allocator to obtain a buffer for this call
instead of manually kmalloc()ing it and then mapping to physical space.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 11638daa2fe5..3a6cefb4eb2e 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1525,37 +1525,27 @@ int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id)
 	unsigned long app_name_len = strlen(app_name);
 	struct qcom_scm_desc desc = {};
 	struct qcom_scm_qseecom_resp res = {};
-	dma_addr_t name_buf_phys;
-	char *name_buf;
 	int status;
 
 	if (app_name_len >= name_buf_size)
 		return -EINVAL;
 
-	name_buf = kzalloc(name_buf_size, GFP_KERNEL);
+	char *name_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							     name_buf_size,
+							     GFP_KERNEL);
 	if (!name_buf)
 		return -ENOMEM;
 
 	memcpy(name_buf, app_name, app_name_len);
 
-	name_buf_phys = dma_map_single(__scm->dev, name_buf, name_buf_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, name_buf_phys);
-	if (status) {
-		kfree(name_buf);
-		dev_err(__scm->dev, "qseecom: failed to map dma address\n");
-		return status;
-	}
-
 	desc.owner = QSEECOM_TZ_OWNER_QSEE_OS;
 	desc.svc = QSEECOM_TZ_SVC_APP_MGR;
 	desc.cmd = QSEECOM_TZ_CMD_APP_LOOKUP;
 	desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL);
-	desc.args[0] = name_buf_phys;
+	desc.args[0] = qcom_tzmem_to_phys(name_buf);
 	desc.args[1] = app_name_len;
 
 	status = qcom_scm_qseecom_call(&desc, &res);
-	dma_unmap_single(__scm->dev, name_buf_phys, name_buf_size, DMA_TO_DEVICE);
-	kfree(name_buf);
 
 	if (status)
 		return status;
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
convert all users of it in the qseecom module to using the TZ allocator
for creating SCM call buffers. Together with using the cleanup macros,
it has the added benefit of a significant code shrink. As this is
largely a module separate from the SCM driver, let's use a separate
memory pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++++-----------
 drivers/firmware/qcom/qcom_scm.c              |  30 +-
 include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
 3 files changed, 111 insertions(+), 204 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 32188f098ef3..3a068f8b6990 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -7,17 +7,21 @@
  * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/ucs2_string.h>
 
 #include <linux/firmware/qcom/qcom_qseecom.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 
 /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
 
@@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info {
 struct qcuefi_client {
 	struct qseecom_client *client;
 	struct efivars efivars;
+	struct qcom_tzmem_pool *mempool;
 };
 
 static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
@@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 					   const efi_guid_t *guid, u32 *attributes,
 					   unsigned long *data_size, void *data)
 {
-	struct qsee_req_uefi_get_variable *req_data;
-	struct qsee_rsp_uefi_get_variable *rsp_data;
+	struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL;
 	unsigned long buffer_size = *data_size;
-	efi_status_t efi_status = EFI_SUCCESS;
 	unsigned long name_length;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 		__array(u8, buffer_size)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
 	req_data->data_size = buffer_size;
@@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	req_data->length = req_size;
 
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length < sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length < sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
@@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 				*attributes = rsp_data->attributes;
 		}
 
-		goto out_free;
+		return efi_status;
 	}
 
-	if (rsp_data->length > rsp_size) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length > rsp_size)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
 	/*
 	 * Note: We need to set attributes and data size even if the buffer is
@@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	if (attributes)
 		*attributes = rsp_data->attributes;
 
-	if (buffer_size == 0 && !data) {
-		efi_status = EFI_SUCCESS;
-		goto out_free;
-	}
+	if (buffer_size == 0 && !data)
+		return EFI_SUCCESS;
 
-	if (buffer_size < rsp_data->data_size) {
-		efi_status = EFI_BUFFER_TOO_SMALL;
-		goto out_free;
-	}
+	if (buffer_size < rsp_data->data_size)
+		return EFI_BUFFER_TOO_SMALL;
 
 	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
 					   const efi_guid_t *guid, u32 attributes,
 					   unsigned long data_size, const void *data)
 {
-	struct qsee_req_uefi_set_variable *req_data;
-	struct qsee_rsp_uefi_set_variable *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL;
 	unsigned long name_length;
 	size_t name_offs;
 	size_t guid_offs;
@@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 		__array_offs(u8, data_size, &data_offs)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
+				    GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
 	req_data->attributes = attributes;
@@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 	req_data->length = req_size;
 
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
@@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
 				       sizeof(*rsp_data));
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length != sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length != sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
 			__func__, rsp_data->status);
-		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+		return qsee_uefi_status_to_efi(rsp_data->status);
 	}
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 						unsigned long *name_size, efi_char16_t *name,
 						efi_guid_t *guid)
 {
-	struct qsee_req_uefi_get_next_variable *req_data;
-	struct qsee_rsp_uefi_get_next_variable *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 		__array(*name, *name_size / sizeof(*name))
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
 	req_data->guid_offset = guid_offs;
@@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
 			      *name_size / sizeof(*name));
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length < sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length < sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
@@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 		if (efi_status == EFI_BUFFER_TOO_SMALL)
 			*name_size = rsp_data->name_size;
 
-		goto out_free;
+		return efi_status;
 	}
 
-	if (rsp_data->length > rsp_size) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length > rsp_size)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->name_size > *name_size) {
 		*name_size = rsp_data->name_size;
-		efi_status = EFI_BUFFER_TOO_SMALL;
-		goto out_free;
+		return EFI_BUFFER_TOO_SMALL;
 	}
 
-	if (rsp_data->guid_size != sizeof(*guid)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->guid_size != sizeof(*guid))
+		return EFI_DEVICE_ERROR;
 
 	memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
 	status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
 			      rsp_data->name_size / sizeof(*name));
 	*name_size = rsp_data->name_size;
 
-	if (status < 0) {
+	if (status < 0)
 		/*
 		 * Return EFI_DEVICE_ERROR here because the buffer size should
 		 * have already been validated above, causing this function to
 		 * bail with EFI_BUFFER_TOO_SMALL.
 		 */
-		efi_status = EFI_DEVICE_ERROR;
-	}
+		return EFI_DEVICE_ERROR;
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
 						  u64 *storage_space, u64 *remaining_space,
 						  u64 *max_variable_size)
 {
-	struct qsee_req_uefi_query_variable_info *req_data;
-	struct qsee_rsp_uefi_query_variable_info *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL;
 	int status;
 
-	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data),
+				    GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
+				    GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
 	req_data->attributes = attr;
@@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
 				       sizeof(*rsp_data));
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length != sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length != sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
 			__func__, rsp_data->status);
-		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
-		goto out_free;
+		return qsee_uefi_status_to_efi(rsp_data->status);
 	}
 
 	if (storage_space)
@@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 	if (max_variable_size)
 		*max_variable_size = rsp_data->max_variable_size;
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 /* -- Global efivar interface. ---------------------------------------------- */
@@ -844,6 +765,10 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 	if (status)
 		qcuefi_set_reference(NULL);
 
+	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, SZ_256K);
+	if (IS_ERR(qcuefi->mempool))
+		return PTR_ERR(qcuefi->mempool);
+
 	return status;
 }
 
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 3a6cefb4eb2e..318d7d398e5f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
 /**
  * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @app_id:   The ID of the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      Request buffer sent to the app (must be TZ memory)
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      Response buffer, written to by the app (must be TZ memory)
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given ID and read back
@@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
 {
 	struct qcom_scm_qseecom_resp res = {};
 	struct qcom_scm_desc desc = {};
-	dma_addr_t req_phys;
-	dma_addr_t rsp_phys;
+	phys_addr_t req_phys;
+	phys_addr_t rsp_phys;
 	int status;
 
-	/* Map request buffer */
-	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, req_phys);
-	if (status) {
-		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
-		return status;
-	}
-
-	/* Map response buffer */
-	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
-	status = dma_mapping_error(__scm->dev, rsp_phys);
-	if (status) {
-		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
-		return status;
-	}
+	req_phys = qcom_tzmem_to_phys(req);
+	rsp_phys = qcom_tzmem_to_phys(rsp);
 
 	/* Set up SCM call data */
 	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
@@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
 	/* Perform call */
 	status = qcom_scm_qseecom_call(&desc, &res);
 
-	/* Unmap buffers */
-	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
-	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-
 	if (status)
 		return status;
 
diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
index 5c28298a98be..e868fac55675 100644
--- a/include/linux/firmware/qcom/qcom_qseecom.h
+++ b/include/linux/firmware/qcom/qcom_qseecom.h
@@ -27,9 +27,9 @@ struct qseecom_client {
 /**
  * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @client:   The QSEECOM client associated with the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      Request buffer sent to the app (must be TZ memory).
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      Response buffer, written to by the app (must be TZ memory).
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given client and read
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
convert all users of it in the qseecom module to using the TZ allocator
for creating SCM call buffers. Together with using the cleanup macros,
it has the added benefit of a significant code shrink. As this is
largely a module separate from the SCM driver, let's use a separate
memory pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++++-----------
 drivers/firmware/qcom/qcom_scm.c              |  30 +-
 include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
 3 files changed, 111 insertions(+), 204 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 32188f098ef3..3a068f8b6990 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -7,17 +7,21 @@
  * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/sizes.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/ucs2_string.h>
 
 #include <linux/firmware/qcom/qcom_qseecom.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 
 /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
 
@@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info {
 struct qcuefi_client {
 	struct qseecom_client *client;
 	struct efivars efivars;
+	struct qcom_tzmem_pool *mempool;
 };
 
 static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
@@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 					   const efi_guid_t *guid, u32 *attributes,
 					   unsigned long *data_size, void *data)
 {
-	struct qsee_req_uefi_get_variable *req_data;
-	struct qsee_rsp_uefi_get_variable *rsp_data;
+	struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL;
 	unsigned long buffer_size = *data_size;
-	efi_status_t efi_status = EFI_SUCCESS;
 	unsigned long name_length;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 		__array(u8, buffer_size)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
 	req_data->data_size = buffer_size;
@@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	req_data->length = req_size;
 
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length < sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length < sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
@@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 				*attributes = rsp_data->attributes;
 		}
 
-		goto out_free;
+		return efi_status;
 	}
 
-	if (rsp_data->length > rsp_size) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length > rsp_size)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
 	/*
 	 * Note: We need to set attributes and data size even if the buffer is
@@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	if (attributes)
 		*attributes = rsp_data->attributes;
 
-	if (buffer_size == 0 && !data) {
-		efi_status = EFI_SUCCESS;
-		goto out_free;
-	}
+	if (buffer_size == 0 && !data)
+		return EFI_SUCCESS;
 
-	if (buffer_size < rsp_data->data_size) {
-		efi_status = EFI_BUFFER_TOO_SMALL;
-		goto out_free;
-	}
+	if (buffer_size < rsp_data->data_size)
+		return EFI_BUFFER_TOO_SMALL;
 
 	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
 					   const efi_guid_t *guid, u32 attributes,
 					   unsigned long data_size, const void *data)
 {
-	struct qsee_req_uefi_set_variable *req_data;
-	struct qsee_rsp_uefi_set_variable *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL;
 	unsigned long name_length;
 	size_t name_offs;
 	size_t guid_offs;
@@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 		__array_offs(u8, data_size, &data_offs)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
+				    GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
 	req_data->attributes = attributes;
@@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 	req_data->length = req_size;
 
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
@@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
 				       sizeof(*rsp_data));
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length != sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length != sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
 			__func__, rsp_data->status);
-		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
+		return qsee_uefi_status_to_efi(rsp_data->status);
 	}
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 						unsigned long *name_size, efi_char16_t *name,
 						efi_guid_t *guid)
 {
-	struct qsee_req_uefi_get_next_variable *req_data;
-	struct qsee_rsp_uefi_get_next_variable *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 		__array(*name, *name_size / sizeof(*name))
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
 	req_data->guid_offset = guid_offs;
@@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
 			      *name_size / sizeof(*name));
-	if (status < 0) {
-		efi_status = EFI_INVALID_PARAMETER;
-		goto out_free;
-	}
+	if (status < 0)
+		return EFI_INVALID_PARAMETER;
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length < sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length < sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
@@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 		if (efi_status == EFI_BUFFER_TOO_SMALL)
 			*name_size = rsp_data->name_size;
 
-		goto out_free;
+		return efi_status;
 	}
 
-	if (rsp_data->length > rsp_size) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length > rsp_size)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length)
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->name_size > *name_size) {
 		*name_size = rsp_data->name_size;
-		efi_status = EFI_BUFFER_TOO_SMALL;
-		goto out_free;
+		return EFI_BUFFER_TOO_SMALL;
 	}
 
-	if (rsp_data->guid_size != sizeof(*guid)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->guid_size != sizeof(*guid))
+		return EFI_DEVICE_ERROR;
 
 	memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
 	status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
 			      rsp_data->name_size / sizeof(*name));
 	*name_size = rsp_data->name_size;
 
-	if (status < 0) {
+	if (status < 0)
 		/*
 		 * Return EFI_DEVICE_ERROR here because the buffer size should
 		 * have already been validated above, causing this function to
 		 * bail with EFI_BUFFER_TOO_SMALL.
 		 */
-		efi_status = EFI_DEVICE_ERROR;
-	}
+		return EFI_DEVICE_ERROR;
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
 						  u64 *storage_space, u64 *remaining_space,
 						  u64 *max_variable_size)
 {
-	struct qsee_req_uefi_query_variable_info *req_data;
-	struct qsee_rsp_uefi_query_variable_info *rsp_data;
-	efi_status_t efi_status = EFI_SUCCESS;
+	struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL;
+	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL;
 	int status;
 
-	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data),
+				    GFP_KERNEL);
+	if (!req_data)
+		return EFI_OUT_OF_RESOURCES;
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
+				    GFP_KERNEL);
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
 	req_data->attributes = attr;
@@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 
 	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
 				       sizeof(*rsp_data));
-	if (status) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (status)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO)
+		return EFI_DEVICE_ERROR;
 
-	if (rsp_data->length != sizeof(*rsp_data)) {
-		efi_status = EFI_DEVICE_ERROR;
-		goto out_free;
-	}
+	if (rsp_data->length != sizeof(*rsp_data))
+		return EFI_DEVICE_ERROR;
 
 	if (rsp_data->status) {
 		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
 			__func__, rsp_data->status);
-		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
-		goto out_free;
+		return qsee_uefi_status_to_efi(rsp_data->status);
 	}
 
 	if (storage_space)
@@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 	if (max_variable_size)
 		*max_variable_size = rsp_data->max_variable_size;
 
-out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
-out:
-	return efi_status;
+	return EFI_SUCCESS;
 }
 
 /* -- Global efivar interface. ---------------------------------------------- */
@@ -844,6 +765,10 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 	if (status)
 		qcuefi_set_reference(NULL);
 
+	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, SZ_256K);
+	if (IS_ERR(qcuefi->mempool))
+		return PTR_ERR(qcuefi->mempool);
+
 	return status;
 }
 
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 3a6cefb4eb2e..318d7d398e5f 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
 /**
  * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @app_id:   The ID of the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      Request buffer sent to the app (must be TZ memory)
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      Response buffer, written to by the app (must be TZ memory)
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given ID and read back
@@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
 {
 	struct qcom_scm_qseecom_resp res = {};
 	struct qcom_scm_desc desc = {};
-	dma_addr_t req_phys;
-	dma_addr_t rsp_phys;
+	phys_addr_t req_phys;
+	phys_addr_t rsp_phys;
 	int status;
 
-	/* Map request buffer */
-	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, req_phys);
-	if (status) {
-		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
-		return status;
-	}
-
-	/* Map response buffer */
-	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
-	status = dma_mapping_error(__scm->dev, rsp_phys);
-	if (status) {
-		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
-		return status;
-	}
+	req_phys = qcom_tzmem_to_phys(req);
+	rsp_phys = qcom_tzmem_to_phys(rsp);
 
 	/* Set up SCM call data */
 	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
@@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
 	/* Perform call */
 	status = qcom_scm_qseecom_call(&desc, &res);
 
-	/* Unmap buffers */
-	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
-	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-
 	if (status)
 		return status;
 
diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
index 5c28298a98be..e868fac55675 100644
--- a/include/linux/firmware/qcom/qcom_qseecom.h
+++ b/include/linux/firmware/qcom/qcom_qseecom.h
@@ -27,9 +27,9 @@ struct qseecom_client {
 /**
  * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @client:   The QSEECOM client associated with the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      Request buffer sent to the app (must be TZ memory).
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      Response buffer, written to by the app (must be TZ memory).
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given client and read
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 09/12] firmware: qcom: scm: add support for SHM bridge operations
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Add low-level primitives for enabling SHM bridge support as well as
creating and destroying SHM bridge pools to qcom-scm.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Acked-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c       | 60 ++++++++++++++++++++++++++
 drivers/firmware/qcom/qcom_scm.h       |  3 ++
 include/linux/firmware/qcom/qcom_scm.h |  6 +++
 3 files changed, 69 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 318d7d398e5f..839773270a21 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1323,6 +1323,66 @@ bool qcom_scm_lmh_dcvsh_available(void)
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
 
+int qcom_scm_shm_bridge_enable(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE,
+		.owner = ARM_SMCCC_OWNER_SIP
+	};
+
+	struct qcom_scm_res res;
+
+	if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+					  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
+		return -EOPNOTSUPP;
+
+	return qcom_scm_call(__scm->dev, &desc, &res) ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
+
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_CREATE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = pfn_and_ns_perm_flags,
+		.args[1] = ipfn_and_s_perm_flags,
+		.args[2] = size_and_flags,
+		.args[3] = ns_vmids,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
+					 QCOM_SCM_VAL, QCOM_SCM_VAL),
+	};
+
+	struct qcom_scm_res res;
+	int ret;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (handle && !ret)
+		*handle = res.result[1];
+
+	return ret ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
+
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_DELETE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = handle,
+		.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_delete);
+
 int qcom_scm_lmh_profile_change(u32 profile_id)
 {
 	struct qcom_scm_desc desc = {
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index aa7d06939f8e..cb7273aa0a5e 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -116,6 +116,9 @@ struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
 #define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE	0x05
 #define QCOM_SCM_MP_VIDEO_VAR			0x08
 #define QCOM_SCM_MP_ASSIGN			0x16
+#define QCOM_SCM_MP_SHM_BRIDGE_ENABLE		0x1c
+#define QCOM_SCM_MP_SHM_BRIDGE_DELETE		0x1d
+#define QCOM_SCM_MP_SHM_BRIDGE_CREATE		0x1e
 
 #define QCOM_SCM_SVC_OCMEM		0x0f
 #define QCOM_SCM_OCMEM_LOCK_CMD		0x01
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index ccaf28846054..9b6054813f59 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -115,6 +115,12 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 int qcom_scm_lmh_profile_change(u32 profile_id);
 bool qcom_scm_lmh_dcvsh_available(void);
 
+int qcom_scm_shm_bridge_enable(void);
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle);
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle);
+
 #ifdef CONFIG_QCOM_QSEECOM
 
 int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 09/12] firmware: qcom: scm: add support for SHM bridge operations
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Add low-level primitives for enabling SHM bridge support as well as
creating and destroying SHM bridge pools to qcom-scm.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Acked-by: Andrew Halaney <ahalaney@redhat.com>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c       | 60 ++++++++++++++++++++++++++
 drivers/firmware/qcom/qcom_scm.h       |  3 ++
 include/linux/firmware/qcom/qcom_scm.h |  6 +++
 3 files changed, 69 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 318d7d398e5f..839773270a21 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1323,6 +1323,66 @@ bool qcom_scm_lmh_dcvsh_available(void)
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
 
+int qcom_scm_shm_bridge_enable(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE,
+		.owner = ARM_SMCCC_OWNER_SIP
+	};
+
+	struct qcom_scm_res res;
+
+	if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+					  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
+		return -EOPNOTSUPP;
+
+	return qcom_scm_call(__scm->dev, &desc, &res) ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
+
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_CREATE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = pfn_and_ns_perm_flags,
+		.args[1] = ipfn_and_s_perm_flags,
+		.args[2] = size_and_flags,
+		.args[3] = ns_vmids,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
+					 QCOM_SCM_VAL, QCOM_SCM_VAL),
+	};
+
+	struct qcom_scm_res res;
+	int ret;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (handle && !ret)
+		*handle = res.result[1];
+
+	return ret ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
+
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_DELETE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = handle,
+		.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_delete);
+
 int qcom_scm_lmh_profile_change(u32 profile_id)
 {
 	struct qcom_scm_desc desc = {
diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h
index aa7d06939f8e..cb7273aa0a5e 100644
--- a/drivers/firmware/qcom/qcom_scm.h
+++ b/drivers/firmware/qcom/qcom_scm.h
@@ -116,6 +116,9 @@ struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
 #define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE	0x05
 #define QCOM_SCM_MP_VIDEO_VAR			0x08
 #define QCOM_SCM_MP_ASSIGN			0x16
+#define QCOM_SCM_MP_SHM_BRIDGE_ENABLE		0x1c
+#define QCOM_SCM_MP_SHM_BRIDGE_DELETE		0x1d
+#define QCOM_SCM_MP_SHM_BRIDGE_CREATE		0x1e
 
 #define QCOM_SCM_SVC_OCMEM		0x0f
 #define QCOM_SCM_OCMEM_LOCK_CMD		0x01
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index ccaf28846054..9b6054813f59 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -115,6 +115,12 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 int qcom_scm_lmh_profile_change(u32 profile_id);
 bool qcom_scm_lmh_dcvsh_available(void);
 
+int qcom_scm_shm_bridge_enable(void);
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle);
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle);
+
 #ifdef CONFIG_QCOM_QSEECOM
 
 int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Add a new Kconfig option for selecting the SHM Bridge mode of operation
for the TrustZone memory allocator.

If enabled at build-time, it will still be checked for availability at
run-time. If the architecture doesn't support SHM Bridge, the allocator
will work just like in the default mode.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/Kconfig      | 10 +++++
 drivers/firmware/qcom/qcom_tzmem.c | 65 +++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index d24d83223867..af6f895c5adf 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_DEFAULT
 	  Use the default allocator mode. The memory is page-aligned, non-cachable
 	  and contiguous.
 
+config QCOM_TZMEM_MODE_SHMBRIDGE
+	bool "SHM Bridge"
+	help
+	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
+	  in the 'Default' allocator but is also explicitly marked as an SHM Bridge
+	  buffer.
+
+	  With this selected, all buffers passed to the TrustZone must be allocated
+	  using the TZMem allocator or else the TrustZone will refuse to use them.
+
 endchoice
 
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 44a062f2abd4..1ca3773263e5 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -55,7 +55,70 @@ static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
 
 }
 
-#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
+#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
+
+#include <linux/firmware/qcom/qcom_scm.h>
+
+#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
+
+static bool qcom_tzmem_using_shm_bridge;
+
+static int qcom_tzmem_init(void)
+{
+	int ret;
+
+	ret = qcom_scm_shm_bridge_enable();
+	if (ret == -EOPNOTSUPP) {
+		dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
+		return 0;
+	}
+
+	if (!ret)
+		qcom_tzmem_using_shm_bridge = true;
+
+	return ret;
+}
+
+static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
+{
+	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags, ns_perms;
+	int ret;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	ns_perms = (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ);
+	pfn_and_ns_perm = (u64)pool->pbase | ns_perms;
+	ipfn_and_s_perm = (u64)pool->pbase | ns_perms;
+	size_and_flags = pool->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
+
+	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
+					 ipfn_and_s_perm, size_and_flags,
+					 QCOM_SCM_VMID_HLOS, handle);
+	if (ret)
+		return ret;
+
+	pool->priv = no_free_ptr(handle);
+
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
+{
+	u64 *handle = pool->priv;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return;
+
+	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
+	kfree(handle);
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
 
 /**
  * qcom_tzmem_pool_new() - Create a new TZ memory pool.
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Add a new Kconfig option for selecting the SHM Bridge mode of operation
for the TrustZone memory allocator.

If enabled at build-time, it will still be checked for availability at
run-time. If the architecture doesn't support SHM Bridge, the allocator
will work just like in the default mode.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/Kconfig      | 10 +++++
 drivers/firmware/qcom/qcom_tzmem.c | 65 +++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index d24d83223867..af6f895c5adf 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_DEFAULT
 	  Use the default allocator mode. The memory is page-aligned, non-cachable
 	  and contiguous.
 
+config QCOM_TZMEM_MODE_SHMBRIDGE
+	bool "SHM Bridge"
+	help
+	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
+	  in the 'Default' allocator but is also explicitly marked as an SHM Bridge
+	  buffer.
+
+	  With this selected, all buffers passed to the TrustZone must be allocated
+	  using the TZMem allocator or else the TrustZone will refuse to use them.
+
 endchoice
 
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
index 44a062f2abd4..1ca3773263e5 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -55,7 +55,70 @@ static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
 
 }
 
-#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
+#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
+
+#include <linux/firmware/qcom/qcom_scm.h>
+
+#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
+
+static bool qcom_tzmem_using_shm_bridge;
+
+static int qcom_tzmem_init(void)
+{
+	int ret;
+
+	ret = qcom_scm_shm_bridge_enable();
+	if (ret == -EOPNOTSUPP) {
+		dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
+		return 0;
+	}
+
+	if (!ret)
+		qcom_tzmem_using_shm_bridge = true;
+
+	return ret;
+}
+
+static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
+{
+	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags, ns_perms;
+	int ret;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	ns_perms = (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ);
+	pfn_and_ns_perm = (u64)pool->pbase | ns_perms;
+	ipfn_and_s_perm = (u64)pool->pbase | ns_perms;
+	size_and_flags = pool->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
+
+	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
+					 ipfn_and_s_perm, size_and_flags,
+					 QCOM_SCM_VMID_HLOS, handle);
+	if (ret)
+		return ret;
+
+	pool->priv = no_free_ptr(handle);
+
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
+{
+	u64 *handle = pool->priv;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return;
+
+	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
+	kfree(handle);
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
 
 /**
  * qcom_tzmem_pool_new() - Create a new TZ memory pool.
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

The "memory protection" mechanism mentioned in the comment is the SHM
Bridge. This is also the reason why we do not convert this call to using
the TZ memory allocator.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 839773270a21..7ba5cff6e4e7 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
 	struct qcom_scm_res res;
 
 	/*
-	 * During the scm call memory protection will be enabled for the meta
-	 * data blob, so make sure it's physically contiguous, 4K aligned and
-	 * non-cachable to avoid XPU violations.
+	 * During the SCM call the hypervisor will make the buffer containing
+	 * the program data into an SHM Bridge. This is why we exceptionally
+	 * must not use the TrustZone memory allocator here as - depending on
+	 * Kconfig - it may already use the SHM Bridge mechanism internally.
+	 *
+	 * If we pass a buffer that is already part of an SHM Bridge to this
+	 * call, it will fail.
 	 */
 	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
 				       GFP_KERNEL);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

The "memory protection" mechanism mentioned in the comment is the SHM
Bridge. This is also the reason why we do not convert this call to using
the TZ memory allocator.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 839773270a21..7ba5cff6e4e7 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
 	struct qcom_scm_res res;
 
 	/*
-	 * During the scm call memory protection will be enabled for the meta
-	 * data blob, so make sure it's physically contiguous, 4K aligned and
-	 * non-cachable to avoid XPU violations.
+	 * During the SCM call the hypervisor will make the buffer containing
+	 * the program data into an SHM Bridge. This is why we exceptionally
+	 * must not use the TrustZone memory allocator here as - depending on
+	 * Kconfig - it may already use the SHM Bridge mechanism internally.
+	 *
+	 * If we pass a buffer that is already part of an SHM Bridge to this
+	 * call, it will fail.
 	 */
 	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
 				       GFP_KERNEL);
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 12/12] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Enable SHM Bridge support in the Qualcomm TrustZone allocator by default
as even on architectures that don't support it, we automatically fall
back to the default behavior.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cfa3e00def09..f17bd3ea4a7f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -253,6 +253,7 @@ CONFIG_INTEL_STRATIX10_RSU=m
 CONFIG_MTK_ADSP_IPC=m
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
 CONFIG_GNSS=m
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH v7 12/12] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator
@ 2024-02-05 18:28   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-05 18:28 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Enable SHM Bridge support in the Qualcomm TrustZone allocator by default
as even on architectures that don't support it, we automatically fall
back to the default behavior.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cfa3e00def09..f17bd3ea4a7f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -253,6 +253,7 @@ CONFIG_INTEL_STRATIX10_RSU=m
 CONFIG_MTK_ADSP_IPC=m
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
 CONFIG_GNSS=m
-- 
2.40.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-13 16:34   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-13 16:34 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski

On Mon, Feb 5, 2024 at 7:28 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>

[snip]

>
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
>

I forgot to mention that I also tested it on db410c where it correctly
reports that:

[    0.107312] qcom_scm firmware:scm: SHM Bridge not supported

and falls back to using non-SHM bridge allocator.

It was also tested on other platforms by other people which is
reflected in Tested-by tags in this series.

Bart

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
@ 2024-02-13 16:34   ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-13 16:34 UTC (permalink / raw)
  To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann
  Cc: linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski

On Mon, Feb 5, 2024 at 7:28 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>

[snip]

>
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
>

I forgot to mention that I also tested it on db410c where it correctly
reports that:

[    0.107312] qcom_scm firmware:scm: SHM Bridge not supported

and falls back to using non-SHM bridge allocator.

It was also tested on other platforms by other people which is
reflected in Tested-by tags in this series.

Bart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
  2024-02-05 18:27 ` Bartosz Golaszewski
@ 2024-02-17 19:58   ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-17 19:58 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski

On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> We've established the need for using separate secured memory pools for
> SCM and QSEECOM

Where has this need been established, what is the actual problem you're
solving with this series?

Does SCM and QSEECOM, as it's implemented in the kernel today, not work
satisfactory?

> as well as the upcoming scminvoke driver.
> 

Is smcinvoke driver upstreaming blocked by not transitioning the scm
driver to a "secure memory pool"?

Is this happening now, or do we need to merge this series when that day
comes?

> It's also become clear that in order to be future-proof, the new
> allocator must be an abstraction layer of a higher level as the SHM
> Bridge will not be the only memory protection mechanism that we'll see
> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
> allocator.
> 
> Also to that end: the new allocator is its own module now and provides a
> Kconfig choice menu for selecting the mode of operation (currently
> default and SHM Bridge).
> 
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
> 

It's reasonable to assume from mentioning of this (and Andrew's t-b),
that the patchset has only been tested on recent platforms that indeed
does implement shmbridge. Can you please share the list of other
platforms that you've tested this on, and can you please get someone
from IPQ to also give their r-b or t-b?

Regards,
Bjorn

> v6 -> v7:
> - fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR
> 
> v5 -> v6:
> Fixed two issues reported by autobuilders:
> - add a fix for memory leaks in the qseecom driver as the first patch for
>   easier backporting to the v6.6.y branch
> - explicitly cast the bus address stored in a variable of type dma_addr_t
>   to phys_addr_t expected by the genpool API
> 
> v4 -> v5:
> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
> - remove a comment that's no longer useful
> - collect tags
> 
> v3 -> v4:
> - include linux/sizes.h for SZ_X macros
> - use dedicated RCU APIs to dereference radix tree slots
> - fix kerneldocs
> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>   that creates the SHM bridge
> 
> v2 -> v3:
> - restore pool management and use separate pools for different users
> - don't use the new allocator in qcom_scm_pas_init_image() as the
>   TrustZone will create an SHM bridge for us here
> - rewrite the entire series again for most part
> 
> v1 -> v2:
> - too many changes to list, it's a complete rewrite as explained above
> 
> Bartosz Golaszewski (12):
>   firmware: qcom: add a dedicated TrustZone buffer allocator
>   firmware: qcom: scm: enable the TZ mem allocator
>   firmware: qcom: scm: smc: switch to using the SCM allocator
>   firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>     allocator
>   firmware: qcom: qseecom: convert to using the TZ allocator
>   firmware: qcom: scm: add support for SHM bridge operations
>   firmware: qcom: tzmem: enable SHM Bridge support
>   firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>   arm64: defconfig: enable SHM Bridge support for the TZ memory
>     allocator
> 
>  MAINTAINERS                                   |   8 +
>  arch/arm64/configs/defconfig                  |   1 +
>  drivers/firmware/qcom/Kconfig                 |  31 ++
>  drivers/firmware/qcom/Makefile                |   1 +
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>  drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>  drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>  drivers/firmware/qcom/qcom_scm.h              |   6 +
>  drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>  drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  include/linux/firmware/qcom/qcom_scm.h        |   6 +
>  include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>  13 files changed, 685 insertions(+), 268 deletions(-)
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>  create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
> 
> -- 
> 2.40.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
@ 2024-02-17 19:58   ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-17 19:58 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski

On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> We've established the need for using separate secured memory pools for
> SCM and QSEECOM

Where has this need been established, what is the actual problem you're
solving with this series?

Does SCM and QSEECOM, as it's implemented in the kernel today, not work
satisfactory?

> as well as the upcoming scminvoke driver.
> 

Is smcinvoke driver upstreaming blocked by not transitioning the scm
driver to a "secure memory pool"?

Is this happening now, or do we need to merge this series when that day
comes?

> It's also become clear that in order to be future-proof, the new
> allocator must be an abstraction layer of a higher level as the SHM
> Bridge will not be the only memory protection mechanism that we'll see
> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
> allocator.
> 
> Also to that end: the new allocator is its own module now and provides a
> Kconfig choice menu for selecting the mode of operation (currently
> default and SHM Bridge).
> 
> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
> remoteproc.
> 

It's reasonable to assume from mentioning of this (and Andrew's t-b),
that the patchset has only been tested on recent platforms that indeed
does implement shmbridge. Can you please share the list of other
platforms that you've tested this on, and can you please get someone
from IPQ to also give their r-b or t-b?

Regards,
Bjorn

> v6 -> v7:
> - fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR
> 
> v5 -> v6:
> Fixed two issues reported by autobuilders:
> - add a fix for memory leaks in the qseecom driver as the first patch for
>   easier backporting to the v6.6.y branch
> - explicitly cast the bus address stored in a variable of type dma_addr_t
>   to phys_addr_t expected by the genpool API
> 
> v4 -> v5:
> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
> - remove a comment that's no longer useful
> - collect tags
> 
> v3 -> v4:
> - include linux/sizes.h for SZ_X macros
> - use dedicated RCU APIs to dereference radix tree slots
> - fix kerneldocs
> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>   that creates the SHM bridge
> 
> v2 -> v3:
> - restore pool management and use separate pools for different users
> - don't use the new allocator in qcom_scm_pas_init_image() as the
>   TrustZone will create an SHM bridge for us here
> - rewrite the entire series again for most part
> 
> v1 -> v2:
> - too many changes to list, it's a complete rewrite as explained above
> 
> Bartosz Golaszewski (12):
>   firmware: qcom: add a dedicated TrustZone buffer allocator
>   firmware: qcom: scm: enable the TZ mem allocator
>   firmware: qcom: scm: smc: switch to using the SCM allocator
>   firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>   firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>     allocator
>   firmware: qcom: qseecom: convert to using the TZ allocator
>   firmware: qcom: scm: add support for SHM bridge operations
>   firmware: qcom: tzmem: enable SHM Bridge support
>   firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>   arm64: defconfig: enable SHM Bridge support for the TZ memory
>     allocator
> 
>  MAINTAINERS                                   |   8 +
>  arch/arm64/configs/defconfig                  |   1 +
>  drivers/firmware/qcom/Kconfig                 |  31 ++
>  drivers/firmware/qcom/Makefile                |   1 +
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>  drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>  drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>  drivers/firmware/qcom/qcom_scm.h              |   6 +
>  drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>  drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  include/linux/firmware/qcom/qcom_scm.h        |   6 +
>  include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>  13 files changed, 685 insertions(+), 268 deletions(-)
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>  create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>  create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
> 
> -- 
> 2.40.1
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-02-05 18:28   ` Bartosz Golaszewski
@ 2024-02-18  3:08     ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:08 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> convert all users of it in the qseecom module to using the TZ allocator
> for creating SCM call buffers.

This reads as if this is removal of duplication, now that we have the TZ
allocation. But wasn't there something about you not being able to mix
and match shmbridge and non-shmbridge allocations in the interface, so
this transition is actually required? Or did I get that wrong and this
just reduction in duplication?

> Together with using the cleanup macros,
> it has the added benefit of a significant code shrink.

That is true, but the move to using cleanup macros at the same time as
changing the implementation makes it unnecessarily hard to reason about
this patch.

This patch would be much better if split in two.

> As this is
> largely a module separate from the SCM driver, let's use a separate
> memory pool.
> 

This module is effectively used to read and write EFI variables today.
Is that worth statically removing 256kb of DDR for? Is this done solely
because it logically makes sense, or did you choose this for a reason?

Regards,
Bjorn

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++++-----------
>  drivers/firmware/qcom/qcom_scm.c              |  30 +-
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  3 files changed, 111 insertions(+), 204 deletions(-)
> 
> diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> index 32188f098ef3..3a068f8b6990 100644
> --- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> +++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> @@ -7,17 +7,21 @@
>   * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
>   */
>  
> +#include <linux/cleanup.h>
>  #include <linux/efi.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/mutex.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/sizes.h>
>  #include <linux/slab.h>
>  #include <linux/types.h>
>  #include <linux/ucs2_string.h>
>  
>  #include <linux/firmware/qcom/qcom_qseecom.h>
> +#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_tzmem.h>
>  
>  /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
>  
> @@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info {
>  struct qcuefi_client {
>  	struct qseecom_client *client;
>  	struct efivars efivars;
> +	struct qcom_tzmem_pool *mempool;
>  };
>  
>  static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
> @@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  					   const efi_guid_t *guid, u32 *attributes,
>  					   unsigned long *data_size, void *data)
>  {
> -	struct qsee_req_uefi_get_variable *req_data;
> -	struct qsee_rsp_uefi_get_variable *rsp_data;
> +	struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL;
>  	unsigned long buffer_size = *data_size;
> -	efi_status_t efi_status = EFI_SUCCESS;
>  	unsigned long name_length;
> +	efi_status_t efi_status;
>  	size_t guid_offs;
>  	size_t name_offs;
>  	size_t req_size;
> @@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  		__array(u8, buffer_size)
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
>  	req_data->data_size = buffer_size;
> @@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  	req_data->length = req_size;
>  
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length < sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length < sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
> @@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  				*attributes = rsp_data->attributes;
>  		}
>  
> -		goto out_free;
> +		return efi_status;
>  	}
>  
> -	if (rsp_data->length > rsp_size) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length > rsp_size)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
>  	/*
>  	 * Note: We need to set attributes and data size even if the buffer is
> @@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  	if (attributes)
>  		*attributes = rsp_data->attributes;
>  
> -	if (buffer_size == 0 && !data) {
> -		efi_status = EFI_SUCCESS;
> -		goto out_free;
> -	}
> +	if (buffer_size == 0 && !data)
> +		return EFI_SUCCESS;
>  
> -	if (buffer_size < rsp_data->data_size) {
> -		efi_status = EFI_BUFFER_TOO_SMALL;
> -		goto out_free;
> -	}
> +	if (buffer_size < rsp_data->data_size)
> +		return EFI_BUFFER_TOO_SMALL;
>  
>  	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
>  					   const efi_guid_t *guid, u32 attributes,
>  					   unsigned long data_size, const void *data)
>  {
> -	struct qsee_req_uefi_set_variable *req_data;
> -	struct qsee_rsp_uefi_set_variable *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL;
>  	unsigned long name_length;
>  	size_t name_offs;
>  	size_t guid_offs;
> @@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  		__array_offs(u8, data_size, &data_offs)
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
> +				    GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
>  	req_data->attributes = attributes;
> @@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  	req_data->length = req_size;
>  
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  
> @@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
>  				       sizeof(*rsp_data));
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length != sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length != sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
>  			__func__, rsp_data->status);
> -		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
> +		return qsee_uefi_status_to_efi(rsp_data->status);
>  	}
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  						unsigned long *name_size, efi_char16_t *name,
>  						efi_guid_t *guid)
>  {
> -	struct qsee_req_uefi_get_next_variable *req_data;
> -	struct qsee_rsp_uefi_get_next_variable *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL;
> +	efi_status_t efi_status;
>  	size_t guid_offs;
>  	size_t name_offs;
>  	size_t req_size;
> @@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  		__array(*name, *name_size / sizeof(*name))
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
>  	req_data->guid_offset = guid_offs;
> @@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
>  			      *name_size / sizeof(*name));
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length < sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length < sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
> @@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  		if (efi_status == EFI_BUFFER_TOO_SMALL)
>  			*name_size = rsp_data->name_size;
>  
> -		goto out_free;
> +		return efi_status;
>  	}
>  
> -	if (rsp_data->length > rsp_size) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length > rsp_size)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->name_size > *name_size) {
>  		*name_size = rsp_data->name_size;
> -		efi_status = EFI_BUFFER_TOO_SMALL;
> -		goto out_free;
> +		return EFI_BUFFER_TOO_SMALL;
>  	}
>  
> -	if (rsp_data->guid_size != sizeof(*guid)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->guid_size != sizeof(*guid))
> +		return EFI_DEVICE_ERROR;
>  
>  	memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
>  	status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
>  			      rsp_data->name_size / sizeof(*name));
>  	*name_size = rsp_data->name_size;
>  
> -	if (status < 0) {
> +	if (status < 0)
>  		/*
>  		 * Return EFI_DEVICE_ERROR here because the buffer size should
>  		 * have already been validated above, causing this function to
>  		 * bail with EFI_BUFFER_TOO_SMALL.
>  		 */
> -		efi_status = EFI_DEVICE_ERROR;
> -	}
> +		return EFI_DEVICE_ERROR;
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
>  						  u64 *storage_space, u64 *remaining_space,
>  						  u64 *max_variable_size)
>  {
> -	struct qsee_req_uefi_query_variable_info *req_data;
> -	struct qsee_rsp_uefi_query_variable_info *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL;
>  	int status;
>  
> -	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data),
> +				    GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
> +				    GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
>  	req_data->attributes = attr;
> @@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
>  				       sizeof(*rsp_data));
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length != sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length != sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
>  			__func__, rsp_data->status);
> -		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
> -		goto out_free;
> +		return qsee_uefi_status_to_efi(rsp_data->status);
>  	}
>  
>  	if (storage_space)
> @@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
>  	if (max_variable_size)
>  		*max_variable_size = rsp_data->max_variable_size;
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  /* -- Global efivar interface. ---------------------------------------------- */
> @@ -844,6 +765,10 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
>  	if (status)
>  		qcuefi_set_reference(NULL);
>  
> +	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, SZ_256K);
> +	if (IS_ERR(qcuefi->mempool))
> +		return PTR_ERR(qcuefi->mempool);
> +
>  	return status;
>  }
>  
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 3a6cefb4eb2e..318d7d398e5f 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
>  /**
>   * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
>   * @app_id:   The ID of the target app.
> - * @req:      Request buffer sent to the app (must be DMA-mappable).
> + * @req:      Request buffer sent to the app (must be TZ memory)
>   * @req_size: Size of the request buffer.
> - * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
> + * @rsp:      Response buffer, written to by the app (must be TZ memory)
>   * @rsp_size: Size of the response buffer.
>   *
>   * Sends a request to the QSEE app associated with the given ID and read back
> @@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
>  {
>  	struct qcom_scm_qseecom_resp res = {};
>  	struct qcom_scm_desc desc = {};
> -	dma_addr_t req_phys;
> -	dma_addr_t rsp_phys;
> +	phys_addr_t req_phys;
> +	phys_addr_t rsp_phys;
>  	int status;
>  
> -	/* Map request buffer */
> -	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
> -	status = dma_mapping_error(__scm->dev, req_phys);
> -	if (status) {
> -		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
> -		return status;
> -	}
> -
> -	/* Map response buffer */
> -	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
> -	status = dma_mapping_error(__scm->dev, rsp_phys);
> -	if (status) {
> -		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
> -		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
> -		return status;
> -	}
> +	req_phys = qcom_tzmem_to_phys(req);
> +	rsp_phys = qcom_tzmem_to_phys(rsp);
>  
>  	/* Set up SCM call data */
>  	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
> @@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
>  	/* Perform call */
>  	status = qcom_scm_qseecom_call(&desc, &res);
>  
> -	/* Unmap buffers */
> -	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
> -	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
> -
>  	if (status)
>  		return status;
>  
> diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
> index 5c28298a98be..e868fac55675 100644
> --- a/include/linux/firmware/qcom/qcom_qseecom.h
> +++ b/include/linux/firmware/qcom/qcom_qseecom.h
> @@ -27,9 +27,9 @@ struct qseecom_client {
>  /**
>   * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
>   * @client:   The QSEECOM client associated with the target app.
> - * @req:      Request buffer sent to the app (must be DMA-mappable).
> + * @req:      Request buffer sent to the app (must be TZ memory).
>   * @req_size: Size of the request buffer.
> - * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
> + * @rsp:      Response buffer, written to by the app (must be TZ memory).
>   * @rsp_size: Size of the response buffer.
>   *
>   * Sends a request to the QSEE app associated with the given client and read
> -- 
> 2.40.1
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-02-18  3:08     ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:08 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> convert all users of it in the qseecom module to using the TZ allocator
> for creating SCM call buffers.

This reads as if this is removal of duplication, now that we have the TZ
allocation. But wasn't there something about you not being able to mix
and match shmbridge and non-shmbridge allocations in the interface, so
this transition is actually required? Or did I get that wrong and this
just reduction in duplication?

> Together with using the cleanup macros,
> it has the added benefit of a significant code shrink.

That is true, but the move to using cleanup macros at the same time as
changing the implementation makes it unnecessarily hard to reason about
this patch.

This patch would be much better if split in two.

> As this is
> largely a module separate from the SCM driver, let's use a separate
> memory pool.
> 

This module is effectively used to read and write EFI variables today.
Is that worth statically removing 256kb of DDR for? Is this done solely
because it logically makes sense, or did you choose this for a reason?

Regards,
Bjorn

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> Tested-by: Maximilian Luz <luzmaximilian@gmail.com>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++++-----------
>  drivers/firmware/qcom/qcom_scm.c              |  30 +-
>  include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>  3 files changed, 111 insertions(+), 204 deletions(-)
> 
> diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> index 32188f098ef3..3a068f8b6990 100644
> --- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> +++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
> @@ -7,17 +7,21 @@
>   * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
>   */
>  
> +#include <linux/cleanup.h>
>  #include <linux/efi.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/mutex.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/sizes.h>
>  #include <linux/slab.h>
>  #include <linux/types.h>
>  #include <linux/ucs2_string.h>
>  
>  #include <linux/firmware/qcom/qcom_qseecom.h>
> +#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_tzmem.h>
>  
>  /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */
>  
> @@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info {
>  struct qcuefi_client {
>  	struct qseecom_client *client;
>  	struct efivars efivars;
> +	struct qcom_tzmem_pool *mempool;
>  };
>  
>  static struct device *qcuefi_dev(struct qcuefi_client *qcuefi)
> @@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  					   const efi_guid_t *guid, u32 *attributes,
>  					   unsigned long *data_size, void *data)
>  {
> -	struct qsee_req_uefi_get_variable *req_data;
> -	struct qsee_rsp_uefi_get_variable *rsp_data;
> +	struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL;
>  	unsigned long buffer_size = *data_size;
> -	efi_status_t efi_status = EFI_SUCCESS;
>  	unsigned long name_length;
> +	efi_status_t efi_status;
>  	size_t guid_offs;
>  	size_t name_offs;
>  	size_t req_size;
> @@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  		__array(u8, buffer_size)
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
>  	req_data->data_size = buffer_size;
> @@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  	req_data->length = req_size;
>  
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length < sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length < sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
> @@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  				*attributes = rsp_data->attributes;
>  		}
>  
> -		goto out_free;
> +		return efi_status;
>  	}
>  
> -	if (rsp_data->length > rsp_size) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length > rsp_size)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
>  	/*
>  	 * Note: We need to set attributes and data size even if the buffer is
> @@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
>  	if (attributes)
>  		*attributes = rsp_data->attributes;
>  
> -	if (buffer_size == 0 && !data) {
> -		efi_status = EFI_SUCCESS;
> -		goto out_free;
> -	}
> +	if (buffer_size == 0 && !data)
> +		return EFI_SUCCESS;
>  
> -	if (buffer_size < rsp_data->data_size) {
> -		efi_status = EFI_BUFFER_TOO_SMALL;
> -		goto out_free;
> -	}
> +	if (buffer_size < rsp_data->data_size)
> +		return EFI_BUFFER_TOO_SMALL;
>  
>  	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name,
>  					   const efi_guid_t *guid, u32 attributes,
>  					   unsigned long data_size, const void *data)
>  {
> -	struct qsee_req_uefi_set_variable *req_data;
> -	struct qsee_rsp_uefi_set_variable *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL;
>  	unsigned long name_length;
>  	size_t name_offs;
>  	size_t guid_offs;
> @@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  		__array_offs(u8, data_size, &data_offs)
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
> +				    GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
>  	req_data->attributes = attributes;
> @@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  	req_data->length = req_size;
>  
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length);
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  
> @@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
>  				       sizeof(*rsp_data));
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length != sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length != sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
>  			__func__, rsp_data->status);
> -		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
> +		return qsee_uefi_status_to_efi(rsp_data->status);
>  	}
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  						unsigned long *name_size, efi_char16_t *name,
>  						efi_guid_t *guid)
>  {
> -	struct qsee_req_uefi_get_next_variable *req_data;
> -	struct qsee_rsp_uefi_get_next_variable *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL;
> +	efi_status_t efi_status;
>  	size_t guid_offs;
>  	size_t name_offs;
>  	size_t req_size;
> @@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  		__array(*name, *name_size / sizeof(*name))
>  	);
>  
> -	req_data = kzalloc(req_size, GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
>  	req_data->guid_offset = guid_offs;
> @@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
>  	status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name,
>  			      *name_size / sizeof(*name));
> -	if (status < 0) {
> -		efi_status = EFI_INVALID_PARAMETER;
> -		goto out_free;
> -	}
> +	if (status < 0)
> +		return EFI_INVALID_PARAMETER;
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length < sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length < sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
> @@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
>  		if (efi_status == EFI_BUFFER_TOO_SMALL)
>  			*name_size = rsp_data->name_size;
>  
> -		goto out_free;
> +		return efi_status;
>  	}
>  
> -	if (rsp_data->length > rsp_size) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length > rsp_size)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length)
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->name_size > *name_size) {
>  		*name_size = rsp_data->name_size;
> -		efi_status = EFI_BUFFER_TOO_SMALL;
> -		goto out_free;
> +		return EFI_BUFFER_TOO_SMALL;
>  	}
>  
> -	if (rsp_data->guid_size != sizeof(*guid)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->guid_size != sizeof(*guid))
> +		return EFI_DEVICE_ERROR;
>  
>  	memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size);
>  	status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset,
>  			      rsp_data->name_size / sizeof(*name));
>  	*name_size = rsp_data->name_size;
>  
> -	if (status < 0) {
> +	if (status < 0)
>  		/*
>  		 * Return EFI_DEVICE_ERROR here because the buffer size should
>  		 * have already been validated above, causing this function to
>  		 * bail with EFI_BUFFER_TOO_SMALL.
>  		 */
> -		efi_status = EFI_DEVICE_ERROR;
> -	}
> +		return EFI_DEVICE_ERROR;
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr,
>  						  u64 *storage_space, u64 *remaining_space,
>  						  u64 *max_variable_size)
>  {
> -	struct qsee_req_uefi_query_variable_info *req_data;
> -	struct qsee_rsp_uefi_query_variable_info *rsp_data;
> -	efi_status_t efi_status = EFI_SUCCESS;
> +	struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL;
> +	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL;
>  	int status;
>  
> -	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
> -	if (!req_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out;
> -	}
> +	req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data),
> +				    GFP_KERNEL);
> +	if (!req_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
> -	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
> -	if (!rsp_data) {
> -		efi_status = EFI_OUT_OF_RESOURCES;
> -		goto out_free_req;
> -	}
> +	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data),
> +				    GFP_KERNEL);
> +	if (!rsp_data)
> +		return EFI_OUT_OF_RESOURCES;
>  
>  	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
>  	req_data->attributes = attr;
> @@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
>  
>  	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
>  				       sizeof(*rsp_data));
> -	if (status) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (status)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO)
> +		return EFI_DEVICE_ERROR;
>  
> -	if (rsp_data->length != sizeof(*rsp_data)) {
> -		efi_status = EFI_DEVICE_ERROR;
> -		goto out_free;
> -	}
> +	if (rsp_data->length != sizeof(*rsp_data))
> +		return EFI_DEVICE_ERROR;
>  
>  	if (rsp_data->status) {
>  		dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n",
>  			__func__, rsp_data->status);
> -		efi_status = qsee_uefi_status_to_efi(rsp_data->status);
> -		goto out_free;
> +		return qsee_uefi_status_to_efi(rsp_data->status);
>  	}
>  
>  	if (storage_space)
> @@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
>  	if (max_variable_size)
>  		*max_variable_size = rsp_data->max_variable_size;
>  
> -out_free:
> -	kfree(rsp_data);
> -out_free_req:
> -	kfree(req_data);
> -out:
> -	return efi_status;
> +	return EFI_SUCCESS;
>  }
>  
>  /* -- Global efivar interface. ---------------------------------------------- */
> @@ -844,6 +765,10 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
>  	if (status)
>  		qcuefi_set_reference(NULL);
>  
> +	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, SZ_256K);
> +	if (IS_ERR(qcuefi->mempool))
> +		return PTR_ERR(qcuefi->mempool);
> +
>  	return status;
>  }
>  
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 3a6cefb4eb2e..318d7d398e5f 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
>  /**
>   * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
>   * @app_id:   The ID of the target app.
> - * @req:      Request buffer sent to the app (must be DMA-mappable).
> + * @req:      Request buffer sent to the app (must be TZ memory)
>   * @req_size: Size of the request buffer.
> - * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
> + * @rsp:      Response buffer, written to by the app (must be TZ memory)
>   * @rsp_size: Size of the response buffer.
>   *
>   * Sends a request to the QSEE app associated with the given ID and read back
> @@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
>  {
>  	struct qcom_scm_qseecom_resp res = {};
>  	struct qcom_scm_desc desc = {};
> -	dma_addr_t req_phys;
> -	dma_addr_t rsp_phys;
> +	phys_addr_t req_phys;
> +	phys_addr_t rsp_phys;
>  	int status;
>  
> -	/* Map request buffer */
> -	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
> -	status = dma_mapping_error(__scm->dev, req_phys);
> -	if (status) {
> -		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
> -		return status;
> -	}
> -
> -	/* Map response buffer */
> -	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
> -	status = dma_mapping_error(__scm->dev, rsp_phys);
> -	if (status) {
> -		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
> -		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
> -		return status;
> -	}
> +	req_phys = qcom_tzmem_to_phys(req);
> +	rsp_phys = qcom_tzmem_to_phys(rsp);
>  
>  	/* Set up SCM call data */
>  	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
> @@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
>  	/* Perform call */
>  	status = qcom_scm_qseecom_call(&desc, &res);
>  
> -	/* Unmap buffers */
> -	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
> -	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
> -
>  	if (status)
>  		return status;
>  
> diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h
> index 5c28298a98be..e868fac55675 100644
> --- a/include/linux/firmware/qcom/qcom_qseecom.h
> +++ b/include/linux/firmware/qcom/qcom_qseecom.h
> @@ -27,9 +27,9 @@ struct qseecom_client {
>  /**
>   * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
>   * @client:   The QSEECOM client associated with the target app.
> - * @req:      Request buffer sent to the app (must be DMA-mappable).
> + * @req:      Request buffer sent to the app (must be TZ memory).
>   * @req_size: Size of the request buffer.
> - * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
> + * @rsp:      Response buffer, written to by the app (must be TZ memory).
>   * @rsp_size: Size of the response buffer.
>   *
>   * Sends a request to the QSEE app associated with the given client and read
> -- 
> 2.40.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
  2024-02-05 18:27   ` Bartosz Golaszewski
@ 2024-02-18  3:22     ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:22 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:27:59PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
[..]
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> new file mode 100644
> index 000000000000..44a062f2abd4
> --- /dev/null
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -0,0 +1,302 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later

Could you please confirm that "-or-later" is intended?

> +/*
> + * Memory allocator for buffers shared with the TrustZone.
> + *
> + * Copyright (C) 2023 Linaro Ltd.
> + */
[..]
> +/**
> + * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> + * @size: Size of the new pool in bytes.
> + *
> + * Create a new pool of memory suitable for sharing with the TrustZone.
> + *
> + * Must not be used in atomic context.

 * Context: Describes whether the function can sleep, what locks it takes,
 *          releases, or expects to be held. It can extend over multiple
 *          lines.

> + *
> + * Returns:
> + * New memory pool address or ERR_PTR() on error.

 * Return: Describe the return value of function_name.

both from:
https://docs.kernel.org/doc-guide/kernel-doc.html#function-documentation

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
@ 2024-02-18  3:22     ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:22 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:27:59PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
[..]
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> new file mode 100644
> index 000000000000..44a062f2abd4
> --- /dev/null
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -0,0 +1,302 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later

Could you please confirm that "-or-later" is intended?

> +/*
> + * Memory allocator for buffers shared with the TrustZone.
> + *
> + * Copyright (C) 2023 Linaro Ltd.
> + */
[..]
> +/**
> + * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> + * @size: Size of the new pool in bytes.
> + *
> + * Create a new pool of memory suitable for sharing with the TrustZone.
> + *
> + * Must not be used in atomic context.

 * Context: Describes whether the function can sleep, what locks it takes,
 *          releases, or expects to be held. It can extend over multiple
 *          lines.

> + *
> + * Returns:
> + * New memory pool address or ERR_PTR() on error.

 * Return: Describe the return value of function_name.

both from:
https://docs.kernel.org/doc-guide/kernel-doc.html#function-documentation

Regards,
Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
  2024-02-05 18:28   ` Bartosz Golaszewski
@ 2024-02-18  3:25     ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:25 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Select the TrustZone memory allocator in Kconfig and create a pool of
> memory shareable with the TrustZone when probing the SCM driver.
> 
> This will allow a gradual conversion of all relevant SCM calls to using
> the dedicated allocator.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  drivers/firmware/qcom/Kconfig    |  1 +
>  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index f18686edf415..d24d83223867 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -7,6 +7,7 @@
>  menu "Qualcomm firmware drivers"
>  
>  config QCOM_SCM
> +	select QCOM_TZMEM
>  	tristate
>  
>  config QCOM_TZMEM
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 520de9b5633a..0d4c028be0c1 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -8,8 +8,10 @@
>  #include <linux/completion.h>
>  #include <linux/cpumask.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/err.h>
>  #include <linux/export.h>
>  #include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_tzmem.h>
>  #include <linux/init.h>
>  #include <linux/interconnect.h>
>  #include <linux/interrupt.h>
> @@ -20,9 +22,11 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset-controller.h>
> +#include <linux/sizes.h>
>  #include <linux/types.h>
>  
>  #include "qcom_scm.h"
> +#include "qcom_tzmem.h"
>  
>  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
>  module_param(download_mode, bool, 0);
> @@ -41,6 +45,8 @@ struct qcom_scm {
>  	int scm_vote_count;
>  
>  	u64 dload_mode_addr;
> +
> +	struct qcom_tzmem_pool *mempool;
>  };
>  
>  struct qcom_scm_current_perm_info {
> @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
>  	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
>  		qcom_scm_disable_sdi();
>  
> +	ret = qcom_tzmem_enable(__scm->dev);
> +	if (ret)
> +		return dev_err_probe(__scm->dev, ret,
> +				     "Failed to enable the TrustZone memory allocator\n");
> +
> +	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);

As we're not moving from the callers freely allocating what they need,
to a fixed sized pool of 256kb. Please document why 256kb was choosen,
so that we have something to fall back on when someone runs out of this
space, or wonders "why not 128kb?".

Regards,
Bjorn

> +	if (IS_ERR(__scm->mempool))
> +		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> +				     "Failed to create the SCM memory pool\n");
> +
>  	/*
>  	 * Initialize the QSEECOM interface.
>  	 *
> -- 
> 2.40.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-02-18  3:25     ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:25 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Select the TrustZone memory allocator in Kconfig and create a pool of
> memory shareable with the TrustZone when probing the SCM driver.
> 
> This will allow a gradual conversion of all relevant SCM calls to using
> the dedicated allocator.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  drivers/firmware/qcom/Kconfig    |  1 +
>  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index f18686edf415..d24d83223867 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -7,6 +7,7 @@
>  menu "Qualcomm firmware drivers"
>  
>  config QCOM_SCM
> +	select QCOM_TZMEM
>  	tristate
>  
>  config QCOM_TZMEM
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 520de9b5633a..0d4c028be0c1 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -8,8 +8,10 @@
>  #include <linux/completion.h>
>  #include <linux/cpumask.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/err.h>
>  #include <linux/export.h>
>  #include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_tzmem.h>
>  #include <linux/init.h>
>  #include <linux/interconnect.h>
>  #include <linux/interrupt.h>
> @@ -20,9 +22,11 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset-controller.h>
> +#include <linux/sizes.h>
>  #include <linux/types.h>
>  
>  #include "qcom_scm.h"
> +#include "qcom_tzmem.h"
>  
>  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
>  module_param(download_mode, bool, 0);
> @@ -41,6 +45,8 @@ struct qcom_scm {
>  	int scm_vote_count;
>  
>  	u64 dload_mode_addr;
> +
> +	struct qcom_tzmem_pool *mempool;
>  };
>  
>  struct qcom_scm_current_perm_info {
> @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
>  	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
>  		qcom_scm_disable_sdi();
>  
> +	ret = qcom_tzmem_enable(__scm->dev);
> +	if (ret)
> +		return dev_err_probe(__scm->dev, ret,
> +				     "Failed to enable the TrustZone memory allocator\n");
> +
> +	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);

As we're not moving from the callers freely allocating what they need,
to a fixed sized pool of 256kb. Please document why 256kb was choosen,
so that we have something to fall back on when someone runs out of this
space, or wonders "why not 128kb?".

Regards,
Bjorn

> +	if (IS_ERR(__scm->mempool))
> +		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> +				     "Failed to create the SCM memory pool\n");
> +
>  	/*
>  	 * Initialize the QSEECOM interface.
>  	 *
> -- 
> 2.40.1
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
  2024-02-05 18:28   ` Bartosz Golaszewski
@ 2024-02-18  3:41     ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:41 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Add a new Kconfig option for selecting the SHM Bridge mode of operation

The Kconfig option is the least significant bit of this patch. I guess
there isn't really a problem to describe, but let's at least mention
that we're switching TZ to shmbridge mode and all. 

> for the TrustZone memory allocator.
> 
> If enabled at build-time, it will still be checked for availability at
> run-time. If the architecture doesn't support SHM Bridge, the allocator
> will work just like in the default mode.

"default mode"...SHMBRIDGE is the default mode from this point onwards.

> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  drivers/firmware/qcom/Kconfig      | 10 +++++
>  drivers/firmware/qcom/qcom_tzmem.c | 65 +++++++++++++++++++++++++++++-
>  2 files changed, 74 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index d24d83223867..af6f895c5adf 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_DEFAULT
>  	  Use the default allocator mode. The memory is page-aligned, non-cachable
>  	  and contiguous.
>  
> +config QCOM_TZMEM_MODE_SHMBRIDGE
> +	bool "SHM Bridge"
> +	help
> +	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> +	  in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> +	  buffer.
> +
> +	  With this selected, all buffers passed to the TrustZone must be allocated
> +	  using the TZMem allocator or else the TrustZone will refuse to use them.

It's funny how this is the only place in the whole series I can find
this mentioned. One could from this statement guess that the eluding
scminvoke requires shmbridge and that this patch series exists solely
to facilitate the requirement stated in this paragraph.

Either this guess is correct and this should have been made clear in
the commit messages, or I'm guessing wrong here, in which case I need
some help to figure out why this series exists.

Regards,
Bjorn

> +
>  endchoice
>  
>  config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> index 44a062f2abd4..1ca3773263e5 100644
> --- a/drivers/firmware/qcom/qcom_tzmem.c
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -55,7 +55,70 @@ static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
>  
>  }
>  
> -#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
> +#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
> +
> +#include <linux/firmware/qcom/qcom_scm.h>
> +
> +#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
> +
> +static bool qcom_tzmem_using_shm_bridge;
> +
> +static int qcom_tzmem_init(void)
> +{
> +	int ret;
> +
> +	ret = qcom_scm_shm_bridge_enable();
> +	if (ret == -EOPNOTSUPP) {
> +		dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
> +		return 0;
> +	}
> +
> +	if (!ret)
> +		qcom_tzmem_using_shm_bridge = true;
> +
> +	return ret;
> +}
> +
> +static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
> +{
> +	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags, ns_perms;
> +	int ret;
> +
> +	if (!qcom_tzmem_using_shm_bridge)
> +		return 0;
> +
> +	ns_perms = (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ);
> +	pfn_and_ns_perm = (u64)pool->pbase | ns_perms;
> +	ipfn_and_s_perm = (u64)pool->pbase | ns_perms;
> +	size_and_flags = pool->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
> +
> +	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
> +	if (!handle)
> +		return -ENOMEM;
> +
> +	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
> +					 ipfn_and_s_perm, size_and_flags,
> +					 QCOM_SCM_VMID_HLOS, handle);
> +	if (ret)
> +		return ret;
> +
> +	pool->priv = no_free_ptr(handle);
> +
> +	return 0;
> +}
> +
> +static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
> +{
> +	u64 *handle = pool->priv;
> +
> +	if (!qcom_tzmem_using_shm_bridge)
> +		return;
> +
> +	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
> +	kfree(handle);
> +}
> +
> +#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
>  
>  /**
>   * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> -- 
> 2.40.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
@ 2024-02-18  3:41     ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:41 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Add a new Kconfig option for selecting the SHM Bridge mode of operation

The Kconfig option is the least significant bit of this patch. I guess
there isn't really a problem to describe, but let's at least mention
that we're switching TZ to shmbridge mode and all. 

> for the TrustZone memory allocator.
> 
> If enabled at build-time, it will still be checked for availability at
> run-time. If the architecture doesn't support SHM Bridge, the allocator
> will work just like in the default mode.

"default mode"...SHMBRIDGE is the default mode from this point onwards.

> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  drivers/firmware/qcom/Kconfig      | 10 +++++
>  drivers/firmware/qcom/qcom_tzmem.c | 65 +++++++++++++++++++++++++++++-
>  2 files changed, 74 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> index d24d83223867..af6f895c5adf 100644
> --- a/drivers/firmware/qcom/Kconfig
> +++ b/drivers/firmware/qcom/Kconfig
> @@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_DEFAULT
>  	  Use the default allocator mode. The memory is page-aligned, non-cachable
>  	  and contiguous.
>  
> +config QCOM_TZMEM_MODE_SHMBRIDGE
> +	bool "SHM Bridge"
> +	help
> +	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> +	  in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> +	  buffer.
> +
> +	  With this selected, all buffers passed to the TrustZone must be allocated
> +	  using the TZMem allocator or else the TrustZone will refuse to use them.

It's funny how this is the only place in the whole series I can find
this mentioned. One could from this statement guess that the eluding
scminvoke requires shmbridge and that this patch series exists solely
to facilitate the requirement stated in this paragraph.

Either this guess is correct and this should have been made clear in
the commit messages, or I'm guessing wrong here, in which case I need
some help to figure out why this series exists.

Regards,
Bjorn

> +
>  endchoice
>  
>  config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
> diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> index 44a062f2abd4..1ca3773263e5 100644
> --- a/drivers/firmware/qcom/qcom_tzmem.c
> +++ b/drivers/firmware/qcom/qcom_tzmem.c
> @@ -55,7 +55,70 @@ static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
>  
>  }
>  
> -#endif /* CONFIG_QCOM_TZMEM_MODE_DEFAULT */
> +#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
> +
> +#include <linux/firmware/qcom/qcom_scm.h>
> +
> +#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
> +
> +static bool qcom_tzmem_using_shm_bridge;
> +
> +static int qcom_tzmem_init(void)
> +{
> +	int ret;
> +
> +	ret = qcom_scm_shm_bridge_enable();
> +	if (ret == -EOPNOTSUPP) {
> +		dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
> +		return 0;
> +	}
> +
> +	if (!ret)
> +		qcom_tzmem_using_shm_bridge = true;
> +
> +	return ret;
> +}
> +
> +static int qcom_tzmem_init_pool(struct qcom_tzmem_pool *pool)
> +{
> +	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags, ns_perms;
> +	int ret;
> +
> +	if (!qcom_tzmem_using_shm_bridge)
> +		return 0;
> +
> +	ns_perms = (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ);
> +	pfn_and_ns_perm = (u64)pool->pbase | ns_perms;
> +	ipfn_and_s_perm = (u64)pool->pbase | ns_perms;
> +	size_and_flags = pool->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
> +
> +	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
> +	if (!handle)
> +		return -ENOMEM;
> +
> +	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
> +					 ipfn_and_s_perm, size_and_flags,
> +					 QCOM_SCM_VMID_HLOS, handle);
> +	if (ret)
> +		return ret;
> +
> +	pool->priv = no_free_ptr(handle);
> +
> +	return 0;
> +}
> +
> +static void qcom_tzmem_cleanup_pool(struct qcom_tzmem_pool *pool)
> +{
> +	u64 *handle = pool->priv;
> +
> +	if (!qcom_tzmem_using_shm_bridge)
> +		return;
> +
> +	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
> +	kfree(handle);
> +}
> +
> +#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
>  
>  /**
>   * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> -- 
> 2.40.1
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  2024-02-05 18:28   ` Bartosz Golaszewski
@ 2024-02-18  3:50     ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:50 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> The "memory protection" mechanism mentioned in the comment is the SHM
> Bridge. This is also the reason why we do not convert this call to using
> the TZ memory allocator.
> 

No, this mechanism predates shmbridge.

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 839773270a21..7ba5cff6e4e7 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
>  	struct qcom_scm_res res;
>  
>  	/*
> -	 * During the scm call memory protection will be enabled for the meta
> -	 * data blob, so make sure it's physically contiguous, 4K aligned and
> -	 * non-cachable to avoid XPU violations.

What this is saying is that the memory will be made unaccessible to
Linux, so it needs to be contiguous and aligned.

> +	 * During the SCM call the hypervisor will make the buffer containing
> +	 * the program data into an SHM Bridge.

Are you saying that the hypervisor will convert this memory to a
shmbridge, and then pass it to TrustZone?

> This is why we exceptionally
> +	 * must not use the TrustZone memory allocator here as - depending on
> +	 * Kconfig - it may already use the SHM Bridge mechanism internally.
> +	 *

"it may already"? You describe above that we shouldn't pass shmbridge
memory, and the other case never deals with shmbridges. So, I think you
can omit this part.

> +	 * If we pass a buffer that is already part of an SHM Bridge to this
> +	 * call, it will fail.

Could this be because the consumer of this buffer operates in EL2, and
not TZ?

Regards,
Bjorn

>  	 */
>  	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
>  				       GFP_KERNEL);
> -- 
> 2.40.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
@ 2024-02-18  3:50     ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-18  3:50 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> The "memory protection" mechanism mentioned in the comment is the SHM
> Bridge. This is also the reason why we do not convert this call to using
> the TZ memory allocator.
> 

No, this mechanism predates shmbridge.

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> ---
>  drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 839773270a21..7ba5cff6e4e7 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
>  	struct qcom_scm_res res;
>  
>  	/*
> -	 * During the scm call memory protection will be enabled for the meta
> -	 * data blob, so make sure it's physically contiguous, 4K aligned and
> -	 * non-cachable to avoid XPU violations.

What this is saying is that the memory will be made unaccessible to
Linux, so it needs to be contiguous and aligned.

> +	 * During the SCM call the hypervisor will make the buffer containing
> +	 * the program data into an SHM Bridge.

Are you saying that the hypervisor will convert this memory to a
shmbridge, and then pass it to TrustZone?

> This is why we exceptionally
> +	 * must not use the TrustZone memory allocator here as - depending on
> +	 * Kconfig - it may already use the SHM Bridge mechanism internally.
> +	 *

"it may already"? You describe above that we shouldn't pass shmbridge
memory, and the other case never deals with shmbridges. So, I think you
can omit this part.

> +	 * If we pass a buffer that is already part of an SHM Bridge to this
> +	 * call, it will fail.

Could this be because the consumer of this buffer operates in EL2, and
not TZ?

Regards,
Bjorn

>  	 */
>  	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
>  				       GFP_KERNEL);
> -- 
> 2.40.1
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
  2024-02-18  3:22     ` Bjorn Andersson
@ 2024-02-19 13:18       ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-19 13:18 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:22 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:27:59PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> [..]
> > diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> > new file mode 100644
> > index 000000000000..44a062f2abd4
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_tzmem.c
> > @@ -0,0 +1,302 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
>
> Could you please confirm that "-or-later" is intended?
>

No, it's not, should have been GPL-2.0-only.

> > +/*
> > + * Memory allocator for buffers shared with the TrustZone.
> > + *
> > + * Copyright (C) 2023 Linaro Ltd.
> > + */
> [..]
> > +/**
> > + * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> > + * @size: Size of the new pool in bytes.
> > + *
> > + * Create a new pool of memory suitable for sharing with the TrustZone.
> > + *
> > + * Must not be used in atomic context.
>
>  * Context: Describes whether the function can sleep, what locks it takes,
>  *          releases, or expects to be held. It can extend over multiple
>  *          lines.
>
> > + *
> > + * Returns:
> > + * New memory pool address or ERR_PTR() on error.
>
>  * Return: Describe the return value of function_name.
>
> both from:
> https://docs.kernel.org/doc-guide/kernel-doc.html#function-documentation
>

I can change it but "Returns:" works too.

Bart

> Regards,
> Bjorn

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator
@ 2024-02-19 13:18       ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-19 13:18 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:22 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:27:59PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> [..]
> > diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c
> > new file mode 100644
> > index 000000000000..44a062f2abd4
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_tzmem.c
> > @@ -0,0 +1,302 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
>
> Could you please confirm that "-or-later" is intended?
>

No, it's not, should have been GPL-2.0-only.

> > +/*
> > + * Memory allocator for buffers shared with the TrustZone.
> > + *
> > + * Copyright (C) 2023 Linaro Ltd.
> > + */
> [..]
> > +/**
> > + * qcom_tzmem_pool_new() - Create a new TZ memory pool.
> > + * @size: Size of the new pool in bytes.
> > + *
> > + * Create a new pool of memory suitable for sharing with the TrustZone.
> > + *
> > + * Must not be used in atomic context.
>
>  * Context: Describes whether the function can sleep, what locks it takes,
>  *          releases, or expects to be held. It can extend over multiple
>  *          lines.
>
> > + *
> > + * Returns:
> > + * New memory pool address or ERR_PTR() on error.
>
>  * Return: Describe the return value of function_name.
>
> both from:
> https://docs.kernel.org/doc-guide/kernel-doc.html#function-documentation
>

I can change it but "Returns:" works too.

Bart

> Regards,
> Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
  2024-02-17 19:58   ` Bjorn Andersson
@ 2024-02-19 15:17     ` Srinivas Kandagatla
  -1 siblings, 0 replies; 72+ messages in thread
From: Srinivas Kandagatla @ 2024-02-19 15:17 UTC (permalink / raw)
  To: Bjorn Andersson, Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Arnd Bergmann, linux-arm-msm, linux-kernel, linux-arm-kernel,
	kernel, Bartosz Golaszewski

On 17/02/2024 19:58, Bjorn Andersson wrote:
> On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>>
>> We've established the need for using separate secured memory pools for
>> SCM and QSEECOM
> 
> Where has this need been established, what is the actual problem you're
> solving with this series?

SHMbridge will restrict the amount of memory that TZ can see, making 
system more secure.

Need for having different pools makes this more scalable overall, so 
that different usecases can run seamlessly. ex: loading a TA and SCM calls.

> 
> Does SCM and QSEECOM, as it's implemented in the kernel today, not work
> satisfactory?
> 
>> as well as the upcoming scminvoke driver.
>>
> 
> Is smcinvoke driver upstreaming blocked by not transitioning the scm
> driver to a "secure memory pool"?
> 
> Is this happening now, or do we need to merge this series when that day
> comes?

SMCInvoke development is happening now, I see no reason for this 
patchset to wait for it.

This series can go as it is for two reasons.
1> improves system security in general
2> Hardware Wrapped key support patches also use this which are also in 
good shape and tested, ready to be merged.

> 
>> It's also become clear that in order to be future-proof, the new
>> allocator must be an abstraction layer of a higher level as the SHM
>> Bridge will not be the only memory protection mechanism that we'll see
>> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
>> allocator.
>>
>> Also to that end: the new allocator is its own module now and provides a
>> Kconfig choice menu for selecting the mode of operation (currently
>> default and SHM Bridge).
>>
>> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
>> remoteproc.
>>
> 
> It's reasonable to assume from mentioning of this (and Andrew's t-b),
> that the patchset has only been tested on recent platforms that indeed
> does implement shmbridge. Can you please share the list of other
> platforms that you've tested this on, and can you please get someone
> from IPQ to also give their r-b or t-b?

We will try to reachout to someone who has access to these.

thanks,
Srini

> 
> Regards,
> Bjorn
> 
>> v6 -> v7:
>> - fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR
>>
>> v5 -> v6:
>> Fixed two issues reported by autobuilders:
>> - add a fix for memory leaks in the qseecom driver as the first patch for
>>    easier backporting to the v6.6.y branch
>> - explicitly cast the bus address stored in a variable of type dma_addr_t
>>    to phys_addr_t expected by the genpool API
>>
>> v4 -> v5:
>> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
>> - remove a comment that's no longer useful
>> - collect tags
>>
>> v3 -> v4:
>> - include linux/sizes.h for SZ_X macros
>> - use dedicated RCU APIs to dereference radix tree slots
>> - fix kerneldocs
>> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>>    that creates the SHM bridge
>>
>> v2 -> v3:
>> - restore pool management and use separate pools for different users
>> - don't use the new allocator in qcom_scm_pas_init_image() as the
>>    TrustZone will create an SHM bridge for us here
>> - rewrite the entire series again for most part
>>
>> v1 -> v2:
>> - too many changes to list, it's a complete rewrite as explained above
>>
>> Bartosz Golaszewski (12):
>>    firmware: qcom: add a dedicated TrustZone buffer allocator
>>    firmware: qcom: scm: enable the TZ mem allocator
>>    firmware: qcom: scm: smc: switch to using the SCM allocator
>>    firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>>      allocator
>>    firmware: qcom: qseecom: convert to using the TZ allocator
>>    firmware: qcom: scm: add support for SHM bridge operations
>>    firmware: qcom: tzmem: enable SHM Bridge support
>>    firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>>    arm64: defconfig: enable SHM Bridge support for the TZ memory
>>      allocator
>>
>>   MAINTAINERS                                   |   8 +
>>   arch/arm64/configs/defconfig                  |   1 +
>>   drivers/firmware/qcom/Kconfig                 |  31 ++
>>   drivers/firmware/qcom/Makefile                |   1 +
>>   .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>>   drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>>   drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>>   drivers/firmware/qcom/qcom_scm.h              |   6 +
>>   drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>>   drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>>   include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>>   include/linux/firmware/qcom/qcom_scm.h        |   6 +
>>   include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>>   13 files changed, 685 insertions(+), 268 deletions(-)
>>   create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>>   create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>>   create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
>>
>> -- 
>> 2.40.1
>>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
@ 2024-02-19 15:17     ` Srinivas Kandagatla
  0 siblings, 0 replies; 72+ messages in thread
From: Srinivas Kandagatla @ 2024-02-19 15:17 UTC (permalink / raw)
  To: Bjorn Andersson, Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Arnd Bergmann, linux-arm-msm, linux-kernel, linux-arm-kernel,
	kernel, Bartosz Golaszewski

On 17/02/2024 19:58, Bjorn Andersson wrote:
> On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>>
>> We've established the need for using separate secured memory pools for
>> SCM and QSEECOM
> 
> Where has this need been established, what is the actual problem you're
> solving with this series?

SHMbridge will restrict the amount of memory that TZ can see, making 
system more secure.

Need for having different pools makes this more scalable overall, so 
that different usecases can run seamlessly. ex: loading a TA and SCM calls.

> 
> Does SCM and QSEECOM, as it's implemented in the kernel today, not work
> satisfactory?
> 
>> as well as the upcoming scminvoke driver.
>>
> 
> Is smcinvoke driver upstreaming blocked by not transitioning the scm
> driver to a "secure memory pool"?
> 
> Is this happening now, or do we need to merge this series when that day
> comes?

SMCInvoke development is happening now, I see no reason for this 
patchset to wait for it.

This series can go as it is for two reasons.
1> improves system security in general
2> Hardware Wrapped key support patches also use this which are also in 
good shape and tested, ready to be merged.

> 
>> It's also become clear that in order to be future-proof, the new
>> allocator must be an abstraction layer of a higher level as the SHM
>> Bridge will not be the only memory protection mechanism that we'll see
>> upstream. Hence the rename to TrustZone Memory rather than SCM Memory
>> allocator.
>>
>> Also to that end: the new allocator is its own module now and provides a
>> Kconfig choice menu for selecting the mode of operation (currently
>> default and SHM Bridge).
>>
>> Tested on sm8550 and sa8775p with the Inline Crypto Engine and
>> remoteproc.
>>
> 
> It's reasonable to assume from mentioning of this (and Andrew's t-b),
> that the patchset has only been tested on recent platforms that indeed
> does implement shmbridge. Can you please share the list of other
> platforms that you've tested this on, and can you please get someone
> from IPQ to also give their r-b or t-b?

We will try to reachout to someone who has access to these.

thanks,
Srini

> 
> Regards,
> Bjorn
> 
>> v6 -> v7:
>> - fix a Kconfig issue: TZMEM must select GENERIC_ALLOCATOR
>>
>> v5 -> v6:
>> Fixed two issues reported by autobuilders:
>> - add a fix for memory leaks in the qseecom driver as the first patch for
>>    easier backporting to the v6.6.y branch
>> - explicitly cast the bus address stored in a variable of type dma_addr_t
>>    to phys_addr_t expected by the genpool API
>>
>> v4 -> v5:
>> - fix the return value from qcom_tzmem_init() if SHM Bridge is not supported
>> - remove a comment that's no longer useful
>> - collect tags
>>
>> v3 -> v4:
>> - include linux/sizes.h for SZ_X macros
>> - use dedicated RCU APIs to dereference radix tree slots
>> - fix kerneldocs
>> - fix the comment in patch 14/15: it's the hypervisor, not the TrustZone
>>    that creates the SHM bridge
>>
>> v2 -> v3:
>> - restore pool management and use separate pools for different users
>> - don't use the new allocator in qcom_scm_pas_init_image() as the
>>    TrustZone will create an SHM bridge for us here
>> - rewrite the entire series again for most part
>>
>> v1 -> v2:
>> - too many changes to list, it's a complete rewrite as explained above
>>
>> Bartosz Golaszewski (12):
>>    firmware: qcom: add a dedicated TrustZone buffer allocator
>>    firmware: qcom: scm: enable the TZ mem allocator
>>    firmware: qcom: scm: smc: switch to using the SCM allocator
>>    firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
>>    firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ
>>      allocator
>>    firmware: qcom: qseecom: convert to using the TZ allocator
>>    firmware: qcom: scm: add support for SHM bridge operations
>>    firmware: qcom: tzmem: enable SHM Bridge support
>>    firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
>>    arm64: defconfig: enable SHM Bridge support for the TZ memory
>>      allocator
>>
>>   MAINTAINERS                                   |   8 +
>>   arch/arm64/configs/defconfig                  |   1 +
>>   drivers/firmware/qcom/Kconfig                 |  31 ++
>>   drivers/firmware/qcom/Makefile                |   1 +
>>   .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 281 +++++---------
>>   drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
>>   drivers/firmware/qcom/qcom_scm.c              | 179 +++++----
>>   drivers/firmware/qcom/qcom_scm.h              |   6 +
>>   drivers/firmware/qcom/qcom_tzmem.c            | 365 ++++++++++++++++++
>>   drivers/firmware/qcom/qcom_tzmem.h            |  13 +
>>   include/linux/firmware/qcom/qcom_qseecom.h    |   4 +-
>>   include/linux/firmware/qcom/qcom_scm.h        |   6 +
>>   include/linux/firmware/qcom/qcom_tzmem.h      |  28 ++
>>   13 files changed, 685 insertions(+), 268 deletions(-)
>>   create mode 100644 drivers/firmware/qcom/qcom_tzmem.c
>>   create mode 100644 drivers/firmware/qcom/qcom_tzmem.h
>>   create mode 100644 include/linux/firmware/qcom/qcom_tzmem.h
>>
>> -- 
>> 2.40.1
>>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-02-18  3:08     ` Bjorn Andersson
@ 2024-02-20  9:54       ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-20  9:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:08 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> > convert all users of it in the qseecom module to using the TZ allocator
> > for creating SCM call buffers.
>
> This reads as if this is removal of duplication, now that we have the TZ
> allocation. But wasn't there something about you not being able to mix
> and match shmbridge and non-shmbridge allocations in the interface, so
> this transition is actually required? Or did I get that wrong and this
> just reduction in duplication?
>

What is the question exactly? Yes it is required because once we
enable SHM bridge, "normal" memory will no longer be accepted for SCM
calls.

> > Together with using the cleanup macros,
> > it has the added benefit of a significant code shrink.
>
> That is true, but the move to using cleanup macros at the same time as
> changing the implementation makes it unnecessarily hard to reason about
> this patch.
>
> This patch would be much better if split in two.
>

I disagree. If we have a better interface in place, then let's use it
right away, otherwise it's just useless churn.

> > As this is
> > largely a module separate from the SCM driver, let's use a separate
> > memory pool.
> >
>
> This module is effectively used to read and write EFI variables today.
> Is that worth statically removing 256kb of DDR for? Is this done solely
> because it logically makes sense, or did you choose this for a reason?
>

Well, it will stop working (with SHM bridge enabled) if we don't. We
can possibly release the pool once we know we'll no longer need to
access EFI variables but I'm not sure if that makes sense? Or maybe
remove the pool after some time of driver inactivity and create a new
one when it's needed again?

Bart

[snip]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-02-20  9:54       ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-20  9:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:08 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> > convert all users of it in the qseecom module to using the TZ allocator
> > for creating SCM call buffers.
>
> This reads as if this is removal of duplication, now that we have the TZ
> allocation. But wasn't there something about you not being able to mix
> and match shmbridge and non-shmbridge allocations in the interface, so
> this transition is actually required? Or did I get that wrong and this
> just reduction in duplication?
>

What is the question exactly? Yes it is required because once we
enable SHM bridge, "normal" memory will no longer be accepted for SCM
calls.

> > Together with using the cleanup macros,
> > it has the added benefit of a significant code shrink.
>
> That is true, but the move to using cleanup macros at the same time as
> changing the implementation makes it unnecessarily hard to reason about
> this patch.
>
> This patch would be much better if split in two.
>

I disagree. If we have a better interface in place, then let's use it
right away, otherwise it's just useless churn.

> > As this is
> > largely a module separate from the SCM driver, let's use a separate
> > memory pool.
> >
>
> This module is effectively used to read and write EFI variables today.
> Is that worth statically removing 256kb of DDR for? Is this done solely
> because it logically makes sense, or did you choose this for a reason?
>

Well, it will stop working (with SHM bridge enabled) if we don't. We
can possibly release the pool once we know we'll no longer need to
access EFI variables but I'm not sure if that makes sense? Or maybe
remove the pool after some time of driver inactivity and create a new
one when it's needed again?

Bart

[snip]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
  2024-02-18  3:25     ` Bjorn Andersson
@ 2024-02-21 18:39       ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-21 18:39 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:25 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Select the TrustZone memory allocator in Kconfig and create a pool of
> > memory shareable with the TrustZone when probing the SCM driver.
> >
> > This will allow a gradual conversion of all relevant SCM calls to using
> > the dedicated allocator.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> > Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> > Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> > Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> > ---
> >  drivers/firmware/qcom/Kconfig    |  1 +
> >  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
> >  2 files changed, 17 insertions(+)
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index f18686edf415..d24d83223867 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -7,6 +7,7 @@
> >  menu "Qualcomm firmware drivers"
> >
> >  config QCOM_SCM
> > +     select QCOM_TZMEM
> >       tristate
> >
> >  config QCOM_TZMEM
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 520de9b5633a..0d4c028be0c1 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -8,8 +8,10 @@
> >  #include <linux/completion.h>
> >  #include <linux/cpumask.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/err.h>
> >  #include <linux/export.h>
> >  #include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/firmware/qcom/qcom_tzmem.h>
> >  #include <linux/init.h>
> >  #include <linux/interconnect.h>
> >  #include <linux/interrupt.h>
> > @@ -20,9 +22,11 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/reset-controller.h>
> > +#include <linux/sizes.h>
> >  #include <linux/types.h>
> >
> >  #include "qcom_scm.h"
> > +#include "qcom_tzmem.h"
> >
> >  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
> >  module_param(download_mode, bool, 0);
> > @@ -41,6 +45,8 @@ struct qcom_scm {
> >       int scm_vote_count;
> >
> >       u64 dload_mode_addr;
> > +
> > +     struct qcom_tzmem_pool *mempool;
> >  };
> >
> >  struct qcom_scm_current_perm_info {
> > @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> >       if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
> >               qcom_scm_disable_sdi();
> >
> > +     ret = qcom_tzmem_enable(__scm->dev);
> > +     if (ret)
> > +             return dev_err_probe(__scm->dev, ret,
> > +                                  "Failed to enable the TrustZone memory allocator\n");
> > +
> > +     __scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
>
> As we're not moving from the callers freely allocating what they need,
> to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> so that we have something to fall back on when someone runs out of this
> space, or wonders "why not 128kb?".
>

If you worry about these pools being taken out of the total memory and
prefer to have a way to avoid it, I was thinking about another
build-time mode for the allocator - one where there's no pool but it
just allocates chunks using dma_alloc_coherent() like before and pool
size is ignored. Does it sound good?

Bart

> Regards,
> Bjorn
>
> > +     if (IS_ERR(__scm->mempool))
> > +             return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> > +                                  "Failed to create the SCM memory pool\n");
> > +
> >       /*
> >        * Initialize the QSEECOM interface.
> >        *
> > --
> > 2.40.1
> >

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-02-21 18:39       ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-21 18:39 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:25 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Select the TrustZone memory allocator in Kconfig and create a pool of
> > memory shareable with the TrustZone when probing the SCM driver.
> >
> > This will allow a gradual conversion of all relevant SCM calls to using
> > the dedicated allocator.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> > Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> > Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> > Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> > ---
> >  drivers/firmware/qcom/Kconfig    |  1 +
> >  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
> >  2 files changed, 17 insertions(+)
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index f18686edf415..d24d83223867 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -7,6 +7,7 @@
> >  menu "Qualcomm firmware drivers"
> >
> >  config QCOM_SCM
> > +     select QCOM_TZMEM
> >       tristate
> >
> >  config QCOM_TZMEM
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 520de9b5633a..0d4c028be0c1 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -8,8 +8,10 @@
> >  #include <linux/completion.h>
> >  #include <linux/cpumask.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/err.h>
> >  #include <linux/export.h>
> >  #include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/firmware/qcom/qcom_tzmem.h>
> >  #include <linux/init.h>
> >  #include <linux/interconnect.h>
> >  #include <linux/interrupt.h>
> > @@ -20,9 +22,11 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/reset-controller.h>
> > +#include <linux/sizes.h>
> >  #include <linux/types.h>
> >
> >  #include "qcom_scm.h"
> > +#include "qcom_tzmem.h"
> >
> >  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
> >  module_param(download_mode, bool, 0);
> > @@ -41,6 +45,8 @@ struct qcom_scm {
> >       int scm_vote_count;
> >
> >       u64 dload_mode_addr;
> > +
> > +     struct qcom_tzmem_pool *mempool;
> >  };
> >
> >  struct qcom_scm_current_perm_info {
> > @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> >       if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
> >               qcom_scm_disable_sdi();
> >
> > +     ret = qcom_tzmem_enable(__scm->dev);
> > +     if (ret)
> > +             return dev_err_probe(__scm->dev, ret,
> > +                                  "Failed to enable the TrustZone memory allocator\n");
> > +
> > +     __scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
>
> As we're not moving from the callers freely allocating what they need,
> to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> so that we have something to fall back on when someone runs out of this
> space, or wonders "why not 128kb?".
>

If you worry about these pools being taken out of the total memory and
prefer to have a way to avoid it, I was thinking about another
build-time mode for the allocator - one where there's no pool but it
just allocates chunks using dma_alloc_coherent() like before and pool
size is ignored. Does it sound good?

Bart

> Regards,
> Bjorn
>
> > +     if (IS_ERR(__scm->mempool))
> > +             return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> > +                                  "Failed to create the SCM memory pool\n");
> > +
> >       /*
> >        * Initialize the QSEECOM interface.
> >        *
> > --
> > 2.40.1
> >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
  2024-02-18  3:41     ` Bjorn Andersson
@ 2024-02-21 19:06       ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-21 19:06 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:41 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Add a new Kconfig option for selecting the SHM Bridge mode of operation
>
> The Kconfig option is the least significant bit of this patch. I guess
> there isn't really a problem to describe, but let's at least mention
> that we're switching TZ to shmbridge mode and all.
>
> > for the TrustZone memory allocator.
> >
> > If enabled at build-time, it will still be checked for availability at
> > run-time. If the architecture doesn't support SHM Bridge, the allocator
> > will work just like in the default mode.
>
> "default mode"...SHMBRIDGE is the default mode from this point onwards.
>

Well, it is starting with patch 12/12 and only with arm64 defconfig.
The Kconfig *default* is still the regular non-SHM bridge pool. I'll
work on the naming convention.

Bart

[snip]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
@ 2024-02-21 19:06       ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-21 19:06 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:41 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Add a new Kconfig option for selecting the SHM Bridge mode of operation
>
> The Kconfig option is the least significant bit of this patch. I guess
> there isn't really a problem to describe, but let's at least mention
> that we're switching TZ to shmbridge mode and all.
>
> > for the TrustZone memory allocator.
> >
> > If enabled at build-time, it will still be checked for availability at
> > run-time. If the architecture doesn't support SHM Bridge, the allocator
> > will work just like in the default mode.
>
> "default mode"...SHMBRIDGE is the default mode from this point onwards.
>

Well, it is starting with patch 12/12 and only with arm64 defconfig.
The Kconfig *default* is still the regular non-SHM bridge pool. I'll
work on the naming convention.

Bart

[snip]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
  2024-02-21 18:39       ` Bartosz Golaszewski
@ 2024-02-22 13:54         ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-22 13:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Wed, Feb 21, 2024 at 7:39 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Sun, Feb 18, 2024 at 4:25 AM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > >
> > > Select the TrustZone memory allocator in Kconfig and create a pool of
> > > memory shareable with the TrustZone when probing the SCM driver.
> > >
> > > This will allow a gradual conversion of all relevant SCM calls to using
> > > the dedicated allocator.
> > >
> > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > > Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> > > Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> > > Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> > > Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> > > ---
> > >  drivers/firmware/qcom/Kconfig    |  1 +
> > >  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
> > >  2 files changed, 17 insertions(+)
> > >
> > > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > > index f18686edf415..d24d83223867 100644
> > > --- a/drivers/firmware/qcom/Kconfig
> > > +++ b/drivers/firmware/qcom/Kconfig
> > > @@ -7,6 +7,7 @@
> > >  menu "Qualcomm firmware drivers"
> > >
> > >  config QCOM_SCM
> > > +     select QCOM_TZMEM
> > >       tristate
> > >
> > >  config QCOM_TZMEM
> > > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > > index 520de9b5633a..0d4c028be0c1 100644
> > > --- a/drivers/firmware/qcom/qcom_scm.c
> > > +++ b/drivers/firmware/qcom/qcom_scm.c
> > > @@ -8,8 +8,10 @@
> > >  #include <linux/completion.h>
> > >  #include <linux/cpumask.h>
> > >  #include <linux/dma-mapping.h>
> > > +#include <linux/err.h>
> > >  #include <linux/export.h>
> > >  #include <linux/firmware/qcom/qcom_scm.h>
> > > +#include <linux/firmware/qcom/qcom_tzmem.h>
> > >  #include <linux/init.h>
> > >  #include <linux/interconnect.h>
> > >  #include <linux/interrupt.h>
> > > @@ -20,9 +22,11 @@
> > >  #include <linux/of_platform.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/reset-controller.h>
> > > +#include <linux/sizes.h>
> > >  #include <linux/types.h>
> > >
> > >  #include "qcom_scm.h"
> > > +#include "qcom_tzmem.h"
> > >
> > >  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
> > >  module_param(download_mode, bool, 0);
> > > @@ -41,6 +45,8 @@ struct qcom_scm {
> > >       int scm_vote_count;
> > >
> > >       u64 dload_mode_addr;
> > > +
> > > +     struct qcom_tzmem_pool *mempool;
> > >  };
> > >
> > >  struct qcom_scm_current_perm_info {
> > > @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> > >       if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
> > >               qcom_scm_disable_sdi();
> > >
> > > +     ret = qcom_tzmem_enable(__scm->dev);
> > > +     if (ret)
> > > +             return dev_err_probe(__scm->dev, ret,
> > > +                                  "Failed to enable the TrustZone memory allocator\n");
> > > +
> > > +     __scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
> >
> > As we're not moving from the callers freely allocating what they need,
> > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > so that we have something to fall back on when someone runs out of this
> > space, or wonders "why not 128kb?".
> >
>
> If you worry about these pools being taken out of the total memory and
> prefer to have a way to avoid it, I was thinking about another
> build-time mode for the allocator - one where there's no pool but it
> just allocates chunks using dma_alloc_coherent() like before and pool
> size is ignored. Does it sound good?
>

Or we could even have an argument for the initial size of the pool and
then once it's exhausted, we'd add a new chunk (maybe twice the size?)
and so on.

Bart

> Bart
>
> > Regards,
> > Bjorn
> >
> > > +     if (IS_ERR(__scm->mempool))
> > > +             return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> > > +                                  "Failed to create the SCM memory pool\n");
> > > +
> > >       /*
> > >        * Initialize the QSEECOM interface.
> > >        *
> > > --
> > > 2.40.1
> > >

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-02-22 13:54         ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-22 13:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Wed, Feb 21, 2024 at 7:39 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Sun, Feb 18, 2024 at 4:25 AM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:00PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > >
> > > Select the TrustZone memory allocator in Kconfig and create a pool of
> > > memory shareable with the TrustZone when probing the SCM driver.
> > >
> > > This will allow a gradual conversion of all relevant SCM calls to using
> > > the dedicated allocator.
> > >
> > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > > Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
> > > Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
> > > Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
> > > Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
> > > ---
> > >  drivers/firmware/qcom/Kconfig    |  1 +
> > >  drivers/firmware/qcom/qcom_scm.c | 16 ++++++++++++++++
> > >  2 files changed, 17 insertions(+)
> > >
> > > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > > index f18686edf415..d24d83223867 100644
> > > --- a/drivers/firmware/qcom/Kconfig
> > > +++ b/drivers/firmware/qcom/Kconfig
> > > @@ -7,6 +7,7 @@
> > >  menu "Qualcomm firmware drivers"
> > >
> > >  config QCOM_SCM
> > > +     select QCOM_TZMEM
> > >       tristate
> > >
> > >  config QCOM_TZMEM
> > > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > > index 520de9b5633a..0d4c028be0c1 100644
> > > --- a/drivers/firmware/qcom/qcom_scm.c
> > > +++ b/drivers/firmware/qcom/qcom_scm.c
> > > @@ -8,8 +8,10 @@
> > >  #include <linux/completion.h>
> > >  #include <linux/cpumask.h>
> > >  #include <linux/dma-mapping.h>
> > > +#include <linux/err.h>
> > >  #include <linux/export.h>
> > >  #include <linux/firmware/qcom/qcom_scm.h>
> > > +#include <linux/firmware/qcom/qcom_tzmem.h>
> > >  #include <linux/init.h>
> > >  #include <linux/interconnect.h>
> > >  #include <linux/interrupt.h>
> > > @@ -20,9 +22,11 @@
> > >  #include <linux/of_platform.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/reset-controller.h>
> > > +#include <linux/sizes.h>
> > >  #include <linux/types.h>
> > >
> > >  #include "qcom_scm.h"
> > > +#include "qcom_tzmem.h"
> > >
> > >  static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
> > >  module_param(download_mode, bool, 0);
> > > @@ -41,6 +45,8 @@ struct qcom_scm {
> > >       int scm_vote_count;
> > >
> > >       u64 dload_mode_addr;
> > > +
> > > +     struct qcom_tzmem_pool *mempool;
> > >  };
> > >
> > >  struct qcom_scm_current_perm_info {
> > > @@ -1887,6 +1893,16 @@ static int qcom_scm_probe(struct platform_device *pdev)
> > >       if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
> > >               qcom_scm_disable_sdi();
> > >
> > > +     ret = qcom_tzmem_enable(__scm->dev);
> > > +     if (ret)
> > > +             return dev_err_probe(__scm->dev, ret,
> > > +                                  "Failed to enable the TrustZone memory allocator\n");
> > > +
> > > +     __scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, SZ_256K);
> >
> > As we're not moving from the callers freely allocating what they need,
> > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > so that we have something to fall back on when someone runs out of this
> > space, or wonders "why not 128kb?".
> >
>
> If you worry about these pools being taken out of the total memory and
> prefer to have a way to avoid it, I was thinking about another
> build-time mode for the allocator - one where there's no pool but it
> just allocates chunks using dma_alloc_coherent() like before and pool
> size is ignored. Does it sound good?
>

Or we could even have an argument for the initial size of the pool and
then once it's exhausted, we'd add a new chunk (maybe twice the size?)
and so on.

Bart

> Bart
>
> > Regards,
> > Bjorn
> >
> > > +     if (IS_ERR(__scm->mempool))
> > > +             return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
> > > +                                  "Failed to create the SCM memory pool\n");
> > > +
> > >       /*
> > >        * Initialize the QSEECOM interface.
> > >        *
> > > --
> > > 2.40.1
> > >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
  2024-02-18  3:41     ` Bjorn Andersson
@ 2024-02-22 16:24       ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-22 16:24 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:41 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >

[snip]

> >
> > +config QCOM_TZMEM_MODE_SHMBRIDGE
> > +     bool "SHM Bridge"
> > +     help
> > +       Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> > +       in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> > +       buffer.
> > +
> > +       With this selected, all buffers passed to the TrustZone must be allocated
> > +       using the TZMem allocator or else the TrustZone will refuse to use them.
>
> It's funny how this is the only place in the whole series I can find
> this mentioned. One could from this statement guess that the eluding
> scminvoke requires shmbridge and that this patch series exists solely
> to facilitate the requirement stated in this paragraph.
>

Yes, scminvoke *requires* SHM bridge. So does the wrapped key support.
No, this is not the only reason as - as stated by Srini - it improves
overall safety of the system for all users.

> Either this guess is correct and this should have been made clear in
> the commit messages, or I'm guessing wrong here, in which case I need
> some help to figure out why this series exists.
>

This series exists and IMO should get upstream soon to facilitate
adding new security features (in addition to improving existing ones).
As there are at least two such features in development (mentioned
above) pushing this series upstream will make it easier to develop
them independently.

Bart

[snip]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
@ 2024-02-22 16:24       ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-22 16:24 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Feb 18, 2024 at 4:41 AM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >

[snip]

> >
> > +config QCOM_TZMEM_MODE_SHMBRIDGE
> > +     bool "SHM Bridge"
> > +     help
> > +       Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> > +       in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> > +       buffer.
> > +
> > +       With this selected, all buffers passed to the TrustZone must be allocated
> > +       using the TZMem allocator or else the TrustZone will refuse to use them.
>
> It's funny how this is the only place in the whole series I can find
> this mentioned. One could from this statement guess that the eluding
> scminvoke requires shmbridge and that this patch series exists solely
> to facilitate the requirement stated in this paragraph.
>

Yes, scminvoke *requires* SHM bridge. So does the wrapped key support.
No, this is not the only reason as - as stated by Srini - it improves
overall safety of the system for all users.

> Either this guess is correct and this should have been made clear in
> the commit messages, or I'm guessing wrong here, in which case I need
> some help to figure out why this series exists.
>

This series exists and IMO should get upstream soon to facilitate
adding new security features (in addition to improving existing ones).
As there are at least two such features in development (mentioned
above) pushing this series upstream will make it easier to develop
them independently.

Bart

[snip]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
  2024-02-22 13:54         ` Bartosz Golaszewski
@ 2024-02-26 10:29           ` Kuldeep Singh
  -1 siblings, 0 replies; 72+ messages in thread
From: Kuldeep Singh @ 2024-02-26 10:29 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Bjorn Andersson, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

> > > As we're not moving from the callers freely allocating what they need,
> > > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > > so that we have something to fall back on when someone runs out of this
> > > space, or wonders "why not 128kb?".
> > >
> >
> > If you worry about these pools being taken out of the total memory and
> > prefer to have a way to avoid it, I was thinking about another
> > build-time mode for the allocator - one where there's no pool but it
> > just allocates chunks using dma_alloc_coherent() like before and pool
> > size is ignored. Does it sound good?
> >
> 
> Or we could even have an argument for the initial size of the pool and
> then once it's exhausted, we'd add a new chunk (maybe twice the size?)
> and so on.

Hi Bartosz,

Thanks for shmbridge patch series. Few questions.

	1. With current design of every client maintaining it's own pool,
	For any target, we might end up occupying lot more space by
	different clients than we actually need.

	2. Also, there's no option to configure pool size for each client at
	runtime level and a fixed 256K value is chosen for qcom_scm/qseecom.
	Pool size will be same for each target and thus making it less
	scalabale if there's adjustment needed at target specific level.
	Ex: For a low DDR memory target, pool size should scale down accordingly
	as 256K will become a big ask but there's no way to choose specific pool
	size for just one target.
		2.1 One way to do configure custom pool size value is to add new
		property in qcom_scm/qseecom or client DT node and then create
		pool of size with this provided value. Though there are ways to
		tackle this, but still clients specifying it's own pool size
		will always fetch more CMA region than what is actually needed.

Can you please share your ideas as well for upcoming version.

Regards
Kuldeep

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-02-26 10:29           ` Kuldeep Singh
  0 siblings, 0 replies; 72+ messages in thread
From: Kuldeep Singh @ 2024-02-26 10:29 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Bjorn Andersson, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

> > > As we're not moving from the callers freely allocating what they need,
> > > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > > so that we have something to fall back on when someone runs out of this
> > > space, or wonders "why not 128kb?".
> > >
> >
> > If you worry about these pools being taken out of the total memory and
> > prefer to have a way to avoid it, I was thinking about another
> > build-time mode for the allocator - one where there's no pool but it
> > just allocates chunks using dma_alloc_coherent() like before and pool
> > size is ignored. Does it sound good?
> >
> 
> Or we could even have an argument for the initial size of the pool and
> then once it's exhausted, we'd add a new chunk (maybe twice the size?)
> and so on.

Hi Bartosz,

Thanks for shmbridge patch series. Few questions.

	1. With current design of every client maintaining it's own pool,
	For any target, we might end up occupying lot more space by
	different clients than we actually need.

	2. Also, there's no option to configure pool size for each client at
	runtime level and a fixed 256K value is chosen for qcom_scm/qseecom.
	Pool size will be same for each target and thus making it less
	scalabale if there's adjustment needed at target specific level.
	Ex: For a low DDR memory target, pool size should scale down accordingly
	as 256K will become a big ask but there's no way to choose specific pool
	size for just one target.
		2.1 One way to do configure custom pool size value is to add new
		property in qcom_scm/qseecom or client DT node and then create
		pool of size with this provided value. Though there are ways to
		tackle this, but still clients specifying it's own pool size
		will always fetch more CMA region than what is actually needed.

Can you please share your ideas as well for upcoming version.

Regards
Kuldeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
  2024-02-26 10:29           ` Kuldeep Singh
@ 2024-02-27  8:24             ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-27  8:24 UTC (permalink / raw)
  To: Kuldeep Singh
  Cc: Bjorn Andersson, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 26, 2024 at 11:30 AM Kuldeep Singh
<quic_kuldsing@quicinc.com> wrote:
>
> > > > As we're not moving from the callers freely allocating what they need,
> > > > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > > > so that we have something to fall back on when someone runs out of this
> > > > space, or wonders "why not 128kb?".
> > > >
> > >
> > > If you worry about these pools being taken out of the total memory and
> > > prefer to have a way to avoid it, I was thinking about another
> > > build-time mode for the allocator - one where there's no pool but it
> > > just allocates chunks using dma_alloc_coherent() like before and pool
> > > size is ignored. Does it sound good?
> > >
> >
> > Or we could even have an argument for the initial size of the pool and
> > then once it's exhausted, we'd add a new chunk (maybe twice the size?)
> > and so on.
>
> Hi Bartosz,
>
> Thanks for shmbridge patch series. Few questions.
>
>         1. With current design of every client maintaining it's own pool,
>         For any target, we might end up occupying lot more space by
>         different clients than we actually need.
>

Technically there are only up to two, three in the future with scminvoke.

>         2. Also, there's no option to configure pool size for each client at
>         runtime level and a fixed 256K value is chosen for qcom_scm/qseecom.

You mean via a module parameter?

>         Pool size will be same for each target and thus making it less
>         scalabale if there's adjustment needed at target specific level.
>         Ex: For a low DDR memory target, pool size should scale down accordingly
>         as 256K will become a big ask but there's no way to choose specific pool
>         size for just one target.

Do we really have any low-DDR platforms that would be affected by this
change? Even for db401c the 256K is a tiny fraction of the total
memory.

>                 2.1 One way to do configure custom pool size value is to add new
>                 property in qcom_scm/qseecom or client DT node and then create
>                 pool of size with this provided value. Though there are ways to
>                 tackle this, but still clients specifying it's own pool size
>                 will always fetch more CMA region than what is actually needed.
>
> Can you please share your ideas as well for upcoming version.
>

I will propose a new solution with several configuration options for
pools. Including scaling the pool size as needed. I hope to send it
this week.

Bart

> Regards
> Kuldeep

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-02-27  8:24             ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-02-27  8:24 UTC (permalink / raw)
  To: Kuldeep Singh
  Cc: Bjorn Andersson, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

On Mon, Feb 26, 2024 at 11:30 AM Kuldeep Singh
<quic_kuldsing@quicinc.com> wrote:
>
> > > > As we're not moving from the callers freely allocating what they need,
> > > > to a fixed sized pool of 256kb. Please document why 256kb was choosen,
> > > > so that we have something to fall back on when someone runs out of this
> > > > space, or wonders "why not 128kb?".
> > > >
> > >
> > > If you worry about these pools being taken out of the total memory and
> > > prefer to have a way to avoid it, I was thinking about another
> > > build-time mode for the allocator - one where there's no pool but it
> > > just allocates chunks using dma_alloc_coherent() like before and pool
> > > size is ignored. Does it sound good?
> > >
> >
> > Or we could even have an argument for the initial size of the pool and
> > then once it's exhausted, we'd add a new chunk (maybe twice the size?)
> > and so on.
>
> Hi Bartosz,
>
> Thanks for shmbridge patch series. Few questions.
>
>         1. With current design of every client maintaining it's own pool,
>         For any target, we might end up occupying lot more space by
>         different clients than we actually need.
>

Technically there are only up to two, three in the future with scminvoke.

>         2. Also, there's no option to configure pool size for each client at
>         runtime level and a fixed 256K value is chosen for qcom_scm/qseecom.

You mean via a module parameter?

>         Pool size will be same for each target and thus making it less
>         scalabale if there's adjustment needed at target specific level.
>         Ex: For a low DDR memory target, pool size should scale down accordingly
>         as 256K will become a big ask but there's no way to choose specific pool
>         size for just one target.

Do we really have any low-DDR platforms that would be affected by this
change? Even for db401c the 256K is a tiny fraction of the total
memory.

>                 2.1 One way to do configure custom pool size value is to add new
>                 property in qcom_scm/qseecom or client DT node and then create
>                 pool of size with this provided value. Though there are ways to
>                 tackle this, but still clients specifying it's own pool size
>                 will always fetch more CMA region than what is actually needed.
>
> Can you please share your ideas as well for upcoming version.
>

I will propose a new solution with several configuration options for
pools. Including scaling the pool size as needed. I hope to send it
this week.

Bart

> Regards
> Kuldeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
  2024-02-19 15:17     ` Srinivas Kandagatla
@ 2024-02-27 16:32       ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-27 16:32 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Bartosz Golaszewski, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On Mon, Feb 19, 2024 at 03:17:24PM +0000, Srinivas Kandagatla wrote:
> On 17/02/2024 19:58, Bjorn Andersson wrote:
> > On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > > 
> > > We've established the need for using separate secured memory pools for
> > > SCM and QSEECOM
> > 
> > Where has this need been established, what is the actual problem you're
> > solving with this series?
> 
> SHMbridge will restrict the amount of memory that TZ can see, making system
> more secure.
> 

Then tell me this in the cover letter and commit messages.

> Need for having different pools makes this more scalable overall, so that
> different usecases can run seamlessly. ex: loading a TA and SCM calls.
> 

How is it more scalable to give each "client" a chunk of 256KB instead
of them sharing a pool of ~4GB memory?

> > 
> > Does SCM and QSEECOM, as it's implemented in the kernel today, not work
> > satisfactory?
> > 
> > > as well as the upcoming scminvoke driver.
> > > 
> > 
> > Is smcinvoke driver upstreaming blocked by not transitioning the scm
> > driver to a "secure memory pool"?
> > 
> > Is this happening now, or do we need to merge this series when that day
> > comes?
> 
> SMCInvoke development is happening now, I see no reason for this patchset to
> wait for it.
> 

As presented, I see no reason to merge this series.

> This series can go as it is for two reasons.
> 1> improves system security in general
> 2> Hardware Wrapped key support patches also use this which are also in good
> shape and tested, ready to be merged.
> 

Then tell me this in the cover letter and commit messages!


It's not sufficient that I happen to know the answer to these questions,
neither community nor maintainer should not have to guess these things.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support
@ 2024-02-27 16:32       ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-27 16:32 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Bartosz Golaszewski, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On Mon, Feb 19, 2024 at 03:17:24PM +0000, Srinivas Kandagatla wrote:
> On 17/02/2024 19:58, Bjorn Andersson wrote:
> > On Mon, Feb 05, 2024 at 07:27:58PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > > 
> > > We've established the need for using separate secured memory pools for
> > > SCM and QSEECOM
> > 
> > Where has this need been established, what is the actual problem you're
> > solving with this series?
> 
> SHMbridge will restrict the amount of memory that TZ can see, making system
> more secure.
> 

Then tell me this in the cover letter and commit messages.

> Need for having different pools makes this more scalable overall, so that
> different usecases can run seamlessly. ex: loading a TA and SCM calls.
> 

How is it more scalable to give each "client" a chunk of 256KB instead
of them sharing a pool of ~4GB memory?

> > 
> > Does SCM and QSEECOM, as it's implemented in the kernel today, not work
> > satisfactory?
> > 
> > > as well as the upcoming scminvoke driver.
> > > 
> > 
> > Is smcinvoke driver upstreaming blocked by not transitioning the scm
> > driver to a "secure memory pool"?
> > 
> > Is this happening now, or do we need to merge this series when that day
> > comes?
> 
> SMCInvoke development is happening now, I see no reason for this patchset to
> wait for it.
> 

As presented, I see no reason to merge this series.

> This series can go as it is for two reasons.
> 1> improves system security in general
> 2> Hardware Wrapped key support patches also use this which are also in good
> shape and tested, ready to be merged.
> 

Then tell me this in the cover letter and commit messages!


It's not sufficient that I happen to know the answer to these questions,
neither community nor maintainer should not have to guess these things.

Regards,
Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-02-20  9:54       ` Bartosz Golaszewski
@ 2024-02-27 16:53         ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-27 16:53 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Tue, Feb 20, 2024 at 10:54:02AM +0100, Bartosz Golaszewski wrote:
> On Sun, Feb 18, 2024 at 4:08 AM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > >
> > > Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> > > convert all users of it in the qseecom module to using the TZ allocator
> > > for creating SCM call buffers.
> >
> > This reads as if this is removal of duplication, now that we have the TZ
> > allocation. But wasn't there something about you not being able to mix
> > and match shmbridge and non-shmbridge allocations in the interface, so
> > this transition is actually required? Or did I get that wrong and this
> > just reduction in duplication?
> >
> 
> What is the question exactly? Yes it is required because once we
> enable SHM bridge, "normal" memory will no longer be accepted for SCM
> calls.
> 

This fact is not covered anywhere in the series.

> > > Together with using the cleanup macros,
> > > it has the added benefit of a significant code shrink.
> >
> > That is true, but the move to using cleanup macros at the same time as
> > changing the implementation makes it unnecessarily hard to reason about
> > this patch.
> >
> > This patch would be much better if split in two.
> >
> 
> I disagree. If we have a better interface in place, then let's use it
> right away, otherwise it's just useless churn.
> 

The functional change and the use of cleanup macros, could be done
independently of each other, each one fully beneficial on their own.

As such I don't find it hard to claim that they are two independent
changes.

> > > As this is
> > > largely a module separate from the SCM driver, let's use a separate
> > > memory pool.
> > >
> >
> > This module is effectively used to read and write EFI variables today.
> > Is that worth statically removing 256kb of DDR for? Is this done solely
> > because it logically makes sense, or did you choose this for a reason?
> >
> 
> Well, it will stop working (with SHM bridge enabled) if we don't. We
> can possibly release the pool once we know we'll no longer need to
> access EFI variables but I'm not sure if that makes sense? Or maybe
> remove the pool after some time of driver inactivity and create a new
> one when it's needed again?
> 

Sounds like a good motivation to me, let's document it so that the next
guy understand why this was done.

Regards,
Bjorn

> Bart
> 
> [snip]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-02-27 16:53         ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-27 16:53 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Tue, Feb 20, 2024 at 10:54:02AM +0100, Bartosz Golaszewski wrote:
> On Sun, Feb 18, 2024 at 4:08 AM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:06PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > >
> > > Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and
> > > convert all users of it in the qseecom module to using the TZ allocator
> > > for creating SCM call buffers.
> >
> > This reads as if this is removal of duplication, now that we have the TZ
> > allocation. But wasn't there something about you not being able to mix
> > and match shmbridge and non-shmbridge allocations in the interface, so
> > this transition is actually required? Or did I get that wrong and this
> > just reduction in duplication?
> >
> 
> What is the question exactly? Yes it is required because once we
> enable SHM bridge, "normal" memory will no longer be accepted for SCM
> calls.
> 

This fact is not covered anywhere in the series.

> > > Together with using the cleanup macros,
> > > it has the added benefit of a significant code shrink.
> >
> > That is true, but the move to using cleanup macros at the same time as
> > changing the implementation makes it unnecessarily hard to reason about
> > this patch.
> >
> > This patch would be much better if split in two.
> >
> 
> I disagree. If we have a better interface in place, then let's use it
> right away, otherwise it's just useless churn.
> 

The functional change and the use of cleanup macros, could be done
independently of each other, each one fully beneficial on their own.

As such I don't find it hard to claim that they are two independent
changes.

> > > As this is
> > > largely a module separate from the SCM driver, let's use a separate
> > > memory pool.
> > >
> >
> > This module is effectively used to read and write EFI variables today.
> > Is that worth statically removing 256kb of DDR for? Is this done solely
> > because it logically makes sense, or did you choose this for a reason?
> >
> 
> Well, it will stop working (with SHM bridge enabled) if we don't. We
> can possibly release the pool once we know we'll no longer need to
> access EFI variables but I'm not sure if that makes sense? Or maybe
> remove the pool after some time of driver inactivity and create a new
> one when it's needed again?
> 

Sounds like a good motivation to me, let's document it so that the next
guy understand why this was done.

Regards,
Bjorn

> Bart
> 
> [snip]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
  2024-02-22 16:24       ` Bartosz Golaszewski
@ 2024-02-27 16:56         ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-27 16:56 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Thu, Feb 22, 2024 at 05:24:19PM +0100, Bartosz Golaszewski wrote:
> On Sun, Feb 18, 2024 at 4:41 AM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > >
> 
> [snip]
> 
> > >
> > > +config QCOM_TZMEM_MODE_SHMBRIDGE
> > > +     bool "SHM Bridge"
> > > +     help
> > > +       Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> > > +       in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> > > +       buffer.
> > > +
> > > +       With this selected, all buffers passed to the TrustZone must be allocated
> > > +       using the TZMem allocator or else the TrustZone will refuse to use them.
> >
> > It's funny how this is the only place in the whole series I can find
> > this mentioned. One could from this statement guess that the eluding
> > scminvoke requires shmbridge and that this patch series exists solely
> > to facilitate the requirement stated in this paragraph.
> >
> 
> Yes, scminvoke *requires* SHM bridge. So does the wrapped key support.
> No, this is not the only reason as - as stated by Srini - it improves
> overall safety of the system for all users.
> 
> > Either this guess is correct and this should have been made clear in
> > the commit messages, or I'm guessing wrong here, in which case I need
> > some help to figure out why this series exists.
> >
> 
> This series exists and IMO should get upstream soon to facilitate
> adding new security features (in addition to improving existing ones).

This needs to be stated in the cover letter/commit messages.

> As there are at least two such features in development (mentioned
> above) pushing this series upstream will make it easier to develop
> them independently.
> 

Show me the work-in-progress code and I will entertain this argument.

Regards,
Bjorn

> Bart
> 
> [snip]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support
@ 2024-02-27 16:56         ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-02-27 16:56 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Thu, Feb 22, 2024 at 05:24:19PM +0100, Bartosz Golaszewski wrote:
> On Sun, Feb 18, 2024 at 4:41 AM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Mon, Feb 05, 2024 at 07:28:08PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > >
> 
> [snip]
> 
> > >
> > > +config QCOM_TZMEM_MODE_SHMBRIDGE
> > > +     bool "SHM Bridge"
> > > +     help
> > > +       Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
> > > +       in the 'Default' allocator but is also explicitly marked as an SHM Bridge
> > > +       buffer.
> > > +
> > > +       With this selected, all buffers passed to the TrustZone must be allocated
> > > +       using the TZMem allocator or else the TrustZone will refuse to use them.
> >
> > It's funny how this is the only place in the whole series I can find
> > this mentioned. One could from this statement guess that the eluding
> > scminvoke requires shmbridge and that this patch series exists solely
> > to facilitate the requirement stated in this paragraph.
> >
> 
> Yes, scminvoke *requires* SHM bridge. So does the wrapped key support.
> No, this is not the only reason as - as stated by Srini - it improves
> overall safety of the system for all users.
> 
> > Either this guess is correct and this should have been made clear in
> > the commit messages, or I'm guessing wrong here, in which case I need
> > some help to figure out why this series exists.
> >
> 
> This series exists and IMO should get upstream soon to facilitate
> adding new security features (in addition to improving existing ones).

This needs to be stated in the cover letter/commit messages.

> As there are at least two such features in development (mentioned
> above) pushing this series upstream will make it easier to develop
> them independently.
> 

Show me the work-in-progress code and I will entertain this argument.

Regards,
Bjorn

> Bart
> 
> [snip]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  2024-02-18  3:50     ` Bjorn Andersson
@ 2024-03-01 18:49       ` Prasad Sodagudi
  -1 siblings, 0 replies; 72+ messages in thread
From: Prasad Sodagudi @ 2024-03-01 18:49 UTC (permalink / raw)
  To: Bjorn Andersson, Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi


On 2/17/2024 7:50 PM, Bjorn Andersson wrote:
> On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>>
>> The "memory protection" mechanism mentioned in the comment is the SHM
>> Bridge. This is also the reason why we do not convert this call to using
>> the TZ memory allocator.
>>
> No, this mechanism predates shmbridge.
Yes. PIL calls are there for very long time and shm bridge concept is 
introduced later.
>
>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
>> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
>> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
>> ---
>>   drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
>> index 839773270a21..7ba5cff6e4e7 100644
>> --- a/drivers/firmware/qcom/qcom_scm.c
>> +++ b/drivers/firmware/qcom/qcom_scm.c
>> @@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
>>   	struct qcom_scm_res res;
>>   
>>   	/*
>> -	 * During the scm call memory protection will be enabled for the meta
>> -	 * data blob, so make sure it's physically contiguous, 4K aligned and
>> -	 * non-cachable to avoid XPU violations.
> What this is saying is that the memory will be made unaccessible to
> Linux, so it needs to be contiguous and aligned.

Based on my understanding,  this buffer has to be  physically 
contiguous, 4K aligned and non-cachable to avoid XPU violations.

We should keep this comment

>
>> +	 * During the SCM call the hypervisor will make the buffer containing
>> +	 * the program data into an SHM Bridge.
> Are you saying that the hypervisor will convert this memory to a
> shmbridge, and then pass it to TrustZone?
Yes.  Specifically for PIL calls hyp is creating shm bridge for 
buffers/regions on behalf of Linux/NS-EL1.
>
>> This is why we exceptionally
>> +	 * must not use the TrustZone memory allocator here as - depending on
>> +	 * Kconfig - it may already use the SHM Bridge mechanism internally.
>> +	 *
> "it may already"? You describe above that we shouldn't pass shmbridge
> memory, and the other case never deals with shmbridges. So, I think you
> can omit this part.
>
>> +	 * If we pass a buffer that is already part of an SHM Bridge to this
>> +	 * call, it will fail.
> Could this be because the consumer of this buffer operates in EL2, and
> not TZ?
These buffers are consumed by TZ only and not by EL2.  hyp creating the 
required bridges for pil buffers.
>
> Regards,
> Bjorn
>
>>   	 */
>>   	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
>>   				       GFP_KERNEL);
>> -- 
>> 2.40.1
>>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
@ 2024-03-01 18:49       ` Prasad Sodagudi
  0 siblings, 0 replies; 72+ messages in thread
From: Prasad Sodagudi @ 2024-03-01 18:49 UTC (permalink / raw)
  To: Bjorn Andersson, Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi


On 2/17/2024 7:50 PM, Bjorn Andersson wrote:
> On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
>> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>>
>> The "memory protection" mechanism mentioned in the comment is the SHM
>> Bridge. This is also the reason why we do not convert this call to using
>> the TZ memory allocator.
>>
> No, this mechanism predates shmbridge.
Yes. PIL calls are there for very long time and shm bridge concept is 
introduced later.
>
>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>> Tested-by: Andrew Halaney <ahalaney@redhat.com> # sc8280xp-lenovo-thinkpad-x13s
>> Tested-by: Deepti Jaggi <quic_djaggi@quicinc.com> #sa8775p-ride
>> Reviewed-by: Elliot Berman <quic_eberman@quicinc.com>
>> ---
>>   drivers/firmware/qcom/qcom_scm.c | 10 +++++++---
>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
>> index 839773270a21..7ba5cff6e4e7 100644
>> --- a/drivers/firmware/qcom/qcom_scm.c
>> +++ b/drivers/firmware/qcom/qcom_scm.c
>> @@ -563,9 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
>>   	struct qcom_scm_res res;
>>   
>>   	/*
>> -	 * During the scm call memory protection will be enabled for the meta
>> -	 * data blob, so make sure it's physically contiguous, 4K aligned and
>> -	 * non-cachable to avoid XPU violations.
> What this is saying is that the memory will be made unaccessible to
> Linux, so it needs to be contiguous and aligned.

Based on my understanding,  this buffer has to be  physically 
contiguous, 4K aligned and non-cachable to avoid XPU violations.

We should keep this comment

>
>> +	 * During the SCM call the hypervisor will make the buffer containing
>> +	 * the program data into an SHM Bridge.
> Are you saying that the hypervisor will convert this memory to a
> shmbridge, and then pass it to TrustZone?
Yes.  Specifically for PIL calls hyp is creating shm bridge for 
buffers/regions on behalf of Linux/NS-EL1.
>
>> This is why we exceptionally
>> +	 * must not use the TrustZone memory allocator here as - depending on
>> +	 * Kconfig - it may already use the SHM Bridge mechanism internally.
>> +	 *
> "it may already"? You describe above that we shouldn't pass shmbridge
> memory, and the other case never deals with shmbridges. So, I think you
> can omit this part.
>
>> +	 * If we pass a buffer that is already part of an SHM Bridge to this
>> +	 * call, it will fail.
> Could this be because the consumer of this buffer operates in EL2, and
> not TZ?
These buffers are consumed by TZ only and not by EL2.  hyp creating the 
required bridges for pil buffers.
>
> Regards,
> Bjorn
>
>>   	 */
>>   	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
>>   				       GFP_KERNEL);
>> -- 
>> 2.40.1
>>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-02-27 16:53         ` Bjorn Andersson
@ 2024-03-03 16:18           ` Bartosz Golaszewski
  -1 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-03-03 16:18 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Tue, Feb 27, 2024 at 5:53 PM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Tue, Feb 20, 2024 at 10:54:02AM +0100, Bartosz Golaszewski wrote:
> >
> > I disagree. If we have a better interface in place, then let's use it
> > right away, otherwise it's just useless churn.
> >
>
> The functional change and the use of cleanup macros, could be done
> independently of each other, each one fully beneficial on their own.
>
> As such I don't find it hard to claim that they are two independent
> changes.
>

This series would be 50% bigger for no reason if we split every patch
using the new allocator into two. I absolutely don't see how this
makes any sense. We're removing the calls to old interfaces and using
the new ones instead. The new ones happen to support cleanup so we use
it right away. If the old ones supported cleanup then maybeeee it
would make some sense to convert them first and then use tzmem. As it
is, there's really no point.

Bart

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-03-03 16:18           ` Bartosz Golaszewski
  0 siblings, 0 replies; 72+ messages in thread
From: Bartosz Golaszewski @ 2024-03-03 16:18 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Tue, Feb 27, 2024 at 5:53 PM Bjorn Andersson <andersson@kernel.org> wrote:
>
> On Tue, Feb 20, 2024 at 10:54:02AM +0100, Bartosz Golaszewski wrote:
> >
> > I disagree. If we have a better interface in place, then let's use it
> > right away, otherwise it's just useless churn.
> >
>
> The functional change and the use of cleanup macros, could be done
> independently of each other, each one fully beneficial on their own.
>
> As such I don't find it hard to claim that they are two independent
> changes.
>

This series would be 50% bigger for no reason if we split every patch
using the new allocator into two. I absolutely don't see how this
makes any sense. We're removing the calls to old interfaces and using
the new ones instead. The new ones happen to support cleanup so we use
it right away. If the old ones supported cleanup then maybeeee it
would make some sense to convert them first and then use tzmem. As it
is, there's really no point.

Bart

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-03 16:18           ` Bartosz Golaszewski
@ 2024-03-16 17:24             ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-03-16 17:24 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Mar 03, 2024 at 05:18:18PM +0100, Bartosz Golaszewski wrote:
> On Tue, Feb 27, 2024 at 5:53 PM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Tue, Feb 20, 2024 at 10:54:02AM +0100, Bartosz Golaszewski wrote:
> > >
> > > I disagree. If we have a better interface in place, then let's use it
> > > right away, otherwise it's just useless churn.
> > >
> >
> > The functional change and the use of cleanup macros, could be done
> > independently of each other, each one fully beneficial on their own.
> >
> > As such I don't find it hard to claim that they are two independent
> > changes.
> >
> 
> This series would be 50% bigger for no reason if we split every patch
> using the new allocator into two.

I'm not asking you to split every patch into two, unless that makes
sense.

> I absolutely don't see how this makes any sense.

I find it unnecessarily hard to determine which parts of _this_ patch is
functional and which is cleanup.

> We're removing the calls to old interfaces and using
> the new ones instead. The new ones happen to support cleanup so we use
> it right away. If the old ones supported cleanup then maybeeee it
> would make some sense to convert them first and then use tzmem. As it
> is, there's really no point.
> 

The old interface is kzalloc(). I haven't used the cleanup mechanism
myself yet, but are you saying that there's no cleanup support for
kzalloc()?

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 08/12] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-03-16 17:24             ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-03-16 17:24 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Konrad Dybcio, Elliot Berman, Krzysztof Kozlowski,
	Guru Das Srinagesh, Andrew Halaney, Maximilian Luz, Alex Elder,
	Srini Kandagatla, Arnd Bergmann, linux-arm-msm, linux-kernel,
	linux-arm-kernel, kernel, Bartosz Golaszewski, Deepti Jaggi

On Sun, Mar 03, 2024 at 05:18:18PM +0100, Bartosz Golaszewski wrote:
> On Tue, Feb 27, 2024 at 5:53 PM Bjorn Andersson <andersson@kernel.org> wrote:
> >
> > On Tue, Feb 20, 2024 at 10:54:02AM +0100, Bartosz Golaszewski wrote:
> > >
> > > I disagree. If we have a better interface in place, then let's use it
> > > right away, otherwise it's just useless churn.
> > >
> >
> > The functional change and the use of cleanup macros, could be done
> > independently of each other, each one fully beneficial on their own.
> >
> > As such I don't find it hard to claim that they are two independent
> > changes.
> >
> 
> This series would be 50% bigger for no reason if we split every patch
> using the new allocator into two.

I'm not asking you to split every patch into two, unless that makes
sense.

> I absolutely don't see how this makes any sense.

I find it unnecessarily hard to determine which parts of _this_ patch is
functional and which is cleanup.

> We're removing the calls to old interfaces and using
> the new ones instead. The new ones happen to support cleanup so we use
> it right away. If the old ones supported cleanup then maybeeee it
> would make some sense to convert them first and then use tzmem. As it
> is, there's really no point.
> 

The old interface is kzalloc(). I haven't used the cleanup mechanism
myself yet, but are you saying that there's no cleanup support for
kzalloc()?

Regards,
Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  2024-03-01 18:49       ` Prasad Sodagudi
@ 2024-03-16 17:27         ` Bjorn Andersson
  -1 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-03-16 17:27 UTC (permalink / raw)
  To: Prasad Sodagudi
  Cc: Bartosz Golaszewski, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

On Fri, Mar 01, 2024 at 10:49:57AM -0800, Prasad Sodagudi wrote:
> On 2/17/2024 7:50 PM, Bjorn Andersson wrote:
> > On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
[..]
> > > +	 * If we pass a buffer that is already part of an SHM Bridge to this
> > > +	 * call, it will fail.
> > Could this be because the consumer of this buffer operates in EL2, and
> > not TZ?
> These buffers are consumed by TZ only and not by EL2.  hyp creating the
> required bridges for pil buffers.

Please help Bartosz document what is actually going on here and why
these buffers should be handled differently.

Regards,
Bjorn

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
@ 2024-03-16 17:27         ` Bjorn Andersson
  0 siblings, 0 replies; 72+ messages in thread
From: Bjorn Andersson @ 2024-03-16 17:27 UTC (permalink / raw)
  To: Prasad Sodagudi
  Cc: Bartosz Golaszewski, Andy Gross, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Maximilian Luz, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel,
	Bartosz Golaszewski, Deepti Jaggi

On Fri, Mar 01, 2024 at 10:49:57AM -0800, Prasad Sodagudi wrote:
> On 2/17/2024 7:50 PM, Bjorn Andersson wrote:
> > On Mon, Feb 05, 2024 at 07:28:09PM +0100, Bartosz Golaszewski wrote:
> > > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
[..]
> > > +	 * If we pass a buffer that is already part of an SHM Bridge to this
> > > +	 * call, it will fail.
> > Could this be because the consumer of this buffer operates in EL2, and
> > not TZ?
> These buffers are consumed by TZ only and not by EL2.  hyp creating the
> required bridges for pil buffers.

Please help Bartosz document what is actually going on here and why
these buffers should be handled differently.

Regards,
Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2024-03-16 17:27 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-05 18:27 [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support Bartosz Golaszewski
2024-02-05 18:27 ` Bartosz Golaszewski
2024-02-05 18:27 ` [PATCH v7 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator Bartosz Golaszewski
2024-02-05 18:27   ` Bartosz Golaszewski
2024-02-18  3:22   ` Bjorn Andersson
2024-02-18  3:22     ` Bjorn Andersson
2024-02-19 13:18     ` Bartosz Golaszewski
2024-02-19 13:18       ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 02/12] firmware: qcom: scm: enable the TZ mem allocator Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-18  3:25   ` Bjorn Andersson
2024-02-18  3:25     ` Bjorn Andersson
2024-02-21 18:39     ` Bartosz Golaszewski
2024-02-21 18:39       ` Bartosz Golaszewski
2024-02-22 13:54       ` Bartosz Golaszewski
2024-02-22 13:54         ` Bartosz Golaszewski
2024-02-26 10:29         ` Kuldeep Singh
2024-02-26 10:29           ` Kuldeep Singh
2024-02-27  8:24           ` Bartosz Golaszewski
2024-02-27  8:24             ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 03/12] firmware: qcom: scm: smc: switch to using the SCM allocator Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 04/12] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 05/12] firmware: qcom: scm: make qcom_scm_ice_set_key() " Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 06/12] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() " Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 07/12] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() " Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 08/12] firmware: qcom: qseecom: convert to using " Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-18  3:08   ` Bjorn Andersson
2024-02-18  3:08     ` Bjorn Andersson
2024-02-20  9:54     ` Bartosz Golaszewski
2024-02-20  9:54       ` Bartosz Golaszewski
2024-02-27 16:53       ` Bjorn Andersson
2024-02-27 16:53         ` Bjorn Andersson
2024-03-03 16:18         ` Bartosz Golaszewski
2024-03-03 16:18           ` Bartosz Golaszewski
2024-03-16 17:24           ` Bjorn Andersson
2024-03-16 17:24             ` Bjorn Andersson
2024-02-05 18:28 ` [PATCH v7 09/12] firmware: qcom: scm: add support for SHM bridge operations Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-05 18:28 ` [PATCH v7 10/12] firmware: qcom: tzmem: enable SHM Bridge support Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-18  3:41   ` Bjorn Andersson
2024-02-18  3:41     ` Bjorn Andersson
2024-02-21 19:06     ` Bartosz Golaszewski
2024-02-21 19:06       ` Bartosz Golaszewski
2024-02-22 16:24     ` Bartosz Golaszewski
2024-02-22 16:24       ` Bartosz Golaszewski
2024-02-27 16:56       ` Bjorn Andersson
2024-02-27 16:56         ` Bjorn Andersson
2024-02-05 18:28 ` [PATCH v7 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image() Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-18  3:50   ` Bjorn Andersson
2024-02-18  3:50     ` Bjorn Andersson
2024-03-01 18:49     ` Prasad Sodagudi
2024-03-01 18:49       ` Prasad Sodagudi
2024-03-16 17:27       ` Bjorn Andersson
2024-03-16 17:27         ` Bjorn Andersson
2024-02-05 18:28 ` [PATCH v7 12/12] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator Bartosz Golaszewski
2024-02-05 18:28   ` Bartosz Golaszewski
2024-02-13 16:34 ` [PATCH v7 00/12] arm64: qcom: add and enable SHM Bridge support Bartosz Golaszewski
2024-02-13 16:34   ` Bartosz Golaszewski
2024-02-17 19:58 ` Bjorn Andersson
2024-02-17 19:58   ` Bjorn Andersson
2024-02-19 15:17   ` Srinivas Kandagatla
2024-02-19 15:17     ` Srinivas Kandagatla
2024-02-27 16:32     ` Bjorn Andersson
2024-02-27 16:32       ` Bjorn Andersson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.