From patchwork Tue Apr 1 17:05:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035193 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (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 3EDAF21C193 for ; Tue, 1 Apr 2025 17:05:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527159; cv=none; b=U26qYyM/IvoJ2qoN+NzjdZkNAEdG6dnOeOk8ieg/MCcY6Uyf2CxFpibovvSU6akBCTfaPmTzgTlAWST0OcTEyOXdiwSXfuXHAmJmJv4i4kEvhx0mWw/JUaqlutbGTM6Asmfhn9n5jccEMt7z3mWgSMur6H5mCFUG7u02c2IgNAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527159; c=relaxed/simple; bh=KXerYYejaebsX7jbyb1Lb5RpqboiWkfKzCdImI0qQB8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h61Ll5K0C0ya85LQskPBEnvrsRBybXcEnHd217vgWjoi7ggx/zv1M1N2eYnnO9/snvh5/HXgd1slPMPbfupbpyZU2LURlh+d0Vog8rEXh2QSfbv5qVrxqI2ddg9FQgRLZuk7de8UfYhdN2IgibzEHMdUhjNGHQ0zdSFY2PwrxW4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nWR6X5ge; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nWR6X5ge" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-22438c356c8so113828305ad.1 for ; Tue, 01 Apr 2025 10:05:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527156; x=1744131956; 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=5jy8qC0h8+P67i9ZAO/Zho3A5/9ZziVLel9NfnuQo2c=; b=nWR6X5gemlBHD4/CJYXdeGqVRbVt5+jRbtFRAvxesHE/AABhHKIyAkEeJ+BvInn/mR 4DJKS6xQOvKCU9+7ok1FOhha/0VWmB2vaVVasfBK3mao7F03jCq8gFCExOCLwgNySUMw B7fpOTY1DevO+QKwB9jmpV7cF4j5Uzq6yqafp6TWYMBWnEihyEPcuO7V8GwVRStRhR6M 87oHQ9+aYNtkrAG0ZfUnMuZmYsXw/FzHhmEMSsQ3gAmD685E6thDHhhm6OaTiP4T9oBY Gm1REtcdTrUkoBgHCv6N4001+YMl4pFx0Qoirn84UU1q5ywkqDo9+iAlWaj8sY7rfliC tFTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527156; x=1744131956; 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=5jy8qC0h8+P67i9ZAO/Zho3A5/9ZziVLel9NfnuQo2c=; b=f5QODAo4ij27db5b3o4ZJX+RWNljLYhW1JzvxuB4OG6jc7LZwVRXrCEouaY10wK4Ba wVjX/YFj2pttzl1NglybY111CIGTbjXUNjvhtvGlyWwv2I1UjomfQQMmNtKXdgSsi+Im d6afFx7vW5OsMx7pHw1eFqF9PMzVz2Kwx31JsmHejMEvKnp7LhMeGv5lIi4HPQAkdxA+ +L1rq/JSTHDFFZ19f6yXBQdD2+h98s2EOJlOg8qSqZCXquMcZ8YxK//7+eqmJMlKoYHB RfGSHzy4UO/Tw9Z9/swA1BrryoC1H5PNPicIsFS8Gvr8VzW4+Hz1lFBNmIZ/Am9d+keB TLkQ== X-Forwarded-Encrypted: i=1; AJvYcCXlSCITT3Wn4qgkQ6W/o1J8FPFQ9kiCfsQjQnNvBve0h4W1Q5R+2nE/CyFfBU5dq3qBO1M=@vger.kernel.org X-Gm-Message-State: AOJu0Yx81rRXIaTtczdpJzSYFxhcJhFsTUc/6JKUbEPHrDnrqcAn6XSH s8o+jRvbP1M9H2xXZSNl0OJwFowzSuinOH5SvT9NsPML1SHr3TDf X-Gm-Gg: ASbGncuDO8sIRl5SReWUcGfIk6boIXq+pY6xqGKmG1e+gz0Zako5zJh4ATJ6k9CR8l8 uXEDc2b6bi5fgxobjT13Z1r4fmRBqdqHhaFQMybpiqvtAhpYQ4MonOgk/DyE5+TGFWnq2wiKFqs B18PIZ5TOyzkmZzZ2/MBVw8mKle8WraiJ1XROyeisyoPKOPq6GHYY42JsZ6THd+Zvsr5RXOWsqU l8isxgf3lWTrdxvw6HFpgmGDvkXqVhHD/MZdShagARgQAj4injzOqJgcyWf8pKGwjYMHYklmiv+ zg/o25ibLFsJdqaKKZMaUR30Y4tH+H0N7Xu5gKFZ X-Google-Smtp-Source: AGHT+IGYkL73/rVCuY5eIXCc8VPG7MsAP5ixlU5mMgBMLHSz5fauZRADZEMVVYLaM4aLq44Kjk0EYQ== X-Received: by 2002:a17:902:ef09:b0:224:11fc:40c0 with SMTP id d9443c01a7336-2292f944013mr234995215ad.11.1743527156410; Tue, 01 Apr 2025 10:05:56 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.05.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:05:56 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 1/7] firmware: smccc: Add macros for Trusted OS/App owner check on SMC value Date: Tue, 1 Apr 2025 22:35:21 +0530 Message-ID: <20250401170527.344092-2-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This patch adds ARM_SMCCC_IS_OWNER_TRUSTED_APP() and ARM_SMCCC_IS_OWNER_TRUSTED_OS() macros. These can be used to identify if the SMC is targetted at a Trusted OS/App in the secure world. Signed-off-by: Yuvraj Sakshith --- include/linux/arm-smccc.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index f19be5754090..da2b4565d5b3 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -56,6 +56,14 @@ #define ARM_SMCCC_OWNER_TRUSTED_OS 50 #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 +#define ARM_SMCCC_IS_OWNER_TRUSTED_APP(smc_val) \ + ((ARM_SMCCC_OWNER_NUM(smc_val) >= ARM_SMCCC_OWNER_TRUSTED_APP) && \ + (ARM_SMCCC_OWNER_NUM(smc_val) <= ARM_SMCCC_OWNER_TRUSTED_APP_END)) + +#define ARM_SMCCC_IS_OWNER_TRUSTED_OS(smc_val) \ + ((ARM_SMCCC_OWNER_NUM(smc_val) >= ARM_SMCCC_OWNER_TRUSTED_OS) && \ + (ARM_SMCCC_OWNER_NUM(smc_val) <= ARM_SMCCC_OWNER_TRUSTED_OS_END)) + #define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01 #define ARM_SMCCC_QUIRK_NONE 0 From patchwork Tue Apr 1 17:05:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035194 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (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 78B4C156C62 for ; Tue, 1 Apr 2025 17:06:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527165; cv=none; b=AGLqH9KZS5luY9lYf8Cr0yoMFV7NCUO/3fwdKCCNOqO5XY6wxBKpUo+GO+3V6eZKrYOowDqGzYXHJxHs+nt75cViOa6hQEHiR8i4dyMRJh60BbeFbwEU9KgWhb8aWdzOwq3JvbkInyl8/Wa8VGut94AiJWbqGvLJ6ye/lTIuXI8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527165; c=relaxed/simple; bh=ZI/sEAhEFCu5lvxGAVZMXb5pyLBeXvdXqe60NbG+FmI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HkPng3pYx9svcOq4/xks0vAt0bt5OANv5SZjb+Qdt+CHv6Hp0oL5Ay7ge/8ZvmYPi4atFmcpcbpJyEIEhthW4kpMFtWI+MRru+5HzswKwPJx72l4ZmcbWztTIn5Ypsf1PNPIKgb96Bf+DrUoSt5zZwNtaG8TI3cEH2rHXWBqcO0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ee2+zBTg; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ee2+zBTg" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-225df540edcso933445ad.0 for ; Tue, 01 Apr 2025 10:06:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527162; x=1744131962; 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=GA2kYs8wQSi+0j0jQaDO25e9tFK5hiSvEa3CXe/PxgU=; b=Ee2+zBTg0zvyfn2x8FRDMXQiRGcNRFqUfeWHwXdpu4fRqq8czYc7txo7A8Pp9voCVK 4qqo14tIJnXMCBqb4OlaIiCt9NQzKyFpw/x1QfnrA5x3eTnQQEDsbfBnd0ndj3hBQqkb Fi34zrTliSTg9gm0kIlDf0gMwdwV/azWimVESiuai9KPhpPCn41dv6mmn3in1GDLf1r6 V1WJ7+V+IENxGMv2lseNCuqggnLifOzPrx6qZgqdfGMS1C3dZ+Ro4CdBLUlKAbbiN/9t otqBKW4P8eSCWhAiv+r5EJxCpPdy2PGpbwKIaVZc0j827NgLHMmAVcts+O8r9kkr+CXS lzig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527162; x=1744131962; 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=GA2kYs8wQSi+0j0jQaDO25e9tFK5hiSvEa3CXe/PxgU=; b=u0EitAYU0IKpY636SByaqrVhcg8zC1kOd4E0MZMcTZJZhCZXUwTe0jU9bK9jbga5kB CeryUXHg7R2nGXlH8piZ+d9MZERcBdU5RBFhAe+eZ70VDngac0IdSJn6KsXaK6HAVWKS vIBJ2KAi+lDMEHtYOxuHP1o8BewXsLqr89DYgMcHOEhf3yppJbHkBDP0h6tfhvdvHg2Z Xrao51n0vv/ZgpIbuyFLyUjDesFQ/Cn4Tl32GykJNDBC4QQiYiYoGc7Bj3JBVfonLGoR rtj1Xqd3lgRo0VtXZJboStHTnS0h/V5+znefK/CpSLDlsyLxQDw41GxOu/DP1KoZNA2R W8uw== X-Forwarded-Encrypted: i=1; AJvYcCVlB3rcr2vjwl02zgaIT/ZhFy7qkltNnjJAI/fooMVbqe+eNsldH6eh8AoggbObqTiRfCY=@vger.kernel.org X-Gm-Message-State: AOJu0YyUzCsvq94GTkbUJi5GmN274hPigvXBWxror9pmpEPhYLFnPaJu t2rCeDBWknnCgxrGorKIS6mCRHOO5Ey2czuV8GpsqT9xbO9oJPNaDSJVTERD X-Gm-Gg: ASbGncuoNnh4cefu17Oo2NXlW4tYhQitJSiTdNfLboi/fqC2Rvry9n7GaAowjNJ7iml k/J/AtHXapaldjQI0L4/YPuB/yEXzFHH2ilRMPQ7PmXE1t96dpGHMFEYYxrG68RhnSjQoSIzuFc /FsjTjmfJDwDTpZ0T7frT6KcrvlJw7ZpUW6hxMI3A8dJJT8fLaVV/IizDVfdO+uevc5ex4q7iMn y0RHwTzjJ3gWMyypVbXQC0HN1/ttrK76m8irxsmxA5QxhAeiOOdSSzzWX1Hj5cWUx8gL31YoRfX fDkU3vFqn4keP3ta8XN++Nw/hSOnLs3+LoLKV9t4Xil2TOyzcb4= X-Google-Smtp-Source: AGHT+IGEHf7ivlGPdc+XvUBtzZ62oiMeiz87MJ8nWnqxYcGMsRisgl9JgQeZkopDQbtkvb1l7k8dXg== X-Received: by 2002:a05:6a00:4512:b0:727:39a4:30cc with SMTP id d2e1a72fcca58-739c42f80d1mr1047495b3a.1.1743527162348; Tue, 01 Apr 2025 10:06:02 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.05.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:06:02 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 2/7] tee: Add TEE Mediator module which aims to expose TEE to a KVM guest. Date: Tue, 1 Apr 2025 22:35:22 +0530 Message-ID: <20250401170527.344092-3-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The TEE Mediator module is an upper abstraction layer which lets KVM guests interact with a trusted execution environment. TEE specific subsystems (such as OP-TEE, for example) can register a set of handlers through tee_mediator_register_ops() with the TEE Mediator, which will be called by the kernel when required. Given this module, architecture specific TEE drivers can implement handler functions to work with these events if necessary. In most implementations, a special instruction (such as SMC, in arm64) switches control leading to the TEE. These instructions are usually trapped by the hypervisor when executed by the guest. This module allows making use of these trapped instructions and mediating the request between guest and TEE. Signed-off-by: Yuvraj Sakshith --- drivers/tee/Kconfig | 5 ++ drivers/tee/Makefile | 1 + drivers/tee/tee_mediator.c | 145 +++++++++++++++++++++++++++++++++++ include/linux/tee_mediator.h | 39 ++++++++++ 4 files changed, 190 insertions(+) create mode 100644 drivers/tee/tee_mediator.c create mode 100644 include/linux/tee_mediator.h diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig index 61b507c18780..dc446c9746ee 100644 --- a/drivers/tee/Kconfig +++ b/drivers/tee/Kconfig @@ -11,6 +11,11 @@ menuconfig TEE This implements a generic interface towards a Trusted Execution Environment (TEE). +config TEE_MEDIATOR + bool "Trusted Execution Environment Mediator support" + depends on KVM + help + Provides an abstraction layer for TEE drivers to mediate KVM guest requests to the TEE. if TEE source "drivers/tee/optee/Kconfig" diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile index 5488cba30bd2..46c44e59dd0b 100644 --- a/drivers/tee/Makefile +++ b/drivers/tee/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEE) += tee.o +obj-$(CONFIG_TEE_MEDIATOR) += tee_mediator.o tee-objs += tee_core.o tee-objs += tee_shm.o tee-objs += tee_shm_pool.o diff --git a/drivers/tee/tee_mediator.c b/drivers/tee/tee_mediator.c new file mode 100644 index 000000000000..d1ae7f4cb994 --- /dev/null +++ b/drivers/tee/tee_mediator.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * TEE Mediator for the Linux Kernel + * + * This module enables a KVM guest to interact with a + * Trusted Execution Environment in the secure processing + * state provided by the architecture. + * + * Author: + * Yuvraj Sakshith + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include + +static struct tee_mediator *mediator; + +int tee_mediator_register_ops(struct tee_mediator_ops *ops) +{ + + int ret = 0; + + if (!ops) { + ret = -EINVAL; + goto out; + } + + if (!mediator) { + ret = -EOPNOTSUPP; + goto out; + } + + mediator->ops = ops; + +out: + return ret; +} + +int tee_mediator_is_active(void) +{ + return (mediator != NULL && + mediator->ops != NULL && mediator->ops->is_active()); +} + +int tee_mediator_create_host(void) +{ + int ret = 0; + + if (!tee_mediator_is_active() || !mediator->ops->create_host) { + ret = -ENODEV; + goto out; + } + + ret = mediator->ops->create_host(); + +out: + return ret; +} + +int tee_mediator_destroy_host(void) +{ + int ret = 0; + + if (!tee_mediator_is_active() || !mediator->ops->destroy_host) { + ret = -ENODEV; + goto out; + } + + ret = mediator->ops->destroy_host(); +out: + return ret; +} + +int tee_mediator_create_vm(struct kvm *kvm) +{ + int ret = 0; + + if (!kvm) { + ret = -EINVAL; + goto out; + } + + if (!tee_mediator_is_active() || !mediator->ops->create_vm) { + ret = -ENODEV; + goto out; + } + + ret = mediator->ops->create_vm(kvm); + +out: + return ret; +} + +int tee_mediator_destroy_vm(struct kvm *kvm) +{ + int ret = 0; + + if (!kvm) { + ret = -EINVAL; + goto out; + } + + if (!tee_mediator_is_active() || !mediator->ops->destroy_vm) { + ret = -ENODEV; + goto out; + } + + ret = mediator->ops->destroy_vm(kvm); + +out: + return ret; +} + +void tee_mediator_forward_request(struct kvm_vcpu *vcpu) +{ + if (!vcpu || !tee_mediator_is_active() || !mediator->ops->forward_request) + return; + + mediator->ops->forward_request(vcpu); +} + +static int __init tee_mediator_init(void) +{ + int ret = 0; + + mediator = kzalloc(sizeof(*mediator), GFP_KERNEL); + if (!mediator) { + ret = -ENOMEM; + goto out; + } + + pr_info("mediator initialised\n"); +out: + return ret; +} +module_init(tee_mediator_init); + +static void __exit tee_mediator_exit(void) +{ + kfree(mediator); + + pr_info("mediator exiting\n"); +} +module_exit(tee_mediator_exit); diff --git a/include/linux/tee_mediator.h b/include/linux/tee_mediator.h new file mode 100644 index 000000000000..4a971de158ec --- /dev/null +++ b/include/linux/tee_mediator.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * TEE Mediator for the Linux Kernel + * + * This module enables a KVM guest to interact with a + * Trusted Execution Environment in the secure processing + * state provided by the architecture. + * + * Author: + * Yuvraj Sakshith + */ + +#ifndef __TEE_MEDIATOR_H +#define __TEE_MEDIATOR_H + +#include + +struct tee_mediator_ops { + int (*create_host)(void); + int (*destroy_host)(void); + int (*create_vm)(struct kvm *kvm); + int (*destroy_vm)(struct kvm *kvm); + void (*forward_request)(struct kvm_vcpu *vcpu); + int (*is_active)(void); +}; + +struct tee_mediator { + struct tee_mediator_ops *ops; +}; + +int tee_mediator_create_host(void); +int tee_mediator_destroy_host(void); +int tee_mediator_create_vm(struct kvm *kvm); +int tee_mediator_destroy_vm(struct kvm *kvm); +void tee_mediator_forward_request(struct kvm_vcpu *vcpu); +int tee_mediator_is_active(void); +int tee_mediator_register_ops(struct tee_mediator_ops *ops); + +#endif From patchwork Tue Apr 1 17:05:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035195 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (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 AC42E20E005 for ; Tue, 1 Apr 2025 17:06:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527170; cv=none; b=laTCtOa0rDi9MnLXH+Nr8q4moU7A8/qx5oB5Ln5LBg/ge5NmEUp0a/cw2XYKIg7ZheIxdWbiYOFyXQnMKbSUohO3e0u4t5bUPjS8EeHJtq7XA7J1g+KPZ2IdGNf/rh0+KPEJSMx9yly0ULji2/qNWTkxv/qyOnsmugV5Qj+iu00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527170; c=relaxed/simple; bh=Rw2iroImYquTfYTUaIXKUvTb6nsAifYMwZfzyDLbF+o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NMo1jsbeqGmOA6fh/In6Rbkv+6Tx8xvvBEWo4VJyrwC05w6UJZcj3qaZtrVeN+9pb2TkjwyL/ZHD7+EWsS0Dn/mBrWZNZ3bpb3/XPS96I1bfdJ0oK8MmHZysQ4CoaW9CDmeeZf4l3A5kuxSW/OxcKnCSMGiM+SrGyLGZEQ6U/S4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RF37Idfk; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RF37Idfk" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-227d6b530d8so106540275ad.3 for ; Tue, 01 Apr 2025 10:06:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527168; x=1744131968; 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=OPTaf4AvEp4o/nHIyBvUFwkL4QhKCenH5rmcz21UYa4=; b=RF37IdfkOi/sgDSBaq2f87zakYV9qAa8Oj1LP45UBm9/+I5En5vYD2HGzk4rPe7+sd SCtuhGThoJD+/Wqf9uSKyKJnUbrW8dq9v/f2a85SxoKuoqxEpHHFAiQ+34yb3vBvbisN D0MNeTuEgiwb3Zaka86zjYV9D77dsKk2ZtJ84cajalzY+bVxzc0WggxNOWI1uZ8v/XUa 4x8agvMifipzXiRUh9qAgV32AC7Z4lrAc7bVB041ZU4lBPODNM8eJYk1f1wyjzTKO88o IOhAsTBiotmekkWEFc879lBzYtC98rwnGuoxJAyKVGGoN+e3joJu1AFJQYVVmJcWNia6 Iy1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527168; x=1744131968; 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=OPTaf4AvEp4o/nHIyBvUFwkL4QhKCenH5rmcz21UYa4=; b=DuL/lzw7zRw3bpGABNx5pIuDa4FZZzNdX0whbRcaR/639KoO+zEas9VTAgo2pA1EKG LlOfmorbySj3mjVUfYH4oG/v1cehZ+C6W9zr69EZu7g3SzxR7CUTFo6Od7U1aDCxYf/e s6xvWHLhif01hpq37piIyjnx9wxO4PM66LjTALcQu2KSb/BYeRHQNpUB9iOxEWjGL3cS e/tAFLvKDmnHXg+0fKM6hy4/MYm3OIxuefNtpkiYII/7BVr8lvefVvG78pakvtkDpfL3 8BIl/pibahTws4fey9F1TgE+0BL390lGvkt1rasS7dugi5QncSEtO+nPxeQoz4bxhxYs 2syw== X-Forwarded-Encrypted: i=1; AJvYcCWe8SJjy8bJgebuoFRD2Kmap2vYFrgoKgcoUdmjov6P9lCGxohCphNHLzR4/gCKA4VveRU=@vger.kernel.org X-Gm-Message-State: AOJu0YzUGkoSQphB0MjOyQVWKjiSc54y7pGSHL1OG1nTrccYXPYRLsn6 HZTMSGZl7bG8zJPAiCvrSh2tgAYcZN4cUTSMrns95Bei2Hzuy1Mk X-Gm-Gg: ASbGncuQc7SeOlGl7ENV5OGq+N0CceNtMyw5YGA7qWL4DeSkDAwwlESEF6RmHDR3s+b dulTxyeae+imHw/HUWUX7vLJ/+xC/KiEAhT3lOExuMH4WNkn0qh5A9/3UQynm1LNlYI06eX36Xh FJngamtEfdR4mTTgJJ/9LQgknw2h/pFDs69Wem3kvyK+l1T6ZtBjRbyhxf15n0MLLOrYPcIjjMQ Nj2Vc8ugKnwgsbaNG1t6GHSGuK7kuzxmtVVqVU46P2/CZVt6eceaQLxxOI7zZBchAp2Bxxih8RV aU/znstn6WxZ8DbeNVHmW/nrFLYHWB4F97oJZCCx X-Google-Smtp-Source: AGHT+IEjsBLuez7vDqzanq2HadS3lU0vRC6ZaIOd+CRj0E+wgUGCYo6tCeZNUN+1jjah0vIuS2C9pA== X-Received: by 2002:a05:6a00:1306:b0:736:65c9:9187 with SMTP id d2e1a72fcca58-739b5ff8a4bmr5231754b3a.9.1743527167748; Tue, 01 Apr 2025 10:06:07 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.06.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:06:07 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 3/7] KVM: Notify TEE Mediator when KVM creates and destroys guests Date: Tue, 1 Apr 2025 22:35:23 +0530 Message-ID: <20250401170527.344092-4-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 TEEs supporting virtualization in the rich execution environment would want to know about guest creation and destruction by the hypervisor. This change notifies the TEE mediator of these events (if its active). Signed-off-by: Yuvraj Sakshith --- virt/kvm/kvm_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ba0327e2d0d3..65f1f5075fdd 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -1250,7 +1251,10 @@ static void kvm_destroy_vm(struct kvm *kvm) { int i; struct mm_struct *mm = kvm->mm; - +#ifdef CONFIG_TEE_MEDIATOR + if (tee_mediator_is_active()) + (void) tee_mediator_destroy_vm(kvm); +#endif kvm_destroy_pm_notifier(kvm); kvm_uevent_notify_change(KVM_EVENT_DESTROY_VM, kvm); kvm_destroy_vm_debugfs(kvm); @@ -5407,7 +5411,10 @@ static int kvm_dev_ioctl_create_vm(unsigned long type) * care of doing kvm_put_kvm(kvm). */ kvm_uevent_notify_change(KVM_EVENT_CREATE_VM, kvm); - +#ifdef CONFIG_TEE_MEDIATOR + if (tee_mediator_is_active()) + (void) tee_mediator_create_vm(kvm); +#endif fd_install(fd, file); return fd; From patchwork Tue Apr 1 17:05:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035196 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (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 3A98720DD63 for ; Tue, 1 Apr 2025 17:06:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527175; cv=none; b=OTEBrlkmWFaFRa79qLUnyLW54D2i+qfxytoebhio4Bi7GOoHp8DafGlcabTLU0NDe+hDD1O1V0jaX4+xwQoY8FjVNrGxH4/Mev/QN11GEBDXNBVx8446zPCmkfJc/T8YVb1ZqIB1bWiOFYEVvwiyS+DjchMENeiB54//F5Kjc1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527175; c=relaxed/simple; bh=/ojOGjSENscu9Pb3+EYr5PYhSwGXxXZJjaejcHeP+sw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J9PjM+lNQRv+XlXO0HJbYVR2SMlhySl51AI25wGYytHnhzdUVNhi2j3T1ir/ubQfVeEM0W8Tvt/hiWYj+OV9cY5MIw0108LRHSKIZzETmq1IzSMIPwU/KkYtMRsYOdAXBnh6PbsynoxKyy+/eZOVzBljB5ATxiLDsUvAVsI4zIU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=S6xiP5HE; arc=none smtp.client-ip=209.85.214.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S6xiP5HE" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-227aaa82fafso113042265ad.2 for ; Tue, 01 Apr 2025 10:06:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527173; x=1744131973; 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=KDtkvMqdi74R/fuGRWaxI6Vx86s77IjYzoT0QepjNQ0=; b=S6xiP5HEq8apTva9FNYjO9i7twUf7S/Kvzpc0PE2T+IvpJPtj/7cTUBMoh53vimGfR kQWPId2cBItBLrtXblAUkA6odn+QkexcgRWdMWIarS1HpX/118mq4A+H3lPPaDZU2xVM L9jXbkscZLo4OJzq+FOFO1hp+G3B1lWzndyznvgl7VW8hHaM44X7CAs7x00nEAuGE9D7 A1PzxbQ4Qdd5kQq843ryfsBLnn5ErEeyWmjTIBKILPnpT7CUFecr1zUIOXwNVBUWp4Xh 4UOhInsGeqD+9Qz2pLXv1iCT/I1as6pAdYbHbvbYwMvD8A70RlBmmgC+jQodpKP21KxH oCTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527173; x=1744131973; 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=KDtkvMqdi74R/fuGRWaxI6Vx86s77IjYzoT0QepjNQ0=; b=IHKfC4p/tzcY+TUP2iY+PPyKq2cf9ZHY9ywzLbDL+5bEHl25YsA0mUuJKAWeJdymTn C/S5xl3KrXmnXy1qCQQx5r0rE/9Buvm1toQMRJSyIOFpNsffPZ1c8HhTjGV7aU2B5YiM 4ZMs3pB7oYqShRMntMZz1Shqa4nn3s6LG1hadOqA7ZaZvT+j47sAVDgxFjhPZCPx2X9A XqfCf/KbtYdfd9cBCHE5Zu3iJslLY6KYoSLGH7zInh41WKU0qv5uzXG3uCUvKUF8fpHO OPyvx9XfzEjP/1rBjZfpwq3FifoJLwgcaEGSt7N5xUPpe6zuMnOdvG9D15eVqf7a7NBo xsUg== X-Forwarded-Encrypted: i=1; AJvYcCUrDpDLIuYJxKHSU2XVnY3OndUmzOxCI6bTYvbi1IQwBq9zN4J159MfV6him68PkiLCXJI=@vger.kernel.org X-Gm-Message-State: AOJu0YwKq7kZYlwjblCxp2/240pnCKttGoGIml2EE6WHtSuLpPGvI8qa F85HCATMCUaJ0aSXZ57SIrNsM+mR6+QDA52krKdkUxQtSe931PMm X-Gm-Gg: ASbGncspSxjd2EL5+B76XddGJu+jSjhXESTi3N8A13ZHepA8YDGJQO3Pxna0NZWCBH9 3zNOzuEwkdZYNvHmm9vLRNvnmQ+3OWLAARzCCVWball+OYDDAItsiAUEz0xb6PXF9mBw+GD760G LWCiHodUiXn5VO0Ft3hGy26MU2mXRQxzkD+BJVVxK44UTenPlS35jKer+Cp/68RxHNJ/4DjVQgl OB0vtFeMnGGq9XnPZ/4M5mpt/e5XqWCSOD4kLScuPVa6GmvOgLpfG2jYi8OJzv2KJipsCQ2Hz90 xjXIIpiqqUR35SCKL2V1Z9val0SncuJopzgzGY+r X-Google-Smtp-Source: AGHT+IGVQaPozKtnYFtEaxGdcDkcmfSHjENYsZlMxOjS55uxLWGM2YiQ/vVbzslmIBGst/k5j79maA== X-Received: by 2002:a05:6a00:3a13:b0:736:491b:536d with SMTP id d2e1a72fcca58-7398046fe65mr22142417b3a.20.1743527173462; Tue, 01 Apr 2025 10:06:13 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.06.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:06:13 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 4/7] KVM: arm64: Forward guest CPU state to TEE mediator on SMC trap Date: Tue, 1 Apr 2025 22:35:24 +0530 Message-ID: <20250401170527.344092-5-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When guest makes an SMC, the call is denied by the hypervisor and not handled (ignored). In the presence of the TEE Mediator module, the SMC from guest is forwarded with it's vCPU register state through tee_mediator_forward_request(). Signed-off-by: Yuvraj Sakshith --- arch/arm64/kvm/hypercalls.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 569941eeb3fe..cb34bb87188c 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -3,6 +3,7 @@ #include #include +#include #include @@ -90,7 +91,10 @@ static bool kvm_smccc_default_allowed(u32 func_id) */ if (func_id >= KVM_PSCI_FN(0) && func_id <= KVM_PSCI_FN(3)) return true; - +#ifdef CONFIG_TEE_MEDIATOR + if (ARM_SMCCC_IS_OWNER_TRUSTED_APP(func_id) || ARM_SMCCC_IS_OWNER_TRUSTED_OS(func_id)) + return true; +#endif return false; } } @@ -284,7 +288,14 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu) WARN_RATELIMIT(1, "Unhandled SMCCC filter action: %d\n", action); goto out; } - +#ifdef CONFIG_TEE_MEDIATOR + if (ARM_SMCCC_IS_OWNER_TRUSTED_APP(func_id) || ARM_SMCCC_IS_OWNER_TRUSTED_OS(func_id)) { + if (tee_mediator_is_active()) { + tee_mediator_forward_request(vcpu); + return 1; + } + } +#endif switch (func_id) { case ARM_SMCCC_VERSION_FUNC_ID: val[0] = ARM_SMCCC_VERSION_1_1; From patchwork Tue Apr 1 17:05:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035197 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (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 2AE9D20E005 for ; Tue, 1 Apr 2025 17:06:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527182; cv=none; b=IOOPMIvui9K1jaePrOZRcKvMBqFLin14HPophRLfUGRu/L/CV42H48L0B5AnHH5NdjXRJrKDlOsZK7Ulm4U+78/de3mlMkXlIZ4Gz35quDJeqagpV8X+JI4DXavAv5xiZ07yTqlJBrbadQHd7ZezKkL+zb7Zrw+NTPFLVim6Xas= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527182; c=relaxed/simple; bh=oa79efjOKM9SRXURi1BaVT0pmfHaFaEt9V3KsZ4Q6nM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=A5rLFYq2c1GAFL5f8xUXHx0EGZd5bXuDsqq2nCFFZR/qKZFoajAWyWTqSMfxPg6ueH1wwXOw2KWv/j6gPXGxIyDeRFBDRLCFXxovQgxfyNCYwcwlKo3dwidnvU1jjLqeG1GNmJbAcC/ok2gLqIkG1EmvPwjzY93dr6rvCaIDHY0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dYNLkqgL; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dYNLkqgL" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-22548a28d0cso156830345ad.3 for ; Tue, 01 Apr 2025 10:06:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527180; x=1744131980; 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=FqoSwIUEkmAFZzDF1jp7biKBQ9RqCAjci7v8QaNjgL0=; b=dYNLkqgLxq6iyQGBDVRkVtH11w/to2SlOE4LjkFa9YMY9w/Q+7u4mdfgUurxElZg24 C+bHTIBXupOpRBsuJbRN+JrkjJKdpYQR3oUrMXyIoFBfjMSJ31POn3UYBrS0pvMZmy3/ keuAky+yxse1HhUyhwkQ6OSr2kNkxRP++ezZ/yyHb2VU2HovF+0n65gNUDwfoC2KBs12 VZOihX5hrVMJQi6ZLxU33VbXc3DFeHTz2jzFUy2ZHhO3X65vYxZOu7Ut4TxJQIjOvwMm h2YqPDKUsbQEKwfFZV2r7aFU3SjTfhRvjgBBHF9MuEYWn9Jb5VR2iddntlyTmyz5WR/G 1YtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527180; x=1744131980; 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=FqoSwIUEkmAFZzDF1jp7biKBQ9RqCAjci7v8QaNjgL0=; b=at0mhmDVAsV6yknoDoVKOZpwherOK4loC+JveGgJ5r6SC4Kea8hP2qNR58sr8QIlV0 MGeJnHvqKJjoo3B+urBOem7VhZ2DKW/8HcCsNpYivAc6vaAi7qIo2xoSeM/O4PosTckp htfWjti7/AFBXV37VX3JyeQQmUxFEQ1ighJr/7CQNYmHe+o341qtki0wM//dhfbaObUo OGoJvvq6Ix1b4/S20bNmqGXqj35E0JIqu96VMDieYR9v/+YdliGfThb74/s96alg4sNK yreqdUrEsrwqCiMA/wM0hthPDkWvuDngUf1b7kXEpdoNilca4p5mn9NspU2wnQBY97IC /iyA== X-Forwarded-Encrypted: i=1; AJvYcCUu3R4JGUJjWU0mYvkyEIOUKW+PSqqGcf69FRUvuJiBVw0bH81KiUssp5m1kHqz9MCchzc=@vger.kernel.org X-Gm-Message-State: AOJu0YyApdnX/5AiyABK3KFcow20Y8Q1vrUWStYAln2gvl65oziau7+5 kCC2bAb3n5jocJHk8CfSs0vywND72NcQRxlpOcf/RLrf6WoO0nXwB3t5AA== X-Gm-Gg: ASbGncuFFtBFZT5Z7/MhJU6aVX9vBywAxsbpmyHf2OlA+L+0VTBLCNmyVAnIlVNNW6o gX26MVoL2o7Y/soiV5zmdF4uBBcPMG6a/Aj0/oDWCny/uEpfIPdVc2OR0b6/qoRwZeT6VWsY2HH YA/mnTG5wOKe+S3ZEyyleL8fmzSH6tl3LpH2SpDMWcJFhkDKmEYLoX3QXylf1iCaU9G93JCdm62 Cd/1yl18cjnZWDZHR0Z+oR8I+qrdjtRjMCxCp1FOcKN2BK9oyfaYuvcK6+XPWzhP0j8DLVbnp6e bnUR1mvyUW7pLYx2bYzj5yO0Ms3Nrc6mT6CM97W8 X-Google-Smtp-Source: AGHT+IHMLcW/UgSU+B9QLYjzegvhSUSQLiYd7WdSUYNTNPJYM4iVdsXCx+9AUOlAl0q1OhIHYB2AXw== X-Received: by 2002:a17:902:f544:b0:21f:6bda:e492 with SMTP id d9443c01a7336-2292f9ee9e8mr226767855ad.35.1743527180233; Tue, 01 Apr 2025 10:06:20 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.06.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:06:19 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 5/7] tee: optee: Add OPTEE_SMC_VM_CREATED and OPTEE_SMC_VM_DESTROYED Date: Tue, 1 Apr 2025 22:35:25 +0530 Message-ID: <20250401170527.344092-6-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 OP-TEE when compiled with NS-Virtualization support expects NS-Hypervisor to notify events such as guest creation and destruction through SMCs. This change adds two macros OPTEE_SMC_VM_CREATED and OPTEE_SMC_VM_DESTROYED. Signed-off-by: Yuvraj Sakshith --- drivers/tee/optee/optee_smc.h | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index 879426300821..988539b2407b 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -452,6 +452,59 @@ struct optee_smc_disable_shm_cache_result { /* See OPTEE_SMC_CALL_WITH_REGD_ARG above */ #define OPTEE_SMC_FUNCID_CALL_WITH_REGD_ARG 19 +/* + * Inform OP-TEE about a new virtual machine + * + * Hypervisor issues this call during virtual machine (guest) creation. + * OP-TEE records client id of new virtual machine and prepares + * to receive requests from it. This call is available only if OP-TEE + * was built with virtualization support. + * + * Call requests usage: + * a0 SMC Function ID, OPTEE_SMC_VM_CREATED + * a1 Hypervisor Client ID of newly created virtual machine + * a2-6 Not used + * a7 Hypervisor Client ID register. Must be 0, because only hypervisor + * can issue this call + * + * Normal return register usage: + * a0 OPTEE_SMC_RETURN_OK + * a1-7 Preserved + * + * Error return: + * a0 OPTEE_SMC_RETURN_ENOTAVAIL OP-TEE have no resources for + * another VM + * a1-7 Preserved + * + */ +#define OPTEE_SMC_FUNCID_VM_CREATED 13 +#define OPTEE_SMC_VM_CREATED \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_VM_CREATED) + +/* + * Inform OP-TEE about shutdown of a virtual machine + * + * Hypervisor issues this call during virtual machine (guest) destruction. + * OP-TEE will clean up all resources associated with this VM. This call is + * available only if OP-TEE was built with virtualization support. + * + * Call requests usage: + * a0 SMC Function ID, OPTEE_SMC_VM_DESTROYED + * a1 Hypervisor Client ID of virtual machine being shut down + * a2-6 Not used + * a7 Hypervisor Client ID register. Must be 0, because only hypervisor + * can issue this call + * + * Normal return register usage: + * a0 OPTEE_SMC_RETURN_OK + * a1-7 Preserved + * + */ + +#define OPTEE_SMC_FUNCID_VM_DESTROYED 14 +#define OPTEE_SMC_VM_DESTROYED \ + OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_VM_DESTROYED) + /* * Resume from RPC (for example after processing a foreign interrupt) * From patchwork Tue Apr 1 17:05:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035198 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (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 71F1A21324D for ; Tue, 1 Apr 2025 17:06:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527191; cv=none; b=VbBor9zOdzESHwMKQjDpBGYiJjLWGIhY/aHCdgcU1yIr+FrsOny1mtqd2sGsg/9BfKAIICTPX4ol3AHLI/wG6YLKUT6SVSQ7HAFAjhUN9KQvxf4RbckYG0SFy/XUeIIHxAE3e096Gwni8KLVd97kMX9H49cc+76dIxNWWv8WGFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527191; c=relaxed/simple; bh=6ty0WWd2Pw+Wx561vA38ol8lBWD4y02HW2GpbWTHBjY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sm14HOh+A+43NsS5AKCSk7xd/7NWwXulEUjXtTVWMFUdAJIl50fQ6TV0WJ7jd98xwPavZQDJ2ACrnotZV4ZNRFB+lu4DdBEnHy57gw80YHuF3auVXdZ6n21K3yjp2pCHjkG2QHphqKuZvtS0+8eTVcR3VnD/nW1TlgKTdok2Dd8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RZE4Rf+y; arc=none smtp.client-ip=209.85.214.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RZE4Rf+y" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-22438c356c8so113838025ad.1 for ; Tue, 01 Apr 2025 10:06:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527188; x=1744131988; 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=PviuPMUBB5gUCbY1XSxJHud91qexychvybubXEpA0/g=; b=RZE4Rf+yoISJgoB2jiZuw1tRM07DEXp1YEZ5ZLPJvKQND4y9Y816scHb7VKmeGcMo7 4g5BlqC2SkcvHT4yd6SAj2Y0k3qQqJJI7OqbY4yk9QaaAKw1f3N37CJapOKG9qhqxQCx 3rwRsDCiMKnh1Gz/4DQ24fYvppw/P93gzFMBxi3BbZziU+lJ2SNVQT5mkL6veG4WHb5W W2DcskTedgOROYJULCwfvyEuxL9AhqlSh3IdtjIc2dS9Uq8VjcfVhvpAr7c0tYvAe9jf yfabMWZrFrFWSLHi+veHjK96j3wtHRQuF6aMlpoF6ByG8IF7zJ25LvuS0DomoajL3INU q68g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527188; x=1744131988; 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=PviuPMUBB5gUCbY1XSxJHud91qexychvybubXEpA0/g=; b=ceSpv7UoAoPKDkbKHtfFvtqUSvwX1fxGUIsPQlR1UXvhiVhkYgl4o8BvuI8FMs/U5n J5hAIyMvesi8u3VV/hnHwel/mXaE3cBY5jrLrM9gpKXNN+C1sp90jzxvTm2XOH6wIA4F Iv5/eFuUFONhfl9rdVj35MYjDfGFCIPmuwlD5f875tKRtUF3eiL+n0NAWsLXmgk2+lvd R7wxLl7xRKUwGqbuC7QIfKjUDExpzGpWmhZFxu0WLddofdcqFTXxyCArfT2Wdw9Hp2Kt lrsYCrGfiZsxrhdsLcsQXgD/QDg0tR0GeIiKR0llNTvWsxeIQin43OB1uupdjJRYskYN 7bhg== X-Forwarded-Encrypted: i=1; AJvYcCXMNQ8NMC97xmiGR1A1Hf8o+j4XK6v4CxyLpZnchfiUAk2z7quyAHCutN/0nYJusv+RVYA=@vger.kernel.org X-Gm-Message-State: AOJu0YwGBsqaZJzmHcR0XzlyxF1AGX/LHRczlMAiBPp/EJnk1H//0kVE N2C8R1L8lNGnJU9Q37HIu+ARa4aoA04ofcbHRAPCTWdohU7XrenI X-Gm-Gg: ASbGncsY3E3NIg8RBDr1zkRvKC3/2iIi5geJUZDo5YfHXDc0m9x6cAzELcIGJbAVWQq /o8jCpvnzJ414yvUkZ60S+UbRb5DB7QJu6j1W2nfsGccbSFujxgOg4Czo+Ey3BnAMYrUMZl0ybS pbMCbio6hpqkys8WZseBwS1BogM2+B4/R+UsQke9FmGp95np0MG1IHvM9m7iH1POj1QdRNS55T0 T70QVuaGTxE64lzi76BMtaDTb5eLEPX/YAhJbvWZUPH1wq7TPzisbvJje7jaMx/1m593S5LC8BN vPk556sXvqHpSbLHP2nanh6FgavIHLYwKzBzLfnI X-Google-Smtp-Source: AGHT+IHCFOZ+4PxxmyIkwsRuIAvlTAuI08a815FrRNBthZd1JhBwwoyi2Z7w+ed2Wyrldvdi8QaisA== X-Received: by 2002:a05:6a00:1412:b0:736:3fa8:cf7b with SMTP id d2e1a72fcca58-739803bc866mr17336367b3a.13.1743527187233; Tue, 01 Apr 2025 10:06:27 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.06.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:06:26 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 6/7] tee: optee: Add OP-TEE Mediator Date: Tue, 1 Apr 2025 22:35:26 +0530 Message-ID: <20250401170527.344092-7-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The OP-TEE mediator is a software entity resposible for bridging the gap between a KVM guest and OP-TEE in the secure world. The guest's OP-TEE driver issues an SMC instruction after populating its CPU registers with appropriate arguments. This SMC is trapped by the hypervisor and control is passed to the OP-TEE mediator with the vCPU state. The mediator is resposible for manipulating the vCPU state accordingly and keeping track of active transactions between the guest and the TEE. This implementation adds event handlers that gets hooked to the TEE Mediator layer and are called when events such as guest creation/destruction, mediator status check and guest SMC trap happen. Important routines implemented: - optee_mediator_{create|destroy}_vm(): Sends an SMC to OP-TEE notifying KVM guest creation or destruction. - optee_mediator_{create|destroy}_host(): Sends an SMC to OP-TEE notifying host OP-TEE driver initalization/release (OP-TEE treats all NS-EL1 entities as a guest, and is not aware of host privilege). - optee_mediator_forward_smc(): Changes vCPU register state as required by OP-TEE and keeps track of standard calls and memory shared by guest. The OP-TEE mediator is implemented in such a way that, the guest/VMM can remain unmodified. The guest interacts with OP-TEE just as it would if it was running natively. Signed-off-by: Yuvraj Sakshith --- drivers/tee/optee/Kconfig | 7 + drivers/tee/optee/Makefile | 1 + drivers/tee/optee/optee_mediator.c | 1319 ++++++++++++++++++++++++++++ drivers/tee/optee/optee_mediator.h | 103 +++ 4 files changed, 1430 insertions(+) create mode 100644 drivers/tee/optee/optee_mediator.c create mode 100644 drivers/tee/optee/optee_mediator.h diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig index 7bb7990d0b07..ef41d6d1793e 100644 --- a/drivers/tee/optee/Kconfig +++ b/drivers/tee/optee/Kconfig @@ -25,3 +25,10 @@ config OPTEE_INSECURE_LOAD_IMAGE Additional documentation on kernel security risks are at Documentation/tee/op-tee.rst. + +config OPTEE_MEDIATOR + bool "OP-TEE Mediator support" + depends on TEE_MEDIATOR && OPTEE && ARM64 && KVM + help + This enables a KVM guest equipped with an OP-TEE driver to interact with OP-TEE + in the secure world. diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index a6eff388d300..4a777940e0df 100644 --- a/drivers/tee/optee/Makefile +++ b/drivers/tee/optee/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_OPTEE_MEDIATOR) += optee_mediator.o obj-$(CONFIG_OPTEE) += optee.o optee-objs += core.o optee-objs += call.o diff --git a/drivers/tee/optee/optee_mediator.c b/drivers/tee/optee/optee_mediator.c new file mode 100644 index 000000000000..d164eae570a9 --- /dev/null +++ b/drivers/tee/optee/optee_mediator.c @@ -0,0 +1,1319 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * OP-TEE Mediator for the Linux Kernel + * + * This module enables a KVM guest to interact with OP-TEE + * in the secure world by hooking event handlers with + * the TEE Mediator layer. + * + * Author: + * Yuvraj Sakshith + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include "optee_mediator.h" +#include "optee_smc.h" +#include "optee_msg.h" +#include "optee_private.h" +#include "optee_rpc_cmd.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define OPTEE_KNOWN_NSEC_CAPS OPTEE_SMC_NSEC_CAP_UNIPROCESSOR +#define OPTEE_KNOWN_SEC_CAPS (OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM | \ + OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM | \ + OPTEE_SMC_SEC_CAP_DYNAMIC_SHM | \ + OPTEE_SMC_SEC_CAP_MEMREF_NULL) + +static struct optee_mediator *mediator; +static spinlock_t mediator_lock; +static u32 optee_thread_limit; + +static void copy_regs_from_vcpu(struct kvm_vcpu *vcpu, struct guest_regs *regs) +{ + if (!vcpu || !regs) + return; + + regs->a0 = vcpu_get_reg(vcpu, 0); + regs->a1 = vcpu_get_reg(vcpu, 1); + regs->a2 = vcpu_get_reg(vcpu, 2); + regs->a3 = vcpu_get_reg(vcpu, 3); + regs->a4 = vcpu_get_reg(vcpu, 4); + regs->a5 = vcpu_get_reg(vcpu, 5); + regs->a6 = vcpu_get_reg(vcpu, 6); + regs->a7 = vcpu_get_reg(vcpu, 7); +} + +static void copy_smccc_res_to_vcpu(struct kvm_vcpu *vcpu, struct arm_smccc_res *res) +{ + + vcpu_set_reg(vcpu, 0, res->a0); + vcpu_set_reg(vcpu, 1, res->a1); + vcpu_set_reg(vcpu, 2, res->a2); + vcpu_set_reg(vcpu, 3, res->a3); +} + +static void optee_mediator_smccc_smc(struct guest_regs *regs, struct arm_smccc_res *res) +{ + + arm_smccc_smc(regs->a0, regs->a1, regs->a2, regs->a3, + regs->a4, regs->a5, regs->a6, regs->a7, res); +} + +static int optee_mediator_pin_guest_page(struct kvm *kvm, gpa_t gpa) +{ + + int ret = 0; + + gfn_t gfn = gpa >> PAGE_SHIFT; + + struct kvm_memory_slot *memslot = gfn_to_memslot(kvm, gfn); + + if (!memslot) { + ret = -EAGAIN; + goto out; + } + + struct page *pages; + + if (!pin_user_pages_unlocked(memslot->userspace_addr, + 1, + &pages, + FOLL_LONGTERM)) { + ret = -EAGAIN; + goto out; + } + +out: + return ret; +} + +static void optee_mediator_unpin_guest_page(struct kvm *kvm, gpa_t gpa) +{ + + gfn_t gfn = gpa >> PAGE_SHIFT; + + struct page *page = gfn_to_page(kvm, gfn); + + if (!page) + goto out; + + unpin_user_page(page); + +out: + return; +} + +static struct optee_vm_context *optee_mediator_find_vm_context(struct kvm *kvm) +{ + + struct optee_vm_context *vm_context, *tmp; + int found = 0; + + if (!kvm) + goto out; + + mutex_lock(&mediator->vm_list_lock); + + list_for_each_entry_safe(vm_context, tmp, &mediator->vm_list, list) { + if (vm_context->kvm == kvm) { + found = 1; + break; + } + } + + mutex_unlock(&mediator->vm_list_lock); + +out: + if (!found) + return NULL; + + return vm_context; +} + +static void optee_mediator_add_vm_context(struct optee_vm_context *vm_context) +{ + + if (!vm_context) + goto out; + + mutex_lock(&mediator->vm_list_lock); + list_add_tail(&vm_context->list, &mediator->vm_list); + mutex_unlock(&mediator->vm_list_lock); + +out: + return; +} + +static void optee_mediator_delete_vm_context(struct optee_vm_context *vm_context) +{ + + struct optee_vm_context *cursor_vm_context, *tmp; + struct optee_std_call *call, *tmp_call; + struct optee_shm_rpc *shm_rpc, *tmp_shm_rpc; + struct optee_shm_buf *shm_buf, *tmp_shm_buf; + + if (!vm_context) + goto out; + + mutex_lock(&vm_context->lock); + + list_for_each_entry_safe(call, tmp_call, &vm_context->std_call_list, list) { + if (call) { + optee_mediator_unpin_guest_page(vm_context->kvm, (gpa_t) call->guest_arg_gpa); + + list_del(&call->list); + kfree(call->shadow_arg); + kfree(call); + } + } + + + list_for_each_entry_safe(shm_buf, tmp_shm_buf, &vm_context->shm_buf_list, list) { + if (shm_buf) { + + for (int j = 0; j < shm_buf->num_pages; j++) + optee_mediator_unpin_guest_page(vm_context->kvm, (gpa_t) shm_buf->guest_page_list[j]); + + list_del(&shm_buf->list); + kfree(shm_buf->shadow_buffer_list); + kfree(shm_buf->guest_page_list); + kfree(shm_buf); + } + } + + list_for_each_entry_safe(shm_rpc, tmp_shm_rpc, &vm_context->shm_rpc_list, list) { + if (shm_rpc) { + optee_mediator_unpin_guest_page(vm_context->kvm, (gpa_t) shm_rpc->rpc_arg_gpa); + list_del(&shm_rpc->list); + kfree(shm_rpc); + } + } + + + mutex_unlock(&vm_context->lock); + + mutex_lock(&mediator->vm_list_lock); + + list_for_each_entry_safe(cursor_vm_context, tmp, &mediator->vm_list, list) { + if (cursor_vm_context == vm_context) { + list_del(&cursor_vm_context->list); + kfree(cursor_vm_context); + + goto out_unlock; + } + } + +out_unlock: + mutex_unlock(&mediator->vm_list_lock); +out: + return; +} + +static struct optee_std_call *optee_mediator_new_std_call(void) +{ + struct optee_std_call *call = kzalloc(sizeof(*call), GFP_KERNEL); + + if (!call) + return NULL; + + return call; +} + +static void optee_mediator_del_std_call(struct optee_std_call *call) +{ + if (!call) + return; + + kfree(call); +} + +static void optee_mediator_enlist_std_call(struct optee_vm_context *vm_context, struct optee_std_call *call) +{ + mutex_lock(&vm_context->lock); + list_add_tail(&call->list, &vm_context->std_call_list); + vm_context->call_count++; + mutex_unlock(&vm_context->lock); + + optee_mediator_pin_guest_page(vm_context->kvm, (gpa_t) call->guest_arg_gpa); +} + +static void optee_mediator_delist_std_call(struct optee_vm_context *vm_context, struct optee_std_call *call) +{ + mutex_lock(&vm_context->lock); + list_del(&call->list); + vm_context->call_count--; + mutex_unlock(&vm_context->lock); + + optee_mediator_unpin_guest_page(vm_context->kvm, (gpa_t) call->guest_arg_gpa); +} + +static struct optee_std_call *optee_mediator_find_std_call(struct optee_vm_context *vm_context, u32 thread_id) +{ + struct optee_std_call *call; + int found = 0; + + mutex_lock(&vm_context->lock); + list_for_each_entry(call, &vm_context->std_call_list, list) { + if (call->thread_id == thread_id) { + found = 1; + break; + } + } + mutex_unlock(&vm_context->lock); + + if (!found) + return NULL; + + return call; +} + +static struct optee_shm_buf *optee_mediator_new_shm_buf(void) +{ + struct optee_shm_buf *shm_buf = kzalloc(sizeof(*shm_buf), GFP_KERNEL); + + return shm_buf; +} + +static void optee_mediator_enlist_shm_buf(struct optee_vm_context *vm_context, struct optee_shm_buf *shm_buf) +{ + mutex_lock(&vm_context->lock); + list_add_tail(&shm_buf->list, &vm_context->shm_buf_list); + vm_context->shm_buf_page_count += shm_buf->num_pages; + mutex_unlock(&vm_context->lock); + + for (int i = 0; i < shm_buf->num_pages; i++) + optee_mediator_pin_guest_page(vm_context->kvm, (gpa_t) shm_buf->guest_page_list[i]); +} + +static void optee_mediator_free_shm_buf(struct optee_vm_context *vm_context, u64 cookie) +{ + + struct optee_shm_buf *shm_buf, *tmp; + + mutex_lock(&vm_context->lock); + list_for_each_entry_safe(shm_buf, tmp, &vm_context->shm_buf_list, list) { + if (shm_buf->cookie == cookie) { + for (int buf = 0; buf < shm_buf->num_buffers; buf++) + kfree(shm_buf->shadow_buffer_list[buf]); + + for (int buf = 0; buf < shm_buf->num_pages; buf++) + optee_mediator_unpin_guest_page(vm_context->kvm, (gpa_t) shm_buf->guest_page_list[buf]); + + vm_context->shm_buf_page_count -= shm_buf->num_pages; + + list_del(&shm_buf->list); + + kfree(shm_buf->shadow_buffer_list); + kfree(shm_buf->guest_page_list); + kfree(shm_buf); + break; + } + } + mutex_unlock(&vm_context->lock); +} + +static void optee_mediator_free_all_buffers(struct optee_vm_context *vm_context, struct optee_std_call *call) +{ + + for (int i = 0; i < call->shadow_arg->num_params; i++) { + u64 attr = call->shadow_arg->params[i].attr; + + switch (attr & OPTEE_MSG_ATTR_TYPE_MASK) { + + case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: + optee_mediator_free_shm_buf(vm_context, call->shadow_arg->params[i].u.tmem.shm_ref); + break; + default: + break; + + } + } +} + +static void optee_mediator_free_shm_buf_page_list(struct optee_vm_context *vm_context, u64 cookie) +{ + mutex_lock(&vm_context->lock); + + struct optee_shm_buf *shm_buf; + + list_for_each_entry(shm_buf, &vm_context->shm_buf_list, list) { + if (shm_buf->cookie == cookie) { + for (int entry = 0; entry < shm_buf->num_buffers; entry++) { + kfree(shm_buf->shadow_buffer_list[entry]); + shm_buf->shadow_buffer_list[entry] = NULL; + } + break; + } + } + + mutex_unlock(&vm_context->lock); +} + +static struct optee_shm_rpc *optee_mediator_new_shm_rpc(void) +{ + struct optee_shm_rpc *shm_rpc = kzalloc(sizeof(*shm_rpc), GFP_KERNEL); + + return shm_rpc; +} + +static void optee_mediator_enlist_shm_rpc(struct optee_vm_context *vm_context, struct optee_shm_rpc *shm_rpc) +{ + mutex_lock(&vm_context->lock); + list_add_tail(&shm_rpc->list, &vm_context->shm_rpc_list); + mutex_unlock(&vm_context->lock); + + optee_mediator_pin_guest_page(vm_context->kvm, (gpa_t) shm_rpc->rpc_arg_gpa); +} + +static struct optee_shm_rpc *optee_mediator_find_shm_rpc(struct optee_vm_context *vm_context, u64 cookie) +{ + + struct optee_shm_rpc *shm_rpc; + int found = 0; + + mutex_lock(&vm_context->lock); + list_for_each_entry(shm_rpc, &vm_context->shm_rpc_list, list) { + if (shm_rpc->cookie == cookie) { + found = 1; + break; + } + } + mutex_unlock(&vm_context->lock); + + if (!found) + return NULL; + + return shm_rpc; +} + +static void optee_mediator_free_shm_rpc(struct optee_vm_context *vm_context, u64 cookie) +{ + + struct optee_shm_rpc *shm_rpc, *tmp; + + mutex_lock(&vm_context->lock); + + list_for_each_entry_safe(shm_rpc, tmp, &vm_context->shm_rpc_list, list) { + if (shm_rpc->cookie == cookie) { + + optee_mediator_unpin_guest_page(vm_context->kvm, (gpa_t) shm_rpc->rpc_arg_gpa); + + list_del(&shm_rpc->list); + kfree(shm_rpc); + break; + } + } + + mutex_unlock(&vm_context->lock); +} + +static hva_t optee_mediator_gpa_to_hva(struct kvm *kvm, gpa_t gpa) +{ + gfn_t gfn = gpa >> PAGE_SHIFT; + + struct page *page = gfn_to_page(kvm, gfn); + + if (!page) + return 0; + + hva_t hva = (hva_t) page_to_virt(page); + return hva; +} + +static hva_t optee_mediator_gpa_to_phys(struct kvm *kvm, gpa_t gpa) +{ + gfn_t gfn = gpa >> PAGE_SHIFT; + + struct page *page = gfn_to_page(kvm, gfn); + + if (!page) + return 0; + + phys_addr_t phys = (phys_addr_t) page_to_phys(page); + return phys; +} + + +static int optee_mediator_shadow_msg_arg(struct kvm *kvm, struct optee_std_call *call) +{ + + int ret = 0; + + call->shadow_arg = kzalloc(OPTEE_MSG_NONCONTIG_PAGE_SIZE, GFP_KERNEL); + + if (!call->shadow_arg) { + ret = OPTEE_SMC_RETURN_ENOMEM; + goto out; + } + + ret = kvm_read_guest(kvm, (gpa_t)call->guest_arg_gpa, (void *) call->shadow_arg, OPTEE_MSG_NONCONTIG_PAGE_SIZE); + +out: + + return ret; +} + +static void optee_mediator_shadow_arg_sync(struct optee_std_call *call) +{ + + + + call->guest_arg_hva->ret = call->shadow_arg->ret; + call->guest_arg_hva->ret_origin = call->shadow_arg->ret_origin; + call->guest_arg_hva->session = call->shadow_arg->session; + + for (int i = 0; i < call->shadow_arg->num_params; i++) { + u32 attr = call->shadow_arg->params[i].attr; + + switch (attr & OPTEE_MSG_ATTR_TYPE_MASK) { + + case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: + call->guest_arg_hva->params[i].u.tmem.size = + call->shadow_arg->params[i].u.tmem.size; + continue; + case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: + case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: + call->guest_arg_hva->params[i].u.rmem.size = + call->shadow_arg->params[i].u.rmem.size; + continue; + case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT: + case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT: + call->guest_arg_hva->params[i].u.value.a = + call->shadow_arg->params[i].u.value.a; + call->guest_arg_hva->params[i].u.value.b = + call->shadow_arg->params[i].u.value.b; + call->guest_arg_hva->params[i].u.value.c = + call->shadow_arg->params[i].u.value.c; + continue; + case OPTEE_MSG_ATTR_TYPE_NONE: + case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: + continue; + + } + } +} + +static int optee_mediator_resolve_noncontig(struct optee_vm_context *vm_context, struct optee_msg_param *param) +{ + + int ret = 0; + + if (!param->u.tmem.buf_ptr) + goto out; + + struct kvm *kvm = vm_context->kvm; + + struct page_data *guest_buffer_gpa = (struct page_data *) param->u.tmem.buf_ptr; + struct page_data *guest_buffer_hva = (struct page_data *) optee_mediator_gpa_to_hva(kvm, (gpa_t) guest_buffer_gpa); + + if (!guest_buffer_hva) { + ret = -EINVAL; + goto out; + } + + u64 guest_buffer_size = param->u.tmem.size; + u64 guest_buffer_offset = param->u.tmem.buf_ptr & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1); + u64 num_entries = DIV_ROUND_UP(guest_buffer_size + guest_buffer_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE); + + mutex_lock(&vm_context->lock); + if (vm_context->shm_buf_page_count + num_entries > OPTEE_MAX_SHM_BUFFER_PAGES) { + ret = -ENOMEM; + mutex_unlock(&vm_context->lock); + goto out; + } + mutex_unlock(&vm_context->lock); + + u64 num_buffers = DIV_ROUND_UP(num_entries, OPTEE_BUFFER_ENTRIES); + + struct page_data **shadow_buffer_list = kzalloc(num_buffers * sizeof(struct page_data *), GFP_KERNEL); + + if (!shadow_buffer_list) { + ret = -ENOMEM; + goto out; + } + + gpa_t *guest_page_list = kzalloc(num_entries * sizeof(gpa_t), GFP_KERNEL); + + if (!guest_page_list) { + ret = -ENOMEM; + goto out_free_shadow_buffer_list; + } + + u32 guest_page_num = 0; + + for (int i = 0; i < num_buffers; i++) { + struct page_data *shadow_buffer = kzalloc(sizeof(struct page_data), GFP_KERNEL); + + if (!shadow_buffer) { + ret = -ENOMEM; + goto out_free_guest_page_list; + } + + for (int entry = 0; entry < MIN(num_entries, OPTEE_BUFFER_ENTRIES); entry++) { + gpa_t buffer_entry_gpa = guest_buffer_hva->pages_list[entry]; + + guest_page_list[guest_page_num++] = buffer_entry_gpa; + + phys_addr_t buffer_entry_phys = optee_mediator_gpa_to_phys(kvm, buffer_entry_gpa); + + shadow_buffer->pages_list[entry] = (u64) buffer_entry_phys; + } + + shadow_buffer_list[i] = shadow_buffer; + if (i > 0) + shadow_buffer_list[i-1]->next_page_data = (u64) virt_to_phys(shadow_buffer_list[i]); + + guest_buffer_hva = (struct page_data *) optee_mediator_gpa_to_hva(kvm, (gpa_t) guest_buffer_hva->next_page_data); + if (!guest_buffer_hva && (i != num_buffers - 1)) { + ret = -EINVAL; + goto out_free_guest_page_list; + } + + } + + struct optee_shm_buf *shm_buf = optee_mediator_new_shm_buf(); + + if (!shm_buf) { + ret = -ENOMEM; + goto out_free_guest_page_list; + } + + shm_buf->shadow_buffer_list = shadow_buffer_list; + shm_buf->num_buffers = num_buffers; + shm_buf->guest_page_list = guest_page_list; + shm_buf->num_pages = num_entries; + shm_buf->cookie = param->u.tmem.shm_ref; + + optee_mediator_enlist_shm_buf(vm_context, shm_buf); + + param->u.tmem.buf_ptr = (u64) virt_to_phys(shadow_buffer_list[0]) | guest_buffer_offset; + + return ret; + +out_free_guest_page_list: + kfree(guest_page_list); +out_free_shadow_buffer_list: + for (int i = 0; i < num_buffers; i++) + kfree(shadow_buffer_list[i]); + + kfree(shadow_buffer_list); +out: + return ret; +} + +static int optee_mediator_resolve_params(struct optee_vm_context *vm_context, struct optee_std_call *call) +{ + + int ret = 0; + + for (int i = 0; i < call->shadow_arg->num_params; i++) { + u32 attr = call->shadow_arg->params[i].attr; + + switch (attr & OPTEE_MSG_ATTR_TYPE_MASK) { + + case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: + if (attr & OPTEE_MSG_ATTR_NONCONTIG) { + ret = optee_mediator_resolve_noncontig(vm_context, call->shadow_arg->params + i); + + if (ret == -ENOMEM) { + call->shadow_arg->ret_origin = TEEC_ORIGIN_COMMS; + call->shadow_arg->ret = TEEC_ERROR_OUT_OF_MEMORY; + goto out; + } + if (ret == -EINVAL) { + call->shadow_arg->ret_origin = TEEC_ORIGIN_COMMS; + call->shadow_arg->ret = TEEC_ERROR_BAD_PARAMETERS; + goto out; + } + } else { + if (call->shadow_arg->params[i].u.tmem.buf_ptr) { + call->shadow_arg->ret_origin = TEEC_ORIGIN_COMMS; + call->shadow_arg->ret = TEEC_ERROR_BAD_PARAMETERS; + ret = -EINVAL; + goto out; + } + } + default: + continue; + + } + } +out: + + return ret; +} + + +static int optee_mediator_new_vmid(u64 *vmid_out) +{ + + int ret = 0; + + u64 vmid = atomic_read(&mediator->next_vmid); + + atomic_inc(&mediator->next_vmid); + + *vmid_out = vmid; + + return ret; +} + +static int optee_mediator_create_host(void) +{ + + int ret = 0; + + struct arm_smccc_res res; + + arm_smccc_smc(OPTEE_SMC_VM_CREATED, OPTEE_HOST_VMID, 0, 0, 0, 0, 0, 0, &res); + + if (res.a0 == OPTEE_SMC_RETURN_ENOTAVAIL) { + ret = -EBUSY; + goto out; + } + +out: + return ret; +} + +static int optee_mediator_destroy_host(void) +{ + + int ret = 0; + + struct arm_smccc_res res; + + arm_smccc_smc(OPTEE_SMC_VM_DESTROYED, OPTEE_HOST_VMID, 0, 0, 0, 0, 0, 0, &res); + + return ret; +} + +static int optee_mediator_create_vm(struct kvm *kvm) +{ + + int ret = 0; + struct arm_smccc_res res; + + if (!kvm) { + ret = -EINVAL; + goto out; + } + + struct optee_vm_context *vm_context = kzalloc(sizeof(*vm_context), GFP_KERNEL); + + if (!vm_context) { + ret = -ENOMEM; + goto out; + } + + ret = optee_mediator_new_vmid(&vm_context->vmid); + if (ret < 0) + goto out_context_free; + + INIT_LIST_HEAD(&vm_context->std_call_list); + INIT_LIST_HEAD(&vm_context->shm_buf_list); + INIT_LIST_HEAD(&vm_context->shm_rpc_list); + + mutex_init(&vm_context->lock); + + vm_context->kvm = kvm; + + arm_smccc_smc(OPTEE_SMC_VM_CREATED, vm_context->vmid, 0, 0, 0, 0, 0, 0, &res); + + if (res.a0 == OPTEE_SMC_RETURN_ENOTAVAIL) { + ret = -EBUSY; + goto out_context_free; + } + + optee_mediator_add_vm_context(vm_context); + +out: + return ret; +out_context_free: + kfree(vm_context); + return ret; +} + +static int optee_mediator_destroy_vm(struct kvm *kvm) +{ + + int ret = 0; + struct arm_smccc_res res; + + if (!kvm) { + ret = -EINVAL; + goto out; + } + + struct optee_vm_context *vm_context = optee_mediator_find_vm_context(kvm); + + if (!vm_context) { + ret = -EINVAL; + goto out; + } + + arm_smccc_smc(OPTEE_SMC_VM_DESTROYED, vm_context->vmid, 0, 0, 0, 0, 0, 0, &res); + + optee_mediator_delete_vm_context(vm_context); + +out: + return ret; +} + +static void optee_mediator_handle_fast_call(struct kvm_vcpu *vcpu, struct guest_regs *regs) +{ + + struct arm_smccc_res res; + struct kvm *kvm = vcpu->kvm; + + struct optee_vm_context *vm_context = optee_mediator_find_vm_context(kvm); + + if (!vm_context) { + res.a0 = OPTEE_SMC_RETURN_ENOTAVAIL; + goto out; + } + + regs->a7 = vm_context->vmid; + + optee_mediator_smccc_smc(regs, &res); + + switch (ARM_SMCCC_FUNC_NUM(regs->a0)) { + + case OPTEE_SMC_FUNCID_GET_THREAD_COUNT: + optee_thread_limit = 0; + if (res.a0 != OPTEE_SMC_RETURN_UNKNOWN_FUNCTION) + optee_thread_limit = res.a1; + break; + + case OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE: + if (res.a0 == OPTEE_SMC_RETURN_OK) { + u64 cookie = (u64) reg_pair_to_ptr(res.a1, res.a2); + + optee_mediator_free_shm_buf(vm_context, cookie); + } + break; + + default: + break; + + } + + copy_smccc_res_to_vcpu(vcpu, &res); +out: + return; +} + +static int optee_mediator_handle_rpc_return(struct optee_vm_context *vm_context, + struct optee_std_call *call, + struct guest_regs *regs, + struct arm_smccc_res *res) +{ + + int ret = 0; + + call->rpc_state.a0 = res->a0; + call->rpc_state.a1 = res->a1; + call->rpc_state.a2 = res->a2; + call->rpc_state.a3 = res->a3; + + call->rpc_func = OPTEE_SMC_RETURN_GET_RPC_FUNC(res->a0); + call->thread_id = res->a3; + + if (call->rpc_func == OPTEE_SMC_RPC_FUNC_FREE) { + u64 cookie = (u64) reg_pair_to_ptr(res->a1, res->a2); + + optee_mediator_free_shm_rpc(vm_context, cookie); + } + + if (call->rpc_func == OPTEE_SMC_RPC_FUNC_CMD) { + u64 cookie = (u64) reg_pair_to_ptr(res->a1, res->a2); + struct optee_shm_rpc *shm_rpc = optee_mediator_find_shm_rpc(vm_context, cookie); + + if (!shm_rpc) { + ret = -ERESTART; + goto out; + } + if (shm_rpc->rpc_arg_hva->cmd == OPTEE_RPC_CMD_SHM_FREE) + optee_mediator_free_shm_buf(vm_context, shm_rpc->rpc_arg_hva->params[0].u.value.b); + } + +out: + return ret; +} + +static void optee_mediator_do_call_with_arg(struct optee_vm_context *vm_context, + struct optee_std_call *call, + struct guest_regs *regs, + struct arm_smccc_res *res) +{ + + regs->a7 = vm_context->vmid; + + optee_mediator_smccc_smc(regs, res); + + if (OPTEE_SMC_RETURN_IS_RPC(res->a0)) { + while (optee_mediator_handle_rpc_return(vm_context, call, regs, res) == -ERESTART) { + optee_mediator_smccc_smc(regs, res); + if (!OPTEE_SMC_RETURN_IS_RPC(res->a0)) + break; + } + } else { + + u32 cmd = call->shadow_arg->cmd; + u32 call_ret = call->shadow_arg->ret; + + switch (cmd) { + + case OPTEE_MSG_CMD_REGISTER_SHM: + if (call_ret == 0) + optee_mediator_free_shm_buf_page_list(vm_context, (u64) call->shadow_arg->params[0].u.tmem.shm_ref); + else + optee_mediator_free_shm_buf(vm_context, (u64) call->shadow_arg->params[0].u.tmem.shm_ref); + + break; + + case OPTEE_MSG_CMD_UNREGISTER_SHM: + if (call_ret == 0) + optee_mediator_free_shm_buf(vm_context, (u64) call->shadow_arg->params[0].u.rmem.shm_ref); + break; + + default: + optee_mediator_free_all_buffers(vm_context, call); + break; + + } + } +} + +static void optee_mediator_handle_std_call(struct kvm_vcpu *vcpu, struct guest_regs *regs) +{ + + struct arm_smccc_res res; + struct kvm *kvm = vcpu->kvm; + int ret; + + struct optee_vm_context *vm_context = optee_mediator_find_vm_context(kvm); + + if (!vm_context) { + res.a0 = OPTEE_SMC_RETURN_ENOTAVAIL; + goto out_copy; + } + + struct optee_std_call *call = optee_mediator_new_std_call(); + + if (!call) { + res.a0 = OPTEE_SMC_RETURN_ENOMEM; + goto out_copy; + } + + call->thread_id = 0xffffffff; + call->guest_arg_gpa = (struct optee_msg_arg *) reg_pair_to_ptr(regs->a1, regs->a2); + call->guest_arg_hva = (struct optee_msg_arg *) optee_mediator_gpa_to_hva(kvm, (gpa_t) call->guest_arg_gpa); + + if (!call->guest_arg_hva) { + res.a0 = OPTEE_SMC_RETURN_EBADADDR; + goto out_call_free; + } + + mutex_lock(&vm_context->lock); + + if (vm_context->call_count >= optee_thread_limit) { + res.a0 = OPTEE_SMC_RETURN_ETHREAD_LIMIT; + mutex_unlock(&vm_context->lock); + goto out_call_free; + } + + mutex_unlock(&vm_context->lock); + + INIT_LIST_HEAD(&call->list); + + ret = optee_mediator_shadow_msg_arg(kvm, call); + if (ret) { + res.a0 = OPTEE_SMC_RETURN_EBADADDR; + goto out_call_free; + } + + optee_mediator_enlist_std_call(vm_context, call); + + if (OPTEE_MSG_GET_ARG_SIZE(call->shadow_arg->num_params) > OPTEE_MSG_NONCONTIG_PAGE_SIZE) { + call->shadow_arg->ret = TEEC_ERROR_BAD_PARAMETERS; + call->shadow_arg->ret_origin = TEEC_ORIGIN_COMMS; + call->shadow_arg->num_params = 0; + + optee_mediator_shadow_arg_sync(call); + goto out_delist_std_call; + } + + + u32 cmd = call->shadow_arg->cmd; + + + switch (cmd) { + + case OPTEE_MSG_CMD_OPEN_SESSION: + case OPTEE_MSG_CMD_CLOSE_SESSION: + case OPTEE_MSG_CMD_INVOKE_COMMAND: + case OPTEE_MSG_CMD_CANCEL: + case OPTEE_MSG_CMD_REGISTER_SHM: + case OPTEE_MSG_CMD_UNREGISTER_SHM: + ret = optee_mediator_resolve_params(vm_context, call); + if (ret) { + res.a0 = OPTEE_SMC_RETURN_OK; + optee_mediator_shadow_arg_sync(call); + goto out_delist_std_call; + } + break; + default: + res.a0 = OPTEE_SMC_RETURN_EBADCMD; + goto out_delist_std_call; + } + + reg_pair_from_64(®s->a1, ®s->a2, (u64) virt_to_phys(call->shadow_arg)); + regs->a3 = OPTEE_SMC_SHM_CACHED; + + optee_mediator_do_call_with_arg(vm_context, call, regs, &res); + optee_mediator_shadow_arg_sync(call); + + if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) + goto out_copy; + +out_delist_std_call: + optee_mediator_delist_std_call(vm_context, call); +out_call_free: + optee_mediator_del_std_call(call); +out_copy: + copy_smccc_res_to_vcpu(vcpu, &res); +} + +static void optee_mediator_handle_rpc_alloc(struct optee_vm_context *vm_context, struct guest_regs *regs) +{ + + u64 ptr = (u64) reg_pair_to_ptr(regs->a1, regs->a2); + u64 cookie = (u64) reg_pair_to_ptr(regs->a4, regs->a5); + + struct optee_shm_rpc *shm_rpc = optee_mediator_new_shm_rpc(); + + if (!shm_rpc) + goto out_err; + + struct optee_shm_rpc *temp_shm_rpc = optee_mediator_find_shm_rpc(vm_context, cookie); + + if (temp_shm_rpc) { // guest is trying to reuse cookie + goto out_err; + } + + shm_rpc->rpc_arg_gpa = (struct optee_msg_arg *) ptr; + shm_rpc->rpc_arg_hva = (struct optee_msg_arg *) optee_mediator_gpa_to_hva(vm_context->kvm, (gpa_t) shm_rpc->rpc_arg_gpa); + + if (!shm_rpc->rpc_arg_hva) { + ptr = 0; + goto out_err_free_rpc; + } + + shm_rpc->cookie = cookie; + + optee_mediator_enlist_shm_rpc(vm_context, shm_rpc); + + ptr = optee_mediator_gpa_to_phys(vm_context->kvm, (gpa_t) shm_rpc->rpc_arg_gpa); + + reg_pair_from_64(®s->a1, ®s->a2, ptr); + return; + +out_err_free_rpc: + kfree(shm_rpc); +out_err: + reg_pair_from_64(®s->a1, ®s->a2, 0); +} + +static int optee_mediator_handle_rpc_cmd(struct optee_vm_context *vm_context, struct guest_regs *regs) +{ + int ret = 0; + u64 cookie = (u64) reg_pair_to_ptr(regs->a1, regs->a2); + + struct optee_shm_rpc *shm_rpc = optee_mediator_find_shm_rpc(vm_context, cookie); + + if (!shm_rpc) { + ret = -EINVAL; + goto out; + } + + if (OPTEE_MSG_GET_ARG_SIZE(shm_rpc->rpc_arg_hva->num_params) > OPTEE_MSG_NONCONTIG_PAGE_SIZE) { + shm_rpc->rpc_arg_hva->ret = TEEC_ERROR_BAD_PARAMETERS; + goto out; + } + + switch (shm_rpc->rpc_arg_hva->cmd) { + case OPTEE_RPC_CMD_SHM_ALLOC: + ret = optee_mediator_resolve_noncontig(vm_context, shm_rpc->rpc_arg_hva->params + 0); + break; + + case OPTEE_RPC_CMD_SHM_FREE: + optee_mediator_free_shm_buf(vm_context, shm_rpc->rpc_arg_hva->params[0].u.value.b); + break; + } + +out: + return ret; +} + +static void optee_mediator_handle_rpc_call(struct kvm_vcpu *vcpu, struct guest_regs *regs) +{ + + int ret = 0; + struct arm_smccc_res res; + struct optee_std_call *call; + u32 thread_id = regs->a3; + + struct optee_vm_context *vm_context = optee_mediator_find_vm_context(vcpu->kvm); + + if (!vm_context) { + res.a0 = OPTEE_SMC_RETURN_ENOTAVAIL; + goto out_copy; + } + + call = optee_mediator_find_std_call(vm_context, thread_id); + if (!call) { + res.a0 = OPTEE_SMC_RETURN_ERESUME; + goto out_copy; + } + + + call->thread_id = 0xffffffff; + + switch (call->rpc_func) { + + case OPTEE_SMC_RPC_FUNC_ALLOC: + optee_mediator_handle_rpc_alloc(vm_context, regs); + break; + case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR: + break; + case OPTEE_SMC_RPC_FUNC_CMD: + ret = optee_mediator_handle_rpc_cmd(vm_context, regs); + + if (ret < 0) + goto out; + break; + } + + + + optee_mediator_do_call_with_arg(vm_context, call, regs, &res); + + optee_mediator_shadow_arg_sync(call); + + if (OPTEE_SMC_RETURN_IS_RPC(res.a0) || res.a0 == OPTEE_SMC_RETURN_ERESUME) + goto out_copy; + + optee_mediator_delist_std_call(vm_context, call); + optee_mediator_del_std_call(call); +out_copy: + copy_smccc_res_to_vcpu(vcpu, &res); +out: + return; +} + +static void optee_mediator_handle_exchange_cap(struct kvm_vcpu *vcpu, struct guest_regs *regs) +{ + + struct arm_smccc_res res; + struct kvm *kvm = vcpu->kvm; + + struct optee_vm_context *vm_context = optee_mediator_find_vm_context(kvm); + + if (!vm_context) { + res.a0 = OPTEE_SMC_RETURN_ENOTAVAIL; + goto out_copy; + } + + regs->a1 &= OPTEE_KNOWN_NSEC_CAPS; + regs->a7 = vm_context->vmid; + + optee_mediator_smccc_smc(regs, &res); + if (res.a0 != OPTEE_SMC_RETURN_OK) + goto out_copy; + + res.a1 &= OPTEE_KNOWN_SEC_CAPS; + res.a1 &= ~OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM; + + if (!(res.a1 & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)) { + res.a0 = OPTEE_SMC_RETURN_ENOTAVAIL; + goto out_copy; + } + +out_copy: + copy_smccc_res_to_vcpu(vcpu, &res); +} + +static void optee_mediator_forward_smc(struct kvm_vcpu *vcpu) +{ + + if (!vcpu) + goto out; + + struct guest_regs regs; + + copy_regs_from_vcpu(vcpu, ®s); + + switch (ARM_SMCCC_FUNC_NUM(regs.a0)) { + + case OPTEE_SMC_FUNCID_CALLS_COUNT: + case OPTEE_SMC_FUNCID_CALLS_UID: + case OPTEE_SMC_FUNCID_CALLS_REVISION: + case OPTEE_SMC_FUNCID_GET_OS_UUID: + case OPTEE_SMC_FUNCID_GET_OS_REVISION: + case OPTEE_SMC_FUNCID_GET_THREAD_COUNT: + case OPTEE_SMC_FUNCID_ENABLE_ASYNC_NOTIF: + case OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE: + case OPTEE_SMC_FUNCID_GET_ASYNC_NOTIF_VALUE: + case OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE: + optee_mediator_handle_fast_call(vcpu, ®s); + break; + + case OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES: + optee_mediator_handle_exchange_cap(vcpu, ®s); + break; + + case OPTEE_SMC_FUNCID_CALL_WITH_ARG: + optee_mediator_handle_std_call(vcpu, ®s); + break; + + case OPTEE_SMC_FUNCID_RETURN_FROM_RPC: + optee_mediator_handle_rpc_call(vcpu, ®s); + break; + + default: + vcpu_set_reg(vcpu, 0, OPTEE_SMC_RETURN_UNKNOWN_FUNCTION); + break; + } + +out: + return; +} + +static int optee_mediator_is_active(void) +{ + + int ret = 1; + + spin_lock(&mediator_lock); + + if (!mediator) + ret = 0; + + spin_unlock(&mediator_lock); + + return ret; +} + +struct tee_mediator_ops optee_mediator_ops = { + .create_host = optee_mediator_create_host, + .destroy_host = optee_mediator_destroy_host, + .create_vm = optee_mediator_create_vm, + .destroy_vm = optee_mediator_destroy_vm, + .forward_request = optee_mediator_forward_smc, + .is_active = optee_mediator_is_active, +}; + +static int optee_check_virtualization(void) +{ + + int ret = 0; + + struct arm_smccc_res res; + + arm_smccc_smc(OPTEE_SMC_VM_DESTROYED, 0, 0, 0, 0, 0, 0, 0, &res); + + if (res.a0 == OPTEE_SMC_RETURN_UNKNOWN_FUNCTION) { + ret = -ENODEV; + goto out; + } + +out: + return ret; +} + +static int optee_check_page_size(void) +{ + if (OPTEE_MSG_NONCONTIG_PAGE_SIZE > PAGE_SIZE) + return -EINVAL; + + return 0; +} + +static int __init optee_mediator_init(void) +{ + + int ret; + + ret = optee_check_virtualization(); + if (ret < 0) { + pr_info("optee virtualization unsupported\n"); + goto out; + } + + ret = optee_check_page_size(); + if (ret < 0) { + pr_info("optee noncontig page size too large"); + goto out; + } + + mediator = kzalloc(sizeof(*mediator), GFP_KERNEL); + if (!mediator) { + ret = -ENOMEM; + goto out; + } + + ret = tee_mediator_register_ops(&optee_mediator_ops); + if (ret < 0) + goto out_free; + + atomic_set(&mediator->next_vmid, 2); // VMID 0 is reserved for the hypervisor and 1 is for host. + + INIT_LIST_HEAD(&mediator->vm_list); + mutex_init(&mediator->vm_list_lock); + spin_lock_init(&mediator_lock); + + pr_info("mediator initialised\n"); + +out: + return ret; +out_free: + kfree(mediator); + return ret; +} +module_init(optee_mediator_init); + +static void __exit optee_mediator_exit(void) +{ + + struct optee_vm_context *vm_context; + struct optee_vm_context *tmp; + + list_for_each_entry_safe(vm_context, tmp, &mediator->vm_list, list) { + list_del(&vm_context->list); + kfree(vm_context); + } + + kfree(mediator); + + pr_info("mediator exiting\n"); + +} +module_exit(optee_mediator_exit); diff --git a/drivers/tee/optee/optee_mediator.h b/drivers/tee/optee/optee_mediator.h new file mode 100644 index 000000000000..d632ed437aa6 --- /dev/null +++ b/drivers/tee/optee/optee_mediator.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * OP-TEE Mediator for the Linux Kernel + * + * This module enables a KVM guest to interact with OP-TEE + * in the secure world by hooking event handlers with + * the TEE Mediator layer. + * + * Author: + * Yuvraj Sakshith + */ + +#ifndef __OPTEE_MEDIATOR_H +#define __OPTEE_MEDIATOR_H + +#include "optee_msg.h" + +#include +#include +#include +#include +#include + +#define OPTEE_HYP_CLIENT_ID 0 +#define OPTEE_HOST_VMID 1 +#define OPTEE_BUFFER_ENTRIES ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) +#define OPTEE_MAX_SHM_BUFFER_PAGES 512 + +struct optee_mediator { + struct list_head vm_list; + struct mutex vm_list_lock; + + atomic_t next_vmid; +}; + +struct optee_vm_context { + struct list_head list; + struct list_head std_call_list; + struct list_head shm_buf_list; + struct list_head shm_rpc_list; + + struct mutex lock; + + struct kvm *kvm; + u64 vmid; + u32 call_count; + u64 shm_buf_page_count; +}; + +struct guest_regs { + u32 a0; + u32 a1; + u32 a2; + u32 a3; + u32 a4; + u32 a5; + u32 a6; + u32 a7; +}; + +struct optee_std_call { + struct list_head list; + + struct optee_msg_arg *guest_arg_gpa; + struct optee_msg_arg *guest_arg_hva; + struct optee_msg_arg *shadow_arg; + + u32 thread_id; + + u32 rpc_func; + u64 rpc_buffer_type; + + struct guest_regs rpc_state; +}; + +struct page_data { + u64 pages_list[OPTEE_BUFFER_ENTRIES]; + u64 next_page_data; +}; + +struct optee_shm_buf { + struct list_head list; + + struct page_data **shadow_buffer_list; + u64 num_buffers; + + gpa_t *guest_page_list; + u64 num_pages; + + u64 cookie; +}; + +struct optee_shm_rpc { + struct list_head list; + + struct optee_msg_arg *rpc_arg_gpa; + struct optee_msg_arg *rpc_arg_hva; + + u64 cookie; +}; + + +#endif From patchwork Tue Apr 1 17:05:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuvraj Sakshith X-Patchwork-Id: 14035199 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (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 DA1A820D51F for ; Tue, 1 Apr 2025 17:06:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527195; cv=none; b=nOCt+6uF6C8wMDqZ81Qd4md5FW8WSg6ho4lsTbwEDrnee9s4FIQrRexkq7wuGFY9P26GPk3c5UOOlUDtwZyz3XNvFPOysYntyTHmax0gogD5QH0Y9YObnT4P/Yd22LYPy5udSkuzTCy4K3c0AKPX/EYopFjXIjEJd2/vRASHz9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743527195; c=relaxed/simple; bh=J4D5P6ZuoPVhklxGsaD5HEAPeXTS8fvFnt2vhSIHhGA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pNUn8nXkCdxql865z7c581elhBoXE1D2i4Hdzh+LSMSYZJwu1n46VbDbe2duEGlW/ns7Mufg+Sa3DYEskJfgP8EquEl31IaIpGW5zDVWu4YCunFK25bEzjPRMs4EH7sCV3r4SX/cjgcJdXB4ysiBw1ztQBdg9GnbAhRu4xGzIg4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DQ7WbqjK; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DQ7WbqjK" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-22435603572so109589655ad.1 for ; Tue, 01 Apr 2025 10:06:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743527193; x=1744131993; 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=kjGdFgC2uV3PZy5Dr2trZqpXgiw/hsN6NMeCx+sevq0=; b=DQ7WbqjKYThUlwDBu2u8CpdQpfERPu50Gqu+Suycto8npgY3WBheuzl1JzdAyk87RL zsomdxWNAYcil9MJ2fNFhsp1ZIzaYpvaG52Ki/FRt3VsJ1CVSElWQULUXwmFrvtG4oZr Hs8QYB6IoDA4De4KzQP8jdCnSI7rsaSkWi8H1nqeBB0If37uTJmudsIfEq3zBMIfr0+k 2pAV3Cez2NB8naN0v96wvfmGXJcM+64Rd6tg1r9wXTBPehpjKO0bSfJwoEPPigzlvt6t ZF0/yeUeDjG59jg3+uX6sy60i+VmNkbjKgzQVYUDWQbY28q8Z2YXr0HCgMAXa8f/YK5+ 6+VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743527193; x=1744131993; 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=kjGdFgC2uV3PZy5Dr2trZqpXgiw/hsN6NMeCx+sevq0=; b=voOb9R/44idH+oTDAfI+IroSlTDOlaEcWy4z13yUYmETiwW4Wb6xsz1vlI0l99lOY9 k6ua/7MyodMU1gcwK2R/MasTO18m/EDgMb1khotJfdceGVYE1ixiYzZYpo1bKtXU8ZDG GXbt+O/lzgAaQSbdH1/X7sOzTfr61ksCbyez5HUpNYU+TZ8f+k67c9YbykHiV9sGQCiv hD8jQC5cqnPjoJ4DQ6q35HEsTsHzawy3vXW9TsfHwkH4p+qoLGKvEEdmUOa0tZPBu0Mp QppYOr9jXYV5X8U9KHd7dlI43ikNzcFXdIM0/zK5Dj1zeiNM1LvPkimQE6GqS9aub1W3 SGIw== X-Forwarded-Encrypted: i=1; AJvYcCUR41WamunmVgwd60i3eYibSTz13YPYG1vZQXwRdCB9hegAHZ24P4dV+JmOeZl06295ts0=@vger.kernel.org X-Gm-Message-State: AOJu0YyEeE7HihjhYMTEHQqB5Uocj1P6cjtb+HuWKmZz6MBkIGcDa64l VeIVsC9sOlOl/F5RdVwWx76pzxd/DxIEFYHTX19Q2P7APovKCxyt X-Gm-Gg: ASbGncsSk3wl22ficnPa8jO2uQiAa2EzrhSunyTk3SqKT5wJ7aPTBl4AYN5uzSMHjzz sdXs/kX0KvHPUA4Cd6QmxF1KbQXdNxfUOOEDDdt0nQ7foISegrKX/vnQnXnLYrrEsh225dm/GJi 1/sJ6O9MkDr2Ncl/1mOVb6De+xG18Y2Gow4gxsXV2t5tQMJ4zd02f18FegVoRmZpkQIe3Jt/XLW v9cw6sQq9bQlifQZ18MbVxEGWhRJPNaekkOMlNZY0tBPnODQDCqQ7BuTrordjbAjJZgsFRw1ivl Nl9uVL40bPURfCRHx2c537T1UhXoMgIJwU6xwuj8 X-Google-Smtp-Source: AGHT+IGzsiDzmzvRlyG7rp+VISpZTasYl/d6ySBJOZLqYXTkt37/lYxy1qELEG9qXXRbOBNMnKz3yw== X-Received: by 2002:a05:6a20:cfa1:b0:1f5:9330:2a18 with SMTP id adf61e73a8af0-2009f63227cmr20369442637.23.1743527193233; Tue, 01 Apr 2025 10:06:33 -0700 (PDT) Received: from raj.. ([103.48.69.244]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7398cd1cc3dsm5902926b3a.80.2025.04.01.10.06.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Apr 2025 10:06:32 -0700 (PDT) From: Yuvraj Sakshith To: kvmarm@lists.linux.dev, op-tee@lists.trustedfirmware.org, kvm@vger.kernel.org Cc: maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org, jens.wiklander@linaro.org, sumit.garg@kernel.org, mark.rutland@arm.com, lpieralisi@kernel.org, sudeep.holla@arm.com, pbonzini@redhat.com, praan@google.com, Yuvraj Sakshith Subject: [RFC PATCH 7/7] tee: optee: Notify TEE Mediator on OP-TEE driver initialization and release Date: Tue, 1 Apr 2025 22:35:27 +0530 Message-ID: <20250401170527.344092-8-yuvraj.kernel@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250401170527.344092-1-yuvraj.kernel@gmail.com> References: <20250401170527.344092-1-yuvraj.kernel@gmail.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When host initializes or releases its OP-TEE driver through optee_core_init()/optee_core_exit(), notify OP-TEE in the secure world about this change. If OP-TEE is built with NS-Virtualization support, it will treat SMCs coming from the host as if it were coming from a VM (as OP-TEE does not understand the KVM paradigm). Hence, OPTEE_SMC_VM_CREATED and OPTEE_SMC_VM_DESTROYED SMCs have to be made for its internal book-keeping. Signed-off-by: Yuvraj Sakshith --- drivers/tee/optee/core.c | 13 ++++++++++++- drivers/tee/optee/smc_abi.c | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index c75fddc83576..5f2ab0ee0893 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "optee_private.h" @@ -195,7 +196,13 @@ static bool intf_is_regged; static int __init optee_core_init(void) { int rc; - +#ifdef CONFIG_TEE_MEDIATOR + if (tee_mediator_is_active()) { + rc = tee_mediator_create_host(); + if (rc < 0) + return rc; + } +#endif /* * The kernel may have crashed at the same time that all available * secure world threads were suspended and we cannot reschedule the @@ -240,6 +247,10 @@ static void __exit optee_core_exit(void) optee_smc_abi_unregister(); if (!ffa_abi_rc) optee_ffa_abi_unregister(); +#ifdef CONFIG_TEE_MEDIATOR + if (tee_mediator_is_active()) + tee_mediator_destroy_host(); +#endif } module_exit(optee_core_exit); diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index f0c3ac1103bb..a930ca8cde23 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -25,8 +25,10 @@ #include #include #include +#include #include #include +#include "optee_mediator.h" #include "optee_private.h" #include "optee_smc.h" #include "optee_rpc_cmd.h" @@ -1396,6 +1398,10 @@ static void optee_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a6, unsigned long a7, struct arm_smccc_res *res) { +#ifdef CONFIG_TEE_MEDIATOR + if (tee_mediator_is_active()) + a7 = OPTEE_HOST_VMID; +#endif arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res); }