All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-03-25 10:03 ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

SCM calls that take memory buffers as arguments require that they be
page-aligned, physically continuous and non-cachable. The same
requirements apply to the buffer used to pass additional arguments to SCM
calls that take more than 4.

To that end drivers typically use dma_alloc_coherent() to allocate memory
of suitable format which is slow and inefficient space-wise.

SHM Bridge is a safety mechanism that - once enabled - will only allow
passing buffers to the TrustZone that have been explicitly marked as
shared. It improves the overall system safety with SCM calls and is
required by the upcoming scminvoke functionality.

The end goal of this series is to enable SHM bridge support for those
architectures that support it but to that end we first need to unify the
way memory for SCM calls is allocated. This in itself is beneficial as
the current approach of using dma_alloc_coherent() in most places is quite
slow.

First let's add a new TZ Memory allocator that allows users to create
dynamic memory pools of format suitable for sharing with the TrustZone.
Make it ready for implementing multiple build-time modes.

Convert all relevant drivers to using it. Add separate pools for SCM core
and for qseecom.

Finally add support for SHM bridge and make it the default mode of
operation with the generic allocator as fallback for the platforms that
don't support SHM bridge.

Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
sa8775p-ride and lenovo X13s (please do retest on those platforms if you
can).

v8 -> v9:
- split the qseecom driver rework into two parts: first convert it to using
  the __free() helper and then make it switch to tzmem
- use QCOM_SCM_PERM_RW instead of (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ)
- add the TZMEM MAINTAINERS entry in correct alphabetical order
- add a missing break; in a switch case in the tzmem module

v7 -> v8:
- make the pool size dynamic and add different policies for pool growth
- improve commit messages and the cover letter: describe what the SHM
  bridge is and why do we need it and the new allocator, explain why it's
  useful to merge these changes already, independently from scminvoke
- improve kerneldoc format
- improve the comment on the PIL SCM calls
- fix license tags, drop "or-later" for GPL v2
- add lockdep and sleeping asserts
- minor tweaks and improvements

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 (13):
  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 cleanup helpers
  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   | 285 ++++-------
 drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
 drivers/firmware/qcom/qcom_scm.c              | 182 ++++---
 drivers/firmware/qcom/qcom_scm.h              |   6 +
 drivers/firmware/qcom/qcom_tzmem.c            | 455 ++++++++++++++++++
 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      |  56 +++
 13 files changed, 813 insertions(+), 265 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] 62+ messages in thread

* [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-03-25 10:03 ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

SCM calls that take memory buffers as arguments require that they be
page-aligned, physically continuous and non-cachable. The same
requirements apply to the buffer used to pass additional arguments to SCM
calls that take more than 4.

To that end drivers typically use dma_alloc_coherent() to allocate memory
of suitable format which is slow and inefficient space-wise.

SHM Bridge is a safety mechanism that - once enabled - will only allow
passing buffers to the TrustZone that have been explicitly marked as
shared. It improves the overall system safety with SCM calls and is
required by the upcoming scminvoke functionality.

The end goal of this series is to enable SHM bridge support for those
architectures that support it but to that end we first need to unify the
way memory for SCM calls is allocated. This in itself is beneficial as
the current approach of using dma_alloc_coherent() in most places is quite
slow.

First let's add a new TZ Memory allocator that allows users to create
dynamic memory pools of format suitable for sharing with the TrustZone.
Make it ready for implementing multiple build-time modes.

Convert all relevant drivers to using it. Add separate pools for SCM core
and for qseecom.

Finally add support for SHM bridge and make it the default mode of
operation with the generic allocator as fallback for the platforms that
don't support SHM bridge.

Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
sa8775p-ride and lenovo X13s (please do retest on those platforms if you
can).

v8 -> v9:
- split the qseecom driver rework into two parts: first convert it to using
  the __free() helper and then make it switch to tzmem
- use QCOM_SCM_PERM_RW instead of (QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_READ)
- add the TZMEM MAINTAINERS entry in correct alphabetical order
- add a missing break; in a switch case in the tzmem module

v7 -> v8:
- make the pool size dynamic and add different policies for pool growth
- improve commit messages and the cover letter: describe what the SHM
  bridge is and why do we need it and the new allocator, explain why it's
  useful to merge these changes already, independently from scminvoke
- improve kerneldoc format
- improve the comment on the PIL SCM calls
- fix license tags, drop "or-later" for GPL v2
- add lockdep and sleeping asserts
- minor tweaks and improvements

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 (13):
  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 cleanup helpers
  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   | 285 ++++-------
 drivers/firmware/qcom/qcom_scm-smc.c          |  30 +-
 drivers/firmware/qcom/qcom_scm.c              | 182 ++++---
 drivers/firmware/qcom/qcom_scm.h              |   6 +
 drivers/firmware/qcom/qcom_tzmem.c            | 455 ++++++++++++++++++
 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      |  56 +++
 13 files changed, 813 insertions(+), 265 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] 62+ messages in thread

* [PATCH v9 01/13] firmware: qcom: add a dedicated TrustZone buffer allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 pools 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.

Make the allocator ready for extending with additional modes of operation
which will allow us to support the SHM bridge safety mechanism once all
users convert.

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       | 393 +++++++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h       |  13 +
 include/linux/firmware/qcom/qcom_tzmem.h |  56 ++++
 6 files changed, 491 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 51d5a64a5a36..d4c290ccf4f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18338,6 +18338,14 @@ F:	Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
 F:	drivers/net/ethernet/qualcomm/rmnet/
 F:	include/linux/if_rmnet.h
 
+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 TSENS THERMAL DRIVER
 M:	Amit Kucheria <amitk@kernel.org>
 M:	Thara Gopinath <thara.gopinath@gmail.com>
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3f05d9854ddf..3c495f8698e1 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_GENERIC
+	help
+	  Selects the mode of the memory allocator providing memory buffers of
+	  suitable format for sharing with the TrustZone. If in doubt, select
+	  'Generic'.
+
+config QCOM_TZMEM_MODE_GENERIC
+	bool "Generic"
+	help
+	  Use the generic allocator mode. The memory is page-aligned, non-cachable
+	  and physically 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..9082966c7e1f
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -0,0 +1,393 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Memory allocator for buffers shared with the TrustZone.
+ *
+ * Copyright (C) 2023-2024 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/kernel.h>
+#include <linux/list.h>
+#include <linux/lockdep.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_area {
+	struct list_head list;
+	void *vaddr;
+	dma_addr_t paddr;
+	size_t size;
+	void *priv;
+};
+
+struct qcom_tzmem_pool {
+	struct gen_pool *genpool;
+	struct list_head areas;
+	enum qcom_tzmem_policy policy;
+	size_t increment;
+	size_t max_size;
+	spinlock_t lock;
+};
+
+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_GENERIC)
+
+static int qcom_tzmem_init(void)
+{
+	return 0;
+}
+
+static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
+{
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
+{
+
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_GENERIC */
+
+static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,
+				      size_t size, gfp_t gfp)
+{
+	int ret;
+
+	struct qcom_tzmem_area *area __free(kfree) = kzalloc(sizeof(*area),
+							     gfp);
+	if (!area)
+		return -ENOMEM;
+
+	area->size = PAGE_ALIGN(size);
+
+	area->vaddr = dma_alloc_coherent(qcom_tzmem_dev, area->size,
+					 &area->paddr, gfp);
+	if (!area->vaddr)
+		return -ENOMEM;
+
+	ret = qcom_tzmem_init_area(area);
+	if (ret) {
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		return ret;
+	}
+
+	ret = gen_pool_add_virt(pool->genpool, (unsigned long)area->vaddr,
+				(phys_addr_t)area->paddr, size, -1);
+	if (ret) {
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		return ret;
+	}
+
+	list_add_tail(&area->list, &pool->areas);
+	area = NULL;
+
+	return 0;
+}
+
+/**
+ * qcom_tzmem_pool_new() - Create a new TZ memory pool.
+ * @config: Pool configuration.
+ *
+ * Create a new pool of memory suitable for sharing with the TrustZone.
+ *
+ * Must not be used in atomic context.
+ *
+ * Return: New memory pool address or ERR_PTR() on error.
+ */
+struct qcom_tzmem_pool *
+qcom_tzmem_pool_new(const struct qcom_tzmem_pool_config *config)
+{
+	int ret = -ENOMEM;
+
+	might_sleep();
+
+	switch (config->policy) {
+	case QCOM_TZMEM_POLICY_STATIC:
+		if (!config->initial_size)
+			return ERR_PTR(-EINVAL);
+		break;
+	case QCOM_TZMEM_POLICY_MULTIPLIER:
+		if (!config->increment)
+			return ERR_PTR(-EINVAL);
+		break;
+	case QCOM_TZMEM_POLICY_ON_DEMAND:
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	struct qcom_tzmem_pool *pool __free(kfree) = kzalloc(sizeof(*pool),
+							     GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->genpool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool->genpool)
+		return ERR_PTR(-ENOMEM);
+
+	gen_pool_set_algo(pool->genpool, gen_pool_best_fit, NULL);
+
+	pool->policy = config->policy;
+	pool->increment = config->increment;
+	pool->max_size = config->max_size;
+	INIT_LIST_HEAD(&pool->areas);
+	spin_lock_init(&pool->lock);
+
+	if (config->initial_size) {
+		ret = qcom_tzmem_pool_add_memory(pool, config->initial_size,
+						 GFP_KERNEL);
+		if (ret) {
+			gen_pool_destroy(pool->genpool);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return no_free_ptr(pool);
+}
+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_area *area, *next;
+	struct qcom_tzmem_chunk *chunk;
+	struct radix_tree_iter iter;
+	bool non_empty = false;
+	void __rcu **slot;
+
+	might_sleep();
+
+	if (!pool)
+		return;
+
+	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");
+
+	list_for_each_entry_safe(area, next, &pool->areas, list) {
+		list_del(&area->list);
+		qcom_tzmem_cleanup_area(area);
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		kfree(area);
+	}
+
+	gen_pool_destroy(pool->genpool);
+	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.
+ * @config: Pool configuration.
+ *
+ * Must not be used in atomic context.
+ *
+ * Return: Address of the managed pool or ERR_PTR() on failure.
+ */
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev,
+			 const struct qcom_tzmem_pool_config *config)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret;
+
+	pool = qcom_tzmem_pool_new(config);
+	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;
+}
+
+static bool qcom_tzmem_try_grow_pool(struct qcom_tzmem_pool *pool,
+				     size_t requested, gfp_t gfp)
+{
+	size_t current_size = gen_pool_size(pool->genpool);
+
+	lockdep_assert_held(&pool->lock);
+
+	if (pool->max_size && (current_size + requested) > pool->max_size)
+		return false;
+
+	switch (pool->policy) {
+	case QCOM_TZMEM_POLICY_STATIC:
+		return false;
+	case QCOM_TZMEM_POLICY_MULTIPLIER:
+		requested = current_size * pool->increment;
+		break;
+	case QCOM_TZMEM_POLICY_ON_DEMAND:
+		break;
+	}
+
+	return !qcom_tzmem_pool_add_memory(pool, requested, gfp);
+}
+
+/**
+ * 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.
+ *
+ * Return:
+ * 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)
+{
+	unsigned long vaddr;
+	int ret;
+
+	if (!size)
+		return NULL;
+
+	size = PAGE_ALIGN(size);
+
+	struct qcom_tzmem_chunk *chunk __free(kfree) = kzalloc(sizeof(*chunk),
+							       gfp);
+	if (!chunk)
+		return NULL;
+
+	guard(spinlock_irqsave)(&pool->lock);
+
+again:
+	vaddr = gen_pool_alloc(pool->genpool, size);
+	if (!vaddr) {
+		if (qcom_tzmem_try_grow_pool(pool, size, gfp))
+			goto again;
+
+		return NULL;
+	}
+
+	chunk->paddr = gen_pool_virt_to_phys(pool->genpool, 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->genpool, vaddr, size);
+			return NULL;
+		}
+
+		chunk = 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;
+	}
+
+	scoped_guard(spinlock_irqsave, &chunk->owner->lock)
+		gen_pool_free(chunk->owner->genpool, (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..8fa8a3eb940e
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 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..b83b63a0c049
--- /dev/null
+++ b/include/linux/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 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;
+
+/**
+ * enum qcom_tzmem_policy - Policy for pool growth.
+ */
+enum qcom_tzmem_policy {
+	/**< Static pool, never grow above initial size. */
+	QCOM_TZMEM_POLICY_STATIC = 1,
+	/**< When out of memory, add increment * current size of memory. */
+	QCOM_TZMEM_POLICY_MULTIPLIER,
+	/**< When out of memory add as much as is needed until max_size. */
+	QCOM_TZMEM_POLICY_ON_DEMAND,
+};
+
+/**
+ * struct qcom_tzmem_pool_config - TZ memory pool configuration.
+ * @initial_size: Number of bytes to allocate for the pool during its creation.
+ * @policy: Pool size growth policy.
+ * @increment: Used with policies that allow pool growth.
+ * @max_size: Size above which the pool will never grow.
+ */
+struct qcom_tzmem_pool_config {
+	size_t initial_size;
+	enum qcom_tzmem_policy policy;
+	size_t increment;
+	size_t max_size;
+};
+
+struct qcom_tzmem_pool *
+qcom_tzmem_pool_new(const struct qcom_tzmem_pool_config *config);
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool);
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev,
+			 const struct qcom_tzmem_pool_config *config);
+
+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] 62+ messages in thread

* [PATCH v9 01/13] firmware: qcom: add a dedicated TrustZone buffer allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 pools 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.

Make the allocator ready for extending with additional modes of operation
which will allow us to support the SHM bridge safety mechanism once all
users convert.

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       | 393 +++++++++++++++++++++++
 drivers/firmware/qcom/qcom_tzmem.h       |  13 +
 include/linux/firmware/qcom/qcom_tzmem.h |  56 ++++
 6 files changed, 491 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 51d5a64a5a36..d4c290ccf4f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18338,6 +18338,14 @@ F:	Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
 F:	drivers/net/ethernet/qualcomm/rmnet/
 F:	include/linux/if_rmnet.h
 
