This is the kernel patch corresponding to the change landed in TF-A
here: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/18635
This appears to be the right place to post this, let me know if not please.
From 81d97a06a48d01eb53661b41905768271f07b870 Mon Sep 17 00:00:00 2001
From: Jeffrey Kardatzke <jkardatzke(a)google.com>
Date: Fri, 3 Feb 2023 11:33:17 -0800
Subject: [PATCH] tee: optee: Add SMC for loading OP-TEE image
Adds an SMC call that will pass an OP-TEE binary image to EL3 and
instruct it to load it as the BL32 payload. This works in conjunction
with a feature added to Trusted Firmware for ARM that supports this.
Signed-off-by: Jeffrey Kardatzke <jkardatzke(a)google.com>
---
drivers/tee/optee/Kconfig | 9 +++++
drivers/tee/optee/optee_msg.h | 14 +++++++
drivers/tee/optee/optee_smc.h | 22 +++++++++++
drivers/tee/optee/smc_abi.c | 70 +++++++++++++++++++++++++++++++++++
4 files changed, 115 insertions(+)
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index f121c224e682..b96b5db52b37 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -7,3 +7,12 @@ config OPTEE
help
This implements the OP-TEE Trusted Execution Environment (TEE)
driver.
+
+config OPTEE_LOAD_IMAGE
+ bool "Load Op-Tee image as firmware"
+ default n
+ depends on OPTEE
+ help
+ This loads the BL32 image for OP-TEE as firmware when the driver is probed.
+ This returns -EPROBE_DEFER until the firmware is loadable from the
+ filesystem.
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index 70e9cc2ee96b..84c1b15032a9 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -284,6 +284,20 @@ struct optee_msg_arg {
*/
#define OPTEE_MSG_FUNCID_GET_OS_REVISION 0x0001
+/*
+ * Load Trusted OS from optee/tee.bin in the Linux firmware.
+ *
+ * WARNING: Use this cautiously as it could lead to insecure loading of the
+ * Trusted OS.
+ * This SMC instructs EL3 to load a binary and excute it as the Trusted OS.
+ * The first two params are the high and low 32 bits of the size of the payload
+ * and the third and fourth params are the high and low 32 bits of the physical
+ * address of the payload. The payload is in the OP-TEE image format.
+ *
+ * Returns 0 on success and an error code otherwise.
+ */
+#define OPTEE_MSG_FUNCID_LOAD_IMAGE 0x0002
+
/*
* Do a secure call with struct optee_msg_arg as argument
* The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
index 73b5e7760d10..908b1005e9db 100644
--- a/drivers/tee/optee/optee_smc.h
+++ b/drivers/tee/optee/optee_smc.h
@@ -104,6 +104,28 @@ struct optee_smc_call_get_os_revision_result {
unsigned long reserved1;
};
+/*
+ * Load Trusted OS from optee/tee.bin in the Linux firmware.
+ *
+ * WARNING: Use this cautiously as it could lead to insecure loading of the
+ * Trusted OS.
+ * This SMC instructs EL3 to load a binary and excute it as the Trusted OS.
+ *
+ * Call register usage:
+ * a0 SMC Function ID, OPTEE_SMC_CALL_LOAD_IMAGE
+ * a1 Upper 32bit of a 64bit size for the payload
+ * a2 Lower 32bit of a 64bit size for the payload
+ * a3 Upper 32bit of the physical address for the payload
+ * a4 Lower 32bit of the physical address for the payload
+ *
+ * The payload is in the OP-TEE image format.
+ *
+ * Returns result in a0, 0 on success and an error code otherwise.
+ */
+#define OPTEE_SMC_FUNCID_LOAD_IMAGE OPTEE_MSG_FUNCID_LOAD_IMAGE
+#define OPTEE_SMC_CALL_LOAD_IMAGE \
+ OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_LOAD_IMAGE)
+
/*
* Call with struct optee_msg_arg as argument
*
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
index a1c1fa1a9c28..b1e6c4a807db 100644
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -8,6 +8,7 @@
#include <linux/arm-smccc.h>
#include <linux/errno.h>
+#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
@@ -1354,6 +1355,69 @@ static void optee_shutdown(struct platform_device *pdev)
optee_disable_shm_cache(optee);
}
+#ifdef CONFIG_OPTEE_LOAD_IMAGE
+
+#define OPTEE_FW_IMAGE "optee/tee.bin"
+
+static int optee_load_fw(struct platform_device *pdev,
+ optee_invoke_fn *invoke_fn)
+{
+ const struct firmware *fw = NULL;
+ struct arm_smccc_res res;
+ phys_addr_t data_pa;
+ u8 *data_buf = NULL;
+ u64 data_size;
+ u32 data_pa_high, data_pa_low;
+ u32 data_size_high, data_size_low;
+ int rc;
+
+ rc = request_firmware(&fw, OPTEE_FW_IMAGE, &pdev->dev);
+ if (rc)
+ return -EPROBE_DEFER;
+
+ data_size = fw->size;
+ /*
+ * This uses the GFP_DMA flag to ensure we are allocated memory in the
+ * 32-bit space since TF-A cannot map memory beyond the 32-bit boundary.
+ */
+ data_buf = kmalloc(fw->size, GFP_KERNEL | GFP_DMA);
+ if (!data_buf) {
+ rc = -ENOMEM;
+ goto fw_err;
+ }
+ memcpy(data_buf, fw->data, fw->size);
+ data_pa = virt_to_phys(data_buf);
+ reg_pair_from_64(&data_pa_high, &data_pa_low, data_pa);
+ reg_pair_from_64(&data_size_high, &data_size_low, data_size);
+ goto fw_load;
+
+fw_err:
+ pr_warn("image loading failed\n");
+ data_pa_high = data_pa_low = data_size_high = data_size_low = 0;
+
+fw_load:
+ /*
+ * Always invoke the SMC, even if loading the image fails, to indicate
+ * to EL3 that we have passed the point where it should allow invoking
+ * this SMC.
+ */
+ invoke_fn(OPTEE_SMC_CALL_LOAD_IMAGE, data_size_high, data_size_low,
+ data_pa_high, data_pa_low, 0, 0, 0, &res);
+ if (!rc)
+ rc = res.a0;
+ if (fw)
+ release_firmware(fw);
+ kfree(data_buf);
+
+ return rc;
+}
+#else
+static inline int optee_load_fw(struct platform_device *__unused,
+ optee_invoke_fn *__unused) {
+ return 0;
+}
+#endif
+
static int optee_probe(struct platform_device *pdev)
{
optee_invoke_fn *invoke_fn;
@@ -1372,6 +1436,12 @@ static int optee_probe(struct platform_device *pdev)
if (IS_ERR(invoke_fn))
return PTR_ERR(invoke_fn);
+ rc = optee_load_fw(pdev, invoke_fn);
+ if (rc) {
+ pr_warn("image loading failed\n");
+ return rc;
+ }
+
if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
pr_warn("api uid mismatch\n");
return -EINVAL;
--
2.39.1.519.gcb327c4b5f-goog
Hi Linus,
Please pull these patches which clean up shm_get_kernel_pages() in the TEE
subsystem and ultimately remove get_kernel_pages(). The patches have only
been in linux-next for close to a week but you told me it was OK to send
them anyway.
I'm normally sending my pull requests to arm-soc, but with the short
time in linux-next and everything I decided to send it directly to you
this time.
Thanks,
Jens
The following changes since commit ceaa837f96adb69c0df0397937cd74991d5d821a:
Linux 6.2-rc8 (2023-02-12 14:10:17 -0800)
are available in the Git repository at:
https://git.linaro.org/people/jens.wiklander/linux-tee.git tags/remove-get_kernel_pages-for-6.3
for you to fetch changes up to 816477edfba6e7ab9411acec5f07cfa00e0882f7:
mm: Remove get_kernel_pages() (2023-02-13 14:16:41 +0100)
----------------------------------------------------------------
Remove get_kernel_pages()
Vmalloc page support is removed from shm_get_kernel_pages() and the
get_kernel_pages() call is replaced by calls to get_page(). With no
remaining callers of get_kernel_pages() the function is removed.
----------------------------------------------------------------
Ira Weiny (4):
highmem: Enhance is_kmap_addr() to check kmap_local_page() mappings
tee: Remove vmalloc page support
tee: Remove call to get_kernel_pages()
mm: Remove get_kernel_pages()
drivers/tee/tee_shm.c | 37 ++++++++++---------------------------
include/linux/highmem-internal.h | 5 ++++-
include/linux/mm.h | 2 --
mm/swap.c | 30 ------------------------------
4 files changed, 14 insertions(+), 60 deletions(-)
This series introduces the tee based EFI Runtime Variable Service.
This version moves StMM related code from drivers/tee/optee to
drivers/firmware/efi/stmm, since StMM code does not contain
OP-TEE specific code and can be used with other TEE implementation.
The eMMC device is typically owned by the non-secure world(linux in
this case). There is an existing solution utilizing eMMC RPMB partition
for EFI Variables, it is implemented by interacting with
OP-TEE, StandaloneMM(as EFI Variable Service Pseudo TA), eMMC driver
and tee-supplicant. The last piece is the tee-based variable access
driver to interact with OP-TEE and StandaloneMM.
Changelog:
rfc v1 -> v2:
- split patch into three patches, one for drivers/tee,
one for include/linux/efi.h, and one for the driver/firmware/efi/stmm
- context/session management into probe() and remove() same as other tee
client driver
- StMM variable driver is moved from driver/tee/optee to driver/firmware/efi
- use "tee" prefix instead of "optee" in driver/firmware/efi/stmm/tee_stmm_efi.c,
this file does not contain op-tee specific code, abstracted by tee layer and
StMM variable driver will work on other tee implementation.
- PTA_STMM_CMD_COMMUNICATE -> PTA_STMM_CMD_COMMUNICATE
- implement query_variable_store() but currently not used
- no use of TEEC_SUCCESS, it is defined in driver/tee/optee/optee_private.h.
Other tee client drivers use 0 instead of using TEEC_SUCCESS
- remove TEEC_ERROR_EXCESS_DATA status, it is refered just to output
error message
Masahisa Kojima (4):
efi: expose efivar generic ops register function
efi: Add EFI_ACCESS_DENIED status code
tee: expose tee efivar register function
efi: Add tee-based EFI variable driver
drivers/firmware/efi/Kconfig | 15 +
drivers/firmware/efi/Makefile | 1 +
drivers/firmware/efi/efi.c | 12 +
drivers/firmware/efi/stmm/mm_communication.h | 249 ++++++++
drivers/firmware/efi/stmm/tee_stmm_efi.c | 620 +++++++++++++++++++
drivers/tee/tee_core.c | 23 +
include/linux/efi.h | 4 +
include/linux/tee_drv.h | 23 +
8 files changed, 947 insertions(+)
create mode 100644 drivers/firmware/efi/stmm/mm_communication.h
create mode 100644 drivers/firmware/efi/stmm/tee_stmm_efi.c
--
2.30.2
This RFC series introduces the op-tee based EFI Runtime Variable
Service.
The eMMC device is typically owned by the non-secure world(linux in
this case). There is an existing solution utilizing eMMC RPMB partition
for EFI Variables, it is implemented by interacting with
OP-TEE, StandaloneMM(as EFI Variable Service Pseudo TA), eMMC driver
and tee-supplicant. The last piece is the tee-based variable access
driver to interact with OP-TEE and StandaloneMM.
Masahisa Kojima (2):
efi: expose efivar generic ops register function
tee: Add op-tee helper functions for variable access
drivers/firmware/efi/efi.c | 12 +
drivers/tee/optee/Kconfig | 10 +
drivers/tee/optee/Makefile | 1 +
drivers/tee/optee/mm_communication.h | 249 +++++++++++
drivers/tee/optee/optee_private.h | 5 +-
drivers/tee/optee/optee_stmm_efi.c | 598 +++++++++++++++++++++++++++
drivers/tee/tee_core.c | 23 ++
include/linux/efi.h | 4 +
include/linux/tee_drv.h | 23 ++
9 files changed, 924 insertions(+), 1 deletion(-)
create mode 100644 drivers/tee/optee/mm_communication.h
create mode 100644 drivers/tee/optee/optee_stmm_efi.c
--
2.30.2
The i2c-designware-amdpsp driver communicates with a platform
features mailbox provided by the PSP. The address used for
communication is discovered via a non-architecturally
guaranteed mechanism.
To better scale, export a feature for communication with platform
features directly from the ccp driver.
Mario Limonciello (6):
crypto: ccp: Drop TEE support for IRQ handler
crypto: ccp: Add a header for multiple drivers to use `__psp_pa`
crypto: ccp: Move some PSP mailbox bit definitions into common header
crypto: ccp: Add support for an interface for platform features
crypto: ccp: Enable platform access interface on client PSP parts
i2c: designware: Use PCI PSP driver for communication
arch/x86/kvm/svm/sev.c | 1 +
drivers/crypto/ccp/Makefile | 3 +-
drivers/crypto/ccp/platform-access.c | 166 ++++++++++++++++++++
drivers/crypto/ccp/platform-access.h | 34 ++++
drivers/crypto/ccp/psp-dev.c | 32 ++--
drivers/crypto/ccp/psp-dev.h | 11 +-
drivers/crypto/ccp/sev-dev.c | 16 +-
drivers/crypto/ccp/sev-dev.h | 2 +-
drivers/crypto/ccp/sp-dev.h | 7 +
drivers/crypto/ccp/sp-pci.c | 7 +
drivers/crypto/ccp/tee-dev.c | 17 +-
drivers/i2c/busses/Kconfig | 2 +-
drivers/i2c/busses/i2c-designware-amdpsp.c | 149 +-----------------
drivers/i2c/busses/i2c-designware-core.h | 1 -
drivers/i2c/busses/i2c-designware-platdrv.c | 1 -
drivers/tee/amdtee/call.c | 2 +-
drivers/tee/amdtee/shm_pool.c | 2 +-
include/linux/psp-platform-access.h | 50 ++++++
include/linux/psp-sev.h | 8 -
include/linux/psp.h | 26 +++
20 files changed, 340 insertions(+), 197 deletions(-)
create mode 100644 drivers/crypto/ccp/platform-access.c
create mode 100644 drivers/crypto/ccp/platform-access.h
create mode 100644 include/linux/psp-platform-access.h
create mode 100644 include/linux/psp.h
base-commit: c7410b425de40e9b163eef781e1bdacf1bf2962e
--
2.34.1
Sumit,
I did not see a follow up on this series per your last email.[1] I'd like to
move forward with getting rid of kmap_to_page(). So Hopefully this can land
and you can build on this rather than the other way around?
All,
Al Viro found[2] that kmap_to_page() is broken. But not only is it broken, it
presents confusion over how highmem should be used because kmap() and friends
should not be used for 'long term' mappings.
get_kernel_pages() is a caller of kmap_to_page(). It only has one caller
[shm_get_kernel_pages()] which does not need the functionality.
Alter shm_get_kernel_pages() to no longer call get_kernel_pages() and remove
get_kernel_pages(). Along the way it was noted that shm_get_kernel_pages()
does not have any need to support vmalloc'ed addresses either. Remove that
functionality to clean up the logic.
This series also fixes is_kmap_addr() and uses it to ensure no kmap addresses
slip in later.
[1] https://lore.kernel.org/all/CAFA6WYMqEVDVW-ifoh-V9ni1zntYdes8adQKf2XXAUpqda…
[2] https://lore.kernel.org/lkml/YzSSl1ItVlARDvG3@ZenIV
To: Sumit Garg <sumit.garg(a)linaro.org>
To: Andrew Morton <akpm(a)linux-foundation.org>
Cc: "Al Viro" <viro(a)zeniv.linux.org.uk>
Cc: "Christoph Hellwig" <hch(a)lst.de>
Cc: linux-kernel(a)vger.kernel.org
Cc: op-tee(a)lists.trustedfirmware.org
Cc: linux-mm(a)kvack.org
Cc: Jens Wiklander <jens.wiklander(a)linaro.org>
Cc: "Fabio M. De Francesco" <fmdefrancesco(a)gmail.com>
Signed-off-by: Ira Weiny <ira.weiny(a)intel.com>
---
Changes in v2:
- Al Viro: Avoid allocating the kiov.
- Sumit: Update cover letter to clarify the motivation behind removing
get_kernel_pages()
- Link to v1: https://lore.kernel.org/r/20221002002326.946620-1-ira.weiny@intel.com
---
Ira Weiny (4):
highmem: Enhance is_kmap_addr() to check kmap_local_page() mappings
tee: Remove vmalloc page support
tee: Remove call to get_kernel_pages()
mm: Remove get_kernel_pages()
drivers/tee/tee_shm.c | 37 ++++++++++---------------------------
include/linux/highmem-internal.h | 5 ++++-
include/linux/mm.h | 2 --
mm/swap.c | 30 ------------------------------
4 files changed, 14 insertions(+), 60 deletions(-)
---
base-commit: 0136d86b78522bbd5755f8194c97a987f0586ba5
change-id: 20230203-get_kernel_pages-199342cfba79
Best regards,
--
Ira Weiny <ira.weiny(a)intel.com>
Add a new ioctl called TEE_IOC_SHM_REGISTER_FD to register a
shared memory from a dmabuf file descriptor.
This new ioctl will allow the Linux Kernel to register a buffer
to be used by the Secure Data Path OPTEE OS feature.
Please find more information here:
https://static.linaro.org/connect/san19/presentations/san19-107.pdf
Patch tested on Hikey 6220.
Etienne Carriere (1):
tee: new ioctl to a register tee_shm from a dmabuf file descriptor
drivers/tee/tee_core.c | 38 +++++++++++++++
drivers/tee/tee_shm.c | 99 +++++++++++++++++++++++++++++++++++++++-
include/linux/tee_drv.h | 11 +++++
include/uapi/linux/tee.h | 29 ++++++++++++
4 files changed, 175 insertions(+), 2 deletions(-)
--
2.25.0