From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B634323ABBE; Mon, 17 Nov 2025 14:00:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388026; cv=none; b=dcREW2KVS3O3RDuZCWISk5YJDKQnUdlPVhDvTUzY9D0IkDJObapPzOddWCk8/5yVO7XvkIsy7V3752MzIFXzRGVsvF6y29iqvwzBNTpefngy2ZFWeTVTzhKEBE1IngbgsKDdAaFFa6bRa6adVhyYz1SwiKL/uZ2qc3MGEeACh6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388026; c=relaxed/simple; bh=/aH15OSMAV10WoTY6Mh5z6rWizKj4fULVUZZPJBmHnQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RtCTDScCKn+rv0oqloqsOFKkjhnTAkwm7jPvNbndqpGMRFV0eI6prFwTWFZIvWkxEx6Dkf6gACrLU7L1+KRc9ylkVfsxNYZHEXI3/Fy2hx/QSuoWo8wakLlRsl28LpCKs9e2uNkDpYp3HnujHqxGAo2h15A8ABCLsiXo0lAVo2M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ERNEqSn/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ERNEqSn/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3870BC19424; Mon, 17 Nov 2025 14:00:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388026; bh=/aH15OSMAV10WoTY6Mh5z6rWizKj4fULVUZZPJBmHnQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ERNEqSn/W/O6E3RWeVVtNElQgmbIvjTTJzSIjxYjc0M3QniGZRDPluYnOLEp4utKS 45zEBM7inHpZPogLEUoWeMzOL0jC0yjdBxjoF9JeYhdXteOKdbkFTekc2xK7sHKgdD ORdVEFlVZSrE+7+E8Py+65NkGkQrG20z9udQNY+u2vkJtDWwlHjdNdASh0ZgmaiYXp FQYibZEpsSVLQZAnZa2jZUJvle9wOiv7ZaDAP4lFzHcrVIQaoSl0fAEXNwNn32ET3k 1S0EM7j+2MSYgoH8guLKk0bTEPXhEA4eq2NldLXUBVx1/zHua+XkoVysypEmm3Wdqe P1DCmIiSvU+fw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 01/11] coco: guest: arm64: Guest TSM callback and realm device lock support Date: Mon, 17 Nov 2025 19:29:57 +0530 Message-ID: <20251117140007.122062-2-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Register the TSM callback when the DA feature is supported by RSI. The build order is also adjusted so that the TSM class is created before the arm-cca-guest driver is initialized. In addition, add support for the TDISP lock sequence. Writing a TSM (TEE Security Manager) device name from `/sys/class/tsm` into `tsm/lock` triggers the realm device lock operation. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi.h | 3 ++ arch/arm64/include/asm/rsi_cmds.h | 17 +++++++ arch/arm64/include/asm/rsi_smc.h | 1 + arch/arm64/kernel/rsi.c | 11 +++++ drivers/virt/coco/Makefile | 2 +- drivers/virt/coco/arm-cca-guest/Kconfig | 8 ++- drivers/virt/coco/arm-cca-guest/Makefile | 1 + drivers/virt/coco/arm-cca-guest/arm-cca.c | 60 ++++++++++++++++++++++- drivers/virt/coco/arm-cca-guest/rsi-da.h | 32 ++++++++++++ 9 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 drivers/virt/coco/arm-cca-guest/rsi-da.h diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h index 2d2d363aaaee..12ccd1ed3dfa 100644 --- a/arch/arm64/include/asm/rsi.h +++ b/arch/arm64/include/asm/rsi.h @@ -67,4 +67,7 @@ static inline int rsi_set_memory_range_shared(phys_addr_t= start, return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY, RSI_CHANGE_DESTROYED); } + +bool rsi_has_da_feature(void); + #endif /* __ASM_RSI_H_ */ diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 2c8763876dfb..6c2db7a24ef3 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -159,4 +159,21 @@ static inline unsigned long rsi_attestation_token_cont= inue(phys_addr_t granule, return res.a0; } =20 +/** + * rsi_features() - Read feature register + * @index: Feature register index + * @out: Feature register value is written to this pointer + * + * Return: RSI return code + */ +static inline unsigned long rsi_features(unsigned long index, unsigned lon= g *out) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_FEATURES, index, &res); + + *out =3D res.a1; + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 6cb070eca9e9..8e486cdef9eb 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -53,6 +53,7 @@ */ #define SMC_RSI_ABI_VERSION SMC_RSI_FID(0x190) =20 +#define RSI_FEATURE_REGISTER_0_DA BIT(0) /* * Read feature register. * diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c index 1b716d18b80e..2ec0f5dff02e 100644 --- a/arch/arm64/kernel/rsi.c +++ b/arch/arm64/kernel/rsi.c @@ -15,6 +15,7 @@ #include =20 static struct realm_config config; +static unsigned long rsi_feat_reg0; =20 unsigned long prot_ns_shared; EXPORT_SYMBOL(prot_ns_shared); @@ -22,6 +23,12 @@ EXPORT_SYMBOL(prot_ns_shared); DEFINE_STATIC_KEY_FALSE_RO(rsi_present); EXPORT_SYMBOL(rsi_present); =20 +bool rsi_has_da_feature(void) +{ + return u64_get_bits(rsi_feat_reg0, RSI_FEATURE_REGISTER_0_DA); +} +EXPORT_SYMBOL_GPL(rsi_has_da_feature); + bool cc_platform_has(enum cc_attr attr) { switch (attr) { @@ -146,6 +153,10 @@ void __init arm64_rsi_init(void) return; if (WARN_ON(rsi_get_realm_config(&config))) return; + + if (WARN_ON(rsi_features(0, &rsi_feat_reg0))) + return; + prot_ns_shared =3D BIT(config.ipa_bits - 1); =20 if (arm64_ioremap_prot_hook_register(realm_ioremap_hook)) diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile index cb52021912b3..57556d7c1cec 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -6,6 +6,6 @@ obj-$(CONFIG_EFI_SECRET) +=3D efi_secret/ obj-$(CONFIG_ARM_PKVM_GUEST) +=3D pkvm-guest/ obj-$(CONFIG_SEV_GUEST) +=3D sev-guest/ obj-$(CONFIG_INTEL_TDX_GUEST) +=3D tdx-guest/ -obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ obj-$(CONFIG_TSM) +=3D tsm-core.o obj-$(CONFIG_TSM_GUEST) +=3D guest/ +obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/ar= m-cca-guest/Kconfig index a42359a90558..66b2d9202b66 100644 --- a/drivers/virt/coco/arm-cca-guest/Kconfig +++ b/drivers/virt/coco/arm-cca-guest/Kconfig @@ -1,11 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-only +# + config ARM_CCA_GUEST tristate "Arm CCA Guest driver" depends on ARM64 + depends on PCI_TSM select TSM_REPORTS select AUXILIARY_BUS + select TSM help - The driver provides userspace interface to request and + The driver provides userspace interface to request an attestation report from the Realm Management Monitor(RMM). + If the DA feature is supported, it also register with TSM framework. =20 If you choose 'M' here, this module will be called arm-cca-guest. diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/a= rm-cca-guest/Makefile index 75a120e24fda..bc3b2be4019f 100644 --- a/drivers/virt/coco/arm-cca-guest/Makefile +++ b/drivers/virt/coco/arm-cca-guest/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +# obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest.o =20 arm-cca-guest-y +=3D arm-cca.o diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index dc96171791db..288fa53ad0af 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2023 ARM Ltd. + * Copyright (C) 2025 ARM Ltd. */ =20 #include @@ -15,6 +15,8 @@ =20 #include =20 +#include "rsi-da.h" + /** * struct arm_cca_token_info - a descriptor for the token buffer. * @challenge: Pointer to the challenge data @@ -192,6 +194,57 @@ static void unregister_cca_tsm_report(void *data) tsm_report_unregister(&arm_cca_tsm_report_ops); } =20 +static struct pci_tsm *cca_tsm_lock(struct tsm_dev *tsm_dev, struct pci_de= v *pdev) +{ + int ret; + + struct cca_guest_dsc *cca_dsc __free(kfree) =3D + kzalloc(sizeof(*cca_dsc), GFP_KERNEL); + if (!cca_dsc) + return ERR_PTR(-ENOMEM); + + ret =3D pci_tsm_devsec_constructor(pdev, &cca_dsc->pci, tsm_dev); + if (ret) + return ERR_PTR(ret); + + return ERR_PTR(-EIO); +} + +static void cca_tsm_unlock(struct pci_tsm *tsm) +{ + struct cca_guest_dsc *cca_dsc =3D to_cca_guest_dsc(tsm->pdev); + + kfree(cca_dsc); +} + +static struct pci_tsm_ops cca_devsec_pci_ops =3D { + .lock =3D cca_tsm_lock, + .unlock =3D cca_tsm_unlock, +}; + +static void cca_devsec_tsm_remove(void *tsm_dev) +{ + tsm_unregister(tsm_dev); +} + +static int cca_devsec_tsm_register(struct auxiliary_device *adev) +{ + struct tsm_dev *tsm_dev; + int rc; + + tsm_dev =3D tsm_register(&adev->dev, &cca_devsec_pci_ops); + if (IS_ERR(tsm_dev)) + return PTR_ERR(tsm_dev); + + rc =3D devm_add_action_or_reset(&adev->dev, cca_devsec_tsm_remove, tsm_de= v); + if (rc) { + cca_devsec_tsm_remove(tsm_dev); + return rc; + } + + return 0; +} + static int cca_devsec_tsm_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) { @@ -212,6 +265,10 @@ static int cca_devsec_tsm_probe(struct auxiliary_devic= e *adev, return ret; } =20 + /* Allow tsm report even if tsm_register fails */ + if (rsi_has_da_feature()) + cca_devsec_tsm_register(adev); + return 0; } =20 @@ -227,5 +284,6 @@ static struct auxiliary_driver cca_devsec_tsm_driver = =3D { }; module_auxiliary_driver(cca_devsec_tsm_driver); MODULE_AUTHOR("Sami Mujawar "); +MODULE_AUTHOR("Aneesh Kumar "); MODULE_DESCRIPTION("Arm CCA Guest TSM Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h new file mode 100644 index 000000000000..5ad3b740710e --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#ifndef _VIRT_COCO_RSI_DA_H_ +#define _VIRT_COCO_RSI_DA_H_ + +#include +#include +#include + +struct cca_guest_dsc { + struct pci_tsm_devsec pci; +}; + +static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) +{ + struct pci_tsm *tsm =3D pdev->tsm; + + if (!tsm) + return NULL; + return container_of(tsm, struct cca_guest_dsc, pci.base_tsm); +} + +static inline int rsi_vdev_id(struct pci_dev *pdev) +{ + return (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); +} + +#endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8EA822AEF5; Mon, 17 Nov 2025 14:00:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388033; cv=none; b=RFx4rGiVDIfaUHvnxgCnfxigj6/EsKy+SfpXg5v7ROEuZ6TUUVMYYbayNI5wmkrTVBPL2FB9wqC/KPPziEj9ozPR03ZlHNzo3L5A3IqgsQC2IG+dlIt4wTt/eAdn+ZMOw5NXJnfJxlaxIE9xvwU1Xp04bakrJNDHN7LqxGg0XG8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388033; c=relaxed/simple; bh=V/BR6e27SASfgNWzEFxjjMuYtGP7obGAPVnBSdkKZ3U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NpHtXsNThKAXS45xLLfX82+sQ3GXkpSH7EMMV6STTqOLGtnwybPT++9gNMcQbCd0qNdIvNCcQnzigj3wGHgrAyBN6mggC3xNZQwV9D6kNCy+eFTdjdi7VybKXfj3ZXykgyHBDeTItsNMneTwIFmn50gT/BuFrlbenB4VhBTwJRU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SZXzaZ8r; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SZXzaZ8r" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D8B02C2BC86; Mon, 17 Nov 2025 14:00:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388033; bh=V/BR6e27SASfgNWzEFxjjMuYtGP7obGAPVnBSdkKZ3U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SZXzaZ8rq8xrT+PDWOoNY/LuYV71ghFsRAOWhJ4fWdUgGitQRXLk7LahGe9U9bs0w LuUxv0OqcfwHk3pmTb9WYoOBXKZSpkRQfGJc46GmU2ektv4u9TxwF77gav7vADzHlW TqKAcM2Tuzu2BlnnYClbHl1yoNRLTNBdVyEgP3fGXdngBRehohKdSTjZkG8q6zibu4 4kghUGxkcq0htGtz4J7SzJFescWdmxgaPTqWktqhU7KJeKnHSTN8NKuC16f3xSog9v SPQGSuaVKbCnMwGrclsEb3nPToR2myxw2RZO2lUMZag4tPlXrDBR8zRpL0lVAalW8z PQsUrm2abJCtg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 02/11] coco: guest: arm64: Add Realm Host Interface and guest DA helper Date: Mon, 17 Nov 2025 19:29:58 +0530 Message-ID: <20251117140007.122062-3-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" - describe the Realm Host Interface SMC IDs and result codes in a new `asm/rhi.h` header - expose `struct rsi_host_call` plus an `rsi_host_call()` helper so we can invoke `SMC_RSI_HOST_CALL` from C code - build a guest-side `rhi-da` helper that drives the vdev TDI state machine via RHI host calls and translates the firmware status codes This provides the basic RHI plumbing that later DA features rely on. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 50 +++++++ arch/arm64/include/asm/rsi_cmds.h | 9 ++ arch/arm64/include/asm/rsi_smc.h | 7 + drivers/virt/coco/arm-cca-guest/Makefile | 2 +- drivers/virt/coco/arm-cca-guest/arm-cca.c | 3 +- drivers/virt/coco/arm-cca-guest/rhi-da.c | 158 ++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.h | 14 ++ 7 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/include/asm/rhi.h create mode 100644 drivers/virt/coco/arm-cca-guest/rhi-da.c create mode 100644 drivers/virt/coco/arm-cca-guest/rhi-da.h diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h new file mode 100644 index 000000000000..335930bbf059 --- /dev/null +++ b/arch/arm64/include/asm/rhi.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Ltd. + */ + +#ifndef __ASM_RHI_H_ +#define __ASM_RHI_H_ + +#include + +#define SMC_RHI_CALL(func) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD_HYP,\ + (func)) + +#define RHI_DA_SUCCESS 0x0 +#define RHI_DA_INCOMPLETE 0x1 +#define RHI_DA_ERROR_DATA_NOT_AVAILABLE 0x2 +#define RHI_DA_ERROR_INVALID_VDEV_ID 0x3 +#define RHI_DA_ERROR_INVALID_OBJECT 0x4 +#define RHI_DA_ERROR_INPUT 0x5 +#define RHI_DA_ERROR_DEVICE 0x6 +#define RHI_DA_ERROR_INVALID_OFFSET 0x7 +#define RHI_DA_ERROR_ACCESS_FAILED 0x8 +#define RHI_DA_ERROR_BUSY 0x9 + +#define RHI_DA_FEATURE_OBJECT_SIZE BIT(0) +#define RHI_DA_FEATURE_OBJECT_READ BIT(1) +#define RHI_DA_FEATURE_VDEV_CONTINUE BIT(2) +#define RHI_DA_FEATURE_VDEV_GET_MEASUREMENT BIT(3) +#define RHI_DA_FEATURE_VDEV_GET_INTF_REPORT BIT(4) +#define RHI_DA_FEATURE_VDEV_SET_TDI_STATE BIT(5) + +#define RHI_DA_BASE_FEATURE (RHI_DA_FEATURE_OBJECT_SIZE | \ + RHI_DA_FEATURE_OBJECT_READ | \ + RHI_DA_FEATURE_VDEV_GET_INTF_REPORT | \ + RHI_DA_FEATURE_VDEV_GET_MEASUREMENT | \ + RHI_DA_FEATURE_VDEV_SET_TDI_STATE) +#define RHI_DA_FEATURES SMC_RHI_CALL(0x004B) + +#define RHI_DA_VDEV_CONTINUE SMC_RHI_CALL(0x0051) + +#define RHI_DA_TDI_CONFIG_UNLOCKED 0x0 +#define RHI_DA_TDI_CONFIG_LOCKED 0x1 +#define RHI_DA_TDI_CONFIG_RUN 0x2 +#define RHI_DA_VDEV_SET_TDI_STATE SMC_RHI_CALL(0x0054) +#define RHI_DA_VDEV_ABORT SMC_RHI_CALL(0x0056) + +#endif diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 6c2db7a24ef3..18aa1b9efb9b 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -176,4 +176,13 @@ static inline unsigned long rsi_features(unsigned long= index, unsigned long *out return res.a0; } =20 +static inline unsigned long rsi_host_call(phys_addr_t addr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_HOST_CALL, addr, &res); + + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 8e486cdef9eb..4dbd87a27d9b 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -183,6 +183,13 @@ struct realm_config { */ #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198) =20 +struct rsi_host_call { + union { + u16 imm; + u64 padding0; + }; + u64 gprs[31]; +} __aligned(0x100); /* * Make a Host call. * diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/a= rm-cca-guest/Makefile index bc3b2be4019f..04d26e398a1d 100644 --- a/drivers/virt/coco/arm-cca-guest/Makefile +++ b/drivers/virt/coco/arm-cca-guest/Makefile @@ -2,4 +2,4 @@ # obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest.o =20 -arm-cca-guest-y +=3D arm-cca.o +arm-cca-guest-y +=3D arm-cca.o rhi-da.o diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 288fa53ad0af..26be2e8fe182 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -16,6 +16,7 @@ #include =20 #include "rsi-da.h" +#include "rhi-da.h" =20 /** * struct arm_cca_token_info - a descriptor for the token buffer. @@ -266,7 +267,7 @@ static int cca_devsec_tsm_probe(struct auxiliary_device= *adev, } =20 /* Allow tsm report even if tsm_register fails */ - if (rsi_has_da_feature()) + if (rsi_has_da_feature() && rhi_has_da_support()) cca_devsec_tsm_register(adev); =20 return 0; diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.c b/drivers/virt/coco/a= rm-cca-guest/rhi-da.c new file mode 100644 index 000000000000..3430d8df4424 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include "rsi-da.h" +#include "rhi-da.h" + +/* return value to indicate the need to call rhi_vdev_continue*/ +#define E_INCOMPLETE 1 +static inline int map_rhi_da_error(unsigned long rhi_da_error) +{ + switch (rhi_da_error) { + case RHI_DA_SUCCESS: + return 0; + case RHI_DA_INCOMPLETE: + return E_INCOMPLETE; + case RHI_DA_ERROR_BUSY: + return -EBUSY; + case RHI_DA_ERROR_INPUT: + case RHI_DA_ERROR_INVALID_VDEV_ID: + return -EINVAL; + case RHI_DA_ERROR_ACCESS_FAILED: + return -EFAULT; + case RHI_DA_ERROR_DEVICE: + return -EIO; + case RHI_DA_ERROR_INVALID_OBJECT: + return -EINVAL; + default: + return -EIO; + } +} + +bool rhi_has_da_support(void) +{ + int ret; + struct rsi_host_call *rhicall; + + rhicall =3D kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhicall) + return -ENOMEM; + + rhicall->imm =3D 0; + rhicall->gprs[0] =3D RHI_DA_FEATURES; + + ret =3D rsi_host_call(virt_to_phys(rhicall)); + if (ret !=3D RSI_SUCCESS || rhicall->gprs[0] =3D=3D SMCCC_RET_NOT_SUPPORT= ED) + return false; + + /* For base DA to work we need these to be supported */ + if ((rhicall->gprs[0] & RHI_DA_BASE_FEATURE) =3D=3D RHI_DA_BASE_FEATURE) + return true; + + return false; +} + +static inline int rhi_vdev_continue(unsigned long vdev_id, unsigned long c= ookie) +{ + unsigned long ret; + + struct rsi_host_call *rhi_call __free(kfree) =3D + kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhi_call) + return -ENOMEM; + + rhi_call->imm =3D 0; + rhi_call->gprs[0] =3D RHI_DA_VDEV_CONTINUE; + rhi_call->gprs[1] =3D vdev_id; + rhi_call->gprs[2] =3D cookie; + + ret =3D rsi_host_call(virt_to_phys(rhi_call)); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + return map_rhi_da_error(rhi_call->gprs[0]); +} + +static int __rhi_vdev_abort(unsigned long vdev_id, unsigned long *da_error) +{ + unsigned long ret; + struct rsi_host_call *rhi_call __free(kfree) =3D + kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhi_call) + return -ENOMEM; + + rhi_call->imm =3D 0; + rhi_call->gprs[0] =3D RHI_DA_VDEV_ABORT; + rhi_call->gprs[1] =3D vdev_id; + + ret =3D rsi_host_call(virt_to_phys(rhi_call)); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + return *da_error =3D rhi_call->gprs[0]; + return 0; +} + +static bool should_abort_rhi_call_loop(unsigned long vdev_id) +{ + int ret; + + cond_resched(); + if (signal_pending(current)) { + unsigned long da_error; + + ret =3D __rhi_vdev_abort(vdev_id, &da_error); + /* consider all kind of error as not aborted */ + if (!ret && (da_error =3D=3D RHI_DA_SUCCESS)) + return true; + } + return false; +} + +static int __rhi_vdev_set_tdi_state(unsigned long vdev_id, + unsigned long target_state, + unsigned long *cookie) +{ + unsigned long ret; + + struct rsi_host_call *rhi_call __free(kfree) =3D + kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhi_call) + return -ENOMEM; + + rhi_call->imm =3D 0; + rhi_call->gprs[0] =3D RHI_DA_VDEV_SET_TDI_STATE; + rhi_call->gprs[1] =3D vdev_id; + rhi_call->gprs[2] =3D target_state; + + ret =3D rsi_host_call(virt_to_phys(rhi_call)); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + *cookie =3D rhi_call->gprs[1]; + return map_rhi_da_error(rhi_call->gprs[0]); +} + +int rhi_vdev_set_tdi_state(struct pci_dev *pdev, unsigned long target_stat= e) +{ + int ret; + unsigned long cookie; + int vdev_id =3D rsi_vdev_id(pdev); + + for (;;) { + ret =3D __rhi_vdev_set_tdi_state(vdev_id, target_state, &cookie); + if (ret !=3D -EBUSY) + break; + cond_resched(); + } + + while (ret =3D=3D E_INCOMPLETE) { + if (should_abort_rhi_call_loop(vdev_id)) + return -EINTR; + ret =3D rhi_vdev_continue(vdev_id, cookie); + } + + return ret; +} diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.h b/drivers/virt/coco/a= rm-cca-guest/rhi-da.h new file mode 100644 index 000000000000..8dd77c7ed645 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Ltd. + */ + +#ifndef _VIRT_COCO_RHI_DA_H_ +#define _VIRT_COCO_RHI_DA_H_ + +#include + +struct pci_dev; +bool rhi_has_da_support(void); +int rhi_vdev_set_tdi_state(struct pci_dev *pdev, unsigned long target_stat= e); +#endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83ECF332EB2; Mon, 17 Nov 2025 14:00:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388040; cv=none; b=hOQ1oyzkODU5Z8bDaya97WG9jlsbYTl+/tJhfZyIeJ8gdjvkuWJgUlX1JhkeLRj6HMnoIyef35zU39KxztPb/cJvwskb8wRQZM3MtAqNnUU0OO/1RMafWH02byVlhoK5vv9xgZBJTuXt4tqDwzbR7B7sByRXBp5JLMskejhqBWc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388040; c=relaxed/simple; bh=skmqiPydXKmGDZG76wasmKG8RYvqg1SsacoWzOtzd+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UEFHYCdAHNiBs+Vy8blaG6baJIeWwScWnVotv/LoolgcyuvrvKTFY/5MVAJLsy8AsORkLF0QFLLxV5hy9sBfyA9O1/1Pvl/J0iTK2oyre+tniSEn3VQ8rMlelLqIKsiDloJKHD6It8Spkt20Gc/JYD5cTKamf4i4Afp+1CK9Rc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Mq2lWTjW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Mq2lWTjW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B6B1BC4CEFB; Mon, 17 Nov 2025 14:00:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388040; bh=skmqiPydXKmGDZG76wasmKG8RYvqg1SsacoWzOtzd+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Mq2lWTjWxhJSZOR6Qpek3FMz0T6WEP1L++ClRQanE8zuxdFK9gc3pTZ5bArzQU96r yOw2oD/HektMSARh6Br7oIRNq6H9DhAuXU9nQsFDuvrvWKM19LJX6EnOUQs02kwMfi oEVzWGtPmtwSdxFNbr3QEJb/IR3xx+D1LlDxAXhzy4KkEAJAMQS8NG018FW83Enyg+ FPuklEp5thTm6hNFVnNkG2gaJVeGmmj/o6xU9H87lY/5awtBpDP9JOMY5WSVZ5Qn8h x+anrBYpkFZRTfVJdlPQqHl9I/ie6BkSCpimLOv08JQHi5zhPHI3P46HirLugZJTEr KEy1ugEHvlYRA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 03/11] coco: guest: arm64: Add support for guest initiated TDI bind/unbind Date: Mon, 17 Nov 2025 19:29:59 +0530 Message-ID: <20251117140007.122062-4-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add RHI for VDEV_SET_TDI_STATE Note: This is not part of RHI spec. This is a POC implementation and will be later converted to correct interface defined by RHI. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/virt/coco/arm-cca-guest/Makefile | 2 +- drivers/virt/coco/arm-cca-guest/arm-cca.c | 8 ++++- drivers/virt/coco/arm-cca-guest/rsi-da.c | 36 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 ++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 drivers/virt/coco/arm-cca-guest/rsi-da.c diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/a= rm-cca-guest/Makefile index 04d26e398a1d..146af69d0362 100644 --- a/drivers/virt/coco/arm-cca-guest/Makefile +++ b/drivers/virt/coco/arm-cca-guest/Makefile @@ -2,4 +2,4 @@ # obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest.o =20 -arm-cca-guest-y +=3D arm-cca.o rhi-da.o +arm-cca-guest-y +=3D arm-cca.o rhi-da.o rsi-da.o diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 26be2e8fe182..f4c9e529c43e 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -208,13 +208,19 @@ static struct pci_tsm *cca_tsm_lock(struct tsm_dev *t= sm_dev, struct pci_dev *pde if (ret) return ERR_PTR(ret); =20 - return ERR_PTR(-EIO); + ret =3D cca_device_lock(pdev); + if (ret) + return ERR_PTR(-EIO); + + return &no_free_ptr(cca_dsc)->pci.base_tsm; } =20 static void cca_tsm_unlock(struct pci_tsm *tsm) { struct cca_guest_dsc *cca_dsc =3D to_cca_guest_dsc(tsm->pdev); =20 + cca_device_unlock(tsm->pdev); + kfree(cca_dsc); } =20 diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c new file mode 100644 index 000000000000..6770861629f2 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include +#include + +#include "rsi-da.h" +#include "rhi-da.h" + +#define PCI_TDISP_MESSAGE_VERSION_10 0x10 + +int cca_device_lock(struct pci_dev *pdev) +{ + int ret; + + ret =3D rhi_vdev_set_tdi_state(pdev, RHI_DA_TDI_CONFIG_LOCKED); + if (ret) { + pci_err(pdev, "failed to lock the device (%u)\n", ret); + return -EIO; + } + return 0; +} + +int cca_device_unlock(struct pci_dev *pdev) +{ + int ret; + + ret =3D rhi_vdev_set_tdi_state(pdev, RHI_DA_TDI_CONFIG_UNLOCKED); + if (ret) { + pci_err(pdev, "failed to unlock the device (%u)\n", ret); + return -EIO; + } + return 0; +} diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 5ad3b740710e..d1f4641a0fa1 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -29,4 +29,6 @@ static inline int rsi_vdev_id(struct pci_dev *pdev) PCI_DEVID(pdev->bus->number, pdev->devfn); } =20 +int cca_device_lock(struct pci_dev *pdev); +int cca_device_unlock(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D28933033A; Mon, 17 Nov 2025 14:00:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388047; cv=none; b=sU/c1jFuqcA2PmqmRTmddx6P1FwXi7iGIqxhBh5xL4Rg3sMSXpZmc9crWXIyeRuItaO3pXgf3tt2LXQ5FyoNLnC5JinRM538Lat/3fgKWYbIyDMtCtw5RN6xqkhrZ29p9lD40q81vBhzjAQ6BdhB5HAtzf6d6Ba/95O8JOL17Ho= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388047; c=relaxed/simple; bh=iuqwUAzOCRRtnJwXt/+Ru2PZgwzmTFNgKLsPlP94gFU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n9QuDg+q6/D1I/7GHjXtdcahG9TRexfpP8MRyL1/UGfkhs0+pGj31btRklvcslxC008vRxmGUl5Zk+8rlgI4upQf4FUjg4Bue0wThkKHrUwXUSfgMqbkt6wKjCqs97nm+auvpP6f2c+i3UeiKUGr1MfbopPkkmvt8YA6F3TRXVM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lM5LpFML; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lM5LpFML" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ADC40C19422; Mon, 17 Nov 2025 14:00:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388046; bh=iuqwUAzOCRRtnJwXt/+Ru2PZgwzmTFNgKLsPlP94gFU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lM5LpFMLdNss7FFTtHLNcMSjoNJxkGfrhd4BZyeY26yW9Ps3LQl9yREH0i0oR0RsL PhUhT4TFjcgWbT6HJwlu53bfek0ZorxVI2lobe8NRds/NDBzYWLYsuJsEl/ld3AKgr 4XVhX+3DeYf1YPhxa8/9qsE+25lJKHoNSnluJ0oUEeiy34kUDQOWcoKvoCYhH7zHAo WFckdJavyQd66x9TSmQTpIS49qsKAxGUFuVDJPpHftyixdbOMLghporIqSsTBCkqi8 g3MPiDnX/tye3OSjutWZ20fDE56OYfMU4zuG1SV0CzlTgoYptNy6dhdNu1WwwVkSKT zD1ToPBvTEOKA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 04/11] coco: guest: arm64: Add support for updating interface reports from device Date: Mon, 17 Nov 2025 19:30:00 +0530 Message-ID: <20251117140007.122062-5-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Support collecting interface reports using RSI calls. The fetched interface report will be cached in the host. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 1 + drivers/virt/coco/arm-cca-guest/arm-cca.c | 6 ++++ drivers/virt/coco/arm-cca-guest/rhi-da.c | 44 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.h | 1 + drivers/virt/coco/arm-cca-guest/rsi-da.c | 13 +++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 ++ 6 files changed, 67 insertions(+) diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index 335930bbf059..5f140015afc3 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -40,6 +40,7 @@ #define RHI_DA_FEATURES SMC_RHI_CALL(0x004B) =20 #define RHI_DA_VDEV_CONTINUE SMC_RHI_CALL(0x0051) +#define RHI_DA_VDEV_GET_INTERFACE_REPORT SMC_RHI_CALL(0x0052) =20 #define RHI_DA_TDI_CONFIG_UNLOCKED 0x0 #define RHI_DA_TDI_CONFIG_LOCKED 0x1 diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index f4c9e529c43e..7988ff6d4b2e 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -212,6 +212,12 @@ static struct pci_tsm *cca_tsm_lock(struct tsm_dev *ts= m_dev, struct pci_dev *pde if (ret) return ERR_PTR(-EIO); =20 + ret =3D cca_update_device_object_cache(pdev, cca_dsc); + if (ret) { + cca_device_unlock(pdev); + return ERR_PTR(-EIO); + } + return &no_free_ptr(cca_dsc)->pci.base_tsm; } =20 diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.c b/drivers/virt/coco/a= rm-cca-guest/rhi-da.c index 3430d8df4424..f4fb8577e1b5 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.c @@ -156,3 +156,47 @@ int rhi_vdev_set_tdi_state(struct pci_dev *pdev, unsig= ned long target_state) =20 return ret; } + +static inline int rhi_vdev_get_interface_report(unsigned long vdev_id, + unsigned long *cookie) +{ + unsigned long ret; + + struct rsi_host_call *rhi_call __free(kfree) =3D + kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhi_call) + return -ENOMEM; + + rhi_call->imm =3D 0; + rhi_call->gprs[0] =3D RHI_DA_VDEV_GET_INTERFACE_REPORT; + rhi_call->gprs[1] =3D vdev_id; + + ret =3D rsi_host_call(virt_to_phys(rhi_call)); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + *cookie =3D rhi_call->gprs[1]; + return map_rhi_da_error(rhi_call->gprs[0]); +} + +int rhi_update_vdev_interface_report_cache(struct pci_dev *pdev) +{ + int ret; + unsigned long cookie; + int vdev_id =3D rsi_vdev_id(pdev); + + for (;;) { + ret =3D rhi_vdev_get_interface_report(vdev_id, &cookie); + if (ret !=3D -EBUSY) + break; + cond_resched(); + } + + while (ret =3D=3D E_INCOMPLETE) { + if (should_abort_rhi_call_loop(vdev_id)) + return -EINTR; + ret =3D rhi_vdev_continue(vdev_id, cookie); + } + + return ret; +} diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.h b/drivers/virt/coco/a= rm-cca-guest/rhi-da.h index 8dd77c7ed645..d83e61359b35 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.h @@ -11,4 +11,5 @@ struct pci_dev; bool rhi_has_da_support(void); int rhi_vdev_set_tdi_state(struct pci_dev *pdev, unsigned long target_stat= e); +int rhi_update_vdev_interface_report_cache(struct pci_dev *pdev); #endif diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 6770861629f2..c8ba72e4be3e 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -34,3 +34,16 @@ int cca_device_unlock(struct pci_dev *pdev) } return 0; } + +int cca_update_device_object_cache(struct pci_dev *pdev, struct cca_guest_= dsc *dsc) +{ + int ret; + + ret =3D rhi_update_vdev_interface_report_cache(pdev); + if (ret) { + pci_err(pdev, "failed to get interface report (%d)\n", ret); + return ret; + } + + return 0; +} diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index d1f4641a0fa1..fd4792a50daf 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -31,4 +31,6 @@ static inline int rsi_vdev_id(struct pci_dev *pdev) =20 int cca_device_lock(struct pci_dev *pdev); int cca_device_unlock(struct pci_dev *pdev); +int cca_update_device_object_cache(struct pci_dev *pdev, struct cca_guest_= dsc *dsc); + #endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A176230D35; Mon, 17 Nov 2025 14:00:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388054; cv=none; b=pFNjJHcMJYSN0JQnXzyK8GYoekCzr/HmEU2R3d+SESWvFaOnexsgC6FrMWtO33ds8r0SZD5OUBtPx7G5FrS6eyHX/DJw3NWrGo+bqEMzbH5STGp1Qikn+44JMt2iV72GEPFHlAXjIGcAR0WVuRQJpbEKTLeD+i0NxpczExaFrak= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388054; c=relaxed/simple; bh=KFq6hm4wYhWj0CmT978SYJI5xZKP3t2GSOqoFO/Gl9A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hn9KtCfBnFgJ20LLQAGrlk94GopRR1oN7Igr0mu+eJZXylR/+7zA/fF8VJA2Kf3r0w5NqXDCgy/2v/oiBwZrJVcElGzVtH5eGVNnMgLUVVftNOLh3dBsXtH1clgHa/kqrW4CrpZYgusUW0X+1Crf6j/SJC2N1sNRGQzZWGULSGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qhn0KxUU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qhn0KxUU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 72B64C4CEF1; Mon, 17 Nov 2025 14:00:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388053; bh=KFq6hm4wYhWj0CmT978SYJI5xZKP3t2GSOqoFO/Gl9A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qhn0KxUUd4EfMAPW9lCXLqPUSvai+QFYXMBBDnYQyZ2HrFezJsI9kJO1kx757u491 wWO0rFl8c2mC+6VrJheGIEYPLUiB8pOhNbh/EhoG50+fzclLHA5meGbE8VaRrAnLJ3 RiXRZtxYoRzo6Y8q4IacUAN4QTZjl8FN5ph0Wdz7q0cc94PYQdo5qMMZyukxQQEAEX oTpZERFalCAx82mv/GRxsGzbRiEOm+TK1RUdDxCZX769ZI80eTgr395wz01K31y7DC UC8aEMS3DsDCxdeQfl95Jw0Qr+Mt7bytHyfQ5y6DUVwaW0cKA8ZDjRQnUhBQmWUJJk ViZ5NHlNK4KAQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 05/11] coco: guest: arm64: Add support for updating measurements from device Date: Mon, 17 Nov 2025 19:30:01 +0530 Message-ID: <20251117140007.122062-6-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fetch device measurements using RSI_RDEV_GET_MEASUREMENTS. The fetched device measurements will be cached in the host. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 19 ++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.c | 48 ++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.h | 2 + drivers/virt/coco/arm-cca-guest/rsi-da.c | 58 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 + 5 files changed, 129 insertions(+) diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index 5f140015afc3..ce2ed8a440c3 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -42,6 +42,25 @@ #define RHI_DA_VDEV_CONTINUE SMC_RHI_CALL(0x0051) #define RHI_DA_VDEV_GET_INTERFACE_REPORT SMC_RHI_CALL(0x0052) =20 +#define RHI_VDEV_MEASURE_SIGNED BIT(0) +#define RHI_VDEV_MEASURE_RAW BIT(1) +#define RHI_VDEV_MEASURE_EXCHANGE BIT(2) +struct rhi_vdev_measurement_params { + union { + u64 flags; + u8 padding0[256]; + }; + union { + u8 indices[32]; + u8 padding1[256]; + }; + union { + u8 nonce[32]; + u8 padding2[256]; + }; +}; +#define RHI_DA_VDEV_GET_MEASUREMENTS SMC_RHI_CALL(0x0053) + #define RHI_DA_TDI_CONFIG_UNLOCKED 0x0 #define RHI_DA_TDI_CONFIG_LOCKED 0x1 #define RHI_DA_TDI_CONFIG_RUN 0x2 diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.c b/drivers/virt/coco/a= rm-cca-guest/rhi-da.c index f4fb8577e1b5..aa17bb3ee562 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.c @@ -200,3 +200,51 @@ int rhi_update_vdev_interface_report_cache(struct pci_= dev *pdev) =20 return ret; } + +static inline int rhi_vdev_get_measurements(unsigned long vdev_id, + phys_addr_t vdev_meas_phys, + unsigned long *cookie) +{ + unsigned long ret; + + struct rsi_host_call *rhi_call __free(kfree) =3D + kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhi_call) + return -ENOMEM; + + rhi_call->imm =3D 0; + rhi_call->gprs[0] =3D RHI_DA_VDEV_GET_MEASUREMENTS; + rhi_call->gprs[1] =3D vdev_id; + rhi_call->gprs[2] =3D vdev_meas_phys; + + ret =3D rsi_host_call(virt_to_phys(rhi_call)); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + *cookie =3D rhi_call->gprs[1]; + return map_rhi_da_error(rhi_call->gprs[0]); +} + +int rhi_update_vdev_measurements_cache(struct pci_dev *pdev, + struct rhi_vdev_measurement_params *params) +{ + int ret; + unsigned long cookie; + int vdev_id =3D rsi_vdev_id(pdev); + phys_addr_t vdev_meas_phys =3D virt_to_phys(params); + + for (;;) { + ret =3D rhi_vdev_get_measurements(vdev_id, vdev_meas_phys, &cookie); + if (ret !=3D -EBUSY) + break; + cond_resched(); + } + + while (ret =3D=3D E_INCOMPLETE) { + if (should_abort_rhi_call_loop(vdev_id)) + return -EINTR; + ret =3D rhi_vdev_continue(vdev_id, cookie); + } + + return ret; +} diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.h b/drivers/virt/coco/a= rm-cca-guest/rhi-da.h index d83e61359b35..f90e0e715073 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.h @@ -12,4 +12,6 @@ struct pci_dev; bool rhi_has_da_support(void); int rhi_vdev_set_tdi_state(struct pci_dev *pdev, unsigned long target_stat= e); int rhi_update_vdev_interface_report_cache(struct pci_dev *pdev); +int rhi_update_vdev_measurements_cache(struct pci_dev *pdev, + struct rhi_vdev_measurement_params *params); #endif diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index c8ba72e4be3e..aa6e13e4c0ea 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -4,6 +4,7 @@ */ =20 #include +#include #include =20 #include "rsi-da.h" @@ -35,9 +36,50 @@ int cca_device_unlock(struct pci_dev *pdev) return 0; } =20 +struct page *alloc_shared_pages(int nid, gfp_t gfp_mask, unsigned long min= _size) +{ + int ret; + struct page *page; + /* We should normalize the size based on hypervisor page size */ + int page_order =3D get_order(min_size); + + /* Always request for zero filled pages */ + page =3D alloc_pages_node(nid, gfp_mask | __GFP_ZERO, page_order); + + if (!page) + return NULL; + + ret =3D set_memory_decrypted((unsigned long)page_address(page), + 1 << page_order); + /* + * If set_memory_decrypted() fails then we don't know what state the + * page is in, so we can't free it. Instead we leak it. + * set_memory_decrypted() will already have WARNed. + */ + if (ret) + return NULL; + + return page; +} + +int free_shared_pages(struct page *page, unsigned long min_size) +{ + int ret; + /* We should normalize the size based on hypervisor page size */ + int page_order =3D get_order(min_size); + + ret =3D set_memory_encrypted((unsigned long)page_address(page), 1 << page= _order); + /* If we fail to mark it encrypted don't free it back */ + if (!ret) + __free_pages(page, page_order); + return ret; +} + int cca_update_device_object_cache(struct pci_dev *pdev, struct cca_guest_= dsc *dsc) { int ret; + struct page *shared_pages; + struct rhi_vdev_measurement_params *dev_meas; =20 ret =3D rhi_update_vdev_interface_report_cache(pdev); if (ret) { @@ -45,5 +87,21 @@ int cca_update_device_object_cache(struct pci_dev *pdev,= struct cca_guest_dsc *d return ret; } =20 + shared_pages =3D alloc_shared_pages(NUMA_NO_NODE, GFP_KERNEL, sizeof(stru= ct rhi_vdev_measurement_params)); + if (!shared_pages) + return -ENOMEM; + + dev_meas =3D (struct rhi_vdev_measurement_params *)page_address(shared_pa= ges); + /* request for signed full transcript */ + dev_meas->flags =3D RHI_VDEV_MEASURE_SIGNED | RHI_VDEV_MEASURE_EXCHANGE; + /* request all measurement block. Set bit 254 */ + dev_meas->indices[31] =3D 0x40; + ret =3D rhi_update_vdev_measurements_cache(pdev, dev_meas); + + free_shared_pages(shared_pages, sizeof(struct rhi_vdev_measurement_params= )); + if (ret) { + pci_err(pdev, "failed to get device measurement (%d)\n", ret); + return ret; + } return 0; } diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index fd4792a50daf..3b01182924bc 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -32,5 +32,7 @@ static inline int rsi_vdev_id(struct pci_dev *pdev) int cca_device_lock(struct pci_dev *pdev); int cca_device_unlock(struct pci_dev *pdev); int cca_update_device_object_cache(struct pci_dev *pdev, struct cca_guest_= dsc *dsc); +struct page *alloc_shared_pages(int nid, gfp_t gfp_mask, unsigned long min= _size); +int free_shared_pages(struct page *page, unsigned long min_size); =20 #endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41D95335560; Mon, 17 Nov 2025 14:01:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388061; cv=none; b=tEQ1pqN2UM66PZj0k3QLffaW9knI7kvWDgGB7t9uLvgGWVKDCH8hfUiqrbYk9uTSaY9V27UDfiUlwpVJYkouT6pu63eLtQ7R48tzmVQHO4XxXIPsBZDU6z3Lh/GioIzM1NomWMpQEV5MDTBjT8lEK13zG+vfyOa8E5FSkU6bYuI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388061; c=relaxed/simple; bh=QOotzErKUJ2UaZQTjbPYpTcSWX1UPnLvI2XjpJa+XTE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZuHZ5LA65UCU9zGasWS4K+WwFFQphO31t+kA3ZRi6FDvQkwZi5Lj0RdALQRCqKAKfDqaiYrB7RlefvKFcsRDOxKWtgZ4SUE/r7hNDa7CGQtcms5PvmdOcwQE3IDTW4dUR73C60CYXj3PdaOOFZG9HfmiYkN3bLtIkiDY6+BCDjw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cFeJFKjj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cFeJFKjj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69BB9C4CEF1; Mon, 17 Nov 2025 14:00:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388060; bh=QOotzErKUJ2UaZQTjbPYpTcSWX1UPnLvI2XjpJa+XTE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cFeJFKjjC2I3ItiTyu7uG8ec2TT/gzlBySnmgzkfWN+sib6gXC9GzA3nAbxDsQjNq QNc4OqNDn7nFULZSGaoOGvUG/AGTQJx4R4a2tYFWGV5kQZ8kMTvVxfzhZYofZf+8YG OTM+vQgRKHx4WcToMLhfUKz079IQs4p1ZqVhAWnDYO7JNzehExBDjsi3299tPQ6TS4 MrqbOPE3Y8h7Cklv7WwqSsTuBmA3yeu+aR8hqbvDnoNbV6AlDnPeFOSed6MvTOSAms 9DdrJpmhneXQFlcuswhBMyucqSRg6at+p75avi728UICh0mghTxrLA++9hEikP3iDd INJdITu+3OUgw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 06/11] coco: guest: arm64: Add support for reading cached objects from host Date: Mon, 17 Nov 2025 19:30:02 +0530 Message-ID: <20251117140007.122062-7-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Teach rsi_device_start() to pull the interface report and device certificate from the host by querying size, sharing a decrypted buffer for the read, copying the payload to private memory. Also track the fetched blobs in struct cca_guest_dsc so later stages can hand them to the attestation flow. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 7 +++ drivers/virt/coco/arm-cca-guest/rhi-da.c | 80 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.h | 1 + drivers/virt/coco/arm-cca-guest/rsi-da.h | 8 +++ 4 files changed, 96 insertions(+) diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index ce2ed8a440c3..738470dfb869 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -39,6 +39,13 @@ RHI_DA_FEATURE_VDEV_SET_TDI_STATE) #define RHI_DA_FEATURES SMC_RHI_CALL(0x004B) =20 +#define RHI_DA_OBJECT_CERTIFICATE 0x1 +#define RHI_DA_OBJECT_MEASUREMENT 0x2 +#define RHI_DA_OBJECT_INTERFACE_REPORT 0x3 +#define RHI_DA_OBJECT_VCA 0x4 +#define RHI_DA_OBJECT_SIZE SMC_RHI_CALL(0x004C) +#define RHI_DA_OBJECT_READ SMC_RHI_CALL(0x004D) + #define RHI_DA_VDEV_CONTINUE SMC_RHI_CALL(0x0051) #define RHI_DA_VDEV_GET_INTERFACE_REPORT SMC_RHI_CALL(0x0052) =20 diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.c b/drivers/virt/coco/a= rm-cca-guest/rhi-da.c index aa17bb3ee562..d29aee0fca58 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.c @@ -248,3 +248,83 @@ int rhi_update_vdev_measurements_cache(struct pci_dev = *pdev, =20 return ret; } + +int rhi_read_cached_object(int vdev_id, int da_object_type, void **object,= int *object_size) +{ + int ret; + int max_data_len; + struct page *shared_pages; + void *data_buf_shared, *data_buf_private; + struct rsi_host_call *rhicall; + + rhicall =3D kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhicall) + return -ENOMEM; + + rhicall->imm =3D 0; + rhicall->gprs[0] =3D RHI_DA_OBJECT_SIZE; + rhicall->gprs[1] =3D vdev_id; + rhicall->gprs[2] =3D da_object_type; + + ret =3D rsi_host_call(virt_to_phys(rhicall)); + if (ret !=3D RSI_SUCCESS) { + ret =3D -EIO; + goto err_return; + } + + if (rhicall->gprs[0] !=3D RHI_DA_SUCCESS) { + ret =3D -EIO; + goto err_return; + } + + /* validate against the max cache object size used on host. */ + max_data_len =3D rhicall->gprs[1]; + if (max_data_len > MAX_CACHE_OBJ_SIZE || max_data_len =3D=3D 0) { + ret =3D -EIO; + goto err_return; + } + *object_size =3D max_data_len; + + data_buf_private =3D kmalloc(*object_size, GFP_KERNEL); + if (!data_buf_private) { + ret =3D -ENOMEM; + goto err_return; + } + + shared_pages =3D alloc_shared_pages(NUMA_NO_NODE, GFP_KERNEL, max_data_le= n); + if (!shared_pages) { + ret =3D -ENOMEM; + goto err_shared_alloc; + } + data_buf_shared =3D page_address(shared_pages); + + rhicall->imm =3D 0; + rhicall->gprs[0] =3D RHI_DA_OBJECT_READ; + rhicall->gprs[1] =3D vdev_id; + rhicall->gprs[2] =3D da_object_type; + rhicall->gprs[3] =3D 0; /* offset within the data buffer */ + rhicall->gprs[4] =3D max_data_len; + rhicall->gprs[5] =3D virt_to_phys(data_buf_shared); + ret =3D rsi_host_call(virt_to_phys(rhicall)); + if (ret !=3D RSI_SUCCESS || rhicall->gprs[0] !=3D RHI_DA_SUCCESS) { + ret =3D -EIO; + goto err_rhi_call; + } + + memcpy(data_buf_private, data_buf_shared, *object_size); + free_shared_pages(shared_pages, max_data_len); + + *object =3D data_buf_private; + kfree(rhicall); + return 0; + +err_rhi_call: + free_shared_pages(shared_pages, max_data_len); +err_shared_alloc: + kfree(data_buf_private); +err_return: + *object =3D NULL; + *object_size =3D 0; + kfree(rhicall); + return ret; +} diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.h b/drivers/virt/coco/a= rm-cca-guest/rhi-da.h index f90e0e715073..303d19a80cd0 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.h @@ -14,4 +14,5 @@ int rhi_vdev_set_tdi_state(struct pci_dev *pdev, unsigned= long target_state); int rhi_update_vdev_interface_report_cache(struct pci_dev *pdev); int rhi_update_vdev_measurements_cache(struct pci_dev *pdev, struct rhi_vdev_measurement_params *params); +int rhi_read_cached_object(int vdev_id, int da_object_type, void **object,= int *object_size); #endif diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 3b01182924bc..fa9cc01095da 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -10,8 +10,16 @@ #include #include =20 +#define MAX_CACHE_OBJ_SIZE SZ_16M + struct cca_guest_dsc { struct pci_tsm_devsec pci; + void *interface_report; + int interface_report_size; + void *certificate; + int certificate_size; + void *measurements; + int measurements_size; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4B5D23ABBE; Mon, 17 Nov 2025 14:01:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388068; cv=none; b=NySA+EZzATU5j0SJZy0yQSDXlEhqYZkM7RB+pVN+R/LfwM8Jg79pskjMAP/dz5kIEEHI3x4dq6AHLFDeEp63pyK3G3sLtTG/HogVGBNrh+VTCETYlpjaIVTsPXiJkhaJip3JEewzUiSVqd272hQ4rUcdXN4m1umhrK0wmnCfWzg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388068; c=relaxed/simple; bh=NqafC8oHuClp/7pmoR0NnAx7CBHhUjEvobX81XmOG+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GKK6MyMoskYTkt4ubidM5GT24Szf3GZV8UvWi2VzHwe+3wqkEVnSlhhkU8I+hvk0Gkkq3Qw7IP0AJWPUeM22kn1i+4s7EsF4d6dgWZ2OjmI0WQDSpDusKk7fWli8LKcU93uldjxMMlfkwY71vIPOSZzidIZBQl8Bll2PzPMdtAQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dNUshUP9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dNUshUP9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 481AEC19421; Mon, 17 Nov 2025 14:01:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388067; bh=NqafC8oHuClp/7pmoR0NnAx7CBHhUjEvobX81XmOG+A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dNUshUP9nFqyUINAruJLwcmBb0o11lWLiVwPToSjMhOtVaP3Ry9T+ZaMsiZncvvzK LJT561Pq8uUG22M7e0Ho3//INWwJGx7Wk6w/rBQQC+/KPk/TnpnUlIP1OE1qvA0R7u sZhqN0rHAJnzkwhCWI+b85RKcmGVCykD4O2WQVB0xxw2eqhskpHKrUffAmH87V1xkK xSKO0CcGwc1MPICIS8eOW7LUi1rSwJcJWOr53cN5tDWLYxTMESkSniggF0X/k4jVZd ByTp2c3qC4/ppuiOUkJSe+sImkeAZMmY+wDQMBpJAYa90nPhVu7F/pyi2KU0076Pi1 Bc7cELHbBy8VQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 07/11] coco: guest: arm64: Validate Realm MMIO mappings from TDISP report Date: Mon, 17 Nov 2025 19:30:03 +0530 Message-ID: <20251117140007.122062-8-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Parse the TDISP device interface report and drive the RSI RDEV_VALIDATE_MAPPING handshake for each Realm MMIO window. The new helper walks the reported ranges, rejects malformed entries, and either validates the IPA->PA mapping when the device transitions to RUN or tears it down with RIPAS updates on unlock. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 29 ++++++++ arch/arm64/include/asm/rsi_smc.h | 4 + drivers/virt/coco/arm-cca-guest/arm-cca.c | 9 +++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 91 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 24 +++++- 5 files changed, 156 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 18aa1b9efb9b..fe36dd2b96ac 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -185,4 +185,33 @@ static inline unsigned long rsi_host_call(phys_addr_t = addr) return res.a0; } =20 +static inline long +rsi_vdev_validate_mapping(unsigned long vdev_id, + phys_addr_t ipa_base, phys_addr_t ipa_top, + phys_addr_t pa_base, phys_addr_t *next_ipa, + unsigned long flags, unsigned long lock_nonce, + unsigned long meas_nonce, unsigned report_nonce) +{ + struct arm_smccc_1_2_regs res; + struct arm_smccc_1_2_regs regs =3D { + .a0 =3D SMC_RSI_VDEV_VALIDATE_MAPPING, + .a1 =3D vdev_id, + .a2 =3D ipa_base, + .a3 =3D ipa_top, + .a4 =3D pa_base, + .a5 =3D flags, + .a6 =3D lock_nonce, + .a7 =3D meas_nonce, + .a8 =3D report_nonce, + }; + + arm_smccc_1_2_invoke(®s, &res); + *next_ipa =3D res.a1; + + if (res.a2 !=3D RSI_ACCEPT) + return -EPERM; + + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 4dbd87a27d9b..26aaa97469e8 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -183,6 +183,10 @@ struct realm_config { */ #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198) =20 +#define RSI_DEV_MEM_COHERENT BIT(0) +#define RSI_DEV_MEM_LIMITED_ORDER BIT(1) +#define SMC_RSI_VDEV_VALIDATE_MAPPING SMC_RSI_FID(0x19F) + struct rsi_host_call { union { u16 imm; diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 7988ff6d4b2e..e86c3ad355f8 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -223,10 +223,19 @@ static struct pci_tsm *cca_tsm_lock(struct tsm_dev *t= sm_dev, struct pci_dev *pde =20 static void cca_tsm_unlock(struct pci_tsm *tsm) { + long ret; struct cca_guest_dsc *cca_dsc =3D to_cca_guest_dsc(tsm->pdev); =20 + /* invalidate dev mapping based on interface report */ + ret =3D cca_apply_interface_report_mappings(tsm->pdev, false); + if (ret) { + pci_err(tsm->pdev, "failed to invalidate the interface report\n"); + goto err_out; + } + cca_device_unlock(tsm->pdev); =20 +err_out: kfree(cca_dsc); } =20 diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index aa6e13e4c0ea..c70fb7dd4838 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -105,3 +105,94 @@ int cca_update_device_object_cache(struct pci_dev *pde= v, struct cca_guest_dsc *d } return 0; } + +static inline int +rsi_validate_dev_mapping(unsigned long vdev_id, phys_addr_t start_ipa, + phys_addr_t end_ipa, phys_addr_t io_pa, + unsigned long flags, unsigned long lock_nonce, + unsigned long meas_nonce, unsigned long report_nonce) +{ + unsigned long ret; + phys_addr_t next_ipa; + + while (start_ipa < end_ipa) { + ret =3D rsi_vdev_validate_mapping(vdev_id, start_ipa, end_ipa, + io_pa, &next_ipa, flags, + lock_nonce, meas_nonce, report_nonce); + if (ret || next_ipa <=3D start_ipa || next_ipa > end_ipa) + return -EINVAL; + io_pa +=3D next_ipa - start_ipa; + start_ipa =3D next_ipa; + } + return 0; +} + +static inline int rsi_invalidate_dev_mapping(phys_addr_t start_ipa, phys_a= ddr_t end_ipa) +{ + return rsi_set_memory_range(start_ipa, end_ipa, RSI_RIPAS_EMPTY, + RSI_CHANGE_DESTROYED); +} + +int cca_apply_interface_report_mappings(struct pci_dev *pdev, bool validat= e) +{ + int ret; + struct resource *r; + unsigned int range_id; + phys_addr_t mmio_start_phys; + struct pci_tdisp_mmio_range *mmio_range; + phys_addr_t ipa_start, ipa_end, bar_offset; + struct pci_tdisp_device_interface_report *interface_report; + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + + interface_report =3D (struct pci_tdisp_device_interface_report *)dsc->int= erface_report; + mmio_range =3D (struct pci_tdisp_mmio_range *)(interface_report + 1); + + + for (int i =3D 0; i < interface_report->mmio_range_count; i++, mmio_range= ++) { + + range_id =3D FIELD_GET(TSM_INTF_REPORT_MMIO_RANGE_ID, mmio_range->range_= attributes); + + if (range_id >=3D PCI_NUM_RESOURCES) { + pci_warn(pdev, "Skipping broken range [%d] #%d %d\n", + i, range_id, mmio_range->num_pages); + continue; + } + + r =3D pci_resource_n(pdev, range_id); + + if (r->end =3D=3D r->start || + resource_size(r) & ~PAGE_MASK || !mmio_range->num_pages) { + pci_warn(pdev, "Skipping broken range [%d] #%d %d pages, %llx..%llx\n", + i, range_id, mmio_range->num_pages, r->start, r->end); + continue; + } + + if (FIELD_GET(TSM_INTF_REPORT_MMIO_IS_NON_TEE, mmio_range->range_attribu= tes)) { + pci_info(pdev, "Skipping non-TEE range [%d] #%d %d pages, %llx..%llx\n", + i, range_id, mmio_range->num_pages, r->start, r->end); + continue; + } + + /* No secure interrupts, we should not find this set, ignore for now. */ + if (FIELD_GET(TSM_INTF_REPORT_MMIO_MSIX_TABLE, mmio_range->range_attribu= tes) || + FIELD_GET(TSM_INTF_REPORT_MMIO_PBA, mmio_range->range_attributes)) { + pci_info(pdev, "Skipping MSIX (%ld/%ld) range [%d] #%d %d pages, %llx..= %llx\n", + FIELD_GET(TSM_INTF_REPORT_MMIO_MSIX_TABLE, mmio_range->range_attribut= es), + FIELD_GET(TSM_INTF_REPORT_MMIO_PBA, mmio_range->range_attributes), + i, range_id, mmio_range->num_pages, r->start, r->end); + continue; + } + + /* units in 4K size*/ + mmio_start_phys =3D mmio_range->first_page << 12; + bar_offset =3D mmio_start_phys & (pci_resource_len(pdev, range_id) - 1); + ipa_start =3D r->start + bar_offset; + ipa_end =3D ipa_start + (mmio_range->num_pages << 12); + + if (!validate) + ret =3D rsi_invalidate_dev_mapping(ipa_start, ipa_end); + if (ret) + return ret; + } + return 0; +} diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index fa9cc01095da..32cf90beb55e 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -12,6 +12,28 @@ =20 #define MAX_CACHE_OBJ_SIZE SZ_16M =20 +struct pci_tdisp_device_interface_report { + u16 interface_info; + u16 reserved; + u16 msi_x_message_control; + u16 lnr_control; + u32 tph_control; + u32 mmio_range_count; +} __packed; + +struct pci_tdisp_mmio_range { + u64 first_page; + u32 num_pages; + u32 range_attributes; +} __packed; + +#define TSM_INTF_REPORT_MMIO_MSIX_TABLE BIT(0) +#define TSM_INTF_REPORT_MMIO_PBA BIT(1) +#define TSM_INTF_REPORT_MMIO_IS_NON_TEE BIT(2) +#define TSM_INTF_REPORT_MMIO_IS_UPDATABLE BIT(3) +#define TSM_INTF_REPORT_MMIO_RESERVED GENMASK(15, 4) +#define TSM_INTF_REPORT_MMIO_RANGE_ID GENMASK(31, 16) + struct cca_guest_dsc { struct pci_tsm_devsec pci; void *interface_report; @@ -42,5 +64,5 @@ int cca_device_unlock(struct pci_dev *pdev); int cca_update_device_object_cache(struct pci_dev *pdev, struct cca_guest_= dsc *dsc); struct page *alloc_shared_pages(int nid, gfp_t gfp_mask, unsigned long min= _size); int free_shared_pages(struct page *page, unsigned long min_size); - +int cca_apply_interface_report_mappings(struct pci_dev *pdev, bool validat= e); #endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D4B3336EC7; Mon, 17 Nov 2025 14:01:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388075; cv=none; b=n4tm25AuG8vdisCjQ3RwoOeEc4fHMCm+q/yB0cn95Im6LOSJplA5EZz+3/KHTPn0lr7qTGVY9BFdf/RuwXatoPzbHITgTBYvn9RxpRrmmVjJzKOqhT9pJQEhPnz33nAHXouaEJoJpWa2Kwph9Uod1DLY4nYzarHQIDh1GhJkR+E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388075; c=relaxed/simple; bh=83cGjVsHaKol+DxWoJqr/upzEHjkOyZzDL5nh2XAtIU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q/VcRfgxLOrugytyMRDJ+TeCRY8z2GURnbtEyRb2mRHw35Wm9YUldrHi6lDR5BRfEFekwrxqcdwtF1cjMkY9mvxy3j2d0imUsmnv1kDil2WhJOEjcMhiZhGrTBbzKMqBRAg/2m8qL1AbNp3xEMumVwMZ24QGSJ1c4onDy6m8xAQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KISwR/Pg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KISwR/Pg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3EE5EC4CEFB; Mon, 17 Nov 2025 14:01:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388074; bh=83cGjVsHaKol+DxWoJqr/upzEHjkOyZzDL5nh2XAtIU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KISwR/PgrPy3fHr1F7Jlawid4JIyto55j0KplUOlois4hUmlkmhYM2CzSI0v1/O/p BU5fWLTSmbkebeBxLwHREhRd+Ape6dlEvE8T5rGTFug2rM1k+852y3PktQ4ePn8+kz pUsuapk9jwd1KvFSbc97gH9woYswM8GX1X/hJeM38jAI98acVnCdCdl+GLIgFwRg9d R5aC4xRFJXSBe2dgfWkDnZSDwQGTUno7n6WqRO/vWtmVxhaxwCs64VtbN2IgL23Jdv JiwdbGbU2eZUrdD9uh9HqE2jTaBFDXj5hiWCdgSqCk70pgiqzwqb49AHqtrv26MdXk h3nfT0XINVm8Q== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 08/11] coco: guest: arm64: Add support for fetching and verifying device info Date: Mon, 17 Nov 2025 19:30:04 +0530 Message-ID: <20251117140007.122062-9-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RSI_RDEV_GET_INFO returns different digest hash values, which can be compared with host cached values to ensure the host didn't tamper with the cached data. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 11 ++ arch/arm64/include/asm/rsi_smc.h | 44 +++++++ drivers/virt/coco/arm-cca-guest/Kconfig | 2 + drivers/virt/coco/arm-cca-guest/rsi-da.c | 139 ++++++++++++++++++++++- drivers/virt/coco/arm-cca-guest/rsi-da.h | 15 +++ 5 files changed, 210 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index fe36dd2b96ac..e6d68760a729 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -214,4 +214,15 @@ rsi_vdev_validate_mapping(unsigned long vdev_id, return res.a0; } =20 +static inline unsigned long rsi_vdev_get_info(unsigned long vdev_id, + unsigned long digest_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_VDEV_GET_INFO, + vdev_id, digest_phys, &res); + + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 26aaa97469e8..49334d07dd55 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -125,6 +125,9 @@ =20 #ifndef __ASSEMBLY__ =20 +#define RSI_HASH_SHA_256 0 +#define RSI_HASH_SHA_512 1 + struct realm_config { union { struct { @@ -183,6 +186,47 @@ struct realm_config { */ #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198) =20 +struct rsi_vdevice_info { + union { + struct { + u64 flags; + u64 cert_id; + union { + u8 hash_algo; + u64 padding0; + }; + u64 lock_nonce; + u64 meas_nonce; + u64 report_nonce; + u64 tdisp_version; + union { + u8 state; + u64 padding1; + }; + + }; + u8 padding2[0x40]; + }; + union { /* 0x40 */ + struct { + u8 vca_digest[0x40]; + u8 cert_digest[0x40]; + u8 pubkey_digest[0x40]; + u8 meas_digest[0x40]; + u8 report_digest[0x40]; + }; + u8 padding3[0x200 - 0x40]; + }; +}; + +/* + * Get information for a device. + * arg1 =3D=3D Realm device identifier (vdev id) + * arg2 =3D=3D IPA to which configuration data will be written + * ret0 =3D=3D Status / error + */ +#define SMC_RSI_VDEV_GET_INFO SMC_RSI_FID(0x19D) + #define RSI_DEV_MEM_COHERENT BIT(0) #define RSI_DEV_MEM_LIMITED_ORDER BIT(1) #define SMC_RSI_VDEV_VALIDATE_MAPPING SMC_RSI_FID(0x19F) diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/ar= m-cca-guest/Kconfig index 66b2d9202b66..7407b5a464e3 100644 --- a/drivers/virt/coco/arm-cca-guest/Kconfig +++ b/drivers/virt/coco/arm-cca-guest/Kconfig @@ -5,6 +5,8 @@ config ARM_CCA_GUEST tristate "Arm CCA Guest driver" depends on ARM64 depends on PCI_TSM + select CRYPTO_LIB_SHA256 + select CRYPTO_LIB_SHA512 select TSM_REPORTS select AUXILIARY_BUS select TSM diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index c70fb7dd4838..c6b92f4ae9c5 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -6,6 +6,7 @@ #include #include #include +#include =20 #include "rsi-da.h" #include "rhi-da.h" @@ -139,10 +140,12 @@ int cca_apply_interface_report_mappings(struct pci_de= v *pdev, bool validate) struct resource *r; unsigned int range_id; phys_addr_t mmio_start_phys; + unsigned long mmio_flags =3D 0; /* non coherent, not limited order */ struct pci_tdisp_mmio_range *mmio_range; phys_addr_t ipa_start, ipa_end, bar_offset; struct pci_tdisp_device_interface_report *interface_report; struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + int vdev_id =3D rsi_vdev_id(pdev); =20 interface_report =3D (struct pci_tdisp_device_interface_report *)dsc->int= erface_report; mmio_range =3D (struct pci_tdisp_mmio_range *)(interface_report + 1); @@ -189,10 +192,144 @@ int cca_apply_interface_report_mappings(struct pci_d= ev *pdev, bool validate) ipa_start =3D r->start + bar_offset; ipa_end =3D ipa_start + (mmio_range->num_pages << 12); =20 - if (!validate) + if (validate) + ret =3D rsi_validate_dev_mapping(vdev_id, ipa_start, + ipa_end, mmio_start_phys, + mmio_flags, + dsc->dev_info.lock_nonce, + dsc->dev_info.meas_nonce, + dsc->dev_info.report_nonce); + else ret =3D rsi_invalidate_dev_mapping(ipa_start, ipa_end); if (ret) return ret; } return 0; } + +static int verify_digests(struct cca_guest_dsc *dsc) +{ + u8 digest[SHA512_DIGEST_SIZE]; + size_t digest_size; + void (*digest_func)(const u8 *data, size_t len, u8 *out); + + struct pci_dev *pdev =3D dsc->pci.base_tsm.pdev; + struct { + uint8_t *report; + size_t size; + uint8_t *digest; + } reports[] =3D { + { + dsc->interface_report, + dsc->interface_report_size, + dsc->dev_info.report_digest + }, + { + dsc->certificate, + dsc->certificate_size, + dsc->dev_info.cert_digest + }, + { + dsc->measurements, + dsc->measurements_size, + dsc->dev_info.meas_digest + } + }; + + switch (dsc->dev_info.hash_algo) { + case RSI_HASH_SHA_256: + digest_func =3D sha256; + digest_size =3D SHA256_DIGEST_SIZE; + break; + + case RSI_HASH_SHA_512: + digest_func =3D sha512; + digest_size =3D SHA512_DIGEST_SIZE; + break; + default: + pci_err(pdev, "Unknown realm hash algorithm!\n"); + return -EINVAL; + } + + for (int i =3D 0; i < ARRAY_SIZE(reports); i++) { + + digest_func(reports[i].report, reports[i].size, digest); + if (memcmp(reports[i].digest, digest, digest_size)) { + pci_err(pdev, "Invalid digest\n"); + return -EINVAL; + } + } + + pci_dbg(pdev, "Successfully verified the digests\n"); + return 0; +} + +int cca_device_verify_and_accept(struct pci_dev *pdev) +{ + int ret; + int vdev_id =3D rsi_vdev_id(pdev); + struct rsi_vdevice_info *dev_info; + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + + /* Now make a host call to copy the interface report to guest. */ + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_INTERFACE_REPORT, + &dsc->interface_report, &dsc->interface_report_size); + if (ret) { + pci_err(pdev, "failed to get interface report from the host (%d)\n", ret= ); + return ret; + } + + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_CERTIFICATE, + &dsc->certificate, &dsc->certificate_size); + if (ret) { + pci_err(pdev, "failed to get device certificate from the host (%d)\n", r= et); + return ret; + } + + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_MEASUREMENT, + &dsc->measurements, &dsc->measurements_size); + if (ret) { + pci_err(pdev, "failed to get device certificate from the host (%d)\n", r= et); + return ret; + } + + /* RMM expects sizeof(*dev_info) =3D 512 bytes aligned address */ + BUILD_BUG_ON(sizeof(*dev_info) !=3D 512); + dev_info =3D kmalloc(sizeof(*dev_info), GFP_KERNEL); + if (!dev_info) + return -ENOMEM; + + if (rsi_vdev_get_info(vdev_id, virt_to_phys(dev_info))) { + pci_err(pdev, "failed to get device digests (%d)\n", ret); + kfree(dev_info); + return -EIO; + } + + dsc->dev_info.cert_id =3D dev_info->cert_id; + dsc->dev_info.hash_algo =3D dev_info->hash_algo; + dsc->dev_info.lock_nonce =3D dev_info->lock_nonce; + dsc->dev_info.meas_nonce =3D dev_info->meas_nonce; + dsc->dev_info.report_nonce =3D dev_info->report_nonce; + memcpy(dsc->dev_info.cert_digest, dev_info->cert_digest, SHA512_DIGEST_SI= ZE); + memcpy(dsc->dev_info.meas_digest, dev_info->meas_digest, SHA512_DIGEST_SI= ZE); + memcpy(dsc->dev_info.report_digest, dev_info->report_digest, SHA512_DIGES= T_SIZE); + + kfree(dev_info); + /* + * Verify that the digests of the provided reports match with the + * digests from RMM + */ + ret =3D verify_digests(dsc); + if (ret) { + pci_err(pdev, "device digest validation failed (%d)\n", ret); + return ret; + } + + ret =3D cca_apply_interface_report_mappings(pdev, true); + if (ret) { + pci_err(pdev, "failed to validate the interface report\n"); + return -EIO; + } + + return 0; +} diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 32cf90beb55e..73d3d095ade6 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -9,6 +9,7 @@ #include #include #include +#include =20 #define MAX_CACHE_OBJ_SIZE SZ_16M =20 @@ -34,6 +35,18 @@ struct pci_tdisp_mmio_range { #define TSM_INTF_REPORT_MMIO_RESERVED GENMASK(15, 4) #define TSM_INTF_REPORT_MMIO_RANGE_ID GENMASK(31, 16) =20 +struct dsm_device_info { + u64 flags; + u64 cert_id; + u64 hash_algo; + u64 lock_nonce; + u64 meas_nonce; + u64 report_nonce; + u8 cert_digest[SHA512_DIGEST_SIZE]; + u8 meas_digest[SHA512_DIGEST_SIZE]; + u8 report_digest[SHA512_DIGEST_SIZE]; +}; + struct cca_guest_dsc { struct pci_tsm_devsec pci; void *interface_report; @@ -42,6 +55,7 @@ struct cca_guest_dsc { int certificate_size; void *measurements; int measurements_size; + struct dsm_device_info dev_info; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) @@ -65,4 +79,5 @@ int cca_update_device_object_cache(struct pci_dev *pdev, = struct cca_guest_dsc *d struct page *alloc_shared_pages(int nid, gfp_t gfp_mask, unsigned long min= _size); int free_shared_pages(struct page *page, unsigned long min_size); int cca_apply_interface_report_mappings(struct pci_dev *pdev, bool validat= e); +int cca_device_verify_and_accept(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08A9B2AEF5; Mon, 17 Nov 2025 14:01:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388082; cv=none; b=tIMCcltNnYE//ey5C3Pfp2CDwq7ld9dHbSYNLk2V6buXlQYtiFpLUIipgXkYlMXmi3qcVgm/Zhdpo0oWFJI6GoufO7H7V1nf7c6ou44KDbn27qBBzff5L8GjcCn1hGCafJmOpABl9tgJOlAB5tJJPkNGjxHPC22lIDo4kZdDjow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388082; c=relaxed/simple; bh=B5XujU80VCitHl868sDLkNEi4u6xgE/QMAq3p56uXoc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bdrk4BTymTPg4BYOh9gWnLc0z6y/3F1/+biK2LGDcxmpVWS+IqzXpzitYKy0aGEs/IA9WXf8oZAD83cTi/MdzyTyOLqIbfBqHLFCC44oRs8u5W1Yql3eFp8ygyWAYFCmL925UZCX6p2OoHy9z1akMwd2jHGBuORbGNnJWlP2TrM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BamaMTuo; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BamaMTuo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36154C19425; Mon, 17 Nov 2025 14:01:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388081; bh=B5XujU80VCitHl868sDLkNEi4u6xgE/QMAq3p56uXoc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BamaMTuo+p74Jicr+te81SqW0vwT+EFTGy26KJ6EpajI7wbZj92bFfl+afOVM7h3J ifVXt4PjD1AvT3OPbFq2MOVAn/W9H6QK66zPmS/I4ceaH6LXQjw3toAPhXow2y8I4R agw9jxW7rLE/pOoeo7QgJjQAS56HhCJoSSVdWS/v5eBt8HY/UbSPK4kNK2w2UekMGj r4yvWCUMism0V0I7WzzvnqUR6GnIPrNMzwABO6TqDe2dNw3gfDSFFfW6ZkdhpdffZE c5a62bvDobXvjWA4PJ1/RPnAdf4LBPhNYzLdglH84HTU+vNFUpxAx4uUODhid6o3g7 Em5s5eJb+xrPQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 09/11] coco: guest: arm64: Wire Realm TDISP RUN/STOP transitions into guest driver Date: Mon, 17 Nov 2025 19:30:05 +0530 Message-ID: <20251117140007.122062-10-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Teach the Arm CCA guest driver how to transition a Realm device between RUN and STOP states. The new helpers issue the RSI START/STOP calls, poll with CONTINUE until completion, and surface errors back to the TSM. The PCI TSM accept/unlock paths now invoke these helpers so writing `1` to `tsm/accept` correctly kicks off the TDISP RUN sequence and unlock tears it back down. Signed-off-by: Aneesh Kumar K.V (Arm) Reviewed-by: Jonathan Cameron --- drivers/virt/coco/arm-cca-guest/arm-cca.c | 13 +++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index e86c3ad355f8..46cc0fdefe34 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -239,9 +239,22 @@ static void cca_tsm_unlock(struct pci_tsm *tsm) kfree(cca_dsc); } =20 +static int cca_tsm_accept(struct pci_dev *pdev) +{ + int ret; + + ret =3D cca_device_verify_and_accept(pdev); + if (ret) { + pci_err(pdev, "failed to transition the device to run state (%d)\n", ret= ); + return -EIO; + } + return 0; +} + static struct pci_tsm_ops cca_devsec_pci_ops =3D { .lock =3D cca_tsm_lock, .unlock =3D cca_tsm_unlock, + .accept =3D cca_tsm_accept, }; =20 static void cca_devsec_tsm_remove(void *tsm_dev) diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index c6b92f4ae9c5..4852a03dd17d 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -331,5 +331,10 @@ int cca_device_verify_and_accept(struct pci_dev *pdev) return -EIO; } =20 + ret =3D rhi_vdev_set_tdi_state(pdev, RHI_DA_TDI_CONFIG_RUN); + if (ret) { + pci_err(pdev, "failed to switch the device (%u) to RUN state\n", ret); + return -EIO; + } return 0; } --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5066C2AEF5; Mon, 17 Nov 2025 14:01:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388089; cv=none; b=YN3bOY05RpO6sjHQBM1/JcCgjyLoPqMviAx+nFThMUXtzBlsL/Sw0Aql5LDmRFYrQsd/wMUp5E7FPt4G+dUAczmJF/xLQzDGOMx1D2kf753h5efGLXHQZVV1YR1LV7G6+ZZ0gsiOLRe5k5L4WO1TXDvCw9KvDTbvywQFKJ4/z4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388089; c=relaxed/simple; bh=25Bn9luUHaEILb28FwLfgiOYmlbDL1Rt6LCuV8FfZHQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=aJNdwqmRieGjkchnENJWTYp9fzln6GjYSEu/ZUOb57yAi77E+GpOFP32rRCnQ/M7m9pIPvy2tGxezGJeKDpg+w4YF0xr/CAq8N1AyQOqYr7ZPEf0Jj0Q8Cnretp2tm7kihu1xwH1VCtDq69haaDmXGGawdWfOoGcFFTTEGDcSA8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gvfAZuCq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gvfAZuCq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 48250C4CEFB; Mon, 17 Nov 2025 14:01:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388088; bh=25Bn9luUHaEILb28FwLfgiOYmlbDL1Rt6LCuV8FfZHQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gvfAZuCqeBlalF6IWqTv9tpoZgvmmsuX4m9OBg8dZWz1wcOCHXPJIK0IMNJFHltbi JjJwhGaAZA13niNoYjenKvHBHvmCPxwfZjgpWEP8Ro7XjVvXNvhbvhc+WCRpT2N0to tzxODcInJIHJkeqV6mh1s8zQZgd1qg6+56x+4HNHxKOaR0zCvsqfzDbF3vrqHdVPa9 jazGTMJQ7Fyjfnzd6EaoPbb1pAqwHDrvXqOSFG7yT3/cE37pndzUZ78D3ug+Y1MKNE IFyTmvcU0xmJEDE9WBGoqbp/rdWLvB5c3Srm2x6Xft4W+Q1bB2kNiicf4fTwTqwrXQ lOEI9MeQEeSqg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 10/11] coco: arm64: dma: Update force_dma_unencrypted for accepted devices Date: Mon, 17 Nov 2025 19:30:06 +0530 Message-ID: <20251117140007.122062-11-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This change updates the DMA behavior for accepted devices by assuming they access only private memory. Currently, the DMA API does not provide a mechanism for allocating shared memory that can be accessed by both the secure realm and the non-secure host. Accepted devices are therefore expected to operate entirely within the private memory space. As of now, there is no API in the DMA layer that allows such devices to explicitly request shared memory allocations for coherent data exchange with the host. If future use cases require accepted devices to interact with shared memory=E2=80=94 for example, for host-device communication, we will need to extend the DMA interface to support such allocation semantics. This commit lays the groundwork for that by clearly defining the current assumption and isolating the enforcement to force_dma_unencrypted. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/mem_encrypt.h | 6 +----- arch/arm64/mm/mem_encrypt.c | 10 ++++++++++ include/linux/swiotlb.h | 5 +++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/= mem_encrypt.h index 314b2b52025f..d77c10cd5b79 100644 --- a/arch/arm64/include/asm/mem_encrypt.h +++ b/arch/arm64/include/asm/mem_encrypt.h @@ -15,14 +15,10 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem= _crypt_ops *ops); =20 int set_memory_encrypted(unsigned long addr, int numpages); int set_memory_decrypted(unsigned long addr, int numpages); +bool force_dma_unencrypted(struct device *dev); =20 int realm_register_memory_enc_ops(void); =20 -static inline bool force_dma_unencrypted(struct device *dev) -{ - return is_realm_world(); -} - /* * For Arm CCA guests, canonical addresses are "encrypted", so no changes * required for dma_addr_encrypted(). diff --git a/arch/arm64/mm/mem_encrypt.c b/arch/arm64/mm/mem_encrypt.c index ee3c0ab04384..645c099fd551 100644 --- a/arch/arm64/mm/mem_encrypt.c +++ b/arch/arm64/mm/mem_encrypt.c @@ -17,6 +17,7 @@ #include #include #include +#include =20 #include =20 @@ -48,3 +49,12 @@ int set_memory_decrypted(unsigned long addr, int numpage= s) return crypt_ops->decrypt(addr, numpages); } EXPORT_SYMBOL_GPL(set_memory_decrypted); + +bool force_dma_unencrypted(struct device *dev) +{ + if (device_cc_accepted(dev)) + return false; + + return is_realm_world(); +} +EXPORT_SYMBOL_GPL(force_dma_unencrypted); diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 3dae0f592063..b27de03f2466 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -173,6 +173,11 @@ static inline bool is_swiotlb_force_bounce(struct devi= ce *dev) { struct io_tlb_mem *mem =3D dev->dma_io_tlb_mem; =20 + if (device_cc_accepted(dev)) { + dev_warn_once(dev, "(TIO) Disable SWIOTLB"); + return false; + } + return mem && mem->force_bounce; } =20 --=20 2.43.0 From nobody Tue Dec 2 02:52:44 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68E9A2AEF5; Mon, 17 Nov 2025 14:01:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388096; cv=none; b=cEMvGco7m8+OYNiE+ZS77Kc2G7eLSGqr2HKjF4qoENgFBIOkUj2UvQKRa4+P4iDO7YbU1KgspxKkQ/CBB+7yeU2AvalMvhmKh+7RRSG8y0jW3bfRL2ybcz/pWwdC3jR42ZjR6hBEqrdStNWokx4gBG7vlNxf2tC7bWr8DWrXMvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763388096; c=relaxed/simple; bh=jzqp5L6i6oSJSOFQ7k80/LJ+BF1WQ9a6s4hanokXhI0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CzvaGju2QWka8tReaZcUi2n5SWITCOK3XZzPg/PI3/AuhpJOFGeb6OSQVl44ZDWmHdcxgQQCdssUNpxCOadnau9+NsNZy+2q9QUH5iZpp2uGiC0woJLZ3eKVpAACtaeEWb35/ldztR4dfrwKzx/iVgh0OZZMEqadxxqtGMtqzPs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dC03GAh6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dC03GAh6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 87D1DC19424; Mon, 17 Nov 2025 14:01:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763388096; bh=jzqp5L6i6oSJSOFQ7k80/LJ+BF1WQ9a6s4hanokXhI0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dC03GAh6W5C1RFPMo5liMfGzVU17Ta6KatQ/l0ICX5l64Ettk36M76oY0HA5QxrXV PAhRg2PAOLDueI96eBHlOYnXNBQWTSrCxI9vVotB/iFfTAb9QheLVGEsK4+GHqAViB Np3Qld9FiUA+mmkcYhfk9nl3pIzDenFzZXc83uQigO22G3d6Gjlj0U2fuy8V/FF8cQ RdswForiQ2KDRZjfYzzyRzG9JQRYkJTjwhCo4UKJ99RmDH5jDTzsvHnvzjunBhMobs uuPMMUzG2I6sNZgeYp/oea/A3BLZhQQsWYaIgvnu31tzdOqI51iY4g13G01jx47XnJ MCIG3ZI4KUNbA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dan.j.williams@intel.com, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Bjorn Helgaas , Jonathan Cameron , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [PATCH v2 11/11] coco: guest: arm64: Enable vdev DMA after attestation Date: Mon, 17 Nov 2025 19:30:07 +0530 Message-ID: <20251117140007.122062-12-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251117140007.122062-1-aneesh.kumar@kernel.org> References: <20251117140007.122062-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" - define SMC_RSI_VDEV_DMA_ENABLE and add wrapper in rsi_cmds.h - invoke the new helper from the guest accept path once the device passes attestation, rolling back to TDI_LOCKED on failure Signed-off-by: Aneesh Kumar K.V (Arm) Reviewed-by: Jonathan Cameron --- arch/arm64/include/asm/rsi_cmds.h | 15 +++++++++++++++ arch/arm64/include/asm/rsi_smc.h | 2 ++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 14 ++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index e6d68760a729..bce08778c799 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -225,4 +225,19 @@ static inline unsigned long rsi_vdev_get_info(unsigned= long vdev_id, return res.a0; } =20 +static inline unsigned long __rsi_vdev_dma_enable(unsigned long vdev_id, + unsigned long non_ats_plane, + unsigned long lock_nonce, + unsigned long meas_nonce, + unsigned long report_nonce) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_VDEV_DMA_ENABLE, vdev_id, + non_ats_plane, lock_nonce, + meas_nonce, report_nonce, &res); + + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 49334d07dd55..7bfc8bc5c2ff 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -186,6 +186,8 @@ struct realm_config { */ #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198) =20 +#define SMC_RSI_VDEV_DMA_ENABLE SMC_RSI_FID(0x19C) + struct rsi_vdevice_info { union { struct { diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 4852a03dd17d..0b98f6271da6 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -264,6 +264,13 @@ static int verify_digests(struct cca_guest_dsc *dsc) return 0; } =20 +static inline int rsi_vdev_enable_dma(int vdev_id, struct dsm_device_info = *dev_info) +{ + return __rsi_vdev_dma_enable(vdev_id, 0, dev_info->lock_nonce, + dev_info->meas_nonce, dev_info->report_nonce); + +} + int cca_device_verify_and_accept(struct pci_dev *pdev) { int ret; @@ -336,5 +343,12 @@ int cca_device_verify_and_accept(struct pci_dev *pdev) pci_err(pdev, "failed to switch the device (%u) to RUN state\n", ret); return -EIO; } + + if (rsi_vdev_enable_dma(vdev_id, &dsc->dev_info)) { + rhi_vdev_set_tdi_state(pdev, RHI_DA_TDI_CONFIG_LOCKED); + pci_err(pdev, "failed to enable DMA from the device %d\n", ret); + return -EIO; + } + return 0; } --=20 2.43.0