+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 TSENS THERMAL DRIVER
 M:	Amit Kucheria <amitk@kernel.org>
 M:	Thara Gopinath <thara.gopinath@gmail.com>
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3f05d9854ddf..3c495f8698e1 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_GENERIC
+	help
+	  Selects the mode of the memory allocator providing memory buffers of
+	  suitable format for sharing with the TrustZone. If in doubt, select
+	  'Generic'.
+
+config QCOM_TZMEM_MODE_GENERIC
+	bool "Generic"
+	help
+	  Use the generic allocator mode. The memory is page-aligned, non-cachable
+	  and physically 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..9082966c7e1f
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -0,0 +1,393 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Memory allocator for buffers shared with the TrustZone.
+ *
+ * Copyright (C) 2023-2024 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/kernel.h>
+#include <linux/list.h>
+#include <linux/lockdep.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_area {
+	struct list_head list;
+	void *vaddr;
+	dma_addr_t paddr;
+	size_t size;
+	void *priv;
+};
+
+struct qcom_tzmem_pool {
+	struct gen_pool *genpool;
+	struct list_head areas;
+	enum qcom_tzmem_policy policy;
+	size_t increment;
+	size_t max_size;
+	spinlock_t lock;
+};
+
+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_GENERIC)
+
+static int qcom_tzmem_init(void)
+{
+	return 0;
+}
+
+static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
+{
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
+{
+
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_GENERIC */
+
+static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,
+				      size_t size, gfp_t gfp)
+{
+	int ret;
+
+	struct qcom_tzmem_area *area __free(kfree) = kzalloc(sizeof(*area),
+							     gfp);
+	if (!area)
+		return -ENOMEM;
+
+	area->size = PAGE_ALIGN(size);
+
+	area->vaddr = dma_alloc_coherent(qcom_tzmem_dev, area->size,
+					 &area->paddr, gfp);
+	if (!area->vaddr)
+		return -ENOMEM;
+
+	ret = qcom_tzmem_init_area(area);
+	if (ret) {
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		return ret;
+	}
+
+	ret = gen_pool_add_virt(pool->genpool, (unsigned long)area->vaddr,
+				(phys_addr_t)area->paddr, size, -1);
+	if (ret) {
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		return ret;
+	}
+
+	list_add_tail(&area->list, &pool->areas);
+	area = NULL;
+
+	return 0;
+}
+
+/**
+ * qcom_tzmem_pool_new() - Create a new TZ memory pool.
+ * @config: Pool configuration.
+ *
+ * Create a new pool of memory suitable for sharing with the TrustZone.
+ *
+ * Must not be used in atomic context.
+ *
+ * Return: New memory pool address or ERR_PTR() on error.
+ */
+struct qcom_tzmem_pool *
+qcom_tzmem_pool_new(const struct qcom_tzmem_pool_config *config)
+{
+	int ret = -ENOMEM;
+
+	might_sleep();
+
+	switch (config->policy) {
+	case QCOM_TZMEM_POLICY_STATIC:
+		if (!config->initial_size)
+			return ERR_PTR(-EINVAL);
+		break;
+	case QCOM_TZMEM_POLICY_MULTIPLIER:
+		if (!config->increment)
+			return ERR_PTR(-EINVAL);
+		break;
+	case QCOM_TZMEM_POLICY_ON_DEMAND:
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	struct qcom_tzmem_pool *pool __free(kfree) = kzalloc(sizeof(*pool),
+							     GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->genpool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool->genpool)
+		return ERR_PTR(-ENOMEM);
+
+	gen_pool_set_algo(pool->genpool, gen_pool_best_fit, NULL);
+
+	pool->policy = config->policy;
+	pool->increment = config->increment;
+	pool->max_size = config->max_size;
+	INIT_LIST_HEAD(&pool->areas);
+	spin_lock_init(&pool->lock);
+
+	if (config->initial_size) {
+		ret = qcom_tzmem_pool_add_memory(pool, config->initial_size,
+						 GFP_KERNEL);
+		if (ret) {
+			gen_pool_destroy(pool->genpool);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return no_free_ptr(pool);
+}
+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_area *area, *next;
+	struct qcom_tzmem_chunk *chunk;
+	struct radix_tree_iter iter;
+	bool non_empty = false;
+	void __rcu **slot;
+
+	might_sleep();
+
+	if (!pool)
+		return;
+
+	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");
+
+	list_for_each_entry_safe(area, next, &pool->areas, list) {
+		list_del(&area->list);
+		qcom_tzmem_cleanup_area(area);
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		kfree(area);
+	}
+
+	gen_pool_destroy(pool->genpool);
+	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.
+ * @config: Pool configuration.
+ *
+ * Must not be used in atomic context.
+ *
+ * Return: Address of the managed pool or ERR_PTR() on failure.
+ */
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev,
+			 const struct qcom_tzmem_pool_config *config)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret;
+
+	pool = qcom_tzmem_pool_new(config);
+	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;
+}
+
+static bool qcom_tzmem_try_grow_pool(struct qcom_tzmem_pool *pool,
+				     size_t requested, gfp_t gfp)
+{
+	size_t current_size = gen_pool_size(pool->genpool);
+
+	lockdep_assert_held(&pool->lock);
+
+	if (pool->max_size && (current_size + requested) > pool->max_size)
+		return false;
+
+	switch (pool->policy) {
+	case QCOM_TZMEM_POLICY_STATIC:
+		return false;
+	case QCOM_TZMEM_POLICY_MULTIPLIER:
+		requested = current_size * pool->increment;
+		break;
+	case QCOM_TZMEM_POLICY_ON_DEMAND:
+		break;
+	}
+
+	return !qcom_tzmem_pool_add_memory(pool, requested, gfp);
+}
+
+/**
+ * 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.
+ *
+ * Return:
+ * 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)
+{
+	unsigned long vaddr;
+	int ret;
+
+	if (!size)
+		return NULL;
+
+	size = PAGE_ALIGN(size);
+
+	struct qcom_tzmem_chunk *chunk __free(kfree) = kzalloc(sizeof(*chunk),
+							       gfp);
+	if (!chunk)
+		return NULL;
+
+	guard(spinlock_irqsave)(&pool->lock);
+
+again:
+	vaddr = gen_pool_alloc(pool->genpool, size);
+	if (!vaddr) {
+		if (qcom_tzmem_try_grow_pool(pool, size, gfp))
+			goto again;
+
+		return NULL;
+	}
+
+	chunk->paddr = gen_pool_virt_to_phys(pool->genpool, 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->genpool, vaddr, size);
+			return NULL;
+		}
+
+		chunk = 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;
+	}
+
+	scoped_guard(spinlock_irqsave, &chunk->owner->lock)
+		gen_pool_free(chunk->owner->genpool, (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..8fa8a3eb940e
--- /dev/null
+++ b/drivers/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 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..b83b63a0c049
--- /dev/null
+++ b/include/linux/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 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;
+
+/**
+ * enum qcom_tzmem_policy - Policy for pool growth.
+ */
+enum qcom_tzmem_policy {
+	/**< Static pool, never grow above initial size. */
+	QCOM_TZMEM_POLICY_STATIC = 1,
+	/**< When out of memory, add increment * current size of memory. */
+	QCOM_TZMEM_POLICY_MULTIPLIER,
+	/**< When out of memory add as much as is needed until max_size. */
+	QCOM_TZMEM_POLICY_ON_DEMAND,
+};
+
+/**
+ * struct qcom_tzmem_pool_config - TZ memory pool configuration.
+ * @initial_size: Number of bytes to allocate for the pool during its creation.
+ * @policy: Pool size growth policy.
+ * @increment: Used with policies that allow pool growth.
+ * @max_size: Size above which the pool will never grow.
+ */
+struct qcom_tzmem_pool_config {
+	size_t initial_size;
+	enum qcom_tzmem_policy policy;
+	size_t increment;
+	size_t max_size;
+};
+
+struct qcom_tzmem_pool *
+qcom_tzmem_pool_new(const struct qcom_tzmem_pool_config *config);
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool);
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev,
+			 const struct qcom_tzmem_pool_config *config);
+
+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] 62+ messages in thread

* [PATCH v9 02/13] firmware: qcom: scm: enable the TZ mem allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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.

The policy used for the pool is "on-demand" and the initial size is 0
as - depending on the config - it's possible that no SCM calls needing
to allocate memory will be called. The sizes of possible allocations also
vary substiantially further warranting the "on-demand" approach.

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 | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3c495f8698e1..4634f8cecc7b 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 49ddbcab0680..ebb1141f8be4 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 {
@@ -1815,6 +1821,7 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data)
 
 static int qcom_scm_probe(struct platform_device *pdev)
 {
+	struct qcom_tzmem_pool_config pool_config;
 	struct qcom_scm *scm;
 	int irq, ret;
 
@@ -1890,6 +1897,21 @@ 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");
+
+	memset(&pool_config, 0, sizeof(pool_config));
+	pool_config.initial_size = 0;
+	pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
+	pool_config.max_size = SZ_256K;
+
+	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
+	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] 62+ messages in thread

* [PATCH v9 02/13] firmware: qcom: scm: enable the TZ mem allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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.

The policy used for the pool is "on-demand" and the initial size is 0
as - depending on the config - it's possible that no SCM calls needing
to allocate memory will be called. The sizes of possible allocations also
vary substiantially further warranting the "on-demand" approach.

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 | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 3c495f8698e1..4634f8cecc7b 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 49ddbcab0680..ebb1141f8be4 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 {
@@ -1815,6 +1821,7 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data)
 
 static int qcom_scm_probe(struct platform_device *pdev)
 {
+	struct qcom_tzmem_pool_config pool_config;
 	struct qcom_scm *scm;
 	int irq, ret;
 
@@ -1890,6 +1897,21 @@ 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");
+
+	memset(&pool_config, 0, sizeof(pool_config));
+	pool_config.initial_size = 0;
+	pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
+	pool_config.max_size = SZ_256K;
+
+	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
+	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] 62+ messages in thread

* [PATCH v9 03/13] firmware: qcom: scm: smc: switch to using the SCM allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 call. 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 ebb1141f8be4..21c22d306aac 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -198,6 +198,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] 62+ messages in thread

* [PATCH v9 03/13] firmware: qcom: scm: smc: switch to using the SCM allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 call. 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 ebb1141f8be4..21c22d306aac 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -198,6 +198,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] 62+ messages in thread

* [PATCH v9 04/13] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 21c22d306aac..cd47389ac80c 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>
@@ -1001,14 +1002,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;
 
@@ -1018,10 +1018,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;
@@ -1050,7 +1053,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] 62+ messages in thread

* [PATCH v9 04/13] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 21c22d306aac..cd47389ac80c 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>
@@ -1001,14 +1002,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;
 
@@ -1018,10 +1018,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;
@@ -1050,7 +1053,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] 62+ messages in thread

* [PATCH v9 05/13] firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 cd47389ac80c..de66319cbfb9 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1200,32 +1200,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] 62+ messages in thread

* [PATCH v9 05/13] firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 cd47389ac80c..de66319cbfb9 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1200,32 +1200,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] 62+ messages in thread

* [PATCH v9 06/13] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 de66319cbfb9..feb44cc03d2c 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1343,8 +1343,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 = {
@@ -1359,7 +1357,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;
 
@@ -1369,11 +1369,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] 62+ messages in thread

* [PATCH v9 06/13] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 de66319cbfb9..feb44cc03d2c 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1343,8 +1343,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 = {
@@ -1359,7 +1357,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;
 
@@ -1369,11 +1369,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] 62+ messages in thread

* [PATCH v9 07/13] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 feb44cc03d2c..d9b189632e61 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1528,37 +1528,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] 62+ messages in thread

* [PATCH v9 07/13] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() use the TZ allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 feb44cc03d2c..d9b189632e61 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1528,37 +1528,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] 62+ messages in thread

* [PATCH v9 08/13] firmware: qcom: qseecom: convert to using the cleanup helpers
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

Shrink the code by using __free() for allocations that are freed within
the same functions.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 254 ++++++------------
 1 file changed, 84 insertions(+), 170 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 32188f098ef3..1f8c5efc2b5a 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -7,6 +7,7 @@
  * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -272,11 +273,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(kfree) = NULL;
+	struct qsee_rsp_uefi_get_variable *rsp_data __free(kfree) = 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;
@@ -305,16 +306,12 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	);
 
 	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	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 +322,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 +349,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 +379,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(kfree) = NULL;
+	struct qsee_rsp_uefi_set_variable *rsp_data __free(kfree) = NULL;
 	unsigned long name_length;
 	size_t name_offs;
 	size_t guid_offs;
@@ -451,16 +426,12 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 	);
 
 	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
 	req_data->attributes = attributes;
@@ -473,10 +444,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 +454,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(kfree) = NULL;
+	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(kfree) = NULL;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -546,16 +504,12 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 	);
 
 	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	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 +521,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 +547,57 @@ 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(kfree) = NULL;
+	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(kfree) = NULL;
 	int status;
 
 	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
 	req_data->attributes = attr;
@@ -679,26 +605,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 +629,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. ---------------------------------------------- */
-- 
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] 62+ messages in thread

* [PATCH v9 08/13] firmware: qcom: qseecom: convert to using the cleanup helpers
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

Shrink the code by using __free() for allocations that are freed within
the same functions.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 254 ++++++------------
 1 file changed, 84 insertions(+), 170 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 32188f098ef3..1f8c5efc2b5a 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -7,6 +7,7 @@
  * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -272,11 +273,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(kfree) = NULL;
+	struct qsee_rsp_uefi_get_variable *rsp_data __free(kfree) = 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;
@@ -305,16 +306,12 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
 	);
 
 	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	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 +322,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 +349,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 +379,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(kfree) = NULL;
+	struct qsee_rsp_uefi_set_variable *rsp_data __free(kfree) = NULL;
 	unsigned long name_length;
 	size_t name_offs;
 	size_t guid_offs;
@@ -451,16 +426,12 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 	);
 
 	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
 	req_data->attributes = attributes;
@@ -473,10 +444,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 +454,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(kfree) = NULL;
+	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(kfree) = NULL;
+	efi_status_t efi_status;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
@@ -546,16 +504,12 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
 	);
 
 	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	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 +521,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 +547,57 @@ 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(kfree) = NULL;
+	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(kfree) = NULL;
 	int status;
 
 	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
-	if (!req_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out;
-	}
+	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;
-	}
+	if (!rsp_data)
+		return EFI_OUT_OF_RESOURCES;
 
 	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
 	req_data->attributes = attr;
@@ -679,26 +605,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 +629,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. ---------------------------------------------- */
-- 
2.40.1


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

* [PATCH v9 09/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

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. As this is largely a module separate from
the SCM driver, let's use a separate memory pool. Set the initial size to
4K and - if we run out - add twice the current amount to the pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 47 ++++++++++++-------
 drivers/firmware/qcom/qcom_scm.c              | 30 +++---------
 include/linux/firmware/qcom/qcom_qseecom.h    |  4 +-
 3 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 1f8c5efc2b5a..0bb13c8225c2 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -14,11 +14,14 @@
 #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. -------------------------- */
 
@@ -254,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)
@@ -273,8 +277,8 @@ 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 __free(kfree) = NULL;
-	struct qsee_rsp_uefi_get_variable *rsp_data __free(kfree) = NULL;
+	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;
 	unsigned long name_length;
 	efi_status_t efi_status;
@@ -305,11 +309,11 @@ 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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -394,8 +398,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 					   const efi_guid_t *guid, u32 attributes,
 					   unsigned long data_size, const void *data)
 {
-	struct qsee_req_uefi_set_variable *req_data __free(kfree) = NULL;
-	struct qsee_rsp_uefi_set_variable *rsp_data __free(kfree) = NULL;
+	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;
@@ -425,11 +429,11 @@ 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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -476,8 +480,8 @@ 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 __free(kfree) = NULL;
-	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(kfree) = NULL;
+	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;
@@ -503,11 +507,11 @@ 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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -587,15 +591,15 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 						  u64 *storage_space, u64 *remaining_space,
 						  u64 *max_variable_size)
 {
-	struct qsee_req_uefi_query_variable_info *req_data __free(kfree) = NULL;
-	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(kfree) = NULL;
+	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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -740,6 +744,7 @@ static const struct efivar_operations qcom_efivar_ops = {
 static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 				 const struct auxiliary_device_id *aux_dev_id)
 {
+	struct qcom_tzmem_pool_config pool_config;
 	struct qcuefi_client *qcuefi;
 	int status;
 
@@ -758,6 +763,16 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 	if (status)
 		qcuefi_set_reference(NULL);
 
+	memset(&pool_config, 0, sizeof(pool_config));
+	pool_config.initial_size = SZ_4K;
+	pool_config.policy = QCOM_TZMEM_POLICY_MULTIPLIER;
+	pool_config.increment = 2;
+	pool_config.max_size = SZ_256K;
+
+	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, &pool_config);
+	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 d9b189632e61..f871af4af829 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1570,9 +1570,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
@@ -1588,26 +1588,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;
@@ -1625,10 +1611,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] 62+ messages in thread

* [PATCH v9 09/13] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

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. As this is largely a module separate from
the SCM driver, let's use a separate memory pool. Set the initial size to
4K and - if we run out - add twice the current amount to the pool.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 .../firmware/qcom/qcom_qseecom_uefisecapp.c   | 47 ++++++++++++-------
 drivers/firmware/qcom/qcom_scm.c              | 30 +++---------
 include/linux/firmware/qcom/qcom_qseecom.h    |  4 +-
 3 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 1f8c5efc2b5a..0bb13c8225c2 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -14,11 +14,14 @@
 #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. -------------------------- */
 
@@ -254,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)
@@ -273,8 +277,8 @@ 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 __free(kfree) = NULL;
-	struct qsee_rsp_uefi_get_variable *rsp_data __free(kfree) = NULL;
+	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;
 	unsigned long name_length;
 	efi_status_t efi_status;
@@ -305,11 +309,11 @@ 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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -394,8 +398,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
 					   const efi_guid_t *guid, u32 attributes,
 					   unsigned long data_size, const void *data)
 {
-	struct qsee_req_uefi_set_variable *req_data __free(kfree) = NULL;
-	struct qsee_rsp_uefi_set_variable *rsp_data __free(kfree) = NULL;
+	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;
@@ -425,11 +429,11 @@ 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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -476,8 +480,8 @@ 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 __free(kfree) = NULL;
-	struct qsee_rsp_uefi_get_next_variable *rsp_data __free(kfree) = NULL;
+	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;
@@ -503,11 +507,11 @@ 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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -587,15 +591,15 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
 						  u64 *storage_space, u64 *remaining_space,
 						  u64 *max_variable_size)
 {
-	struct qsee_req_uefi_query_variable_info *req_data __free(kfree) = NULL;
-	struct qsee_rsp_uefi_query_variable_info *rsp_data __free(kfree) = NULL;
+	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);
+	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);
+	rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), GFP_KERNEL);
 	if (!rsp_data)
 		return EFI_OUT_OF_RESOURCES;
 
@@ -740,6 +744,7 @@ static const struct efivar_operations qcom_efivar_ops = {
 static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 				 const struct auxiliary_device_id *aux_dev_id)
 {
+	struct qcom_tzmem_pool_config pool_config;
 	struct qcuefi_client *qcuefi;
 	int status;
 
@@ -758,6 +763,16 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev,
 	if (status)
 		qcuefi_set_reference(NULL);
 
+	memset(&pool_config, 0, sizeof(pool_config));
+	pool_config.initial_size = SZ_4K;
+	pool_config.policy = QCOM_TZMEM_POLICY_MULTIPLIER;
+	pool_config.increment = 2;
+	pool_config.max_size = SZ_256K;
+
+	qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, &pool_config);
+	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 d9b189632e61..f871af4af829 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1570,9 +1570,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
@@ -1588,26 +1588,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;
@@ -1625,10 +1611,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] 62+ messages in thread

