From patchwork Sun Mar 3 15:01:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 777655 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 136B667C43 for ; Sun, 3 Mar 2024 15:01:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478090; cv=none; b=MbEFF49BPH2cwpOVDI7i/wESWeX8QJ6JRbsUO/a6Z2S1S7i8jRdUge9nnkQSU3SNsA8Gy4rRoVd7PRpyd5sJpE1a5GoqsOMGQFQYoWpWVAaaOVWZRKFnarUq0D7fpDitQ0KgCw2W0m/x9re2Y7XXhP4pBqjpBnBp9jgt5lII4e0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478090; c=relaxed/simple; bh=pU6mrgroinLht95k8WFXE/0Con1+YBJRDYD5JMmOcyc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bk4sTnNhbEKW2zciVU+C7u/5wC0T6htwvwFA+nUZ/sU2rTJ6e1WP1JDmykbu/SaYadve43xIucA4ghcsb2yTyAZ7p97CN/WAw/gf1GLCY29fqf38p7QFQ0zHYMJfaFu3+3u0A8MoLXCgefyvbIp9bXf3wZdoNiFL0VJwTQmRKI4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=WsQZvAnF; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="WsQZvAnF" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-a26fa294e56so646715166b.0 for ; Sun, 03 Mar 2024 07:01:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1709478084; x=1710082884; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=omWEpNMS3+uKdLcCHx2ERnon/p7l0GHwPHHpg6EUlWU=; b=WsQZvAnFcMRG0nOIqAthU0T0YBPM6Uqbv0iPVTNohHauzqVE+ZV7Q+IXU/zv+d+47+ H0/+uf7W9f0ldQHX67WdTr9joSEwOzdFu7XX0m4GBEZjE5puzn7ln2M3U/rjL9CSMwFu dYdJcI4S+2I0/F88mbE3AlDUIY/2Vrt31XQUJpDePcHPo4BfYcWYUtfcYAvYJob7Lt/7 InvWI3l4zNoUe6OX59E+UwJX0VfZyyh4JhX5pnfXnPyIF5pkSQHGjU8nX29kDr7e97OJ L+AiVzUCe4f4BFZgRwY1AaDYfe2w+AGHpVDGk2QXMTrZet1ByiZnnID5vWkpPhR/rOcs Akwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709478084; x=1710082884; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=omWEpNMS3+uKdLcCHx2ERnon/p7l0GHwPHHpg6EUlWU=; b=tDprBuk1X90nEHeLMWrPIg/1BzkOoMuQXKsXV8RUhcSupNe3RNtkHfgXLBmQV2ykns xD+L3qr7kSugVsn/uGPhyBUHuLCOPQ3377C0+5u6u+A0JvJ1Bvqgxy+JVIAZgzHiqAiK 2QLZDJRlMxm1LFuIcL9/FZxzHNhYba+MFMbILgw/GtC+r4lE4be6a3qiwjrwz4S9e64T QbkBKg4+mdFsPtag2QlIT88aok5GkytVtw2nnPkNmV0U5Vtr58/TIClkspnev3dQT+XA fRuVfL4PL5CoyZ4ZNp+CYcV4fs03yF7OXWJlgMKhfPrTTqdHxpS4gr2Xy8u0T1HpLazk 3SlQ== X-Gm-Message-State: AOJu0Yw47YePzvXq+nvPtLyEBgIYONsMxI1mL8LotCI04Jduh5+BGWJ4 lATF4/8RY0xTreXIO3KmK4NQihjn4Z45vUReuNCtUO5Sv5hXv2MVWlrbmkGXmfY= X-Google-Smtp-Source: AGHT+IG7l8tLBdAcqOUmTQ8q9YqmxGpIJwZrrQZWFJkG4+xAa/5uz2ONBIwi1xccuDSbdLPs6vzX7w== X-Received: by 2002:a17:906:339a:b0:a44:ff95:3911 with SMTP id v26-20020a170906339a00b00a44ff953911mr1768068eja.66.1709478084274; Sun, 03 Mar 2024 07:01:24 -0800 (PST) Received: from brgl-uxlite.. ([77.241.232.10]) by smtp.gmail.com with ESMTPSA id ch14-20020a170906c2ce00b00a42ea946917sm3740293ejb.130.2024.03.03.07.01.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Mar 2024 07:01:23 -0800 (PST) From: Bartosz Golaszewski 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@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@quicinc.com, Bartosz Golaszewski , Deepti Jaggi Subject: [PATCH v8 01/12] firmware: qcom: add a dedicated TrustZone buffer allocator Date: Sun, 3 Mar 2024 16:01:04 +0100 Message-Id: <20240303150115.133633-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240303150115.133633-1-brgl@bgdev.pl> References: <20240303150115.133633-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Bartosz Golaszewski 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 Reviewed-by: Andrew Halaney Tested-by: Andrew Halaney # sc8280xp-lenovo-thinkpad-x13s Tested-by: Deepti Jaggi #sa8775p-ride Reviewed-by: Elliot Berman --- MAINTAINERS | 8 + drivers/firmware/qcom/Kconfig | 20 ++ drivers/firmware/qcom/Makefile | 1 + drivers/firmware/qcom/qcom_tzmem.c | 392 +++++++++++++++++++++++ drivers/firmware/qcom/qcom_tzmem.h | 13 + include/linux/firmware/qcom/qcom_tzmem.h | 56 ++++ 6 files changed, 490 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 1794b8d7c76b..c1138c709365 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18327,6 +18327,14 @@ L: linux-arm-msm@vger.kernel.org S: Maintained F: drivers/firmware/qcom/qcom_qseecom.c +QUALCOMM TRUST ZONE MEMORY ALLOCATOR +M: Bartosz Golaszewski +L: linux-arm-msm@vger.kernel.org +S: Maintained +F: drivers/firmware/qcom/qcom_tzmem.c +F: drivers/firmware/qcom/qcom_tzmem.h +F: include/linux/firmware/qcom/qcom_tzmem.h + QUALCOMM QSEECOM UEFISECAPP DRIVER M: Maximilian Luz L: linux-arm-msm@vger.kernel.org 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..23f364afa6ca --- /dev/null +++ b/drivers/firmware/qcom/qcom_tzmem.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Memory allocator for buffers shared with the TrustZone. + * + * Copyright (C) 2023-2024 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + 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 "); +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 +#include +#include + +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 */ From patchwork Sun Mar 3 15:01:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 777656 Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D2BE67C41 for ; Sun, 3 Mar 2024 15:01:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478088; cv=none; b=axb+MJFecwOuqlGaBkh3IdYRW4wxATdeG0dgdOfno/ZMr1/NH+PbIu8y9ZcpAhEE4+VbWEpNG+dh/9ESKO1WF4zi5570AghkLyVw3pBeolcmevVH55NJr3uQWH3xkja8vJ5dQ8u8hkC4Gaz/OX/RE7vXI9E8RtPU7Nvl8rlH43g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478088; c=relaxed/simple; bh=dhPHG49+UE+Xhs0MBAhilLHAVcEDT01o86GHYILdoTg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FAOAvil6o7l2XmSMPoDZdcBuXNBySxjmLaEJMIoM6es0/zTnWeJsepEpH8GUj6sOdaXBPDgCxbikAq2rdXFAd5S0qOrLqlZxKxg25M9y7e/TZBmLi5gJhuZAGwO1YtAs8o8X4iRnuu163di5pVxwmmY+Lu5/E4ufnjV6eRdXAiM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=mml4Wgv0; arc=none smtp.client-ip=209.85.208.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="mml4Wgv0" Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-56533e30887so6287675a12.1 for ; Sun, 03 Mar 2024 07:01:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1709478085; x=1710082885; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9f0fZ+mvuobwqRmEJ6FMeGs/lhMedUb8b4lbCQGk2+4=; b=mml4Wgv0Ypl5SBnNTihue0Pv3SdkUH3/qaPF9qiX9UmRnU1W2NsFWOsudabBxdN8lm XXdHdONYvL4RrfrbuG2PvrUMKRyBU5u3a0A10ZP77gbeiMPfPgUwDg6j+qr9Qghh0ymo PGwNXiTizw+voRbnzUYAOM4m9xTVugkpSW8b98tN3nTnN9dIm/9pskJanO8aoKBtwmW5 3K+NGjpPOaXNI0Zciu695Q+cwPaQdBafKPd1s4czAw8AxXapiN8rjQKu9xSCXvgoTAyv QqfhTYdr0rbth1b3dTrZcy0qe0LpWPpMIU3L6Ck5+rzB4bFvxj31b8QrDhZjtjR5zoen u7Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709478085; x=1710082885; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9f0fZ+mvuobwqRmEJ6FMeGs/lhMedUb8b4lbCQGk2+4=; b=oM7KjYzSl8MOnvr4KsoqXcJhg6RT24mEfw4Z0I5wWKZGakw224HfUT3eQYmBounMV6 THMkZKVjP3bAZXq7E6ml0+XQf8wrB9E7rVMuAsU2fr3jaNTJTqR28Bru5ARDDQ9tfIxe Xo9gj41r541GmmOgzxaokSKBNjilFnT9TXlTrH8EOsT0B4URtXLKkUfml/K4FET+cr/+ 8azFT6j8RPnN1FZ7Zgtn7w6R9uDP0eMyRkCOkQT52xnE8ds4O1wfJ/OtmMbxyYsElcgJ uYMloImAJKN0dLcvLo9QkIP7+IGuYnAe39EAimez7Ytyl4a7oLyiD5MCvly8XumEHTxH gnyg== X-Gm-Message-State: AOJu0YxnKCHcVghRYGBR32O49vDm0Wxpo4066LyG7KQ7dmeRd6IyWAA1 /odlh+DJECTpFsGWzGoVkIsnn11g357l0PRldGg/6zEKDl6aTqcOs+bnG8NU5I0= X-Google-Smtp-Source: AGHT+IGx+UAn5om3k3T5rx4lM6IEAlIbTzf7XS1OK8hZ2qhS6tn94N+XdFsJhI4ljzF0dHMof1lz3Q== X-Received: by 2002:a17:907:7677:b0:a3f:98e4:7dc9 with SMTP id kk23-20020a170907767700b00a3f98e47dc9mr4853658ejc.28.1709478085081; Sun, 03 Mar 2024 07:01:25 -0800 (PST) Received: from brgl-uxlite.. ([77.241.232.10]) by smtp.gmail.com with ESMTPSA id ch14-20020a170906c2ce00b00a42ea946917sm3740293ejb.130.2024.03.03.07.01.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Mar 2024 07:01:24 -0800 (PST) From: Bartosz Golaszewski 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@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@quicinc.com, Bartosz Golaszewski , Deepti Jaggi Subject: [PATCH v8 02/12] firmware: qcom: scm: enable the TZ mem allocator Date: Sun, 3 Mar 2024 16:01:05 +0100 Message-Id: <20240303150115.133633-3-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240303150115.133633-1-brgl@bgdev.pl> References: <20240303150115.133633-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Bartosz Golaszewski 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 Reviewed-by: Andrew Halaney Tested-by: Andrew Halaney # sc8280xp-lenovo-thinkpad-x13s Tested-by: Deepti Jaggi #sa8775p-ride Reviewed-by: Elliot Berman --- 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 520de9b5633a..2245ec8278e0 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -20,9 +22,11 @@ #include #include #include +#include #include #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 { @@ -1812,6 +1818,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; @@ -1887,6 +1894,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. * From patchwork Sun Mar 3 15:01:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 777654 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B4F7367C4A for ; Sun, 3 Mar 2024 15:01:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478091; cv=none; b=XfWge6TYNPe/fyGAq4W9g25agSvcRurMdJYLLQCnot1qFANcVT5cZBHW0pg5l07T5sNToKeJspZRktywm+jfd9OIUJMnHLepKaG4Tv61mwHqeNkAl6IM+WWulQxqBytlg+RRs8Sz4xCHKjlBQgkjlvHkAAO0gtW39933JbKBftk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478091; c=relaxed/simple; bh=OjLFQivtHlaSfovOENt2lbC4EBIzbzcugSyAVDkhXsY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=K3a0NFAs06JqDnrs6yD8ctGvjoRKrciAnPqXJlduA21gwZHhNRmo7WPXugnGpJcBIVYyt1quGIACS8yurl9s30DhPFLTN/Qbf8/nr1TDraM8/wbUMGjZreagmYUaMs+SyqMm2+hW+bnFR2QICbbaiYRelcVFiM+N8lLVF69U/2A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=NurPyJBn; arc=none smtp.client-ip=209.85.218.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="NurPyJBn" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-a44f2d894b7so91494966b.1 for ; Sun, 03 Mar 2024 07:01:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1709478088; x=1710082888; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fcH8Gs0ePK1IRGlv4zM5EcshiNK/rdgYWkudHAB0izE=; b=NurPyJBn+7dlm0QdXpg7iPjfa3cWWXeQmeEfXO43zW1oYZXSk5mTS9W5DS3voWLE1M UQ0su2jnK6EKj5Cv2KnHeOkM9ryZuCtRbExvftxFg69J6+3h0zExWj6CkKSVepSQL9fc JCjfwmRtHFfe6CcUPTMri32RGKkcfftc+lPrXuXfku2I17QlI/11gUCe75qJGbS4VZst s62YoWf2dotdfMtW8Sgk5odluSzvEzQ65epkI3SGEZJbRouDcAAHmbLs+EkZsEjb/8Z/ VNzIBh4gwYdRSC6gjAHBuMy5r8ADrcIXrD85QHdGvgExMbshFyTrvvy06tjnIBp1HL6W VxVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709478088; x=1710082888; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fcH8Gs0ePK1IRGlv4zM5EcshiNK/rdgYWkudHAB0izE=; b=ivbnBHTb/lHm6yUfQQWuX3EskEHmaFc2av/kXV+BOwnsBk8yd7UiSAHoTepl+Iw+zZ ZpuaGVQeS3zSP6Qo3fp9qHRyrbAJckkVd9R+xqM2TvRK3Vf+P/du8WWWWPWKgEdPUTEi /UyV2lFoyY8Ih5BPhE1jgmQzkokXHzXUfR0i8hRBpt7xkCsTdKkKXFU6RSzTV/69130s pHO42Kw8po81rcUFFnjzYFhtxWcV+t4zcGVFlnjaXmOPBfcgfeOe88+H3MTT/ezqR1NE 9s8jgpdpP7nWQeaGRmk2ho4QhjG79PgGHWhbaQLHON00B21F3XXU0sMwU0Sg4jwXSyHu Ma5A== X-Gm-Message-State: AOJu0YxpkuzogbCySeGWOh8J71vNuGA0lEzzXEllYJARSdSnkl97fQSZ l0A6/fRrdcDo/Wb/V2oGd9C1NMd2Z65BTx2A+p4tnSOrhSEw9bXuadjY+zxZlQU= X-Google-Smtp-Source: AGHT+IHvinUrWnb2ODBDZj/G27wn+bgJ59fftISqEVUtBV74uxy7DphSvelwNQdD7qV6cUmJJn5hPQ== X-Received: by 2002:a17:906:3bd5:b0:a3f:ac54:5aa1 with SMTP id v21-20020a1709063bd500b00a3fac545aa1mr5265556ejf.21.1709478088194; Sun, 03 Mar 2024 07:01:28 -0800 (PST) Received: from brgl-uxlite.. ([77.241.232.10]) by smtp.gmail.com with ESMTPSA id ch14-20020a170906c2ce00b00a42ea946917sm3740293ejb.130.2024.03.03.07.01.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Mar 2024 07:01:27 -0800 (PST) From: Bartosz Golaszewski 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@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@quicinc.com, Bartosz Golaszewski , Deepti Jaggi Subject: [PATCH v8 05/12] firmware: qcom: scm: make qcom_scm_ice_set_key() use the TZ allocator Date: Sun, 3 Mar 2024 16:01:08 +0100 Message-Id: <20240303150115.133633-6-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240303150115.133633-1-brgl@bgdev.pl> References: <20240303150115.133633-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Bartosz Golaszewski 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 Reviewed-by: Andrew Halaney Tested-by: Andrew Halaney # sc8280xp-lenovo-thinkpad-x13s Tested-by: Deepti Jaggi #sa8775p-ride Reviewed-by: Elliot Berman --- 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 054b538828d5..50c574fef3ac 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1197,32 +1197,21 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, .args[4] = data_unit_size, .owner = ARM_SMCCC_OWNER_SIP, }; - void *keybuf; - dma_addr_t key_phys; + int ret; - /* - * 'key' may point to vmalloc()'ed memory, but we need to pass a - * physical address that's been properly flushed. The sanctioned way to - * do this is by using the DMA API. But as is best practice for crypto - * keys, we also must wipe the key after use. This makes kmemdup() + - * dma_map_single() not clearly correct, since the DMA API can use - * bounce buffers. Instead, just use dma_alloc_coherent(). Programming - * keys is normally rare and thus not performance-critical. - */ - - keybuf = dma_alloc_coherent(__scm->dev, key_size, &key_phys, - GFP_KERNEL); + void *keybuf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + key_size, + GFP_KERNEL); if (!keybuf) return -ENOMEM; memcpy(keybuf, key, key_size); - desc.args[1] = key_phys; + desc.args[1] = qcom_tzmem_to_phys(keybuf); ret = qcom_scm_call(__scm->dev, &desc, NULL); memzero_explicit(keybuf, key_size); - dma_free_coherent(__scm->dev, key_size, keybuf, key_phys); return ret; } EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key); From patchwork Sun Mar 3 15:01:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 777653 Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B392692E5 for ; Sun, 3 Mar 2024 15:01:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478093; cv=none; b=scOncDvTw3zL3OZQIJBIjSqljnFLiGUAYdPsvcSWB9cWHVOAFyqylTeR4ToskfSUEF1afs6H9MQP4ReswRZW+jIMs535mvcB2qNb1o1THzaKssU03/gUxR71MEZual24b7bY+3XUK3j9CsG+uhCAgE5Pv0yF981jcfVlzygBaKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478093; c=relaxed/simple; bh=W62wClgcYa0PKLUh0EyUOEk3cSRlXh6BgLiU1tYJFYc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JVjGQvLEIqJ0cwSO+JJhCO+/Fe2Rl191ueMo0KVlfaDE1ynJ9N4hJ9VfSDTfjA9v8SQFynwku+6U1advJa2dX6sB770Uu3JCSEqVWFgLaHtecS3bN8ddTUMGqOAUDd9NdLJ2EapLbNVo6HgaLywK5hfIm+PWheyp/JajWYQYiMw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=TpO8HbMc; arc=none smtp.client-ip=209.85.167.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="TpO8HbMc" Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-512bde3d197so3479232e87.0 for ; Sun, 03 Mar 2024 07:01:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1709478089; x=1710082889; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rwOsyagATLxiLLSOZuWrrte+FT3urOwesDO7wStwSyU=; b=TpO8HbMcU/yz6W1heY4uOaJbXNOhanlA2XBDXuz+yAZEhgVnXXzz7LdiGNDwmLVf3y lILHopD4iR47j4JXXf/DYDkH8VHAJ46dic+c/MFWNkZCvaKtovGy03ExXIAEfYiQwhhb CTtM9mztquL8jz4JEC6gGc8LdBv5EfntYy/i9j7HIb7C7LcwhFfhJ5VMZ8EVuCrb6ef7 9jl48yxUE9/WTiKGHox7+PFiVYYGrq5rYTaHYZISozqe7s6Qhq4ECzMZNfgul2TO7VRE ilmI0IGaGpM2si8usHqlpgDI5QEuNE2fToA/SDiernr2hNX9t0DK8uAlK27HmohlHafz 0gPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709478089; x=1710082889; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rwOsyagATLxiLLSOZuWrrte+FT3urOwesDO7wStwSyU=; b=nJ5CXJ3SyAlcwT2SsWCJYxjbmQ1IqTzDCxj5fiAXjJp1DSsHqOxcNAapb4zl5gx3RN CJ3ZcM5nRI+OWuwaOXUpCHyRRZpPYcQzGKaeY2GP/iiYSZPH3OHuY6kodhv1AVsL9qCk EwzVjrzvL1DOPTu0/A+UcKkvetOZTt/N4YeaMp3AQ41CQdOL9KoHbSWsQyIXWDn53lc0 TnGDUcO9i5mRRYtuLV5W4cnH3pRGHSuscHr+4U6HOcPPXANCatNdGImlGq5YiHAbizJp 3LqROHdB9IstvW8fCvfJJ6scOHuW2rDQM66VC9pEp1/ljX6vIxXSY3xVD1v9Av5LbuSs wNWg== X-Gm-Message-State: AOJu0YxgAgZSMLD8zwJJAfd1fV0df8FHqZlGJhVH/XrNR1zHku39thtS ukutocLDIHB0sjvBuU9LaJCBe5nVxolwNCZUN77kWwpKoz6MnUQV9SJvNuq4Vd9uqJbnAU370gT mTshZng== X-Google-Smtp-Source: AGHT+IHGQCA1nHfqiZlNwIm3ejWFnOM2lHkM5W3Q89+JQgso6u9tVFPfbbwJCf9MV7KbXIbcr0DDXA== X-Received: by 2002:a05:6512:3493:b0:512:d89e:946 with SMTP id v19-20020a056512349300b00512d89e0946mr3969996lfr.44.1709478089065; Sun, 03 Mar 2024 07:01:29 -0800 (PST) Received: from brgl-uxlite.. ([77.241.232.10]) by smtp.gmail.com with ESMTPSA id ch14-20020a170906c2ce00b00a42ea946917sm3740293ejb.130.2024.03.03.07.01.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Mar 2024 07:01:28 -0800 (PST) From: Bartosz Golaszewski 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@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@quicinc.com, Bartosz Golaszewski , Deepti Jaggi Subject: [PATCH v8 06/12] firmware: qcom: scm: make qcom_scm_lmh_dcvsh() use the TZ allocator Date: Sun, 3 Mar 2024 16:01:09 +0100 Message-Id: <20240303150115.133633-7-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240303150115.133633-1-brgl@bgdev.pl> References: <20240303150115.133633-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Bartosz Golaszewski 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 Reviewed-by: Andrew Halaney Tested-by: Andrew Halaney # sc8280xp-lenovo-thinkpad-x13s Tested-by: Deepti Jaggi #sa8775p-ride Reviewed-by: Elliot Berman --- 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 50c574fef3ac..ed2600bbd4eb 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1340,8 +1340,6 @@ EXPORT_SYMBOL_GPL(qcom_scm_lmh_profile_change); int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, u64 limit_node, u32 node_id, u64 version) { - dma_addr_t payload_phys; - u32 *payload_buf; int ret, payload_size = 5 * sizeof(u32); struct qcom_scm_desc desc = { @@ -1356,7 +1354,9 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, .owner = ARM_SMCCC_OWNER_SIP, }; - payload_buf = dma_alloc_coherent(__scm->dev, payload_size, &payload_phys, GFP_KERNEL); + u32 *payload_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + payload_size, + GFP_KERNEL); if (!payload_buf) return -ENOMEM; @@ -1366,11 +1366,10 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, payload_buf[3] = 1; payload_buf[4] = payload_val; - desc.args[0] = payload_phys; + desc.args[0] = qcom_tzmem_to_phys(payload_buf); ret = qcom_scm_call(__scm->dev, &desc, NULL); - dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys); return ret; } EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh); From patchwork Sun Mar 3 15:01:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 777652 Received: from mail-lj1-f173.google.com (mail-lj1-f173.google.com [209.85.208.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE18469DE1 for ; Sun, 3 Mar 2024 15:01:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478095; cv=none; b=ItnhpT5z1cOYawpoV9Jgkbd0vU0Q2Dx4hRMYp0C1rka7COueFDZ2Oe5RbtCHOE9L4xByaGbLRk1nxcmPbZdmiRvTOjhB3TRyy2lbaIjcoM0B67GmqdvYa9n1Qo91qslw7n4QqyNule/GistqIaH6iipk9+C8uZ74dMqCv7q9068= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478095; c=relaxed/simple; bh=JzOml6c2V28hQVwZ5HkSztWfEi02ismkb1ZVE583aP8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B+DkE+kp1Th3ZP81UaXl/VpVK8NpvgXugqaaQtwGq3iHpXOgWp/pExd3WhIPjwA7Kd6lP+iN7wE4iF7JGNFRZeUXT/gg/0hf0aMXNyKLRGcYnkCJTJkjaQDfV48k+ORC55VDhKWR/a3igvhdADNab13l8CqF9GlnGK5jKPm/odc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=qMJDCGit; arc=none smtp.client-ip=209.85.208.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="qMJDCGit" Received: by mail-lj1-f173.google.com with SMTP id 38308e7fff4ca-2d28e465655so52422901fa.0 for ; Sun, 03 Mar 2024 07:01:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1709478091; x=1710082891; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rvxbHPzpiDWwdWBrzUR22pLvzfzBM3Zj0U9nhwJP3FQ=; b=qMJDCGitK89ccgnKKcNV69dloldZYAWc5QIA/qYKJCpXLNWpc1RDUaYQZfqR3yfDDa 63Llw1cd/U8AV95h5D/B1B92Hl5c9AoYEA3/UJZJAVWcXSXDCdRoPiunk8Q1yonNBmv2 /n7q7XwQP2UUC2fsVqDerMvZQ9QapDTY8x4kNOdbVb1bxNjvRd77sWdK993M9oHsn2Y5 hXSVkaxMuHJvQsX/Q1iL3Ky3N77bKTKBx1rPgTlATm+JGJVXEyoWGRbHIU2z4cOdvDTV DXD333ACM8XzEtqUMHCzzBOHUDuEIDckqIIouVxgqOLupium79YI8t47uG3Xu8dAUIKZ Dthw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709478091; x=1710082891; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rvxbHPzpiDWwdWBrzUR22pLvzfzBM3Zj0U9nhwJP3FQ=; b=lyusiZLzuf8/nSIppreSyh2um1gyEJgW+jEv3Q3/mVNjOwiicaX30U7Q1ok3vg6Q8g B22t+SPbUj5ZJLfgjID++ow2wISlWWh8eITP8rEjB0CN1TzrVDJToZx+pD23k5IwPUc4 ylpJq7+KqR2wMrlVokS6f0m/D9CepySQvHV0By7DwjlVp/mCvakPG0iOUssa8qhlwQFu qXhjh/Z73rpWzlESmtHOYZnyrz+CONdZXeVmMUZ/PQNixOYrgVoUbPbmNlGp86Bl/LBZ lBPpOJSFmrYORUJvEZdeHYKY7bozrHUxEVZddXMILmrEhLpht8fc6R8Sk84Q6rstLnsp 0ZQA== X-Gm-Message-State: AOJu0Yzf7o4342pHTiRQioBmATlA+OG22BQS6LCu3uh204SKeGrM8QRn 9LJ/tGlY2R8fBNu3TmYgg7fou6crJDuCili3h1V8BLK4oI/7/6og4EuVCiAACpE= X-Google-Smtp-Source: AGHT+IGirOm2qCTPRK1BB6qTA+a5ED4GMu6hVFtsl2HMZq0eXFWkokV4SAN8NJdzS6p9Br9+E229wg== X-Received: by 2002:a05:6512:2209:b0:512:bce5:5564 with SMTP id h9-20020a056512220900b00512bce55564mr5614087lfu.43.1709478090989; Sun, 03 Mar 2024 07:01:30 -0800 (PST) Received: from brgl-uxlite.. ([77.241.232.10]) by smtp.gmail.com with ESMTPSA id ch14-20020a170906c2ce00b00a42ea946917sm3740293ejb.130.2024.03.03.07.01.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Mar 2024 07:01:30 -0800 (PST) From: Bartosz Golaszewski 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@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@quicinc.com, Bartosz Golaszewski , Deepti Jaggi Subject: [PATCH v8 08/12] firmware: qcom: qseecom: convert to using the TZ allocator Date: Sun, 3 Mar 2024 16:01:11 +0100 Message-Id: <20240303150115.133633-9-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240303150115.133633-1-brgl@bgdev.pl> References: <20240303150115.133633-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Bartosz Golaszewski Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and convert all users of it in the qseecom module to using the TZ allocator for creating SCM call buffers. Together with using the cleanup macros, it has the added benefit of a significant code shrink. As this is largely a module separate from the SCM driver, let's use a separate memory pool. Set the initial size to 4K and - if we run out - add twice the current amount to the pool. Signed-off-by: Bartosz Golaszewski Reviewed-by: Andrew Halaney Tested-by: Maximilian Luz Tested-by: Andrew Halaney # sc8280xp-lenovo-thinkpad-x13s Tested-by: Deepti Jaggi #sa8775p-ride Reviewed-by: Elliot Berman --- .../firmware/qcom/qcom_qseecom_uefisecapp.c | 288 +++++++----------- drivers/firmware/qcom/qcom_scm.c | 30 +- include/linux/firmware/qcom/qcom_qseecom.h | 4 +- 3 files changed, 118 insertions(+), 204 deletions(-) diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c index 32188f098ef3..cf258a884c20 100644 --- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c +++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c @@ -7,17 +7,21 @@ * Copyright (C) 2023 Maximilian Luz */ +#include #include #include #include #include #include #include +#include #include #include #include #include +#include +#include /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */ @@ -253,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info { struct qcuefi_client { struct qseecom_client *client; struct efivars efivars; + struct qcom_tzmem_pool *mempool; }; static struct device *qcuefi_dev(struct qcuefi_client *qcuefi) @@ -272,11 +277,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e const efi_guid_t *guid, u32 *attributes, unsigned long *data_size, void *data) { - struct qsee_req_uefi_get_variable *req_data; - struct qsee_rsp_uefi_get_variable *rsp_data; + struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL; unsigned long buffer_size = *data_size; - efi_status_t efi_status = EFI_SUCCESS; unsigned long name_length; + efi_status_t efi_status; size_t guid_offs; size_t name_offs; size_t req_size; @@ -304,17 +309,13 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e __array(u8, buffer_size) ); - req_data = kzalloc(req_size, GFP_KERNEL); - if (!req_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out; - } + req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL); + if (!req_data) + return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(rsp_size, GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL); + if (!rsp_data) + return EFI_OUT_OF_RESOURCES; req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE; req_data->data_size = buffer_size; @@ -325,28 +326,20 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e req_data->length = req_size; status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length); - if (status < 0) { - efi_status = EFI_INVALID_PARAMETER; - goto out_free; - } + if (status < 0) + return EFI_INVALID_PARAMETER; memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size); status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size); - if (status) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (status) + return EFI_DEVICE_ERROR; - if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->command_id != QSEE_CMD_UEFI_GET_VARIABLE) + return EFI_DEVICE_ERROR; - if (rsp_data->length < sizeof(*rsp_data)) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->length < sizeof(*rsp_data)) + return EFI_DEVICE_ERROR; if (rsp_data->status) { dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n", @@ -360,18 +353,14 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e *attributes = rsp_data->attributes; } - goto out_free; + return efi_status; } - if (rsp_data->length > rsp_size) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->length > rsp_size) + return EFI_DEVICE_ERROR; - if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->data_offset + rsp_data->data_size > rsp_data->length) + return EFI_DEVICE_ERROR; /* * Note: We need to set attributes and data size even if the buffer is @@ -394,33 +383,23 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e if (attributes) *attributes = rsp_data->attributes; - if (buffer_size == 0 && !data) { - efi_status = EFI_SUCCESS; - goto out_free; - } + if (buffer_size == 0 && !data) + return EFI_SUCCESS; - if (buffer_size < rsp_data->data_size) { - efi_status = EFI_BUFFER_TOO_SMALL; - goto out_free; - } + if (buffer_size < rsp_data->data_size) + return EFI_BUFFER_TOO_SMALL; memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size); -out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); -out: - return efi_status; + return EFI_SUCCESS; } static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const efi_char16_t *name, const efi_guid_t *guid, u32 attributes, unsigned long data_size, const void *data) { - struct qsee_req_uefi_set_variable *req_data; - struct qsee_rsp_uefi_set_variable *rsp_data; - efi_status_t efi_status = EFI_SUCCESS; + struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL; unsigned long name_length; size_t name_offs; size_t guid_offs; @@ -450,17 +429,14 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e __array_offs(u8, data_size, &data_offs) ); - req_data = kzalloc(req_size, GFP_KERNEL); - if (!req_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out; - } + req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL); + if (!req_data) + return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), + GFP_KERNEL); + if (!rsp_data) + return EFI_OUT_OF_RESOURCES; req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE; req_data->attributes = attributes; @@ -473,10 +449,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e req_data->length = req_size; status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, name_length); - if (status < 0) { - efi_status = EFI_INVALID_PARAMETER; - goto out_free; - } + if (status < 0) + return EFI_INVALID_PARAMETER; memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size); @@ -485,42 +459,31 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, sizeof(*rsp_data)); - if (status) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (status) + return EFI_DEVICE_ERROR; - if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->command_id != QSEE_CMD_UEFI_SET_VARIABLE) + return EFI_DEVICE_ERROR; - if (rsp_data->length != sizeof(*rsp_data)) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->length != sizeof(*rsp_data)) + return EFI_DEVICE_ERROR; if (rsp_data->status) { dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n", __func__, rsp_data->status); - efi_status = qsee_uefi_status_to_efi(rsp_data->status); + return qsee_uefi_status_to_efi(rsp_data->status); } -out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); -out: - return efi_status; + return EFI_SUCCESS; } static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, unsigned long *name_size, efi_char16_t *name, efi_guid_t *guid) { - struct qsee_req_uefi_get_next_variable *req_data; - struct qsee_rsp_uefi_get_next_variable *rsp_data; - efi_status_t efi_status = EFI_SUCCESS; + struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL; + efi_status_t efi_status; size_t guid_offs; size_t name_offs; size_t req_size; @@ -545,17 +508,13 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, __array(*name, *name_size / sizeof(*name)) ); - req_data = kzalloc(req_size, GFP_KERNEL); - if (!req_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out; - } + req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL); + if (!req_data) + return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(rsp_size, GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL); + if (!rsp_data) + return EFI_OUT_OF_RESOURCES; req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE; req_data->guid_offset = guid_offs; @@ -567,26 +526,18 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size); status = ucs2_strscpy(((void *)req_data) + req_data->name_offset, name, *name_size / sizeof(*name)); - if (status < 0) { - efi_status = EFI_INVALID_PARAMETER; - goto out_free; - } + if (status < 0) + return EFI_INVALID_PARAMETER; status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size); - if (status) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (status) + return EFI_DEVICE_ERROR; - if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->command_id != QSEE_CMD_UEFI_GET_NEXT_VARIABLE) + return EFI_DEVICE_ERROR; - if (rsp_data->length < sizeof(*rsp_data)) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->length < sizeof(*rsp_data)) + return EFI_DEVICE_ERROR; if (rsp_data->status) { dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n", @@ -601,77 +552,59 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, if (efi_status == EFI_BUFFER_TOO_SMALL) *name_size = rsp_data->name_size; - goto out_free; + return efi_status; } - if (rsp_data->length > rsp_size) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->length > rsp_size) + return EFI_DEVICE_ERROR; - if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->name_offset + rsp_data->name_size > rsp_data->length) + return EFI_DEVICE_ERROR; - if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->guid_offset + rsp_data->guid_size > rsp_data->length) + return EFI_DEVICE_ERROR; if (rsp_data->name_size > *name_size) { *name_size = rsp_data->name_size; - efi_status = EFI_BUFFER_TOO_SMALL; - goto out_free; + return EFI_BUFFER_TOO_SMALL; } - if (rsp_data->guid_size != sizeof(*guid)) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->guid_size != sizeof(*guid)) + return EFI_DEVICE_ERROR; memcpy(guid, ((void *)rsp_data) + rsp_data->guid_offset, rsp_data->guid_size); status = ucs2_strscpy(name, ((void *)rsp_data) + rsp_data->name_offset, rsp_data->name_size / sizeof(*name)); *name_size = rsp_data->name_size; - if (status < 0) { + if (status < 0) /* * Return EFI_DEVICE_ERROR here because the buffer size should * have already been validated above, causing this function to * bail with EFI_BUFFER_TOO_SMALL. */ - efi_status = EFI_DEVICE_ERROR; - } + return EFI_DEVICE_ERROR; -out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); -out: - return efi_status; + return EFI_SUCCESS; } static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u32 attr, u64 *storage_space, u64 *remaining_space, u64 *max_variable_size) { - struct qsee_req_uefi_query_variable_info *req_data; - struct qsee_rsp_uefi_query_variable_info *rsp_data; - efi_status_t efi_status = EFI_SUCCESS; + struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL; int status; - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); - if (!req_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out; - } + req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data), + GFP_KERNEL); + if (!req_data) + return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), + GFP_KERNEL); + if (!rsp_data) + return EFI_OUT_OF_RESOURCES; req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO; req_data->attributes = attr; @@ -679,26 +612,19 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data, sizeof(*rsp_data)); - if (status) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (status) + return EFI_DEVICE_ERROR; - if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->command_id != QSEE_CMD_UEFI_QUERY_VARIABLE_INFO) + return EFI_DEVICE_ERROR; - if (rsp_data->length != sizeof(*rsp_data)) { - efi_status = EFI_DEVICE_ERROR; - goto out_free; - } + if (rsp_data->length != sizeof(*rsp_data)) + return EFI_DEVICE_ERROR; if (rsp_data->status) { dev_dbg(qcuefi_dev(qcuefi), "%s: uefisecapp error: 0x%x\n", __func__, rsp_data->status); - efi_status = qsee_uefi_status_to_efi(rsp_data->status); - goto out_free; + return qsee_uefi_status_to_efi(rsp_data->status); } if (storage_space) @@ -710,12 +636,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, if (max_variable_size) *max_variable_size = rsp_data->max_variable_size; -out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); -out: - return efi_status; + return EFI_SUCCESS; } /* -- Global efivar interface. ---------------------------------------------- */ @@ -826,6 +747,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; @@ -844,6 +766,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 b0fc0727d090..6578fe9c8d62 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1567,9 +1567,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id); /** * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app. * @app_id: The ID of the target app. - * @req: Request buffer sent to the app (must be DMA-mappable). + * @req: Request buffer sent to the app (must be TZ memory) * @req_size: Size of the request buffer. - * @rsp: Response buffer, written to by the app (must be DMA-mappable). + * @rsp: Response buffer, written to by the app (must be TZ memory) * @rsp_size: Size of the response buffer. * * Sends a request to the QSEE app associated with the given ID and read back @@ -1585,26 +1585,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, { struct qcom_scm_qseecom_resp res = {}; struct qcom_scm_desc desc = {}; - dma_addr_t req_phys; - dma_addr_t rsp_phys; + phys_addr_t req_phys; + phys_addr_t rsp_phys; int status; - /* Map request buffer */ - req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE); - status = dma_mapping_error(__scm->dev, req_phys); - if (status) { - dev_err(__scm->dev, "qseecom: failed to map request buffer\n"); - return status; - } - - /* Map response buffer */ - rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE); - status = dma_mapping_error(__scm->dev, rsp_phys); - if (status) { - dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); - dev_err(__scm->dev, "qseecom: failed to map response buffer\n"); - return status; - } + req_phys = qcom_tzmem_to_phys(req); + rsp_phys = qcom_tzmem_to_phys(rsp); /* Set up SCM call data */ desc.owner = QSEECOM_TZ_OWNER_TZ_APPS; @@ -1622,10 +1608,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, /* Perform call */ status = qcom_scm_qseecom_call(&desc, &res); - /* Unmap buffers */ - dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE); - dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); - if (status) return status; diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h index 5c28298a98be..e868fac55675 100644 --- a/include/linux/firmware/qcom/qcom_qseecom.h +++ b/include/linux/firmware/qcom/qcom_qseecom.h @@ -27,9 +27,9 @@ struct qseecom_client { /** * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app. * @client: The QSEECOM client associated with the target app. - * @req: Request buffer sent to the app (must be DMA-mappable). + * @req: Request buffer sent to the app (must be TZ memory). * @req_size: Size of the request buffer. - * @rsp: Response buffer, written to by the app (must be DMA-mappable). + * @rsp: Response buffer, written to by the app (must be TZ memory). * @rsp_size: Size of the response buffer. * * Sends a request to the QSEE app associated with the given client and read From patchwork Sun Mar 3 15:01:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 777651 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 87AFA67C44 for ; Sun, 3 Mar 2024 15:01:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478097; cv=none; b=IW/s2mIchJToliLNL4KqB4YxROsQJUZfmmJs2+yrH6MJ8ACWCENzpULNISIKEOlaHAEHOB26miGJGYVGvl47aPq9LmTe0s7WmJAn4MABw0k9iAaJilLuY4upAqIkRV8dpQ0GcpylRxMdNU5xpLBJJ4ESZ4mXGAQcKcVE3TKuPzY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709478097; c=relaxed/simple; bh=BUOiJMJAEpUEY/4J8P8EFUX7DemWfjIpSlIVs71qurE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GGD/v6dnTnvrfy97xdXyLK6GPRvjqlppdZ5sCeu6X/Ulab5g/52EqJy0eQrnaE8FTKUY6PeEmCKXV1Vtj6JBmrbkzO21GHvGrGsDeJ6ksqagvImAIUsZONLBHKlKoBks02xKwq6384uzBYS/IRs5Pw9wA6s59gAspvVRxbLGCkE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=Qt2//bnh; arc=none smtp.client-ip=209.85.218.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="Qt2//bnh" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-a26ed1e05c7so645284866b.2 for ; Sun, 03 Mar 2024 07:01:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1709478094; x=1710082894; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=L12WZQfIjPLa8ST8Z/BOMDM6oqnRCJHCQVsMSwzBc0M=; b=Qt2//bnh3TZAGI+9m51FSvWPjhRu3YnmakxQix81idiR0cfKUQUpwVGxY1I3TTXgRS BHFV8PnzZpBKTSw/CtTeODNwM9PyfBkWo1UDYrRTrCyHLMNPbE8KaxpPacW+AaXO4Sfp JRsjFi3fdoAn3FcknjVrtP4WHSEe44hq0uM2VHKMYxC1uJ2F8rtZl4HpklVaddAzWdNE Ecfl0H3Q6jJ1j8p9L1Cvcg3JwUgy3ukekthDhar5JPV4hxupobyCBJ9iuzyUByqAoUrC 602IafQhESNUoomwdYoWYLwcML52syDaJwLTrWfxN1fJjFz4vM6rlqNW4qhe1g2TmSSA LzjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709478094; x=1710082894; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L12WZQfIjPLa8ST8Z/BOMDM6oqnRCJHCQVsMSwzBc0M=; b=pEH4aH3q6kL+vImxWfr1q4PvZj1cGlZHK/hDykGoDJ7gCOX5t0f8pQ+r9yCQZxsbB5 tsU+OHr/6gNcMhLdJrJTXNEKY375wdQV9lhd7VGj7LpBO8+DGglDtQyk1MQWFT1PKuTA szlNEC8wzJaIsDR7CEsXvaUcFVxk+yEbe+zpz50UEcd4nlnVVkxJFA7hzLocFRteNgfZ q+Wjlq/ivRxOwp2sldiGSbOVBF4b/tiYNcVqUWBif84zeL+qdKk7lri2XvAJ6auA9cM/ 00GxpmgKzd2ExzIgf62GZ4xgluLAs4xAebdv02KHkFD+eQs11XQQVkfJJGLisTr2fAmP BazA== X-Gm-Message-State: AOJu0YyLK1SX9ySgmK/xVT/gu216KFRDINLvK2r1BMv/CASxATN83fbY /klbIgHOVifI+6X4NlXiYDkM9g5hmI+xJYTSs0SlQZOBnYPV1jPZvuxGcytXm+w= X-Google-Smtp-Source: AGHT+IHW70cWGZpmNZWU3rtJ73z8LCBjIZw93+By8b7kiMvBnTYxyj+8PGipVGYRTU0OyQfXajoSsA== X-Received: by 2002:a17:906:4f0a:b0:a45:46f8:a181 with SMTP id t10-20020a1709064f0a00b00a4546f8a181mr125275eju.46.1709478093972; Sun, 03 Mar 2024 07:01:33 -0800 (PST) Received: from brgl-uxlite.. ([77.241.232.10]) by smtp.gmail.com with ESMTPSA id ch14-20020a170906c2ce00b00a42ea946917sm3740293ejb.130.2024.03.03.07.01.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Mar 2024 07:01:33 -0800 (PST) From: Bartosz Golaszewski 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@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@quicinc.com, Bartosz Golaszewski , Deepti Jaggi Subject: [PATCH v8 11/12] firmware: qcom: scm: clarify the comment in qcom_scm_pas_init_image() Date: Sun, 3 Mar 2024 16:01:14 +0100 Message-Id: <20240303150115.133633-12-brgl@bgdev.pl> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240303150115.133633-1-brgl@bgdev.pl> References: <20240303150115.133633-1-brgl@bgdev.pl> Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Bartosz Golaszewski 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 Tested-by: Andrew Halaney # sc8280xp-lenovo-thinkpad-x13s Tested-by: Deepti Jaggi #sa8775p-ride Reviewed-by: Elliot Berman --- 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 811f93edac7f..fbacc959b6fa 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -566,6 +566,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);