From nobody Tue Apr 7 18:00:30 2026 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 2533D27470; Thu, 12 Mar 2026 08:05:00 +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=1773302700; cv=none; b=RSFezxUf+eFpCXflU8tQihuFsTH9/UEigQ7FbhHxRIUen1cGnsr5v5qGLZvj08fjzPCLt3f7z9OFtclOUak45OsGx7/kvuURn7tlnhd05PmZ9f48Ct6VDTrtJuQT2Wbj24Ha6iQMXnwHR+/HZCGgVoFnjMBIduAffiHB1KIHMZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302700; c=relaxed/simple; bh=4+Yt465AqY2sihQ6fJfZxhUEPLtuJ1924Wwm1dlVPZc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B0Z5O/3fqM9ri+A7B8B0NlP4ztc3SVQktVgQmf+fmHmAqEzdh+kezCTqEIOvv1zl6sOboeCJYrrYUpsa6ixpnNgZnD7PUF3BXIJd8ngLh9HTot/HYjYcD0/e5ErAUOn7WldjXEpcrgju54Nw7cSSm7tIQTN9k8Cprfo5+OaCVbE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZluGMJ/e; 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="ZluGMJ/e" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 13D0EC116C6; Thu, 12 Mar 2026 08:04:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302700; bh=4+Yt465AqY2sihQ6fJfZxhUEPLtuJ1924Wwm1dlVPZc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZluGMJ/eB0Wc6xy0Q4YVyYkMfV0SRh+vNAbCrZbSFLsmwgfb6+wC78RJfzt/NAktY WI3nbcBcwdGPPzVoPqSp/f6KYOqzCoYt8e9GfflF0izfGBujwaedt/ejKFZyq+Wwbu ac98bip93+AaQNdS4YsL99C6y0Y1gwIZnNCSOksDkLe3Ppj8lTkpSnp058PhRWUKGl fhutU7T8PCrgQg/PE0PY3yeKNmicZGZrwO/z3SCryygzbsXjMp7pN7VgYq26KpvHS8 tijnJd5Qp/WnuezlOmpzmLDjPws/tW1igJAsb1O7NRXvlStSKmYux56toP0Z1tuZ40 pG1K1AMVMpVXw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 01/11] coco: guest: arm64: Guest TSM callback and realm device lock support Date: Thu, 12 Mar 2026 13:34:32 +0530 Message-ID: <20260312080442.3485633-2-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi.h | 1 + arch/arm64/include/asm/rsi_cmds.h | 17 +++++++ arch/arm64/include/asm/rsi_smc.h | 1 + arch/arm64/kernel/rsi.c | 10 ++++ drivers/virt/coco/Makefile | 2 +- drivers/virt/coco/arm-cca-guest/Kconfig | 5 ++ drivers/virt/coco/arm-cca-guest/arm-cca.c | 60 ++++++++++++++++++++++- drivers/virt/coco/arm-cca-guest/rsi-da.h | 35 +++++++++++++ 8 files changed, 129 insertions(+), 2 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 34c8f649fe48..f5288551ae77 100644 --- a/arch/arm64/include/asm/rsi.h +++ b/arch/arm64/include/asm/rsi.h @@ -68,5 +68,6 @@ static inline int rsi_set_memory_range_shared(phys_addr_t= start, RSI_CHANGE_DESTROYED); } =20 +bool rsi_has_da_feature(void); unsigned long realm_get_hyp_pagesize(void); #endif /* __ASM_RSI_H_ */ diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index a341ce0eeda1..596bdc356f1a 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -169,4 +169,21 @@ static inline unsigned long rsi_host_call(struct rsi_h= ost_call *rhi_call) 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, u64 *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 9ee8b5c7612e..4af4638fdd49 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 29d3c20ce011..2816f31d0dc6 100644 --- a/arch/arm64/kernel/rsi.c +++ b/arch/arm64/kernel/rsi.c @@ -16,6 +16,7 @@ #include =20 static struct realm_config config; +static u64 rsi_feat_reg0; static unsigned long ipa_change_alignment =3D PAGE_SIZE; =20 unsigned long prot_ns_shared; @@ -24,6 +25,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) { @@ -159,6 +166,9 @@ void __init arm64_rsi_init(void) if (!ipa_change_alignment) return; =20 + 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 b323b0ae4f82..4f7e30f5aeb8 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -7,6 +7,6 @@ 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_INTEL_TDX_HOST) +=3D tdx-host/ -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..5f7f284dae1a 100644 --- a/drivers/virt/coco/arm-cca-guest/Kconfig +++ b/drivers/virt/coco/arm-cca-guest/Kconfig @@ -1,11 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +# + config ARM_CCA_GUEST tristate "Arm CCA Guest driver" depends on ARM64 + select PCI_TSM if PCI select TSM_REPORTS select AUXILIARY_BUS help The driver provides userspace interface to request and 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/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 3d5c0fe75500..1d78727702be 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) 2023-2025 ARM Ltd. */ =20 #include @@ -15,6 +15,10 @@ =20 #include =20 +#ifdef CONFIG_PCI_TSM +#include "rsi-da.h" +#endif + /** * struct arm_cca_token_info - a descriptor for the token buffer. * @challenge: Pointer to the challenge data @@ -192,6 +196,53 @@ static void unregister_cca_tsm_report(void *data) tsm_report_unregister(&arm_cca_tsm_report_ops); } =20 +#ifdef CONFIG_PCI_TSM +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_obj(struct cca_guest_dsc); + 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); + + /* For now always return an error */ + 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; + + tsm_dev =3D tsm_register(&adev->dev, &cca_devsec_pci_ops); + if (IS_ERR(tsm_dev)) + return PTR_ERR(tsm_dev); + + return devm_add_action_or_reset(&adev->dev, cca_devsec_tsm_remove, tsm_de= v); +} +#endif /* CONFIG_PCI_TSM */ + static int cca_devsec_tsm_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) { @@ -212,6 +263,12 @@ static int cca_devsec_tsm_probe(struct auxiliary_devic= e *adev, return ret; } =20 +#ifdef CONFIG_PCI_TSM + /* Allow tsm report even if tsm_register fails */ + if (rsi_has_da_feature()) + cca_devsec_tsm_register(adev); +#endif + 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..858bfdaf59c9 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 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); +} + +/* + * Linux use device requester id as the vdev id. + */ +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 Apr 7 18:00:30 2026 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 5B1BC2DF13E; Thu, 12 Mar 2026 08:05:03 +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=1773302703; cv=none; b=BDimxybiH8xrGtwS4RYrgvIbbvyItQBWAHfwjMB0b8gsfRsnCYXf/ituqNdBFh2FUhrnCnixwV6OYiXc6QioyoHTDQKzJ5gYEvYngyvE29DT4hGAX4SIvOgYCSKRWfnkGWavCqjUHApIg1ml7Vm7BLDhhJngQR5tlWJLuNlnB/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302703; c=relaxed/simple; bh=ozzuj0X/PtzwBrR765l0/YzAmLPg8mI7Pw/GI5p4YRg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hr2ripBrRAhURZNgpSLOXTfNyoORYCKE2cnyaNMddvMz5E3hV29PbX66p0/Z6XqhezFlLb5JhdoveaCRACKLV3Xf3gAUXhS9kCeFf9fzlKGCzO1nEjWzyZYo4C4vXncJ3WLiReQctVIW8BoaRAOtI0qz3EFkX1ulVnZ+jZA8J0I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ok9i91G3; 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="ok9i91G3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B0380C19424; Thu, 12 Mar 2026 08:05:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302703; bh=ozzuj0X/PtzwBrR765l0/YzAmLPg8mI7Pw/GI5p4YRg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ok9i91G36sGhFiu9Y4Ttdr0KMibF0qeTM7ReY6MZgkGswNfpF87TmLgC0BkoRCbOy rPVAcukPTJyOrprYh9Yyz1wnCI5CVAg22KmSBBoosNsPkXvu6ZAS3EXna0ajn5HZw7 Sih4H8AOiTBppiAnUJZB03Oa3kfEmuDn2bMlcHxq2X00vEu19KhMxc76rkXE1ZG4Ik c5Jm7JLp4xz8rmVSxTHfPqUJ5z8l/7hKLkxWUAh41qvaB72k8+ZyQbQ31WHeWRc4mG GCbkR2Fq261EkYhWPD3uLhEN5NT+Fbggq7YtXeTGVWwUxZtT9C7OQo+vKjfKHTq7Rw Uq0CMeAvqod+w== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v3 02/11] coco: guest: arm64: Fix a typo in the ARM_CCA_GUEST Kconfig help string ("and" -> "an"). Date: Thu, 12 Mar 2026 13:34:33 +0530 Message-ID: <20260312080442.3485633-3-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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" Fix a typo in Kconfig file. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/virt/coco/arm-cca-guest/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/ar= m-cca-guest/Kconfig index 5f7f284dae1a..d295146bd92a 100644 --- a/drivers/virt/coco/arm-cca-guest/Kconfig +++ b/drivers/virt/coco/arm-cca-guest/Kconfig @@ -8,7 +8,7 @@ config ARM_CCA_GUEST select TSM_REPORTS select AUXILIARY_BUS 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 --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 C4AF82DEA95; Thu, 12 Mar 2026 08:05:09 +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=1773302709; cv=none; b=Z7bqGCJfZ9e6SeAz/isFioIa2KVJK26B8FacJ+qghzTOYhF3YC0NoD603Er7uYCRPHG7dcdVJWpT4nylr5XcVcZJ1uqZBn1adWriau1Yl4v5rY5nimNIwVWFD+ZLybHHTJgWmD9PMmiFV4vCfzebaMwuJ70iRlGRPoVlcIsZLVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302709; c=relaxed/simple; bh=Cs3+6+wk9JTF3NHoik0ZLmLLLmjDdYn0+4+5JTMfico=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Z8agqI1YahYnWEGyzyUvues1L8xc8S8WbKalzy6Fb2dGEMOT44vw7rE5SatX8um++GOgGbjnzSbwDwfT17keMP8OR0oDmU4g1aIzY+pD09pQ6gGz9frPckzp48tdJOe4Kf2babswlbx/JYx8qvXeTc5ZtevFqt6qRba99meavU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ojQnlPSj; 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="ojQnlPSj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6A90C116C6; Thu, 12 Mar 2026 08:05:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302709; bh=Cs3+6+wk9JTF3NHoik0ZLmLLLmjDdYn0+4+5JTMfico=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ojQnlPSje7hrYPC2DGbrRQ8r3wIOkKXoxSHltIqp4x8d3afhjQuM8GWUQLlQKOZRx 7Geej2YXO4LcYniVSzn25L0RFp8Eh0+XWma57uWOoHuVvukTZ28AFgZch34zsJrRdl Qp082YxTuBCcBImIlEXrz9xtXbRJisqtr7P4EJhiKK2jCRoyc7DoC5/Ojqs0N2/sap rl3vz5c7C1Za10nCkTV0BxfIdKnbaMY4ZDRnjJHh0PPbdERCG4YiYT6VrRG3FM3roQ //dVbbMrwZDwmb7Qj9y06lG43NdQlSV3Xu2tCFqXrxJ26RAh6Lc6kYU5p3luIzmp0j WiL6owzLbE91A== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 03/11] coco: guest: arm64: Add Realm Host Interface and guest DA helper Date: Thu, 12 Mar 2026 13:34:34 +0530 Message-ID: <20260312080442.3485633-4-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 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. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 37 +++++ drivers/virt/coco/arm-cca-guest/Makefile | 1 + 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 ++ 5 files changed, 212 insertions(+), 1 deletion(-) 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 index 0895dd92ea1d..029ccd77cfbf 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -21,4 +21,41 @@ unsigned long rhi_get_ipa_change_alignment(void); #define __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT BIT(0) #define RHI_HOSTCONF_FEATURES SMC_RHI_CALL(0x004F) #define RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT SMC_RHI_CALL(0x0050) + +#define RHI_DA_SUCCESS 0x0 +#define RHI_DA_ERROR_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_ABORTED_OPERATION_HAD_COMPLETED 0xA + +#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) + +enum rhi_tdi_state { + RHI_DA_TDI_CONFIG_UNLOCKED, + RHI_DA_TDI_CONFIG_LOCKED, + RHI_DA_TDI_CONFIG_RUN, +}; +#define RHI_DA_VDEV_SET_TDI_STATE SMC_RHI_CALL(0x0054) +#define RHI_DA_VDEV_ABORT SMC_RHI_CALL(0x0056) + #endif diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/a= rm-cca-guest/Makefile index 75a120e24fda..65c4cc52c154 100644 --- a/drivers/virt/coco/arm-cca-guest/Makefile +++ b/drivers/virt/coco/arm-cca-guest/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest.o =20 arm-cca-guest-y +=3D arm-cca.o +arm-cca-guest-$(CONFIG_PCI_TSM) +=3D 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 1d78727702be..07f74f67d22c 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -17,6 +17,7 @@ =20 #ifdef CONFIG_PCI_TSM #include "rsi-da.h" +#include "rhi-da.h" #endif =20 /** @@ -265,7 +266,7 @@ static int cca_devsec_tsm_probe(struct auxiliary_device= *adev, =20 #ifdef CONFIG_PCI_TSM /* 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); #endif =20 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..0a04c0ec9320 --- /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) 2026 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_ERROR_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 *rhi_call __free(kfree) =3D + kmalloc(sizeof(*rhi_call), GFP_KERNEL); + if (!rhi_call) + return -ENOMEM; + + rhi_call->imm =3D 0; + rhi_call->gprs[0] =3D RHI_DA_FEATURES; + + ret =3D rsi_host_call(rhi_call); + if (ret !=3D RSI_SUCCESS || rhi_call->gprs[0] =3D=3D SMCCC_RET_NOT_SUPPOR= TED) + return false; + + /* For base DA to work we need these to be supported */ + if ((rhi_call->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(*rhi_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(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(rhi_call); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + *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, + enum rhi_tdi_state 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(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, enum rhi_tdi_state target= _state) +{ + 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..43c1cda8738d --- /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) 2026 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, enum rhi_tdi_state target= _state); +#endif --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 3090427470; Thu, 12 Mar 2026 08:05:15 +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=1773302716; cv=none; b=YzB13laBKM1nSKZPD7deFTY/gNk+8VKvyWYJphOU1GDHFRzJU3PqZWlKu9GmpbPQZKP0lopllbyYPBWIjEMTDMrYJv9tLGIPV6nm7RK+mwJuT5irN75CjILDW7svz39OA7Rv/woSrLaxR6RXTcChTuQyqGisVhSD5BDqDe6i2Hs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302716; c=relaxed/simple; bh=Zug2KbC+qKpyPQFy5aZ3Snq91MpXjqLfX4iRpg+DcFU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jCJ5qtCTbI5zUTTr5jvIGn3FCU3UReye6tGSAnCxlt++1NcxIXv9LmfEL6C12+Kt7m/PIm2OsopTKg2C0d+c1cEfZxrMTNZ9l5UcClbcF6JhVsjnbq/j/hL2gHfVj1AzY7Y8jWce/vxrlNsSUOYjqj2Xt5I2ZGtV55DJa8PevTk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tu3KriES; 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="Tu3KriES" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 57EF2C19424; Thu, 12 Mar 2026 08:05:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302715; bh=Zug2KbC+qKpyPQFy5aZ3Snq91MpXjqLfX4iRpg+DcFU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tu3KriESxpam7LaWZWZ71I3C9oSaaLmYWjY7TnTHc9tYehqRs99ZU2EVoCikCq0aY pO2hXD5lgOdZjVRXRf5ZPU9eKta2PUUbXI8LOJSCQa+Gk6aDZ7WvCERLNJ7MyBoSyu DKvU9vFp52Bc482JU9xeRs2rN3WmiYyQqFmyNVIA6rCWgfe2aowzo+BswwDLrBUA+n cp7vq6NcR5lfaIX0yy/p0UZJFG5BZ+1HYxKqwAcdyV5uK5/pRuyj7WJ2TGy7K96KW7 Hc1ZU09UGYvwfoEQ75sfGhNhvXccHeV8LTNkk/q4H5H0QOd/g+ulMt05bClOKBClHR JIXAXdiQonmUA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 04/11] coco: guest: arm64: Support guest-initiated TDI lock/unlock transitions Date: Thu, 12 Mar 2026 13:34:35 +0530 Message-ID: <20260312080442.3485633-5-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 guest helpers to drive TDI state transitions through RHI: - cca_device_lock() -> RHI_DA_TDI_CONFIG_LOCKED - cca_device_unlock() -> RHI_DA_TDI_CONFIG_UNLOCKED Use these helpers in the PCI TSM lock/unlock callbacks so a successful lock path returns a live pci_tsm handle and unlock transitions the device back to unlocked state. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price 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 | 9 ++++-- drivers/virt/coco/arm-cca-guest/rsi-da.c | 34 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 ++ 4 files changed, 44 insertions(+), 3 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 65c4cc52c154..11db7af095c9 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-$(CONFIG_PCI_TSM) +=3D rhi-da.o +arm-cca-guest-$(CONFIG_PCI_TSM) +=3D 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 07f74f67d22c..5e3a66315c70 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -211,14 +211,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 - /* For now always return an error */ - return ERR_PTR(-EIO); + ret =3D cca_device_lock(pdev); + if (ret) + return ERR_PTR(ret); + + 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..2c3017933fb0 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include +#include + +#include "rsi-da.h" +#include "rhi-da.h" + +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 (%d)\n", ret); + return ret; + } + 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 (%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 858bfdaf59c9..3619a75e160e 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -32,4 +32,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 Apr 7 18:00:30 2026 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 6E0C12DA775; Thu, 12 Mar 2026 08:05:22 +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=1773302722; cv=none; b=fP+pRdLkYYksZInJJuRQ3UwdjYeIqjz9KB2UzZX7FW2s1jr0vdV0ZiVrjw3ncpbvc528Ns+P+srUKsT5+1WBo5nMzLlA0nB8muN7aKjaqM44jbJbtwH4lGVb/gVg3NtdG4LXtR/DuofcO/v5Ku8vY9H7iAD4Ab3cH4VkAoHdb9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302722; c=relaxed/simple; bh=DkO/R9INwpiXbkUZ7Y5YuPYANwhfaZ7AaTmvxjGcFgQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eiTbMA0Yx+PsGVAbjwlIxGdtryKGauNUpv5idLucdf+rQDOBiDzw54hLCKe6SBXccxUmNXISjHfBEYt6JmpcVW6TLjXWg0/FtCCkzmeiNEynuZaAXA6bxz/cHrhpdfoqa/LDK2HAMBVPvrYtxRnbiUGYQYic3KiXlEmdFBM+fVc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j7OS/fOD; 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="j7OS/fOD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7F514C19424; Thu, 12 Mar 2026 08:05:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302722; bh=DkO/R9INwpiXbkUZ7Y5YuPYANwhfaZ7AaTmvxjGcFgQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j7OS/fOD5rRJj4PQUyc6TU63NPlqG8LagC0g8p6Q7VgXvfTSOO0b73Mtb1zr6Tail LpClAXyZevOqBY6TVbSkhmgKu6vkTIWY++E3ANvLX/p62wmMmAlVk+cgl8KNE4DdIe B40bsk56OWtwYCi7Uw6HP/K93IPbmbn22wDUpthopZLY0yIMBUk9HeatzGMiLmHCKl GJqYCMFEfPAxJweFaUfgJoaavlO9sDhb2+R55DCJaXl9b+PEpVSqx2JOWdTm1sIbP3 TexFIi8OfO2+UGT5YCSbze2EsUTq5cJsOb7yIMvApiHPj02uGmJVib6Fx6+OZR0hjP 5tMtp6+ebLEig== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 05/11] coco: guest: arm64: Refresh interface-report cache during device lock Date: Thu, 12 Mar 2026 13:34:36 +0530 Message-ID: <20260312080442.3485633-6-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 support for RHI_DA_VDEV_GET_INTERFACE_REPORT and use it to refresh the host-side cached interface report when a device is locked. Implement rhi_update_vdev_interface_report_cache() with busy retry and cookie-based CONTINUE handling for incomplete operations. Surface the flow through cca_update_device_object_cache(), and call it from the lock path so the interface report is fetched before lock succeeds. On refresh failure, unwind by unlocking the device and returning the error. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price 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 | 1 + 6 files changed, 66 insertions(+) diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index 029ccd77cfbf..076aecbce1c5 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -49,6 +49,7 @@ unsigned long rhi_get_ipa_change_alignment(void); #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(0x0053) =20 enum rhi_tdi_state { RHI_DA_TDI_CONFIG_UNLOCKED, diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 5e3a66315c70..cb9f389be8b8 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -215,6 +215,12 @@ static struct pci_tsm *cca_tsm_lock(struct tsm_dev *ts= m_dev, struct pci_dev *pde if (ret) return ERR_PTR(ret); =20 + ret =3D cca_update_device_object_cache(pdev, NULL); + if (ret) { + cca_device_unlock(pdev); + return ERR_PTR(ret); + } + 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 0a04c0ec9320..4597fb87044e 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, enum = rhi_tdi_state 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(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 43c1cda8738d..8b7faf4d1c8a 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, enum rhi_tdi_state target= _state); +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 2c3017933fb0..6c78f0e2f3a1 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -32,3 +32,16 @@ int cca_device_unlock(struct pci_dev *pdev) } return 0; } + +int cca_update_device_object_cache(struct pci_dev *pdev, const u8 *nonce) +{ + 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 3619a75e160e..9ab3408d6354 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -34,4 +34,5 @@ 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, const u8 *nonce); #endif --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 7CE342DA775; Thu, 12 Mar 2026 08:05:28 +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=1773302728; cv=none; b=dGftZ7BO/NubfjYyHqOiQcjsrvfjDdROA0/TnmNdb8bD5pqe4yi5L/t/T0wBijTPGMs/S5AOhb87sAHeN41+hD0+QntHw7SBCPsOpVpx9sAlnJpBNiFrKejiVlXPW0iYDGY1KaF+DUEIp0pmMoELAk4zjfABm43Xzcz09Qbu0kk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302728; c=relaxed/simple; bh=XIr4gNW1jlBalBO6JtSnGoH5HWlLWagg++XO5DPfrLM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XhdP0G2bIOMwIwqhOrTZ49q/LXi5XHOunCvD2cXmuXTf5/Li9HZCu0f4Kf1T+qAZ/+xOjCyE5IYQsy9OuLWOW2ob5SKbFqU8T+muF7mdeQ9V4dFBJqPj3gf16G7W9I03RSezg0NfPw+aGKJxgWEqNjQPiYXBee+abGNwqRCGQcQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bK6wJPIN; 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="bK6wJPIN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA1DFC116C6; Thu, 12 Mar 2026 08:05:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302728; bh=XIr4gNW1jlBalBO6JtSnGoH5HWlLWagg++XO5DPfrLM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bK6wJPIN1d9E1RmWTBAFxDV+vdTWU2nAP854sgx/3f2p5deDV9XzRrt1pxQ1I4RRy +5yicdVNGiAASe1oky74ige8F69o1B7dsrPIXkylVnQCdggGsEhZVYnSdb/tzoNLKX 8wSF3MLZRcs7k9OynmIfjCphND+FycO7GmlFPTm/kAr1Bw8Ir+lLiS51J1VMhM1DnF ktdPm9PCnuCa/AESyPX7OHu+QHD1N+Yrm8LgcCyF/nsdxh1Hmg8teGE45YHmgNtAVq LNnA9HytC0PgLxkAqUvebXzN/H00Jn3jc4qyjeVH+/1qrdBlk2Wy+oLsMYSmsZv6JC BHTjqTF61/0fA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 06/11] coco: guest: arm64: Add measurement refresh via RHI_DA_VDEV_GET_MEASUREMENTS Date: Thu, 12 Mar 2026 13:34:37 +0530 Message-ID: <20260312080442.3485633-7-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 guest support to request fresh device measurements using RHI_DA_VDEV_GET_MEASUREMENTS. Define measurement request parameters (flags + nonce), request RAW measurements, and implement cookie-based continuation for incomplete DA operations. Extend cca_update_device_object_cache() to refresh both interface report and measurements. Because RHI buffers are shared with the host, add shared-page allocation helpers that convert pages to decrypted/shared memory before use and restore them to encrypted/private state on free. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 13 ++++ drivers/virt/coco/arm-cca-guest/arm-cca.c | 1 + drivers/virt/coco/arm-cca-guest/rhi-da.c | 79 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.h | 1 + drivers/virt/coco/arm-cca-guest/rsi-da.c | 42 +++++++++++- drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 + 6 files changed, 137 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index 076aecbce1c5..d4759f410a17 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -49,6 +49,19 @@ unsigned long rhi_get_ipa_change_alignment(void); #define RHI_DA_FEATURES SMC_RHI_CALL(0x004B) =20 #define RHI_DA_VDEV_CONTINUE SMC_RHI_CALL(0x0051) +#define RHI_VDEV_MEASURE_HASH 0x0 +#define RHI_VDEV_MEASURE_RAW 0x1 +struct rhi_vdev_measurement_params { + union { + u64 flags; + u8 padding0[256]; + }; + union { + u8 nonce[32]; + u8 padding1[256]; + }; +}; +#define RHI_DA_VDEV_GET_MEASUREMENTS SMC_RHI_CALL(0x0052) #define RHI_DA_VDEV_GET_INTERFACE_REPORT SMC_RHI_CALL(0x0053) =20 enum rhi_tdi_state { diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index cb9f389be8b8..435645e97ab4 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -215,6 +215,7 @@ static struct pci_tsm *cca_tsm_lock(struct tsm_dev *tsm= _dev, struct pci_dev *pde if (ret) return ERR_PTR(ret); =20 + /* collect evidence without nonce */ ret =3D cca_update_device_object_cache(pdev, NULL); if (ret) { cca_device_unlock(pdev); diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.c b/drivers/virt/coco/a= rm-cca-guest/rhi-da.c index 4597fb87044e..5130d4911f3a 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.c @@ -200,3 +200,82 @@ 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(*rhi_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(rhi_call); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + *cookie =3D rhi_call->gprs[1]; + return map_rhi_da_error(rhi_call->gprs[0]); +} + +static inline struct rhi_vdev_measurement_params *alloc_vdev_meas_params(v= oid) +{ + struct page *pages; + + pages =3D alloc_shared_pages(NUMA_NO_NODE, GFP_KERNEL, sizeof(struct rhi_= vdev_measurement_params)); + if (!pages) + return NULL; + return page_address(pages); +} + +static inline void vdev_meas_params_free(struct rhi_vdev_measurement_param= s *params) +{ + struct page *pages =3D virt_to_page(params); + + free_shared_pages(pages, sizeof(struct rhi_vdev_measurement_params)); +} + +DEFINE_FREE(vdev_meas_params_free, struct rhi_vdev_measurement_params *, i= f (_T) vdev_meas_params_free(_T)) +int rhi_update_vdev_measurements_cache(struct pci_dev *pdev, const u8 *non= ce) +{ + int ret; + unsigned long cookie; + int vdev_id =3D rsi_vdev_id(pdev); + phys_addr_t vdev_meas_phys; + + struct rhi_vdev_measurement_params *dev_meas __free(vdev_meas_params_free= ) =3D + alloc_vdev_meas_params(); + if (!dev_meas) + return -ENOMEM; + + vdev_meas_phys =3D virt_to_phys(dev_meas); + /* request for raw bitstream */ + dev_meas->flags =3D RHI_VDEV_MEASURE_RAW; + if (nonce) + memcpy(dev_meas->nonce, nonce, 32); + + 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); + } + + if (ret) + pci_err(pdev, "failed to get device measurement (%d)\n", ret); + 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 8b7faf4d1c8a..d32ccc48c0d0 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.h @@ -12,4 +12,5 @@ struct pci_dev; bool rhi_has_da_support(void); int rhi_vdev_set_tdi_state(struct pci_dev *pdev, enum rhi_tdi_state target= _state); int rhi_update_vdev_interface_report_cache(struct pci_dev *pdev); +int rhi_update_vdev_measurements_cache(struct pci_dev *pdev, const u8 *non= ce); #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 6c78f0e2f3a1..9f9e54174813 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" @@ -33,6 +34,45 @@ 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); + + 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 size) +{ + int ret; + /* We should normalize the size based on hypervisor page size */ + int page_order =3D get_order(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) + return ret; + + __free_pages(page, page_order); + return 0; +} + int cca_update_device_object_cache(struct pci_dev *pdev, const u8 *nonce) { int ret; @@ -43,5 +83,5 @@ int cca_update_device_object_cache(struct pci_dev *pdev, = const u8 *nonce) return ret; } =20 - return 0; + return rhi_update_vdev_measurements_cache(pdev, nonce); } diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 9ab3408d6354..2e3440f7c849 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -35,4 +35,6 @@ 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, const u8 *nonce); +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); #endif --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 B808D2D949F; Thu, 12 Mar 2026 08:05:34 +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=1773302734; cv=none; b=sViF+hCiZfqgr7vDXTwUlqLGl3APHATlX5tOvDii4v26IXI1altTs2rBB89qrTM4Eb5GC2R1CMs6Q50cuYCsguTMxQ+KI3B4P/Poz9mNiwpa1UJqeOQolQTQWOe9RFvH7QNuAUEFWW2PnOkpfW/ycndnYSPEZxU3mhwY2UY4vho= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302734; c=relaxed/simple; bh=9Cr+mReEZvMBuHZp4clR6ZSndmPb9mcsBiEseyuxWms=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eNFFxV/KLzi5P4zFuKiDo9S/U6ej4Q03UxNLCZPUclSX6na10YgPyMF1DBScKYsSjW1xSU7CreU6sYx/qXkoNx0Y6yiDTans88D6tiVMh9dwP6y7+usvyXXJtbyW6MdtcvvD+f80pytzCLN/IO7qlgJOvoJjnkbA6TmH3JpcmME= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oXVxVMQx; 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="oXVxVMQx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE2A8C4AF09; Thu, 12 Mar 2026 08:05:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302734; bh=9Cr+mReEZvMBuHZp4clR6ZSndmPb9mcsBiEseyuxWms=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oXVxVMQxCduNc2I91MGGi3RycxHfo5dMp1rAlFL4MvN7T7HdF7hSXTNbKVLoa34yc ohaj5swzo08JD7nbS+V9GUo7fhlOJPbaQREt8oqAS4L/WJ1fDMXzHP0A8uBqlIT4X8 FKOM3mzWd3pazwKTW9aYRl2CDQAUDz3D6Yy0srtUOykQeBeVfXTOPRmqZhutCFxy4s 4DrZ/08ulfjsUlNYaTtM9eTezFGg7wV15bI+3DU++VxGzSYDPBTUbhy+84Lqgr5LpY gzJSnEdj2NA+A1sqCmkacGjvGnC5lkUB4dEekb//dOAqukJ26dPTbBpdNr7BafA6+S XlrKjwjzxlUlA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 07/11] coco: guest: arm64: Add guest APIs to read host-cached DA objects Date: Thu, 12 Mar 2026 13:34:38 +0530 Message-ID: <20260312080442.3485633-8-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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" Introduce guest-side helpers to read host-cached DA objects (certificate, VCA, interface report, and measurements). Add RHI_DA_OBJECT_SIZE and RHI_DA_OBJECT_READ definitions, then implement rhi_read_cached_object() that: - queries object size from host - validates size against MAX_CACHE_OBJ_SIZE - allocates a shared buffer - issues OBJECT_READ into shared memory - copies data into private memory and frees shared pages Export the helper for later evidence-collection and verification code. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 7 +++ drivers/virt/coco/arm-cca-guest/rhi-da.c | 64 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rhi-da.h | 1 + drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 + 4 files changed, 74 insertions(+) diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index d4759f410a17..8f9ea4a4bb7c 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -48,6 +48,13 @@ unsigned long rhi_get_ipa_change_alignment(void); 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_VDEV_MEASURE_HASH 0x0 #define RHI_VDEV_MEASURE_RAW 0x1 diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.c b/drivers/virt/coco/a= rm-cca-guest/rhi-da.c index 5130d4911f3a..c9b05fddccb9 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.c @@ -3,6 +3,8 @@ * Copyright (C) 2026 ARM Ltd. */ =20 +#include + #include "rsi-da.h" #include "rhi-da.h" =20 @@ -279,3 +281,65 @@ int rhi_update_vdev_measurements_cache(struct pci_dev = *pdev, const u8 *nonce) return ret; } =20 +int rhi_read_cached_object(int vdev_id, int da_object_type, void **object,= int *object_size) +{ + int ret; + int max_data_len; + void *data_buf_shared; + struct page *shared_pages; + + *object_size =3D 0; + *object =3D NULL; + + struct rsi_host_call *rhicall __free(kfree) =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(rhicall); + if (ret !=3D RSI_SUCCESS) + return -EIO; + + if (rhicall->gprs[0] !=3D RHI_DA_SUCCESS) + return -EIO; + + /* 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) + return -EIO; + + shared_pages =3D alloc_shared_pages(NUMA_NO_NODE, GFP_KERNEL, max_data_le= n); + if (!shared_pages) + return -ENOMEM; + + 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 virt_to_phys(data_buf_shared); + rhicall->gprs[4] =3D max_data_len; + rhicall->gprs[5] =3D 0; /* offset within the data buffer */ + ret =3D rsi_host_call(rhicall); + if (ret !=3D RSI_SUCCESS || rhicall->gprs[0] !=3D RHI_DA_SUCCESS) { + free_shared_pages(shared_pages, max_data_len); + return -EIO; + } + + void *data_buf_private =3D kvmemdup(data_buf_shared, + max_data_len, GFP_KERNEL); + /* free the shared pages irrespective of error condition */ + free_shared_pages(shared_pages, max_data_len); + if (!data_buf_private) + return -ENOMEM; + + *object =3D data_buf_private; + *object_size =3D max_data_len; + return 0; +} diff --git a/drivers/virt/coco/arm-cca-guest/rhi-da.h b/drivers/virt/coco/a= rm-cca-guest/rhi-da.h index d32ccc48c0d0..f7655d7ecf18 100644 --- a/drivers/virt/coco/arm-cca-guest/rhi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rhi-da.h @@ -13,4 +13,5 @@ bool rhi_has_da_support(void); int rhi_vdev_set_tdi_state(struct pci_dev *pdev, enum rhi_tdi_state target= _state); int rhi_update_vdev_interface_report_cache(struct pci_dev *pdev); int rhi_update_vdev_measurements_cache(struct pci_dev *pdev, const u8 *non= ce); +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 2e3440f7c849..f28dc44b5cd2 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -10,6 +10,8 @@ #include #include =20 +#define MAX_CACHE_OBJ_SIZE SZ_16M + struct cca_guest_dsc { struct pci_tsm_devsec pci; }; --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 102E72E718B; Thu, 12 Mar 2026 08:05:41 +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=1773302741; cv=none; b=CHf0JUyrO1bky4rfjSSSQPHX7dBT3hBcp557SfbAqVJCjJjH6zx6WwQIZLdXdi2F2EJpcZNuU84ZRDbZud9RRdNZ30TB/4BZZSAxTPrGuiJ204Wny4A6R/h3nV3uALRsuKN2DgM//5lZJCA44g35CSMrw6DEpa0x94N/jBlhSXA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302741; c=relaxed/simple; bh=tfbfCi5u4eBMyyYZ9AUUQsGGdCvtniLQQRQTdvyONFk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=krWaFNFQp/6/U6gkn6eTPoP1e42ONd3VssatnMA6STVxRQ/4Y/1naG74/32lo89VkdIefag40LRER1aSUNGoQOpWVRaBc8RpQQawE8TtUSRb3HWEJggyOhqJ5L7F8zto6r/xuwM/K0wIV5JrLBThBKb/ARZDxt+7K4QV6JyQf30= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IjLwhhH8; 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="IjLwhhH8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3B78CC2BC9E; Thu, 12 Mar 2026 08:05:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302740; bh=tfbfCi5u4eBMyyYZ9AUUQsGGdCvtniLQQRQTdvyONFk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IjLwhhH8biZMQuPbg5D2gOTCAnHNTyKMzjQA2zeS5T3XBWZgjqB1RjY10rm62TLtr tixZtMJ4LZIskJe+tNKCgp31pdIju9Wd0hkf+2gWYQYqIs1iAtDSuTlpJxI+wDynPo TN/B1zsnLlnaDDWuD+qCQW4nDfcmD1Jw1POkeBuWerklK9+s27kC4g145vJMJGyjHB FH2k2vGHKw0BozgH190rSo48oygd22N4gSvH3TiqzRIvdCD6NONYy4P+Rbk2pcNeml V7RbDAU9wzxUKqN7qqbzLUYJsqLPf5CCaTHFOJmm/Db1q0YByj8k/qYkPt/FEJ+nnV geqAOCcbxhW1A== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 08/11] coco: guest: arm64: Verify DA evidence with RSI_VDEV_GET_INFO digests Date: Thu, 12 Mar 2026 13:34:39 +0530 Message-ID: <20260312080442.3485633-9-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 guest-side evidence verification based on RSI_VDEV_GET_INFO and use the verified TDISP interface report to validate Realm MMIO mappings. During lock: - refresh host caches from device - read certificate/VCA/interface-report/measurement objects from host cache - fetch trusted digest metadata from RSI_VDEV_GET_INFO - verify host-provided objects against RSI digests - initialize and populate PCI TSM evidence objects - preserve lock/meas/report nonces and digests in guest state Add mapping helpers to walk MMIO entries from the TDISP report and perform RSI_VDEV_VALIDATE_MAPPING on map, or RIPAS destroy on unmap. Reject malform= ed range progress while validating. During unlock: - invalidate mappings derived from the evidence report - unlock the device and tear down MMIO bookkeeping This ensures host-cached DA objects are cryptographically verified before being trusted for mapping and attestation state transitions. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 40 +++ arch/arm64/include/asm/rsi_smc.h | 48 ++++ drivers/virt/coco/arm-cca-guest/Kconfig | 2 + drivers/virt/coco/arm-cca-guest/arm-cca.c | 287 +++++++++++++++++++++- drivers/virt/coco/arm-cca-guest/rsi-da.c | 145 +++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 22 ++ 6 files changed, 533 insertions(+), 11 deletions(-) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 596bdc356f1a..f72d8e0cd422 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -186,4 +186,44 @@ static inline unsigned long rsi_features(unsigned long= index, u64 *out) 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 long 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; +} + +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 4af4638fdd49..5f1837282237 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -125,6 +125,9 @@ =20 #ifndef __ASSEMBLER__ =20 +#define RSI_HASH_SHA_256 0 +#define RSI_HASH_SHA_512 1 + struct realm_config { union { struct { @@ -183,6 +186,51 @@ 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) + struct rsi_host_call { union { u16 imm; diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/ar= m-cca-guest/Kconfig index d295146bd92a..8ed4b95df5e4 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 select PCI_TSM if PCI + select CRYPTO_LIB_SHA256 + select CRYPTO_LIB_SHA512 select TSM_REPORTS select AUXILIARY_BUS help diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 435645e97ab4..80ee20c8a7a6 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -198,39 +198,304 @@ static void unregister_cca_tsm_report(void *data) } =20 #ifdef CONFIG_PCI_TSM + +static int __maybe_unused +cca_update_dev_measurements(struct pci_dev *pdev, const u8 *nonce) +{ + int ret; + void *measurements; + int measurements_size; + int vdev_id =3D rsi_vdev_id(pdev); + struct pci_tsm_evidence *evidence; + struct rsi_vdevice_info *dev_info; + struct pci_tsm_evidence_object *obj; + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + + /* Regenerate the measurement from the device */ + ret =3D rhi_update_vdev_measurements_cache(pdev, nonce); + if (ret) { + pci_err(pdev, "failed to update device measurements from device (%d)\n",= ret); + return ret; + } + + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_MEASUREMENT, + &measurements, &measurements_size); + if (ret) { + pci_err(pdev, "failed to get device measurements from the host (%d)\n", = ret); + return ret; + } + + dev_info =3D kmalloc(sizeof(*dev_info), GFP_KERNEL); + if (!dev_info) { + ret =3D -ENOMEM; + goto free_measurements; + } + + if (rsi_vdev_get_info(vdev_id, virt_to_phys(dev_info))) { + pci_err(pdev, "failed to get device digests (%d)\n", ret); + ret =3D -EIO; + goto free_dev_info; + } + + /* Make sure no unexpected lock/unlock operation happened from guest */ + if (dsc->dev_info.lock_nonce !=3D dev_info->lock_nonce) { + pci_err(pdev, "Unexpected lock/unlock operation from host (%d)\n", ret); + ret =3D -EIO; + goto free_dev_info; + } + + /* + * Verify that the digests of the provided reports match with the + * digests from RMM + */ + ret =3D cca_verify_digest(dev_info->hash_algo, measurements, + measurements_size, dev_info->meas_digest); + if (ret) { + pci_err(pdev, "RMM provided digest mismatch (%d)\n", ret); + goto free_dev_info; + } + + /* fill evidence details */ + evidence =3D &dsc->pci.base_tsm.evidence; + + /* Now update the evidence under lock. */ + down_write(&evidence->lock); + evidence->generation =3D dev_info->meas_nonce; + + obj =3D &evidence->obj[PCI_TSM_EVIDENCE_TYPE_MEASUREMENTS]; + if (obj->data) + kvfree(obj->data); + obj->data =3D measurements; + obj->len =3D measurements_size; + + dsc->dev_info.meas_nonce =3D dev_info->meas_nonce; + memcpy(dsc->dev_info.meas_digest, dev_info->meas_digest, SHA512_DIGEST_SI= ZE); + up_write(&evidence->lock); + + kfree(dev_info); + return 0; + +free_dev_info: + kfree(dev_info); +free_measurements: + kvfree(measurements); + return ret; +} + +static int cca_collect_dev_evidence(struct pci_dev *pdev, struct cca_guest= _dsc *dsc) +{ + int ret; + int vdev_id =3D rsi_vdev_id(pdev); + struct pci_tsm_evidence *evidence; + struct rsi_vdevice_info *dev_info; + struct pci_tsm_evidence_object *obj; + void *certificate, *vca, *interface_report, *measurements; + int certificate_size, vca_size, interface_report_size, measurements_size; + + /* Regenerate interface report and measurement from the device */ + ret =3D cca_update_device_object_cache(pdev, NULL); + if (ret) { + pci_err(pdev, "failed to update device objects from device (%d)\n", ret); + return ret; + } + + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_CERTIFICATE, + &certificate, &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_VCA, &vca, &vca_siz= e); + if (ret) { + pci_err(pdev, "failed to get device VCA from the host (%d)\n", ret); + goto free_certificate; + } + + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_INTERFACE_REPORT, + &interface_report, &interface_report_size); + if (ret) { + pci_err(pdev, "failed to get interface report from the host (%d)\n", ret= ); + goto free_vca; + } + + ret =3D rhi_read_cached_object(vdev_id, RHI_DA_OBJECT_MEASUREMENT, + &measurements, &measurements_size); + if (ret) { + pci_err(pdev, "failed to get device certificate from the host (%d)\n", r= et); + goto free_interface_report; + } + + dev_info =3D kmalloc(sizeof(*dev_info), GFP_KERNEL); + if (!dev_info) { + ret =3D -ENOMEM; + goto free_measurements; + } + + if (rsi_vdev_get_info(vdev_id, virt_to_phys(dev_info))) { + pci_err(pdev, "failed to get device digests (%d)\n", ret); + ret =3D -EIO; + goto free_dev_info; + } + + /* Make sure no unexpected lock/unlock operation happened from guest */ + if (dsc->dev_info.lock_nonce !=3D dev_info->lock_nonce) { + pci_err(pdev, "Unexpected lock/unlock operation from host (%d)\n", ret); + ret =3D -EIO; + goto free_dev_info; + } + + /* + * Verify that the digests of the provided reports match with the + * digests from RMM + */ + ret =3D cca_verify_digests(dev_info->hash_algo, certificate, + certificate_size, vca, vca_size, + interface_report, interface_report_size, + measurements, measurements_size, dev_info); + if (ret) { + pci_err(pdev, "RMM provided digest mismatch (%d)\n", ret); + goto free_dev_info; + } + + /* fill evidence details */ + evidence =3D &dsc->pci.base_tsm.evidence; + + /* Now update the evidence under lock. */ + down_write(&evidence->lock); + evidence->generation =3D dev_info->meas_nonce; + + /* we default to slot 0 in pdev_create */ + obj =3D &evidence->obj[PCI_TSM_EVIDENCE_TYPE_CERT0]; + WARN_ON(obj->data); + obj->data =3D certificate; + obj->len =3D certificate_size; + + obj =3D &evidence->obj[PCI_TSM_EVIDENCE_TYPE_VCA]; + WARN_ON(obj->data); + obj->data =3D vca; + obj->len =3D vca_size; + + obj =3D &evidence->obj[PCI_TSM_EVIDENCE_TYPE_REPORT]; + WARN_ON(obj->data); + obj->data =3D interface_report; + obj->len =3D interface_report_size; + + obj =3D &evidence->obj[PCI_TSM_EVIDENCE_TYPE_MEASUREMENTS]; + WARN_ON(obj->data); + obj->data =3D measurements; + obj->len =3D measurements_size; + + 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.vca_digest, dev_info->vca_digest, SHA512_DIGEST_SIZE= ); + 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); + up_write(&evidence->lock); + + kfree(dev_info); + return 0; + +free_dev_info: + kfree(dev_info); +free_measurements: + kvfree(measurements); +free_interface_report: + kvfree(interface_report); +free_vca: + kvfree(vca); +free_certificate: + kvfree(certificate); + return ret; +} + static struct pci_tsm *cca_tsm_lock(struct tsm_dev *tsm_dev, struct pci_de= v *pdev) { int ret; + enum hash_algo digest_algo; + struct cca_guest_dsc *cca_dsc; + int vdev_id =3D rsi_vdev_id(pdev); + struct rsi_vdevice_info *dev_info; =20 - struct cca_guest_dsc *cca_dsc __free(kfree) =3D - kzalloc_obj(struct cca_guest_dsc); + cca_dsc =3D kzalloc_obj(struct cca_guest_dsc); if (!cca_dsc) return ERR_PTR(-ENOMEM); =20 ret =3D pci_tsm_devsec_constructor(pdev, &cca_dsc->pci, tsm_dev); if (ret) - return ERR_PTR(ret); + goto free_cca_dsc; =20 ret =3D cca_device_lock(pdev); if (ret) - return ERR_PTR(ret); + goto free_cca_dsc; =20 - /* collect evidence without nonce */ - ret =3D cca_update_device_object_cache(pdev, NULL); - if (ret) { - cca_device_unlock(pdev); - return ERR_PTR(ret); + dev_info =3D kmalloc_obj(struct rsi_vdevice_info); + if (!dev_info) { + ret =3D -ENOMEM; + goto dev_unlock; + } + + if (rsi_vdev_get_info(vdev_id, virt_to_phys(dev_info))) { + ret =3D -EIO; + goto free_dev_info; + } + + /* collect the lock nonce */ + cca_dsc->dev_info.lock_nonce =3D dev_info->lock_nonce; + + switch (dev_info->hash_algo) { + case RSI_HASH_SHA_256: + digest_algo =3D HASH_ALGO_SHA256; + break; + case RSI_HASH_SHA_512: + digest_algo =3D HASH_ALGO_SHA512; + break; + default: + ret =3D -EIO; + goto free_dev_info; } + pci_tsm_init_evidence(&cca_dsc->pci.base_tsm.evidence, + dev_info->cert_id, digest_algo); =20 - return &no_free_ptr(cca_dsc)->pci.base_tsm; + /* collect evidence without nonce */ + ret =3D cca_collect_dev_evidence(pdev, cca_dsc); + if (ret) + goto free_dev_info; + + kfree(dev_info); + return &cca_dsc->pci.base_tsm; + +free_dev_info: + kfree(dev_info); +dev_unlock: + cca_device_unlock(pdev); +free_cca_dsc: + kfree(cca_dsc); + return ERR_PTR(ret); } =20 static void cca_tsm_unlock(struct pci_tsm *tsm) { - struct cca_guest_dsc *cca_dsc =3D to_cca_guest_dsc(tsm->pdev); + long ret; + struct pci_dev *pdev =3D tsm->pdev; + struct cca_guest_dsc *cca_dsc =3D to_cca_guest_dsc(pdev); + + /* invalidate dev mapping based on interface report */ + ret =3D cca_unmap_evidence_report_range(tsm->pdev); + if (ret) { + pci_err(tsm->pdev, "failed to invalidate the interface report\n"); + goto err_out; + } =20 cca_device_unlock(tsm->pdev); + pci_tsm_mmio_teardown(cca_dsc->pci.mmio); =20 +err_out: + /* + * No error handling from this function. Leave the device locked + */ + pci_tsm_mmio_free(tsm->pdev, cca_dsc->pci.mmio); 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 9f9e54174813..6f40329ac2f9 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" @@ -85,3 +86,147 @@ int cca_update_device_object_cache(struct pci_dev *pdev= , const u8 *nonce) =20 return rhi_update_vdev_measurements_cache(pdev, nonce); } + +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); +} + +static int cca_apply_evidence_report_range(struct pci_dev *pdev, + struct pci_tsm_mmio *mmio, bool map) +{ + int i, ret; + struct resource *res; + unsigned long mmio_flags =3D 0; /* non coherent, not limited order */ + int vdev_id =3D rsi_vdev_id(pdev); + struct pci_tsm_mmio_entry *entry; + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + + for (i =3D 0; i < mmio->nr; i++) { + entry =3D pci_tsm_mmio_entry(mmio, i); + res =3D &entry->res; + + if (res->desc !=3D IORES_DESC_ENCRYPTED) + continue; + + if (map) + ret =3D rsi_validate_dev_mapping(vdev_id, res->start, + res->end + 1, entry->tsm_offset, + mmio_flags, + dsc->dev_info.lock_nonce, + dsc->dev_info.meas_nonce, + dsc->dev_info.report_nonce); + else + ret =3D rsi_invalidate_dev_mapping(res->start, res->end + 1); + if (ret) + return ret; + } + return 0; +} + +int cca_map_evidence_report_range(struct pci_dev *pdev, struct pci_tsm_mmi= o *mmio) +{ + return cca_apply_evidence_report_range(pdev, mmio, true); +} + +int cca_unmap_evidence_report_range(struct pci_dev *pdev) +{ + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + struct pci_tsm_mmio *tsm_mmio =3D dsc->pci.mmio; + + return cca_apply_evidence_report_range(pdev, tsm_mmio, false); +} + +int cca_verify_digest(u64 hash_algo, uint8_t *report, + size_t report_size, uint8_t *report_digest) +{ + u8 digest[SHA512_DIGEST_SIZE]; + size_t digest_size; + void (*digest_func)(const u8 *data, size_t len, u8 *out); + + switch (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: + return -EINVAL; + } + + digest_func(report, report_size, digest); + if (memcmp(report_digest, digest, digest_size)) + return -EINVAL; + + return 0; +} + +int cca_verify_digests(u64 hash_algo, + uint8_t *certificate, size_t certificate_size, + uint8_t *vca, size_t vca_size, + uint8_t *interface_report, size_t interface_report_size, + uint8_t *measurements, size_t measurements_size, + struct rsi_vdevice_info *dev_info) +{ + int ret; + struct { + uint8_t *report; + size_t size; + uint8_t *digest; + } reports[] =3D { + { + certificate, + certificate_size, + dev_info->cert_digest + }, + { + vca, + vca_size, + dev_info->vca_digest + }, + { + interface_report, + interface_report_size, + dev_info->report_digest + }, + { + measurements, + measurements_size, + dev_info->meas_digest + } + + }; + + for (int i =3D 0; i < ARRAY_SIZE(reports); i++) { + ret =3D cca_verify_digest(hash_algo, reports[i].report, + reports[i].size, reports[i].digest); + 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 f28dc44b5cd2..4903a770412e 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -9,11 +9,23 @@ #include #include #include +#include =20 #define MAX_CACHE_OBJ_SIZE SZ_16M =20 +struct dsm_device_info { + u64 lock_nonce; + u64 meas_nonce; + u64 report_nonce; + u8 cert_digest[SHA512_DIGEST_SIZE]; + u8 vca_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; + struct dsm_device_info dev_info; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) @@ -39,4 +51,14 @@ int cca_device_unlock(struct pci_dev *pdev); int cca_update_device_object_cache(struct pci_dev *pdev, const u8 *nonce); 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_map_evidence_report_range(struct pci_dev *pdev, struct pci_tsm_mmi= o *mmio); +int cca_unmap_evidence_report_range(struct pci_dev *pdev); +int cca_verify_digest(u64 hash_algo, uint8_t *report, + size_t report_size, uint8_t *report_digest); +int cca_verify_digests(u64 hash_algo, + uint8_t *certificate, size_t certificate_size, + uint8_t *vca, size_t vca_size, + uint8_t *interface_report, size_t interface_report_size, + uint8_t *measurements, size_t measurements_size, + struct rsi_vdevice_info *dev_info); #endif --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 CB6512D949F; Thu, 12 Mar 2026 08:05:47 +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=1773302747; cv=none; b=PtYqXd9a+8UCAUpWK/WqHjFns8oYUVtUYgCxQbi6/SDWjY0OBCBw5FAVzzZWTaiUe1PHNpc+xsN03w0dolFOyE8Ar6MHsMQ1nv8FwOkpA4LdUjhTT2MjDHoN3c0CBcDMIK0ZQuH7xdPnBwyNYAkuyFoVctjjmtQcMFgydJlx3hg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302747; c=relaxed/simple; bh=AFb8qJO3yWFdMCBJS62LAGaVA5aASPEzQ42qXitN/5U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X67xGHyRyB7Dj9DldqaCrfmfX9skaNPpvATWqZ0m7nxUGlZElx+04cFTqLP23Plfq3wntUTQFET9S7Tst83txZ//fMtgbzVrno9nUizDaf9VVcJlwANh0ahHinuLxOAjbcZUe9CU+1poT8Uiy9D1tNmATAG7SbRwh5wk3/DofXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MsiNiQ2A; 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="MsiNiQ2A" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C3A51C2BC87; Thu, 12 Mar 2026 08:05:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302747; bh=AFb8qJO3yWFdMCBJS62LAGaVA5aASPEzQ42qXitN/5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MsiNiQ2A1lQ/hM/cQN23aHdmLk1FOoDo9pAPQ+2JqE5rwwY0qASoqRpx8WO5Pj2fx eOoB1LM28zq0L9qyeulid+8ckcJ5WMv6SlVbheaDya78YpTox3dYsSgO/F85RhsGO4 mOM7+DKWURuImM2jjaixR6sF5MIL71VTxR5SrR2oWTLcr/qOq7jrsBnp3jDJeFSlE8 MccIBHoZDP+7YZByHFlMAS42qTmJy0cyC8hS+IHEoc3BzrmWQsMOJHaJjjJPwhElWe oxfzH8Z3yYvo15kWhgfqBhaYD/BaN5dsJzQwe95UfFVuQUPGRX3cimhs/kAhINTwLw 0RD12oON2gDeQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price , Jonathan Cameron Subject: [RFC PATCH v3 09/11] coco: guest: arm64: Hook TSM accept to Realm TDISP RUN transition Date: Thu, 12 Mar 2026 13:34:40 +0530 Message-ID: <20260312080442.3485633-10-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 an accept callback in pci_tsm_ops and implement cca_device_accept() to: - verify evidence generation (lock_nonce) - allocate and register protected MMIO ranges - transition TDI state to RUN Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Reviewed-by: Jonathan Cameron Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/virt/coco/arm-cca-guest/arm-cca.c | 20 +++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 43 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 1 + 3 files changed, 64 insertions(+) diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 80ee20c8a7a6..84152f505b10 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -499,9 +499,29 @@ static void cca_tsm_unlock(struct pci_tsm *tsm) kfree(cca_dsc); } =20 +static int __cca_tsm_accept(struct pci_dev *pdev, unsigned long lock_nonce) +{ + int ret; + + ret =3D cca_device_accept(pdev, lock_nonce); + if (ret) { + pci_err(pdev, "failed to transition the device to run state (%d)\n", ret= ); + return ret; + } + return 0; +} + +static int cca_tsm_accept(struct pci_dev *pdev) +{ + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + + return __cca_tsm_accept(pdev, dsc->dev_info.lock_nonce); +} + 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 6f40329ac2f9..4030fa213ff4 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -230,3 +230,46 @@ int cca_verify_digests(u64 hash_algo, } return 0; } + +int cca_device_accept(struct pci_dev *pdev, unsigned long lock_nonce) +{ + int ret; + struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); + + if (lock_nonce !=3D dsc->dev_info.lock_nonce) { + pci_err(pdev, "Device evidence generation mismatch\n"); + return -EIO; + } + + /* Allocation private mmio range based on interface report. */ + struct pci_tsm_mmio *tsm_mmio __free(kfree) =3D pci_tsm_mmio_alloc(pdev); + if (!tsm_mmio) { + pci_err(pdev, "Protected mmio range allocation failure\n"); + return -ENOMEM; + } + + /* + * Present the private mmio range in the resource hierarchy. + * We don't use this for ioremap, ioremap check the RIPAS value. + */ + ret =3D pci_tsm_mmio_setup(pdev, tsm_mmio); + if (ret) { + pci_err(pdev, "Protected mmio setup failure\n"); + return ret; + } + + ret =3D cca_map_evidence_report_range(pdev, tsm_mmio); + if (ret) { + pci_err(pdev, "failed to validate the interface report\n"); + return ret; + } + + 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 ret; + } + + dsc->pci.mmio =3D no_free_ptr(tsm_mmio); + 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 4903a770412e..c550926145a0 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -61,4 +61,5 @@ int cca_verify_digests(u64 hash_algo, uint8_t *interface_report, size_t interface_report_size, uint8_t *measurements, size_t measurements_size, struct rsi_vdevice_info *dev_info); +int cca_device_accept(struct pci_dev *pdev, unsigned long lock_nonce); #endif --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 2F0E82EA154; Thu, 12 Mar 2026 08:05: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=1773302754; cv=none; b=KGUbrTCxxFUf4wHF9QFcQ+mBQnJdV7Iwpx0UNL4joj9crHCWCsgvkdd2E1kEZy4ZuWZoU57MH/Ofo5Rv2gXBK8b5PZbY5uKj7cD5U6rE39AHlmsFW8EFn3LusIzaW3hrGjpQScEMZDQ3rDcZZDWE+Xsbz9gAA33bVJh7xyDqW5U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302754; c=relaxed/simple; bh=0csSeUlZauiC2yr1plM5karIEhjfC8fi+r1dZY3rwSc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VEsgSY1ovies3wTcWW2aXx4n/hQOAcPpKRQuJPaOghGwf8gjJy3elcz/ZdpL7Zfi1cpM+o8m6dCH+Mglnz3/nR302q1lpgB45XYHw9qySu1/lv8rqUUMxSyy0tDqFflNZWiyAXl4sCLG+zfkc/7jgiLlmn0iHJTDhh+xnIp2JVQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JqlfWZu6; 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="JqlfWZu6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52AA6C116C6; Thu, 12 Mar 2026 08:05:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302753; bh=0csSeUlZauiC2yr1plM5karIEhjfC8fi+r1dZY3rwSc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JqlfWZu6rAXAO6dOU+A7Udf1owiqizRBdGd5Fxek3Tg01XikVLdTgHoaqxvctiRhw 1UHWSTIz7/tPg+ALJjvzgN7v3hRQX++h4R6CW6ZHnyH5UQ0l36AOhghni3/EOQde4+ dQoqDARtwAZBcPBn4jG2Thfq+m/FnJH7Xh6gAXlMHeSXo4DMR1Gki/oWw8uW+VNqcm nEOyKZybp+2hmv2MBHymY9aRpDn19IJTft1b6fNR1l37IyFMfJfDi17FL9dqw2hGdq zymbPb8uYf+MW1qrYU3Xyfs2xrtbns5mLGRCW8ajZAPFZ6cdRXiJ9J7pV5EZcRAgNi 9eGoXOQbyyGOQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price Subject: [RFC PATCH v3 10/11] coco: arm64: dma: Update force_dma_unencrypted for accepted devices Date: Thu, 12 Mar 2026 13:34:41 +0530 Message-ID: <20260312080442.3485633-11-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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. 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. Treat swiotlb and decrypted DMA pools as shared-memory paths and avoid them for accepted devices by: - returning false from is_swiotlb_for_alloc() for accepted devices - returning false from is_swiotlb_active() for accepted devices - bypassing dma-direct atomic pool usage for accepted devices This is based on the current assumption that accepted devices operate on pr= ivate Realm memory only, and prevents accidental fallback to shared/decrypted DMA backends. Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price 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 | 3 +++ kernel/dma/direct.c | 8 ++++++++ kernel/dma/swiotlb.c | 3 +++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/= mem_encrypt.h index 5541911eb028..ae0b0cac0900 100644 --- a/arch/arm64/include/asm/mem_encrypt.h +++ b/arch/arm64/include/asm/mem_encrypt.h @@ -15,17 +15,13 @@ 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 #define mem_decrypt_granule_size mem_decrypt_granule_size size_t mem_decrypt_granule_size(void); =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 f5d64bc29c20..18dea5d879b8 100644 --- a/arch/arm64/mm/mem_encrypt.c +++ b/arch/arm64/mm/mem_encrypt.c @@ -18,6 +18,7 @@ #include #include #include +#include =20 static const struct arm64_mem_crypt_ops *crypt_ops; =20 @@ -67,3 +68,12 @@ size_t mem_decrypt_granule_size(void) return PAGE_SIZE; } EXPORT_SYMBOL_GPL(mem_decrypt_granule_size); + +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 0efb9b8e5dd0..224dcec6a58f 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -296,6 +296,9 @@ bool swiotlb_free(struct device *dev, struct page *page= , size_t size); =20 static inline bool is_swiotlb_for_alloc(struct device *dev) { + if (device_cc_accepted(dev)) + return false; + return dev->dma_io_tlb_mem->for_alloc; } #else diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 34eccd047e9b..a7a9984db342 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -158,6 +158,14 @@ static struct page *__dma_direct_alloc_pages(struct de= vice *dev, size_t size, */ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp) { + /* + * Atomic pools are marked decrypted and are used if we require + * updation of pfn mem encryption attributes or for DMA non-coherent + * device allocation. Both is not true for trusted device. + */ + if (device_cc_accepted(dev)) + return false; + return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev); } =20 diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 309a8b398a7d..339147d1d42f 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -1634,6 +1634,9 @@ bool is_swiotlb_active(struct device *dev) { struct io_tlb_mem *mem =3D dev->dma_io_tlb_mem; =20 + if (device_cc_accepted(dev)) + return false; + return mem && mem->nslabs; } =20 --=20 2.43.0 From nobody Tue Apr 7 18:00:30 2026 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 183DC2D8DDB; Thu, 12 Mar 2026 08:06:00 +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=1773302761; cv=none; b=q+mgb185zCtjfMzWenQFMRgnhQRupxiJ9rKG2V0xLNRzaff6MIrOhE7c8FnPYjcGccdCcL+BGa8pJJ29SGwBAyIaaxUSheagZAw26Bj/4Rp/cD3OfKrubDHj3xVQ+3dJz52uobFec+dt5Z2txUVYCGK4h61sXx2Eqx/WMW9eUN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773302761; c=relaxed/simple; bh=GrsKvOZ6VufbBgYbhrd6xHH3pkcwgPsCkJfdzsv8h80=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S600ZwuXJLjzou02K/S4jN7dZa7lugcII3NwBYztdBL547rqcwDomVXgKipp4lJ5mLDSl/swi/8Pj05ZD5tnae2sH6AHkX5/vvNUUxVNBD14VH4o/+xdOqlaBfSP1n4eY8P35dyPItJFAAzuiHZXzMVQnPhHSL4GgTOpoMeeleE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=L+xYzgEz; 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="L+xYzgEz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7F92C4CEF7; Thu, 12 Mar 2026 08:05:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773302760; bh=GrsKvOZ6VufbBgYbhrd6xHH3pkcwgPsCkJfdzsv8h80=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L+xYzgEzmUqSoms73n0IBLxp2/AjrTR5NE6GxICk3JjchloFho4SdZODXCqLkLDt2 V/8ra8nSHv2A7KbfblknEAe8f0/tWRV9PjcGfLU6FZwZ7RfI+1M59Qvszk7qh8bv5+ RsvqPRmp+AWYmCe2BM/8G2vNbZghAF5QPRFKM2TCW/MaY4AbB6KcfDO3/GUQIcRXoV 7HzAmy+zsSBWAH3cBIOQVRfxGwBU9b3qCUt7SU944LyB1pVM7aQySy4uKxq+tr6z3k QUoTN/QeLHDxPK+w855b770kNjB8P0x1uJxsSx7rrn74HwIzTn/UwgF4GIWH8HgKTH rWL49xyQTaHww== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, "Aneesh Kumar K.V (Arm)" , Marc Zyngier , Catalin Marinas , Will Deacon , Jonathan Cameron , Jason Gunthorpe , Dan Williams , Alexey Kardashevskiy , Samuel Ortiz , Xu Yilun , Suzuki K Poulose , Steven Price , Jonathan Cameron Subject: [RFC PATCH v3 11/11] coco: guest: arm64: Enable vdev DMA after attestation Date: Thu, 12 Mar 2026 13:34:42 +0530 Message-ID: <20260312080442.3485633-12-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260312080442.3485633-1-aneesh.kumar@kernel.org> References: <20260312080442.3485633-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 Cc: Marc Zyngier Cc: Catalin Marinas Cc: Will Deacon Cc: Jonathan Cameron Cc: Jason Gunthorpe Cc: Dan Williams Cc: Alexey Kardashevskiy Cc: Samuel Ortiz Cc: Xu Yilun Cc: Suzuki K Poulose Cc: Steven Price Reviewed-by: Jonathan Cameron Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 16 ++++++++++++++++ arch/arm64/include/asm/rsi_smc.h | 2 ++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 14 ++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index f72d8e0cd422..1e0d1cd8841a 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -226,4 +226,20 @@ 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 flags, + 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, flags, + 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 5f1837282237..d2ea3656ea8f 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 4030fa213ff4..74594066f46c 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -231,9 +231,17 @@ int cca_verify_digests(u64 hash_algo, return 0; } =20 +static inline int rsi_vdev_enable_dma(int vdev_id, struct dsm_device_info = *dev_info) +{ + /* No ATS support */ + return __rsi_vdev_dma_enable(vdev_id, 0, 0, dev_info->lock_nonce, + dev_info->meas_nonce, dev_info->report_nonce); +} + int cca_device_accept(struct pci_dev *pdev, unsigned long lock_nonce) { int ret; + int vdev_id =3D rsi_vdev_id(pdev); struct cca_guest_dsc *dsc =3D to_cca_guest_dsc(pdev); =20 if (lock_nonce !=3D dsc->dev_info.lock_nonce) { @@ -270,6 +278,12 @@ int cca_device_accept(struct pci_dev *pdev, unsigned l= ong lock_nonce) return ret; } =20 + 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\n"); + return -EIO; + } + dsc->pci.mmio =3D no_free_ptr(tsm_mmio); return 0; } --=20 2.43.0