* [PATCH v9 10/13] firmware: qcom: scm: add support for SHM bridge operations
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

SHM Bridge is a safety mechanism allowing to limit the amount of memory
shared between the kernel and the TrustZone to regions explicitly marked
as such.

Add low-level primitives for enabling SHM bridge support as well as
creating and destroying SHM bridges 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 f871af4af829..7a8d67c7b71c 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1326,6 +1326,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] 62+ messages in thread

* [PATCH v9 10/13] firmware: qcom: scm: add support for SHM bridge operations
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

SHM Bridge is a safety mechanism allowing to limit the amount of memory
shared between the kernel and the TrustZone to regions explicitly marked
as such.

Add low-level primitives for enabling SHM bridge support as well as
creating and destroying SHM bridges 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 f871af4af829..7a8d67c7b71c 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -1326,6 +1326,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] 62+ messages in thread

* [PATCH v9 11/13] firmware: qcom: tzmem: enable SHM Bridge support
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

SHM Bridge is a safety mechanism allowing to limit the amount of memory
shared between the kernel and the TrustZone to regions explicitly marked
as such.

Add a variant of the tzmem allocator that configures the memory pools as
SHM bridges. It also enables the SHM bridge globally so non-SHM bridge
memory will no longer work with SCM calls.

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 fall back to the generic 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 | 64 +++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 4634f8cecc7b..7f6eb4174734 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_GENERIC
 	  Use the generic allocator mode. The memory is page-aligned, non-cachable
 	  and physically contiguous.
 
+config QCOM_TZMEM_MODE_SHMBRIDGE
+	bool "SHM Bridge"
+	help
+	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
+	  in the 'Generic' 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 9082966c7e1f..570fda7b1aad 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -67,7 +67,69 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
 
 }
 
-#endif /* CONFIG_QCOM_TZMEM_MODE_GENERIC */
+#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_area(struct qcom_tzmem_area *area)
+{
+	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags;
+	int ret;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	pfn_and_ns_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
+	ipfn_and_s_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
+	size_and_flags = area->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;
+
+	area->priv = no_free_ptr(handle);
+
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
+{
+	u64 *handle = area->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 */
 
 static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,
 				      size_t size, gfp_t gfp)
-- 
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] 62+ messages in thread

* [PATCH v9 11/13] firmware: qcom: tzmem: enable SHM Bridge support
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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>

SHM Bridge is a safety mechanism allowing to limit the amount of memory
shared between the kernel and the TrustZone to regions explicitly marked
as such.

Add a variant of the tzmem allocator that configures the memory pools as
SHM bridges. It also enables the SHM bridge globally so non-SHM bridge
memory will no longer work with SCM calls.

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 fall back to the generic 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 | 64 +++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
index 4634f8cecc7b..7f6eb4174734 100644
--- a/drivers/firmware/qcom/Kconfig
+++ b/drivers/firmware/qcom/Kconfig
@@ -28,6 +28,16 @@ config QCOM_TZMEM_MODE_GENERIC
 	  Use the generic allocator mode. The memory is page-aligned, non-cachable
 	  and physically contiguous.
 
+config QCOM_TZMEM_MODE_SHMBRIDGE
+	bool "SHM Bridge"
+	help
+	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
+	  in the 'Generic' 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 9082966c7e1f..570fda7b1aad 100644
--- a/drivers/firmware/qcom/qcom_tzmem.c
+++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -67,7 +67,69 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
 
 }
 
-#endif /* CONFIG_QCOM_TZMEM_MODE_GENERIC */
+#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_area(struct qcom_tzmem_area *area)
+{
+	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags;
+	int ret;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	pfn_and_ns_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
+	ipfn_and_s_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
+	size_and_flags = area->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;
+
+	area->priv = no_free_ptr(handle);
+
+	return 0;
+}
+
+static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
+{
+	u64 *handle = area->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 */
 
 static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,
 				      size_t size, gfp_t gfp)
-- 
2.40.1


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

* [PATCH v9 12/13] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 7a8d67c7b71c..1972757f8931 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -563,6 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
 	 * 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.
+	 *
+	 * For PIL calls the hypervisor creates SHM Bridges for the blob
+	 * buffers on behalf of Linus so we must not do it ourselves hence
+	 * not using the TZMem allocator here.
+	 *
+	 * 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] 62+ messages in thread

* [PATCH v9 12/13] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image()
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 7a8d67c7b71c..1972757f8931 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -563,6 +563,13 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
 	 * 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.
+	 *
+	 * For PIL calls the hypervisor creates SHM Bridges for the blob
+	 * buffers on behalf of Linus so we must not do it ourselves hence
+	 * not using the TZMem allocator here.
+	 *
+	 * 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] 62+ messages in thread

* [PATCH v9 13/13] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 generic 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>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c45a465a071..37280815dc6f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -255,6 +255,7 @@ CONFIG_GOOGLE_CBMEM=m
 CONFIG_GOOGLE_COREBOOT_TABLE=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] 62+ messages in thread

* [PATCH v9 13/13] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator
@ 2024-03-25 10:03   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:03 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 generic 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>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c45a465a071..37280815dc6f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -255,6 +255,7 @@ CONFIG_GOOGLE_CBMEM=m
 CONFIG_GOOGLE_COREBOOT_TABLE=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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-25 10:03 ` Bartosz Golaszewski
@ 2024-03-25 10:08   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:08 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, Mar 25, 2024 at 11:04 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> SCM calls that take memory buffers as arguments require that they be
> page-aligned, physically continuous and non-cachable. The same
> requirements apply to the buffer used to pass additional arguments to SCM
> calls that take more than 4.
>
> To that end drivers typically use dma_alloc_coherent() to allocate memory
> of suitable format which is slow and inefficient space-wise.
>
> SHM Bridge is a safety mechanism that - once enabled - will only allow
> passing buffers to the TrustZone that have been explicitly marked as
> shared. It improves the overall system safety with SCM calls and is
> required by the upcoming scminvoke functionality.
>
> The end goal of this series is to enable SHM bridge support for those
> architectures that support it but to that end we first need to unify the
> way memory for SCM calls is allocated. This in itself is beneficial as
> the current approach of using dma_alloc_coherent() in most places is quite
> slow.
>
> First let's add a new TZ Memory allocator that allows users to create
> dynamic memory pools of format suitable for sharing with the TrustZone.
> Make it ready for implementing multiple build-time modes.
>
> Convert all relevant drivers to using it. Add separate pools for SCM core
> and for qseecom.
>
> Finally add support for SHM bridge and make it the default mode of
> operation with the generic allocator as fallback for the platforms that
> don't support SHM bridge.
>
> Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
> sa8775p-ride and lenovo X13s (please do retest on those platforms if you
> can).
>

The Subject should have been "firmware: qcom: implement support for
and enable SHM bridge", sorry for the mixup.

Bartosz

_______________________________________________
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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
@ 2024-03-25 10:08   ` Bartosz Golaszewski
  0 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-25 10:08 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, Mar 25, 2024 at 11:04 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> SCM calls that take memory buffers as arguments require that they be
> page-aligned, physically continuous and non-cachable. The same
> requirements apply to the buffer used to pass additional arguments to SCM
> calls that take more than 4.
>
> To that end drivers typically use dma_alloc_coherent() to allocate memory
> of suitable format which is slow and inefficient space-wise.
>
> SHM Bridge is a safety mechanism that - once enabled - will only allow
> passing buffers to the TrustZone that have been explicitly marked as
> shared. It improves the overall system safety with SCM calls and is
> required by the upcoming scminvoke functionality.
>
> The end goal of this series is to enable SHM bridge support for those
> architectures that support it but to that end we first need to unify the
> way memory for SCM calls is allocated. This in itself is beneficial as
> the current approach of using dma_alloc_coherent() in most places is quite
> slow.
>
> First let's add a new TZ Memory allocator that allows users to create
> dynamic memory pools of format suitable for sharing with the TrustZone.
> Make it ready for implementing multiple build-time modes.
>
> Convert all relevant drivers to using it. Add separate pools for SCM core
> and for qseecom.
>
> Finally add support for SHM bridge and make it the default mode of
> operation with the generic allocator as fallback for the platforms that
> don't support SHM bridge.
>
> Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
> sa8775p-ride and lenovo X13s (please do retest on those platforms if you
> can).
>

The Subject should have been "firmware: qcom: implement support for
and enable SHM bridge", sorry for the mixup.

Bartosz

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

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

On 3/25/24 11:03 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> SCM calls that take memory buffers as arguments require that they be
> page-aligned, physically continuous and non-cachable. The same
> requirements apply to the buffer used to pass additional arguments to SCM
> calls that take more than 4.
> 
> To that end drivers typically use dma_alloc_coherent() to allocate memory
> of suitable format which is slow and inefficient space-wise.
> 
> SHM Bridge is a safety mechanism that - once enabled - will only allow
> passing buffers to the TrustZone that have been explicitly marked as
> shared. It improves the overall system safety with SCM calls and is
> required by the upcoming scminvoke functionality.
> 
> The end goal of this series is to enable SHM bridge support for those
> architectures that support it but to that end we first need to unify the
> way memory for SCM calls is allocated. This in itself is beneficial as
> the current approach of using dma_alloc_coherent() in most places is quite
> slow.
> 
> First let's add a new TZ Memory allocator that allows users to create
> dynamic memory pools of format suitable for sharing with the TrustZone.
> Make it ready for implementing multiple build-time modes.
> 
> Convert all relevant drivers to using it. Add separate pools for SCM core
> and for qseecom.
> 
> Finally add support for SHM bridge and make it the default mode of
> operation with the generic allocator as fallback for the platforms that
> don't support SHM bridge.
> 
> Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
> sa8775p-ride and lenovo X13s (please do retest on those platforms if you
> can).

Not sure in which version things changed (I haven't really kept up with
that, sorry), but this version (with the generic allocator selected in
the config) fails reading EFI vars on my Surface Pro X (sc8180x):

[    2.381020] BUG: scheduling while atomic: mount/258/0x00000002
[    2.383356] Modules linked in:
[    2.385669] Preemption disabled at:
[    2.385672] [<ffff800080f7868c>] qcom_tzmem_alloc+0x7c/0x224
[    2.390325] CPU: 1 PID: 258 Comm: mount Not tainted 6.8.0-1-surface-dev #2
[    2.392632] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
[    2.394955] Call trace:
[    2.397269]  dump_backtrace+0x94/0x114
[    2.399583]  show_stack+0x18/0x24
[    2.401883]  dump_stack_lvl+0x48/0x60
[    2.404181]  dump_stack+0x18/0x24
[    2.406476]  __schedule_bug+0x84/0xa0
[    2.408770]  __schedule+0x6f4/0x7fc
[    2.411051]  schedule+0x30/0xf0
[    2.413323]  synchronize_rcu_expedited+0x158/0x1ec
[    2.415594]  lru_cache_disable+0x28/0x74
[    2.417853]  __alloc_contig_migrate_range+0x68/0x210
[    2.420122]  alloc_contig_range+0x140/0x280
[    2.422384]  cma_alloc+0x128/0x404
[    2.424643]  cma_alloc_aligned+0x44/0x6c
[    2.426881]  dma_alloc_contiguous+0x30/0x44
[    2.429111]  __dma_direct_alloc_pages.isra.0+0x60/0x20c
[    2.431343]  dma_direct_alloc+0x6c/0x2ec
[    2.433569]  dma_alloc_attrs+0x80/0xf4
[    2.435786]  qcom_tzmem_pool_add_memory+0x8c/0x178
[    2.438008]  qcom_tzmem_alloc+0xe8/0x224
[    2.440232]  qsee_uefi_get_next_variable+0x78/0x2cc
[    2.442443]  qcuefi_get_next_variable+0x50/0x94
[    2.444643]  efivar_get_next_variable+0x20/0x2c
[    2.446832]  efivar_init+0x8c/0x29c
[    2.449009]  efivarfs_fill_super+0xd4/0xec
[    2.451182]  get_tree_single+0x74/0xbc
[    2.453349]  efivarfs_get_tree+0x18/0x24
[    2.455513]  vfs_get_tree+0x28/0xe8
[    2.457680]  vfs_cmd_create+0x5c/0xf4
[    2.459840]  __do_sys_fsconfig+0x458/0x598
[    2.461993]  __arm64_sys_fsconfig+0x24/0x30
[    2.464143]  invoke_syscall+0x48/0x110
[    2.466281]  el0_svc_common.constprop.0+0x40/0xe0
[    2.468415]  do_el0_svc+0x1c/0x28
[    2.470546]  el0_svc+0x34/0xb4
[    2.472669]  el0t_64_sync_handler+0x120/0x12c
[    2.474793]  el0t_64_sync+0x190/0x194

and subsequently

[    2.477613] DEBUG_LOCKS_WARN_ON(val > preempt_count())
[    2.477618] WARNING: CPU: 4 PID: 258 at kernel/sched/core.c:5889 preempt_count_sub+0x90/0xd4
[    2.478682] Modules linked in:
[    2.479214] CPU: 4 PID: 258 Comm: mount Tainted: G        W          6.8.0-1-surface-dev #2
[    2.479752] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
[    2.480296] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    2.480839] pc : preempt_count_sub+0x90/0xd4
[    2.481380] lr : preempt_count_sub+0x90/0xd4
[    2.481917] sp : ffff8000857cbb00
[    2.482450] x29: ffff8000857cbb00 x28: ffff8000806b759c x27: 8000000000000005
[    2.482988] x26: 0000000000000000 x25: ffff0000802cbaa0 x24: ffff0000809228b0
[    2.483525] x23: 0000000000000000 x22: ffff800082b462f0 x21: 0000000000001000
[    2.484062] x20: ffff80008363d000 x19: ffff000080922880 x18: fffffffffffc9660
[    2.484600] x17: 0000000000000020 x16: 0000000000000000 x15: 0000000000000038
[    2.485137] x14: 0000000000000000 x13: ffff800082649258 x12: 00000000000006db
[    2.485674] x11: 0000000000000249 x10: ffff8000826fc930 x9 : ffff800082649258
[    2.486207] x8 : 00000000ffffdfff x7 : ffff8000826f9258 x6 : 0000000000000249
[    2.486738] x5 : 0000000000000000 x4 : 40000000ffffe249 x3 : 0000000000000000
[    2.487267] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000841fa300
[    2.487792] Call trace:
[    2.488311]  preempt_count_sub+0x90/0xd4
[    2.488831]  _raw_spin_unlock_irqrestore+0x1c/0x44
[    2.489352]  qcom_tzmem_alloc+0x1cc/0x224
[    2.489873]  qsee_uefi_get_next_variable+0x78/0x2cc
[    2.490390]  qcuefi_get_next_variable+0x50/0x94
[    2.490907]  efivar_get_next_variable+0x20/0x2c
[    2.491420]  efivar_init+0x8c/0x29c
[    2.491931]  efivarfs_fill_super+0xd4/0xec
[    2.492440]  get_tree_single+0x74/0xbc
[    2.492948]  efivarfs_get_tree+0x18/0x24
[    2.493453]  vfs_get_tree+0x28/0xe8
[    2.493957]  vfs_cmd_create+0x5c/0xf4
[    2.494459]  __do_sys_fsconfig+0x458/0x598
[    2.494963]  __arm64_sys_fsconfig+0x24/0x30
[    2.495468]  invoke_syscall+0x48/0x110
[    2.495972]  el0_svc_common.constprop.0+0x40/0xe0
[    2.496475]  do_el0_svc+0x1c/0x28
[    2.496976]  el0_svc+0x34/0xb4
[    2.497475]  el0t_64_sync_handler+0x120/0x12c
[    2.497975]  el0t_64_sync+0x190/0x194
[    2.498466] ---[ end trace 0000000000000000 ]---
[    2.507347] qcom_scm firmware:scm: qseecom: scm call failed with error -22
[    2.507813] efivars: get_next_variable: status=8000000000000007

If I understand correctly, it enters an atomic section in
qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
So this shouldn't be qseecom specific.

I should probably also say that I'm currently testing this on a patched
v6.8 kernel, so there's a chance that it's my fault. However, as far as
I understand, it enters an atomic section in qcom_tzmem_alloc() and then
later tries to expand the pool memory with dma_alloc_coherent(). Which
AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
issue here).

I've also tried the shmem allocator option, but that seems to get stuck
quite early at boot, before I even have usb-serial access to get any
logs. If I can find some more time, I'll try to see if I can get some
useful output for that.

Best regards,
Max

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

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

On 3/25/24 11:03 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> SCM calls that take memory buffers as arguments require that they be
> page-aligned, physically continuous and non-cachable. The same
> requirements apply to the buffer used to pass additional arguments to SCM
> calls that take more than 4.
> 
> To that end drivers typically use dma_alloc_coherent() to allocate memory
> of suitable format which is slow and inefficient space-wise.
> 
> SHM Bridge is a safety mechanism that - once enabled - will only allow
> passing buffers to the TrustZone that have been explicitly marked as
> shared. It improves the overall system safety with SCM calls and is
> required by the upcoming scminvoke functionality.
> 
> The end goal of this series is to enable SHM bridge support for those
> architectures that support it but to that end we first need to unify the
> way memory for SCM calls is allocated. This in itself is beneficial as
> the current approach of using dma_alloc_coherent() in most places is quite
> slow.
> 
> First let's add a new TZ Memory allocator that allows users to create
> dynamic memory pools of format suitable for sharing with the TrustZone.
> Make it ready for implementing multiple build-time modes.
> 
> Convert all relevant drivers to using it. Add separate pools for SCM core
> and for qseecom.
> 
> Finally add support for SHM bridge and make it the default mode of
> operation with the generic allocator as fallback for the platforms that
> don't support SHM bridge.
> 
> Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
> sa8775p-ride and lenovo X13s (please do retest on those platforms if you
> can).

Not sure in which version things changed (I haven't really kept up with
that, sorry), but this version (with the generic allocator selected in
the config) fails reading EFI vars on my Surface Pro X (sc8180x):

[    2.381020] BUG: scheduling while atomic: mount/258/0x00000002
[    2.383356] Modules linked in:
[    2.385669] Preemption disabled at:
[    2.385672] [<ffff800080f7868c>] qcom_tzmem_alloc+0x7c/0x224
[    2.390325] CPU: 1 PID: 258 Comm: mount Not tainted 6.8.0-1-surface-dev #2
[    2.392632] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
[    2.394955] Call trace:
[    2.397269]  dump_backtrace+0x94/0x114
[    2.399583]  show_stack+0x18/0x24
[    2.401883]  dump_stack_lvl+0x48/0x60
[    2.404181]  dump_stack+0x18/0x24
[    2.406476]  __schedule_bug+0x84/0xa0
[    2.408770]  __schedule+0x6f4/0x7fc
[    2.411051]  schedule+0x30/0xf0
[    2.413323]  synchronize_rcu_expedited+0x158/0x1ec
[    2.415594]  lru_cache_disable+0x28/0x74
[    2.417853]  __alloc_contig_migrate_range+0x68/0x210
[    2.420122]  alloc_contig_range+0x140/0x280
[    2.422384]  cma_alloc+0x128/0x404
[    2.424643]  cma_alloc_aligned+0x44/0x6c
[    2.426881]  dma_alloc_contiguous+0x30/0x44
[    2.429111]  __dma_direct_alloc_pages.isra.0+0x60/0x20c
[    2.431343]  dma_direct_alloc+0x6c/0x2ec
[    2.433569]  dma_alloc_attrs+0x80/0xf4
[    2.435786]  qcom_tzmem_pool_add_memory+0x8c/0x178
[    2.438008]  qcom_tzmem_alloc+0xe8/0x224
[    2.440232]  qsee_uefi_get_next_variable+0x78/0x2cc
[    2.442443]  qcuefi_get_next_variable+0x50/0x94
[    2.444643]  efivar_get_next_variable+0x20/0x2c
[    2.446832]  efivar_init+0x8c/0x29c
[    2.449009]  efivarfs_fill_super+0xd4/0xec
[    2.451182]  get_tree_single+0x74/0xbc
[    2.453349]  efivarfs_get_tree+0x18/0x24
[    2.455513]  vfs_get_tree+0x28/0xe8
[    2.457680]  vfs_cmd_create+0x5c/0xf4
[    2.459840]  __do_sys_fsconfig+0x458/0x598
[    2.461993]  __arm64_sys_fsconfig+0x24/0x30
[    2.464143]  invoke_syscall+0x48/0x110
[    2.466281]  el0_svc_common.constprop.0+0x40/0xe0
[    2.468415]  do_el0_svc+0x1c/0x28
[    2.470546]  el0_svc+0x34/0xb4
[    2.472669]  el0t_64_sync_handler+0x120/0x12c
[    2.474793]  el0t_64_sync+0x190/0x194

and subsequently

[    2.477613] DEBUG_LOCKS_WARN_ON(val > preempt_count())
[    2.477618] WARNING: CPU: 4 PID: 258 at kernel/sched/core.c:5889 preempt_count_sub+0x90/0xd4
[    2.478682] Modules linked in:
[    2.479214] CPU: 4 PID: 258 Comm: mount Tainted: G        W          6.8.0-1-surface-dev #2
[    2.479752] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
[    2.480296] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    2.480839] pc : preempt_count_sub+0x90/0xd4
[    2.481380] lr : preempt_count_sub+0x90/0xd4
[    2.481917] sp : ffff8000857cbb00
[    2.482450] x29: ffff8000857cbb00 x28: ffff8000806b759c x27: 8000000000000005
[    2.482988] x26: 0000000000000000 x25: ffff0000802cbaa0 x24: ffff0000809228b0
[    2.483525] x23: 0000000000000000 x22: ffff800082b462f0 x21: 0000000000001000
[    2.484062] x20: ffff80008363d000 x19: ffff000080922880 x18: fffffffffffc9660
[    2.484600] x17: 0000000000000020 x16: 0000000000000000 x15: 0000000000000038
[    2.485137] x14: 0000000000000000 x13: ffff800082649258 x12: 00000000000006db
[    2.485674] x11: 0000000000000249 x10: ffff8000826fc930 x9 : ffff800082649258
[    2.486207] x8 : 00000000ffffdfff x7 : ffff8000826f9258 x6 : 0000000000000249
[    2.486738] x5 : 0000000000000000 x4 : 40000000ffffe249 x3 : 0000000000000000
[    2.487267] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000841fa300
[    2.487792] Call trace:
[    2.488311]  preempt_count_sub+0x90/0xd4
[    2.488831]  _raw_spin_unlock_irqrestore+0x1c/0x44
[    2.489352]  qcom_tzmem_alloc+0x1cc/0x224
[    2.489873]  qsee_uefi_get_next_variable+0x78/0x2cc
[    2.490390]  qcuefi_get_next_variable+0x50/0x94
[    2.490907]  efivar_get_next_variable+0x20/0x2c
[    2.491420]  efivar_init+0x8c/0x29c
[    2.491931]  efivarfs_fill_super+0xd4/0xec
[    2.492440]  get_tree_single+0x74/0xbc
[    2.492948]  efivarfs_get_tree+0x18/0x24
[    2.493453]  vfs_get_tree+0x28/0xe8
[    2.493957]  vfs_cmd_create+0x5c/0xf4
[    2.494459]  __do_sys_fsconfig+0x458/0x598
[    2.494963]  __arm64_sys_fsconfig+0x24/0x30
[    2.495468]  invoke_syscall+0x48/0x110
[    2.495972]  el0_svc_common.constprop.0+0x40/0xe0
[    2.496475]  do_el0_svc+0x1c/0x28
[    2.496976]  el0_svc+0x34/0xb4
[    2.497475]  el0t_64_sync_handler+0x120/0x12c
[    2.497975]  el0t_64_sync+0x190/0x194
[    2.498466] ---[ end trace 0000000000000000 ]---
[    2.507347] qcom_scm firmware:scm: qseecom: scm call failed with error -22
[    2.507813] efivars: get_next_variable: status=8000000000000007

If I understand correctly, it enters an atomic section in
qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
So this shouldn't be qseecom specific.

I should probably also say that I'm currently testing this on a patched
v6.8 kernel, so there's a chance that it's my fault. However, as far as
I understand, it enters an atomic section in qcom_tzmem_alloc() and then
later tries to expand the pool memory with dma_alloc_coherent(). Which
AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
issue here).

I've also tried the shmem allocator option, but that seems to get stuck
quite early at boot, before I even have usb-serial access to get any
logs. If I can find some more time, I'll try to see if I can get some
useful output for that.

Best regards,
Max

_______________________________________________
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] 62+ messages in thread

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

On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> On 3/25/24 11:03 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > SCM calls that take memory buffers as arguments require that they be
> > page-aligned, physically continuous and non-cachable. The same
> > requirements apply to the buffer used to pass additional arguments to SCM
> > calls that take more than 4.
> >
> > To that end drivers typically use dma_alloc_coherent() to allocate memory
> > of suitable format which is slow and inefficient space-wise.
> >
> > SHM Bridge is a safety mechanism that - once enabled - will only allow
> > passing buffers to the TrustZone that have been explicitly marked as
> > shared. It improves the overall system safety with SCM calls and is
> > required by the upcoming scminvoke functionality.
> >
> > The end goal of this series is to enable SHM bridge support for those
> > architectures that support it but to that end we first need to unify the
> > way memory for SCM calls is allocated. This in itself is beneficial as
> > the current approach of using dma_alloc_coherent() in most places is quite
> > slow.
> >
> > First let's add a new TZ Memory allocator that allows users to create
> > dynamic memory pools of format suitable for sharing with the TrustZone.
> > Make it ready for implementing multiple build-time modes.
> >
> > Convert all relevant drivers to using it. Add separate pools for SCM core
> > and for qseecom.
> >
> > Finally add support for SHM bridge and make it the default mode of
> > operation with the generic allocator as fallback for the platforms that
> > don't support SHM bridge.
> >
> > Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
> > sa8775p-ride and lenovo X13s (please do retest on those platforms if you
> > can).
>
> Not sure in which version things changed (I haven't really kept up with
> that, sorry), but this version (with the generic allocator selected in
> the config) fails reading EFI vars on my Surface Pro X (sc8180x):
>
> [    2.381020] BUG: scheduling while atomic: mount/258/0x00000002
> [    2.383356] Modules linked in:
> [    2.385669] Preemption disabled at:
> [    2.385672] [<ffff800080f7868c>] qcom_tzmem_alloc+0x7c/0x224
> [    2.390325] CPU: 1 PID: 258 Comm: mount Not tainted 6.8.0-1-surface-dev #2
> [    2.392632] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
> [    2.394955] Call trace:
> [    2.397269]  dump_backtrace+0x94/0x114
> [    2.399583]  show_stack+0x18/0x24
> [    2.401883]  dump_stack_lvl+0x48/0x60
> [    2.404181]  dump_stack+0x18/0x24
> [    2.406476]  __schedule_bug+0x84/0xa0
> [    2.408770]  __schedule+0x6f4/0x7fc
> [    2.411051]  schedule+0x30/0xf0
> [    2.413323]  synchronize_rcu_expedited+0x158/0x1ec
> [    2.415594]  lru_cache_disable+0x28/0x74
> [    2.417853]  __alloc_contig_migrate_range+0x68/0x210
> [    2.420122]  alloc_contig_range+0x140/0x280
> [    2.422384]  cma_alloc+0x128/0x404
> [    2.424643]  cma_alloc_aligned+0x44/0x6c
> [    2.426881]  dma_alloc_contiguous+0x30/0x44
> [    2.429111]  __dma_direct_alloc_pages.isra.0+0x60/0x20c
> [    2.431343]  dma_direct_alloc+0x6c/0x2ec
> [    2.433569]  dma_alloc_attrs+0x80/0xf4
> [    2.435786]  qcom_tzmem_pool_add_memory+0x8c/0x178
> [    2.438008]  qcom_tzmem_alloc+0xe8/0x224
> [    2.440232]  qsee_uefi_get_next_variable+0x78/0x2cc
> [    2.442443]  qcuefi_get_next_variable+0x50/0x94
> [    2.444643]  efivar_get_next_variable+0x20/0x2c
> [    2.446832]  efivar_init+0x8c/0x29c
> [    2.449009]  efivarfs_fill_super+0xd4/0xec
> [    2.451182]  get_tree_single+0x74/0xbc
> [    2.453349]  efivarfs_get_tree+0x18/0x24
> [    2.455513]  vfs_get_tree+0x28/0xe8
> [    2.457680]  vfs_cmd_create+0x5c/0xf4
> [    2.459840]  __do_sys_fsconfig+0x458/0x598
> [    2.461993]  __arm64_sys_fsconfig+0x24/0x30
> [    2.464143]  invoke_syscall+0x48/0x110
> [    2.466281]  el0_svc_common.constprop.0+0x40/0xe0
> [    2.468415]  do_el0_svc+0x1c/0x28
> [    2.470546]  el0_svc+0x34/0xb4
> [    2.472669]  el0t_64_sync_handler+0x120/0x12c
> [    2.474793]  el0t_64_sync+0x190/0x194
>
> and subsequently
>
> [    2.477613] DEBUG_LOCKS_WARN_ON(val > preempt_count())
> [    2.477618] WARNING: CPU: 4 PID: 258 at kernel/sched/core.c:5889 preempt_count_sub+0x90/0xd4
> [    2.478682] Modules linked in:
> [    2.479214] CPU: 4 PID: 258 Comm: mount Tainted: G        W          6.8.0-1-surface-dev #2
> [    2.479752] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
> [    2.480296] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [    2.480839] pc : preempt_count_sub+0x90/0xd4
> [    2.481380] lr : preempt_count_sub+0x90/0xd4
> [    2.481917] sp : ffff8000857cbb00
> [    2.482450] x29: ffff8000857cbb00 x28: ffff8000806b759c x27: 8000000000000005
> [    2.482988] x26: 0000000000000000 x25: ffff0000802cbaa0 x24: ffff0000809228b0
> [    2.483525] x23: 0000000000000000 x22: ffff800082b462f0 x21: 0000000000001000
> [    2.484062] x20: ffff80008363d000 x19: ffff000080922880 x18: fffffffffffc9660
> [    2.484600] x17: 0000000000000020 x16: 0000000000000000 x15: 0000000000000038
> [    2.485137] x14: 0000000000000000 x13: ffff800082649258 x12: 00000000000006db
> [    2.485674] x11: 0000000000000249 x10: ffff8000826fc930 x9 : ffff800082649258
> [    2.486207] x8 : 00000000ffffdfff x7 : ffff8000826f9258 x6 : 0000000000000249
> [    2.486738] x5 : 0000000000000000 x4 : 40000000ffffe249 x3 : 0000000000000000
> [    2.487267] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000841fa300
> [    2.487792] Call trace:
> [    2.488311]  preempt_count_sub+0x90/0xd4
> [    2.488831]  _raw_spin_unlock_irqrestore+0x1c/0x44
> [    2.489352]  qcom_tzmem_alloc+0x1cc/0x224
> [    2.489873]  qsee_uefi_get_next_variable+0x78/0x2cc
> [    2.490390]  qcuefi_get_next_variable+0x50/0x94
> [    2.490907]  efivar_get_next_variable+0x20/0x2c
> [    2.491420]  efivar_init+0x8c/0x29c
> [    2.491931]  efivarfs_fill_super+0xd4/0xec
> [    2.492440]  get_tree_single+0x74/0xbc
> [    2.492948]  efivarfs_get_tree+0x18/0x24
> [    2.493453]  vfs_get_tree+0x28/0xe8
> [    2.493957]  vfs_cmd_create+0x5c/0xf4
> [    2.494459]  __do_sys_fsconfig+0x458/0x598
> [    2.494963]  __arm64_sys_fsconfig+0x24/0x30
> [    2.495468]  invoke_syscall+0x48/0x110
> [    2.495972]  el0_svc_common.constprop.0+0x40/0xe0
> [    2.496475]  do_el0_svc+0x1c/0x28
> [    2.496976]  el0_svc+0x34/0xb4
> [    2.497475]  el0t_64_sync_handler+0x120/0x12c
> [    2.497975]  el0t_64_sync+0x190/0x194
> [    2.498466] ---[ end trace 0000000000000000 ]---
> [    2.507347] qcom_scm firmware:scm: qseecom: scm call failed with error -22
> [    2.507813] efivars: get_next_variable: status=8000000000000007
>
> If I understand correctly, it enters an atomic section in
> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
> So this shouldn't be qseecom specific.
>
> I should probably also say that I'm currently testing this on a patched
> v6.8 kernel, so there's a chance that it's my fault. However, as far as
> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
> later tries to expand the pool memory with dma_alloc_coherent(). Which
> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
> issue here).
>
> I've also tried the shmem allocator option, but that seems to get stuck
> quite early at boot, before I even have usb-serial access to get any
> logs. If I can find some more time, I'll try to see if I can get some
> useful output for that.
>

Ah, I think it happens here:

+       guard(spinlock_irqsave)(&pool->lock);
+
+again:
+       vaddr = gen_pool_alloc(pool->genpool, size);
+       if (!vaddr) {
+               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
+                       goto again;

We were called with GFP_KERNEL so this is what we pass on to
qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
to revisit it. Thanks for the catch!

Bart

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

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

On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> On 3/25/24 11:03 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > SCM calls that take memory buffers as arguments require that they be
> > page-aligned, physically continuous and non-cachable. The same
> > requirements apply to the buffer used to pass additional arguments to SCM
> > calls that take more than 4.
> >
> > To that end drivers typically use dma_alloc_coherent() to allocate memory
> > of suitable format which is slow and inefficient space-wise.
> >
> > SHM Bridge is a safety mechanism that - once enabled - will only allow
> > passing buffers to the TrustZone that have been explicitly marked as
> > shared. It improves the overall system safety with SCM calls and is
> > required by the upcoming scminvoke functionality.
> >
> > The end goal of this series is to enable SHM bridge support for those
> > architectures that support it but to that end we first need to unify the
> > way memory for SCM calls is allocated. This in itself is beneficial as
> > the current approach of using dma_alloc_coherent() in most places is quite
> > slow.
> >
> > First let's add a new TZ Memory allocator that allows users to create
> > dynamic memory pools of format suitable for sharing with the TrustZone.
> > Make it ready for implementing multiple build-time modes.
> >
> > Convert all relevant drivers to using it. Add separate pools for SCM core
> > and for qseecom.
> >
> > Finally add support for SHM bridge and make it the default mode of
> > operation with the generic allocator as fallback for the platforms that
> > don't support SHM bridge.
> >
> > Tested on db410c, RB5, sm8550-qrd. Previous iteration tested also on
> > sa8775p-ride and lenovo X13s (please do retest on those platforms if you
> > can).
>
> Not sure in which version things changed (I haven't really kept up with
> that, sorry), but this version (with the generic allocator selected in
> the config) fails reading EFI vars on my Surface Pro X (sc8180x):
>
> [    2.381020] BUG: scheduling while atomic: mount/258/0x00000002
> [    2.383356] Modules linked in:
> [    2.385669] Preemption disabled at:
> [    2.385672] [<ffff800080f7868c>] qcom_tzmem_alloc+0x7c/0x224
> [    2.390325] CPU: 1 PID: 258 Comm: mount Not tainted 6.8.0-1-surface-dev #2
> [    2.392632] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
> [    2.394955] Call trace:
> [    2.397269]  dump_backtrace+0x94/0x114
> [    2.399583]  show_stack+0x18/0x24
> [    2.401883]  dump_stack_lvl+0x48/0x60
> [    2.404181]  dump_stack+0x18/0x24
> [    2.406476]  __schedule_bug+0x84/0xa0
> [    2.408770]  __schedule+0x6f4/0x7fc
> [    2.411051]  schedule+0x30/0xf0
> [    2.413323]  synchronize_rcu_expedited+0x158/0x1ec
> [    2.415594]  lru_cache_disable+0x28/0x74
> [    2.417853]  __alloc_contig_migrate_range+0x68/0x210
> [    2.420122]  alloc_contig_range+0x140/0x280
> [    2.422384]  cma_alloc+0x128/0x404
> [    2.424643]  cma_alloc_aligned+0x44/0x6c
> [    2.426881]  dma_alloc_contiguous+0x30/0x44
> [    2.429111]  __dma_direct_alloc_pages.isra.0+0x60/0x20c
> [    2.431343]  dma_direct_alloc+0x6c/0x2ec
> [    2.433569]  dma_alloc_attrs+0x80/0xf4
> [    2.435786]  qcom_tzmem_pool_add_memory+0x8c/0x178
> [    2.438008]  qcom_tzmem_alloc+0xe8/0x224
> [    2.440232]  qsee_uefi_get_next_variable+0x78/0x2cc
> [    2.442443]  qcuefi_get_next_variable+0x50/0x94
> [    2.444643]  efivar_get_next_variable+0x20/0x2c
> [    2.446832]  efivar_init+0x8c/0x29c
> [    2.449009]  efivarfs_fill_super+0xd4/0xec
> [    2.451182]  get_tree_single+0x74/0xbc
> [    2.453349]  efivarfs_get_tree+0x18/0x24
> [    2.455513]  vfs_get_tree+0x28/0xe8
> [    2.457680]  vfs_cmd_create+0x5c/0xf4
> [    2.459840]  __do_sys_fsconfig+0x458/0x598
> [    2.461993]  __arm64_sys_fsconfig+0x24/0x30
> [    2.464143]  invoke_syscall+0x48/0x110
> [    2.466281]  el0_svc_common.constprop.0+0x40/0xe0
> [    2.468415]  do_el0_svc+0x1c/0x28
> [    2.470546]  el0_svc+0x34/0xb4
> [    2.472669]  el0t_64_sync_handler+0x120/0x12c
> [    2.474793]  el0t_64_sync+0x190/0x194
>
> and subsequently
>
> [    2.477613] DEBUG_LOCKS_WARN_ON(val > preempt_count())
> [    2.477618] WARNING: CPU: 4 PID: 258 at kernel/sched/core.c:5889 preempt_count_sub+0x90/0xd4
> [    2.478682] Modules linked in:
> [    2.479214] CPU: 4 PID: 258 Comm: mount Tainted: G        W          6.8.0-1-surface-dev #2
> [    2.479752] Hardware name: Microsoft Corporation Surface Pro X/Surface Pro X, BIOS 7.620.140 08/11/2023
> [    2.480296] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [    2.480839] pc : preempt_count_sub+0x90/0xd4
> [    2.481380] lr : preempt_count_sub+0x90/0xd4
> [    2.481917] sp : ffff8000857cbb00
> [    2.482450] x29: ffff8000857cbb00 x28: ffff8000806b759c x27: 8000000000000005
> [    2.482988] x26: 0000000000000000 x25: ffff0000802cbaa0 x24: ffff0000809228b0
> [    2.483525] x23: 0000000000000000 x22: ffff800082b462f0 x21: 0000000000001000
> [    2.484062] x20: ffff80008363d000 x19: ffff000080922880 x18: fffffffffffc9660
> [    2.484600] x17: 0000000000000020 x16: 0000000000000000 x15: 0000000000000038
> [    2.485137] x14: 0000000000000000 x13: ffff800082649258 x12: 00000000000006db
> [    2.485674] x11: 0000000000000249 x10: ffff8000826fc930 x9 : ffff800082649258
> [    2.486207] x8 : 00000000ffffdfff x7 : ffff8000826f9258 x6 : 0000000000000249
> [    2.486738] x5 : 0000000000000000 x4 : 40000000ffffe249 x3 : 0000000000000000
> [    2.487267] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000841fa300
> [    2.487792] Call trace:
> [    2.488311]  preempt_count_sub+0x90/0xd4
> [    2.488831]  _raw_spin_unlock_irqrestore+0x1c/0x44
> [    2.489352]  qcom_tzmem_alloc+0x1cc/0x224
> [    2.489873]  qsee_uefi_get_next_variable+0x78/0x2cc
> [    2.490390]  qcuefi_get_next_variable+0x50/0x94
> [    2.490907]  efivar_get_next_variable+0x20/0x2c
> [    2.491420]  efivar_init+0x8c/0x29c
> [    2.491931]  efivarfs_fill_super+0xd4/0xec
> [    2.492440]  get_tree_single+0x74/0xbc
> [    2.492948]  efivarfs_get_tree+0x18/0x24
> [    2.493453]  vfs_get_tree+0x28/0xe8
> [    2.493957]  vfs_cmd_create+0x5c/0xf4
> [    2.494459]  __do_sys_fsconfig+0x458/0x598
> [    2.494963]  __arm64_sys_fsconfig+0x24/0x30
> [    2.495468]  invoke_syscall+0x48/0x110
> [    2.495972]  el0_svc_common.constprop.0+0x40/0xe0
> [    2.496475]  do_el0_svc+0x1c/0x28
> [    2.496976]  el0_svc+0x34/0xb4
> [    2.497475]  el0t_64_sync_handler+0x120/0x12c
> [    2.497975]  el0t_64_sync+0x190/0x194
> [    2.498466] ---[ end trace 0000000000000000 ]---
> [    2.507347] qcom_scm firmware:scm: qseecom: scm call failed with error -22
> [    2.507813] efivars: get_next_variable: status=8000000000000007
>
> If I understand correctly, it enters an atomic section in
> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
> So this shouldn't be qseecom specific.
>
> I should probably also say that I'm currently testing this on a patched
> v6.8 kernel, so there's a chance that it's my fault. However, as far as
> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
> later tries to expand the pool memory with dma_alloc_coherent(). Which
> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
> issue here).
>
> I've also tried the shmem allocator option, but that seems to get stuck
> quite early at boot, before I even have usb-serial access to get any
> logs. If I can find some more time, I'll try to see if I can get some
> useful output for that.
>

Ah, I think it happens here:

+       guard(spinlock_irqsave)(&pool->lock);
+
+again:
+       vaddr = gen_pool_alloc(pool->genpool, size);
+       if (!vaddr) {
+               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
+                       goto again;

We were called with GFP_KERNEL so this is what we pass on to
qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
to revisit it. Thanks for the catch!

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] 62+ messages in thread

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

On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >
> > If I understand correctly, it enters an atomic section in
> > qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
> > So this shouldn't be qseecom specific.
> >
> > I should probably also say that I'm currently testing this on a patched
> > v6.8 kernel, so there's a chance that it's my fault. However, as far as
> > I understand, it enters an atomic section in qcom_tzmem_alloc() and then
> > later tries to expand the pool memory with dma_alloc_coherent(). Which
> > AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
> > issue here).
> >
> > I've also tried the shmem allocator option, but that seems to get stuck
> > quite early at boot, before I even have usb-serial access to get any
> > logs. If I can find some more time, I'll try to see if I can get some
> > useful output for that.
> >
>
> Ah, I think it happens here:
>
> +       guard(spinlock_irqsave)(&pool->lock);
> +
> +again:
> +       vaddr = gen_pool_alloc(pool->genpool, size);
> +       if (!vaddr) {
> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
> +                       goto again;
>
> We were called with GFP_KERNEL so this is what we pass on to
> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
> to revisit it. Thanks for the catch!
>
> Bart

Can you try the following tree?

    https://git.codelinaro.org/bartosz_golaszewski/linux.git
topic/shm-bridge-v10

gen_pool_alloc() and gen_pool_add_virt() can be used without external
serialization. We only really need to protect the list of areas in the
pool when adding a new element. We could possibly even use
list_add_tail_rcu() as it updates the pointers atomically and go
lockless.

Bart

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

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

On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >
> > If I understand correctly, it enters an atomic section in
> > qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
> > So this shouldn't be qseecom specific.
> >
> > I should probably also say that I'm currently testing this on a patched
> > v6.8 kernel, so there's a chance that it's my fault. However, as far as
> > I understand, it enters an atomic section in qcom_tzmem_alloc() and then
> > later tries to expand the pool memory with dma_alloc_coherent(). Which
> > AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
> > issue here).
> >
> > I've also tried the shmem allocator option, but that seems to get stuck
> > quite early at boot, before I even have usb-serial access to get any
> > logs. If I can find some more time, I'll try to see if I can get some
> > useful output for that.
> >
>
> Ah, I think it happens here:
>
> +       guard(spinlock_irqsave)(&pool->lock);
> +
> +again:
> +       vaddr = gen_pool_alloc(pool->genpool, size);
> +       if (!vaddr) {
> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
> +                       goto again;
>
> We were called with GFP_KERNEL so this is what we pass on to
> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
> to revisit it. Thanks for the catch!
>
> Bart

Can you try the following tree?

    https://git.codelinaro.org/bartosz_golaszewski/linux.git
topic/shm-bridge-v10

gen_pool_alloc() and gen_pool_add_virt() can be used without external
serialization. We only really need to protect the list of areas in the
pool when adding a new element. We could possibly even use
list_add_tail_rcu() as it updates the pointers atomically and go
lockless.

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] 62+ messages in thread

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

On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>
>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>
>>> If I understand correctly, it enters an atomic section in
>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
>>> So this shouldn't be qseecom specific.
>>>
>>> I should probably also say that I'm currently testing this on a patched
>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
>>> issue here).
>>>
>>> I've also tried the shmem allocator option, but that seems to get stuck
>>> quite early at boot, before I even have usb-serial access to get any
>>> logs. If I can find some more time, I'll try to see if I can get some
>>> useful output for that.
>>>
>>
>> Ah, I think it happens here:
>>
>> +       guard(spinlock_irqsave)(&pool->lock);
>> +
>> +again:
>> +       vaddr = gen_pool_alloc(pool->genpool, size);
>> +       if (!vaddr) {
>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
>> +                       goto again;
>>
>> We were called with GFP_KERNEL so this is what we pass on to
>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
>> to revisit it. Thanks for the catch!
>>
>> Bart
> 
> Can you try the following tree?
> 
>      https://git.codelinaro.org/bartosz_golaszewski/linux.git
> topic/shm-bridge-v10
> 
> gen_pool_alloc() and gen_pool_add_virt() can be used without external
> serialization. We only really need to protect the list of areas in the
> pool when adding a new element. We could possibly even use
> list_add_tail_rcu() as it updates the pointers atomically and go
> lockless.

Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
Unfortunately, with the shmbridge mode it still gets stuck at boot (and
I haven't had the time to look into it yet).

And for more bad news: It looks like the new allocator now fully exposes
a bug that I've been tracking down the last couple of days. In short,
uefisecapp doesn't seem to be happy when we split the allocations for
request and response into two, causing commands to fail. Instead it
wants a single buffer for both. Before, it seemed to be fairly sporadic
(likely because kzalloc in sequence just returned consecutive memory
almost all of the time) but now it's basically every call that fails.

I have a fix for that almost ready and I'll likely post it in the next
hour. But that means that you'll probably have to rebase this series
on top of it...

Best regards,
Max


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

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

On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>
>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>
>>> If I understand correctly, it enters an atomic section in
>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
>>> So this shouldn't be qseecom specific.
>>>
>>> I should probably also say that I'm currently testing this on a patched
>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
>>> issue here).
>>>
>>> I've also tried the shmem allocator option, but that seems to get stuck
>>> quite early at boot, before I even have usb-serial access to get any
>>> logs. If I can find some more time, I'll try to see if I can get some
>>> useful output for that.
>>>
>>
>> Ah, I think it happens here:
>>
>> +       guard(spinlock_irqsave)(&pool->lock);
>> +
>> +again:
>> +       vaddr = gen_pool_alloc(pool->genpool, size);
>> +       if (!vaddr) {
>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
>> +                       goto again;
>>
>> We were called with GFP_KERNEL so this is what we pass on to
>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
>> to revisit it. Thanks for the catch!
>>
>> Bart
> 
> Can you try the following tree?
> 
>      https://git.codelinaro.org/bartosz_golaszewski/linux.git
> topic/shm-bridge-v10
> 
> gen_pool_alloc() and gen_pool_add_virt() can be used without external
> serialization. We only really need to protect the list of areas in the
> pool when adding a new element. We could possibly even use
> list_add_tail_rcu() as it updates the pointers atomically and go
> lockless.

Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
Unfortunately, with the shmbridge mode it still gets stuck at boot (and
I haven't had the time to look into it yet).

And for more bad news: It looks like the new allocator now fully exposes
a bug that I've been tracking down the last couple of days. In short,
uefisecapp doesn't seem to be happy when we split the allocations for
request and response into two, causing commands to fail. Instead it
wants a single buffer for both. Before, it seemed to be fairly sporadic
(likely because kzalloc in sequence just returned consecutive memory
almost all of the time) but now it's basically every call that fails.

I have a fix for that almost ready and I'll likely post it in the next
hour. But that means that you'll probably have to rebase this series
on top of it...

Best regards,
Max


_______________________________________________
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] 62+ messages in thread

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



On 3/29/24 7:53 PM, Maximilian Luz wrote:
> On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
>> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>
>>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>
>>>> If I understand correctly, it enters an atomic section in
>>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
>>>> So this shouldn't be qseecom specific.
>>>>
>>>> I should probably also say that I'm currently testing this on a patched
>>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
>>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
>>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
>>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
>>>> issue here).
>>>>
>>>> I've also tried the shmem allocator option, but that seems to get stuck
>>>> quite early at boot, before I even have usb-serial access to get any
>>>> logs. If I can find some more time, I'll try to see if I can get some
>>>> useful output for that.
>>>>
>>>
>>> Ah, I think it happens here:
>>>
>>> +       guard(spinlock_irqsave)(&pool->lock);
>>> +
>>> +again:
>>> +       vaddr = gen_pool_alloc(pool->genpool, size);
>>> +       if (!vaddr) {
>>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
>>> +                       goto again;
>>>
>>> We were called with GFP_KERNEL so this is what we pass on to
>>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
>>> to revisit it. Thanks for the catch!
>>>
>>> Bart
>>
>> Can you try the following tree?
>>
>>      https://git.codelinaro.org/bartosz_golaszewski/linux.git
>> topic/shm-bridge-v10
>>
>> gen_pool_alloc() and gen_pool_add_virt() can be used without external
>> serialization. We only really need to protect the list of areas in the
>> pool when adding a new element. We could possibly even use
>> list_add_tail_rcu() as it updates the pointers atomically and go
>> lockless.
> 
> Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
> Unfortunately, with the shmbridge mode it still gets stuck at boot (and
> I haven't had the time to look into it yet).
> 
> And for more bad news: It looks like the new allocator now fully exposes
> a bug that I've been tracking down the last couple of days. In short,
> uefisecapp doesn't seem to be happy when we split the allocations for
> request and response into two, causing commands to fail. Instead it
> wants a single buffer for both. Before, it seemed to be fairly sporadic
> (likely because kzalloc in sequence just returned consecutive memory
> almost all of the time) but now it's basically every call that fails.
> 
> I have a fix for that almost ready and I'll likely post it in the next
> hour. But that means that you'll probably have to rebase this series
> on top of it...

Forgot to mention: I tested it with the fix and this series, and that
works.

> Best regards,
> Max
> 

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

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



On 3/29/24 7:53 PM, Maximilian Luz wrote:
> On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
>> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>
>>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>
>>>> If I understand correctly, it enters an atomic section in
>>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
>>>> So this shouldn't be qseecom specific.
>>>>
>>>> I should probably also say that I'm currently testing this on a patched
>>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
>>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
>>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
>>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
>>>> issue here).
>>>>
>>>> I've also tried the shmem allocator option, but that seems to get stuck
>>>> quite early at boot, before I even have usb-serial access to get any
>>>> logs. If I can find some more time, I'll try to see if I can get some
>>>> useful output for that.
>>>>
>>>
>>> Ah, I think it happens here:
>>>
>>> +       guard(spinlock_irqsave)(&pool->lock);
>>> +
>>> +again:
>>> +       vaddr = gen_pool_alloc(pool->genpool, size);
>>> +       if (!vaddr) {
>>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
>>> +                       goto again;
>>>
>>> We were called with GFP_KERNEL so this is what we pass on to
>>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
>>> to revisit it. Thanks for the catch!
>>>
>>> Bart
>>
>> Can you try the following tree?
>>
>>      https://git.codelinaro.org/bartosz_golaszewski/linux.git
>> topic/shm-bridge-v10
>>
>> gen_pool_alloc() and gen_pool_add_virt() can be used without external
>> serialization. We only really need to protect the list of areas in the
>> pool when adding a new element. We could possibly even use
>> list_add_tail_rcu() as it updates the pointers atomically and go
>> lockless.
> 
> Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
> Unfortunately, with the shmbridge mode it still gets stuck at boot (and
> I haven't had the time to look into it yet).
> 
> And for more bad news: It looks like the new allocator now fully exposes
> a bug that I've been tracking down the last couple of days. In short,
> uefisecapp doesn't seem to be happy when we split the allocations for
> request and response into two, causing commands to fail. Instead it
> wants a single buffer for both. Before, it seemed to be fairly sporadic
> (likely because kzalloc in sequence just returned consecutive memory
> almost all of the time) but now it's basically every call that fails.
> 
> I have a fix for that almost ready and I'll likely post it in the next
> hour. But that means that you'll probably have to rebase this series
> on top of it...

Forgot to mention: I tested it with the fix and this series, and that
works.

> Best regards,
> Max
> 

_______________________________________________
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] 62+ messages in thread

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

On Fri, Mar 29, 2024 at 7:56 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
>
>
> On 3/29/24 7:53 PM, Maximilian Luz wrote:
> > On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
> >> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >>>
> >>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>>>
> >>>> If I understand correctly, it enters an atomic section in
> >>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
> >>>> So this shouldn't be qseecom specific.
> >>>>
> >>>> I should probably also say that I'm currently testing this on a patched
> >>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
> >>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
> >>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
> >>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
> >>>> issue here).
> >>>>
> >>>> I've also tried the shmem allocator option, but that seems to get stuck
> >>>> quite early at boot, before I even have usb-serial access to get any
> >>>> logs. If I can find some more time, I'll try to see if I can get some
> >>>> useful output for that.
> >>>>
> >>>
> >>> Ah, I think it happens here:
> >>>
> >>> +       guard(spinlock_irqsave)(&pool->lock);
> >>> +
> >>> +again:
> >>> +       vaddr = gen_pool_alloc(pool->genpool, size);
> >>> +       if (!vaddr) {
> >>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
> >>> +                       goto again;
> >>>
> >>> We were called with GFP_KERNEL so this is what we pass on to
> >>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
> >>> to revisit it. Thanks for the catch!
> >>>
> >>> Bart
> >>
> >> Can you try the following tree?
> >>
> >>      https://git.codelinaro.org/bartosz_golaszewski/linux.git
> >> topic/shm-bridge-v10
> >>
> >> gen_pool_alloc() and gen_pool_add_virt() can be used without external
> >> serialization. We only really need to protect the list of areas in the
> >> pool when adding a new element. We could possibly even use
> >> list_add_tail_rcu() as it updates the pointers atomically and go
> >> lockless.
> >
> > Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
> > Unfortunately, with the shmbridge mode it still gets stuck at boot (and
> > I haven't had the time to look into it yet).
> >
> > And for more bad news: It looks like the new allocator now fully exposes
> > a bug that I've been tracking down the last couple of days. In short,
> > uefisecapp doesn't seem to be happy when we split the allocations for
> > request and response into two, causing commands to fail. Instead it
> > wants a single buffer for both. Before, it seemed to be fairly sporadic
> > (likely because kzalloc in sequence just returned consecutive memory
> > almost all of the time) but now it's basically every call that fails.
> >
> > I have a fix for that almost ready and I'll likely post it in the next
> > hour. But that means that you'll probably have to rebase this series
> > on top of it...
>
> Forgot to mention: I tested it with the fix and this series, and that
> works.
>

Both with and without SHM bridge?

If so, please Cc me on the fix.

Bart

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

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

On Fri, Mar 29, 2024 at 7:56 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
>
>
> On 3/29/24 7:53 PM, Maximilian Luz wrote:
> > On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
> >> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >>>
> >>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>>>
> >>>> If I understand correctly, it enters an atomic section in
> >>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
> >>>> So this shouldn't be qseecom specific.
> >>>>
> >>>> I should probably also say that I'm currently testing this on a patched
> >>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
> >>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
> >>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
> >>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
> >>>> issue here).
> >>>>
> >>>> I've also tried the shmem allocator option, but that seems to get stuck
> >>>> quite early at boot, before I even have usb-serial access to get any
> >>>> logs. If I can find some more time, I'll try to see if I can get some
> >>>> useful output for that.
> >>>>
> >>>
> >>> Ah, I think it happens here:
> >>>
> >>> +       guard(spinlock_irqsave)(&pool->lock);
> >>> +
> >>> +again:
> >>> +       vaddr = gen_pool_alloc(pool->genpool, size);
> >>> +       if (!vaddr) {
> >>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
> >>> +                       goto again;
> >>>
> >>> We were called with GFP_KERNEL so this is what we pass on to
> >>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
> >>> to revisit it. Thanks for the catch!
> >>>
> >>> Bart
> >>
> >> Can you try the following tree?
> >>
> >>      https://git.codelinaro.org/bartosz_golaszewski/linux.git
> >> topic/shm-bridge-v10
> >>
> >> gen_pool_alloc() and gen_pool_add_virt() can be used without external
> >> serialization. We only really need to protect the list of areas in the
> >> pool when adding a new element. We could possibly even use
> >> list_add_tail_rcu() as it updates the pointers atomically and go
> >> lockless.
> >
> > Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
> > Unfortunately, with the shmbridge mode it still gets stuck at boot (and
> > I haven't had the time to look into it yet).
> >
> > And for more bad news: It looks like the new allocator now fully exposes
> > a bug that I've been tracking down the last couple of days. In short,
> > uefisecapp doesn't seem to be happy when we split the allocations for
> > request and response into two, causing commands to fail. Instead it
> > wants a single buffer for both. Before, it seemed to be fairly sporadic
> > (likely because kzalloc in sequence just returned consecutive memory
> > almost all of the time) but now it's basically every call that fails.
> >
> > I have a fix for that almost ready and I'll likely post it in the next
> > hour. But that means that you'll probably have to rebase this series
> > on top of it...
>
> Forgot to mention: I tested it with the fix and this series, and that
> works.
>

Both with and without SHM bridge?

If so, please Cc me on the fix.

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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-29 19:07             ` Bartosz Golaszewski
@ 2024-03-29 19:22               ` Maximilian Luz
  -1 siblings, 0 replies; 62+ messages in thread
From: Maximilian Luz @ 2024-03-29 19:22 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Alex Elder, Srini Kandagatla, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> On Fri, Mar 29, 2024 at 7:56 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>
>>
>>
>> On 3/29/24 7:53 PM, Maximilian Luz wrote:
>>> On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
>>>> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>>>
>>>>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>
>>>>>> If I understand correctly, it enters an atomic section in
>>>>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
>>>>>> So this shouldn't be qseecom specific.
>>>>>>
>>>>>> I should probably also say that I'm currently testing this on a patched
>>>>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
>>>>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
>>>>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
>>>>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
>>>>>> issue here).
>>>>>>
>>>>>> I've also tried the shmem allocator option, but that seems to get stuck
>>>>>> quite early at boot, before I even have usb-serial access to get any
>>>>>> logs. If I can find some more time, I'll try to see if I can get some
>>>>>> useful output for that.
>>>>>>
>>>>>
>>>>> Ah, I think it happens here:
>>>>>
>>>>> +       guard(spinlock_irqsave)(&pool->lock);
>>>>> +
>>>>> +again:
>>>>> +       vaddr = gen_pool_alloc(pool->genpool, size);
>>>>> +       if (!vaddr) {
>>>>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
>>>>> +                       goto again;
>>>>>
>>>>> We were called with GFP_KERNEL so this is what we pass on to
>>>>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
>>>>> to revisit it. Thanks for the catch!
>>>>>
>>>>> Bart
>>>>
>>>> Can you try the following tree?
>>>>
>>>>       https://git.codelinaro.org/bartosz_golaszewski/linux.git
>>>> topic/shm-bridge-v10
>>>>
>>>> gen_pool_alloc() and gen_pool_add_virt() can be used without external
>>>> serialization. We only really need to protect the list of areas in the
>>>> pool when adding a new element. We could possibly even use
>>>> list_add_tail_rcu() as it updates the pointers atomically and go
>>>> lockless.
>>>
>>> Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
>>> Unfortunately, with the shmbridge mode it still gets stuck at boot (and
>>> I haven't had the time to look into it yet).
>>>
>>> And for more bad news: It looks like the new allocator now fully exposes
>>> a bug that I've been tracking down the last couple of days. In short,
>>> uefisecapp doesn't seem to be happy when we split the allocations for
>>> request and response into two, causing commands to fail. Instead it
>>> wants a single buffer for both. Before, it seemed to be fairly sporadic
>>> (likely because kzalloc in sequence just returned consecutive memory
>>> almost all of the time) but now it's basically every call that fails.
>>>
>>> I have a fix for that almost ready and I'll likely post it in the next
>>> hour. But that means that you'll probably have to rebase this series
>>> on top of it...
>>
>> Forgot to mention: I tested it with the fix and this series, and that
>> works.
>>
> 
> Both with and without SHM bridge?

With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
still get stuck at boot (regardless of the fix). I think that's
happening even before anything efivar related should come up.

> If so, please Cc me on the fix.

Sure, will do.

Best regards,
Max

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

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

On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> On Fri, Mar 29, 2024 at 7:56 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>
>>
>>
>> On 3/29/24 7:53 PM, Maximilian Luz wrote:
>>> On 3/29/24 11:22 AM, Bartosz Golaszewski wrote:
>>>> On Thu, Mar 28, 2024 at 7:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>>>
>>>>> On Thu, Mar 28, 2024 at 5:50 PM Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>
>>>>>> If I understand correctly, it enters an atomic section in
>>>>>> qcom_tzmem_alloc() and then tries to schedule somewhere down the line.
>>>>>> So this shouldn't be qseecom specific.
>>>>>>
>>>>>> I should probably also say that I'm currently testing this on a patched
>>>>>> v6.8 kernel, so there's a chance that it's my fault. However, as far as
>>>>>> I understand, it enters an atomic section in qcom_tzmem_alloc() and then
>>>>>> later tries to expand the pool memory with dma_alloc_coherent(). Which
>>>>>> AFAIK is allowed to sleep with GFP_KERNEL (and I guess that that's the
>>>>>> issue here).
>>>>>>
>>>>>> I've also tried the shmem allocator option, but that seems to get stuck
>>>>>> quite early at boot, before I even have usb-serial access to get any
>>>>>> logs. If I can find some more time, I'll try to see if I can get some
>>>>>> useful output for that.
>>>>>>
>>>>>
>>>>> Ah, I think it happens here:
>>>>>
>>>>> +       guard(spinlock_irqsave)(&pool->lock);
>>>>> +
>>>>> +again:
>>>>> +       vaddr = gen_pool_alloc(pool->genpool, size);
>>>>> +       if (!vaddr) {
>>>>> +               if (qcom_tzmem_try_grow_pool(pool, size, gfp))
>>>>> +                       goto again;
>>>>>
>>>>> We were called with GFP_KERNEL so this is what we pass on to
>>>>> qcom_tzmem_try_grow_pool() but we're now holding the spinlock. I need
>>>>> to revisit it. Thanks for the catch!
>>>>>
>>>>> Bart
>>>>
>>>> Can you try the following tree?
>>>>
>>>>       https://git.codelinaro.org/bartosz_golaszewski/linux.git
>>>> topic/shm-bridge-v10
>>>>
>>>> gen_pool_alloc() and gen_pool_add_virt() can be used without external
>>>> serialization. We only really need to protect the list of areas in the
>>>> pool when adding a new element. We could possibly even use
>>>> list_add_tail_rcu() as it updates the pointers atomically and go
>>>> lockless.
>>>
>>> Thanks! That fixes the allocations for CONFIG_QCOM_TZMEM_MODE_GENERIC=y.
>>> Unfortunately, with the shmbridge mode it still gets stuck at boot (and
>>> I haven't had the time to look into it yet).
>>>
>>> And for more bad news: It looks like the new allocator now fully exposes
>>> a bug that I've been tracking down the last couple of days. In short,
>>> uefisecapp doesn't seem to be happy when we split the allocations for
>>> request and response into two, causing commands to fail. Instead it
>>> wants a single buffer for both. Before, it seemed to be fairly sporadic
>>> (likely because kzalloc in sequence just returned consecutive memory
>>> almost all of the time) but now it's basically every call that fails.
>>>
>>> I have a fix for that almost ready and I'll likely post it in the next
>>> hour. But that means that you'll probably have to rebase this series
>>> on top of it...
>>
>> Forgot to mention: I tested it with the fix and this series, and that
>> works.
>>
> 
> Both with and without SHM bridge?

With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
still get stuck at boot (regardless of the fix). I think that's
happening even before anything efivar related should come up.

> If so, please Cc me on the fix.

Sure, will do.

Best regards,
Max

_______________________________________________
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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-29 19:22               ` Maximilian Luz
@ 2024-03-29 19:26                 ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-29 19:26 UTC (permalink / raw)
  To: Maximilian Luz
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Alex Elder, Srini Kandagatla, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> >
> > Both with and without SHM bridge?
>
> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> still get stuck at boot (regardless of the fix). I think that's
> happening even before anything efivar related should come up.
>

This is on X13s? I will get one in 3 weeks. Can you get the bootlog
somehow? Does the laptop have any serial console?

Bart

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

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

On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> >
> > Both with and without SHM bridge?
>
> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> still get stuck at boot (regardless of the fix). I think that's
> happening even before anything efivar related should come up.
>

This is on X13s? I will get one in 3 weeks. Can you get the bootlog
somehow? Does the laptop have any serial console?

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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-29 19:26                 ` Bartosz Golaszewski
@ 2024-03-29 19:38                   ` Maximilian Luz
  -1 siblings, 0 replies; 62+ messages in thread
From: Maximilian Luz @ 2024-03-29 19:38 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Alex Elder, Srini Kandagatla, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>
>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>
>>> Both with and without SHM bridge?
>>
>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>> still get stuck at boot (regardless of the fix). I think that's
>> happening even before anything efivar related should come up.
>>
> 
> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> somehow? Does the laptop have any serial console?

Surface Pro X (sc8180x), but it should be similar enough to the X13s in
that regard. At least from what people with access to the X13s told me,
the qseecom stuff seems to behave the same.

Unfortunately I don't have a direct serial console. Best I have is
USB-serial, but it's not even getting there. I'll have to try and see if
I can get some more info on the screen.

Best regards,
Max

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

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

On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>
>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>
>>> Both with and without SHM bridge?
>>
>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>> still get stuck at boot (regardless of the fix). I think that's
>> happening even before anything efivar related should come up.
>>
> 
> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> somehow? Does the laptop have any serial console?

Surface Pro X (sc8180x), but it should be similar enough to the X13s in
that regard. At least from what people with access to the X13s told me,
the qseecom stuff seems to behave the same.

Unfortunately I don't have a direct serial console. Best I have is
USB-serial, but it's not even getting there. I'll have to try and see if
I can get some more info on the screen.

Best regards,
Max

_______________________________________________
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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-29 19:38                   ` Maximilian Luz
@ 2024-03-29 19:46                     ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-03-29 19:46 UTC (permalink / raw)
  To: Maximilian Luz
  Cc: Bartosz Golaszewski, Andy Gross, Bjorn Andersson, Konrad Dybcio,
	Elliot Berman, Krzysztof Kozlowski, Guru Das Srinagesh,
	Andrew Halaney, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel

On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> > On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>
> >> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> >>>
> >>> Both with and without SHM bridge?
> >>
> >> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> >> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> >> still get stuck at boot (regardless of the fix). I think that's
> >> happening even before anything efivar related should come up.
> >>
> >
> > This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> > somehow? Does the laptop have any serial console?
>
> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
> that regard. At least from what people with access to the X13s told me,
> the qseecom stuff seems to behave the same.
>
> Unfortunately I don't have a direct serial console. Best I have is
> USB-serial, but it's not even getting there. I'll have to try and see if
> I can get some more info on the screen.
>

I have access to a sc8180x-primus board, does it make sense to test
with this one? If so, could you give me instructions on how to do it?

Bart

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

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

On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>
> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> > On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>
> >> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> >>>
> >>> Both with and without SHM bridge?
> >>
> >> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> >> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> >> still get stuck at boot (regardless of the fix). I think that's
> >> happening even before anything efivar related should come up.
> >>
> >
> > This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> > somehow? Does the laptop have any serial console?
>
> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
> that regard. At least from what people with access to the X13s told me,
> the qseecom stuff seems to behave the same.
>
> Unfortunately I don't have a direct serial console. Best I have is
> USB-serial, but it's not even getting there. I'll have to try and see if
> I can get some more info on the screen.
>

I have access to a sc8180x-primus board, does it make sense to test
with this one? If so, could you give me instructions on how to do it?

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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-29 19:46                     ` Bartosz Golaszewski
@ 2024-03-29 19:57                       ` Maximilian Luz
  -1 siblings, 0 replies; 62+ messages in thread
From: Maximilian Luz @ 2024-03-29 19:57 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Bartosz Golaszewski, Andy Gross, Bjorn Andersson, Konrad Dybcio,
	Elliot Berman, Krzysztof Kozlowski, Guru Das Srinagesh,
	Andrew Halaney, Alex Elder, Srini Kandagatla, Arnd Bergmann,
	linux-arm-msm, linux-kernel, linux-arm-kernel, kernel

On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>
>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>
>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>
>>>>> Both with and without SHM bridge?
>>>>
>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>> still get stuck at boot (regardless of the fix). I think that's
>>>> happening even before anything efivar related should come up.
>>>>
>>>
>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>> somehow? Does the laptop have any serial console?
>>
>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>> that regard. At least from what people with access to the X13s told me,
>> the qseecom stuff seems to behave the same.
>>
>> Unfortunately I don't have a direct serial console. Best I have is
>> USB-serial, but it's not even getting there. I'll have to try and see if
>> I can get some more info on the screen.
>>
> 
> I have access to a sc8180x-primus board, does it make sense to test
> with this one? If so, could you give me instructions on how to do it?

I guess it's worth a shot.

 From what I can tell, there shouldn't be any patches in my tree that
would conflict with it. So I guess it should just be building it with
CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.

I am currently testing it on top of a patched v6.8 tree though (but that
should just contain patches to get the Pro X running). You can find the
full tree at

     https://github.com/linux-surface/kernel/tree/spx/v6.8

The last commit is the fix I mentioned, so you might want to revert
that, since the shmem issue triggers regardless of that and it prevents
your series from applying cleanly.

Best regards,
Max


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

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

On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>
>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>
>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>
>>>>> Both with and without SHM bridge?
>>>>
>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>> still get stuck at boot (regardless of the fix). I think that's
>>>> happening even before anything efivar related should come up.
>>>>
>>>
>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>> somehow? Does the laptop have any serial console?
>>
>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>> that regard. At least from what people with access to the X13s told me,
>> the qseecom stuff seems to behave the same.
>>
>> Unfortunately I don't have a direct serial console. Best I have is
>> USB-serial, but it's not even getting there. I'll have to try and see if
>> I can get some more info on the screen.
>>
> 
> I have access to a sc8180x-primus board, does it make sense to test
> with this one? If so, could you give me instructions on how to do it?

I guess it's worth a shot.

 From what I can tell, there shouldn't be any patches in my tree that
would conflict with it. So I guess it should just be building it with
CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.

I am currently testing it on top of a patched v6.8 tree though (but that
should just contain patches to get the Pro X running). You can find the
full tree at

     https://github.com/linux-surface/kernel/tree/spx/v6.8

The last commit is the fix I mentioned, so you might want to revert
that, since the shmem issue triggers regardless of that and it prevents
your series from applying cleanly.

Best regards,
Max


_______________________________________________
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] 62+ messages in thread

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

On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz
<luzmaximilian@gmail.com> said:
> On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
>> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>
>>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>
>>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>>
>>>>>> Both with and without SHM bridge?
>>>>>
>>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>>> still get stuck at boot (regardless of the fix). I think that's
>>>>> happening even before anything efivar related should come up.
>>>>>
>>>>
>>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>>> somehow? Does the laptop have any serial console?
>>>
>>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>>> that regard. At least from what people with access to the X13s told me,
>>> the qseecom stuff seems to behave the same.
>>>
>>> Unfortunately I don't have a direct serial console. Best I have is
>>> USB-serial, but it's not even getting there. I'll have to try and see if
>>> I can get some more info on the screen.
>>>
>>
>> I have access to a sc8180x-primus board, does it make sense to test
>> with this one? If so, could you give me instructions on how to do it?
>
> I guess it's worth a shot.
>
>  From what I can tell, there shouldn't be any patches in my tree that
> would conflict with it. So I guess it should just be building it with
> CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
>
> I am currently testing it on top of a patched v6.8 tree though (but that
> should just contain patches to get the Pro X running). You can find the
> full tree at
>
>      https://github.com/linux-surface/kernel/tree/spx/v6.8
>
> The last commit is the fix I mentioned, so you might want to revert
> that, since the shmem issue triggers regardless of that and it prevents
> your series from applying cleanly.
>
> Best regards,
> Max
>

sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
However it's true that with SHM bridge it gets to:

mount: mounting efivarfs on /sys/firmware/efi/efivars failed:
Operation not supported

and stops 100% of the time. Without SHM bridge I cannot boot it either because
I suppose I need the patch you sent yesterday. I haven't had the time to
rebase it yet, it's quite intrusive to my series.

I can confirm that with that patch the board still boots but still 50% of the
time.

Bart

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

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

On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz
<luzmaximilian@gmail.com> said:
> On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
>> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>
>>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>
>>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>>
>>>>>> Both with and without SHM bridge?
>>>>>
>>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>>> still get stuck at boot (regardless of the fix). I think that's
>>>>> happening even before anything efivar related should come up.
>>>>>
>>>>
>>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>>> somehow? Does the laptop have any serial console?
>>>
>>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>>> that regard. At least from what people with access to the X13s told me,
>>> the qseecom stuff seems to behave the same.
>>>
>>> Unfortunately I don't have a direct serial console. Best I have is
>>> USB-serial, but it's not even getting there. I'll have to try and see if
>>> I can get some more info on the screen.
>>>
>>
>> I have access to a sc8180x-primus board, does it make sense to test
>> with this one? If so, could you give me instructions on how to do it?
>
> I guess it's worth a shot.
>
>  From what I can tell, there shouldn't be any patches in my tree that
> would conflict with it. So I guess it should just be building it with
> CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
>
> I am currently testing it on top of a patched v6.8 tree though (but that
> should just contain patches to get the Pro X running). You can find the
> full tree at
>
>      https://github.com/linux-surface/kernel/tree/spx/v6.8
>
> The last commit is the fix I mentioned, so you might want to revert
> that, since the shmem issue triggers regardless of that and it prevents
> your series from applying cleanly.
>
> Best regards,
> Max
>

sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
However it's true that with SHM bridge it gets to:

mount: mounting efivarfs on /sys/firmware/efi/efivars failed:
Operation not supported

and stops 100% of the time. Without SHM bridge I cannot boot it either because
I suppose I need the patch you sent yesterday. I haven't had the time to
rebase it yet, it's quite intrusive to my series.

I can confirm that with that patch the board still boots but still 50% of the
time.

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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-03-30 19:16                         ` Bartosz Golaszewski
@ 2024-04-02  8:44                           ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-04-02  8:44 UTC (permalink / raw)
  To: Maximilian Luz
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Alex Elder, Srini Kandagatla, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
> > On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
> >> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>>
> >>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> >>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>>>>
> >>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> >>>>>>
> >>>>>> Both with and without SHM bridge?
> >>>>>
> >>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> >>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> >>>>> still get stuck at boot (regardless of the fix). I think that's
> >>>>> happening even before anything efivar related should come up.
> >>>>>
> >>>>
> >>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> >>>> somehow? Does the laptop have any serial console?
> >>>
> >>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
> >>> that regard. At least from what people with access to the X13s told me,
> >>> the qseecom stuff seems to behave the same.
> >>>
> >>> Unfortunately I don't have a direct serial console. Best I have is
> >>> USB-serial, but it's not even getting there. I'll have to try and see if
> >>> I can get some more info on the screen.
> >>>
> >>
> >> I have access to a sc8180x-primus board, does it make sense to test
> >> with this one? If so, could you give me instructions on how to do it?
> >
> > I guess it's worth a shot.
> >
> >  From what I can tell, there shouldn't be any patches in my tree that
> > would conflict with it. So I guess it should just be building it with
> > CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
> >
> > I am currently testing it on top of a patched v6.8 tree though (but that
> > should just contain patches to get the Pro X running). You can find the
> > full tree at
> >
> >      https://github.com/linux-surface/kernel/tree/spx/v6.8
> >
> > The last commit is the fix I mentioned, so you might want to revert
> > that, since the shmem issue triggers regardless of that and it prevents
> > your series from applying cleanly.
> >
> > Best regards,
> > Max
> >
>
> sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
> However it's true that with SHM bridge it gets to:
>
> mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
>
> and stops 100% of the time. Without SHM bridge I cannot boot it either because
> I suppose I need the patch you sent yesterday. I haven't had the time to
> rebase it yet, it's quite intrusive to my series.
>
> I can confirm that with that patch the board still boots but still 50% of the
> time.
>
> Bart

Hi!

I was under the impression that until v8, the series worked on sc8180x
but I'm seeing that even v7 has the same issue with SHM Bridge on
sc8180x-primus. Could you confirm? Because I'm not sure if I should
track the differences or the whole thing was broken for this platform
from the beginning.

Bart

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

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

On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
> > On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
> >> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>>
> >>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> >>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> >>>>>
> >>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> >>>>>>
> >>>>>> Both with and without SHM bridge?
> >>>>>
> >>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> >>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> >>>>> still get stuck at boot (regardless of the fix). I think that's
> >>>>> happening even before anything efivar related should come up.
> >>>>>
> >>>>
> >>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> >>>> somehow? Does the laptop have any serial console?
> >>>
> >>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
> >>> that regard. At least from what people with access to the X13s told me,
> >>> the qseecom stuff seems to behave the same.
> >>>
> >>> Unfortunately I don't have a direct serial console. Best I have is
> >>> USB-serial, but it's not even getting there. I'll have to try and see if
> >>> I can get some more info on the screen.
> >>>
> >>
> >> I have access to a sc8180x-primus board, does it make sense to test
> >> with this one? If so, could you give me instructions on how to do it?
> >
> > I guess it's worth a shot.
> >
> >  From what I can tell, there shouldn't be any patches in my tree that
> > would conflict with it. So I guess it should just be building it with
> > CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
> >
> > I am currently testing it on top of a patched v6.8 tree though (but that
> > should just contain patches to get the Pro X running). You can find the
> > full tree at
> >
> >      https://github.com/linux-surface/kernel/tree/spx/v6.8
> >
> > The last commit is the fix I mentioned, so you might want to revert
> > that, since the shmem issue triggers regardless of that and it prevents
> > your series from applying cleanly.
> >
> > Best regards,
> > Max
> >
>
> sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
> However it's true that with SHM bridge it gets to:
>
> mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
>
> and stops 100% of the time. Without SHM bridge I cannot boot it either because
> I suppose I need the patch you sent yesterday. I haven't had the time to
> rebase it yet, it's quite intrusive to my series.
>
> I can confirm that with that patch the board still boots but still 50% of the
> time.
>
> Bart

Hi!

I was under the impression that until v8, the series worked on sc8180x
but I'm seeing that even v7 has the same issue with SHM Bridge on
sc8180x-primus. Could you confirm? Because I'm not sure if I should
track the differences or the whole thing was broken for this platform
from the beginning.

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] 62+ messages in thread

* Re: [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator
  2024-04-02  8:44                           ` Bartosz Golaszewski
@ 2024-04-03  7:47                             ` Bartosz Golaszewski
  -1 siblings, 0 replies; 62+ messages in thread
From: Bartosz Golaszewski @ 2024-04-03  7:47 UTC (permalink / raw)
  To: Maximilian Luz
  Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Elliot Berman,
	Krzysztof Kozlowski, Guru Das Srinagesh, Andrew Halaney,
	Alex Elder, Srini Kandagatla, Arnd Bergmann, linux-arm-msm,
	linux-kernel, linux-arm-kernel, kernel, Bartosz Golaszewski

On Tue, Apr 2, 2024 at 10:44 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >
> > On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
> > > On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
> > >> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> > >>>
> > >>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> > >>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> > >>>>>
> > >>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> > >>>>>>
> > >>>>>> Both with and without SHM bridge?
> > >>>>>
> > >>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> > >>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> > >>>>> still get stuck at boot (regardless of the fix). I think that's
> > >>>>> happening even before anything efivar related should come up.
> > >>>>>
> > >>>>
> > >>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> > >>>> somehow? Does the laptop have any serial console?
> > >>>
> > >>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
> > >>> that regard. At least from what people with access to the X13s told me,
> > >>> the qseecom stuff seems to behave the same.
> > >>>
> > >>> Unfortunately I don't have a direct serial console. Best I have is
> > >>> USB-serial, but it's not even getting there. I'll have to try and see if
> > >>> I can get some more info on the screen.
> > >>>
> > >>
> > >> I have access to a sc8180x-primus board, does it make sense to test
> > >> with this one? If so, could you give me instructions on how to do it?
> > >
> > > I guess it's worth a shot.
> > >
> > >  From what I can tell, there shouldn't be any patches in my tree that
> > > would conflict with it. So I guess it should just be building it with
> > > CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
> > >
> > > I am currently testing it on top of a patched v6.8 tree though (but that
> > > should just contain patches to get the Pro X running). You can find the
> > > full tree at
> > >
> > >      https://github.com/linux-surface/kernel/tree/spx/v6.8
> > >
> > > The last commit is the fix I mentioned, so you might want to revert
> > > that, since the shmem issue triggers regardless of that and it prevents
> > > your series from applying cleanly.
> > >
> > > Best regards,
> > > Max
> > >
> >
> > sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
> > However it's true that with SHM bridge it gets to:
> >
> > mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
> >
> > and stops 100% of the time. Without SHM bridge I cannot boot it either because
> > I suppose I need the patch you sent yesterday. I haven't had the time to
> > rebase it yet, it's quite intrusive to my series.
> >
> > I can confirm that with that patch the board still boots but still 50% of the
> > time.
> >
> > Bart
>
> Hi!
>
> I was under the impression that until v8, the series worked on sc8180x
> but I'm seeing that even v7 has the same issue with SHM Bridge on
> sc8180x-primus. Could you confirm? Because I'm not sure if I should
> track the differences or the whole thing was broken for this platform
> from the beginning.
>
> Bart

Interestingly, it doesn't seem like a problem with qseecom - even if I
disable the driver, the board still freezes after the first SCM call
using SHM bridge. I suspect - and am trying to clarify that with qcom
- that this architecture doesn't support SHM bridge but doesn't report
it either unlike other older platforms. Or maybe there's some quirk
somewhere. Anyway, I'm on it.

Bart

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

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

On Tue, Apr 2, 2024 at 10:44 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >
> > On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
> > > On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
> > >> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> > >>>
> > >>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
> > >>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
> > >>>>>
> > >>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
> > >>>>>>
> > >>>>>> Both with and without SHM bridge?
> > >>>>>
> > >>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
> > >>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
> > >>>>> still get stuck at boot (regardless of the fix). I think that's
> > >>>>> happening even before anything efivar related should come up.
> > >>>>>
> > >>>>
> > >>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
> > >>>> somehow? Does the laptop have any serial console?
> > >>>
> > >>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
> > >>> that regard. At least from what people with access to the X13s told me,
> > >>> the qseecom stuff seems to behave the same.
> > >>>
> > >>> Unfortunately I don't have a direct serial console. Best I have is
> > >>> USB-serial, but it's not even getting there. I'll have to try and see if
> > >>> I can get some more info on the screen.
> > >>>
> > >>
> > >> I have access to a sc8180x-primus board, does it make sense to test
> > >> with this one? If so, could you give me instructions on how to do it?
> > >
> > > I guess it's worth a shot.
> > >
> > >  From what I can tell, there shouldn't be any patches in my tree that
> > > would conflict with it. So I guess it should just be building it with
> > > CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
> > >
> > > I am currently testing it on top of a patched v6.8 tree though (but that
> > > should just contain patches to get the Pro X running). You can find the
> > > full tree at
> > >
> > >      https://github.com/linux-surface/kernel/tree/spx/v6.8
> > >
> > > The last commit is the fix I mentioned, so you might want to revert
> > > that, since the shmem issue triggers regardless of that and it prevents
> > > your series from applying cleanly.
> > >
> > > Best regards,
> > > Max
> > >
> >
> > sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
> > However it's true that with SHM bridge it gets to:
> >
> > mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
> >
> > and stops 100% of the time. Without SHM bridge I cannot boot it either because
> > I suppose I need the patch you sent yesterday. I haven't had the time to
> > rebase it yet, it's quite intrusive to my series.
> >
> > I can confirm that with that patch the board still boots but still 50% of the
> > time.
> >
> > Bart
>
> Hi!
>
> I was under the impression that until v8, the series worked on sc8180x
> but I'm seeing that even v7 has the same issue with SHM Bridge on
> sc8180x-primus. Could you confirm? Because I'm not sure if I should
> track the differences or the whole thing was broken for this platform
> from the beginning.
>
> Bart

Interestingly, it doesn't seem like a problem with qseecom - even if I
disable the driver, the board still freezes after the first SCM call
using SHM bridge. I suspect - and am trying to clarify that with qcom
- that this architecture doesn't support SHM bridge but doesn't report
it either unlike other older platforms. Or maybe there's some quirk
somewhere. Anyway, I'm on it.

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] 62+ messages in thread

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


On 4/2/24 10:44 AM, Bartosz Golaszewski wrote:
> On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>
>> On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
>>> On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
>>>> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>
>>>>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>>>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>>
>>>>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>>>>
>>>>>>>> Both with and without SHM bridge?
>>>>>>>
>>>>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>>>>> still get stuck at boot (regardless of the fix). I think that's
>>>>>>> happening even before anything efivar related should come up.
>>>>>>>
>>>>>>
>>>>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>>>>> somehow? Does the laptop have any serial console?
>>>>>
>>>>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>>>>> that regard. At least from what people with access to the X13s told me,
>>>>> the qseecom stuff seems to behave the same.
>>>>>
>>>>> Unfortunately I don't have a direct serial console. Best I have is
>>>>> USB-serial, but it's not even getting there. I'll have to try and see if
>>>>> I can get some more info on the screen.
>>>>>
>>>>
>>>> I have access to a sc8180x-primus board, does it make sense to test
>>>> with this one? If so, could you give me instructions on how to do it?
>>>
>>> I guess it's worth a shot.
>>>
>>>   From what I can tell, there shouldn't be any patches in my tree that
>>> would conflict with it. So I guess it should just be building it with
>>> CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
>>>
>>> I am currently testing it on top of a patched v6.8 tree though (but that
>>> should just contain patches to get the Pro X running). You can find the
>>> full tree at
>>>
>>>       https://github.com/linux-surface/kernel/tree/spx/v6.8
>>>
>>> The last commit is the fix I mentioned, so you might want to revert
>>> that, since the shmem issue triggers regardless of that and it prevents
>>> your series from applying cleanly.
>>>
>>> Best regards,
>>> Max
>>>
>>
>> sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
>> However it's true that with SHM bridge it gets to:
>>
>> mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
>>
>> and stops 100% of the time. Without SHM bridge I cannot boot it either because
>> I suppose I need the patch you sent yesterday. I haven't had the time to
>> rebase it yet, it's quite intrusive to my series.
>>
>> I can confirm that with that patch the board still boots but still 50% of the
>> time.
>>
>> Bart
> 
> Hi!
> 
> I was under the impression that until v8, the series worked on sc8180x
> but I'm seeing that even v7 has the same issue with SHM Bridge on
> sc8180x-primus. Could you confirm? Because I'm not sure if I should
> track the differences or the whole thing was broken for this platform
> from the beginning.

Hi, sorry for the delay.

Unfortunately I haven't had the time to test anything since v3. I don't
remember all the details, but based on what I wrote back then, enabling
the SHM bridge option did not lead to this result.

I can try to test v7 (and others) on the weekend.

Best regards,
Max

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

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


On 4/2/24 10:44 AM, Bartosz Golaszewski wrote:
> On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>
>> On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
>>> On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
>>>> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>
>>>>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>>>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>>
>>>>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>>>>
>>>>>>>> Both with and without SHM bridge?
>>>>>>>
>>>>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>>>>> still get stuck at boot (regardless of the fix). I think that's
>>>>>>> happening even before anything efivar related should come up.
>>>>>>>
>>>>>>
>>>>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>>>>> somehow? Does the laptop have any serial console?
>>>>>
>>>>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>>>>> that regard. At least from what people with access to the X13s told me,
>>>>> the qseecom stuff seems to behave the same.
>>>>>
>>>>> Unfortunately I don't have a direct serial console. Best I have is
>>>>> USB-serial, but it's not even getting there. I'll have to try and see if
>>>>> I can get some more info on the screen.
>>>>>
>>>>
>>>> I have access to a sc8180x-primus board, does it make sense to test
>>>> with this one? If so, could you give me instructions on how to do it?
>>>
>>> I guess it's worth a shot.
>>>
>>>   From what I can tell, there shouldn't be any patches in my tree that
>>> would conflict with it. So I guess it should just be building it with
>>> CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
>>>
>>> I am currently testing it on top of a patched v6.8 tree though (but that
>>> should just contain patches to get the Pro X running). You can find the
>>> full tree at
>>>
>>>       https://github.com/linux-surface/kernel/tree/spx/v6.8
>>>
>>> The last commit is the fix I mentioned, so you might want to revert
>>> that, since the shmem issue triggers regardless of that and it prevents
>>> your series from applying cleanly.
>>>
>>> Best regards,
>>> Max
>>>
>>
>> sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
>> However it's true that with SHM bridge it gets to:
>>
>> mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
>>
>> and stops 100% of the time. Without SHM bridge I cannot boot it either because
>> I suppose I need the patch you sent yesterday. I haven't had the time to
>> rebase it yet, it's quite intrusive to my series.
>>
>> I can confirm that with that patch the board still boots but still 50% of the
>> time.
>>
>> Bart
> 
> Hi!
> 
> I was under the impression that until v8, the series worked on sc8180x
> but I'm seeing that even v7 has the same issue with SHM Bridge on
> sc8180x-primus. Could you confirm? Because I'm not sure if I should
> track the differences or the whole thing was broken for this platform
> from the beginning.

Hi, sorry for the delay.

Unfortunately I haven't had the time to test anything since v3. I don't
remember all the details, but based on what I wrote back then, enabling
the SHM bridge option did not lead to this result.

I can try to test v7 (and others) on the weekend.

Best regards,
Max

_______________________________________________
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] 62+ messages in thread

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

On 4/3/24 9:47 AM, Bartosz Golaszewski wrote:
> On Tue, Apr 2, 2024 at 10:44 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>
>> On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>
>>> On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
>>>> On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
>>>>> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>
>>>>>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>>>>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>>>
>>>>>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>>>>>
>>>>>>>>> Both with and without SHM bridge?
>>>>>>>>
>>>>>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>>>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>>>>>> still get stuck at boot (regardless of the fix). I think that's
>>>>>>>> happening even before anything efivar related should come up.
>>>>>>>>
>>>>>>>
>>>>>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>>>>>> somehow? Does the laptop have any serial console?
>>>>>>
>>>>>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>>>>>> that regard. At least from what people with access to the X13s told me,
>>>>>> the qseecom stuff seems to behave the same.
>>>>>>
>>>>>> Unfortunately I don't have a direct serial console. Best I have is
>>>>>> USB-serial, but it's not even getting there. I'll have to try and see if
>>>>>> I can get some more info on the screen.
>>>>>>
>>>>>
>>>>> I have access to a sc8180x-primus board, does it make sense to test
>>>>> with this one? If so, could you give me instructions on how to do it?
>>>>
>>>> I guess it's worth a shot.
>>>>
>>>>   From what I can tell, there shouldn't be any patches in my tree that
>>>> would conflict with it. So I guess it should just be building it with
>>>> CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
>>>>
>>>> I am currently testing it on top of a patched v6.8 tree though (but that
>>>> should just contain patches to get the Pro X running). You can find the
>>>> full tree at
>>>>
>>>>       https://github.com/linux-surface/kernel/tree/spx/v6.8
>>>>
>>>> The last commit is the fix I mentioned, so you might want to revert
>>>> that, since the shmem issue triggers regardless of that and it prevents
>>>> your series from applying cleanly.
>>>>
>>>> Best regards,
>>>> Max
>>>>
>>>
>>> sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
>>> However it's true that with SHM bridge it gets to:
>>>
>>> mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
>>>
>>> and stops 100% of the time. Without SHM bridge I cannot boot it either because
>>> I suppose I need the patch you sent yesterday. I haven't had the time to
>>> rebase it yet, it's quite intrusive to my series.
>>>
>>> I can confirm that with that patch the board still boots but still 50% of the
>>> time.
>>>
>>> Bart
>>
>> Hi!
>>
>> I was under the impression that until v8, the series worked on sc8180x
>> but I'm seeing that even v7 has the same issue with SHM Bridge on
>> sc8180x-primus. Could you confirm? Because I'm not sure if I should
>> track the differences or the whole thing was broken for this platform
>> from the beginning.
>>
>> Bart
> 
> Interestingly, it doesn't seem like a problem with qseecom - even if I
> disable the driver, the board still freezes after the first SCM call
> using SHM bridge. I suspect - and am trying to clarify that with qcom
> - that this architecture doesn't support SHM bridge but doesn't report
> it either unlike other older platforms. Or maybe there's some quirk
> somewhere. Anyway, I'm on it.

Awesome, thanks!

Best regards,
Max

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

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

On 4/3/24 9:47 AM, Bartosz Golaszewski wrote:
> On Tue, Apr 2, 2024 at 10:44 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>
>> On Sat, Mar 30, 2024 at 8:16 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>>>
>>> On Fri, 29 Mar 2024 20:57:52 +0100, Maximilian Luz <luzmaximilian@gmail.com> said:
>>>> On 3/29/24 8:46 PM, Bartosz Golaszewski wrote:
>>>>> On Fri, 29 Mar 2024 at 20:39, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>
>>>>>> On 3/29/24 8:26 PM, Bartosz Golaszewski wrote:
>>>>>>> On Fri, 29 Mar 2024 at 20:22, Maximilian Luz <luzmaximilian@gmail.com> wrote:
>>>>>>>>
>>>>>>>> On 3/29/24 8:07 PM, Bartosz Golaszewski wrote:
>>>>>>>>>
>>>>>>>>> Both with and without SHM bridge?
>>>>>>>>
>>>>>>>> With CONFIG_QCOM_TZMEM_MODE_GENERIC=y (and the upcoming fix) everything
>>>>>>>> works. With CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y things unfortunately
>>>>>>>> still get stuck at boot (regardless of the fix). I think that's
>>>>>>>> happening even before anything efivar related should come up.
>>>>>>>>
>>>>>>>
>>>>>>> This is on X13s? I will get one in 3 weeks. Can you get the bootlog
>>>>>>> somehow? Does the laptop have any serial console?
>>>>>>
>>>>>> Surface Pro X (sc8180x), but it should be similar enough to the X13s in
>>>>>> that regard. At least from what people with access to the X13s told me,
>>>>>> the qseecom stuff seems to behave the same.
>>>>>>
>>>>>> Unfortunately I don't have a direct serial console. Best I have is
>>>>>> USB-serial, but it's not even getting there. I'll have to try and see if
>>>>>> I can get some more info on the screen.
>>>>>>
>>>>>
>>>>> I have access to a sc8180x-primus board, does it make sense to test
>>>>> with this one? If so, could you give me instructions on how to do it?
>>>>
>>>> I guess it's worth a shot.
>>>>
>>>>   From what I can tell, there shouldn't be any patches in my tree that
>>>> would conflict with it. So I guess it should just be building it with
>>>> CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y and booting.
>>>>
>>>> I am currently testing it on top of a patched v6.8 tree though (but that
>>>> should just contain patches to get the Pro X running). You can find the
>>>> full tree at
>>>>
>>>>       https://github.com/linux-surface/kernel/tree/spx/v6.8
>>>>
>>>> The last commit is the fix I mentioned, so you might want to revert
>>>> that, since the shmem issue triggers regardless of that and it prevents
>>>> your series from applying cleanly.
>>>>
>>>> Best regards,
>>>> Max
>>>>
>>>
>>> sc8180x-primus' support upstream is quite flaky. The board boots 50% of time.
>>> However it's true that with SHM bridge it gets to:
>>>
>>> mount: mounting efivarfs on /sys/firmware/efi/efivars failed: Operation not supported
>>>
>>> and stops 100% of the time. Without SHM bridge I cannot boot it either because
>>> I suppose I need the patch you sent yesterday. I haven't had the time to
>>> rebase it yet, it's quite intrusive to my series.
>>>
>>> I can confirm that with that patch the board still boots but still 50% of the
>>> time.
>>>
>>> Bart
>>
>> Hi!
>>
>> I was under the impression that until v8, the series worked on sc8180x
>> but I'm seeing that even v7 has the same issue with SHM Bridge on
>> sc8180x-primus. Could you confirm? Because I'm not sure if I should
>> track the differences or the whole thing was broken for this platform
>> from the beginning.
>>
>> Bart
> 
> Interestingly, it doesn't seem like a problem with qseecom - even if I
> disable the driver, the board still freezes after the first SCM call
> using SHM bridge. I suspect - and am trying to clarify that with qcom
> - that this architecture doesn't support SHM bridge but doesn't report
> it either unlike other older platforms. Or maybe there's some quirk
> somewhere. Anyway, I'm on it.

Awesome, thanks!

Best regards,
Max

_______________________________________________
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] 62+ messages in thread

end of thread, other threads:[~2024-04-04 18:37 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-25 10:03 [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator Bartosz Golaszewski
2024-03-25 10:03 ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 01/13] firmware: qcom: add a dedicated TrustZone buffer allocator Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 02/13] firmware: qcom: scm: enable the TZ mem allocator Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 03/13] firmware: qcom: scm: smc: switch to using the SCM allocator Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 04/13] firmware: qcom: scm: make qcom_scm_assign_mem() use the TZ allocator Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 05/13] firmware: qcom: scm: make qcom_scm_ice_set_key() " Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 06/13] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() " Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 07/13] firmware: qcom: scm: make qcom_scm_qseecom_app_get_id() " Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 08/13] firmware: qcom: qseecom: convert to using the cleanup helpers Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 09/13] firmware: qcom: qseecom: convert to using the TZ allocator Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 10/13] firmware: qcom: scm: add support for SHM bridge operations Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 11/13] firmware: qcom: tzmem: enable SHM Bridge support Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 12/13] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image() Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:03 ` [PATCH v9 13/13] arm64: defconfig: enable SHM Bridge support for the TZ memory allocator Bartosz Golaszewski
2024-03-25 10:03   ` Bartosz Golaszewski
2024-03-25 10:08 ` [PATCH v9 00/13] firmware: qcom: qseecom: convert to using the TZ allocator Bartosz Golaszewski
2024-03-25 10:08   ` Bartosz Golaszewski
2024-03-28 16:50 ` Maximilian Luz
2024-03-28 16:50   ` Maximilian Luz
2024-03-28 18:55   ` Bartosz Golaszewski
2024-03-28 18:55     ` Bartosz Golaszewski
2024-03-29 10:22     ` Bartosz Golaszewski
2024-03-29 10:22       ` Bartosz Golaszewski
2024-03-29 18:53       ` Maximilian Luz
2024-03-29 18:53         ` Maximilian Luz
2024-03-29 18:56         ` Maximilian Luz
2024-03-29 18:56           ` Maximilian Luz
2024-03-29 19:07           ` Bartosz Golaszewski
2024-03-29 19:07             ` Bartosz Golaszewski
2024-03-29 19:22             ` Maximilian Luz
2024-03-29 19:22               ` Maximilian Luz
2024-03-29 19:26               ` Bartosz Golaszewski
2024-03-29 19:26                 ` Bartosz Golaszewski
2024-03-29 19:38                 ` Maximilian Luz
2024-03-29 19:38                   ` Maximilian Luz
2024-03-29 19:46                   ` Bartosz Golaszewski
2024-03-29 19:46                     ` Bartosz Golaszewski
2024-03-29 19:57                     ` Maximilian Luz
2024-03-29 19:57                       ` Maximilian Luz
2024-03-30 19:16                       ` Bartosz Golaszewski
2024-03-30 19:16                         ` Bartosz Golaszewski
2024-04-02  8:44                         ` Bartosz Golaszewski
2024-04-02  8:44                           ` Bartosz Golaszewski
2024-04-03  7:47                           ` Bartosz Golaszewski
2024-04-03  7:47                             ` Bartosz Golaszewski
2024-04-04 18:37                             ` Maximilian Luz
2024-04-04 18:37                               ` Maximilian Luz
2024-04-04 18:36                           ` Maximilian Luz
2024-04-04 18:36                             ` Maximilian Luz

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.