From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BFB626B743; Mon, 28 Jul 2025 13:52:43 +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=1753710764; cv=none; b=n7g72Ye8PjC+10q0/ZHzmYREVyJ1DG7i/PuG83D6cNFC+mINMj7nzufaoOtJAZ5E5QWU9FA2JHF6jTbcCf8ZspCwbFw/1cuEgmncGcCMnHWqfe9dmvfx8vjiYwO9J+Og1irojaNivBvZkd1k1+TbCXIUivWEeZ01Z6Ifyg1SiTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710764; c=relaxed/simple; bh=r9I5x3rhdwoNdyxPe37nFGR+zoeXLnHyQ8tCPsAsayQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B9KcBHGxUnWK0oKJ5g2j8PPxzcGSelrx8BSxMHE+PMt5e6cwagPFSH45Vrv1flnm9iO8QW31k76iraL9+J8leb4Xi5+RMkBZ3dpeDTWrZcVScm8IVnMtMt7ONSQ8cOgGxzppKtNAkw1On8iVTbDtlT3ZsnNMMbEnlcGlHGQp8Rg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tv2nI0qE; 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="Tv2nI0qE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43F85C4CEF7; Mon, 28 Jul 2025 13:52:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710763; bh=r9I5x3rhdwoNdyxPe37nFGR+zoeXLnHyQ8tCPsAsayQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tv2nI0qE/IofMktgF1TJRe/ckGstPmaO7cm3Cquh+AUB0qZcCTfrJ5yqe9/eRld8m 3ZKrFwX9mmQMnPnUE7eWcvIzfjb9C4zQI8NZXYpaRKLYXmdI2Qvd4GzVOXAOZVafUK 5k5rToNhHrzV34LQWswGd3X07+rxuTcSveo7Lbnz2Uv484ptb+G6z9VNkMYY14+Rb2 n4i+nPtazkHvIhkUP5m1gdDnbQ7M9v9CVZ/zLCj8Bp5dbpikOhPN2MqGigpI2R4LgP DCgy4UDbDQ9amdvcIWvGD2cUmwh0qA1CBRsY2gFcLbVifNLveHsqk9jYGnhCClnmUB y9BqQEBjGNOEA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 01/38] tsm: Add tsm_bind/unbind helpers Date: Mon, 28 Jul 2025 19:21:38 +0530 Message-ID: <20250728135216.48084-2-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" This will be later used by iommufd to bind a tdi to guest. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/virt/coco/host/tsm-core.c | 18 ++++++++++++++++++ include/linux/tsm.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drivers/virt/coco/host/tsm-core.c b/drivers/virt/coco/host/tsm= -core.c index bd9e09b07412..0a7c9aa46c56 100644 --- a/drivers/virt/coco/host/tsm-core.c +++ b/drivers/virt/coco/host/tsm-core.c @@ -116,6 +116,24 @@ void tsm_ide_stream_unregister(struct pci_ide *ide) } EXPORT_SYMBOL_GPL(tsm_ide_stream_unregister); =20 +int tsm_bind(struct device *dev, struct kvm *kvm, u64 tdi_id) +{ + if (!dev_is_pci(dev)) + return -EINVAL; + + return pci_tsm_bind(to_pci_dev(dev), kvm, tdi_id); +} +EXPORT_SYMBOL_GPL(tsm_bind); + +int tsm_unbind(struct device *dev) +{ + if (!dev_is_pci(dev)) + return -EINVAL; + + return pci_tsm_unbind(to_pci_dev(dev)); +} +EXPORT_SYMBOL_GPL(tsm_unbind); + static void tsm_release(struct device *dev) { struct tsm_core_dev *core =3D container_of(dev, typeof(*core), dev); diff --git a/include/linux/tsm.h b/include/linux/tsm.h index 915c4c8b061b..0aab8d037e71 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -118,6 +118,9 @@ struct tsm_core_dev *tsm_register(struct device *parent, void tsm_unregister(struct tsm_core_dev *tsm_core); struct pci_dev; struct pci_ide; +struct kvm; int tsm_ide_stream_register(struct pci_dev *pdev, struct pci_ide *ide); void tsm_ide_stream_unregister(struct pci_ide *ide); +int tsm_bind(struct device *dev, struct kvm *kvm, u64 tdi_id); +int tsm_unbind(struct device *dev); #endif /* __TSM_H */ --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D409B265CDD; Mon, 28 Jul 2025 13:52:49 +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=1753710770; cv=none; b=OVImODeWRvwvcx16oWzVRKXJVKz6jnRg1f+gtjQX6sUmu3/dtXWRLHH88MdA3UbgWuUs5ZfhtSBOU5RPBe7jt01oJU8l4LvUWf/sXuhQWxoQ9eZ3ocq3ktWRcyPxL8SLSN3KdC+1ttRCfZR+cZ3WPSxZ/70h6d6/LUR/tDdBukw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710770; c=relaxed/simple; bh=GcvXXx1lH7e5vihnT4eJBpV8ZfmSctEe/4HiQvmUR7M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AqU6xM9DQ12EqrdtUno/kdG+MLd0obadn8bkaid7a3r0CsJHaklMe6S+DXLTYJPDdxxCJVaNYxFlNMvyEFr+ud0L2qnCVBcZQwbZnXdK8mjTChqzoeKYrnnvXIYjIGoWJLwbEmVIqQW19SMWd+ap93Xy+WpjJLRNO04MIHRcRUw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n4nbgzXG; 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="n4nbgzXG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4DFE4C4CEE7; Mon, 28 Jul 2025 13:52:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710769; bh=GcvXXx1lH7e5vihnT4eJBpV8ZfmSctEe/4HiQvmUR7M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n4nbgzXGytKie8QjM2gZk0snFtn4Qd7ijbdfmS12NoKBMtFxsZljNEy/StsgiSFsC T83aEkES7dg6x4hTeWXhSwgPbIVMLY6wEZfTi0o/okeCOqVOu/YRm0JnEfuq8q/DA9 W+ZwNq07I5YRzou+aYWBcSYqcN+QDmd7c1Rwc1JG0tWNrPVvdmQ79nuZvMBcJfd2S4 3vKjjC6BbYQjapBd7CDM7eua8lqd96KibfD2iJcko99598DJ9TAYyrmzqzeXTlSoyy OWCljYzbhYF3XNqga9E39lbXZVOTwGLNcT6go9th6R0YPYgbo06OHemunEQKXJwBCS jGTfReMlqZoiA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 02/38] tsm: Move tsm core outside the host directory Date: Mon, 28 Jul 2025 19:21:39 +0530 Message-ID: <20250728135216.48084-3-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" A later patch will add guest changes that will also use the same infrastructure. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/virt/coco/Kconfig | 3 ++- drivers/virt/coco/Makefile | 6 ++++-- drivers/virt/coco/host/Kconfig | 6 ------ drivers/virt/coco/host/Makefile | 6 ------ drivers/virt/coco/{host =3D> }/tsm-core.c | 0 5 files changed, 6 insertions(+), 15 deletions(-) delete mode 100644 drivers/virt/coco/host/Kconfig delete mode 100644 drivers/virt/coco/host/Makefile rename drivers/virt/coco/{host =3D> }/tsm-core.c (100%) diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig index 14e7cf145d85..57248b088545 100644 --- a/drivers/virt/coco/Kconfig +++ b/drivers/virt/coco/Kconfig @@ -15,4 +15,5 @@ source "drivers/virt/coco/arm-cca-guest/Kconfig" =20 source "drivers/virt/coco/guest/Kconfig" =20 -source "drivers/virt/coco/host/Kconfig" +config TSM + tristate diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile index 73f1b7bc5b11..04e124b2d7cf 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -2,10 +2,12 @@ # # Confidential computing related collateral # + obj-$(CONFIG_EFI_SECRET) +=3D efi_secret/ obj-$(CONFIG_ARM_PKVM_GUEST) +=3D pkvm-guest/ obj-$(CONFIG_SEV_GUEST) +=3D sev-guest/ obj-$(CONFIG_INTEL_TDX_GUEST) +=3D tdx-guest/ obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ -obj-$(CONFIG_TSM_REPORTS) +=3D guest/ -obj-y +=3D host/ + +obj-$(CONFIG_TSM) +=3D tsm-core.o +obj-y +=3D guest/ diff --git a/drivers/virt/coco/host/Kconfig b/drivers/virt/coco/host/Kconfig deleted file mode 100644 index 4fbc6ef34f12..000000000000 --- a/drivers/virt/coco/host/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# TSM (TEE Security Manager) Common infrastructure and host drivers -# -config TSM - tristate diff --git a/drivers/virt/coco/host/Makefile b/drivers/virt/coco/host/Makef= ile deleted file mode 100644 index be0aba6007cd..000000000000 --- a/drivers/virt/coco/host/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# TSM (TEE Security Manager) Common infrastructure and host drivers - -obj-$(CONFIG_TSM) +=3D tsm.o -tsm-y :=3D tsm-core.o diff --git a/drivers/virt/coco/host/tsm-core.c b/drivers/virt/coco/tsm-core= .c similarity index 100% rename from drivers/virt/coco/host/tsm-core.c rename to drivers/virt/coco/tsm-core.c --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ACBDE26D4DD; Mon, 28 Jul 2025 13:52:55 +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=1753710775; cv=none; b=pic2jpjJXSu/MUo0/XeBm2ZB6JQ3oA1HTDGx8PpfTUZOqvvhNWg8WDexACnDfejEIvq6bJsWz1h1GdApWW97fxV8MyiTuzzpMcDzcE5Y6YiV8KeLkXp4xMuEsg4nku4XSFvRUt6Ds/KqMc+RyZDOMm3XRXesVRj3LnbZjz431YE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710775; c=relaxed/simple; bh=AqBuQnK0sDfshKqlYHLg/bl0U14MWqk1At9ebxulyvA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ezWuQ55tFOTBnfMNP74Caa1svAHFNCtEYbuTZHdsIOPLc2RPYaavrfO/8ke+d5DxgeEswfhak7Jh0wDiCPWTlpbKgouu6EzGSP3AQ9tPk0l+uwIXDGQfHYP51L6EVbDU5kz/+lrdwCrF7WR5q+r6YbU7uFflG695LmnRqiPvooQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KLmSmbmJ; 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="KLmSmbmJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3109FC4CEE7; Mon, 28 Jul 2025 13:52:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710775; bh=AqBuQnK0sDfshKqlYHLg/bl0U14MWqk1At9ebxulyvA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KLmSmbmJBslsBOUQm6x1VY/uQhZDigYPp6vu6f8cZnOFKdUgddBGu5LoZYiHoJ/uE VYJSjGusa7UGBn3joUWUEtUQF9W3kamKiA4oQKfVMomuw9MOxUfAyzmUwcS6Xp4JCo r3OstmDVhEs5rEkquJVjIR25JeSNDD1ij81nUF0jhpNgbxy3opqS/dRgLP364cRTcR DvDqfpSrl+511jQ8KDt56t370BxvU5TQuo4iLEgOU9b1qOgFytstpyG+N87XIVYQ4m z4g3NrRiqSjeXZEqK3gfIkYwYgyVMGBqU9WZlysh7e8VK5EvbG9yWsSWLJXX4jaAhy fbe087Qq8IA5w== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 03/38] tsm: Move dsm_dev from pci_tdi to pci_tsm Date: Mon, 28 Jul 2025 19:21:40 +0530 Message-ID: <20250728135216.48084-4-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/pci/tsm.c | 72 ++++++++++++++++++++++++----------------- include/linux/pci-tsm.h | 4 +-- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c index 794de2f258c3..e4a3b5b37939 100644 --- a/drivers/pci/tsm.c +++ b/drivers/pci/tsm.c @@ -415,15 +415,55 @@ static enum pci_tsm_type pci_tsm_type(struct pci_dev = *pdev) return PCI_TSM_INVALID; } =20 +/* lookup the Device Security Manager (DSM) pf0 for @pdev */ +static struct pci_dev *dsm_dev_get(struct pci_dev *pdev) +{ + struct pci_dev *uport_pf0; + + struct pci_dev *pf0 __free(pci_dev_put) =3D pf0_dev_get(pdev); + if (!pf0) + return NULL; + + if (pf0 =3D=3D pdev) + return no_free_ptr(pf0); + + /* Check that @pf0 was not initialized as PCI_TSM_DOWNSTREAM */ + if (pf0->tsm && pf0->tsm->type =3D=3D PCI_TSM_PF0) + return no_free_ptr(pf0); + + /* + * For cases where a switch may be hosting TDISP services on + * behalf of downstream devices, check the first usptream port + * relative to this endpoint. + */ + if (!pdev->dev.parent || !pdev->dev.parent->parent) + return NULL; + + uport_pf0 =3D to_pci_dev(pdev->dev.parent->parent); + if (!uport_pf0->tsm) + return NULL; + return pci_dev_get(uport_pf0); +} + /** * pci_tsm_initialize() - base 'struct pci_tsm' initialization * @pdev: The PCI device * @tsm: context to initialize */ -void pci_tsm_initialize(struct pci_dev *pdev, struct pci_tsm *tsm) +int pci_tsm_initialize(struct pci_dev *pdev, struct pci_tsm *tsm) { + struct pci_dev *dsm_dev __free(pci_dev_put) =3D dsm_dev_get(pdev); + if (!dsm_dev) + return -EINVAL; + tsm->type =3D pci_tsm_type(pdev); tsm->pdev =3D pdev; + /* + * No reference needed because when we destroy + * dsm_dev all the tdis get destroyed before that. + */ + tsm->dsm_dev =3D dsm_dev; + return 0; } EXPORT_SYMBOL_GPL(pci_tsm_initialize); =20 @@ -447,7 +487,8 @@ int pci_tsm_pf0_initialize(struct pci_dev *pdev, struct= pci_tsm_pf0 *tsm) } =20 tsm->state =3D PCI_TSM_INIT; - pci_tsm_initialize(pdev, &tsm->tsm); + if (pci_tsm_initialize(pdev, &tsm->tsm)) + return -ENODEV; =20 return 0; } @@ -612,32 +653,6 @@ int pci_tsm_doe_transfer(struct pci_dev *pdev, enum pc= i_doe_proto type, } EXPORT_SYMBOL_GPL(pci_tsm_doe_transfer); =20 -/* lookup the Device Security Manager (DSM) pf0 for @pdev */ -static struct pci_dev *dsm_dev_get(struct pci_dev *pdev) -{ - struct pci_dev *uport_pf0; - - struct pci_dev *pf0 __free(pci_dev_put) =3D pf0_dev_get(pdev); - if (!pf0) - return NULL; - - /* Check that @pf0 was not initialized as PCI_TSM_DOWNSTREAM */ - if (pf0->tsm && pf0->tsm->type =3D=3D PCI_TSM_PF0) - return no_free_ptr(pf0); - - /* - * For cases where a switch may be hosting TDISP services on - * behalf of downstream devices, check the first usptream port - * relative to this endpoint. - */ - if (!pdev->dev.parent || !pdev->dev.parent->parent) - return NULL; - - uport_pf0 =3D to_pci_dev(pdev->dev.parent->parent); - if (!uport_pf0->tsm) - return NULL; - return pci_dev_get(uport_pf0); -} =20 /* Only implement non-interruptible lock for now */ static struct mutex *tdi_ops_lock(struct pci_dev *pf0_dev) @@ -695,7 +710,6 @@ int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm,= u64 tdi_id) return -ENXIO; =20 tdi->pdev =3D pdev; - tdi->dsm_dev =3D dsm_dev; tdi->kvm =3D kvm; pdev->tsm->tdi =3D tdi; =20 diff --git a/include/linux/pci-tsm.h b/include/linux/pci-tsm.h index 1920ca591a42..0d4303726b25 100644 --- a/include/linux/pci-tsm.h +++ b/include/linux/pci-tsm.h @@ -38,7 +38,6 @@ enum pci_tsm_type { */ struct pci_tdi { struct pci_dev *pdev; - struct pci_dev *dsm_dev; struct kvm *kvm; }; =20 @@ -56,6 +55,7 @@ struct pci_tdi { */ struct pci_tsm { struct pci_dev *pdev; + struct pci_dev *dsm_dev; enum pci_tsm_type type; struct pci_tdi *tdi; }; @@ -173,7 +173,7 @@ void pci_tsm_core_unregister(const struct pci_tsm_ops *= ops); int pci_tsm_doe_transfer(struct pci_dev *pdev, enum pci_doe_proto type, const void *req, size_t req_sz, void *resp, size_t resp_sz); -void pci_tsm_initialize(struct pci_dev *pdev, struct pci_tsm *tsm); +int pci_tsm_initialize(struct pci_dev *pdev, struct pci_tsm *tsm); int pci_tsm_pf0_initialize(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm); int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u64 tdi_id); int pci_tsm_unbind(struct pci_dev *pdev); --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CE7DA26E706; Mon, 28 Jul 2025 13:53: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=1753710780; cv=none; b=RAMrhOjnqNUSiG11TWJcRS5Rm+dYHtTqSyz2cRTPrYaCGVBvC3K2XD6pIvvw3yT4Ely0QGkH1jNciAw9BRfotmXmntTjH5maT+RhF2oE0Tvx4vJNW5aAvoZ+8Q37H2calvtwpvrAv++sQE88BG8WG+TGfHwSXuHZz6CjcrhVbcA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710780; c=relaxed/simple; bh=crQmIBxnXL3o3APy/KQ9gWV678svZmleS6w7UUsQBYM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ihj6jD7xWgRLeDeGf8lX4YKTocyprICgNZBVAEDwy+k84j0mWOCSA3LQ/o3aXywzUTlsSgXQHAu2vteEvrj8NACCDwHW9ctr78ixlXJXSnWNiicEkFeCuLSsgqR+6C7ZwbEWk0dLDkjnlLv+kV1foikRkzXL1BuGMYhU+9BtPFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gvWNFLot; 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="gvWNFLot" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A77FFC4CEEF; Mon, 28 Jul 2025 13:52:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710780; bh=crQmIBxnXL3o3APy/KQ9gWV678svZmleS6w7UUsQBYM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gvWNFLotkMFXKc2YnfRzLBhcO6Ch2DrZp6shgUC6yA0OTdhEukyJzBbql4VQl5Tfs 5tt2LpzoJtcb7ZT/qWVxelh6+LGYKPyU6Ays4SqHlbEznEJJEgT2DKX8dWGpU0mI8j CesKY5K3Rc5dKdT9szwGJYeO+ojwd1jorT/3gylSG1wtW6JPWUelIX7IA3gupHQMRv 2wC7Xe/9XoK2MWpd669RWoVncOF09EmVuvhgBujyYWsk3WTfyGLfJxa9EvzuLreWDo hibfXaYXqgGIyThhX47foGPCNj6dQRGunRL9h1dJD3RYgNdJScJsEvYHfxiChPRQRC TB1vsPV71XjvA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 04/38] tsm: Support DMA Allocation from private memory Date: Mon, 28 Jul 2025 19:21:41 +0530 Message-ID: <20250728135216.48084-5-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Currently, we enforce the use of bounce buffers to ensure that memory accessed by non-secure devices is explicitly shared with the host [1]. However, for secure devices, this approach must be avoided. To achieve this, we introduce a device flag that controls whether a bounce buffer allocation is required for the device. Additionally, this fla= g is used to manage the top IPA bit assignment for setting up protected/unprotected IPA aliases. [1] commit fbf979a01375 ("arm64: Enforce bounce buffers for realm DMA") based on changes from Alexey Kardashevskiy Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/mem_encrypt.h | 6 +----- arch/arm64/mm/mem_encrypt.c | 10 ++++++++++ drivers/pci/tsm.c | 6 ++++++ include/linux/device.h | 1 + include/linux/swiotlb.h | 4 ++++ 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/= mem_encrypt.h index 314b2b52025f..d77c10cd5b79 100644 --- a/arch/arm64/include/asm/mem_encrypt.h +++ b/arch/arm64/include/asm/mem_encrypt.h @@ -15,14 +15,10 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem= _crypt_ops *ops); =20 int set_memory_encrypted(unsigned long addr, int numpages); int set_memory_decrypted(unsigned long addr, int numpages); +bool force_dma_unencrypted(struct device *dev); =20 int realm_register_memory_enc_ops(void); =20 -static inline bool force_dma_unencrypted(struct device *dev) -{ - return is_realm_world(); -} - /* * For Arm CCA guests, canonical addresses are "encrypted", so no changes * required for dma_addr_encrypted(). diff --git a/arch/arm64/mm/mem_encrypt.c b/arch/arm64/mm/mem_encrypt.c index ee3c0ab04384..279696a8af3f 100644 --- a/arch/arm64/mm/mem_encrypt.c +++ b/arch/arm64/mm/mem_encrypt.c @@ -17,6 +17,7 @@ #include #include #include +#include =20 #include =20 @@ -48,3 +49,12 @@ int set_memory_decrypted(unsigned long addr, int numpage= s) return crypt_ops->decrypt(addr, numpages); } EXPORT_SYMBOL_GPL(set_memory_decrypted); + +bool force_dma_unencrypted(struct device *dev) +{ + if (dev->tdi_enabled) + return false; + + return is_realm_world(); +} +EXPORT_SYMBOL_GPL(force_dma_unencrypted); diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c index e4a3b5b37939..60f50d57a725 100644 --- a/drivers/pci/tsm.c +++ b/drivers/pci/tsm.c @@ -120,6 +120,7 @@ static int pci_tsm_disconnect(struct pci_dev *pdev) =20 tsm_ops->disconnect(pdev); tsm->state =3D PCI_TSM_INIT; + pdev->dev.tdi_enabled =3D false; =20 return 0; } @@ -199,6 +200,8 @@ static int pci_tsm_accept(struct pci_dev *pdev) if (rc) return rc; tsm->state =3D PCI_TSM_ACCEPT; + pdev->dev.tdi_enabled =3D true; + return 0; } =20 @@ -557,6 +560,9 @@ static void __pci_tsm_init(struct pci_dev *pdev) default: break; } + + /* FIXME!! should this be default true and switch to false for TEE capabl= e device */ + pdev->dev.tdi_enabled =3D false; } =20 void pci_tsm_init(struct pci_dev *pdev) diff --git a/include/linux/device.h b/include/linux/device.h index 4940db137fff..d62e0dd9d8ee 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -688,6 +688,7 @@ struct device { #ifdef CONFIG_IOMMU_DMA bool dma_iommu:1; #endif + bool tdi_enabled:1; }; =20 /** diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 3dae0f592063..61e7cff7768b 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -173,6 +173,10 @@ static inline bool is_swiotlb_force_bounce(struct devi= ce *dev) { struct io_tlb_mem *mem =3D dev->dma_io_tlb_mem; =20 + if (dev->tdi_enabled) { + dev_warn_once(dev, "(TIO) Disable SWIOTLB"); + return false; + } return mem && mem->force_bounce; } =20 --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69EC526B76A; Mon, 28 Jul 2025 13:53:06 +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=1753710787; cv=none; b=uc0hgP6m40nDunHZ0y/vnbzfzOSSZh16j8vRGVlbF0KJT/2alaQEmK4ElrwkVnDt3/W+LWhLoaZECP6fQkM0IqriFghRH/TSILKVFMuhqlK9MmuPBAAAlubRypnrKFK357ymfrqmQwr2q20F+HaPYeSICA2ujWaNOO7p9SR/dzc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710787; c=relaxed/simple; bh=qgAWSBrBt4Mp1vTQmTeuVxATZ+M9negO3KdY1K96Ob0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MDKthqXIeCmHbUOojhYcIwdABfv7CvdyjDQ8Yn/2NBw9vd+I48gLvQUxw50rt7YDDBkhvMPSxbuJC29a465MzBD1YcnLjBNdroWPsQekjAy8ZPUbwu5Bx2MzeayPg88uHt//PpijueHhVp8F4k0TW/j/N70SGeTkkVrFAvXY708= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BXNWCz7C; 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="BXNWCz7C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68332C4CEEF; Mon, 28 Jul 2025 13:53:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710786; bh=qgAWSBrBt4Mp1vTQmTeuVxATZ+M9negO3KdY1K96Ob0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BXNWCz7CFPZYgExjIa82AZYmQhOEUZ1q852OU2YtUJABQiF+7Jh7UX37XV8rF8O8F XKIoOfx+GsMIfUeGcIviaWh1y2+++ZLr4IAqV3mvr0uthFUDcuRpdtCcRBtY1aF8Dw iw3+JjUAyjvVWImq06o8rasSEMM4yvYncO8rfzFiNMSptCLIS6VkZWeeW4CkSEzJmk nZCehN0US0/Wmw6CtC6j6sfylluq8r5b8EYA89dumVB9YR4c+xJlqIhU9lP6Dv1l9I gtTQy1KM21hsXEuBynfT2t4R+urk//uklIupPw+njEkPINrA7ucSYncQJvQDPGzIr5 m32p8fyo8sG0Q== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 05/38] tsm: Don't overload connect Date: Mon, 28 Jul 2025 19:21:42 +0530 Message-ID: <20250728135216.48084-6-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" We need separate handling in the guest while destroying the device. Hence switch to new callback lock and unlock. Hide the connect sysfs file in guest. guest sysfs will now looks like ls -al /sys/bus/pci/devices/0000:02:00.0/tsm/ total 0 drwxr-xr-x 2 root root 0 Jan 1 00:00 . drwxr-xr-x 7 root root 0 Jan 1 00:00 .. -rw-r--r-- 1 root root 4096 Jan 1 00:00 accept -rw-r--r-- 1 root root 4096 Jan 1 00:00 lock Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/pci/tsm.c | 136 ++++++++++++++++++++++++++++++++++------ include/linux/pci-tsm.h | 3 + 2 files changed, 121 insertions(+), 18 deletions(-) diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c index 60f50d57a725..80607082b7f0 100644 --- a/drivers/pci/tsm.c +++ b/drivers/pci/tsm.c @@ -125,18 +125,6 @@ static int pci_tsm_disconnect(struct pci_dev *pdev) return 0; } =20 -/* - * TDISP locked state temporarily makes the device inaccessible, do not - * surprise live attached drivers - */ -static int __driver_idle_connect(struct pci_dev *pdev) -{ - guard(device)(&pdev->dev); - if (pdev->dev.driver) - return -EBUSY; - return tsm_ops->connect(pdev); -} - /* * When the registered ops support accept it indicates that this is a * TVM-side (guest) TSM operations structure. In this mode ->connect() @@ -162,10 +150,7 @@ static int pci_tsm_connect(struct pci_dev *pdev) if (tsm->state >=3D PCI_TSM_CONNECT) return 0; =20 - if (tvm_mode()) - rc =3D __driver_idle_connect(pdev); - else - rc =3D tsm_ops->connect(pdev); + rc =3D tsm_ops->connect(pdev); if (rc) return rc; tsm->state =3D PCI_TSM_CONNECT; @@ -299,6 +284,99 @@ static ssize_t accept_show(struct device *dev, struct = device_attribute *attr, } static DEVICE_ATTR_RW(accept); =20 +static int pci_tsm_unlock(struct pci_dev *pdev) +{ + struct pci_tsm_pf0 *tsm =3D to_pci_tsm_pf0(pdev->tsm); + + struct mutex *lock __free(tsm_ops_unlock) =3D tsm_ops_lock(tsm); + if (!lock) + return -EINTR; + + if (tsm->state < PCI_TSM_INIT) + return -ENXIO; + if (tsm->state < PCI_TSM_LOCK) + return 0; + + tsm_ops->unlock(pdev); + tsm->state =3D PCI_TSM_INIT; + pdev->dev.tdi_enabled =3D false; + + return 0; +} + +/* + * TDISP locked state temporarily makes the device inaccessible, do not + * surprise live attached drivers + */ +static int __driver_idle_lock(struct pci_dev *pdev) +{ + guard(device)(&pdev->dev); + if (pdev->dev.driver) + return -EBUSY; + return tsm_ops->lock(pdev); +} + +static int pci_tsm_lock(struct pci_dev *pdev) +{ + struct pci_tsm_pf0 *tsm =3D to_pci_tsm_pf0(pdev->tsm); + int rc; + + struct mutex *lock __free(tsm_ops_unlock) =3D tsm_ops_lock(tsm); + if (!lock) + return -EINTR; + + if (tsm->state < PCI_TSM_INIT) + return -ENXIO; + + rc =3D __driver_idle_lock(pdev); + if (rc) + return rc; + tsm->state =3D PCI_TSM_CONNECT; + return 0; +} + +static ssize_t lock_store(struct device *dev, struct device_attribute *att= r, + const char *buf, size_t len) +{ + int rc; + bool connect; + struct pci_dev *pdev =3D to_pci_dev(dev); + + rc =3D kstrtobool(buf, &connect); + if (rc) + return rc; + + struct rw_semaphore *lock __free(tsm_read_unlock) =3D tsm_read_lock(); + if (!lock) + return -EINTR; + + if (connect) + rc =3D pci_tsm_lock(pdev); + else + rc =3D pci_tsm_unlock(pdev); + if (rc) + return rc; + return len; +} + +static ssize_t lock_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pci_dev *pdev =3D to_pci_dev(dev); + struct pci_tsm_pf0 *tsm; + + struct rw_semaphore *lock __free(tsm_read_unlock) =3D tsm_read_lock(); + if (!lock) + return -EINTR; + + if (!pdev->tsm) + return -ENXIO; + + tsm =3D to_pci_tsm_pf0(pdev->tsm); + return sysfs_emit(buf, "%d\n", tsm->state >=3D PCI_TSM_LOCK); +} +static DEVICE_ATTR_RW(lock); + static umode_t pci_tsm_pf0_attr_visible(struct kobject *kobj, struct attribute *a, int n) { @@ -306,6 +384,11 @@ static umode_t pci_tsm_pf0_attr_visible(struct kobject= *kobj, /* Host context, filter out guest only attributes */ if (a =3D=3D &dev_attr_accept.attr) return 0; + if (a =3D=3D &dev_attr_lock.attr) + return 0; + } else { + if (a =3D=3D &dev_attr_connect.attr) + return 0; } =20 return a->mode; @@ -325,6 +408,7 @@ DEFINE_SYSFS_GROUP_VISIBLE(pci_tsm_pf0); static struct attribute *pci_tsm_pf0_attrs[] =3D { &dev_attr_connect.attr, &dev_attr_accept.attr, + &dev_attr_lock.attr, NULL }; =20 @@ -537,7 +621,8 @@ static void pci_tsm_pf0_init(struct pci_dev *pdev) return; =20 pdev->tsm =3D no_free_ptr(pci_tsm); - sysfs_update_group(&pdev->dev.kobj, &pci_tsm_auth_attr_group); + if (!tvm_mode()) + sysfs_update_group(&pdev->dev.kobj, &pci_tsm_auth_attr_group); sysfs_update_group(&pdev->dev.kobj, &pci_tsm_pf0_attr_group); if (pci_tsm_owner_attr_group) sysfs_merge_group(&pdev->dev.kobj, pci_tsm_owner_attr_group); @@ -602,6 +687,19 @@ static void pci_tsm_pf0_destroy(struct pci_dev *pdev) __pci_tsm_pf0_destroy(tsm); } =20 +static void pci_tsm_guest_destroy(struct pci_dev *pdev) +{ + struct pci_tsm_pf0 *tsm =3D to_pci_tsm_pf0(pdev->tsm); + + if (tsm->state > PCI_TSM_INIT) + pci_tsm_unlock(pdev); + pdev->tsm =3D NULL; + if (pci_tsm_owner_attr_group) + sysfs_unmerge_group(&pdev->dev.kobj, pci_tsm_owner_attr_group); + sysfs_update_group(&pdev->dev.kobj, &pci_tsm_pf0_attr_group); + __pci_tsm_pf0_destroy(tsm); +} + static void __pci_tsm_destroy(struct pci_dev *pdev) { struct pci_tsm *pci_tsm =3D pdev->tsm; @@ -611,7 +709,9 @@ static void __pci_tsm_destroy(struct pci_dev *pdev) =20 lockdep_assert_held_write(&pci_tsm_rwsem); =20 - if (is_pci_tsm_pf0(pdev)) { + if (tvm_mode()) { + pci_tsm_guest_destroy(pdev); + } else if (is_pci_tsm_pf0(pdev)) { pci_tsm_pf0_destroy(pdev); } else { __pci_tsm_unbind(pdev); diff --git a/include/linux/pci-tsm.h b/include/linux/pci-tsm.h index 0d4303726b25..7639e7963681 100644 --- a/include/linux/pci-tsm.h +++ b/include/linux/pci-tsm.h @@ -11,6 +11,7 @@ enum pci_tsm_state { PCI_TSM_ERR =3D -1, PCI_TSM_INIT, PCI_TSM_CONNECT, + PCI_TSM_LOCK, PCI_TSM_ACCEPT, }; =20 @@ -153,6 +154,8 @@ struct pci_tsm_ops { void (*remove)(struct pci_tsm *tsm); int (*connect)(struct pci_dev *pdev); void (*disconnect)(struct pci_dev *pdev); + int (*lock)(struct pci_dev *pdev); + void (*unlock)(struct pci_dev *pdev); struct pci_tdi *(*bind)(struct pci_dev *pdev, struct pci_dev *pf0_dev, struct kvm *kvm, u64 tdi_id); void (*unbind)(struct pci_tdi *tdi); --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBCDC270EA4; Mon, 28 Jul 2025 13:53:12 +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=1753710792; cv=none; b=ZzJKGbd+YPf81U2TU/KEZw1AsudYj3KLAfxyUdhdKJClnuZAnh7D3B2HUNv36aVy5HND5YmLcVHqiqjk9V5flbrlM01A2MWxsxg5YI3a1QNYVqfQvIV01k6BWwpoE4yHCitN4Fj/ikMJQwl4ZHgwilmy1nmyx/zWwED9I2yJ9P8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710792; c=relaxed/simple; bh=d+5HhA/RM0XRXjhVWrZjfkcucjv6dqn+ILMfw2/nkW8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=biNSFfL3Ecyw27GrCeM/fyjK2wGcNqYuD0xvIKByobkLpGBg/Mwux/bTifWOkTAzOmg3O2UlmKi5sZrPgAznCuzwk0fd8Hn6KMbq5thw91mZ5m/7qCSYH2CuRFV0g6zkbpHzqAkfr1EOvGMKJzPMu8tUbQ76N3o9up+Ionxlqmc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ax4vbWTp; 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="ax4vbWTp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 22502C4CEE7; Mon, 28 Jul 2025 13:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710792; bh=d+5HhA/RM0XRXjhVWrZjfkcucjv6dqn+ILMfw2/nkW8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ax4vbWTpAj5oWtKqPDHQunDjLBJJBQ+0swxGUvwfXst7+A/K6EUvr68gl9+GHSXLU ELeFp1tUOVhj3KnS4tvDnvIE79f44R7Y+pppohRD0sAxFRB3dd7DwnOCnocnRLr4D8 L/ZWeiqyJgUjGI7NJF/klQO8oWSzXjwR2u68wYhJpsDCiz3pDIq2gKrWYQTNwLKsqQ EBFEp0HZcZmdREobm0mqFVdHMZyUuozCsjMnxXh3RBeYzQdnePOTU14IUK7edD7Fft JDFyTyxmcQnHjbbnF3vcHTKMt0MEBB+kDPEgrYhN2/STkijkkSzMRygoztdaXUtGoD Uyrgiv66cZCGQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 06/38] iommufd: Add and option to request for bar mapping with IORESOURCE_EXCLUSIVE Date: Mon, 28 Jul 2025 19:21:43 +0530 Message-ID: <20250728135216.48084-7-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/iommu/iommufd/device.c | 54 +++++++++++++++++++++++++ drivers/iommu/iommufd/iommufd_private.h | 4 ++ drivers/iommu/iommufd/main.c | 3 ++ drivers/vfio/pci/vfio_pci_core.c | 9 ++++- include/linux/iommufd.h | 1 + include/uapi/linux/iommufd.h | 1 + 6 files changed, 71 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 65fbd098f9e9..3bd6972836a1 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -1660,3 +1660,57 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd) iommufd_put_object(ucmd->ictx, &idev->obj); return rc; } + +static int iommufd_device_option_exclusive_ranges(struct iommu_option *cmd, + struct iommufd_device *idev) +{ + if (cmd->op =3D=3D IOMMU_OPTION_OP_GET) { + cmd->val64 =3D idev->flags & IOMMUFD_DEVICE_EXCLUSIVE_RANGE; + return 0; + } + + if (cmd->op =3D=3D IOMMU_OPTION_OP_SET) { + if (cmd->val64 =3D=3D 0) { + idev->flags &=3D ~IOMMUFD_DEVICE_EXCLUSIVE_RANGE; + return 0; + } else if (cmd->val64 & IOMMUFD_DEVICE_EXCLUSIVE_RANGE) { + idev->flags |=3D IOMMUFD_DEVICE_EXCLUSIVE_RANGE; + return 0; + } + return -EINVAL; + } + return -EOPNOTSUPP; +} +bool iommufd_device_need_exclusive_range(struct iommufd_device *idev) +{ + return !!(idev->flags & IOMMUFD_DEVICE_EXCLUSIVE_RANGE); +} + +int iommufd_device_option(struct iommufd_ucmd *ucmd) +{ + struct iommu_option *cmd =3D ucmd->cmd; + struct iommufd_device *idev; + int rc =3D 0; + + if (cmd->__reserved) + return -EOPNOTSUPP; + + idev =3D iommufd_get_device(ucmd, cmd->object_id); + if (IS_ERR(idev)) + return PTR_ERR(idev); + + mutex_lock(&idev->igroup->lock); + + + switch (cmd->option_id) { + case IOMMU_OPTION_EXCLUSIVE_RANGES: + rc =3D iommufd_device_option_exclusive_ranges(cmd, idev); + break; + default: + rc =3D -EOPNOTSUPP; + } + + mutex_unlock(&idev->igroup->lock); + iommufd_put_object(ucmd->ictx, &idev->obj); + return rc; +} diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommuf= d/iommufd_private.h index 0da2a81eedfa..fce68714c80f 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -346,6 +346,7 @@ int iommufd_ioas_change_process(struct iommufd_ucmd *uc= md); int iommufd_ioas_copy(struct iommufd_ucmd *ucmd); int iommufd_ioas_unmap(struct iommufd_ucmd *ucmd); int iommufd_ioas_option(struct iommufd_ucmd *ucmd); +int iommufd_device_option(struct iommufd_ucmd *ucmd); int iommufd_option_rlimit_mode(struct iommu_option *cmd, struct iommufd_ctx *ictx); =20 @@ -489,10 +490,13 @@ struct iommufd_device { /* always the physical device */ struct device *dev; bool enforce_cache_coherency; + unsigned long flags; struct iommufd_vdevice *vdev; bool destroying; }; =20 +#define IOMMUFD_DEVICE_EXCLUSIVE_RANGE BIT(0) + static inline struct iommufd_device * iommufd_get_device(struct iommufd_ucmd *ucmd, u32 id) { diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 15af7ced0501..89830da8b418 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -376,6 +376,9 @@ static int iommufd_option(struct iommufd_ucmd *ucmd) case IOMMU_OPTION_HUGE_PAGES: rc =3D iommufd_ioas_option(ucmd); break; + case IOMMU_OPTION_EXCLUSIVE_RANGES: + rc =3D iommufd_device_option(ucmd); + break; default: return -EOPNOTSUPP; } diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_c= ore.c index 6328c3a05bcd..bee3cf3226e9 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1753,8 +1753,15 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev= , struct vm_area_struct *vma * we need to request the region and the barmap tracks that. */ if (!vdev->barmap[index]) { - ret =3D pci_request_selected_regions(pdev, + + if (core_vdev->iommufd_device && + iommufd_device_need_exclusive_range(core_vdev->iommufd_device)) + ret =3D pci_request_selected_regions_exclusive(pdev, + 1 << index, "vfio-pci"); + else + ret =3D pci_request_selected_regions(pdev, 1 << index, "vfio-pci"); + if (ret) return ret; =20 diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h index 6e7efe83bc5d..55ae02581f9b 100644 --- a/include/linux/iommufd.h +++ b/include/linux/iommufd.h @@ -70,6 +70,7 @@ void iommufd_device_detach(struct iommufd_device *idev, i= oasid_t pasid); =20 struct iommufd_ctx *iommufd_device_to_ictx(struct iommufd_device *idev); u32 iommufd_device_to_id(struct iommufd_device *idev); +bool iommufd_device_need_exclusive_range(struct iommufd_device *idev); =20 struct iommufd_access_ops { u8 needs_pin_pages : 1; diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index c218c89e0e2e..548d4b5afcd4 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -310,6 +310,7 @@ struct iommu_ioas_unmap { enum iommufd_option { IOMMU_OPTION_RLIMIT_MODE =3D 0, IOMMU_OPTION_HUGE_PAGES =3D 1, + IOMMU_OPTION_EXCLUSIVE_RANGES =3D 2, }; =20 /** --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7906F273D71; Mon, 28 Jul 2025 13:53:18 +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=1753710798; cv=none; b=Pg6svSlcquQC13jRvW8gP12KVIq3FWwCEZF0xa2TuidU3e2BGVhoeoTDQ9ECrxTYNlprQfzX6TC+/XcxQ5WOk9T8yqYVq12/FBitAj88Q0ulbvxQUdUuzUcfHG0OkvJt/Ymh/rYwOpvcNQeWsyAc+tg6C+eVb0Ow89OZWfno9dg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710798; c=relaxed/simple; bh=0XY3diaRsG7pI3ZAlRxXSg0vozyit/SCU9/52C1YpTs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Egj8dktJXFvjNkQcto9tbWxLPfVaIIRj5e7jQdnJUp024dOA8etfBcm+SUW/Z0ApLouQk0jyE2x9gmgbxag1mbkSfbvaLgaO/Q3/DV1lBgg5OAN7V+MAzJDi8D7LOzWbQfsG/3tvIebck8uPdUoJIUPeqb/gFXL0TE6lAwb4gnA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fSojXbb9; 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="fSojXbb9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F27FFC4CEE7; Mon, 28 Jul 2025 13:53:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710798; bh=0XY3diaRsG7pI3ZAlRxXSg0vozyit/SCU9/52C1YpTs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fSojXbb9VOqyrMvpbAZNMDhq/+cnD0gfvBZmp74Rs2EfSd72rpRsApZ3zhXoZSD9l cypVLbdcc95sUZq/CYFFKEGmIWMcl5W7UzR91ua2fJPv3TtU0cJdOgbQsaTf5pRcIO 6FBvzgGbMLbx1G3W6gus9/cUbw5fZu3m5qQfmr0BF6OWbv9wSIUAbd5Y/vjf/VxcTJ mjVyqcnP2+6+LzxQaKJMqhjtqKkfSgoP1op01djw9IhQbYrs9bL3eQVnV1fGAUT7V/ E4mzeaUtz5c0/NPZswAGegoQi/2vZKUrgTEuSUEKLixqsYqp/d8SKUe9VBR0nrYYlk WS1UmuCzrQgeA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 07/38] iommufd/viommu: Add support to associate viommu with kvm instance Date: Mon, 28 Jul 2025 19:21:44 +0530 Message-ID: <20250728135216.48084-8-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" The associated kvm instance will be used in later patch by iommufd to bind a tdi to kvm. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/iommu/iommufd/viommu.c | 45 +++++++++++++++++++++++++++++++++- include/linux/iommufd.h | 3 +++ include/uapi/linux/iommufd.h | 12 +++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c index 2ca5809b238b..59f1e1176f7f 100644 --- a/drivers/iommu/iommufd/viommu.c +++ b/drivers/iommu/iommufd/viommu.c @@ -2,6 +2,36 @@ /* Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES */ #include "iommufd_private.h" +#include "linux/tsm.h" + +#if IS_ENABLED(CONFIG_KVM) +#include + +static int viommu_get_kvm(struct iommufd_viommu *viommu, int kvm_vm_fd) +{ + int rc =3D -EBADF; + struct file *filp; + + filp =3D fget(kvm_vm_fd); + + if (!file_is_kvm(filp)) + goto err_out; + + /* hold the kvm reference via file descriptor */ + viommu->kvm_filp =3D filp; + return 0; +err_out: + viommu->kvm_filp =3D NULL; + fput(filp); + return rc; +} + +static void viommu_put_kvm(struct iommufd_viommu *viommu) +{ + fput(viommu->kvm_filp); + viommu->kvm_filp =3D NULL; +} +#endif =20 void iommufd_viommu_destroy(struct iommufd_object *obj) { @@ -12,6 +42,8 @@ void iommufd_viommu_destroy(struct iommufd_object *obj) viommu->ops->destroy(viommu); refcount_dec(&viommu->hwpt->common.obj.users); xa_destroy(&viommu->vdevs); + + viommu_put_kvm(viommu); } =20 int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd) @@ -29,7 +61,9 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd) size_t viommu_size; int rc; =20 - if (cmd->flags || cmd->type =3D=3D IOMMU_VIOMMU_TYPE_DEFAULT) + if (cmd->flags & ~IOMMU_VIOMMU_KVM_FD) + return -EOPNOTSUPP; + if (cmd->type =3D=3D IOMMU_VIOMMU_TYPE_DEFAULT) return -EOPNOTSUPP; =20 idev =3D iommufd_get_device(ucmd, cmd->dev_id); @@ -100,8 +134,17 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *uc= md) goto out_put_hwpt; } =20 + /* get the kvm details if specified. */ + if (cmd->flags & IOMMU_VIOMMU_KVM_FD) { + rc =3D viommu_get_kvm(viommu, cmd->kvm_vm_fd); + if (rc) + goto out_put_hwpt; + } + cmd->out_viommu_id =3D viommu->obj.id; rc =3D iommufd_ucmd_respond(ucmd, sizeof(*cmd)); + if (rc) + viommu_put_kvm(viommu); =20 out_put_hwpt: iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj); diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h index 55ae02581f9b..b7617ba7a536 100644 --- a/include/linux/iommufd.h +++ b/include/linux/iommufd.h @@ -12,6 +12,7 @@ #include #include #include +#include #include =20 struct device; @@ -58,6 +59,7 @@ struct iommufd_object { unsigned int id; }; =20 +struct kvm; struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx, struct device *dev, u32 *id); void iommufd_device_unbind(struct iommufd_device *idev); @@ -102,6 +104,7 @@ struct iommufd_viommu { struct iommufd_ctx *ictx; struct iommu_device *iommu_dev; struct iommufd_hwpt_paging *hwpt; + struct file *kvm_filp; =20 const struct iommufd_viommu_ops *ops; =20 diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 548d4b5afcd4..9014c61a97d4 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -1023,6 +1023,17 @@ struct iommu_viommu_tegra241_cmdqv { __aligned_u64 out_vintf_mmap_length; }; =20 +/** + * define IOMMU_VIOMMU_KVM_FD - Flag indicating a valid KVM VM file descri= ptor + * + * This flag must be set when allocating a viommu instance that will be + * associated with a specific KVM VM. When allocating a viommu instance fo= r a + * KVM VM, this flag must be set to inform the initialization logic that + * @iommu_viommu_alloc::kvm_vm_fd is properly initialized. If this flag is= not + * provided but @iommu_viommu_alloc::kvm_vm_fd field will be ignored. + */ +#define IOMMU_VIOMMU_KVM_FD BIT(0) + /** * struct iommu_viommu_alloc - ioctl(IOMMU_VIOMMU_ALLOC) * @size: sizeof(struct iommu_viommu_alloc) @@ -1057,6 +1068,7 @@ struct iommu_viommu_alloc { __u32 data_len; __u32 __reserved; __aligned_u64 data_uptr; + __u32 kvm_vm_fd; }; #define IOMMU_VIOMMU_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VIOMMU_ALLOC) =20 --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34C8B26F477; Mon, 28 Jul 2025 13:53:24 +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=1753710804; cv=none; b=gK0DuiDziAfm1LIAA83fDX6BQZ8dEjK91ku/YSkzU9cDG407QZQEuMQ6Uyq52M58CCEcSYo68Oh9HYRDKajkzxAYYDTjkSJcfQxNqWKIqU5b7FyTbaRuqFQtHum9R5n8HnWpfq0lSDq1mjzImd1CxpGXt1hutkCpvOezWxX/ldE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710804; c=relaxed/simple; bh=r2X8xQvXTe2/rt3IYYSojQHGbzxLf/rj14w8bO/KdGg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FJQZH41Nw5ctlwVo+LI/Bw6sReH2BoZ0SldAr9h6KP77x2VnPxYn1dSc+bwnX3KoWRAuQ1kn1X8I4hj8vpcMmrqNUKtYU3DQAMsYFsddeyDsvxlJ6qK8FGRAArtnOWadet2czeavKbMS1ezO2cuh+zOk8/YSzJfxuobR9REXOHk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PK6GN05P; 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="PK6GN05P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB64BC4CEE7; Mon, 28 Jul 2025 13:53:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710804; bh=r2X8xQvXTe2/rt3IYYSojQHGbzxLf/rj14w8bO/KdGg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PK6GN05PlcmyBbbuiiSpCSnkeMnqNg80hm05KVJXhu9JPDMGIr2puTifIPcJmGDRe wLQyafhLNU+vaaFhmr/S/YGMklH2xDQzz0xP5w98mxCLBfB2N+cvt6rBas8Tpi0JKo JzdciaYWDd4Zvhacj0EBoaMcwp4cQZebPY7ofhGA5oDTuZFw3Slk8eJ//1D9rmclNQ G69RRStZ17/1/oHq4cMCJ7G/hNf9qx6eNYLvT+wJZAyoe3+4EmhE4tufHjqT02PJ2g hA2nzdczhWXWovII7kJxmr3xZKajOjjl4nyYRBM/NCQ+Ab2mx/bwyZYBaydSxt6q25 YeYq2bpg6uBOw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 08/38] iommufd/tsm: Add tsm_op iommufd ioctls Date: Mon, 28 Jul 2025 19:21:45 +0530 Message-ID: <20250728135216.48084-9-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 operations bind and unbind used to bind a TDI to the secure guest. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/iommu/iommufd/iommufd_private.h | 1 + drivers/iommu/iommufd/main.c | 3 ++ drivers/iommu/iommufd/viommu.c | 50 +++++++++++++++++++++++++ drivers/vfio/pci/vfio_pci_core.c | 10 +++++ include/uapi/linux/iommufd.h | 18 +++++++++ 5 files changed, 82 insertions(+) diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommuf= d/iommufd_private.h index fce68714c80f..e08186f1d102 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -697,6 +697,7 @@ void iommufd_vdevice_destroy(struct iommufd_object *obj= ); void iommufd_vdevice_abort(struct iommufd_object *obj); int iommufd_hw_queue_alloc_ioctl(struct iommufd_ucmd *ucmd); void iommufd_hw_queue_destroy(struct iommufd_object *obj); +int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *ucmd); =20 static inline struct iommufd_vdevice * iommufd_get_vdevice(struct iommufd_ctx *ictx, u32 id) diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 89830da8b418..4f2a1995bd1f 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -410,6 +410,7 @@ union ucmd_buffer { struct iommu_veventq_alloc veventq; struct iommu_vfio_ioas vfio_ioas; struct iommu_viommu_alloc viommu; + struct iommu_vdevice_tsm_op tsm_op; #ifdef CONFIG_IOMMUFD_TEST struct iommu_test_cmd test; #endif @@ -471,6 +472,8 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[= ] =3D { __reserved), IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl, struct iommu_viommu_alloc, out_viommu_id), + IOCTL_OP(IOMMU_VDEVICE_TSM_OP, iommufd_vdevice_tsm_op_ioctl, + struct iommu_vdevice_tsm_op, vdevice_id), #ifdef CONFIG_IOMMUFD_TEST IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last), #endif diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c index 59f1e1176f7f..c934312e5397 100644 --- a/drivers/iommu/iommufd/viommu.c +++ b/drivers/iommu/iommufd/viommu.c @@ -162,6 +162,9 @@ void iommufd_vdevice_abort(struct iommufd_object *obj) =20 lockdep_assert_held(&idev->igroup->lock); =20 +#ifdef CONFIG_TSM + tsm_unbind(idev->dev); +#endif if (vdev->destroy) vdev->destroy(vdev); /* xa_cmpxchg is okay to fail if alloc failed xa_cmpxchg previously */ @@ -471,3 +474,50 @@ int iommufd_hw_queue_alloc_ioctl(struct iommufd_ucmd *= ucmd) iommufd_put_object(ucmd->ictx, &viommu->obj); return rc; } + +#ifdef CONFIG_TSM +int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *ucmd) +{ + struct iommu_vdevice_tsm_op *cmd =3D ucmd->cmd; + struct iommufd_vdevice *vdev; + struct kvm *kvm; + int rc =3D -ENODEV; + + if (cmd->flags) + return -EOPNOTSUPP; + + vdev =3D container_of(iommufd_get_object(ucmd->ictx, cmd->vdevice_id, + IOMMUFD_OBJ_VDEVICE), + struct iommufd_vdevice, obj); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + + kvm =3D vdev->viommu->kvm_filp->private_data; + if (kvm) { + /* + * tsm layer will make take care of parallel calls to tsm_bind/unbind + */ + if (cmd->op =3D=3D IOMMU_VDEICE_TSM_BIND) + rc =3D tsm_bind(vdev->idev->dev, kvm, vdev->virt_id); + else if (cmd->op =3D=3D IOMMU_VDEICE_TSM_UNBIND) + rc =3D tsm_unbind(vdev->idev->dev); + + if (rc) { + rc =3D -ENODEV; + goto out_put_vdev; + } + } else { + goto out_put_vdev; + } + rc =3D iommufd_ucmd_respond(ucmd, sizeof(*cmd)); + +out_put_vdev: + iommufd_put_object(ucmd->ictx, &vdev->obj); + return rc; +} +#else /* !CONFIG_TSM */ +int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *ucmd) +{ + return -ENODEV; +} +#endif diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_c= ore.c index bee3cf3226e9..afdb39c6aefd 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -694,6 +694,16 @@ void vfio_pci_core_close_device(struct vfio_device *co= re_vdev) #if IS_ENABLED(CONFIG_EEH) eeh_dev_release(vdev->pdev); #endif + +#if 0 + /* + * destroy vdevice which involves tsm unbind before we disable pci disable + * A MSE/BME clear will transition the device to error state. + */ + if (core_vdev->iommufd_device) + iommufd_device_tombstone_vdevice(core_vdev->iommufd_device); +#endif + vfio_pci_core_disable(vdev); =20 mutex_lock(&vdev->igate); diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 9014c61a97d4..8b1fbf1ef25c 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -57,6 +57,7 @@ enum { IOMMUFD_CMD_IOAS_CHANGE_PROCESS =3D 0x92, IOMMUFD_CMD_VEVENTQ_ALLOC =3D 0x93, IOMMUFD_CMD_HW_QUEUE_ALLOC =3D 0x94, + IOMMUFD_CMD_VDEVICE_TSM_OP =3D 0x95, }; =20 /** @@ -1127,6 +1128,23 @@ enum iommu_veventq_flag { IOMMU_VEVENTQ_FLAG_LOST_EVENTS =3D (1U << 0), }; =20 +/** + * struct iommu_vdevice_tsm_OP - ioctl(IOMMU_VDEVICE_TSM_OP) + * @size: sizeof(struct iommu_vdevice_tsm_OP) + * @op: Either TSM_BIND or TSM_UNBIMD + * @flags: Must be 0 + * @vdevice_id: Object handle for the vDevice. Returned from IOMMU_VDEVICE= _ALLOC + */ +struct iommu_vdevice_tsm_op { + __u32 size; + __u32 op; + __u32 flags; + __u32 vdevice_id; +}; +#define IOMMU_VDEVICE_TSM_OP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VDEVICE_TSM_OP) +#define IOMMU_VDEICE_TSM_BIND 0x1 +#define IOMMU_VDEICE_TSM_UNBIND 0x2 + /** * struct iommufd_vevent_header - Virtual Event Header for a vEVENTQ Status * @flags: Combination of enum iommu_veventq_flag --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DF4826F477; Mon, 28 Jul 2025 13:53:30 +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=1753710810; cv=none; b=BUIAb2z2EsIWQybNm8Y/h1pz3I/gPtzoI5Ny7K+7Ey2t/OSRuNWKCCiKTTzETHX6/Jr9etlbzB6Ws5PHnI0f6vaXSAj5Wac7AovJUJCqr8fdQ4mCPop9zX6Yf0UdqHpoJ6HLM1h2gfW+SUclsjT6sCUrJNj4UTOs96oOm8yBMNI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710810; c=relaxed/simple; bh=WA5m+a2dUJtMdyp7kjgPNPN6wCrN/6b+STzciuqotTo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IsRFwDIZsiUU4KfON4E+tmx0Gd0xgiglBaED8eLSjvUcN0/MOdrGuw+W5COlIUP22gm+H9Xz0ihA4aac+9EZetOvWyu/SroxOlCPxb+PyoSoBt3QQc+b3257DiTAchFI++85Hufw3Jp2nikeZjWjNqLMHxxooj3/gKTNHgPIyZ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aMZ38ZZW; 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="aMZ38ZZW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A789DC4CEFA; Mon, 28 Jul 2025 13:53:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710810; bh=WA5m+a2dUJtMdyp7kjgPNPN6wCrN/6b+STzciuqotTo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aMZ38ZZWSjIdNK/1lEUDw/ERsqwPWeD4iNTLVSby00grYkV8/5mFFTe5De7yjYr4W nHwQdPH3uAyMzFwD78KD+tsw74bTRkN5OVHSsLrUfUtmQJpZuwJwIiSGgHmOIJ1YnZ cjK8dAdeVTccpVy7nRet9Kctll9GhUK48a7UbpPeeLzi7VtpEtOWVGuAy3lzaATS1n 5uwpUrvqMbZuliFQ3OiO/XLW6pkbp2z+Ci4TpvTGPZ30xYwVpY/ni2Vilv/WGdEfC1 gM+lJ/+Uy0nDce75mVdd8r/TxLWZSP07kf9JNzcrv/G6sp7xUcxChVpudBDim5056/ oP+r15U+ADGqw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 09/38] iommufd/vdevice: Add TSM Guest request uAPI Date: Mon, 28 Jul 2025 19:21:46 +0530 Message-ID: <20250728135216.48084-10-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 TSM Guest request uAPI against iommufd_vdevice to forward various TSM attestation & acceptance requests from guest to TSM driver/secure firmware. This uAPI takes function only after TSM Bind. After a vPCI device is locked down by TSM Bind, CoCo VM should attest and accept the device in its TEE. These operations needs interaction with secure firmware and the device, but doesn't impact the device management from host's POV. It doesn't change the fact that host should not touch some part of the device (see TDISP spec) to keep the trusted assignment, and host could exit trusted assignment and roll back everything by TSM Unbind. So the TSM Guest request becomes a passthrough channel for CoCo VM to exchange request/response blobs with TSM driver/secure firmware. The definition of this IOCTL illustates this idea. Based on changes from: Alexey Kardashevskiy Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/iommu/iommufd/iommufd_private.h | 1 + drivers/iommu/iommufd/main.c | 3 ++ drivers/iommu/iommufd/viommu.c | 40 +++++++++++++++++++++++++ drivers/pci/tsm.c | 15 ++++++++-- drivers/virt/coco/tsm-core.c | 9 ++++++ include/linux/pci-tsm.h | 30 ++----------------- include/linux/tsm.h | 23 ++++++++++++++ include/uapi/linux/iommufd.h | 28 +++++++++++++++++ 8 files changed, 120 insertions(+), 29 deletions(-) diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommuf= d/iommufd_private.h index e08186f1d102..0c0d96135432 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -698,6 +698,7 @@ void iommufd_vdevice_abort(struct iommufd_object *obj); int iommufd_hw_queue_alloc_ioctl(struct iommufd_ucmd *ucmd); void iommufd_hw_queue_destroy(struct iommufd_object *obj); int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *ucmd); +int iommufd_vdevice_tsm_guest_request_ioctl(struct iommufd_ucmd *ucmd); =20 static inline struct iommufd_vdevice * iommufd_get_vdevice(struct iommufd_ctx *ictx, u32 id) diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 4f2a1995bd1f..65e60da9caef 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -411,6 +411,7 @@ union ucmd_buffer { struct iommu_vfio_ioas vfio_ioas; struct iommu_viommu_alloc viommu; struct iommu_vdevice_tsm_op tsm_op; + struct iommu_vdevice_tsm_guest_request gr; #ifdef CONFIG_IOMMUFD_TEST struct iommu_test_cmd test; #endif @@ -474,6 +475,8 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[= ] =3D { struct iommu_viommu_alloc, out_viommu_id), IOCTL_OP(IOMMU_VDEVICE_TSM_OP, iommufd_vdevice_tsm_op_ioctl, struct iommu_vdevice_tsm_op, vdevice_id), + IOCTL_OP(IOMMU_VDEVICE_TSM_GUEST_REQUEST, iommufd_vdevice_tsm_guest_reque= st_ioctl, + struct iommu_vdevice_tsm_guest_request, resp_uptr), #ifdef CONFIG_IOMMUFD_TEST IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last), #endif diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c index c934312e5397..9f4d4d69b82b 100644 --- a/drivers/iommu/iommufd/viommu.c +++ b/drivers/iommu/iommufd/viommu.c @@ -515,9 +515,49 @@ int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *= ucmd) iommufd_put_object(ucmd->ictx, &vdev->obj); return rc; } + +int iommufd_vdevice_tsm_guest_request_ioctl(struct iommufd_ucmd *ucmd) +{ + struct iommu_vdevice_tsm_guest_request *cmd =3D ucmd->cmd; + struct tsm_guest_req_info info =3D { + .type =3D cmd->type, + .type_info =3D u64_to_user_ptr(cmd->type_info_uptr), + .type_info_len =3D cmd->type_info_len, + .req =3D u64_to_user_ptr(cmd->req_uptr), + .req_len =3D cmd->req_len, + .resp =3D u64_to_user_ptr(cmd->resp_uptr), + .resp_len =3D cmd->resp_len, + }; + struct iommufd_vdevice *vdev; + int rc; + + vdev =3D container_of(iommufd_get_object(ucmd->ictx, cmd->vdevice_id, + IOMMUFD_OBJ_VDEVICE), + struct iommufd_vdevice, obj); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + + rc =3D tsm_guest_req(vdev->idev->dev, &info); + if (rc) + goto err_out; + + cmd->resp_len =3D info.resp_len; + rc =3D iommufd_ucmd_respond(ucmd, sizeof(*cmd)); +err_out: + iommufd_put_object(ucmd->ictx, &vdev->obj); + return rc; +} + #else /* !CONFIG_TSM */ + int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *ucmd) { return -ENODEV; } + +int iommufd_vdevice_tsm_guest_request_ioctl(struct iommufd_ucmd *ucmd) +{ + return -ENODEV; +} + #endif diff --git a/drivers/pci/tsm.c b/drivers/pci/tsm.c index 80607082b7f0..896ef0f5fbe7 100644 --- a/drivers/pci/tsm.c +++ b/drivers/pci/tsm.c @@ -861,7 +861,7 @@ int pci_tsm_unbind(struct pci_dev *pdev) EXPORT_SYMBOL_GPL(pci_tsm_unbind); =20 /** - * pci_tsm_guest_req - VFIO/IOMMUFD helper to handle guest requests + * pci_tsm_guest_req - IOMMUFD helper to handle guest requests * @pdev: @pdev representing a bound tdi * @info: envelope for the request * @@ -871,11 +871,12 @@ EXPORT_SYMBOL_GPL(pci_tsm_unbind); * posts to userspace (e.g. QEMU) that holds the host-to-guest RID * mapping. */ -int pci_tsm_guest_req(struct pci_dev *pdev, struct pci_tsm_guest_req_info = *info) +static int __pci_tsm_guest_req(struct pci_dev *pdev, struct tsm_guest_req_= info *info) { struct pci_tdi *tdi; int rc; =20 + lockdep_assert_held_read(&pci_tsm_rwsem); =20 if (!pdev->tsm) @@ -899,4 +900,14 @@ int pci_tsm_guest_req(struct pci_dev *pdev, struct pci= _tsm_guest_req_info *info) =20 return 0; } + +int pci_tsm_guest_req(struct pci_dev *pdev, struct tsm_guest_req_info *inf= o) +{ + struct rw_semaphore *lock __free(tsm_read_unlock) =3D tsm_read_lock(); + if (!lock) + return -EINTR; + + return __pci_tsm_guest_req(pdev, info); +} + EXPORT_SYMBOL_GPL(pci_tsm_guest_req); diff --git a/drivers/virt/coco/tsm-core.c b/drivers/virt/coco/tsm-core.c index 0a7c9aa46c56..32b1235518b4 100644 --- a/drivers/virt/coco/tsm-core.c +++ b/drivers/virt/coco/tsm-core.c @@ -134,6 +134,15 @@ int tsm_unbind(struct device *dev) } EXPORT_SYMBOL_GPL(tsm_unbind); =20 +int tsm_guest_req(struct device *dev, struct tsm_guest_req_info *info) +{ + if (!dev_is_pci(dev)) + return -EINVAL; + + return pci_tsm_guest_req(to_pci_dev(dev), info); +} +EXPORT_SYMBOL_GPL(tsm_guest_req); + static void tsm_release(struct device *dev) { struct tsm_core_dev *core =3D container_of(dev, typeof(*core), dev); diff --git a/include/linux/pci-tsm.h b/include/linux/pci-tsm.h index 7639e7963681..530f8b3093f8 100644 --- a/include/linux/pci-tsm.h +++ b/include/linux/pci-tsm.h @@ -108,31 +108,7 @@ static inline bool is_pci_tsm_pf0(struct pci_dev *pdev) return PCI_FUNC(pdev->devfn) =3D=3D 0; } =20 -enum pci_tsm_guest_req_type { - PCI_TSM_GUEST_REQ_TDXC, -}; - -/** - * struct pci_tsm_guest_req_info - parameter for pci_tsm_ops.guest_req() - * @type: identify the format of the following blobs - * @type_info: extra input/output info, e.g. firmware error code - * @type_info_len: the size of @type_info - * @req: request data buffer filled by guest - * @req_len: the size of @req filled by guest - * @resp: response data buffer filled by host - * @resp_len: for input, the size of @resp buffer filled by guest - * for output, the size of actual response data filled by host - */ -struct pci_tsm_guest_req_info { - enum pci_tsm_guest_req_type type; - void *type_info; - size_t type_info_len; - void *req; - size_t req_len; - void *resp; - size_t resp_len; -}; - +struct tsm_guest_req_info; /** * struct pci_tsm_ops - Low-level TSM-exported interface to the PCI core * @probe: probe/accept device for tsm operation, setup DSM context @@ -160,7 +136,7 @@ struct pci_tsm_ops { struct kvm *kvm, u64 tdi_id); void (*unbind)(struct pci_tdi *tdi); int (*guest_req)(struct pci_dev *pdev, - struct pci_tsm_guest_req_info *info); + struct tsm_guest_req_info *info); int (*accept)(struct pci_dev *pdev); }; =20 @@ -180,7 +156,7 @@ int pci_tsm_initialize(struct pci_dev *pdev, struct pci= _tsm *tsm); int pci_tsm_pf0_initialize(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm); int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u64 tdi_id); int pci_tsm_unbind(struct pci_dev *pdev); -int pci_tsm_guest_req(struct pci_dev *pdev, struct pci_tsm_guest_req_info = *info); +int pci_tsm_guest_req(struct pci_dev *pdev, struct tsm_guest_req_info *inf= o); #else static inline int pci_tsm_core_register(const struct pci_tsm_ops *ops, const struct attribute_group *grp) diff --git a/include/linux/tsm.h b/include/linux/tsm.h index 0aab8d037e71..497a3b4df5a0 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -123,4 +123,27 @@ int tsm_ide_stream_register(struct pci_dev *pdev, stru= ct pci_ide *ide); void tsm_ide_stream_unregister(struct pci_ide *ide); int tsm_bind(struct device *dev, struct kvm *kvm, u64 tdi_id); int tsm_unbind(struct device *dev); + +/** + * struct tsm_guest_req_info - parameter for pci_tsm_ops.guest_req() + * @type: identify the format of the following blobs + * @type_info: extra input/output info, e.g. firmware error code + * @type_info_len: the size of @type_info + * @req: request data buffer filled by guest + * @req_len: the size of @req filled by guest + * @resp: response data buffer filled by host + * @resp_len: for input, the size of @resp buffer filled by guest + * for output, the size of actual response data filled by host + */ +struct tsm_guest_req_info { + u32 type; + void __user *type_info; + size_t type_info_len; + void __user *req; + size_t req_len; + void __user *resp; + size_t resp_len; +}; + +int tsm_guest_req(struct device *dev, struct tsm_guest_req_info *info); #endif /* __TSM_H */ diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 8b1fbf1ef25c..56542cfcfa38 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -58,6 +58,7 @@ enum { IOMMUFD_CMD_VEVENTQ_ALLOC =3D 0x93, IOMMUFD_CMD_HW_QUEUE_ALLOC =3D 0x94, IOMMUFD_CMD_VDEVICE_TSM_OP =3D 0x95, + IOMMUFD_CMD_VDEVICE_TSM_GUEST_REQUEST =3D 0x96, }; =20 /** @@ -1320,4 +1321,31 @@ struct iommu_hw_queue_alloc { __aligned_u64 length; }; #define IOMMU_HW_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HW_QUEUE_ALLOC) + +/** + * struct iommu_vdevice_tsm_guest_request - ioctl(IOMMU_VDEVICE_TSM_GUEST_= REQUEST) + * @size: sizeof(struct iommu_vdevice_tsm_guest_request) + * @vdevice_id: vDevice ID the guest request is for + * @type: identify the format of the following blobs + * @type_info_len: the blob size for @type_info_uptr + * @req_len: the blob size for @req_uptr, filled by guest + * @resp_len: for input, the blob size for @resp_uptr, filled by guest + * for output, the size of actual response data, filled by host + * @type_info_uptr: extra input/output info, e.g. firmware error code + * @req_uptr: request data buffer filled by guest + * @resp_uptr: response data buffer filled by host + */ +struct iommu_vdevice_tsm_guest_request { + __u32 size; + __u32 vdevice_id; + __u32 type; + __u32 type_info_len; + __u32 req_len; + __u32 resp_len; + __aligned_u64 type_info_uptr; + __aligned_u64 req_uptr; + __aligned_u64 resp_uptr; +}; +#define IOMMU_VDEVICE_TSM_GUEST_REQUEST _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VDEV= ICE_TSM_GUEST_REQUEST) + #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD7AA26738C; Mon, 28 Jul 2025 13:53:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710817; cv=none; b=fBwno8xtNSSpnf20mkR5lK9MdcKGgDJFwchFeVJ5MB10nTkk3u+RTx7yNH5Pl8+1uJl+hPeLQN4EjVjaPGSARV0iPhyNxrKLz1xPG7wHoHURX+Fzm8YvC4lRTJFlOZKSBlTJ8hJOBoNSLry3k9RuWE5wPCKvCRzHKHudUaYWIhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710817; c=relaxed/simple; bh=Thi9yU+6tSWyVmTIGO1nyLQl2Xw4SWgbWppOY/SS248=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VGnrGM0u1KZWYXVAYJLO4yS3qpTl3uMC2kNtrelz3nUE+GiApAXNhGQTq7U6PWzrT2YawnTnIcckmWpm52Q2FkJBHlQrzGuvwnSEct8vF5Es4FJq7vBMa2OtsqiPObatMT0zN8WNbQIFHapneF5BetrGQ2QRrM5KCp+d9I0/aCk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kARqcFtN; 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="kARqcFtN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03BA0C4CEEF; Mon, 28 Jul 2025 13:53:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710816; bh=Thi9yU+6tSWyVmTIGO1nyLQl2Xw4SWgbWppOY/SS248=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kARqcFtNVkwBM+NMuWiZc8Qlv6o9fCqsdo85x6zkUq0i16+h2kbQz2FVS46G7XemG 8TIjRh28fORV2T/Vtj0GgmdXhi313CFD3Lg57YmjEE0DCPCF5hwHmQs2+kWxtuTaI8 SvIl59simJ+4BUPTMEzygptqH8/p7LPKF10D74NMdS+VmA/esFGeNHQqr76d/x3jeL l7Hx7QvQu5Ywgnh8AtsUPWJRKKbS8+uiQWyi6RTUi1hZcsw3ybRfIca+NltzBUNxjM ZIW08+9ESKKEXm+1NYyNHLgK8lig2woZH9GW9azt2giiyW2CnEdHLvcNASx81+sgxx qe/oEzp5izalw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 10/38] iommufd/vdevice: Add TSM map ioctl Date: Mon, 28 Jul 2025 19:21:47 +0530 Message-ID: <20250728135216.48084-11-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" With passthrough devices, we need to make sure private memory is allocated and assigned to the secure guest before we can issue the DMA. For ARM RMM, we only need to map and the secure SMMU management is internal to RMM. For shared IPA, vfio/iommufd DMA MAP/UNMAP interface does the equivalent Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/kvm/mmu.c | 45 +++++++++++++++++++++++++ drivers/iommu/iommufd/iommufd_private.h | 1 + drivers/iommu/iommufd/main.c | 4 +++ drivers/iommu/iommufd/viommu.c | 43 +++++++++++++++++++++++ include/linux/kvm_host.h | 1 + include/uapi/linux/iommufd.h | 10 ++++++ 6 files changed, 104 insertions(+) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index c866891fd8f9..8788d24095d6 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1530,6 +1530,51 @@ static int realm_map_ipa(struct kvm *kvm, phys_addr_= t ipa, return realm_map_protected(realm, ipa, pfn, map_size, memcache); } =20 +int kvm_map_private_memory(struct kvm *kvm, phys_addr_t start_gpa, + phys_addr_t end_gpa) +{ + struct kvm_mmu_memory_cache cache =3D { .gfp_zero =3D __GFP_ZERO }; + struct kvm_s2_mmu *mmu =3D &kvm->arch.mmu; + struct kvm_memory_slot *memslot; + phys_addr_t addr; + struct page *page; + kvm_pfn_t pfn; + int ret =3D 0, idx; + gfn_t gfn; + + idx =3D srcu_read_lock(&kvm->srcu); + for (addr =3D start_gpa; addr < end_gpa; addr +=3D PAGE_SIZE) { + + ret =3D kvm_mmu_topup_memory_cache(&cache, + kvm_mmu_cache_min_pages(mmu)); + if (ret) + break; + + gfn =3D addr >> PAGE_SHIFT; + + memslot =3D gfn_to_memslot(kvm, gfn); + if (!kvm_slot_can_be_private(memslot)) { + ret =3D -EINVAL; + break; + } + /* should we check if kvm_mem_is_private()? */ + ret =3D kvm_gmem_get_pfn(kvm, memslot, gfn, &pfn, &page, NULL); + if (ret) + break; + + /* should we hold kvm_fault_lock()? */ + ret =3D realm_map_ipa(kvm, addr, pfn, PAGE_SIZE, KVM_PGTABLE_PROT_W, + &cache); + if (ret) { + put_page(page); + break; + } + } + kvm_mmu_free_memory_cache(&cache); + srcu_read_unlock(&kvm->srcu, idx); + return ret; +} + static int private_memslot_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_memory_slot *memslot) diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommuf= d/iommufd_private.h index 0c0d96135432..34f3ae0e0cd1 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -698,6 +698,7 @@ void iommufd_vdevice_abort(struct iommufd_object *obj); int iommufd_hw_queue_alloc_ioctl(struct iommufd_ucmd *ucmd); void iommufd_hw_queue_destroy(struct iommufd_object *obj); int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *ucmd); +int iommufd_vdevice_tsm_map_ioctl(struct iommufd_ucmd *ucmd); int iommufd_vdevice_tsm_guest_request_ioctl(struct iommufd_ucmd *ucmd); =20 static inline struct iommufd_vdevice * diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 65e60da9caef..388d11334994 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -411,6 +411,7 @@ union ucmd_buffer { struct iommu_vfio_ioas vfio_ioas; struct iommu_viommu_alloc viommu; struct iommu_vdevice_tsm_op tsm_op; + struct iommu_vdevice_tsm_map tsm_map; struct iommu_vdevice_tsm_guest_request gr; #ifdef CONFIG_IOMMUFD_TEST struct iommu_test_cmd test; @@ -475,6 +476,9 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[= ] =3D { struct iommu_viommu_alloc, out_viommu_id), IOCTL_OP(IOMMU_VDEVICE_TSM_OP, iommufd_vdevice_tsm_op_ioctl, struct iommu_vdevice_tsm_op, vdevice_id), + IOCTL_OP(IOMMU_VDEVICE_TSM_MAP, iommufd_vdevice_tsm_map_ioctl, + struct iommu_vdevice_tsm_map, vdevice_id), + IOCTL_OP(IOMMU_VDEVICE_TSM_GUEST_REQUEST, iommufd_vdevice_tsm_guest_reque= st_ioctl, struct iommu_vdevice_tsm_guest_request, resp_uptr), #ifdef CONFIG_IOMMUFD_TEST diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c index 9f4d4d69b82b..1ffc996caa3e 100644 --- a/drivers/iommu/iommufd/viommu.c +++ b/drivers/iommu/iommufd/viommu.c @@ -516,6 +516,44 @@ int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *= ucmd) return rc; } =20 +int __weak kvm_map_private_memory(struct kvm *kvm, phys_addr_t start_gpa, + phys_addr_t end_gpa) +{ + return -EINVAL; +} + +int iommufd_vdevice_tsm_map_ioctl(struct iommufd_ucmd *ucmd) +{ + struct iommu_vdevice_tsm_map *cmd =3D ucmd->cmd; + struct iommufd_vdevice *vdev; + struct kvm *kvm; + int rc =3D -ENODEV; + + if (cmd->flags) + return -EOPNOTSUPP; + + vdev =3D container_of(iommufd_get_object(ucmd->ictx, cmd->vdevice_id, + IOMMUFD_OBJ_VDEVICE), + struct iommufd_vdevice, obj); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + + kvm =3D vdev->viommu->kvm_filp->private_data; + if (kvm) { + rc =3D kvm_map_private_memory(kvm, cmd->start_gpa, cmd->end_gpa); + if (rc) + goto out_put_vdev; + + } else { + goto out_put_vdev; + } + rc =3D iommufd_ucmd_respond(ucmd, sizeof(*cmd)); + +out_put_vdev: + iommufd_put_object(ucmd->ictx, &vdev->obj); + return rc; +} + int iommufd_vdevice_tsm_guest_request_ioctl(struct iommufd_ucmd *ucmd) { struct iommu_vdevice_tsm_guest_request *cmd =3D ucmd->cmd; @@ -555,6 +593,11 @@ int iommufd_vdevice_tsm_op_ioctl(struct iommufd_ucmd *= ucmd) return -ENODEV; } =20 +int iommufd_vdevice_tsm_map_ioctl(struct iommufd_ucmd *ucmd) +{ + return -ENODEV; +} + int iommufd_vdevice_tsm_guest_request_ioctl(struct iommufd_ucmd *ucmd) { return -ENODEV; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3bde4fb5c6aa..bfdfb4f32d28 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2602,4 +2602,5 @@ static inline int kvm_enable_virtualization(void) { r= eturn 0; } static inline void kvm_disable_virtualization(void) { } #endif =20 +int kvm_map_private_memory(struct kvm *kvm, phys_addr_t start_gpa, phys_ad= dr_t end_gpa); #endif diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 56542cfcfa38..75056d1f141d 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -59,6 +59,7 @@ enum { IOMMUFD_CMD_HW_QUEUE_ALLOC =3D 0x94, IOMMUFD_CMD_VDEVICE_TSM_OP =3D 0x95, IOMMUFD_CMD_VDEVICE_TSM_GUEST_REQUEST =3D 0x96, + IOMMUFD_CMD_VDEVICE_TSM_MAP =3D 0x97, }; =20 /** @@ -1146,6 +1147,15 @@ struct iommu_vdevice_tsm_op { #define IOMMU_VDEICE_TSM_BIND 0x1 #define IOMMU_VDEICE_TSM_UNBIND 0x2 =20 +struct iommu_vdevice_tsm_map { + __u32 size; + __u32 flags; + __u64 start_gpa; + __u64 end_gpa; + __u32 vdevice_id; +}; +#define IOMMU_VDEVICE_TSM_MAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VDEVICE_TSM_MA= P) + /** * struct iommufd_vevent_header - Virtual Event Header for a vEVENTQ Status * @flags: Combination of enum iommu_veventq_flag --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E0B626CE1C; Mon, 28 Jul 2025 13:53:42 +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=1753710824; cv=none; b=P8OeezRjkrr3wzeJ9a++Nqx4zGKQJtl+NwRgGa29VsNQt5fMIASQkzQfm9Vo4NABvcIZLWVqgY9547qbORt3qGzVAr6bBVXUNsAQiic829d/UrSe7MLKtb9iaJ77QrqvfXsXD2jSHkqGS7HeBi1h4wosXZ7VWylIkdXpQJWhRCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710824; c=relaxed/simple; bh=b8DNZd0OWQO+/qyBhIEURTzrRcRTx4S5avd9jivd7EU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hOGmPR1caHcHzarFzAEYpH3g9Nf4o5WiKtNG8EvA56Mwcieon4hUksDnQvH8jfTJpaLBN8OqRhdB1xJQgzqzYVtVsx7EgAd04X1/Od8ERwAEONEjlCy9frAtNdTcblQHXoUr+Eg1XUmb/ZfKWt4LEaUs0lWs/0ekvNBPLXhmtfA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F13jPxay; 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="F13jPxay" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3101FC4CEE7; Mon, 28 Jul 2025 13:53:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710822; bh=b8DNZd0OWQO+/qyBhIEURTzrRcRTx4S5avd9jivd7EU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F13jPxayOoMzgp7VKZEdViJybGfxuLkSHJUCPgTuWQJ0i+CLH33v+qmwcZJUi8lNT Q1RtRnDhuxiqteYRDQAmCJE9bhpkyhDmetlhujeaP4VHVfS5/3+seo0w99SRxy32Ql O/38UqmGE7syHkqUW2JLox1WdLGknXnhzFsPL80PGhfbpp7PpGAOQrqiZ4u2ZkKl8N QeZ4BzZkzNYEnvdyI+IhhfX1+Xa7qG7LFYLUN0zsxIebsekBqwXUfAc2NUrSRI2tHp w7zxhSFR0mF+5N7HwdyU4ZpuerB0kLeUg0xgQb10HKxqN8hwwABigryOPDnQ5AyZQ1 LXqmvqfoDoeAw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 11/38] KVM: arm64: CCA: register host tsm platform device Date: Mon, 28 Jul 2025 19:21:48 +0530 Message-ID: <20250728135216.48084-12-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 a platform device if the CCA DA feature is supported. A driver for this platform device will further drive the CCA DA workflow. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_smc.h | 3 +++ arch/arm64/kvm/rme.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 504009a42035..42708d500048 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -12,6 +12,8 @@ =20 #include =20 +#define RMI_DEV_NAME "arm-rmi-dev" + #define SMC_RMI_CALL(func) \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \ @@ -87,6 +89,7 @@ enum rmi_ripas { #define RMI_FEATURE_REGISTER_0_GICV3_NUM_LRS GENMASK(37, 34) #define RMI_FEATURE_REGISTER_0_MAX_RECS_ORDER GENMASK(41, 38) #define RMI_FEATURE_REGISTER_0_Reserved GENMASK(63, 42) +#define RMI_FEATURE_REGISTER_0_DA BIT(42) =20 #define RMI_REALM_PARAM_FLAG_LPA2 BIT(0) #define RMI_REALM_PARAM_FLAG_SVE BIT(1) diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c index ec8093ec2da3..d1c147aba2ed 100644 --- a/arch/arm64/kvm/rme.c +++ b/arch/arm64/kvm/rme.c @@ -4,6 +4,7 @@ */ =20 #include +#include =20 #include #include @@ -1724,6 +1725,18 @@ int kvm_init_realm_vm(struct kvm *kvm) return 0; } =20 +static struct platform_device cca_host_dev =3D { + .name =3D RMI_DEV_NAME, + .id =3D PLATFORM_DEVID_NONE +}; + +static void rmm_tsm_init(void) +{ + if (!platform_device_register(&cca_host_dev)) + pr_info("CCA host DA platform device initialized.\n"); + +} + void kvm_init_rme(void) { if (PAGE_SIZE !=3D SZ_4K) @@ -1737,6 +1750,9 @@ void kvm_init_rme(void) if (WARN_ON(rmi_features(0, &rmm_feat_reg0))) return; =20 + if (rme_has_feature(RMI_FEATURE_REGISTER_0_DA)) + rmm_tsm_init(); + if (rme_vmid_init()) return; =20 --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B4ACC274B25; Mon, 28 Jul 2025 13:53:48 +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=1753710828; cv=none; b=MgZGFftTH4FWZmZG4l2DF8boVw0JauUfEs6yQFDUDBtQ7iGHer6rl2J028/6QlkXz+20adhdKOvKGi/huVv9jJMxBnOzdQc+Gy4d4c0QuMOgPPfijXFuIC1NJ8MiMs0j01bxHy9QFnZ6V2jIHaHr5AQSlOg7TQiYPOWDGr+lZ6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710828; c=relaxed/simple; bh=skkmTrobQDZGFt53QbtosVSpxpFbDP0+nW5NvEz59wg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UhYgEKn5ecfy4I1uI0+3FUsMIVtx82ArlSV8b8tbygkOk/04u96vqzU/0Ipsz/JPvG+15jNkoYa+JQLXG6bcPiHwMCUm9E5vJ7Jbv4RDADZemOgjdIu6BWp25koR8r5L4FW0x+MFHGIgCxRvqI6rq8UDTpIvQpnOCE2n9HbhJ0E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iDj5USVM; 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="iDj5USVM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5079FC4CEF7; Mon, 28 Jul 2025 13:53:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710828; bh=skkmTrobQDZGFt53QbtosVSpxpFbDP0+nW5NvEz59wg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iDj5USVMbhRXmRBxR4tAWy3HrA9W0KOQGGr03N8mmrkma9x4TkkKI87JB3DmEYawK RG1A9g51wQtN5LsBxR7rWDedvb3sVG7PrgFRJ/AlpsCb1nBspdESRL0fGrd+QjmCGe lMZmtei3Gga6HOlbMtM5u+/imfLR+yeBuyTpnLB7YFjsqPcAhnrJZKLghfRkv7RUTC 6RB5E8UAX0unPHGNMxZUlLLK6kW/wBNx4o6JdxU3kxUEbRHRltb9E6GqYo9GUAv52H Z9qAYHNQeIaJHKFtRu4rvm9xLfXDoHeOySON3Y8PvIz9P81LYRBbv7MD7h5BT4kVDg 1FGZL+4h7OrEA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 12/38] coco: host: arm64: CCA host platform device driver Date: Mon, 28 Jul 2025 19:21:49 +0530 Message-ID: <20250728135216.48084-13-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" This driver registers the pci_tsm_ops with tsm subsystem. Signed-off-by: Aneesh Kumar K.V (Arm) --- drivers/virt/coco/Kconfig | 2 + drivers/virt/coco/Makefile | 1 + drivers/virt/coco/arm-cca-host/Kconfig | 12 ++ drivers/virt/coco/arm-cca-host/Makefile | 5 + drivers/virt/coco/arm-cca-host/arm-cca.c | 209 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 29 ++++ 6 files changed, 258 insertions(+) create mode 100644 drivers/virt/coco/arm-cca-host/Kconfig create mode 100644 drivers/virt/coco/arm-cca-host/Makefile create mode 100644 drivers/virt/coco/arm-cca-host/arm-cca.c create mode 100644 drivers/virt/coco/arm-cca-host/rmm-da.h diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig index 57248b088545..43e9508301bf 100644 --- a/drivers/virt/coco/Kconfig +++ b/drivers/virt/coco/Kconfig @@ -15,5 +15,7 @@ source "drivers/virt/coco/arm-cca-guest/Kconfig" =20 source "drivers/virt/coco/guest/Kconfig" =20 +source "drivers/virt/coco/arm-cca-host/Kconfig" + config TSM tristate diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile index 04e124b2d7cf..d0a859dd9eaf 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ =20 obj-$(CONFIG_TSM) +=3D tsm-core.o obj-y +=3D guest/ +obj-$(CONFIG_ARM_CCA_HOST) +=3D arm-cca-host/ diff --git a/drivers/virt/coco/arm-cca-host/Kconfig b/drivers/virt/coco/arm= -cca-host/Kconfig new file mode 100644 index 000000000000..0f19fbf47613 --- /dev/null +++ b/drivers/virt/coco/arm-cca-host/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# TSM (TEE Security Manager) host drivers +# +config ARM_CCA_HOST + tristate "Arm CCA Host driver" + depends on ARM64 + depends on PCI_TSM + select TSM + + help + The driver provides TSM backend for ARM CCA diff --git a/drivers/virt/coco/arm-cca-host/Makefile b/drivers/virt/coco/ar= m-cca-host/Makefile new file mode 100644 index 000000000000..ad353b07e95a --- /dev/null +++ b/drivers/virt/coco/arm-cca-host/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +obj-$(CONFIG_ARM_CCA_HOST) +=3D arm-cca-host.o + +arm-cca-host-$(CONFIG_TSM) +=3D arm-cca.o diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c new file mode 100644 index 000000000000..c8b0e6db1f47 --- /dev/null +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rmm-da.h" + +/* Number of streams that we can support at the hostbridge level */ +#define CCA_HB_PLATFORM_STREAMS 4 + +/* Total number of stream id supported at root port level */ +#define MAX_STREAM_ID 256 + +DEFINE_FREE(vfree, void *, if (!IS_ERR_OR_NULL(_T)) vfree(_T)) +static struct pci_tsm *cca_tsm_pci_probe(struct pci_dev *pdev) +{ + int rc; + struct pci_host_bridge *hb; + struct cca_host_dsc_pf0 *dsc_pf0 __free(vfree) =3D NULL; + + if (pdev->is_virtfn) + return NULL; + + if (!is_pci_tsm_pf0(pdev)) { + struct pci_tsm *tsm =3D kzalloc(sizeof(*tsm), GFP_KERNEL); + + if (!tsm) + goto err_out; + + pci_tsm_initialize(pdev, tsm); + return tsm; + } + + if (!pdev->ide_cap) + goto err_out; + + dsc_pf0 =3D vcalloc(sizeof(*dsc_pf0), GFP_KERNEL); + if (!dsc_pf0) + goto err_out; + + rc =3D pci_tsm_pf0_initialize(pdev, &dsc_pf0->pci); + if (rc) + return NULL; + /* + * FIXME!! + * update the hostbridge details. This should go into + * some host bridge probe/init routine. + * than the selective index supported by the endpoint + */ + hb =3D pci_find_host_bridge(pdev->bus); + pci_ide_init_nr_streams(hb, CCA_HB_PLATFORM_STREAMS); + + pci_info(pdev, "tsm enabled\n"); + return &no_free_ptr(dsc_pf0)->pci.tsm; + +err_out: + return NULL; +} + +static void cca_tsm_pci_remove(struct pci_tsm *tsm) +{ + struct pci_dev *pdev =3D tsm->pdev; + struct cca_host_dsc_pf0 *dsc_pf0; + + if (WARN_ON(pdev->is_virtfn)) + return; + + if (!is_pci_tsm_pf0(pdev)) { + + pci_dbg(tsm->pdev, "tsm disabled\n"); + kfree(pdev->tsm); + return; + } + + dsc_pf0 =3D to_cca_dsc_pf0(pdev); + pci_dbg(tsm->pdev, "tsm disabled\n"); + vfree(dsc_pf0); +} + +/* per root port unique with multiple restrictions. For now global */ +static DECLARE_BITMAP(cca_stream_ids, MAX_STREAM_ID); + +static int cca_tsm_connect(struct pci_dev *pdev) +{ + struct pci_dev *rp =3D pcie_find_root_port(pdev); + struct cca_host_dsc_pf0 *dsc_pf0; + struct pci_ide *ide; + int rc, stream_id; + + /* Only function 0 supports connect in host */ + if (WARN_ON(!is_pci_tsm_pf0(pdev))) + return -EIO; + + dsc_pf0 =3D to_cca_dsc_pf0(pdev); + /* Allocate stream id */ + stream_id =3D find_first_zero_bit(cca_stream_ids, MAX_STREAM_ID); + if (stream_id =3D=3D MAX_STREAM_ID) + return -EBUSY; + set_bit(stream_id, cca_stream_ids); + + ide =3D pci_ide_stream_alloc(pdev); + if (!ide) { + rc =3D -ENOMEM; + goto err_stream_alloc; + } + + dsc_pf0->sel_stream =3D ide; + ide->stream_id =3D stream_id; + rc =3D pci_ide_stream_register(ide); + if (rc) + goto err_stream; + + pci_ide_stream_setup(pdev, ide); + pci_ide_stream_setup(rp, ide); + + rc =3D tsm_ide_stream_register(pdev, ide); + if (rc) + goto err_tsm; + + /* + * Once ide is setup enable the stream at endpoint + * Root port will be done by RMM + */ + pci_ide_stream_enable(pdev, ide); + return 0; + +err_tsm: + pci_ide_stream_teardown(rp, ide); + pci_ide_stream_teardown(pdev, ide); + pci_ide_stream_unregister(ide); +err_stream: + pci_ide_stream_free(ide); +err_stream_alloc: + clear_bit(stream_id, cca_stream_ids); + + return rc; +} + +static void cca_tsm_disconnect(struct pci_dev *pdev) +{ + struct pci_dev *rp =3D pcie_find_root_port(pdev); + struct cca_host_dsc_pf0 *dsc_pf0; + struct pci_ide *ide; + + if (WARN_ON(!is_pci_tsm_pf0(pdev))) + return; + + dsc_pf0 =3D to_cca_dsc_pf0(pdev); + ide =3D dsc_pf0->sel_stream; + dsc_pf0->sel_stream =3D NULL; + pci_ide_stream_disable(pdev, ide); + tsm_ide_stream_unregister(ide); + pci_ide_stream_teardown(rp, ide); + pci_ide_stream_teardown(pdev, ide); + pci_ide_stream_unregister(ide); + clear_bit(ide->stream_id, cca_stream_ids); + pci_ide_stream_free(ide); +} + +static const struct pci_tsm_ops cca_pci_ops =3D { + .probe =3D cca_tsm_pci_probe, + .remove =3D cca_tsm_pci_remove, + .connect =3D cca_tsm_connect, + .disconnect =3D cca_tsm_disconnect, +}; + +static void cca_tsm_remove(void *tsm_core) +{ + tsm_unregister(tsm_core); +} + +static int cca_tsm_probe(struct platform_device *pdev) +{ + struct tsm_core_dev *tsm_core; + + tsm_core =3D tsm_register(&pdev->dev, NULL, &cca_pci_ops); + if (IS_ERR(tsm_core)) + return PTR_ERR(tsm_core); + + return devm_add_action_or_reset(&pdev->dev, cca_tsm_remove, tsm_core); +} + +static const struct platform_device_id arm_cca_host_id_table[] =3D { + { RMI_DEV_NAME, 0}, + { } +}; +MODULE_DEVICE_TABLE(platform, arm_cca_host_id_table); + + +static struct platform_driver cca_tsm_platform_driver =3D { + .probe =3D cca_tsm_probe, + .id_table =3D arm_cca_host_id_table, + .driver =3D { + .name =3D "cca_tsm", + }, +}; + +MODULE_IMPORT_NS("PCI_IDE"); +module_platform_driver(cca_tsm_platform_driver); +MODULE_DESCRIPTION("ARM CCA Host TSM driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h new file mode 100644 index 000000000000..840cb584acdd --- /dev/null +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Ltd. + */ + +#ifndef RMM_DA_H_ +#define RMM_DA_H_ + +#include +#include +#include +#include + +struct cca_host_dsc_pf0 { + struct pci_tsm_pf0 pci; + struct pci_ide *sel_stream; +}; + +static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(struct pci_dev *pdev) +{ + struct pci_tsm *tsm =3D pdev->tsm; + + if (!tsm || pdev->is_virtfn || !is_pci_tsm_pf0(pdev)) + return NULL; + + return container_of(tsm, struct cca_host_dsc_pf0, pci.tsm); +} + +#endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 567AE26D4E1; Mon, 28 Jul 2025 13:53:54 +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=1753710834; cv=none; b=BXi6QybvkV7KtZ1Wn5ByOpvDoYbGqi0XdKjE5EELELy0fQAcTVr5TEbyRkkMu4dEB7tW+wJ2Jzo3S1ebmxdW39pXQ3xIB6AFqNLKsW83Yh8ywb4xaIVSywLqoomDTcw/kXhttQmyEh47Frn9/gRImNXNTIasRiBSZbQ1aUC6UVw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710834; c=relaxed/simple; bh=2SwyQ3vlGXa0Nm3vqUWA7biqP68F7YZnLp9tkXwlo4M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DH5yQc3zj9JaF/U9H9cfgHXxfs9AzciFNlhxcYBj23y6zpNpR5ZBMgbM7tJzbPtWmb0y/DfOZkWm8qvW97WSzLMKcYPaS2hPGXH5SptmEN5U+xvZsscUcsO4TTCKCsJFGfAbar7lBj7rP2QoRllwLmNAAveW0Bmv7aqaUS3Ic+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=edxZctTq; 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="edxZctTq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34478C4CEE7; Mon, 28 Jul 2025 13:53:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710834; bh=2SwyQ3vlGXa0Nm3vqUWA7biqP68F7YZnLp9tkXwlo4M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=edxZctTqLQn/0BWxgSyZfk71LkNYxySkxT0ZRaIe8fevY8yJn/N4Rk090WiH5Ss0Y 5kiVPtbIifzVsyTxyC2xC34MWOoX8mhBB9ETOtRRDqrNIzLGq2YXqcZ8a0QjNFiu3D i66wCnbzOQDgRNpuYE2fTcjTP/ZyMLZhWp+TjFaGY5l4EaMK9mNa31qbCjSwrNTSeX jLo0g+KlF1Eclf5rDp5KxoaYjC6PpGMeZOt8KuKzje5PCrhxdE7xlEkDF+l0Ph+nrt y3cCThVEZotoIDCW7nGn6sYyTShwjYACx8wg3QPGD3tiuTsBiE9L27horyiWJlm0K+ jb94J79keriag== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 13/38] coco: host: arm64: Create a PDEV with rmm Date: Mon, 28 Jul 2025 19:21:50 +0530 Message-ID: <20250728135216.48084-14-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Create the realm physical device with RMM. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 31 +++++ arch/arm64/include/asm/rmi_smc.h | 72 ++++++++++- drivers/virt/coco/arm-cca-host/Makefile | 2 +- drivers/virt/coco/arm-cca-host/arm-cca.c | 10 +- drivers/virt/coco/arm-cca-host/rmm-da.c | 150 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 5 + 6 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 drivers/virt/coco/arm-cca-host/rmm-da.c diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index ef53147c1984..f0817bd3bab4 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -505,4 +505,35 @@ static inline int rmi_rtt_unmap_unprotected(unsigned l= ong rd, return res.a0; } =20 +static inline unsigned long rmi_pdev_aux_count(unsigned long flags, u64 *a= ux_count) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_AUX_COUNT, flags, &res); + + *aux_count =3D res.a1; + return res.a0; +} + +static inline unsigned long rmi_pdev_create(unsigned long pdev_phys, + unsigned long pdev_params_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_CREATE, + pdev_phys, pdev_params_phys, &res); + + return res.a0; +} + +static inline unsigned long rmi_pdev_get_state(unsigned long pdev_phys, un= signed long *state) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_GET_STATE, pdev_phys, &res); + + *state =3D res.a1; + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 42708d500048..a84ed61e5001 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -26,7 +26,7 @@ #define SMC_RMI_DATA_CREATE SMC_RMI_CALL(0x0153) #define SMC_RMI_DATA_CREATE_UNKNOWN SMC_RMI_CALL(0x0154) #define SMC_RMI_DATA_DESTROY SMC_RMI_CALL(0x0155) - +#define SMC_RMI_PDEV_AUX_COUNT SMC_RMI_CALL(0x0156) #define SMC_RMI_REALM_ACTIVATE SMC_RMI_CALL(0x0157) #define SMC_RMI_REALM_CREATE SMC_RMI_CALL(0x0158) #define SMC_RMI_REALM_DESTROY SMC_RMI_CALL(0x0159) @@ -47,6 +47,9 @@ #define SMC_RMI_RTT_INIT_RIPAS SMC_RMI_CALL(0x0168) #define SMC_RMI_RTT_SET_RIPAS SMC_RMI_CALL(0x0169) =20 +#define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176) +#define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) + #define RMI_ABI_MAJOR_VERSION 1 #define RMI_ABI_MINOR_VERSION 0 =20 @@ -268,4 +271,71 @@ struct rec_run { struct rec_exit exit; }; =20 +enum rmi_pdev_state { + RMI_PDEV_NEW, + RMI_PDEV_NEEDS_KEY, + RMI_PDEV_HAS_KEY, + RMI_PDEV_READY, + RMI_PDEV_COMMUNICATING, + RMI_PDEV_STOPPING, + RMI_PDEV_STOPPED, + RMI_PDEV_ERROR, +}; + +#define MAX_PDEV_AUX_GRANULES 32 +#define MAX_IOCOH_ADDR_RANGE 16 +#define MAX_FCOH_ADDR_RANGE 4 + +#define RMI_PDEV_SPDM_TRUE BIT(0) +#define RMI_PDEV_IDE_TRUE BIT(1) +#define RMI_PDEV_FOCOH BIT(2) +#define RMI_PDEV_P2P_STREAM BIT(3) + +#define RMI_HASH_SHA_256 0 +#define RMI_HASH_SHA_512 1 + +struct rmi_pdev_addr_range { + unsigned long base; + unsigned long top; +}; + +struct rmi_pdev_params { + union { + struct { + u64 flags; + u64 pdev_id; + u64 segment_id; + u64 ecam_addr; + u64 root_id; + u64 cert_id; + u64 rid_base; + u64 rid_top; + u64 hash_algo; + u64 num_aux; + u64 ide_sid; + u64 ncoh_num_addr_range; + u64 coh_num_addr_range; + }; + u8 padding1[0x100]; + }; + + union { /* 0x100 */ + u64 aux_granule[MAX_PDEV_AUX_GRANULES]; + u8 padding2[0x100]; + }; + + union { /* 0x200 */ + struct { + struct rmi_pdev_addr_range ncoh_addr_range[MAX_IOCOH_ADDR_RANGE]; + }; + u8 padding3[0x100]; + }; + union { /* 0x300 */ + struct { + struct rmi_pdev_addr_range coh_addr_range[MAX_FCOH_ADDR_RANGE]; + }; + u8 padding4[0x100]; + }; +}; + #endif /* __ASM_RMI_SMC_H */ diff --git a/drivers/virt/coco/arm-cca-host/Makefile b/drivers/virt/coco/ar= m-cca-host/Makefile index ad353b07e95a..8409220a6510 100644 --- a/drivers/virt/coco/arm-cca-host/Makefile +++ b/drivers/virt/coco/arm-cca-host/Makefile @@ -2,4 +2,4 @@ # obj-$(CONFIG_ARM_CCA_HOST) +=3D arm-cca-host.o =20 -arm-cca-host-$(CONFIG_TSM) +=3D arm-cca.o +arm-cca-host-$(CONFIG_TSM) +=3D arm-cca.o rmm-da.o diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index c8b0e6db1f47..84d97dd41191 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -124,7 +124,15 @@ static int cca_tsm_connect(struct pci_dev *pdev) rc =3D tsm_ide_stream_register(pdev, ide); if (rc) goto err_tsm; - + /* + * Take a module reference so that we won't call unregister + * without rme_unasign_device + */ + if (!try_module_get(THIS_MODULE)) { + rc =3D -ENXIO; + goto err_tsm; + } + rme_asign_device(pdev); /* * Once ide is setup enable the stream at endpoint * Root port will be done by RMM diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c new file mode 100644 index 000000000000..426e530ac182 --- /dev/null +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include +#include +#include + +#include "rmm-da.h" + +static int pci_res_to_pdev_addr(struct rmi_pdev_addr_range *pdev_addr, + unsigned int naddr, struct resource *res, + unsigned int nres) +{ + int i, j; + + for (i =3D 0, j =3D 0; i < naddr && j < nres; j++) { + if (res[j].flags & IORESOURCE_MEM) { + pdev_addr[i].base =3D res[j].start; + pdev_addr[i].top =3D res[j].end; + i++; + } + } + return i; +} + +static void free_aux_pages(int cnt, void *aux[]) +{ + int ret; + + while (cnt--) { + ret =3D rmi_granule_undelegate(virt_to_phys(aux[cnt])); + if (!ret) + free_page((unsigned long)aux[cnt]); + } +} + +static int init_pdev_params(struct pci_dev *pdev, struct rmi_pdev_params *= params) +{ + void *aux; + int rid, ret, i; + phys_addr_t aux_phys; + struct cca_host_dsc_pf0 *dsc_pf0; + struct pci_dev *rp =3D pcie_find_root_port(pdev); + struct pci_config_window *cfg =3D pdev->bus->sysdata; + + dsc_pf0 =3D to_cca_dsc_pf0(pdev); + /* assign the ep device with RMM */ + rid =3D pci_dev_id(pdev); + params->pdev_id =3D rid; + /* slot number for certificate chain */ + params->cert_id =3D 0; + /* io coherent spdm/ide and non p2p */ + params->flags =3D RMI_PDEV_SPDM_TRUE | RMI_PDEV_IDE_TRUE; + params->ide_sid =3D dsc_pf0->sel_stream->stream_id; + params->hash_algo =3D RMI_HASH_SHA_256; + /* use the rid and MMIO resources of the epdev */ + params->rid_top =3D params->rid_base =3D rid; + params->ecam_addr =3D cfg->res.start; + params->root_id =3D pci_dev_id(rp); + + params->ncoh_num_addr_range =3D pci_res_to_pdev_addr(params->ncoh_addr_ra= nge, + ARRAY_SIZE(params->ncoh_addr_range), + pdev->resource, + DEVICE_COUNT_RESOURCE); + + rmi_pdev_aux_count(params->flags, ¶ms->num_aux); + pr_debug("%s using %ld pdev aux granules\n", __func__, (unsigned long)par= ams->num_aux); + dsc_pf0->num_aux =3D params->num_aux; + for (i =3D 0; i < params->num_aux; i++) { + aux =3D (void *)__get_free_page(GFP_KERNEL); + if (!aux) { + ret =3D -ENOMEM; + goto err_free_aux; + } + + aux_phys =3D virt_to_phys(aux); + if (rmi_granule_delegate(aux_phys)) { + ret =3D -ENXIO; + free_page((unsigned long)aux); + goto err_free_aux; + } + params->aux_granule[i] =3D aux_phys; + dsc_pf0->aux[i] =3D aux; + } + return 0; + +err_free_aux: + free_aux_pages(i, dsc_pf0->aux[i]); + return -ENOMEM; +} + + +int rme_asign_device(struct pci_dev *pci_dev) +{ + int ret; + void *rmm_pdev; + unsigned long state; + phys_addr_t rmm_pdev_phys; + struct rmi_pdev_params *params; + struct cca_host_dsc_pf0 *dsc_pf0; + + dsc_pf0 =3D to_cca_dsc_pf0(pci_dev); + rmm_pdev =3D (void *)get_zeroed_page(GFP_KERNEL); + if (!rmm_pdev) { + ret =3D -ENOMEM; + goto err_out; + } + + rmm_pdev_phys =3D virt_to_phys(rmm_pdev); + if (rmi_granule_delegate(rmm_pdev_phys)) { + ret =3D -ENXIO; + goto err_free_pdev; + } + + params =3D (struct rmi_pdev_params *)get_zeroed_page(GFP_KERNEL); + if (!params) { + ret =3D -ENOMEM; + goto err_granule_undelegate; + } + + ret =3D init_pdev_params(pci_dev, params); + if (ret) + goto err_free_params; + + ret =3D rmi_pdev_create(rmm_pdev_phys, virt_to_phys(params)); + pr_info("rmi_pdev_create(0x%llx, 0x%llx): %d\n", rmm_pdev_phys, virt_to_p= hys(params), ret); + if (ret) + goto err_free_aux; + + rmi_pdev_get_state(rmm_pdev_phys, &state); + if (state !=3D RMI_PDEV_NEW) + goto err_free_aux; + + dsc_pf0->rmm_pdev =3D rmm_pdev; + free_page((unsigned long)params); + return 0; + +err_free_aux: + free_aux_pages(dsc_pf0->num_aux, dsc_pf0->aux); +err_free_params: + free_page((unsigned long)params); +err_granule_undelegate: + rmi_granule_undelegate(rmm_pdev_phys); +err_free_pdev: + free_page((unsigned long)rmm_pdev); +err_out: + return ret; +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 840cb584acdd..179ba68f2430 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -14,6 +14,10 @@ struct cca_host_dsc_pf0 { struct pci_tsm_pf0 pci; struct pci_ide *sel_stream; + + void *rmm_pdev; + int num_aux; + void *aux[MAX_PDEV_AUX_GRANULES]; }; =20 static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(struct pci_dev *pdev) @@ -26,4 +30,5 @@ static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(str= uct pci_dev *pdev) return container_of(tsm, struct cca_host_dsc_pf0, pci.tsm); } =20 +int rme_asign_device(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A76F726B2AE; Mon, 28 Jul 2025 13:53:59 +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=1753710839; cv=none; b=R7AEeyWaDwzBP0RbUqgxEmuSNa/T+repDZS9yxh9hUUOmbHGU86MLZCdpwOYYYD5odeZBBCyO0OLEgaXZ7TMYek0+fcXIZ2Ptg3bslbEbwcKjXw5Kpa0b4g/0fryYOWNOYTx7kyKg53BayH/sYoP5rEyBS10ea7dBjhSg9ZFmKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710839; c=relaxed/simple; bh=pTFLZSrecLAJYJK7PHzfqJWYpecELNS3T10QO0aiFFM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t25hz2yWg9iHJRFDjkWJn19it22GX+mIakDZIEJkPFnI+EUbp585b1ZvxVCfVQbGEGqqMUQ6ftlQfP4oR6SeV7P3g1PRUsTVS+Ygwj78PdPQaS+fXwxpWVC0yxrhrDn1waqdKMPzM5tEAFlTaSaUoUlSAcyW4If9xTQTygHBc8Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K0sMdNLw; 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="K0sMdNLw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB702C4CEFF; Mon, 28 Jul 2025 13:53:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710839; bh=pTFLZSrecLAJYJK7PHzfqJWYpecELNS3T10QO0aiFFM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K0sMdNLwc39LiXKuz8mixWW/o667lasthM0O+hcVRpz0cV+wW3oQ5JY+vRi1+6c0+ zBHgENyjFxc1xmj5zfyrQPj/Vw2O8jCtgMYbsZjPx7Bm0LaYt3sUghpWVgMOyuLPz7 iYxrjDCnndpzcQYuevVpiU3/MsAJmd7K3R3+g+5gsRO77EAa5ysWJFmmuZ+d7bodNY AKLCN9870hSoc9O3d/EGfgt35DDB1tNn+zsN8uh1zirJzD3hcLr8idRAWzb2KcSUiy 0vOddw3HxxpssTyylRBl3Jekqg4bF8nk90cV6djluyHnfPQCcGWb51pIOMDDDBdzts eKSX9AQlNO5nQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 14/38] coco: host: arm64: Device communication support Date: Mon, 28 Jul 2025 19:21:51 +0530 Message-ID: <20250728135216.48084-15-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 helpers for device communication from RMM Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 11 ++ arch/arm64/include/asm/rmi_smc.h | 49 ++++++ drivers/virt/coco/arm-cca-host/arm-cca.c | 45 ++++++ drivers/virt/coco/arm-cca-host/rmm-da.c | 198 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 41 +++++ 5 files changed, 344 insertions(+) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index f0817bd3bab4..eb0034a675bb 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -536,4 +536,15 @@ static inline unsigned long rmi_pdev_get_state(unsigne= d long pdev_phys, unsigned return res.a0; } =20 +static inline unsigned long rmi_pdev_communicate(unsigned long pdev_phys, + unsigned long pdev_comm_data_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_COMMUNICATE, + pdev_phys, pdev_comm_data_phys, &res); + + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index a84ed61e5001..8bece465b670 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -47,6 +47,7 @@ #define SMC_RMI_RTT_INIT_RIPAS SMC_RMI_CALL(0x0168) #define SMC_RMI_RTT_SET_RIPAS SMC_RMI_CALL(0x0169) =20 +#define SMC_RMI_PDEV_COMMUNICATE SMC_RMI_CALL(0x0175) #define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176) #define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) =20 @@ -338,4 +339,52 @@ struct rmi_pdev_params { }; }; =20 +#define RMI_DEV_COMM_EXIT_CACHE_REQ BIT(0) +#define RMI_DEV_COMM_EXIT_CACHE_RSP BIT(1) +#define RMI_DEV_COMM_EXIT_SEND BIT(2) +#define RMI_DEV_COMM_EXIT_WAIT BIT(3) +#define RMI_DEV_COMM_EXIT_MULTI BIT(4) + +#define RMI_DEV_COMM_NONE 0 +#define RMI_DEV_COMM_RESPONSE 1 +#define RMI_DEV_COMM_ERROR 2 + +#define RMI_PROTOCOL_SPDM 0 +#define RMI_PROTOCOL_SECURE_SPDM 1 + +#define RMI_DEV_VCA 0 +#define RMI_DEV_CERTIFICATE 1 +#define RMI_DEV_MEASUREMENTS 2 +#define RMI_DEV_INTERFACE_REPORT 3 + +struct rmi_dev_comm_enter { + u64 status; + u64 req_addr; + u64 resp_addr; + u64 resp_len; +}; + +struct rmi_dev_comm_exit { + u64 flags; + u64 cache_req_offset; + u64 cache_req_len; + u64 cache_rsp_offset; + u64 cache_rsp_len; + u64 cache_obj_id; + u64 protocol; + u64 req_len; + u64 timeout; +}; + +struct rmi_dev_comm_data { + union { /* 0x0 */ + struct rmi_dev_comm_enter enter; + u8 padding_1[0x800]; + }; + union { /* 0x800 */ + struct rmi_dev_comm_exit exit; + u8 padding_2[0x800]; + }; +}; + #endif /* __ASM_RMI_SMC_H */ diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index 84d97dd41191..294a6ef60d5f 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -85,6 +85,45 @@ static void cca_tsm_pci_remove(struct pci_tsm *tsm) vfree(dsc_pf0); } =20 +static int init_dev_communication_buffers(struct cca_host_comm_data *comm_= data) +{ + int ret =3D -ENOMEM; + + comm_data->io_params =3D (struct rmi_dev_comm_data *)get_zeroed_page(GFP_= KERNEL); + if (!comm_data->io_params) + goto err_out; + + comm_data->resp_buff =3D (void *)__get_free_page(GFP_KERNEL); + if (!comm_data->resp_buff) + goto err_res_buff; + + comm_data->req_buff =3D (void *)__get_free_page(GFP_KERNEL); + if (!comm_data->req_buff) + goto err_req_buff; + + + comm_data->io_params->enter.status =3D RMI_DEV_COMM_NONE; + comm_data->io_params->enter.resp_addr =3D virt_to_phys(comm_data->resp_bu= ff); + comm_data->io_params->enter.req_addr =3D virt_to_phys((void *)comm_data-= >req_buff); + comm_data->io_params->enter.resp_len =3D 0; + + return 0; + +err_req_buff: + free_page((unsigned long)comm_data->resp_buff); +err_res_buff: + free_page((unsigned long)comm_data->io_params); +err_out: + return ret; +} + +static inline void free_dev_communication_buffers(struct cca_host_comm_dat= a *comm_data) +{ + free_page((unsigned long)comm_data->req_buff); + free_page((unsigned long)comm_data->resp_buff); + free_page((unsigned long)comm_data->io_params); +} + /* per root port unique with multiple restrictions. For now global */ static DECLARE_BITMAP(cca_stream_ids, MAX_STREAM_ID); =20 @@ -124,6 +163,7 @@ static int cca_tsm_connect(struct pci_dev *pdev) rc =3D tsm_ide_stream_register(pdev, ide); if (rc) goto err_tsm; + init_dev_communication_buffers(&dsc_pf0->comm_data); /* * Take a module reference so that we won't call unregister * without rme_unasign_device @@ -133,6 +173,11 @@ static int cca_tsm_connect(struct pci_dev *pdev) goto err_tsm; } rme_asign_device(pdev); + /* + * Schedule a work to fetch device certificate and setup IDE + */ + schedule_rme_ide_setup(pdev); + /* * Once ide is setup enable the stream at endpoint * Root port will be done by RMM diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index 426e530ac182..d123940ce82e 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -148,3 +148,201 @@ int rme_asign_device(struct pci_dev *pci_dev) err_out: return ret; } + +static int doe_send_req_resp(struct pci_tsm *tsm) +{ + u8 protocol; + int ret, data_obj_type; + struct cca_host_comm_data *comm_data; + struct rmi_dev_comm_exit *io_exit; + + comm_data =3D to_cca_comm_data(tsm->pdev); + + io_exit =3D &comm_data->io_params->exit; + protocol =3D io_exit->protocol; + + pr_debug("doe_req size:%lld doe_io_type=3D%d\n", io_exit->req_len, (int)p= rotocol); + + if (protocol =3D=3D RMI_PROTOCOL_SPDM) + data_obj_type =3D PCI_DOE_PROTO_CMA; + else if (protocol =3D=3D RMI_PROTOCOL_SECURE_SPDM) + data_obj_type =3D PCI_DOE_PROTO_SSESSION; + else + return -EINVAL; + + ret =3D pci_tsm_doe_transfer(tsm->dsm_dev, data_obj_type, + comm_data->req_buff, io_exit->req_len, + comm_data->resp_buff, PAGE_SIZE); + pr_debug("doe returned:%d\n", ret); + return ret; +} + +/* Parallel update for cca_dsc contents FIXME!! */ +static int __do_dev_communicate(int type, struct pci_tsm *tsm) +{ + int ret; + bool is_multi; + u8 *cache_buf; + int *cache_offset; + int nbytes, cache_remaining; + struct cca_host_dsc_pf0 *dsc_pf0; + struct rmi_dev_comm_exit *io_exit; + struct rmi_dev_comm_enter *io_enter; + struct cca_host_comm_data *comm_data; + + + comm_data =3D to_cca_comm_data(tsm->pdev); + io_enter =3D &comm_data->io_params->enter; + io_exit =3D &comm_data->io_params->exit; + + dsc_pf0 =3D to_cca_dsc_pf0(tsm->dsm_dev); +redo_communicate: + is_multi =3D false; + + if (type =3D=3D PDEV_COMMUNICATE) + ret =3D rmi_pdev_communicate(virt_to_phys(dsc_pf0->rmm_pdev), + virt_to_phys(comm_data->io_params)); + else + ret =3D RMI_ERROR_INPUT; + if (ret !=3D RMI_SUCCESS) { + pr_err("pdev communicate error\n"); + return ret; + } + + /* caching request from RMM */ + if (io_exit->flags & RMI_DEV_COMM_EXIT_CACHE_RSP) { + switch (io_exit->cache_obj_id) { + case RMI_DEV_VCA: + cache_buf =3D dsc_pf0->vca.buf; + cache_offset =3D &dsc_pf0->vca.size; + cache_remaining =3D sizeof(dsc_pf0->vca.buf) - *cache_offset; + break; + case RMI_DEV_CERTIFICATE: + cache_buf =3D dsc_pf0->cert_chain.cache.buf; + cache_offset =3D &dsc_pf0->cert_chain.cache.size; + cache_remaining =3D sizeof(dsc_pf0->cert_chain.cache.buf) - *cache_offs= et; + break; + default: + /* FIXME!! depending on the DevComms status, + * it might require to ABORT the communcation. + */ + return -EINVAL; + } + + if (io_exit->cache_rsp_len > cache_remaining) + return -EINVAL; + + memcpy(cache_buf + *cache_offset, + (comm_data->resp_buff + io_exit->cache_rsp_offset), io_exit->cach= e_rsp_len); + *cache_offset +=3D io_exit->cache_rsp_len; + } + + /* + * wait for last packet request from RMM. + * We should not find this because our device communication in synchronous + */ + if (io_exit->flags & RMI_DEV_COMM_EXIT_WAIT) + return -ENXIO; + + is_multi =3D !!(io_exit->flags & RMI_DEV_COMM_EXIT_MULTI); + + /* next packet to send */ + if (io_exit->flags & RMI_DEV_COMM_EXIT_SEND) { + nbytes =3D doe_send_req_resp(tsm); + if (nbytes < 0) { + /* report error back to RMM */ + io_enter->status =3D RMI_DEV_COMM_ERROR; + } else { + /* send response back to RMM */ + io_enter->resp_len =3D nbytes; + io_enter->status =3D RMI_DEV_COMM_RESPONSE; + } + } else { + /* no data transmitted =3D> no data received */ + io_enter->resp_len =3D 0; + } + + /* The call need to do multiple request/respnse */ + if (is_multi) + goto redo_communicate; + + return 0; +} + +static int do_dev_communicate(int type, struct pci_tsm *tsm, int target_st= ate) +{ + int ret; + unsigned long state; + unsigned long error_state; + struct cca_host_dsc_pf0 *dsc_pf0; + struct rmi_dev_comm_enter *io_enter; + + dsc_pf0 =3D to_cca_dsc_pf0(tsm->dsm_dev); + io_enter =3D &dsc_pf0->comm_data.io_params->enter; + io_enter->resp_len =3D 0; + io_enter->status =3D RMI_DEV_COMM_NONE; + + state =3D -1; + do { + ret =3D __do_dev_communicate(type, tsm); + if (ret !=3D 0) { + pr_err("dev communication error\n"); + break; + } + + if (type =3D=3D PDEV_COMMUNICATE) { + ret =3D rmi_pdev_get_state(virt_to_phys(dsc_pf0->rmm_pdev), + &state); + error_state =3D RMI_PDEV_ERROR; + } + if (ret !=3D 0) { + pr_err("Get dev state error\n"); + break; + } + } while (state !=3D target_state && state !=3D error_state); + + pr_info("dev_io_complete: status: %d state:%ld\n", ret, state); + + return state; +} + +static int do_pdev_communicate(struct pci_tsm *tsm, int target_state) +{ + return do_dev_communicate(PDEV_COMMUNICATE, tsm, target_state); +} + +struct dev_comm_work { + struct pci_tsm *tsm; + struct work_struct work; + struct completion complete; +}; + +static void pdev_ide_setup_work(struct work_struct *work) +{ + unsigned long state; + struct pci_tsm *tsm; + struct dev_comm_work *setup_work; + + setup_work =3D container_of(work, struct dev_comm_work, work); + tsm =3D setup_work->tsm; + + state =3D do_pdev_communicate(tsm, RMI_PDEV_NEEDS_KEY); + WARN_ON(state !=3D RMI_PDEV_NEEDS_KEY); + + complete(&setup_work->complete); +} + +int schedule_rme_ide_setup(struct pci_dev *pdev) +{ + struct dev_comm_work setup_work =3D { + .tsm =3D pdev->tsm, + }; + + INIT_WORK_ONSTACK(&setup_work.work, pdev_ide_setup_work); + init_completion(&setup_work.complete); + schedule_work(&setup_work.work); + wait_for_completion(&setup_work.complete); + destroy_work_on_stack(&setup_work.work); + + return 0; +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 179ba68f2430..b9ddc4d9112b 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -11,15 +11,40 @@ #include #include =20 +#define MAX_CACHE_OBJ_SIZE 4096 +struct cache_object { + u8 buf[MAX_CACHE_OBJ_SIZE]; + int size; +}; + +/* dsc =3D device security context */ +struct cca_host_comm_data { + void *resp_buff; + void *req_buff; + struct rmi_dev_comm_data *io_params; +}; + struct cca_host_dsc_pf0 { + struct cca_host_comm_data comm_data; struct pci_tsm_pf0 pci; struct pci_ide *sel_stream; =20 void *rmm_pdev; int num_aux; void *aux[MAX_PDEV_AUX_GRANULES]; + + struct { + struct cache_object cache; + + void *public_key; + size_t public_key_size; + + bool valid; + } cert_chain; + struct cache_object vca; }; =20 +#define PDEV_COMMUNICATE 0x1 static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(struct pci_dev *pdev) { struct pci_tsm *tsm =3D pdev->tsm; @@ -30,5 +55,21 @@ static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(st= ruct pci_dev *pdev) return container_of(tsm, struct cca_host_dsc_pf0, pci.tsm); } =20 +static inline struct cca_host_comm_data *to_cca_comm_data(struct pci_dev *= pdev) +{ + struct cca_host_dsc_pf0 *dsc_pf0; + + dsc_pf0 =3D to_cca_dsc_pf0(pdev); + if (dsc_pf0) + return &dsc_pf0->comm_data; + + dsc_pf0 =3D to_cca_dsc_pf0(pdev->tsm->dsm_dev); + if (dsc_pf0) + return &dsc_pf0->comm_data; + + return NULL; +} + int rme_asign_device(struct pci_dev *pdev); +int schedule_rme_ide_setup(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C721226E6F0; Mon, 28 Jul 2025 13:54:05 +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=1753710845; cv=none; b=ryVZyD/qvvdVgVH391mL9kOASG9bc/nEwqZiTnTFt2r2H+dce4TZ+nFNFyCvIyQ+N2styQ1z53g6rwq+SlAwfgYDfs/cmodfxtqetFhhOk4mQyWWJdAga9b2O9l+5Bq5/NUdPTPHEzp+hqhdAeZdbklYmegGqUrkz/cawrCu5cs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710845; c=relaxed/simple; bh=39NjrON3fdz7R0RVBkNfRuMvDFDaOl+UaCfGWmmBGgE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y7s564zU7aFyDTVSAY2R22fSzcdUncv695LS7TF9STfQwJUKSLfHKkfO6APPV5QGutqWjLh6fEcPfX74a0rjtvcP3DxJj33SCdViHpvThaLTgk1dJto2MoufiNLbZESuqahgGfOFV7FIPRXTL6UNjYuNl9Y0TnZTosqiqk8t4A4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pdTFlHcl; 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="pdTFlHcl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 29E21C4CEF7; Mon, 28 Jul 2025 13:53:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710845; bh=39NjrON3fdz7R0RVBkNfRuMvDFDaOl+UaCfGWmmBGgE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pdTFlHclFtGJaQ3oOwHPM7Oe7iv7kimYB9D4wCfFnTgkGPVT1cFFr4RyglxPqxIxR 4qIfd1db/97/CLSjfa2BTf3yQMQ1NTat77P7UuwCLzwJPPs+WOXYyWoAJcEoNNNA5w 045VTrmWqvU3i5hPW78wSQRoRyVaLQRSRKcMpYMnCYFJW9Yly+l55rXnRKtH8H1K5q 67oHrADgRvnK0vNCZ/5RuAYuh6r3LXfw/BHE3r6+3vFnwbzcEh+Rf0v2XOWu07x8j6 A58IjLzE61E0AE7XHWAuluMHqorZJpo1292KUbOICOw9Ja2YQDY1fefv5ANd53tTQ1 i+wEL05nqn2rQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 15/38] coco: host: arm64: Stop and destroy the physical device Date: Mon, 28 Jul 2025 19:21:52 +0530 Message-ID: <20250728135216.48084-16-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 stopping and destroying physical devices. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 18 ++++++++++++++++++ arch/arm64/include/asm/rmi_smc.h | 2 ++ drivers/virt/coco/arm-cca-host/arm-cca.c | 3 +++ drivers/virt/coco/arm-cca-host/rmm-da.c | 21 +++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 1 + 5 files changed, 45 insertions(+) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index eb0034a675bb..d4ea9f8363f5 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -547,4 +547,22 @@ static inline unsigned long rmi_pdev_communicate(unsig= ned long pdev_phys, return res.a0; } =20 +static inline unsigned long rmi_pdev_stop(unsigned long pdev_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_STOP, pdev_phys, &res); + + return res.a0; +} + +static inline unsigned long rmi_pdev_destroy(unsigned long pdev_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_DESTROY, pdev_phys, &res); + + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 8bece465b670..9f25a876238e 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -49,7 +49,9 @@ =20 #define SMC_RMI_PDEV_COMMUNICATE SMC_RMI_CALL(0x0175) #define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176) +#define SMC_RMI_PDEV_DESTROY SMC_RMI_CALL(0x0177) #define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) +#define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c) =20 #define RMI_ABI_MAJOR_VERSION 1 #define RMI_ABI_MINOR_VERSION 0 diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index 294a6ef60d5f..c65b81f0706f 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -210,12 +210,15 @@ static void cca_tsm_disconnect(struct pci_dev *pdev) ide =3D dsc_pf0->sel_stream; dsc_pf0->sel_stream =3D NULL; pci_ide_stream_disable(pdev, ide); + rme_unassign_device(pdev); + module_put(THIS_MODULE); tsm_ide_stream_unregister(ide); pci_ide_stream_teardown(rp, ide); pci_ide_stream_teardown(pdev, ide); pci_ide_stream_unregister(ide); clear_bit(ide->stream_id, cca_stream_ids); pci_ide_stream_free(ide); + free_dev_communication_buffers(&dsc_pf0->comm_data); } =20 static const struct pci_tsm_ops cca_pci_ops =3D { diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index d123940ce82e..ec8c5bfcee35 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -346,3 +346,24 @@ int schedule_rme_ide_setup(struct pci_dev *pdev) =20 return 0; } + +void rme_unassign_device(struct pci_dev *pdev) +{ + unsigned long ret; + unsigned long state; + phys_addr_t rmm_pdev_phys; + struct cca_host_dsc_pf0 *dsc_pf0; + + dsc_pf0 =3D to_cca_dsc_pf0(pdev); + rmm_pdev_phys =3D virt_to_phys(dsc_pf0->rmm_pdev); + ret =3D rmi_pdev_stop(rmm_pdev_phys); + if (WARN_ON(ret !=3D RMI_SUCCESS)) + return; + + state =3D do_pdev_communicate(pdev->tsm, RMI_PDEV_STOPPED); + /* ignore the error state and destroy the device */ + WARN_ON(state !=3D RMI_PDEV_STOPPED); + ret =3D rmi_pdev_destroy(rmm_pdev_phys); + if (WARN_ON(ret !=3D RMI_SUCCESS)) + return; +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index b9ddc4d9112b..c401be55d770 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -71,5 +71,6 @@ static inline struct cca_host_comm_data *to_cca_comm_data= (struct pci_dev *pdev) } =20 int rme_asign_device(struct pci_dev *pdev); +void rme_unassign_device(struct pci_dev *pdev); int schedule_rme_ide_setup(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6866226FDA3; Mon, 28 Jul 2025 13:54:12 +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=1753710852; cv=none; b=Oq1dBCCaQ7TGkPgL6uPTNGgjM9+d2gu9QDMV9PIv/w3JrF5nXzAUJ8M4Ppp/caCgu+nni50h2CRRNSF7SIpB+at7reqY/+1KArIlGWs6v96r/su3m+1pwQzYPqydi1aY+zvJsjeKyZHrSMjXvDzyfkybtT6likU7XSbrRM/tN4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710852; c=relaxed/simple; bh=Jxd55h7fhwYrRLJ8lptvnzcQtZN9e7g9TUuMgKyZmrY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SUMLKL7JZrcD9FHIdMyRdniI8ElZpt2W/N+r22iKyIWuERFroV5xwd2uO4n1sGlnF0hKT6gU1cJF31Tpg7xJN3cr0Ngg61bDmSJkVvUcvGTG6U7A4KDZKSMkf5tzfkPNL6/B6x4xLPMj/rrJUHfSHB+yZnQYwAbJ+i6qduFUlEQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Fw+tVLme; 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="Fw+tVLme" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 33EE7C4CEFE; Mon, 28 Jul 2025 13:54:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710852; bh=Jxd55h7fhwYrRLJ8lptvnzcQtZN9e7g9TUuMgKyZmrY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fw+tVLmeafGBL3A5bjNn+QEpeihChg+mx2H21ye58w/brTy5j6zODIAGIyZ/5+Ulo 7bf5YFvJj8UuAPdT/uUCvbTFiBaJqf2ccSkbS6v9tR9QfcUQwQx1P8Jii/xzwKiWdq EqdOjiIU05c9O2UonVJRs3Vp69rbKKDLQX5jA15raytP0H5TR1CUTAaQWD8vPWl/Yj bqA5iIq7P8Pu9eaBy9Oq37OFa9FYMGYmf5L/jh62MVVEMKhUI+kBc3jnyCKXAsJ+bK SpPC9BZ1ssQgQFM0EVGZvYf/m2g/srC9nnkBHm0rnRx/z17uXbPD3Gl+kX4A01F03D nPis6KJCCOWlg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , Dan Williams , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Jonathan Cameron Subject: [RFC PATCH v1 16/38] X.509: Make certificate parser public Date: Mon, 28 Jul 2025 19:21:53 +0530 Message-ID: <20250728135216.48084-17-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 From: Lukas Wunner The upcoming support for PCI device authentication with CMA-SPDM (PCIe r6.1 sec 6.31) requires validating the Subject Alternative Name in X.509 certificates. High-level functions for X.509 parsing such as key_create_or_update() throw away the internal, low-level struct x509_certificate after extracting the struct public_key and public_key_signature from it. The Subject Alternative Name is thus inaccessible when using those functions. Afford CMA-SPDM access to the Subject Alternative Name by making struct x509_certificate public, together with the functions for parsing an X.509 certificate into such a struct and freeing such a struct. The private header file x509_parser.h previously included for the definition of time64_t. That definition was since moved to by commit 361a3bf00582 ("time64: Add time64.h header and define struct timespec64"), so adjust the #include directive as part of the move to the new public header file . No functional change intended. Signed-off-by: Lukas Wunner Reviewed-by: Dan Williams Reviewed-by: Ilpo J=C3=A4rvinen Reviewed-by: Jonathan Cameron --- crypto/asymmetric_keys/x509_parser.h | 40 +-------------------- include/keys/x509-parser.h | 53 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 39 deletions(-) create mode 100644 include/keys/x509-parser.h diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/= x509_parser.h index 0688c222806b..39f1521b773d 100644 --- a/crypto/asymmetric_keys/x509_parser.h +++ b/crypto/asymmetric_keys/x509_parser.h @@ -5,49 +5,11 @@ * Written by David Howells (dhowells@redhat.com) */ =20 -#include -#include -#include -#include - -struct x509_certificate { - struct x509_certificate *next; - struct x509_certificate *signer; /* Certificate that signed this one */ - struct public_key *pub; /* Public key details */ - struct public_key_signature *sig; /* Signature parameters */ - char *issuer; /* Name of certificate issuer */ - char *subject; /* Name of certificate subject */ - struct asymmetric_key_id *id; /* Issuer + Serial number */ - struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */ - time64_t valid_from; - time64_t valid_to; - const void *tbs; /* Signed data */ - unsigned tbs_size; /* Size of signed data */ - unsigned raw_sig_size; /* Size of signature */ - const void *raw_sig; /* Signature data */ - const void *raw_serial; /* Raw serial number in ASN.1 */ - unsigned raw_serial_size; - unsigned raw_issuer_size; - const void *raw_issuer; /* Raw issuer name in ASN.1 */ - const void *raw_subject; /* Raw subject name in ASN.1 */ - unsigned raw_subject_size; - unsigned raw_skid_size; - const void *raw_skid; /* Raw subjectKeyId in ASN.1 */ - unsigned index; - bool seen; /* Infinite recursion prevention */ - bool verified; - bool self_signed; /* T if self-signed (check unsupported_sig too) */ - bool unsupported_sig; /* T if signature uses unsupported crypto */ - bool blacklisted; -}; +#include =20 /* * x509_cert_parser.c */ -extern void x509_free_certificate(struct x509_certificate *cert); -DEFINE_FREE(x509_free_certificate, struct x509_certificate *, - if (!IS_ERR(_T)) x509_free_certificate(_T)) -extern struct x509_certificate *x509_cert_parse(const void *data, size_t d= atalen); extern int x509_decode_time(time64_t *_t, size_t hdrlen, unsigned char tag, const unsigned char *value, size_t vlen); diff --git a/include/keys/x509-parser.h b/include/keys/x509-parser.h new file mode 100644 index 000000000000..37436a5c7526 --- /dev/null +++ b/include/keys/x509-parser.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* X.509 certificate parser + * + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#ifndef _KEYS_X509_PARSER_H +#define _KEYS_X509_PARSER_H + +#include +#include +#include +#include + +struct x509_certificate { + struct x509_certificate *next; + struct x509_certificate *signer; /* Certificate that signed this one */ + struct public_key *pub; /* Public key details */ + struct public_key_signature *sig; /* Signature parameters */ + char *issuer; /* Name of certificate issuer */ + char *subject; /* Name of certificate subject */ + struct asymmetric_key_id *id; /* Issuer + Serial number */ + struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */ + time64_t valid_from; + time64_t valid_to; + const void *tbs; /* Signed data */ + unsigned tbs_size; /* Size of signed data */ + unsigned raw_sig_size; /* Size of signature */ + const void *raw_sig; /* Signature data */ + const void *raw_serial; /* Raw serial number in ASN.1 */ + unsigned raw_serial_size; + unsigned raw_issuer_size; + const void *raw_issuer; /* Raw issuer name in ASN.1 */ + const void *raw_subject; /* Raw subject name in ASN.1 */ + unsigned raw_subject_size; + unsigned raw_skid_size; + const void *raw_skid; /* Raw subjectKeyId in ASN.1 */ + unsigned index; + bool seen; /* Infinite recursion prevention */ + bool verified; + bool self_signed; /* T if self-signed (check unsupported_sig too) */ + bool unsupported_sig; /* T if signature uses unsupported crypto */ + bool blacklisted; +}; + +struct x509_certificate *x509_cert_parse(const void *data, size_t datalen); +void x509_free_certificate(struct x509_certificate *cert); + +DEFINE_FREE(x509_free_certificate, struct x509_certificate *, + if (!IS_ERR(_T)) x509_free_certificate(_T)) + +#endif /* _KEYS_X509_PARSER_H */ --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 322562701C8; Mon, 28 Jul 2025 13:54:19 +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=1753710859; cv=none; b=GtFRlqxJKLiwjvkw3Y6+oh8ogNfJ78UOApGBkZj0N7TaWLJkZpTOXmMnrXJelzP6z76WJl/aM5csoxNJtPPoWg1bKty/I4U5kFcC3UGXK/ceJkgaQE7kIn134LayhLdK8A0FYYmknW3+0RS20uJRW29lTAuJsilwOjesDYmRUUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710859; c=relaxed/simple; bh=tQeo2gHr3WzOtcNTI9kRaE714QohDLHrOKasMXl+XLA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ukvIclqya2fmHuTC+FBIBacBSOvH/v+FmU1j8s8jl4L5Yr32H3a/8Et1eHTR1o99orSYCOmj+eWmGznSaYgXtvZX5Jf3W2VVDdGItbEqDX3pLcBqyUfzLa5zb2mwOdHMtwRY+XHYx3F6M6cosP1aj4z99vtUQmR3jfH/wtteIyw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CS8wbfHd; 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="CS8wbfHd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D468CC116B1; Mon, 28 Jul 2025 13:54:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710859; bh=tQeo2gHr3WzOtcNTI9kRaE714QohDLHrOKasMXl+XLA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CS8wbfHd63SixPN09zu+HTRf9TJeLndhmm0Osw+BHGeC7d7LAe+lC5vA7Pzj3eq9O 2Ck9Wmd9FjBZvVRR+b/byx1tqKJxQbDc4p0oiO853/EI4Rf52TQEI8Ad0y1T9FOyII b8sSs4ukqHtc5X2P9SMOM5l94X72UtLnvE5J0aNUc3OW3Mjt1S2y1Crhxgm3ip+PLc eQoiFu5lsv0ZCYgWnz3r1RsC3jjIrNoIMuJswt83o1ReiNCuBhqRZrNyLiH1/Rep3U I/mDd7X5zqwZROVTitGUNQW6akS9ixrbkZC+lpnR6vpu/hU+g1viZn/e8prPbJN8zx 5JS/inHOtTaeA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , Wilfred Mallawa , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Jonathan Cameron , Dan Williams Subject: [RFC PATCH v1 17/38] X.509: Parse Subject Alternative Name in certificates Date: Mon, 28 Jul 2025 19:21:54 +0530 Message-ID: <20250728135216.48084-18-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 From: Lukas Wunner The upcoming support for PCI device authentication with CMA-SPDM (PCIe r6.1 sec 6.31) requires validating the Subject Alternative Name in X.509 certificates. Store a pointer to the Subject Alternative Name upon parsing for consumption by CMA-SPDM. Signed-off-by: Lukas Wunner Reviewed-by: Wilfred Mallawa Reviewed-by: Ilpo J=C3=A4rvinen Reviewed-by: Jonathan Cameron Acked-by: Dan Williams --- crypto/asymmetric_keys/x509_cert_parser.c | 9 +++++++++ include/keys/x509-parser.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_= keys/x509_cert_parser.c index 2ffe4ae90bea..ac8a01c2b9fc 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -571,6 +571,15 @@ int x509_process_extension(void *context, size_t hdrle= n, return 0; } =20 + if (ctx->last_oid =3D=3D OID_subjectAltName) { + if (ctx->cert->raw_san) + return -EBADMSG; + + ctx->cert->raw_san =3D v; + ctx->cert->raw_san_size =3D vlen; + return 0; + } + if (ctx->last_oid =3D=3D OID_keyUsage) { /* * Get hold of the keyUsage bit string diff --git a/include/keys/x509-parser.h b/include/keys/x509-parser.h index 37436a5c7526..8e450befe3b9 100644 --- a/include/keys/x509-parser.h +++ b/include/keys/x509-parser.h @@ -36,6 +36,8 @@ struct x509_certificate { unsigned raw_subject_size; unsigned raw_skid_size; const void *raw_skid; /* Raw subjectKeyId in ASN.1 */ + const void *raw_san; /* Raw subjectAltName in ASN.1 */ + unsigned raw_san_size; unsigned index; bool seen; /* Infinite recursion prevention */ bool verified; --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28289270557; Mon, 28 Jul 2025 13:54:25 +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=1753710865; cv=none; b=rjihfwttdtlDbh0bdM4/VmRjIwAMB5uF0fcEG9Dd3/cyNPodS0MJdcAbHcfDYH1O9I8X1H8wod1lzMKtLZPeT6hYZBgLGNNeyTqMcPXsceXWGRIP72unrzygmCGyey6cV+GAhS5sNi9tGqRhLdG54XbnRdGlyUowhU/hsUZpFTQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710865; c=relaxed/simple; bh=GTTAsUvGA0z7kzwZp8HnqrA/zR5zZGrXrfASn4SucGI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t43FNH0H5kinny5+4fz/1cmkPeWY7GuD4eKTFvOlqndeqMWCA6AIABBN1M7rvXnmHlG5jFZBA50FlltzfKwrkTB2Bvxvkp8hv7Y6LaVVZazPFm2E0OD4mYHRH4687jnllk9xiHoO/CF9SJHiNjje9yrtw+1XUp9ZrV/KvIdmInY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oRFmya0a; 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="oRFmya0a" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A62B6C4CEF8; Mon, 28 Jul 2025 13:54:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710865; bh=GTTAsUvGA0z7kzwZp8HnqrA/zR5zZGrXrfASn4SucGI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oRFmya0a4DXWNnlwzGx9XgWsjNEjKrmnZTPJ3C1+M4bCQiN+XfE+VuUFk6lf1ntuG TwS9+LHT9UjkSgPBjnwKvHvrUFw+LRR0DmK1A8xq2sKPNVGCC735vWbf5qKtdh5MC9 EEDLFeZjMT85vMe9BzRfeJl7yfc+oFUdSmx+SWduIofbW4J77g0dRtQnnUF4Kj2/4C TKWnnS39yiVqjgP/1TeH90xbYcK74Vbqvtj17MJwNThHfKrQJZtarSgPJeJmaWYOwT ZsSQKQ8ZUa8MTM7kR9aXqTs1Xu/S7Ek0reaMCeq+AtCQ/W2qMfWsXLTNsGzPAF8209 5qS1uUJ0cKZfg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , Dan Williams , Jonathan Cameron Subject: [RFC PATCH v1 18/38] X.509: Move certificate length retrieval into new helper Date: Mon, 28 Jul 2025 19:21:55 +0530 Message-ID: <20250728135216.48084-19-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" From: Lukas Wunner The upcoming in-kernel SPDM library (Security Protocol and Data Model, https://www.dmtf.org/dsp/DSP0274) needs to retrieve the length from ASN.1 DER-encoded X.509 certificates. Such code already exists in x509_load_certificate_list(), so move it into a new helper for reuse by SPDM. Export the helper so that SPDM can be tristate. (Some upcoming users of the SPDM libray may be modular, such as SCSI and ATA.) No functional change intended. Signed-off-by: Lukas Wunner Reviewed-by: Dan Williams Reviewed-by: Jonathan Cameron --- crypto/asymmetric_keys/x509_loader.c | 38 +++++++++++++++++++--------- include/keys/asymmetric-type.h | 2 ++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/= x509_loader.c index a41741326998..25ff027fad1d 100644 --- a/crypto/asymmetric_keys/x509_loader.c +++ b/crypto/asymmetric_keys/x509_loader.c @@ -4,28 +4,42 @@ #include #include =20 +ssize_t x509_get_certificate_length(const u8 *p, unsigned long buflen) +{ + ssize_t plen; + + /* Each cert begins with an ASN.1 SEQUENCE tag and must be more + * than 256 bytes in size. + */ + if (buflen < 4) + return -EINVAL; + + if (p[0] !=3D 0x30 && + p[1] !=3D 0x82) + return -EINVAL; + + plen =3D (p[2] << 8) | p[3]; + plen +=3D 4; + if (plen > buflen) + return -EINVAL; + + return plen; +} +EXPORT_SYMBOL_GPL(x509_get_certificate_length); + int x509_load_certificate_list(const u8 cert_list[], const unsigned long list_size, const struct key *keyring) { key_ref_t key; const u8 *p, *end; - size_t plen; + ssize_t plen; =20 p =3D cert_list; end =3D p + list_size; while (p < end) { - /* Each cert begins with an ASN.1 SEQUENCE tag and must be more - * than 256 bytes in size. - */ - if (end - p < 4) - goto dodgy_cert; - if (p[0] !=3D 0x30 && - p[1] !=3D 0x82) - goto dodgy_cert; - plen =3D (p[2] << 8) | p[3]; - plen +=3D 4; - if (plen > end - p) + plen =3D x509_get_certificate_length(p, end - p); + if (plen < 0) goto dodgy_cert; =20 key =3D key_create_or_update(make_key_ref(keyring, 1), diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h index 69a13e1e5b2e..e2af07fec3c6 100644 --- a/include/keys/asymmetric-type.h +++ b/include/keys/asymmetric-type.h @@ -84,6 +84,8 @@ extern struct key *find_asymmetric_key(struct key *keyrin= g, const struct asymmetric_key_id *id_2, bool partial); =20 +ssize_t x509_get_certificate_length(const u8 *p, unsigned long buflen); + int x509_load_certificate_list(const u8 cert_list[], const unsigned long l= ist_size, const struct key *keyring); =20 --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 061BB27146D; Mon, 28 Jul 2025 13:54:31 +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=1753710871; cv=none; b=ttGn8IbB05qM2Eyz8FD3pFIjDmG2cL5TZk6ebC2ZhNX92AFb5J1A/Dk+qMx4OpzEaN9Rmc1O/luXSdk9mwB0Lth3goC5SzNiV6YhZ0kEPldd3p03ClhkaKZOwpTVcJ05f7BCs0fB9l8QR937DTZ98SwBTnwWzVHgcWEW4B4AL0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710871; c=relaxed/simple; bh=NfNusfkzh50PeDCdhq+KciggPStSiL2LRdEwdbf5nLo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bOTLXtNHMlfbg0FsBGCTtsv9oLDEXzskl1lybdN7r3xLol+k25U0uWd5dj4VSbh2HrSrAxZmYCsH1DZ8ZXG0LOczulfk8DMFk/XvAEkYoW7RMCdT3I7BSc+Kvf2wbbAdR/ZftRH/+E/9f7HQNDL1N9k5WlTVDKQ/uOdWRuYuUoA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rozdvDTj; 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="rozdvDTj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3A14C113CF; Mon, 28 Jul 2025 13:54:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710870; bh=NfNusfkzh50PeDCdhq+KciggPStSiL2LRdEwdbf5nLo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rozdvDTjCuZNhT5CtSaslOibx/6eZT1yC7TUZ6mP2seostI1PWLgIgn1jOOnmxrja UVCOlJl18+9Um/GIvRIDCG28yxagcZDBTvF23h/uc+L4ODszt6WcZpjMHQrs3p8eqY nDt07+YEhyJUhOFWTYlCINFZrfLQm7DtFFPMnhv0S6D8WY0sFrB4cHRAN1/ST6/hO9 Hqbdckh1gqKPdMdzWk1eQS1PFvxMKobzpAwNM0NTCN7ZmqXR2CPCRTBGWibkr9Cczh la7rdT6er0acUOuSr4JvTiCg52DuCOP0wG9EA2gk8QA/AlA1dM6sMfwCg0NO6oRONY 22M4v6a563rIg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 19/38] coco: host: arm64: set_pubkey support Date: Mon, 28 Jul 2025 19:21:56 +0530 Message-ID: <20250728135216.48084-20-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 changes to share the device's public key with the RMM. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 9 ++ arch/arm64/include/asm/rmi_smc.h | 18 +++ drivers/virt/coco/arm-cca-host/Kconfig | 4 + drivers/virt/coco/arm-cca-host/rmm-da.c | 150 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 1 + 5 files changed, 182 insertions(+) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index d4ea9f8363f5..aef0b0ee062e 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -565,4 +565,13 @@ static inline unsigned long rmi_pdev_destroy(unsigned = long pdev_phys) return res.a0; } =20 +static inline unsigned long rmi_pdev_set_pubkey(unsigned long pdev_phys, u= nsigned long key_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PDEV_SET_PUBKEY, pdev_phys, key_phys, &res); + + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 9f25a876238e..4a5ba98c1c0d 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -51,6 +51,7 @@ #define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176) #define SMC_RMI_PDEV_DESTROY SMC_RMI_CALL(0x0177) #define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) +#define SMC_RMI_PDEV_SET_PUBKEY SMC_RMI_CALL(0x017b) #define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c) =20 #define RMI_ABI_MAJOR_VERSION 1 @@ -389,4 +390,21 @@ struct rmi_dev_comm_data { }; }; =20 +#define RMI_SIG_RSASSA_3072 0 +#define RMI_SIG_ECDSA_P256 1 +#define RMI_SIG_ECDSA_P384 2 + +struct rmi_public_key_params { + union { + struct { + u8 public_key[1024]; + u8 metadata[1024]; + u64 public_key_len; + u64 metadata_len; + u8 rmi_signature_algorithm; + } __packed; + u8 padding[0x1000]; + }; +}; + #endif /* __ASM_RMI_SMC_H */ diff --git a/drivers/virt/coco/arm-cca-host/Kconfig b/drivers/virt/coco/arm= -cca-host/Kconfig index 0f19fbf47613..a5b777f0d50e 100644 --- a/drivers/virt/coco/arm-cca-host/Kconfig +++ b/drivers/virt/coco/arm-cca-host/Kconfig @@ -6,7 +6,11 @@ config ARM_CCA_HOST tristate "Arm CCA Host driver" depends on ARM64 depends on PCI_TSM + select KEYS + select X509_CERTIFICATE_PARSER select TSM + select CRYPTO_ECDSA + select CRYPTO_RSA =20 help The driver provides TSM backend for ARM CCA diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index ec8c5bfcee35..3715e6d58c83 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include =20 #include "rmm-da.h" =20 @@ -311,6 +314,136 @@ static int do_pdev_communicate(struct pci_tsm *tsm, i= nt target_state) return do_dev_communicate(PDEV_COMMUNICATE, tsm, target_state); } =20 +static int parse_certificate_chain(struct pci_tsm *tsm) +{ + struct cca_host_dsc_pf0 *dsc_pf0; + unsigned int chain_size; + unsigned int offset =3D 0; + u8 *chain_data; + int ret =3D 0; + + dsc_pf0 =3D to_cca_dsc_pf0(tsm->pdev); + chain_size =3D dsc_pf0->cert_chain.cache.size; + chain_data =3D dsc_pf0->cert_chain.cache.buf; + + while (offset < chain_size) { + unsigned int cert_len =3D + x509_get_certificate_length(chain_data + offset, + chain_size - offset); + struct x509_certificate *cert =3D + x509_cert_parse(chain_data + offset, cert_len); + + if (IS_ERR(cert)) { + pr_warn("%s(): parsing of certificate chain not successful\n", __func__= ); + ret =3D PTR_ERR(cert); + break; + } + + if (offset + cert_len =3D=3D chain_size) { + dsc_pf0->cert_chain.public_key =3D kzalloc(cert->pub->keylen, GFP_KERNE= L); + if (!dsc_pf0->cert_chain.public_key) { + ret =3D -ENOMEM; + x509_free_certificate(cert); + break; + } + + if (!strcmp("ecdsa-nist-p256", cert->pub->pkey_algo)) { + dsc_pf0->rmi_signature_algorithm =3D RMI_SIG_ECDSA_P256; + } else if (!strcmp("ecdsa-nist-p384", cert->pub->pkey_algo)) { + dsc_pf0->rmi_signature_algorithm =3D RMI_SIG_ECDSA_P384; + } else if (!strcmp("rsa", cert->pub->pkey_algo)) { + dsc_pf0->rmi_signature_algorithm =3D RMI_SIG_RSASSA_3072; + } else { + ret =3D -ENXIO; + x509_free_certificate(cert); + break; + } + memcpy(dsc_pf0->cert_chain.public_key, cert->pub->key, cert->pub->keyle= n); + dsc_pf0->cert_chain.public_key_size =3D cert->pub->keylen; + } + + x509_free_certificate(cert); + + offset +=3D cert_len; + } + + if (ret =3D=3D 0) + dsc_pf0->cert_chain.valid =3D true; + + return ret; +} + +static int pdev_set_public_key(struct pci_tsm *tsm) +{ + struct rmi_public_key_params *key_shared; + unsigned long expected_key_len =3D 0; + struct cca_host_dsc_pf0 *dsc_pf0; + int ret; + + dsc_pf0 =3D to_cca_dsc_pf0(tsm->pdev); + /* Check that all the necessary information was captured from communicati= on */ + if (!dsc_pf0->cert_chain.valid) + return -EINVAL; + + key_shared =3D (struct rmi_public_key_params *)get_zeroed_page(GFP_KERNEL= ); + if (!key_shared) + return -ENOMEM; + + key_shared->rmi_signature_algorithm =3D dsc_pf0->rmi_signature_algorithm; + + switch (key_shared->rmi_signature_algorithm) { + case RMI_SIG_ECDSA_P384: + expected_key_len =3D 97; + + if (dsc_pf0->cert_chain.public_key_size !=3D expected_key_len) + return -EINVAL; + key_shared->public_key_len =3D dsc_pf0->cert_chain.public_key_size; + memcpy(key_shared->public_key, + dsc_pf0->cert_chain.public_key, + dsc_pf0->cert_chain.public_key_size); + key_shared->metadata_len =3D 0; + break; + case RMI_SIG_ECDSA_P256: + expected_key_len =3D 65; + + if (dsc_pf0->cert_chain.public_key_size !=3D expected_key_len) + return -EINVAL; + key_shared->public_key_len =3D dsc_pf0->cert_chain.public_key_size; + memcpy(key_shared->public_key, + dsc_pf0->cert_chain.public_key, + dsc_pf0->cert_chain.public_key_size); + key_shared->metadata_len =3D 0; + break; + case RMI_SIG_RSASSA_3072: + expected_key_len =3D 385; + struct rsa_key rsa_key =3D {0}; + int ret_rsa_parse =3D rsa_parse_pub_key(&rsa_key, + dsc_pf0->cert_chain.public_key, + dsc_pf0->cert_chain.public_key_size); + /* This also checks the key_len */ + if (ret_rsa_parse) + return ret_rsa_parse; + /* + * exponent is usally 65537 (size =3D 24bits) but in rare cases + * it size can be as large as the modulus + */ + if (rsa_key.e_sz > expected_key_len) + return -EINVAL; + key_shared->public_key_len =3D rsa_key.n_sz; + key_shared->metadata_len =3D rsa_key.e_sz; + memcpy(key_shared->public_key, (unsigned char *)rsa_key.n, rsa_key.n_sz); + memcpy(key_shared->metadata, (unsigned char *)rsa_key.e, rsa_key.e_sz); + break; + default: + return -EINVAL; + } + + ret =3D rmi_pdev_set_pubkey(virt_to_phys(dsc_pf0->rmm_pdev), + virt_to_phys(key_shared)); + free_page((unsigned long)key_shared); + return ret; +} + struct dev_comm_work { struct pci_tsm *tsm; struct work_struct work; @@ -319,6 +452,7 @@ struct dev_comm_work { =20 static void pdev_ide_setup_work(struct work_struct *work) { + int ret; unsigned long state; struct pci_tsm *tsm; struct dev_comm_work *setup_work; @@ -329,6 +463,22 @@ static void pdev_ide_setup_work(struct work_struct *wo= rk) state =3D do_pdev_communicate(tsm, RMI_PDEV_NEEDS_KEY); WARN_ON(state !=3D RMI_PDEV_NEEDS_KEY); =20 + /* + * we now have certificate chain in dsm->cert_chain. Parse + * that and set the pubkey. + */ + ret =3D parse_certificate_chain(tsm); + if (ret) + goto err_out; + + ret =3D pdev_set_public_key(tsm); + if (ret) + goto err_out; + + state =3D do_pdev_communicate(tsm, RMI_PDEV_READY); + WARN_ON(state !=3D RMI_PDEV_READY); + +err_out: complete(&setup_work->complete); } =20 diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index c401be55d770..03c3149b8a98 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -33,6 +33,7 @@ struct cca_host_dsc_pf0 { int num_aux; void *aux[MAX_PDEV_AUX_GRANULES]; =20 + uint8_t rmi_signature_algorithm; struct { struct cache_object cache; =20 --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 092E3266B64; Mon, 28 Jul 2025 13:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710878; cv=none; b=dz/BWujlJWetLT94hzyyWN8QqSFBOgYlBSvlUMEAF0mKUE1LojdhZvPmwyVKeOdeaEBa3IUX0DedMCOpk8wzlZMmyr12git9XI/+quJpDEaOUz5wOPzDI6vSKir7n33jCrYqTp52VPAvuB7l+RROimpdf6HoLfz59Fm4qTbkG94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710878; c=relaxed/simple; bh=+O/Ekqre//pHRoxg1Kfr3iyIx8FWcqaOqXHmmmNgPiI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iWTlTfcIs6QgKpF7w1uorCTXsWxMkduaT+DZAqjAf5zvTEWCC45tLGUA/UCUXrWGb2IPklS8J4/V9mw1Vx0RzCHMyvAmytS2UNz+Kla8+s/vv/U5bLf45Qj/FgsG2tLjie8bs2ppmaBeKaD6JZdSRMCHpL9S27Ja73v+ue7FQNg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ulgfYV/j; 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="ulgfYV/j" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 95EF6C4CEE7; Mon, 28 Jul 2025 13:54:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710876; bh=+O/Ekqre//pHRoxg1Kfr3iyIx8FWcqaOqXHmmmNgPiI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ulgfYV/jNL7gXEFZR+Y0s+wwjgiB0l8I7uKkh5I/Xws+j0YXbEvG5zUsyrdW4nOoN 9MiuBBvLYi2Kw4nDvdKibDmZBq3AHQM3O+BKdhTQUGz3kvOgRxByDYALCjsMu7CpfD 4h6PfmKTO5ltOkOwAHW8CVQDyOb7HCz8eMDNXeIeWdEvWyOH7uttWJitx292kBSajA l9ehAdhfLK+L5ivNEyvHCkPGFC0PF57JOQxKsjRo5565wkx0SG7Bsi5cLysffUIxGp Ja3JbD50NsPVZtu1dgOTEh1I5n1wDi9BAilV0/OnX7k+g/1K8gt2/ucyCmee01SPvD E6rdj3LZBN4vQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 20/38] coco: host: arm64: Add support for creating a virtual device Date: Mon, 28 Jul 2025 19:21:57 +0530 Message-ID: <20250728135216.48084-21-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Changes to support the creation of virtual device objects with RMM. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 13 +++++ arch/arm64/include/asm/rmi_smc.h | 30 +++++++++++ drivers/virt/coco/arm-cca-host/Kconfig | 1 + drivers/virt/coco/arm-cca-host/arm-cca.c | 30 +++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.c | 67 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 17 ++++++ 6 files changed, 158 insertions(+) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index aef0b0ee062e..7d91f847069b 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -574,4 +574,17 @@ static inline unsigned long rmi_pdev_set_pubkey(unsign= ed long pdev_phys, unsigne return res.a0; } =20 +static inline unsigned long rmi_vdev_create(unsigned long rd, + unsigned long pdev_phys, + unsigned long vdev_phys, + unsigned long vdev_params_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_CREATE, rd, pdev_phys, + vdev_phys, vdev_params_phys, &res); + + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 4a5ba98c1c0d..e5238b271493 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -53,6 +53,8 @@ #define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) #define SMC_RMI_PDEV_SET_PUBKEY SMC_RMI_CALL(0x017b) #define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c) +#define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187) + =20 #define RMI_ABI_MAJOR_VERSION 1 #define RMI_ABI_MINOR_VERSION 0 @@ -407,4 +409,32 @@ struct rmi_public_key_params { }; }; =20 +enum rmi_vdev_state { + RMI_VDEV_READY, + RMI_VDEV_COMMUNICATING, + RMI_VDEV_STOPPING, + RMI_VDEV_STOPPED, + RMI_VDEV_ERROR, +}; + +#define MAX_VDEV_AUX_GRANULES 32 + +struct rmi_vdev_params { + union { + struct { + u64 flags; + u64 vdev_id; + u64 tdi_id; + u64 num_aux; + }; + u8 padding1[0x100]; + }; + union { /* 0x100 */ + struct { + unsigned long aux[MAX_VDEV_AUX_GRANULES]; + }; + u8 padding2[0x900]; + }; +}; + #endif /* __ASM_RMI_SMC_H */ diff --git a/drivers/virt/coco/arm-cca-host/Kconfig b/drivers/virt/coco/arm= -cca-host/Kconfig index a5b777f0d50e..52ed1cd5f06a 100644 --- a/drivers/virt/coco/arm-cca-host/Kconfig +++ b/drivers/virt/coco/arm-cca-host/Kconfig @@ -6,6 +6,7 @@ config ARM_CCA_HOST tristate "Arm CCA Host driver" depends on ARM64 depends on PCI_TSM + depends on KVM select KEYS select X509_CERTIFICATE_PARSER select TSM diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index c65b81f0706f..2da513f45974 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include =20 #include "rmm-da.h" =20 @@ -221,11 +223,39 @@ static void cca_tsm_disconnect(struct pci_dev *pdev) free_dev_communication_buffers(&dsc_pf0->comm_data); } =20 +static struct pci_tdi *cca_tsm_bind(struct pci_dev *pdev, struct pci_dev *= pf0_dev, + struct kvm *kvm, u64 tdi_id) +{ + void *rmm_vdev; + struct cca_host_tdi *host_tdi __free(kfree) =3D NULL; + struct realm *realm =3D &kvm->arch.realm; + + if (pdev->is_virtfn) + return ERR_PTR(-ENXIO); + + if (!try_module_get(THIS_MODULE)) + return ERR_PTR(-ENXIO); + + host_tdi =3D kmalloc(sizeof(struct cca_host_tdi), GFP_KERNEL); + if (!host_tdi) + return ERR_PTR(-ENOMEM); + + rmm_vdev =3D rme_create_vdev(realm, pdev, pf0_dev, tdi_id); + if (!IS_ERR_OR_NULL(rmm_vdev)) { + host_tdi->rmm_vdev =3D rmm_vdev; + return &no_free_ptr(host_tdi)->tdi; + } + + module_put(THIS_MODULE); + return rmm_vdev; +} + static const struct pci_tsm_ops cca_pci_ops =3D { .probe =3D cca_tsm_pci_probe, .remove =3D cca_tsm_pci_remove, .connect =3D cca_tsm_connect, .disconnect =3D cca_tsm_disconnect, + .bind =3D cca_tsm_bind, }; =20 static void cca_tsm_remove(void *tsm_core) diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index 3715e6d58c83..41314db1d568 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include =20 #include "rmm-da.h" =20 @@ -517,3 +519,68 @@ void rme_unassign_device(struct pci_dev *pdev) if (WARN_ON(ret !=3D RMI_SUCCESS)) return; } + +static unsigned long pci_get_tdi_id(struct pci_dev *pdev) +{ + /* requester segment is marked reserved. */ + return pci_dev_id(pdev); + +} + +void *rme_create_vdev(struct realm *realm, struct pci_dev *pdev, + struct pci_dev *pf0_dev, u32 guest_rid) +{ + phys_addr_t rd_phys =3D virt_to_phys(realm->rd); + struct rmi_vdev_params *params =3D NULL; + struct cca_host_dsc_pf0 *dsc_pf0; + phys_addr_t rmm_pdev_phys; + phys_addr_t rmm_vdev_phys; + void *rmm_vdev; + int ret; + + dsc_pf0 =3D to_cca_dsc_pf0(pf0_dev); + if (!dsc_pf0->rmm_pdev) { + ret =3D -EINVAL; + goto err_out; + } + + rmm_vdev =3D (void *)get_zeroed_page(GFP_KERNEL); + if (!rmm_vdev) { + ret =3D -ENOMEM; + goto err_out; + } + + rmm_vdev_phys =3D virt_to_phys(rmm_vdev); + if (rmi_granule_delegate(rmm_vdev_phys)) { + ret =3D -ENXIO; + goto err_free_vdev; + } + + params =3D (struct rmi_vdev_params *)get_zeroed_page(GFP_KERNEL); + if (!params) { + ret =3D -ENOMEM; + goto err_granule_undelegate; + } + + params->flags =3D 0; + params->vdev_id =3D guest_rid; + params->tdi_id =3D pci_get_tdi_id(pdev); + params->num_aux =3D 0; + + rmm_pdev_phys =3D virt_to_phys(dsc_pf0->rmm_pdev); + ret =3D rmi_vdev_create(rd_phys, rmm_pdev_phys, + rmm_vdev_phys, virt_to_phys(params)); + if (ret) + goto err_granule_undelegate; + + free_page((unsigned long)params); + return rmm_vdev; + +err_granule_undelegate: + rmi_granule_undelegate(rmm_vdev_phys); +err_free_vdev: + free_page((unsigned long)rmm_vdev); + free_page((unsigned long)params); +err_out: + return ERR_PTR(ret); +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 03c3149b8a98..6d612ea3b87f 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -45,6 +45,11 @@ struct cca_host_dsc_pf0 { struct cache_object vca; }; =20 +struct cca_host_tdi { + struct pci_tdi tdi; + void *rmm_vdev; +}; + #define PDEV_COMMUNICATE 0x1 static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(struct pci_dev *pdev) { @@ -71,7 +76,19 @@ static inline struct cca_host_comm_data *to_cca_comm_dat= a(struct pci_dev *pdev) return NULL; } =20 +static inline struct cca_host_tdi *to_cca_host_tdi(struct pci_dev *pdev) +{ + struct pci_tsm *tsm =3D pdev->tsm; + + if (!tsm || !tsm->tdi) + return NULL; + + return container_of(tsm->tdi, struct cca_host_tdi, tdi); +} + int rme_asign_device(struct pci_dev *pdev); void rme_unassign_device(struct pci_dev *pdev); int schedule_rme_ide_setup(struct pci_dev *pdev); +void *rme_create_vdev(struct realm *realm, struct pci_dev *pdev, + struct pci_dev *pf0_dev, u32 guest_rid); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BCFB2701DC; Mon, 28 Jul 2025 13:54:43 +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=1753710883; cv=none; b=tB4hPGqqu9Au41zeOB4XHDj+RpKceK2kD9qEpjAAj3JTJeKn8TEVIp+OH83du1yFIFxcGEXBppR4TUIM/TdUaOg44P/y8cd2jSWU+H/ASDX/1sJadHPkk3SvnvqsYBNmFW4R70GjnYI/AGyQPougtWPDz0UwqPo/ei9PJOoVCEk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710883; c=relaxed/simple; bh=ca64YW29BY+3yIJN+Yk7BMDE8wvfxyvVL6RXDmvMNyo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cjXXjTFpiq7U+AgB8G81Mpvo6IkGhI8trTHC+lOIpSkIrkIc4DhPQEVcKGnthIHjSGbSKmMi8QrLKroGDVwJtAkVpiOpDWGeBvxcPVHauKEEsxJW+gvTY4UC0hezDewa3kspig4arApZWMs/kH92IjS1xsCaSfp5OkcCcOmNWTg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=p1OMyLaW; 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="p1OMyLaW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 604A4C4CEEF; Mon, 28 Jul 2025 13:54:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710883; bh=ca64YW29BY+3yIJN+Yk7BMDE8wvfxyvVL6RXDmvMNyo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p1OMyLaWhvCNRDeCNZRukzEocmJ0dFl7+RLKUeM9FqtqhPViDI9p7YGHOUMa42vKW VhGqcHqQgv+ZMcw8nSR6nr8PmdU1YtrvViSMoriSwH10QDPok3euRktO+e1ge8Jxpl iRWEvBfNPIKYJEdR1CKWkdvkH7+ZIvIcErteCyvhdS3NhMfIdMI0a4nGqBzvR6/j1+ Z3HBdqH9HC0bcKgEv1zu3pYQJkRRwzB/hwmAd685vjf51ZdnZjwur9gp7V5dwOGKFo 5qwBernyZOOCI937jw73EIJXmixAe6Ifhz23oB/+70LvPxJVC4wD+KU7qEAiqlmLI0 D5nOF9A5eoCkA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 21/38] coco: host: arm64: Add support for virtual device communication Date: Mon, 28 Jul 2025 19:21:58 +0530 Message-ID: <20250728135216.48084-22-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 vdev_communicate with RMM. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 22 ++++++++++++++++++++++ arch/arm64/include/asm/rmi_smc.h | 2 ++ drivers/virt/coco/arm-cca-host/rmm-da.c | 21 +++++++++++++++++++-- drivers/virt/coco/arm-cca-host/rmm-da.h | 2 ++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index 7d91f847069b..25197f47a0a9 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -587,4 +587,26 @@ static inline unsigned long rmi_vdev_create(unsigned l= ong rd, return res.a0; } =20 +static inline unsigned long rmi_vdev_communicate(unsigned long pdev_phys, + unsigned long vdev_phys, + unsigned long vdev_comm_data_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_COMMUNICATE, + pdev_phys, vdev_phys, vdev_comm_data_phys, &res); + + return res.a0; +} + +static inline unsigned long rmi_vdev_get_state(unsigned long vdev_phys, un= signed long *state) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_GET_STATE, vdev_phys, &res); + + *state =3D res.a1; + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index e5238b271493..127dd0938604 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -53,7 +53,9 @@ #define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) #define SMC_RMI_PDEV_SET_PUBKEY SMC_RMI_CALL(0x017b) #define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c) +#define SMC_RMI_VDEV_COMMUNICATE SMC_RMI_CALL(0x0186) #define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187) +#define SMC_RMI_VDEV_GET_STATE SMC_RMI_CALL(0x0189) =20 =20 #define RMI_ABI_MAJOR_VERSION 1 diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index 41314db1d568..8635f361bbe8 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -207,8 +207,14 @@ static int __do_dev_communicate(int type, struct pci_t= sm *tsm) if (type =3D=3D PDEV_COMMUNICATE) ret =3D rmi_pdev_communicate(virt_to_phys(dsc_pf0->rmm_pdev), virt_to_phys(comm_data->io_params)); - else - ret =3D RMI_ERROR_INPUT; + else { + struct cca_host_tdi *host_tdi =3D container_of(tsm->tdi, struct cca_host= _tdi, tdi); + + ret =3D rmi_vdev_communicate(virt_to_phys(dsc_pf0->rmm_pdev), + virt_to_phys(host_tdi->rmm_vdev), + virt_to_phys(comm_data->io_params)); + } + if (ret !=3D RMI_SUCCESS) { pr_err("pdev communicate error\n"); return ret; @@ -299,6 +305,12 @@ static int do_dev_communicate(int type, struct pci_tsm= *tsm, int target_state) ret =3D rmi_pdev_get_state(virt_to_phys(dsc_pf0->rmm_pdev), &state); error_state =3D RMI_PDEV_ERROR; + } else { + struct cca_host_tdi *host_tdi =3D container_of(tsm->tdi, struct cca_hos= t_tdi, tdi); + + ret =3D rmi_vdev_get_state(virt_to_phys(host_tdi->rmm_vdev), + &state); + error_state =3D RMI_VDEV_ERROR; } if (ret !=3D 0) { pr_err("Get dev state error\n"); @@ -584,3 +596,8 @@ void *rme_create_vdev(struct realm *realm, struct pci_d= ev *pdev, err_out: return ERR_PTR(ret); } + +static int __maybe_unused do_vdev_communicate(struct pci_tsm *tsm, int tar= get_state) +{ + return do_dev_communicate(VDEV_COMMUNICATE, tsm, target_state); +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 6d612ea3b87f..37a8f4dce68e 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -51,6 +51,8 @@ struct cca_host_tdi { }; =20 #define PDEV_COMMUNICATE 0x1 +#define VDEV_COMMUNICATE 0x2 + static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(struct pci_dev *pdev) { struct pci_tsm *tsm =3D pdev->tsm; --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFF592701DC; Mon, 28 Jul 2025 13:54:48 +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=1753710888; cv=none; b=so9pYhPJMJr5BE+TKiKPcgr9bx+ITYx9hTqL6f+q2ue70RZmQW5mUpLzKDE5it4T8PIB/xYqZZOB/oKCBAVuM0Wkua5Ox7Ju30Z5x73r/SMl7P4oHVF0z9IZDN3kb9GZpolhq5zqe2iVYFbKlSFuBz7cBxqNVia1ODTJsJI9wz0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710888; c=relaxed/simple; bh=b0HLfMpilQyrnxIwwp5ybtMAfIvQ43yfDBQfDKLvSC8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SaydVsH+Clrr4UXFy3I4BL0r95mliwQMRD6BKlVvIrne8Kq5R6nOSw6IC/MbK1fjmh4RPm59OSAgNVUfLk9+Nr/NfvzVeN7TVP2EOJSNNw8FywRJuGq5E2kFug82MkESgm4B+dan7JXADjQkC8fNiXsf+d1jtHBXiBPQg62b4Ac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=T3cvtuBs; 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="T3cvtuBs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E20BC4CEFD; Mon, 28 Jul 2025 13:54:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710888; bh=b0HLfMpilQyrnxIwwp5ybtMAfIvQ43yfDBQfDKLvSC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T3cvtuBsxK9RgbLvp+iqcef4RKnKaapKnlrrC1pM4FzBJN8XGTfgS71LpHgsLpItJ X+F6nKDSVjJbKHHXprl2Jdt+bOCVeQQQJrtQiRlfkz/tVURgR3DmNfnZdI1E23kRQ5 uefrvoO8bVFnoLq7Ldd1bHu3XUXBRzFkYaarf/ZHgc/8V0+QnrNCPthZd3wKfgTaY8 bXEGGb38jFUDZPs3DRTN2J8gpf6MQKx/J80BewcRX8VPqQc5zlMvILpEDXa4q17q73 rF3BrSX195NkhMPnSU6OAXY03R1SlJ+AeXLV53uGYGlBQnh0/hDUq+q/lAA5MRjeiz GUcNx+pbzCeog== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 22/38] coco: host: arm64: Stop and destroy virtual device Date: Mon, 28 Jul 2025 19:21:59 +0530 Message-ID: <20250728135216.48084-23-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 vdev_stop and vdev_destroy. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 21 ++++++++ arch/arm64/include/asm/rmi_smc.h | 3 +- drivers/virt/coco/arm-cca-host/arm-cca.c | 10 ++++ drivers/virt/coco/arm-cca-host/rmm-da.c | 61 +++++++++++++++++++++++- drivers/virt/coco/arm-cca-host/rmm-da.h | 2 + 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index 25197f47a0a9..eb4f67eb6b01 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -609,4 +609,25 @@ static inline unsigned long rmi_vdev_get_state(unsigne= d long vdev_phys, unsigned return res.a0; } =20 +static inline unsigned long rmi_vdev_stop(unsigned long vdev_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_STOP, vdev_phys, &res); + + return res.a0; +} + +static inline unsigned long rmi_vdev_destroy(unsigned long rd, + unsigned long pdev_phys, + unsigned long vdev_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_DESTROY, rd, pdev_phys, vdev_phys, &res= ); + + return res.a0; +} + + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 127dd0938604..c6e16ab608e1 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -55,8 +55,9 @@ #define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c) #define SMC_RMI_VDEV_COMMUNICATE SMC_RMI_CALL(0x0186) #define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187) +#define SMC_RMI_VDEV_DESTROY SMC_RMI_CALL(0x0188) #define SMC_RMI_VDEV_GET_STATE SMC_RMI_CALL(0x0189) - +#define SMC_RMI_VDEV_STOP SMC_RMI_CALL(0x018A) =20 #define RMI_ABI_MAJOR_VERSION 1 #define RMI_ABI_MINOR_VERSION 0 diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index 2da513f45974..3792d7b5cb99 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -250,12 +250,22 @@ static struct pci_tdi *cca_tsm_bind(struct pci_dev *p= dev, struct pci_dev *pf0_de return rmm_vdev; } =20 +static void cca_tsm_unbind(struct pci_tdi *tdi) +{ + struct realm *realm =3D &tdi->kvm->arch.realm; + + rme_unbind_vdev(realm, tdi->pdev, tdi->pdev->tsm->dsm_dev); + + module_put(THIS_MODULE); +} + static const struct pci_tsm_ops cca_pci_ops =3D { .probe =3D cca_tsm_pci_probe, .remove =3D cca_tsm_pci_remove, .connect =3D cca_tsm_connect, .disconnect =3D cca_tsm_disconnect, .bind =3D cca_tsm_bind, + .unbind =3D cca_tsm_unbind, }; =20 static void cca_tsm_remove(void *tsm_core) diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index 8635f361bbe8..53072610fa67 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -597,7 +597,66 @@ void *rme_create_vdev(struct realm *realm, struct pci_= dev *pdev, return ERR_PTR(ret); } =20 -static int __maybe_unused do_vdev_communicate(struct pci_tsm *tsm, int tar= get_state) +static int do_vdev_communicate(struct pci_tsm *tsm, int target_state) { return do_dev_communicate(VDEV_COMMUNICATE, tsm, target_state); } + +static void vdev_stop_work(struct work_struct *work) +{ + struct dev_comm_work *stop_work; + struct pci_tsm *tsm; + unsigned long state; + + stop_work =3D container_of(work, struct dev_comm_work, work); + tsm =3D stop_work->tsm; + + state =3D do_vdev_communicate(tsm, RMI_VDEV_STOPPED); + WARN_ON(state !=3D RMI_VDEV_STOPPED); + + complete(&stop_work->complete); +} + +static int schedule_vdev_unbind(struct pci_dev *pdev) +{ + struct dev_comm_work unbind_work =3D { + .tsm =3D pdev->tsm, + }; + + INIT_WORK_ONSTACK(&unbind_work.work, vdev_stop_work); + init_completion(&unbind_work.complete); + schedule_work(&unbind_work.work); + wait_for_completion(&unbind_work.complete); + destroy_work_on_stack(&unbind_work.work); + + return 0; +} + +void rme_unbind_vdev(struct realm *realm, struct pci_dev *pdev, struct pci= _dev *pf0_dev) +{ + int ret; + phys_addr_t rmm_pdev_phys; + phys_addr_t rmm_vdev_phys; + struct cca_host_dsc_pf0 *dsc_pf0; + struct cca_host_tdi *host_tdi; + phys_addr_t rd_phys =3D virt_to_phys(realm->rd); + + host_tdi =3D container_of(pdev->tsm->tdi, struct cca_host_tdi, tdi); + rmm_vdev_phys =3D virt_to_phys(host_tdi->rmm_vdev); + + dsc_pf0 =3D to_cca_dsc_pf0(pf0_dev); + rmm_pdev_phys =3D virt_to_phys(dsc_pf0->rmm_pdev); + /* Request stopping the VDEV */ + ret =3D rmi_vdev_stop(rmm_vdev_phys); + if (ret) { + pr_err("failed to stop vdev (%d)\n", ret); + return; + } + + schedule_vdev_unbind(pdev); + ret =3D rmi_vdev_destroy(rd_phys, rmm_pdev_phys, rmm_vdev_phys); + if (ret) { + pr_err("failed to destroy vdev (%d)\n", ret); + return; + } +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 37a8f4dce68e..6361f7403f95 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -93,4 +93,6 @@ void rme_unassign_device(struct pci_dev *pdev); int schedule_rme_ide_setup(struct pci_dev *pdev); void *rme_create_vdev(struct realm *realm, struct pci_dev *pdev, struct pci_dev *pf0_dev, u32 guest_rid); +void rme_unbind_vdev(struct realm *realm, struct pci_dev *pdev, + struct pci_dev *pf0_dev); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C22831FBE9B; Mon, 28 Jul 2025 13:54:54 +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=1753710894; cv=none; b=oEp8JN6pTpdf38PgBSrWxLpAv+l8ZpQqbo7+uv4yy4rjcgrgGUcCJ8/t2K0gYSFE47vGfeyJMEGIqNWoB7x2IZkd7BepbsuNHjoEn0avnepwr0jbMMOFL1mpbMtKvF7QfxuGgsKKYGbpivyefbUJ0IMPG7Nd63CKnFydO86yGdY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710894; c=relaxed/simple; bh=0uRSZsgUrPsLQX8cHcPVQBzeHfezwcb/o6314ZYbxOQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P/J0ga4NRPSFhWuyux9RaaDg/3iNbU3Frx1gj/eCFfMr1RLop8bsU0BNBAJlsqkbSLbkrh+bIZ6XkuuyH3nwx0QVBQRScKdN9lGUqDDzC6XLD7wRF5HJk1taI+x/Bc6oWBJj0WcXpCajJL8mRTgOqi/gsEveyKtPddO9w5B3qPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TnK64EkI; 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="TnK64EkI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69DA1C4CEF9; Mon, 28 Jul 2025 13:54:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710894; bh=0uRSZsgUrPsLQX8cHcPVQBzeHfezwcb/o6314ZYbxOQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TnK64EkIp5HEQKmIWV9qJmAGXYHcebJHzjGu0iFRo0N97Z+fGupGK3Zo7CL99fAtX K9wxKq7eyx8yVHbUhRY6Hmm+nCHBJdvPCVuFRxnmz2sfOfPyclifYvjPkLioZRR9kL qev8O6n35NF00gBistj0oe9Tg6DfbEAPVlY6+GhGC59V3sdRIERRB/TiX4VS4aLpLX wYpEEMo0OcVEOFTvFdBC3AOMA06oBksisNVYMHJJ75wbNDB3neUJ5/tynpd4pCKOoI AsCD52h5hbtXGcbky8tWgTec/EBBjA2txODWOWWoJptxzUl/JwT+V+saMSgWL3NgxJ uIB5YrdEHClZg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 23/38] coco: guest: arm64: Update arm CCA guest driver Date: Mon, 28 Jul 2025 19:22:00 +0530 Message-ID: <20250728135216.48084-24-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" This patch includes renaming changes to simplify the registration of a TSM backend in the next patch. There are no functional changes in this update. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi.h | 2 +- arch/arm64/kernel/rsi.c | 2 +- drivers/virt/coco/arm-cca-guest/Makefile | 3 ++ .../{arm-cca-guest.c =3D> arm-cca.c} | 52 +++++++++---------- 4 files changed, 29 insertions(+), 30 deletions(-) rename drivers/virt/coco/arm-cca-guest/{arm-cca-guest.c =3D> arm-cca.c} (8= 6%) diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h index b42aeac05340..26ef6143562b 100644 --- a/arch/arm64/include/asm/rsi.h +++ b/arch/arm64/include/asm/rsi.h @@ -10,7 +10,7 @@ #include #include =20 -#define RSI_PDEV_NAME "arm-cca-dev" +#define RSI_DEV_NAME "arm-rsi-dev" =20 DECLARE_STATIC_KEY_FALSE(rsi_present); =20 diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c index ce4778141ec7..bf9ea99e2aa1 100644 --- a/arch/arm64/kernel/rsi.c +++ b/arch/arm64/kernel/rsi.c @@ -142,7 +142,7 @@ void __init arm64_rsi_init(void) } =20 static struct platform_device rsi_dev =3D { - .name =3D RSI_PDEV_NAME, + .name =3D RSI_DEV_NAME, .id =3D PLATFORM_DEVID_NONE }; =20 diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/a= rm-cca-guest/Makefile index 69eeba08e98a..609462ea9438 100644 --- a/drivers/virt/coco/arm-cca-guest/Makefile +++ b/drivers/virt/coco/arm-cca-guest/Makefile @@ -1,2 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +# obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest.o + +arm-cca-guest-$(CONFIG_TSM) +=3D arm-cca.o diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c b/drivers/virt= /coco/arm-cca-guest/arm-cca.c similarity index 86% rename from drivers/virt/coco/arm-cca-guest/arm-cca-guest.c rename to drivers/virt/coco/arm-cca-guest/arm-cca.c index 0c9ea24a200c..547fc2c79f7d 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca-guest.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -11,6 +11,7 @@ #include #include #include +#include =20 #include =20 @@ -181,52 +182,47 @@ static int arm_cca_report_new(struct tsm_report *repo= rt, void *data) return ret; } =20 -static const struct tsm_report_ops arm_cca_tsm_ops =3D { +static const struct tsm_report_ops arm_cca_tsm_report_ops =3D { .name =3D KBUILD_MODNAME, .report_new =3D arm_cca_report_new, }; =20 -/** - * arm_cca_guest_init - Register with the Trusted Security Module (TSM) - * interface. - * - * Return: - * * %0 - Registered successfully with the TSM interface. - * * %-ENODEV - The execution context is not an Arm Realm. - * * %-EBUSY - Already registered. - */ -static int __init arm_cca_guest_init(void) +static void unregister_cca_tsm_report(void *data) +{ + tsm_report_unregister(&arm_cca_tsm_report_ops); +} + +static int cca_guest_probe(struct platform_device *pdev) { int ret; =20 if (!is_realm_world()) return -ENODEV; =20 - ret =3D tsm_report_register(&arm_cca_tsm_ops, NULL); + ret =3D tsm_report_register(&arm_cca_tsm_report_ops, NULL); if (ret < 0) pr_err("Error %d registering with TSM\n", ret); =20 - return ret; -} -module_init(arm_cca_guest_init); + ret =3D devm_add_action_or_reset(&pdev->dev, unregister_cca_tsm_report, N= ULL); =20 -/** - * arm_cca_guest_exit - unregister with the Trusted Security Module (TSM) - * interface. - */ -static void __exit arm_cca_guest_exit(void) -{ - tsm_report_unregister(&arm_cca_tsm_ops); + return ret; } -module_exit(arm_cca_guest_exit); =20 /* modalias, so userspace can autoload this module when RSI is available */ -static const struct platform_device_id arm_cca_match[] __maybe_unused =3D { - { RSI_PDEV_NAME, 0}, +static const struct platform_device_id arm_cca_guest_id_table[] =3D { + { RSI_DEV_NAME, 0}, { } }; - -MODULE_DEVICE_TABLE(platform, arm_cca_match); +MODULE_DEVICE_TABLE(platform, arm_cca_guest_id_table); + +static struct platform_driver cca_guest_platform_driver =3D { + .probe =3D cca_guest_probe, + .id_table =3D arm_cca_guest_id_table, + .driver =3D { + .name =3D "arm-cca-guest", + }, +}; +module_platform_driver(cca_guest_platform_driver); MODULE_AUTHOR("Sami Mujawar "); -MODULE_DESCRIPTION("Arm CCA Guest TSM Driver"); +MODULE_DESCRIPTION("Arm CCA Guest TSM driver"); MODULE_LICENSE("GPL"); --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C4F51FBE9B; Mon, 28 Jul 2025 13:55: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=1753710900; cv=none; b=uHiylAzqqgSIkXIa2MCKB05mheVfQyagkkutOAxKlA/5CPG5aFIENK0Q6fB3o/d7fgc5gxJZOJ8vIJ+DqAlgMqksi+v5vf6C4nSmVV/9UCV9WVbqA4StkmEuvXyA8uU4VbqVC9eYkjwnMzqVApWWfctXBi5r53/gtqYUkPZHmDQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710900; c=relaxed/simple; bh=XSrCT05HbDUDeu8oleh4pmbLFUEXF7PC0mWM5VkwuCk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nSotZnedjXE3BDWXwaUrXfsMTfTrpBAXoI59htPXK6V1E9+wmgmM73TV0p9ZVKWUOPrACaN/IA4BdKrjoMvsC7eH5hWd4tkkBBQOHWuw3gsj9vZp/roqpzXpiSXcRWNxh2LQJT9BXFBjdABO4htBEBa/ESyn3ko2j9hJxUFZPso= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=puHPfETZ; 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="puHPfETZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 292BDC4CEFB; Mon, 28 Jul 2025 13:54:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710900; bh=XSrCT05HbDUDeu8oleh4pmbLFUEXF7PC0mWM5VkwuCk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=puHPfETZ1gMQhA8IT3G5aX6ltI3YA+g/BgIE8eYx1ogB2suYv9YYwOTk2n9J3RbTN qTZW9e3i8JUfBzfLGUDtEoo0zI64maAZUb3x3HV5Qd98FPblNspaPa6tovGwi50wk4 Q/kBY5exgSrYQ6AR9+NxPLvbm4kTIFmaDLYfONO4m+iIG/qMjYTzHw8839yYycfMf4 +j7GcoCSvk2X++9WlcE0qLEj6UoJ2ydrYtWgWn8aAVOgKOiLpbbevZx4TDdFpWZcde FpQt2r0CaJ+eTawIoNh6HnJfrwAry32sqsWH33QmZJQetXW/3AfhEe3e9fmp3UJcm2 XEUM11EBoroZg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 24/38] arm64: CCA: Register guest tsm callback Date: Mon, 28 Jul 2025 19:22:01 +0530 Message-ID: <20250728135216.48084-25-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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 if the DA feature is supported by RSI. Additionally, adjust the build order so that the TSM class is created before the arm-cca-guest driver initialization. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi.h | 3 + arch/arm64/include/asm/rsi_cmds.h | 18 ++++++ arch/arm64/include/asm/rsi_smc.h | 1 + arch/arm64/kernel/rsi.c | 24 ++++++-- drivers/virt/coco/Makefile | 2 +- drivers/virt/coco/arm-cca-guest/Kconfig | 8 ++- drivers/virt/coco/arm-cca-guest/arm-cca.c | 71 ++++++++++++++++++++++- drivers/virt/coco/arm-cca-guest/rsi-da.h | 27 +++++++++ 8 files changed, 144 insertions(+), 10 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 26ef6143562b..35dfbba4767b 100644 --- a/arch/arm64/include/asm/rsi.h +++ b/arch/arm64/include/asm/rsi.h @@ -67,4 +67,7 @@ static inline int rsi_set_memory_range_shared(phys_addr_t= start, return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY, RSI_CHANGE_DESTROYED); } + +bool rsi_has_da_feature(void); + #endif /* __ASM_RSI_H_ */ diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 2c8763876dfb..d4834baeef1b 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -159,4 +159,22 @@ static inline unsigned long rsi_attestation_token_cont= inue(phys_addr_t granule, return res.a0; } =20 +/** + * rsi_features() - Read feature register + * @index: Feature register index + * @out: Feature register value is written to this pointer + * + * Return: RSI return code + */ +static inline int rsi_features(unsigned long index, unsigned long *out) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_FEATURES, index, &res); + + if (out) + *out =3D res.a1; + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 6cb070eca9e9..8e486cdef9eb 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -53,6 +53,7 @@ */ #define SMC_RSI_ABI_VERSION SMC_RSI_FID(0x190) =20 +#define RSI_FEATURE_REGISTER_0_DA BIT(0) /* * Read feature register. * diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c index bf9ea99e2aa1..ef06c083990a 100644 --- a/arch/arm64/kernel/rsi.c +++ b/arch/arm64/kernel/rsi.c @@ -15,6 +15,7 @@ #include =20 static struct realm_config config; +static unsigned long rsi_feat_reg0; =20 unsigned long prot_ns_shared; EXPORT_SYMBOL(prot_ns_shared); @@ -22,6 +23,12 @@ EXPORT_SYMBOL(prot_ns_shared); DEFINE_STATIC_KEY_FALSE_RO(rsi_present); EXPORT_SYMBOL(rsi_present); =20 +bool rsi_has_da_feature(void) +{ + return !!u64_get_bits(rsi_feat_reg0, RSI_FEATURE_REGISTER_0_DA); +} +EXPORT_SYMBOL_GPL(rsi_has_da_feature); + bool cc_platform_has(enum cc_attr attr) { switch (attr) { @@ -128,6 +135,10 @@ void __init arm64_rsi_init(void) return; if (WARN_ON(rsi_get_realm_config(&config))) return; + + if (WARN_ON(rsi_features(0, &rsi_feat_reg0))) + return; + prot_ns_shared =3D BIT(config.ipa_bits - 1); =20 if (arm64_ioremap_prot_hook_register(realm_ioremap_hook)) @@ -141,17 +152,18 @@ void __init arm64_rsi_init(void) static_branch_enable(&rsi_present); } =20 -static struct platform_device rsi_dev =3D { +static struct platform_device cca_guest_dev =3D { .name =3D RSI_DEV_NAME, .id =3D PLATFORM_DEVID_NONE }; =20 -static int __init arm64_create_dummy_rsi_dev(void) +static int __init arm64_create_cca_guest_dev(void) { - if (is_realm_world() && - platform_device_register(&rsi_dev)) - pr_err("failed to register rsi platform device\n"); + if (is_realm_world()) { + if (!platform_device_register(&cca_guest_dev)) + pr_info("CCA guest platform device registered.\n"); + } return 0; } =20 -arch_initcall(arm64_create_dummy_rsi_dev) +device_initcall(arm64_create_cca_guest_dev) diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile index d0a859dd9eaf..4264ee367b3b 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -7,8 +7,8 @@ obj-$(CONFIG_EFI_SECRET) +=3D efi_secret/ obj-$(CONFIG_ARM_PKVM_GUEST) +=3D pkvm-guest/ obj-$(CONFIG_SEV_GUEST) +=3D sev-guest/ obj-$(CONFIG_INTEL_TDX_GUEST) +=3D tdx-guest/ -obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ =20 obj-$(CONFIG_TSM) +=3D tsm-core.o obj-y +=3D guest/ +obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ obj-$(CONFIG_ARM_CCA_HOST) +=3D arm-cca-host/ diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/ar= m-cca-guest/Kconfig index 3f0f013f03f1..410d9c3fb2b3 100644 --- a/drivers/virt/coco/arm-cca-guest/Kconfig +++ b/drivers/virt/coco/arm-cca-guest/Kconfig @@ -1,10 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +# + config ARM_CCA_GUEST tristate "Arm CCA Guest driver" depends on ARM64 + depends on PCI_TSM select TSM_REPORTS + select TSM help - The driver provides userspace interface to request and + The driver provides userspace interface to request an attestation report from the Realm Management Monitor(RMM). + If the DA feature is supported, it also register with TSM framework. =20 If you choose 'M' here, this module will be called arm-cca-guest. diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 547fc2c79f7d..3adbbd67e06e 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2023 ARM Ltd. + * Copyright (C) 2025 ARM Ltd. */ =20 #include @@ -15,6 +15,8 @@ =20 #include =20 +#include "rsi-da.h" + /** * struct arm_cca_token_info - a descriptor for the token buffer. * @challenge: Pointer to the challenge data @@ -192,6 +194,60 @@ static void unregister_cca_tsm_report(void *data) tsm_report_unregister(&arm_cca_tsm_report_ops); } =20 +static struct pci_tsm *cca_tsm_pci_probe(struct pci_dev *pdev) +{ + struct cca_guest_dsc *cca_dsc __free(kfree); + + if (!is_pci_tsm_pf0(pdev)) + return NULL; + + cca_dsc =3D kzalloc(sizeof(*cca_dsc), GFP_KERNEL); + if (!cca_dsc) + return NULL; + + if (pci_tsm_pf0_initialize(pdev, &cca_dsc->pci)) + return NULL; + + pci_info(pdev, "Guest tsm enabled\n"); + return &no_free_ptr(cca_dsc)->pci.tsm; +} + +static void cca_tsm_pci_remove(struct pci_tsm *tsm) +{ + struct cca_guest_dsc *cca_dsc =3D to_cca_guest_dsc(tsm->pdev); + + pci_dbg(tsm->pdev, "tsm disabled\n"); + kfree(cca_dsc); +} + +static const struct pci_tsm_ops cca_pci_ops =3D { + .probe =3D cca_tsm_pci_probe, + .remove =3D cca_tsm_pci_remove, +}; + +static void cca_tsm_unregister(void *tsm) +{ + tsm_unregister(tsm); +} + +static int cca_tsm_register(struct platform_device *pdev) +{ + struct tsm_core_dev *tsm_core; + int rc; + + tsm_core =3D tsm_register(&pdev->dev, NULL, &cca_pci_ops); + if (IS_ERR(tsm_core)) + return PTR_ERR(tsm_core); + + rc =3D devm_add_action_or_reset(&pdev->dev, cca_tsm_unregister, tsm_core); + if (rc) { + cca_tsm_unregister(tsm_core); + return rc; + } + + return 0; +} + static int cca_guest_probe(struct platform_device *pdev) { int ret; @@ -200,11 +256,22 @@ static int cca_guest_probe(struct platform_device *pd= ev) return -ENODEV; =20 ret =3D tsm_report_register(&arm_cca_tsm_report_ops, NULL); - if (ret < 0) + if (ret < 0) { pr_err("Error %d registering with TSM\n", ret); + goto err_out; + } =20 ret =3D devm_add_action_or_reset(&pdev->dev, unregister_cca_tsm_report, N= ULL); + if (ret < 0) { + pr_err("Error %d registering devm action\n", ret); + unregister_cca_tsm_report(NULL); + goto err_out; + } + + if (rsi_has_da_feature()) + ret =3D cca_tsm_register(pdev); =20 +err_out: return ret; } =20 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..8a4d5f1b0263 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#ifndef RSI_DA_H_ +#define RSI_DA_H_ + +#include +#include +#include + + +struct cca_guest_dsc { + struct pci_tsm_pf0 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.tsm); +} + +#endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D23B270EAB; Mon, 28 Jul 2025 13:55:06 +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=1753710906; cv=none; b=MLEY/6Gf7PLAWM6i4WzJipXuXF6yBizdzZcFkWlp+oOiFA0CHQ+j5rx7qCSTIP/uqkM/IWY33EhspRbtr9yYZ1d3RAmbH2F/nldde2agoHkGutnGhARuqnfPw7i8W+4S4Qp48MSnG7/+/aTO0ZNeyvSBofsr2dTL3zEj+GhHoss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710906; c=relaxed/simple; bh=Lk97WGWsKchJQr3PhJmRHtHWylEzWXYJvraenT8o+zQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IvzDAQNKVnwm1wWV97eSlBgHMnzNi1PyuKW0OkrE7vFcv3a7ZDd+V+gT2RUGDy/urJcrQxW+vl4xNIRB1BcfijmDbETvaYk2yNcNLReppxDrGs4GPH8dPFmJ22LteWBdAM/vz1clCzKos7TejW9SlAxZpsiU5cZhqJGV8rwlH9Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dBtlceBu; 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="dBtlceBu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B744BC113CF; Mon, 28 Jul 2025 13:55:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710906; bh=Lk97WGWsKchJQr3PhJmRHtHWylEzWXYJvraenT8o+zQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dBtlceBu4lEJlJk1f8YMPlJuJwJf1Pbb9RnV1xOX1lvTAoOsXFK5tvjBHVCZliISu ivvQ0Inly0gRb+H4cGlW4aev7UzJWtTG9Pv9Dm9KN0nMOgRl5pUUvDphUnlGzkc1F4 O+Ehu7jBIVZMnjt8x/g8c6TRrZbRgtlq+S208FXofV4bCHnu2vI65Q5oJANN/2ge+Y J4S0QNOIsjuYwFvaXHpdymPV43vBpBH8qfDiR7vwe8CshlgbhlmPrh9QGojbo/ZUEz lcYuTLosxkYgfAUxzRnPpSgQifBZMRWlkO2/C4H+4Mmz37S/+lNyHaAUmZLhtQSbjD 5bmUqOh2zdNaQ== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 25/38] cca: guest: arm64: Realm device lock support Date: Mon, 28 Jul 2025 19:22:02 +0530 Message-ID: <20250728135216.48084-26-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Writing 1 to 'tsm/lock' will initiate the TDISP lock sequence. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 32 +++++++++++++- arch/arm64/include/asm/rsi_smc.h | 5 +++ drivers/virt/coco/arm-cca-guest/Makefile | 2 +- drivers/virt/coco/arm-cca-guest/arm-cca.c | 18 ++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 52 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 3 +- 6 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 drivers/virt/coco/arm-cca-guest/rsi-da.c diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index d4834baeef1b..b9c4b8ff5631 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -172,8 +172,36 @@ static inline int rsi_features(unsigned long index, un= signed long *out) =20 arm_smccc_1_1_invoke(SMC_RSI_FEATURES, index, &res); =20 - if (out) - *out =3D res.a1; + *out =3D res.a1; + return res.a0; +} + +static inline unsigned long rsi_rdev_get_instance_id(unsigned long vdev_id= , unsigned long *inst_id) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_GET_INSTANCE_ID, vdev_id, &res); + + *inst_id =3D res.a1; + return res.a0; +} + +static inline unsigned long __rsi_rdev_lock(unsigned long vdev_id, unsigne= d long inst_id) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_LOCK, vdev_id, inst_id, &res); + + return res.a0; +} + + +static inline unsigned long rsi_rdev_continue(unsigned long vdev_id, unsig= ned long inst_id) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_CONTINUE, vdev_id, inst_id, &res); + return res.a0; } =20 diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 8e486cdef9eb..44b583ab6d67 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -191,4 +191,9 @@ struct realm_config { */ #define SMC_RSI_HOST_CALL SMC_RSI_FID(0x199) =20 +#define SMC_RSI_RDEV_GET_INSTANCE_ID SMC_RSI_FID(0x19c) +#define SMC_RSI_RDEV_CONTINUE SMC_RSI_FID(0x1a4) + +#define SMC_RSI_RDEV_LOCK SMC_RSI_FID(0x1a9) + #endif /* __ASM_RSI_SMC_H_ */ diff --git a/drivers/virt/coco/arm-cca-guest/Makefile b/drivers/virt/coco/a= rm-cca-guest/Makefile index 609462ea9438..341c7b37d610 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-$(CONFIG_TSM) +=3D arm-cca.o +arm-cca-guest-$(CONFIG_TSM) +=3D arm-cca.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 3adbbd67e06e..2c0190bcb2a9 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -220,9 +220,27 @@ static void cca_tsm_pci_remove(struct pci_tsm *tsm) kfree(cca_dsc); } =20 +static int cca_tsm_lock(struct pci_dev *pdev) +{ + unsigned long ret; + + ret =3D rsi_device_lock(pdev); + if (ret) { + pci_err(pdev, "failed to lock the device (%lu)\n", ret); + return -EIO; + } + return 0; +} + +static void cca_tsm_unlock(struct pci_dev *pdev) +{ +} + static const struct pci_tsm_ops cca_pci_ops =3D { .probe =3D cca_tsm_pci_probe, .remove =3D cca_tsm_pci_remove, + .lock =3D cca_tsm_lock, + .unlock =3D cca_tsm_unlock, }; =20 static void cca_tsm_unregister(void *tsm) 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..097cf52ee199 --- /dev/null +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include +#include + +#include "rsi-da.h" + +#define PCI_TDISP_MESSAGE_VERSION_10 0x10 + +static inline unsigned long rsi_rdev_lock(struct pci_dev *pdev, + unsigned long vdev_id, unsigned long inst_id) +{ + unsigned long ret; + + ret =3D __rsi_rdev_lock(vdev_id, inst_id); + if (ret !=3D RSI_SUCCESS) + return ret; + + do { + ret =3D rsi_rdev_continue(vdev_id, inst_id); + } while (ret =3D=3D RSI_INCOMPLETE); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to communicate with the device (%lu)\n", ret); + return ret; + } + return RSI_SUCCESS; +} + +int rsi_device_lock(struct pci_dev *pdev) +{ + unsigned long ret; + struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); + int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); + + ret =3D rsi_rdev_get_instance_id(vdev_id, &dsm->instance_id); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to get the device instance id (%lu)\n", ret); + return -EIO; + } + + ret =3D rsi_rdev_lock(pdev, vdev_id, dsm->instance_id); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to lock the device (%lu)\n", ret); + return -EIO; + } + + return ret; +} diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 8a4d5f1b0263..f12430c7d792 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -10,9 +10,9 @@ #include #include =20 - struct cca_guest_dsc { struct pci_tsm_pf0 pci; + unsigned long instance_id; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) @@ -24,4 +24,5 @@ static inline struct cca_guest_dsc *to_cca_guest_dsc(stru= ct pci_dev *pdev) return container_of(tsm, struct cca_guest_dsc, pci.tsm); } =20 +int rsi_device_lock(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E3B0273816; Mon, 28 Jul 2025 13:55:12 +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=1753710912; cv=none; b=tmmVVknH7WLPE32ILgh2XvTAKLnBdjh0NJa84C0mksrAeXZGpplyy4bTHHpf1MEpV0GtrRd9Ztg7jxOK2ffmXODT8KolM/G1Vk8tgxP9a6KeiolB7vkGRe6QybDh8z8nKo64fhBLIziyqeFIbe50hB31fAAlbWbeIxoVwfRnA2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710912; c=relaxed/simple; bh=5O1aCSLxWRGk90AUlS+nM3HRgGXDX51MN4Gn1sHyQ5A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U4cI9MS0FhedkqKQ6K/7fDSPtp/pxGVr09SAvDTw8HX+S0NQsdKGjkZpe3/Ju9EgraZDLG7UfSyHBWMtJu7qX0O6QG/vqUkPY2whB5ywLWTsJVCvA1ubqmWgGaJLWPJqL61vLWFw0f3rX30paYdabBTFy7pxowsoeuGgrmv4AGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Og5KxAEy; 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="Og5KxAEy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EBCABC4AF09; Mon, 28 Jul 2025 13:55:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710912; bh=5O1aCSLxWRGk90AUlS+nM3HRgGXDX51MN4Gn1sHyQ5A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Og5KxAEyG6Ivs3PPLTPzjDDVh37ivsLjGc9h4+lzF/jmEjAr2hBhNdKcF56rDFUzS i+2Yw8tED3/6DGxOSWSgIyW8RVGd2Q4xRSZ0gMwdHCUiIg0lknwpuNemBSL/ePRdEB 4VbZokzy406QwTtF1XU2JzFGmNrzUKcBfzuJJxUEVALRaOlVDeDLcUPkws5tvKGmgD +HCGZ1vcl3ekreIXUoAfE9rj89LkpFE/G2B1SZK11CN+vJnhTlvGAkp0mxxwPpJJPs DjYBPlIrXHB7b5i0SAercLJDjVRi+ngXbDNgpnGDRFG6Tbt1F6L7TM8solfSw/aUYE q4lxZn0uTunxA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 26/38] KVM: arm64: Add exit handler related to device assignment Date: Mon, 28 Jul 2025 19:22:03 +0530 Message-ID: <20250728135216.48084-27-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Different RSI calls related to DA result in REC exits. Add a facility to register handlers for handling these REC exits. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/kvm_rme.h | 3 ++ arch/arm64/include/asm/rmi_smc.h | 14 +++++++- arch/arm64/kvm/rme-exit.c | 60 ++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_rme.h b/arch/arm64/include/asm/kvm_= rme.h index e954bb95dc86..370d056222e8 100644 --- a/arch/arm64/include/asm/kvm_rme.h +++ b/arch/arm64/include/asm/kvm_rme.h @@ -136,4 +136,7 @@ static inline bool kvm_realm_is_private_address(struct = realm *realm, return !(addr & BIT(realm->ia_bits - 1)); } =20 +extern int (*realm_exit_vdev_req_handler)(struct realm_rec *rec); +extern int (*realm_exit_vdev_comm_handler)(struct realm_rec *rec); +extern int (*realm_exit_dev_mem_map_handler)(struct realm_rec *rec); #endif /* __ASM_KVM_RME_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index c6e16ab608e1..a5ef68b62bc0 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -219,6 +219,9 @@ struct rec_enter { #define RMI_EXIT_RIPAS_CHANGE 0x04 #define RMI_EXIT_HOST_CALL 0x05 #define RMI_EXIT_SERROR 0x06 +#define RMI_EXIT_VDEV_REQUEST 0x08 +#define RMI_EXIT_VDEV_COMM 0x09 +#define RMI_EXIT_DEV_MEM_MAP 0x0a =20 struct rec_exit { union { /* 0x000 */ @@ -264,7 +267,16 @@ struct rec_exit { u8 padding5[0x100]; }; union { /* 0x600 */ - u16 imm; + struct { + u16 imm; + u8 padding[6]; + u64 plane; + u64 vdev; + u64 vdev_action; + u64 dev_mem_base; + u64 dev_mem_top; + u64 dev_mem_pa; + }; u8 padding6[0x100]; }; union { /* 0x700 */ diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c index 1a8ca7526863..25948207fc5b 100644 --- a/arch/arm64/kvm/rme-exit.c +++ b/arch/arm64/kvm/rme-exit.c @@ -129,6 +129,60 @@ static int rec_exit_host_call(struct kvm_vcpu *vcpu) return kvm_smccc_call_handler(vcpu); } =20 +int (*realm_exit_vdev_req_handler)(struct realm_rec *rec); +EXPORT_SYMBOL_GPL(realm_exit_vdev_req_handler); +static int rec_exit_vdev_request(struct kvm_vcpu *vcpu) +{ + int ret; + struct realm_rec *rec =3D &vcpu->arch.rec; + + if (realm_exit_vdev_req_handler) { + ret =3D (*realm_exit_vdev_req_handler)(rec); + } else { + kvm_pr_unimpl("Unsupported exit reason: %u\n", + rec->run->exit.exit_reason); + vcpu->run->exit_reason =3D KVM_EXIT_INTERNAL_ERROR; + ret =3D 0; + } + return ret; +} + +int (*realm_exit_vdev_comm_handler)(struct realm_rec *rec); +EXPORT_SYMBOL_GPL(realm_exit_vdev_comm_handler); +static int rec_exit_vdev_communication(struct kvm_vcpu *vcpu) +{ + int ret; + struct realm_rec *rec =3D &vcpu->arch.rec; + + if (realm_exit_vdev_comm_handler) { + ret =3D (*realm_exit_vdev_comm_handler)(rec); + } else { + kvm_pr_unimpl("Unsupported exit reason: %u\n", + rec->run->exit.exit_reason); + vcpu->run->exit_reason =3D KVM_EXIT_INTERNAL_ERROR; + ret =3D 0; + } + return ret; +} + +int (*realm_exit_dev_mem_map_handler)(struct realm_rec *rec); +EXPORT_SYMBOL_GPL(realm_exit_dev_mem_map_handler); +static int rec_exit_dev_mem_map(struct kvm_vcpu *vcpu) +{ + int ret; + struct realm_rec *rec =3D &vcpu->arch.rec; + + if (realm_exit_dev_mem_map_handler) { + ret =3D (*realm_exit_dev_mem_map_handler)(rec); + } else { + kvm_pr_unimpl("Unsupported exit reason: %u\n", + rec->run->exit.exit_reason); + vcpu->run->exit_reason =3D KVM_EXIT_INTERNAL_ERROR; + ret =3D 0; + } + return ret; +} + static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu) { struct realm_rec *rec =3D &vcpu->arch.rec; @@ -198,6 +252,12 @@ int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run= _ret) return rec_exit_ripas_change(vcpu); case RMI_EXIT_HOST_CALL: return rec_exit_host_call(vcpu); + case RMI_EXIT_VDEV_REQUEST: + return rec_exit_vdev_request(vcpu); + case RMI_EXIT_VDEV_COMM: + return rec_exit_vdev_communication(vcpu); + case RMI_EXIT_DEV_MEM_MAP: + return rec_exit_dev_mem_map(vcpu); } =20 kvm_pr_unimpl("Unsupported exit reason: %u\n", --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24A85270EA9; Mon, 28 Jul 2025 13:55:18 +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=1753710918; cv=none; b=nUge+oh5Zvnn7z76bH1NygGcOSghmNq9qEcuYnxY9hbmjBZhAAOO6LNUAJnIuMLMqCcl4a3km5xm/D0VnCwpyceC2JQNYJXtxPeeAjcWfy1gpxiaCwFCGaEyhWVj02kms/1fQc44J/iQqggQ+CHB7+s2IOExJko/sY0cgDApBVw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710918; c=relaxed/simple; bh=fqnzlrHLcIMF/lg6bG+5Jt046U62wnLlnwGVVvNwy90=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RvWLMMYUY8eqcLmevY/ysK0nl1L1yf6tIR2A+GhxFlE2V/9UraZ7f0R/OorcoKqSpAYKyuqUn1nkfVrWcToDNm1TqT23X7uOS9OW+ZKPSQwRjB/FxmzuhMzKBNJt6DcNp6Wob92GnvY+skLb2ROMeJxLSU2l5wMSyzl0vMotbM8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oca8P+Ad; 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="oca8P+Ad" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B6CC7C4CEE7; Mon, 28 Jul 2025 13:55:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710918; bh=fqnzlrHLcIMF/lg6bG+5Jt046U62wnLlnwGVVvNwy90=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oca8P+Adv6G68EpAKr+jO0tSMmI+LeTI3Qk8wtMpF6E3dcmlmxlAmH+jh3PxW0Xv/ 9F1w2KqbDw33b9A88SmuAMFwDswj2UkojHBWqdp00+f9XJvN/aZ+NqPhbcrX3jCWct 6UTVZLOXA2TmYsjCtQ2NNnEkPZK3zZ6IDV0okrQ4AZvUISz5uSvACkscRVZ2Ij5HY/ 5FHCPIKxlRh934rlUbgzvS6jBPf9MXf6a3XzXAO4DDVZH5BWUYlzsDeRLQyhR6ANAc Km4Vm3P/BkE65z40HAcZKBRxevxEVF1I2hCwQ9mnNzvxWNKeNtMAUmNrykj2YJ98tI mduY4ddfrFkfw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 27/38] coco: host: arm64: add RSI_RDEV_GET_INSTANCE_ID related exit handler Date: Mon, 28 Jul 2025 19:22:04 +0530 Message-ID: <20250728135216.48084-28-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Mapping the VDEV object that matches a specified virtual device ID results in a REC exit, which is handled by the VDEV request exit handler. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 8 +++++ arch/arm64/include/asm/rmi_smc.h | 9 ++++-- drivers/virt/coco/arm-cca-host/arm-cca.c | 8 ++++- drivers/virt/coco/arm-cca-host/rmm-da.c | 39 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 2 ++ 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index eb4f67eb6b01..fcf6b319e953 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -629,5 +629,13 @@ static inline unsigned long rmi_vdev_destroy(unsigned = long rd, return res.a0; } =20 +static inline unsigned long rmi_vdev_complete(unsigned long rec_phys, unsi= gned long vdev_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_COMPLETE, rec_phys, vdev_phys, &res); + + return res.a0; +} =20 #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index a5ef68b62bc0..6b23afa070d1 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -57,7 +57,8 @@ #define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187) #define SMC_RMI_VDEV_DESTROY SMC_RMI_CALL(0x0188) #define SMC_RMI_VDEV_GET_STATE SMC_RMI_CALL(0x0189) -#define SMC_RMI_VDEV_STOP SMC_RMI_CALL(0x018A) +#define SMC_RMI_VDEV_STOP SMC_RMI_CALL(0x018a) +#define SMC_RMI_VDEV_COMPLETE SMC_RMI_CALL(0x018e) =20 #define RMI_ABI_MAJOR_VERSION 1 #define RMI_ABI_MINOR_VERSION 0 @@ -262,7 +263,11 @@ struct rec_exit { struct { u64 ripas_base; u64 ripas_top; - u64 ripas_value; + u8 ripas_value; + u8 padding8[15]; + u64 s2ap_base; + u64 s2ap_top; + u64 vdev_id; }; u8 padding5[0x100]; }; diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index 3792d7b5cb99..837bd10ccd47 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -275,13 +275,19 @@ static void cca_tsm_remove(void *tsm_core) =20 static int cca_tsm_probe(struct platform_device *pdev) { + int rc; struct tsm_core_dev *tsm_core; =20 tsm_core =3D tsm_register(&pdev->dev, NULL, &cca_pci_ops); if (IS_ERR(tsm_core)) return PTR_ERR(tsm_core); =20 - return devm_add_action_or_reset(&pdev->dev, cca_tsm_remove, tsm_core); + rc =3D devm_add_action_or_reset(&pdev->dev, cca_tsm_remove, tsm_core); + if (rc) + return rc; + + rme_register_exit_handlers(); + return 0; } =20 static const struct platform_device_id arm_cca_host_id_table[] =3D { diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index 53072610fa67..d4f1da590b90 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -660,3 +660,42 @@ void rme_unbind_vdev(struct realm *realm, struct pci_d= ev *pdev, struct pci_dev * return; } } + +static struct pci_tsm *find_pci_tsm_from_vdev_id(unsigned long vdev_id) +{ + struct pci_dev *pdev =3D NULL; + struct cca_host_tdi *host_tdi; + + for_each_pci_dev(pdev) { + host_tdi =3D to_cca_host_tdi(pdev); + if (!host_tdi) + continue; + if (host_tdi->vdev_id =3D=3D vdev_id) + return pdev->tsm; + } + return NULL; +} + +static int rme_exit_vdev_req_handler(struct realm_rec *rec) +{ + struct cca_host_tdi *host_tdi =3D NULL; + unsigned long vdev_id =3D rec->run->exit.vdev_id; + struct pci_tsm *tsm =3D find_pci_tsm_from_vdev_id(vdev_id); + phys_addr_t rec_phys =3D virt_to_phys(rec->rec_page); + + if (tsm) + host_tdi =3D to_cca_host_tdi(tsm->pdev); + + if (host_tdi) + rmi_vdev_complete(rec_phys, virt_to_phys(host_tdi->rmm_vdev)); + /* + * Return back to the guest without calling vdev complete. + * The Realm will treat that as an error. + */ + return 1; +} + +void rme_register_exit_handlers(void) +{ + realm_exit_vdev_req_handler =3D rme_exit_vdev_req_handler; +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 6361f7403f95..7f51b611467b 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -48,6 +48,7 @@ struct cca_host_dsc_pf0 { struct cca_host_tdi { struct pci_tdi tdi; void *rmm_vdev; + unsigned long vdev_id; }; =20 #define PDEV_COMMUNICATE 0x1 @@ -95,4 +96,5 @@ void *rme_create_vdev(struct realm *realm, struct pci_dev= *pdev, struct pci_dev *pf0_dev, u32 guest_rid); void rme_unbind_vdev(struct realm *realm, struct pci_dev *pdev, struct pci_dev *pf0_dev); +void rme_register_exit_handlers(void); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF307270EA9; Mon, 28 Jul 2025 13:55:23 +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=1753710924; cv=none; b=uUQKF/zi4B1yYnO8yT6Wwerk7cqJ5f5PUicNTZDr6wiV0CQIXZOenq834xiQIKStmAvI5BixRNwJ1fgT59K+aJXN9OmYIXRAsL79Zx6JH2GP+LwFpqTjTUMSf2zeWSSuo8cSXWUB59ikvsTU3ewfdVa0NooV7C5BAHwVw7H4Vqg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710924; c=relaxed/simple; bh=uAR/fHNQy0wfaJGiSb9ysOvjo+hmJLlA8JN4JOUsFiM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T6q0fYKtJ9CZdW3S0lY7IV6lnzx1jcSuh6J+bUpJXMrgrrdco9w+uAzJc0I3n8kdt3MCM/E9PzrBLLO2AsdGcU/O75VLycni2FGRf5ngXZZjRMqoNLkPhXgvQ5K/oDqU653MDxx2kaem6obaM3ognFjFfWHetRXso4zs2UZ9qlQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TznB8qC9; 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="TznB8qC9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7D28C4CEF8; Mon, 28 Jul 2025 13:55:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710923; bh=uAR/fHNQy0wfaJGiSb9ysOvjo+hmJLlA8JN4JOUsFiM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TznB8qC94CBNClsONzdJpQ1lDat0p5hFbSDwJGQzr5qpetO2lbP52rtuoIU1ZotUG ET62gdXUgRNIHIeTYJ2+PfyRUk2+R5mgCfURTXGPFS9m493pwWz3sP1qsrCqJClhzz 1cJVUs0ORHpTl3rRY8AvAxYYzAAo9+olRQkUF70TieUNJrQTPUuFT7AEPIouKAOb4V czXlK43d1LhGmAcrl8r+16WbLYnvm3pBVIgQ7koUtCw4X6PC71qpNANSWFB2alnr26 ZkRSHEwfCBPkcf9L1iYmOT2WkiihBKAz05iOxBpQiCk/fKdjzs4/OKPsRfviVZVytr dGbobRT5MaEDg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 28/38] coco: host: arm64: Add support for device communication exit handler Date: Mon, 28 Jul 2025 19:22:05 +0530 Message-ID: <20250728135216.48084-29-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Different RSI calls that require device communication result in a REC exit, which is handled by the device communication exit handler. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_smc.h | 6 ++ drivers/virt/coco/arm-cca-host/arm-cca.c | 1 + drivers/virt/coco/arm-cca-host/rmm-da.c | 75 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 4 ++ 4 files changed, 86 insertions(+) diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 6b23afa070d1..7073eccaec5f 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -457,4 +457,10 @@ struct rmi_vdev_params { }; }; =20 +#define RMI_VDEV_ACTION_GET_INTERFACE_REPORT 0x0 +#define RMI_VDEV_ACTION_GET_MEASUREMENTS 0x1 +#define RMI_VDEV_ACTION_LOCK 0x2 +#define RMI_VDEV_ACTION_START 0x3 +#define RMI_VDEV_ACTION_STOP 0x4 + #endif /* __ASM_RMI_SMC_H */ diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index 837bd10ccd47..be1296fb1bf2 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -243,6 +243,7 @@ static struct pci_tdi *cca_tsm_bind(struct pci_dev *pde= v, struct pci_dev *pf0_de rmm_vdev =3D rme_create_vdev(realm, pdev, pf0_dev, tdi_id); if (!IS_ERR_OR_NULL(rmm_vdev)) { host_tdi->rmm_vdev =3D rmm_vdev; + host_tdi->vdev_id =3D tdi_id; return &no_free_ptr(host_tdi)->tdi; } =20 diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index d4f1da590b90..bef33e618fd3 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -233,6 +233,16 @@ static int __do_dev_communicate(int type, struct pci_t= sm *tsm) cache_offset =3D &dsc_pf0->cert_chain.cache.size; cache_remaining =3D sizeof(dsc_pf0->cert_chain.cache.buf) - *cache_offs= et; break; + case RMI_DEV_INTERFACE_REPORT: + cache_buf =3D dsc_pf0->interface_report.buf; + cache_offset =3D &dsc_pf0->interface_report.size; + cache_remaining =3D sizeof(dsc_pf0->interface_report.buf) - *cache_offs= et; + break; + case RMI_DEV_MEASUREMENTS: + cache_buf =3D dsc_pf0->measurements.buf; + cache_offset =3D &dsc_pf0->measurements.size; + cache_remaining =3D sizeof(dsc_pf0->measurements.buf) - *cache_offset; + break; default: /* FIXME!! depending on the DevComms status, * it might require to ABORT the communcation. @@ -661,6 +671,21 @@ void rme_unbind_vdev(struct realm *realm, struct pci_d= ev *pdev, struct pci_dev * } } =20 +static struct pci_tsm *find_pci_tsm_from_vdev(phys_addr_t vdev_phys) +{ + struct pci_dev *pdev =3D NULL; + struct cca_host_tdi *host_tdi; + + for_each_pci_dev(pdev) { + host_tdi =3D to_cca_host_tdi(pdev); + if (!host_tdi) + continue; + if (virt_to_phys(host_tdi->rmm_vdev) =3D=3D vdev_phys) + return pdev->tsm; + } + return NULL; +} + static struct pci_tsm *find_pci_tsm_from_vdev_id(unsigned long vdev_id) { struct pci_dev *pdev =3D NULL; @@ -676,6 +701,55 @@ static struct pci_tsm *find_pci_tsm_from_vdev_id(unsig= ned long vdev_id) return NULL; } =20 +static int rme_exit_vdev_comm_handler(struct realm_rec *rec) +{ + int ret; + unsigned long state; + struct cca_host_tdi *host_tdi; + struct cca_host_comm_data *comm_data; + phys_addr_t vdev_phys =3D rec->run->exit.vdev; + struct pci_tsm *tsm =3D find_pci_tsm_from_vdev(vdev_phys); + + if (!tsm) + goto err_out; + + host_tdi =3D to_cca_host_tdi(tsm->pdev); + if (!host_tdi) + goto err_out; + + comm_data =3D to_cca_comm_data(tsm->pdev); + if (!comm_data->vdev_comm_active) { + struct rmi_dev_comm_enter *io_enter; + + io_enter =3D &comm_data->io_params->enter; + io_enter->resp_len =3D 0; + io_enter->status =3D RMI_DEV_COMM_NONE; + comm_data->vdev_comm_active =3D true; + } + + /* FIXME!! Should this be a work? */ + ret =3D __do_dev_communicate(VDEV_COMMUNICATE, tsm); + if (ret) + goto err_out; + + ret =3D rmi_vdev_get_state(virt_to_phys(host_tdi->rmm_vdev), &state); + if (ret) + goto err_out; + /* + * If vdev is done communicating, the next update should + * reinitialize the cache + */ + if (state !=3D RMI_VDEV_COMMUNICATING) + comm_data->vdev_comm_active =3D false; + +err_out: + /* + * Return back to the guest without calling DEV communicate. + * The Realm will treat that as an error. + */ + return 1; +} + static int rme_exit_vdev_req_handler(struct realm_rec *rec) { struct cca_host_tdi *host_tdi =3D NULL; @@ -697,5 +771,6 @@ static int rme_exit_vdev_req_handler(struct realm_rec *= rec) =20 void rme_register_exit_handlers(void) { + realm_exit_vdev_comm_handler =3D rme_exit_vdev_comm_handler; realm_exit_vdev_req_handler =3D rme_exit_vdev_req_handler; } diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index 7f51b611467b..cebddab8464d 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -22,6 +22,8 @@ struct cca_host_comm_data { void *resp_buff; void *req_buff; struct rmi_dev_comm_data *io_params; + + bool vdev_comm_active; }; =20 struct cca_host_dsc_pf0 { @@ -43,6 +45,8 @@ struct cca_host_dsc_pf0 { bool valid; } cert_chain; struct cache_object vca; + struct cache_object interface_report; + struct cache_object measurements; }; =20 struct cca_host_tdi { --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2612273D7C; Mon, 28 Jul 2025 13:55:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710929; cv=none; b=ALg4C5LKVr4M+eURqOspOHbPBIggVlieQeXXoZDa58xDiEnu6JpV299uevFkifLFKhrEbjDrbgIgfp8QbI+LQg6S4ku6Gs6TYXNCBA1FAzp7SwquQAln3FAS8nOFkjd9ZjUZtQYotLeSXgxZ8Onr7E0WawS0XkDd2W2u/oJ/MIc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710929; c=relaxed/simple; bh=Ze7PT5F9v/p5VT9WHtpaCA4SAdVWFE+04WmlwvCiPpM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CRRZzN3E0YnmKTJcowu9Hvzb3Am5weht/+IfXwGx0j75PwPgjHMli0F2wQWLp+/IgclCzSjes5T4z9vyOUrYrP6s/NvH7yIE8dqywu1k1xyJPR8Byb6tKYl0Tir+hx+TiDf4QNmq5xu7vl8tgRtcSIKDlz5zIF1UJDbHf1HR5eU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EHTzaYAT; 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="EHTzaYAT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E0FDC4CEF7; Mon, 28 Jul 2025 13:55:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710929; bh=Ze7PT5F9v/p5VT9WHtpaCA4SAdVWFE+04WmlwvCiPpM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EHTzaYATelYucJ58eoPs+D2HGmOMerJ9TqheUwRR9fWa80wiu3b7afAwuTXXVMx0I qsZeHTG96YAtnWohw8UHhyOWU2J/5tD2kQ50w4nSMXCSccAmy2AhKu+Ut7PD3VJduq PufT9ds23yxb9pGu5O6xzmm2B1Y4R2ps9R4O9G0SNcMEZORyDtPltcVnV+x70gUOXm VEyKWeePSybKuOavQnrlTsT5ftDRNVnkcAN9h+u2p/cmb9PE3q0uy3zi9E29Dz8LtJ EmkeGgRzC0G2jfvSgWMMrUm7PD43syBGxXI3GABAkrgMJhYAxcSvG3Cnt80sFXokdY OzFg2rvRigPXA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 29/38] coco: guest: arm64: Add support for collecting interface reports Date: Mon, 28 Jul 2025 19:22:06 +0530 Message-ID: <20250728135216.48084-30-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Support collecting interface reports using RSI calls. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 14 ++++++++++ arch/arm64/include/asm/rsi_smc.h | 2 ++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 34 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index b9c4b8ff5631..1d76f7d37cb6 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -205,4 +205,18 @@ static inline unsigned long rsi_rdev_continue(unsigned= long vdev_id, unsigned lo return res.a0; } =20 +static inline unsigned long __rsi_rdev_get_interface_report(unsigned long = vdev_id, + unsigned long inst_id, + unsigned long version_max, + unsigned long *version) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_GET_INTERFACE_REPORT, + vdev_id, inst_id, version_max, &res); + + *version =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 44b583ab6d67..6afcccee2ae7 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -194,6 +194,8 @@ struct realm_config { #define SMC_RSI_RDEV_GET_INSTANCE_ID SMC_RSI_FID(0x19c) #define SMC_RSI_RDEV_CONTINUE SMC_RSI_FID(0x1a4) =20 +#define SMC_RSI_RDEV_GET_INTERFACE_REPORT SMC_RSI_FID(0x1a6) + #define SMC_RSI_RDEV_LOCK SMC_RSI_FID(0x1a9) =20 #endif /* __ASM_RSI_SMC_H_ */ diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 097cf52ee199..28ec946df1e2 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -29,9 +29,31 @@ static inline unsigned long rsi_rdev_lock(struct pci_dev= *pdev, return RSI_SUCCESS; } =20 +static inline unsigned long +rsi_rdev_get_interface_report(struct pci_dev *pdev, unsigned long vdev_id, + unsigned long inst_id, unsigned long version_max, + unsigned long *version) +{ + unsigned long ret; + + ret =3D __rsi_rdev_get_interface_report(vdev_id, inst_id, version_max, ve= rsion); + if (ret !=3D RSI_SUCCESS) + return ret; + + do { + ret =3D rsi_rdev_continue(vdev_id, inst_id); + } while (ret =3D=3D RSI_INCOMPLETE); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to communicate with the device (%lu)\n", ret); + return ret; + } + return RSI_SUCCESS; +} + int rsi_device_lock(struct pci_dev *pdev) { unsigned long ret; + unsigned long tdisp_version; struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); @@ -48,5 +70,17 @@ int rsi_device_lock(struct pci_dev *pdev) return -EIO; } =20 + ret =3D rsi_rdev_get_interface_report(pdev, vdev_id, dsm->instance_id, + PCI_TDISP_MESSAGE_VERSION_10, &tdisp_version); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to get interface report (%lu)\n", ret); + return -EIO; + } + + if (tdisp_version !=3D PCI_TDISP_MESSAGE_VERSION_10) { + pci_err(pdev, "unknown TDISP version (%lu)\n", tdisp_version); + return -EOPNOTSUPP; + } + return ret; } --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93BD0273D7C; Mon, 28 Jul 2025 13:55:35 +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=1753710935; cv=none; b=HUTFh/5FJx3514diBoiLB4/DmJ9xYBmwdPevz0ct5Ux/WRCIlh8KpvGqvLkKqVj24xVCNE3/VD81RWKC5Bk8DZY5KPYrFJz6CFG00bKj+Yo9eZVcLjOOvZF46weG8WBMZgmn7fGZKCqaQqkJ1UJJQJsJYeBDV3YS4uuAxV4RDFI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710935; c=relaxed/simple; bh=RN0CUhbZzR040Mg0s29M+9z5gFuvjBCdUvvmi2BiIEc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DOvaOS/U5rpaahrXk0UTdoYrjyjnuYyCLsGiVi4RWdRevn16+4of7hAc3f4RU3M+d5fs/sT8jknHCaWypDXlFO0CEiWGsl/TRlIafG33CgfWCkGOa1tVEQQmGeJjiALaep1aBsbOFXELkjRQi2WFA59Uzq5xikRJCDCjwEGpImQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mX3ZdPKz; 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="mX3ZdPKz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 176AFC4CEFE; Mon, 28 Jul 2025 13:55:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710935; bh=RN0CUhbZzR040Mg0s29M+9z5gFuvjBCdUvvmi2BiIEc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mX3ZdPKz02WSxNRrbXpCzA2um2VhieabFSA7AL+4A2JIB+zlzWvbQJatA96WeJwNS Y08gFfbphtbkRgplTRqNZCrLfiK6lsjM59WkowBvOrRiQQlPn+xJEPHaGi7xdiFlZV /9/1qoeqikPt4tOmIF3yJmWdQQ9WBbBqZx/bnfuXxj2SsgIu3vghiuilZq9WAgIlPt Lr2UhRlBGZsy+cQscYAcaYp1uiEuQCZb69+3UnxOhvzKbu2vDNQwPMQdfPAxReIBaP CRRCGWn5Teu6nFJPSF/lyIBJ0jU28nCHIh88WSrPx/xMBDibj7HMzBw3NRX8MjJyCL +Hyfdx1iaXBwg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 30/38] coco: host: arm64: Add support for realm host interface (RHI) Date: Mon, 28 Jul 2025 19:22:07 +0530 Message-ID: <20250728135216.48084-31-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Device assignment-related RHI calls result in a REC exit, which is handled by the tsm guest_request callback. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 32 ++++++++++ drivers/virt/coco/arm-cca-host/arm-cca.c | 68 ++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.c | 81 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-host/rmm-da.h | 4 ++ include/linux/tsm.h | 3 + 5 files changed, 188 insertions(+) create mode 100644 arch/arm64/include/asm/rhi.h diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h new file mode 100644 index 000000000000..d3c22e582678 --- /dev/null +++ b/arch/arm64/include/asm/rhi.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Ltd. + */ + +#ifndef __ASM_RHI_H_ +#define __ASM_RHI_H_ + +#define SMC_RHI_CALL(func) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD_HYP,\ + (func)) + + +#define RHI_DA_FEATURES SMC_RHI_CALL(0x004d) +#define RHI_DA_OBJECT_SIZE SMC_RHI_CALL(0x004e) +#define RHI_DA_OBJECT_READ SMC_RHI_CALL(0x004f) + +#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_SUCCESS 0x1 +#define RHI_ERROR_INVALID_VDEV_ID 0x2 +#define RHI_ERROR_INVALID_DA_OBJECT_TYPE 0x3 +#define RHI_ERROR_DATA_NOT_AVAILABLE 0x4 +#define RHI_ERROR_INVALID_OFFSET 0x5 +#define RHI_ERROR_INVALID_ADDR 0x6 +#endif diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index be1296fb1bf2..0807fcf8d222 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -260,6 +260,73 @@ static void cca_tsm_unbind(struct pci_tdi *tdi) module_put(THIS_MODULE); } =20 +struct da_object_size_req { + int object_type; +}; + +struct da_object_read_req { + int object_type; + unsigned long offset; +}; + +static int cca_tsm_guest_req(struct pci_dev *pdev, struct tsm_guest_req_in= fo *info) +{ + int ret; + + switch (info->type) { + case ARM_CCA_DA_OBJECT_SIZE: + { + int object_size; + struct da_object_size_req req; + + if (sizeof(req) !=3D info->req_len) + return -EINVAL; + + if (copy_from_user(&req, info->req, info->req_len)) + return -EFAULT; + + object_size =3D rme_get_da_object_size(pdev, req.object_type); + if (object_size > 0) { + if (info->resp_len < sizeof(object_size)) + return -EINVAL; + if (copy_to_user(info->resp, &object_size, sizeof(object_size))) + return -EFAULT; + info->resp_len =3D sizeof(object_size); + ret =3D 0; + } else + /* error */ + ret =3D object_size; + break; + } + case ARM_CCA_DA_OBJECT_READ: + { + int resp_len; + struct da_object_read_req req; + + if (sizeof(req) !=3D info->req_len) + return -EINVAL; + + if (copy_from_user(&req, info->req, info->req_len)) + return -EFAULT; + + resp_len =3D rme_da_object_read(pdev, req.object_type, req.offset, + info->resp_len, + info->resp); + if (resp_len > 0) { + info->resp_len =3D resp_len; + ret =3D 0; + } else + /* error */ + ret =3D resp_len; + break; + } + default: + ret =3D -EINVAL; + break; + } + return ret; +} + static const struct pci_tsm_ops cca_pci_ops =3D { .probe =3D cca_tsm_pci_probe, .remove =3D cca_tsm_pci_remove, @@ -267,6 +334,7 @@ static const struct pci_tsm_ops cca_pci_ops =3D { .disconnect =3D cca_tsm_disconnect, .bind =3D cca_tsm_bind, .unbind =3D cca_tsm_unbind, + .guest_req =3D cca_tsm_guest_req, }; =20 static void cca_tsm_remove(void *tsm_core) diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/ar= m-cca-host/rmm-da.c index bef33e618fd3..c7da9d12f258 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include =20 #include "rmm-da.h" =20 @@ -769,6 +771,85 @@ static int rme_exit_vdev_req_handler(struct realm_rec = *rec) return 1; } =20 +int rme_get_da_object_size(struct pci_dev *pdev, int type) +{ + int ret =3D 0; + unsigned long len; + struct pci_tsm *tsm =3D pdev->tsm; + struct cca_host_dsc_pf0 *dsc_pf0; + + if (!tsm) + return -EINVAL; + + dsc_pf0 =3D to_cca_dsc_pf0(tsm->dsm_dev); + + /* Determine the buffer that should be used */ + if (type =3D=3D RHI_DA_OBJECT_INTERFACE_REPORT) { + len =3D dsc_pf0->interface_report.size; + } else if (type =3D=3D RHI_DA_OBJECT_MEASUREMENT) { + len =3D dsc_pf0->measurements.size; + } else if (type =3D=3D RHI_DA_OBJECT_CERTIFICATE) { + len =3D dsc_pf0->cert_chain.cache.size; + } else if (type =3D=3D RHI_DA_OBJECT_VCA) { + len =3D dsc_pf0->vca.size; + } else { + ret =3D -EINVAL; + goto err_out; + } + + return len; +err_out: + return ret; +} + +int rme_da_object_read(struct pci_dev *pdev, int type, unsigned long offse= t, + unsigned long max_len, void __user *user_buf) +{ + void *buf; + int ret =3D 0; + unsigned long len; + struct cca_host_dsc_pf0 *dsc_pf0; + struct pci_tsm *tsm =3D pdev->tsm; + + if (!tsm) + return -EINVAL; + + dsc_pf0 =3D to_cca_dsc_pf0(tsm->dsm_dev); + + /* Determine the buffer that should be used */ + if (type =3D=3D RHI_DA_OBJECT_INTERFACE_REPORT) { + len =3D dsc_pf0->interface_report.size; + buf =3D dsc_pf0->interface_report.buf; + } else if (type =3D=3D RHI_DA_OBJECT_MEASUREMENT) { + len =3D dsc_pf0->measurements.size; + buf =3D dsc_pf0->measurements.buf; + } else if (type =3D=3D RHI_DA_OBJECT_CERTIFICATE) { + len =3D dsc_pf0->cert_chain.cache.size; + buf =3D dsc_pf0->cert_chain.cache.buf; + } else if (type =3D=3D RHI_DA_OBJECT_VCA) { + len =3D dsc_pf0->vca.size; + buf =3D dsc_pf0->vca.buf; + } else { + ret =3D -EINVAL; + goto err_out; + } + + /* Assume that the buffer is large enough for the whole report */ + if ((max_len - offset) < len) { + /* FIXME!! the error code */ + ret =3D -ENOMEM; + goto err_out; + } + + if (copy_to_user(user_buf + offset, buf, len)) { + ret =3D -EIO; + goto err_out; + } + ret =3D len; +err_out: + return ret; +} + void rme_register_exit_handlers(void) { realm_exit_vdev_comm_handler =3D rme_exit_vdev_comm_handler; diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/ar= m-cca-host/rmm-da.h index cebddab8464d..457660ff3b69 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -10,6 +10,7 @@ #include #include #include +#include =20 #define MAX_CACHE_OBJ_SIZE 4096 struct cache_object { @@ -101,4 +102,7 @@ void *rme_create_vdev(struct realm *realm, struct pci_d= ev *pdev, void rme_unbind_vdev(struct realm *realm, struct pci_dev *pdev, struct pci_dev *pf0_dev); void rme_register_exit_handlers(void); +int rme_get_da_object_size(struct pci_dev *pdev, int type); +int rme_da_object_read(struct pci_dev *pdev, int type, unsigned long offse= t, + unsigned long max_len, void __user *user_buf); #endif diff --git a/include/linux/tsm.h b/include/linux/tsm.h index 497a3b4df5a0..e82046b0c7fa 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -145,5 +145,8 @@ struct tsm_guest_req_info { size_t resp_len; }; =20 +#define ARM_CCA_DA_OBJECT_SIZE 0x1 +#define ARM_CCA_DA_OBJECT_READ 0x2 + int tsm_guest_req(struct device *dev, struct tsm_guest_req_info *info); #endif /* __TSM_H */ --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB98626F478; Mon, 28 Jul 2025 13:55: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=1753710943; cv=none; b=TXO3OdXm0dggbfnpinA6iWacAEsqgc+qBTxV0L9pcUPTsOtYZVqBdrPG+DAZl0INV4QxMZ/wEbD2pUjPeK7MNAB6cSE6THtrn/377h1BRfDkIXWPKEKU7Fs7rGjNvT0h0YO/8ixHXqNxOrf2xWL7o2HGBf8v4lDFbXotx30Up+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710943; c=relaxed/simple; bh=jMF8HCm3Xp9lU82DGkhsoTy0DGh7IgTN4O7PJLsN8Po=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M9b6H/t4tH+b8kM0YfAHEmpLPkA0CBJAy4r+bNC6Lk23wAy4Fb4R5Eobsvrw6ORCHBFEO3h6+IGuoJUpRp3Bkh8Th1QE83DZsjzVPYK9zshG4k/pcqUDCsrablinoABPDwO6djAjycSzFlAbMr7u3xNyvOTB9aud4C0AKLJJheg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O8Ap4s3E; 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="O8Ap4s3E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 174DAC4CEFA; Mon, 28 Jul 2025 13:55:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710941; bh=jMF8HCm3Xp9lU82DGkhsoTy0DGh7IgTN4O7PJLsN8Po=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O8Ap4s3EyktRj3uCJ/vsNBOMv69LSBbdRvAhSe8qBTwNOb2q2VGnCR6xN9wwh1jzw IhOuBKOoseNZHI8Lwzv7VMjFOFek1C5KoG4k1H+pd9qRccd0kPaGQ18Kh/meg+cdv+ Pr9rYm2iFIwQ/YsJRQgPoS2A1WXrKYe4frnmVaNqrJSl7TkmXevClKogQ3bhq4rRR2 gbdosR0WcxUCaUms2uoFu4Nawp/V7XCHasalAzsmvkpU46PFtuw4H1fSmnFWYphJ9z hDTNIt8TZB2sUDSGvtPpEDfyAS5FbCE6HIDdXB2cgWeBawt0ErrI4YsM6KEXS+HLL5 vr7rJh4rzb/2w== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 31/38] coco: guest: arm64: Add support for fetching interface report and certificate chain from host Date: Mon, 28 Jul 2025 19:22:08 +0530 Message-ID: <20250728135216.48084-32-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fetch interface report and certificate chain from the host using RHI calls. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 9 ++ arch/arm64/include/asm/rsi_smc.h | 6 ++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 131 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 5 + 4 files changed, 151 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 1d76f7d37cb6..18fc4e1ce577 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -219,4 +219,13 @@ static inline unsigned long __rsi_rdev_get_interface_r= eport(unsigned long vdev_i return res.a0; } =20 +static inline unsigned long rsi_host_call(phys_addr_t addr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_HOST_CALL, addr, &res); + + return res.a0; +} + #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 6afcccee2ae7..1d762fe3777b 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -183,6 +183,12 @@ struct realm_config { */ #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198) =20 +struct rsi_host_call { + u16 imm; + u8 padding[6]; + u64 gprs[31]; +}; + /* * Make a Host call. * diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 28ec946df1e2..47b379318e7c 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" @@ -50,6 +51,121 @@ rsi_rdev_get_interface_report(struct pci_dev *pdev, uns= igned long vdev_id, return RSI_SUCCESS; } =20 +static long rhi_get_report(int vdev_id, int da_object_type, void **report,= int *report_size) +{ + int ret, enc_ret =3D 0; + int nr_pages; + int max_data_len; + void *data_buf_shared, *data_buf_private; + struct rsi_host_call *rhicall; + + rhicall =3D kmalloc(sizeof(struct rsi_host_call), GFP_KERNEL); + if (!rhicall) + return -ENOMEM; + + rhicall->imm =3D 0; + rhicall->gprs[0] =3D RHI_DA_FEATURES; + + ret =3D rsi_host_call(virt_to_phys(rhicall)); + if (ret !=3D RSI_SUCCESS) { + ret =3D -EIO; + goto err_out; + } + + if (rhicall->gprs[0] !=3D 0x3) { + ret =3D -EIO; + goto err_out; + } + + rhicall->imm =3D 0; + rhicall->gprs[0] =3D RHI_DA_OBJECT_SIZE; + rhicall->gprs[1] =3D vdev_id; + rhicall->gprs[2] =3D da_object_type; + + ret =3D rsi_host_call(virt_to_phys(rhicall)); + if (ret !=3D RSI_SUCCESS) { + ret =3D -EIO; + goto err_out; + } + if (rhicall->gprs[0] !=3D RHI_DA_SUCCESS) { + ret =3D -EIO; + goto err_out; + } + max_data_len =3D rhicall->gprs[1]; + *report_size =3D max_data_len; + + /* + * We need to share this memory with hypervisor. + * So it should be multiple of sharing unit. + */ + max_data_len =3D ALIGN(max_data_len, PAGE_SIZE); + nr_pages =3D max_data_len >> PAGE_SHIFT; + + if (!max_data_len || nr_pages > MAX_ORDER_NR_PAGES) { + ret =3D -ENOMEM; + goto err_out; + } + + /* + * We need to share this memory with hypervisor. + * So it should be multiple of sharing unit. + */ + data_buf_shared =3D (void *)__get_free_pages(GFP_KERNEL, get_order(max_da= ta_len)); + if (!data_buf_shared) { + ret =3D -ENOMEM; + goto err_out; + } + + data_buf_private =3D kmalloc(*report_size, GFP_KERNEL); + if (!data_buf_private) { + ret =3D -ENOMEM; + goto err_private_alloc; + } + + ret =3D set_memory_decrypted((unsigned long)data_buf_shared, nr_pages); + if (ret) { + ret =3D -EIO; + goto err_decrypt; + } + + rhicall->imm =3D 0; + rhicall->gprs[0] =3D RHI_DA_OBJECT_READ; + rhicall->gprs[1] =3D vdev_id; + rhicall->gprs[2] =3D da_object_type; + rhicall->gprs[3] =3D 0; /* offset within the data buffer */ + rhicall->gprs[4] =3D max_data_len; + rhicall->gprs[5] =3D virt_to_phys(data_buf_shared); + ret =3D rsi_host_call(virt_to_phys(rhicall)); + if (ret !=3D RSI_SUCCESS || rhicall->gprs[0] !=3D RHI_DA_SUCCESS) { + ret =3D -EIO; + goto err_rhi_call; + } + + memcpy(data_buf_private, data_buf_shared, *report_size); + enc_ret =3D set_memory_encrypted((unsigned long)data_buf_shared, nr_pages= ); + if (!enc_ret) + /* If we fail to mark it encrypted don't free it back */ + free_pages((unsigned long)data_buf_shared, get_order(max_data_len)); + + *report =3D data_buf_private; + kfree(rhicall); + return 0; + +err_rhi_call: + enc_ret =3D set_memory_encrypted((unsigned long)data_buf_shared, nr_pages= ); +err_decrypt: + kfree(data_buf_private); +err_private_alloc: + if (!enc_ret) + /* If we fail to mark it encrypted don't free it back */ + free_pages((unsigned long)data_buf_shared, get_order(max_data_len)); +err_out: + *report =3D NULL; + *report_size =3D 0; + kfree(rhicall); + return ret; +} + int rsi_device_lock(struct pci_dev *pdev) { unsigned long ret; @@ -82,5 +198,20 @@ int rsi_device_lock(struct pci_dev *pdev) return -EOPNOTSUPP; } =20 + /* Now make a host call to copy the interface report to guest. */ + ret =3D rhi_get_report(vdev_id, RHI_DA_OBJECT_INTERFACE_REPORT, + &dsm->interface_report, &dsm->interface_report_size); + if (ret) { + pci_err(pdev, "failed to get interface report from the host (%lu)\n", re= t); + return -EIO; + } + + ret =3D rhi_get_report(vdev_id, RHI_DA_OBJECT_CERTIFICATE, + &dsm->certificate, &dsm->certificate_size); + if (ret) { + pci_err(pdev, "failed to get device certificate from the host (%lu)\n", = ret); + return -EIO; + } + return ret; } diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index f12430c7d792..bd565785ff4b 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -9,10 +9,15 @@ #include #include #include +#include =20 struct cca_guest_dsc { struct pci_tsm_pf0 pci; unsigned long instance_id; + void *interface_report; + int interface_report_size; + void *certificate; + int certificate_size; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C0D0726FA60; Mon, 28 Jul 2025 13:55: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=1753710947; cv=none; b=AoMQrI1GpNnILgTqfGYYI3K01I//14qncOheKZkWfcN0EuZnQCrnD8MH6bGZdM/FtbHSkX7UrSenDNRwsTeY2MNu9k39QvadfeisTgJCoIHwvUXn59txOLAdUxE2Q1J9ffnmrC2HLTlyhZO75Ty2gETEP0HJ6zStPV0IgHBhwZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710947; c=relaxed/simple; bh=a0YStxMFkGn3VVGT8LHrbE2+pWRULcaCe29nuP1s6PQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t6QvFyPexIOewiYhfiVhW86UnxGqtA+tHGhC6tT6Vzl0MZfi6HR8gAmbByEG/I7B7+OAV3qBtTTJURVtTN9q16QWkh0b/OcH5BlINTfXQIEMytDiCZS117b9t1G3HQH7KttimSaH7ZNICkUxZJQ5A/KsxfmImJpKnEc5UyR6S1U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fH3xFRjB; 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="fH3xFRjB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08CB6C4CEE7; Mon, 28 Jul 2025 13:55:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710947; bh=a0YStxMFkGn3VVGT8LHrbE2+pWRULcaCe29nuP1s6PQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fH3xFRjBTaZDjZhXgUBn3tyJ0Ckj9hK1LMVKW6Bb0zzPpxVnzuupQohFR7SOG4jv+ B317DahRvEeQhOrzYQgpn5LvHCrtEXlTw28DRjqAzTeeorqkRpec+q7J2q8xNG+Jtr S83NBwKbb0yLiQzkPt6ekYh7Q8lRndjVestX6WY7jUWTH59ApSZvwPRXOJci3b4Srg 9f9I1qRbf4NlTTxrwDVWnHpWESXE8HtvXG9CfYZzsk7k78pxxIn2JViKNj9r0tzs3v wySZeQNKrYAjYUwToiCF1NkHx5DYPoHf+hHvQxzYYg9lZCEdJOP29c1x9tT9M2l7FF PfS2iMKCnGxGg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 32/38] coco: guest: arm64: Add support for guest initiated TDI bind/unbind Date: Mon, 28 Jul 2025 19:22:09 +0530 Message-ID: <20250728135216.48084-33-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add RHI for VDEV_SET_TDI_STATE Note: This is not part of RHI spec. This is a POC implementation and will be later switced to correct interface defined by RHI. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rhi.h | 7 +++++ arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/rhi.c | 35 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/arm-cca.c | 22 ++++++++++++-- drivers/virt/coco/arm-cca-host/arm-cca.c | 8 ++++-- 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/kernel/rhi.c diff --git a/arch/arm64/include/asm/rhi.h b/arch/arm64/include/asm/rhi.h index d3c22e582678..993b4b15b057 100644 --- a/arch/arm64/include/asm/rhi.h +++ b/arch/arm64/include/asm/rhi.h @@ -16,6 +16,7 @@ #define RHI_DA_FEATURES SMC_RHI_CALL(0x004d) #define RHI_DA_OBJECT_SIZE SMC_RHI_CALL(0x004e) #define RHI_DA_OBJECT_READ SMC_RHI_CALL(0x004f) +#define RHI_DA_VDEV_SET_TDI_STATE SMC_RHI_CALL(0x0052) =20 #define RHI_DA_OBJECT_CERTIFICATE 0x1 #define RHI_DA_OBJECT_MEASUREMENT 0x2 @@ -29,4 +30,10 @@ #define RHI_ERROR_DATA_NOT_AVAILABLE 0x4 #define RHI_ERROR_INVALID_OFFSET 0x5 #define RHI_ERROR_INVALID_ADDR 0x6 + +#define RHI_DA_TDI_CONFIG_UNLOCKED 0x0 +#define RHI_DA_TDI_CONFIG_LOCKED 0x1 +#define RHI_DA_TDI_CONFIG_RUN 0x2 +long rhi_da_vdev_set_tdi_state(unsigned long vdev_id, unsigned long target= _state); + #endif diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index a2faf0049dab..dde8fa78852c 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -34,7 +34,7 @@ obj-y :=3D debug-monitors.o entry.o irq.o fpsimd.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ syscall.o proton-pack.o idle.o patching.o pi/ \ - rsi.o jump_label.o + rsi.o jump_label.o rhi.o =20 obj-$(CONFIG_COMPAT) +=3D sys32.o signal32.o \ sys_compat.o diff --git a/arch/arm64/kernel/rhi.c b/arch/arm64/kernel/rhi.c new file mode 100644 index 000000000000..3685b50c2e94 --- /dev/null +++ b/arch/arm64/kernel/rhi.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 ARM Ltd. + */ + +#include +#include +#include +#include + +#include + +long rhi_da_vdev_set_tdi_state(unsigned long guest_rid, unsigned long targ= et_state) +{ + long ret; + struct rsi_host_call *rhi_call; + + rhi_call =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 guest_rid; + rhi_call->gprs[2] =3D target_state; + + ret =3D rsi_host_call(virt_to_phys(rhi_call)); + if (ret !=3D RSI_SUCCESS) + ret =3D -EIO; + else + ret =3D rhi_call->gprs[0]; + + kfree(rhi_call); + return ret; +} diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index 2c0190bcb2a9..de70fba09e92 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -222,11 +222,20 @@ static void cca_tsm_pci_remove(struct pci_tsm *tsm) =20 static int cca_tsm_lock(struct pci_dev *pdev) { - unsigned long ret; + long ret; + int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); =20 + ret =3D rhi_da_vdev_set_tdi_state(vdev_id, RHI_DA_TDI_CONFIG_LOCKED); + if (ret) { + pci_err(pdev, "failed to TSM bind the device (%ld)\n", ret); + return -EIO; + } + + /* This will be done by above rhi in later spec */ ret =3D rsi_device_lock(pdev); if (ret) { - pci_err(pdev, "failed to lock the device (%lu)\n", ret); + pci_err(pdev, "failed to lock the device (%ld)\n", ret); return -EIO; } return 0; @@ -234,6 +243,15 @@ static int cca_tsm_lock(struct pci_dev *pdev) =20 static void cca_tsm_unlock(struct pci_dev *pdev) { + long ret; + int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); + + ret =3D rhi_da_vdev_set_tdi_state(vdev_id, RHI_DA_TDI_CONFIG_UNLOCKED); + if (ret) { + pci_err(pdev, "failed to TSM unbind the device (%ld)\n", ret); + return; + } } =20 static const struct pci_tsm_ops cca_pci_ops =3D { diff --git a/drivers/virt/coco/arm-cca-host/arm-cca.c b/drivers/virt/coco/a= rm-cca-host/arm-cca.c index 0807fcf8d222..18d0a627baa4 100644 --- a/drivers/virt/coco/arm-cca-host/arm-cca.c +++ b/drivers/virt/coco/arm-cca-host/arm-cca.c @@ -254,9 +254,13 @@ static struct pci_tdi *cca_tsm_bind(struct pci_dev *pd= ev, struct pci_dev *pf0_de static void cca_tsm_unbind(struct pci_tdi *tdi) { struct realm *realm =3D &tdi->kvm->arch.realm; - + /* + * FIXME!! + * All the related DEV RIPAS regions should be unmapped by now. + * For now we handle them during stage2 teardown. There is no + * bound IPA address available here. Possibly dmabuf can help + */ rme_unbind_vdev(realm, tdi->pdev, tdi->pdev->tsm->dsm_dev); - module_put(THIS_MODULE); } =20 --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 862442741C6; Mon, 28 Jul 2025 13:55: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=1753710953; cv=none; b=qbKLG2clpWm0dx9xfzWTgY8l3sjyWdN7IvIBO+qhp3H+e4Zv81q7voDgsm5NJjqy50eyUztjOq1F1Ca/YQAtIcZ1C45ej0SpaDG1lKSf7xt7WrmUiC1ev2v+6PGHmQDOKyu8gQFEdaPmUA4oFueaG76o3ieu/N3TN3myKmjPRRo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710953; c=relaxed/simple; bh=b2qi+JW50MnmkaO8ACOeTYJhbGQg2MNXTFbDlnbHVbE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MW+8PkX5fsrtTddXhdcWv6LX4CewMfhEXGq5wx6ySHeF4oTBxakwZYeqNEEG5EVNUyMojKCCUaSMPa2coOT+pZRs0pNAZdPXpd89SGfV3CtgiO++Hv/zKvTRz4Y80ti6MiDqGKqB7HsX9d7NjOMbEnniPH/bSPL1jDc5qYau5j4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SGgI2aej; 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="SGgI2aej" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 37024C4CEE7; Mon, 28 Jul 2025 13:55:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710953; bh=b2qi+JW50MnmkaO8ACOeTYJhbGQg2MNXTFbDlnbHVbE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SGgI2aejizXQyYZ7XwB7uSgxedVfLzm0eIpVxqMS/xgrbDf9v8k11rufycOcX29zL pI22oKsSpHJWqP/+G1WmEm+i56BLd1pJU1gFNoIHQXCQI57XwyXt1L5p+gpTHvy/5T vRLU26PeIqCTxxDdOBzoar6N4T1PzRBa8yXo/qA41ld3YDIH4gtSkocTAx3KxYUuuB scs4vfYW4lyHpdgD/zGOC/eFbyHpdJGqCA12EzESvIDtTKGNR/gBRIh6zXZ4McEyGO WJDC3VpWfT0w+wAybbAuX/emezjXtMd9C8zOngia6CWyHcXbBlo9nKC9CsVsnaKar5 d2UlBZ+a5wv8w== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 33/38] KVM: arm64: CCA: handle dev mem map/unmap Date: Mon, 28 Jul 2025 19:22:10 +0530 Message-ID: <20250728135216.48084-34-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Handle VM exit on DEV_MEM_MAP Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_cmds.h | 40 +++++++ arch/arm64/include/asm/rmi_smc.h | 5 + arch/arm64/kvm/rme-exit.c | 39 +++++- arch/arm64/kvm/rme.c | 190 ++++++++++++++++++++++++++++-- drivers/vfio/pci/vfio_pci_core.c | 1 + 5 files changed, 262 insertions(+), 13 deletions(-) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi= _cmds.h index fcf6b319e953..900e35dae740 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -638,4 +638,44 @@ static inline unsigned long rmi_vdev_complete(unsigned= long rec_phys, unsigned l return res.a0; } =20 +static inline int rmi_rtt_dev_mem_validate(unsigned long rd, unsigned long= rec, + unsigned long base, unsigned long top, + unsigned long *out_top) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_DEV_MEM_VALIDATE, rd, rec, base, top, &r= es); + + if (out_top) + *out_top =3D res.a1; + + return res.a0; +} + +static inline int rmi_dev_mem_map(unsigned long rd, unsigned long ipa, + unsigned long level, unsigned long pa) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_DEV_MEM_MAP, rd, ipa, level, pa, &res); + + return res.a0; +} + +static inline int rmi_dev_mem_unmap(unsigned long rd, unsigned long ipa, + unsigned long level, unsigned long *out_pa, + unsigned long *out_ipa) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_DEV_MEM_UNMAP, rd, ipa, level, &res); + + if (out_pa) + *out_pa =3D res.a1; + if (out_ipa) + *out_ipa =3D res.a2; + + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index 7073eccaec5f..ab169b375198 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -39,6 +39,7 @@ =20 #define SMC_RMI_RTT_READ_ENTRY SMC_RMI_CALL(0x0161) #define SMC_RMI_RTT_UNMAP_UNPROTECTED SMC_RMI_CALL(0x0162) +#define SMC_RMI_RTT_DEV_MEM_VALIDATE SMC_RMI_CALL(0x0163) =20 #define SMC_RMI_PSCI_COMPLETE SMC_RMI_CALL(0x0164) #define SMC_RMI_FEATURES SMC_RMI_CALL(0x0165) @@ -47,6 +48,9 @@ #define SMC_RMI_RTT_INIT_RIPAS SMC_RMI_CALL(0x0168) #define SMC_RMI_RTT_SET_RIPAS SMC_RMI_CALL(0x0169) =20 +#define SMC_RMI_DEV_MEM_MAP SMC_RMI_CALL(0x0172) +#define SMC_RMI_DEV_MEM_UNMAP SMC_RMI_CALL(0x0173) + #define SMC_RMI_PDEV_COMMUNICATE SMC_RMI_CALL(0x0175) #define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176) #define SMC_RMI_PDEV_DESTROY SMC_RMI_CALL(0x0177) @@ -84,6 +88,7 @@ enum rmi_ripas { RMI_EMPTY =3D 0, RMI_RAM =3D 1, RMI_DESTROYED =3D 2, + RMI_DEV =3D 3, }; =20 #define RMI_NO_MEASURE_CONTENT 0 diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c index 25948207fc5b..77829491805b 100644 --- a/arch/arm64/kvm/rme-exit.c +++ b/arch/arm64/kvm/rme-exit.c @@ -170,17 +170,44 @@ EXPORT_SYMBOL_GPL(realm_exit_dev_mem_map_handler); static int rec_exit_dev_mem_map(struct kvm_vcpu *vcpu) { int ret; + struct kvm *kvm =3D vcpu->kvm; + struct realm *realm =3D &kvm->arch.realm; struct realm_rec *rec =3D &vcpu->arch.rec; + unsigned long base =3D rec->run->exit.dev_mem_base; + unsigned long top =3D rec->run->exit.dev_mem_top; + + if (!kvm_realm_is_private_address(realm, base) || + !kvm_realm_is_private_address(realm, top - 1)) { + vcpu_err(vcpu, "Invalid DEV_MEM_VALIDATE for %#lx - %#lx\n", base, top); + return -EINVAL; + } =20 + /* See if coco driver want to look at the dev mem_map request */ if (realm_exit_dev_mem_map_handler) { ret =3D (*realm_exit_dev_mem_map_handler)(rec); - } else { - kvm_pr_unimpl("Unsupported exit reason: %u\n", - rec->run->exit.exit_reason); - vcpu->run->exit_reason =3D KVM_EXIT_INTERNAL_ERROR; - ret =3D 0; + if (ret) + return ret; } - return ret; + +#if 0 + /* we don't need a memory fault exit for device mapping. + * 1. On enter to rec, we map the device memory using dev_mem_map + 2. There is no fallocate, and we are not tracking this via memory attr= ibutes. + If we need a fault exit, we need to differentiate it in VMM so that we= don't + map the private memory via tsm map ioctl. + */ + /* + * Exit to VMM so that VMM can deny the validation, the actual + * validation response is done on next entry + */ + kvm_prepare_memory_fault_exit(vcpu, base, top - base, false, false, + true); + + /* exit to hypervisor */ + return -EFAULT; +#else + return 1; +#endif } =20 static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c index d1c147aba2ed..11c8d47e3e9b 100644 --- a/arch/arm64/kvm/rme.c +++ b/arch/arm64/kvm/rme.c @@ -445,18 +445,27 @@ void kvm_realm_destroy_rtts(struct kvm *kvm, u32 ia_b= its) WARN_ON(realm_tear_down_rtt_range(realm, 0, (1UL << ia_bits))); } =20 -static int realm_destroy_private_granule(struct realm *realm, - unsigned long ipa, +static int realm_destroy_private_granule(struct realm *realm, unsigned lon= g ipa, unsigned long *next_addr, - phys_addr_t *out_rtt) + phys_addr_t *out_rtt, + int *ripas) { unsigned long rd =3D virt_to_phys(realm->rd); unsigned long rtt_addr; + struct rtt_entry rtt_entry; phys_addr_t rtt; int ret; =20 + ret =3D rmi_rtt_read_entry(rd, ipa, RMM_RTT_MAX_LEVEL, &rtt_entry); + if (ret !=3D RMI_SUCCESS) + return -ENXIO; + retry: - ret =3D rmi_data_destroy(rd, ipa, &rtt_addr, next_addr); + if (rtt_entry.ripas =3D=3D RMI_DEV) + ret =3D rmi_dev_mem_unmap(rd, ipa, RMM_RTT_MAX_LEVEL, &rtt_addr, next_ad= dr); + else + ret =3D rmi_data_destroy(rd, ipa, &rtt_addr, next_addr); + if (RMI_RETURN_STATUS(ret) =3D=3D RMI_ERROR_RTT) { if (*next_addr > ipa) return 0; /* UNASSIGNED */ @@ -484,6 +493,7 @@ static int realm_destroy_private_granule(struct realm *= realm, return -ENXIO; =20 *out_rtt =3D rtt_addr; + *ripas =3D rtt_entry.ripas; =20 return 0; } @@ -495,16 +505,16 @@ static int realm_unmap_private_page(struct realm *rea= lm, unsigned long end =3D ALIGN(ipa + 1, PAGE_SIZE); unsigned long addr; phys_addr_t out_rtt =3D PHYS_ADDR_MAX; - int ret; + int ret, ripas; =20 for (addr =3D ipa; addr < end; addr =3D *next_addr) { ret =3D realm_destroy_private_granule(realm, addr, next_addr, - &out_rtt); + &out_rtt, &ripas); if (ret) return ret; } =20 - if (out_rtt !=3D PHYS_ADDR_MAX) { + if (out_rtt !=3D PHYS_ADDR_MAX && ripas !=3D RMI_DEV) { out_rtt =3D ALIGN_DOWN(out_rtt, PAGE_SIZE); free_page((unsigned long)phys_to_virt(out_rtt)); } @@ -1222,8 +1232,17 @@ static int realm_set_ipa_state(struct kvm_vcpu *vcpu, struct kvm *kvm =3D vcpu->kvm; int ret =3D ripas_change(kvm, vcpu, start, end, RIPAS_SET, top_ipa); =20 +#if 0 + /* + * We don't need to do this because a ripas change will take a memory + * fault exit That results in stage2 invalidate which will take care of + * unmap of both private and shared ipa.. IF we need to do this, we + * should do it before ripas change, we look at ripas when unmapping the + * private range. + */ if (ripas =3D=3D RMI_EMPTY && *top_ipa !=3D start) realm_unmap_private_range(kvm, start, *top_ipa, false); +#endif =20 return ret; } @@ -1492,6 +1511,159 @@ static void kvm_complete_ripas_change(struct kvm_vc= pu *vcpu) rec->run->exit.ripas_base =3D base; } =20 +/* + * Even though we can map larger block, since we need to delegate each gra= nule. + * We map granule size and fold + */ +static int realm_dev_mem_map(struct kvm_vcpu *vcpu, unsigned long start_ip= a, + unsigned long end_ipa, phys_addr_t phys) +{ + int ret =3D 0; + unsigned long ipa; + struct kvm *kvm =3D vcpu->kvm; + struct realm *realm =3D &kvm->arch.realm; + phys_addr_t rd =3D virt_to_phys(realm->rd); + struct kvm_mmu_memory_cache *memcache =3D &vcpu->arch.mmu_page_cache; + + for (ipa =3D start_ipa ; ipa < end_ipa; ipa +=3D PAGE_SIZE) { + + if (rmi_granule_delegate(phys)) + return -EINVAL; + + ret =3D rmi_dev_mem_map(rd, ipa, RMM_RTT_MAX_LEVEL, phys); + + if (RMI_RETURN_STATUS(ret) =3D=3D RMI_ERROR_RTT) { + /* Create missing RTTs and retry */ + int level =3D RMI_RETURN_INDEX(ret); + + ret =3D realm_create_rtt_levels(realm, ipa, level, + RMM_RTT_MAX_LEVEL, + memcache); + WARN_ON(ret); + if (ret) + goto err_undelegate; + + ret =3D rmi_dev_mem_map(rd, ipa, RMM_RTT_MAX_LEVEL, phys); + } + WARN_ON(ret); + + if (ret) + goto err_undelegate; + + phys +=3D PAGE_SIZE; + } + + /* : ipa =3D ALIGN(start_ipa, RMM_L2_BLOCK_SIZE) to be safer ? */ + for (ipa =3D start_ipa; ((ipa + RMM_L2_BLOCK_SIZE) < end_ipa); ipa +=3D R= MM_L2_BLOCK_SIZE) + fold_rtt(realm, ipa, RMM_RTT_BLOCK_LEVEL); + + return 0; + +err_undelegate: + WARN_ON(rmi_granule_undelegate(phys)); + + while (ipa > start_ipa) { + unsigned long out_pa; + + phys -=3D PAGE_SIZE; + ipa -=3D PAGE_SIZE; + + WARN_ON(rmi_dev_mem_unmap(rd, ipa, RMM_RTT_MAX_LEVEL, &out_pa, NULL)); + + WARN_ON(phys !=3D out_pa); + WARN_ON(rmi_granule_undelegate(out_pa)); + } + return -ENXIO; +} + +static int realm_dev_mem_validate(struct kvm_vcpu *vcpu, + unsigned long start, unsigned long end, + unsigned long *top_ipa) +{ + struct kvm *kvm =3D vcpu->kvm; + struct realm *realm =3D &kvm->arch.realm; + struct realm_rec *rec =3D &vcpu->arch.rec; + phys_addr_t rd_phys =3D virt_to_phys(realm->rd); + phys_addr_t rec_phys =3D virt_to_phys(rec->rec_page); + struct kvm_mmu_memory_cache *memcache =3D &vcpu->arch.mmu_page_cache; + unsigned long ipa =3D start; + int ret =3D 0; + + while (ipa < end) { + unsigned long next; + + ret =3D rmi_rtt_dev_mem_validate(rd_phys, rec_phys, ipa, end, &next); + + if (RMI_RETURN_STATUS(ret) =3D=3D RMI_ERROR_RTT) { + /* + * FIXME!! We can't find the RTT error here, because + * things are already setup by dev_mem_map before + */ + int walk_level =3D RMI_RETURN_INDEX(ret); + int level =3D find_map_level(realm, ipa, end); + + /* + * If the RMM walk ended early then more tables are + * needed to reach the required depth to set the RIPAS. + */ + if (walk_level < level) { + ret =3D realm_create_rtt_levels(realm, ipa, + walk_level, + level, + memcache); + /* Retry with RTTs created */ + if (!ret) + continue; + } else { + ret =3D -EINVAL; + } + + break; + } else if (RMI_RETURN_STATUS(ret) !=3D RMI_SUCCESS) { + WARN(1, "Unexpected error in %s: %#x\n", __func__, + ret); + ret =3D -EINVAL; + break; + } + ipa =3D next; + } + + *top_ipa =3D ipa; + + return ret; +} + +static void kvm_complete_dev_mem_change(struct kvm_vcpu *vcpu) +{ + struct kvm *kvm =3D vcpu->kvm; + struct realm_rec *rec =3D &vcpu->arch.rec; + unsigned long base =3D rec->run->exit.dev_mem_base; + unsigned long top =3D rec->run->exit.dev_mem_top; + unsigned long pa =3D rec->run->exit.dev_mem_pa; + unsigned long top_ipa; + int ret; + + do { + kvm_mmu_topup_memory_cache(&vcpu->arch.mmu_page_cache, + kvm_mmu_cache_min_pages(vcpu->arch.hw_mmu)); + write_lock(&kvm->mmu_lock); + /* + * FIXME!! we need validate these values. Also PA need to be tied to the= life cycle + * of vfio device/file descriptor. + */ + ret =3D realm_dev_mem_map(vcpu, base, top, pa); + if (!ret) + ret =3D realm_dev_mem_validate(vcpu, base, top, &top_ipa); + write_unlock(&kvm->mmu_lock); + if (ret) + break; + + base =3D top_ipa; + } while (top_ipa < top); + + WARN(ret, "Unable to satisfy DEV_MEM_CHANGE for %#lx - %#lx\n", base, top= ); +} + /* * kvm_rec_pre_enter - Complete operations before entering a REC * @@ -1520,6 +1692,10 @@ int kvm_rec_pre_enter(struct kvm_vcpu *vcpu) case RMI_EXIT_RIPAS_CHANGE: kvm_complete_ripas_change(vcpu); break; + case RMI_EXIT_DEV_MEM_MAP: + kvm_complete_dev_mem_change(vcpu); + break; + } =20 return 1; diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_c= ore.c index afdb39c6aefd..264ee84d7ecd 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1718,6 +1718,7 @@ static const struct vm_operations_struct vfio_pci_mma= p_ops =3D { #endif }; =20 +/* FIXME!! don't allow mmap once the device is TDISP locked and we did dev= mem_map. */ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struc= t *vma) { struct vfio_pci_core_device *vdev =3D --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7F0626B764; Mon, 28 Jul 2025 13:55:59 +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=1753710959; cv=none; b=M7/O+5IcB46V07nUA7IO71Q3t7y17WYdKVpoQQDXpsgv3aD467g1BsuGbV05CbzYN14B5qmJuol4wQUGMWNrgOVFW/VP4whdE3oHuhEgdnFZRwUTtJaBsgsNjOdvX4M6J8FRRVQHC6dUam0CW2RPoQBxKSvfeZo3AqESj4BV8YA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710959; c=relaxed/simple; bh=fLG0zNq+rkQS0AkmSrJIwAxcxEMl8AXx3l1V+ubQACY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U2QQ1ee5ngiNAvJRnK6ZERvX7ItcRGmsr/NtOoOu52TQ6Em347HHWs9d6cGRpTaxZmPQG9H9HDdMtpEuGMWVNIgU+emAFk67vsPS4SGTP3YVqjn1ljBQtq42IA3F3UG4nNGaS5N7Lywe3rTUAvAyxZ0k4u4TJ9bRPXrkX+Pq+GY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pC5mRm2N; 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="pC5mRm2N" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F2F9EC4CEEF; Mon, 28 Jul 2025 13:55:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710959; bh=fLG0zNq+rkQS0AkmSrJIwAxcxEMl8AXx3l1V+ubQACY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pC5mRm2Nz7E+xrsouiNe/IeW8XD2Zw2F/Ay5Cpz4+fFJ/xGy48WcSps2Y87mTmPqD 8tFTb7uQJ3FUmlixbyyAalat4blllbbCKqUO0laYwTN6KVPPyigbz2MKFV2hrhw1gr Ks//N6vIF9DZpszrnKQA5z4iOk9q1rhihWA/7L5LDFM8UbUOwLE0ZORai1NBWTV2CD l6jYxhhM9Z2eajZysT/+Ps4elh+pvGT3+2Hf5+ibhfW+oMTtNA5QHVfcCsD7OHY29p aRTl2OE2Z3lr9ERICGIJso4JLheoYprk5TZJ+Qpokk3o8bnJJxqRAmdA9GUEyxu6+F v9Z8dvxxneBuw== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 34/38] coco: guest: arm64: Validate mmio range found in the interface report Date: Mon, 28 Jul 2025 19:22:11 +0530 Message-ID: <20250728135216.48084-35-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" This starts the sequence to transition the realm device to the TDISP RUN state by writing 1 to 'tsm/accept'. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 18 +++ arch/arm64/include/asm/rsi_smc.h | 4 + drivers/virt/coco/arm-cca-guest/arm-cca.c | 3 + drivers/virt/coco/arm-cca-guest/rsi-da.c | 132 ++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 25 ++++ 5 files changed, 182 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 18fc4e1ce577..1cc00d404e53 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -228,4 +228,22 @@ static inline unsigned long rsi_host_call(phys_addr_t = addr) return res.a0; } =20 +static inline unsigned long +rsi_rdev_validate_mapping(unsigned long vdev_id, unsigned long inst_id, + phys_addr_t start_ipa, phys_addr_t end_ipa, + phys_addr_t io_pa, phys_addr_t *next_ipa, unsigned long flags) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_VALIDATE_MAPPING, vdev_id, + inst_id, start_ipa, end_ipa, io_pa, flags, &res); + *next_ipa =3D res.a1; + + if (res.a2 !=3D RSI_ACCEPT) + return -EPERM; + + if (res.a0 !=3D RSI_SUCCESS) + return -EINVAL; + return 0; +} #endif /* __ASM_RSI_CMDS_H */ diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_= smc.h index 1d762fe3777b..a28b41cf01ca 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -204,4 +204,8 @@ struct rsi_host_call { =20 #define SMC_RSI_RDEV_LOCK SMC_RSI_FID(0x1a9) =20 +#define RSI_DEV_MEM_COHERENT BIT(0) +#define RSI_DEV_MEM_LIMITED_ORDER BIT(1) +#define SMC_RSI_RDEV_VALIDATE_MAPPING SMC_RSI_FID(0x1ac) + #endif /* __ASM_RSI_SMC_H_ */ diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index de70fba09e92..c1cefb983ac7 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -247,6 +247,9 @@ static void cca_tsm_unlock(struct pci_dev *pdev) int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); =20 + /* invalidate dev mapping based on interface report */ + rsi_update_interface_report(pdev, false); + ret =3D rhi_da_vdev_set_tdi_state(vdev_id, RHI_DA_TDI_CONFIG_UNLOCKED); if (ret) { pci_err(pdev, "failed to TSM unbind the device (%ld)\n", ret); diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 47b379318e7c..936f844880de 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -215,3 +215,135 @@ int rsi_device_lock(struct pci_dev *pdev) =20 return ret; } + +static inline unsigned long +rsi_validate_dev_mapping(unsigned long vdev_id, unsigned long inst_id, + phys_addr_t start_ipa, phys_addr_t end_ipa, + phys_addr_t io_pa, unsigned long flags) +{ + unsigned long ret; + phys_addr_t next_ipa; + + while (start_ipa < end_ipa) { + ret =3D rsi_rdev_validate_mapping(vdev_id, inst_id, + start_ipa, end_ipa, + io_pa, &next_ipa, flags); + if (ret || next_ipa < start_ipa || next_ipa > end_ipa) + return -EINVAL; + io_pa +=3D next_ipa - start_ipa; + start_ipa =3D next_ipa; + } + return 0; +} + +static int rsi_invalidate_dev_mapping(phys_addr_t start_ipa, phys_addr_t e= nd_ipa) +{ + return rsi_set_memory_range(start_ipa, end_ipa, RSI_RIPAS_EMPTY, + RSI_CHANGE_DESTROYED); +} + +static int get_msix_bar(struct pci_dev *pdev, int cap) +{ + int bar; + u32 table_offset; + unsigned long flags; + + pci_read_config_dword(pdev, pdev->msix_cap + cap, &table_offset); + bar =3D (u8)(table_offset & PCI_MSIX_TABLE_BIR); + flags =3D pci_resource_flags(pdev, bar); + if (!flags || (flags & IORESOURCE_UNSET)) + return -1; + + return bar; +} + +int rsi_update_interface_report(struct pci_dev *pdev, bool validate) +{ + int ret; + struct resource *r; + int msix_tbl_bar, msix_pba_bar; + unsigned int range_id; + unsigned long mmio_start_phys; + unsigned long mmio_flags =3D 0; /* non coherent, not limited order */ + struct pci_tdisp_mmio_range *mmio_range; + struct pci_tdisp_device_interface_report *interface_report; + struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); + int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); + + + interface_report =3D (struct pci_tdisp_device_interface_report *)dsm->int= erface_report; + mmio_range =3D (struct pci_tdisp_mmio_range *)(interface_report + 1); + + + msix_tbl_bar =3D get_msix_bar(pdev, PCI_MSIX_TABLE); + msix_pba_bar =3D get_msix_bar(pdev, PCI_MSIX_PBA); + + for (int i =3D 0; i < interface_report->mmio_range_count; i++, mmio_range= ++) { + + /*FIXME!! units in 4K size*/ + range_id =3D FIELD_GET(TSM_INTF_REPORT_MMIO_RANGE_ID, mmio_range->range_= attributes); + + /* no secure interrupts */ + if (msix_tbl_bar !=3D -1 && range_id =3D=3D msix_tbl_bar) { + pr_info("Skipping misx table\n"); + continue; + } + + if (msix_pba_bar !=3D -1 && range_id =3D=3D msix_pba_bar) { + pr_info("Skipping misx pba\n"); + continue; + } + + r =3D pci_resource_n(pdev, range_id); + + if (r->end =3D=3D r->start || + ((r->end - r->start + 1) & ~PAGE_MASK) || !mmio_range->num_pages) { + pci_warn(pdev, "Skipping broken range [%d] #%d %d pages, %llx..%llx\n", + i, range_id, mmio_range->num_pages, r->start, r->end); + continue; + } + + if (FIELD_GET(TSM_INTF_REPORT_MMIO_IS_NON_TEE, mmio_range->range_attribu= tes)) { + pci_info(pdev, "Skipping non-TEE range [%d] #%d %d pages, %llx..%llx\n", + i, range_id, mmio_range->num_pages, r->start, r->end); + continue; + } + + /* No secure interrupts, we should not find this set, ignore for now. */ + if (FIELD_GET(TSM_INTF_REPORT_MMIO_MSIX_TABLE, mmio_range->range_attribu= tes) || + FIELD_GET(TSM_INTF_REPORT_MMIO_PBA, mmio_range->range_attributes)) { + pci_info(pdev, "Skipping MSIX (%ld/%ld) range [%d] #%d %d pages, %llx..= %llx\n", + FIELD_GET(TSM_INTF_REPORT_MMIO_MSIX_TABLE, mmio_range->range_attribut= es), + FIELD_GET(TSM_INTF_REPORT_MMIO_PBA, mmio_range->range_attributes), + i, range_id, mmio_range->num_pages, r->start, r->end); + continue; + } + + mmio_start_phys =3D mmio_range->first_page; + if (validate) + ret =3D rsi_validate_dev_mapping(vdev_id, dsm->instance_id, + r->start, r->end + 1, + mmio_start_phys << 12, mmio_flags); + else + ret =3D rsi_invalidate_dev_mapping(r->start, r->end + 1); + if (ret) { + pci_err(pdev, "failed to set protection attributes for the address rang= e\n"); + return -EIO; + } + } + return 0; +} + +int rsi_device_start(struct pci_dev *pdev) +{ + int ret; + + ret =3D rsi_update_interface_report(pdev, true); + if (ret) { + pci_err(pdev, "failed validate the interface report\n"); + return -EIO; + } + + return 0; +} diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index bd565785ff4b..0d6e1c0ada4a 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -11,6 +11,28 @@ #include #include =20 +struct pci_tdisp_device_interface_report { + u16 interface_info; + u16 reserved; + u16 msi_x_message_control; + u16 lnr_control; + u32 tph_control; + u32 mmio_range_count; +} __packed; + +struct pci_tdisp_mmio_range { + u64 first_page; + u32 num_pages; + u32 range_attributes; +} __packed; + +#define TSM_INTF_REPORT_MMIO_MSIX_TABLE BIT(0) +#define TSM_INTF_REPORT_MMIO_PBA BIT(1) +#define TSM_INTF_REPORT_MMIO_IS_NON_TEE BIT(2) +#define TSM_INTF_REPORT_MMIO_IS_UPDATABLE BIT(3) +#define TSM_INTF_REPORT_MMIO_RESERVED GENMASK(15, 4) +#define TSM_INTF_REPORT_MMIO_RANGE_ID GENMASK(31, 16) + struct cca_guest_dsc { struct pci_tsm_pf0 pci; unsigned long instance_id; @@ -29,5 +51,8 @@ static inline struct cca_guest_dsc *to_cca_guest_dsc(stru= ct pci_dev *pdev) return container_of(tsm, struct cca_guest_dsc, pci.tsm); } =20 +int rsi_update_interface_report(struct pci_dev *pdev, bool validate); int rsi_device_lock(struct pci_dev *pdev); +int rsi_device_start(struct pci_dev *pdev); + #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6053E27465A; Mon, 28 Jul 2025 13:56:05 +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=1753710965; cv=none; b=IJNdmk100zA3LByaDXlogCrepV949bw9EuSGahjFITqWz9nnLDiRd2jObpjkEPQfdaQzIIdrKiC4fr13YTkK/dHRXqCIB1CMDbEXXyaqIajccPcsfeLBZ2ZxGKmX+3FHsl+mMvGBGduaNUyAXlYO/RSqfV0Zb9CQHTTmBlhf7SI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710965; c=relaxed/simple; bh=V4MrTdte0492OtV3PFGAqQTiSyPRnkCgmWBOOJ+F/+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ug2DbAkwwWuQv9eXF6ZcgFyhe2xW/oXYJe96YMU6Rhjs4p4G5vl0a2iuU7Kh9IHX6pPH31fYE95SD9f9sWcd45UFloycB5Jf5fAcWME2GQSA73yg3gYxdajFaLbSpVLfCdoi0m65OEDAGi8nxf+sgyX05HiWT/7AWgOUDac6eOw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=l0XKvpm4; 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="l0XKvpm4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBB80C4CEE7; Mon, 28 Jul 2025 13:55:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710965; bh=V4MrTdte0492OtV3PFGAqQTiSyPRnkCgmWBOOJ+F/+A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l0XKvpm4JRHxtgfKKcHwlhKi8gPmHZt6IK22YSgaGAh8qw7SRs1jBgKcJEPfiX4xS +Q6+RcgQTYvQXYA6HIWjv+tli5JIDfbik6D5cTiILvRIpLejIOXz7hK46l74nYcUMR 6VO4JEilZKoxOQzedneSW8P1/8e8W119c7RfD0U4/tF21Tfw8Os5Ygdy2CFFW+qDdU DsE9Qo/ySfVO/CQ/bei1Ev4wINusZ7RuQ7Z6MsCGFKfXwViXpfQLw0k/SeKpkd10uf PqBkaHFCi+AG+uJhOU5ZIk9rp/W6DbADI3awjSrfFH1V3PUe5fgQzeArQ9aAZzl+iN i449r3JK7O3QA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 35/38] coco: guest: arm64: Add Realm device start and stop support Date: Mon, 28 Jul 2025 19:22:12 +0530 Message-ID: <20250728135216.48084-36-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Writing 1 to 'tsm/acceept' will initiate the TDISP RUN sequence. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 19 +++++++ arch/arm64/include/asm/rsi_smc.h | 2 + drivers/virt/coco/arm-cca-guest/arm-cca.c | 15 ++++++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 60 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 +- 5 files changed, 97 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 1cc00d404e53..3463d571d7db 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -246,4 +246,23 @@ rsi_rdev_validate_mapping(unsigned long vdev_id, unsig= ned long inst_id, return -EINVAL; return 0; } + +static inline unsigned long __rsi_rdev_start(unsigned long vdev_id, unsign= ed long inst_id) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_START, vdev_id, inst_id, &res); + + return res.a0; +} + +static inline unsigned long __rsi_rdev_stop(unsigned long vdev_id, unsigne= d long inst_id) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_STOP, vdev_id, inst_id, &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 a28b41cf01ca..f6aa647239c0 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -203,6 +203,8 @@ struct rsi_host_call { #define SMC_RSI_RDEV_GET_INTERFACE_REPORT SMC_RSI_FID(0x1a6) =20 #define SMC_RSI_RDEV_LOCK SMC_RSI_FID(0x1a9) +#define SMC_RSI_RDEV_START SMC_RSI_FID(0x1aa) +#define SMC_RSI_RDEV_STOP SMC_RSI_FID(0x1ab) =20 #define RSI_DEV_MEM_COHERENT BIT(0) #define RSI_DEV_MEM_LIMITED_ORDER BIT(1) diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/= arm-cca-guest/arm-cca.c index c1cefb983ac7..7eeb9732d20a 100644 --- a/drivers/virt/coco/arm-cca-guest/arm-cca.c +++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c @@ -250,6 +250,8 @@ static void cca_tsm_unlock(struct pci_dev *pdev) /* invalidate dev mapping based on interface report */ rsi_update_interface_report(pdev, false); =20 + rsi_device_stop(pdev); + ret =3D rhi_da_vdev_set_tdi_state(vdev_id, RHI_DA_TDI_CONFIG_UNLOCKED); if (ret) { pci_err(pdev, "failed to TSM unbind the device (%ld)\n", ret); @@ -257,11 +259,24 @@ static void cca_tsm_unlock(struct pci_dev *pdev) } } =20 +static int cca_tsm_accept(struct pci_dev *pdev) +{ + int ret; + + ret =3D rsi_device_start(pdev); + if (ret) { + pci_err(pdev, "failed to transition the device to run state (%d)\n", ret= ); + return -EIO; + } + return 0; +} + static const struct pci_tsm_ops cca_pci_ops =3D { .probe =3D cca_tsm_pci_probe, .remove =3D cca_tsm_pci_remove, .lock =3D cca_tsm_lock, .unlock =3D cca_tsm_unlock, + .accept =3D cca_tsm_accept, }; =20 static void cca_tsm_unregister(void *tsm) diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 936f844880de..64034d220e02 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -215,6 +215,24 @@ int rsi_device_lock(struct pci_dev *pdev) =20 return ret; } +static inline unsigned long rsi_rdev_start(struct pci_dev *pdev, + unsigned long vdev_id, unsigned long inst_id) +{ + unsigned long ret; + + ret =3D __rsi_rdev_start(vdev_id, inst_id); + if (ret !=3D RSI_SUCCESS) + return ret; + + do { + ret =3D rsi_rdev_continue(vdev_id, inst_id); + } while (ret =3D=3D RSI_INCOMPLETE); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to communicate with the device (%lu)\n", ret); + return ret; + } + return RSI_SUCCESS; +} =20 static inline unsigned long rsi_validate_dev_mapping(unsigned long vdev_id, unsigned long inst_id, @@ -338,6 +356,9 @@ int rsi_update_interface_report(struct pci_dev *pdev, b= ool validate) int rsi_device_start(struct pci_dev *pdev) { int ret; + struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); + int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); =20 ret =3D rsi_update_interface_report(pdev, true); if (ret) { @@ -345,5 +366,44 @@ int rsi_device_start(struct pci_dev *pdev) return -EIO; } =20 + ret =3D rsi_rdev_start(pdev, vdev_id, dsm->instance_id); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to start the device (%u)\n", ret); + return -EIO; + } + return 0; +} + +static inline unsigned long rsi_rdev_stop(struct pci_dev *pdev, + unsigned long vdev_id, unsigned long inst_id) +{ + unsigned long ret; + + ret =3D __rsi_rdev_stop(vdev_id, inst_id); + if (ret !=3D RSI_SUCCESS) + return ret; + + do { + ret =3D rsi_rdev_continue(vdev_id, inst_id); + } while (ret =3D=3D RSI_INCOMPLETE); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to communicate with the device (%lu)\n", ret); + return ret; + } + return RSI_SUCCESS; +} + +int rsi_device_stop(struct pci_dev *pdev) +{ + int ret; + struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); + int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | + PCI_DEVID(pdev->bus->number, pdev->devfn); + + ret =3D rsi_rdev_stop(pdev, vdev_id, dsm->instance_id); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to stop the device (%u)\n", ret); + return -EIO; + } return 0; } diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 0d6e1c0ada4a..71ee1edb832e 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -54,5 +54,5 @@ static inline struct cca_guest_dsc *to_cca_guest_dsc(stru= ct pci_dev *pdev) int rsi_update_interface_report(struct pci_dev *pdev, bool validate); int rsi_device_lock(struct pci_dev *pdev); int rsi_device_start(struct pci_dev *pdev); - +int rsi_device_stop(struct pci_dev *pdev); #endif --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7EFA126AAB5; Mon, 28 Jul 2025 13:56:11 +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=1753710971; cv=none; b=jiiH3AMFeSv11aoXsynjzedOM6p7VTuPkJ62m6aZqOw8gdoAErulVWUcx5qrYOF11r0xkvwxnoM1DYz9K0q3FnkClcnqcTJFfY0H4EKXPYJgmnQXqsktoAwMmoqaFgXX9vPXh5C1TqIUQyEJWYr5iViPT0vc1OACqmvSehTIt1Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710971; c=relaxed/simple; bh=3efNmr/84SDYWqmCQPInd8xkYI9ZwW9+f+F31pYvQt4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m9EoNm4U9AipN8bIAI/iDJekYh52b70lR6Vot0DSfKLVHmi+M15Zn8ImT4dBR7TogKDs9/jxBi0mtlJJ+XKozcqw+xY9F1W5ZIJSSp8XrpP1MWqeP1IQthTHMALG5Ua32A84PdCN0/gmk93BhuXtG6oHU87BW7gel+NjF/dbyMU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XQgYFKli; 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="XQgYFKli" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBDD2C4CEFB; Mon, 28 Jul 2025 13:56:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710971; bh=3efNmr/84SDYWqmCQPInd8xkYI9ZwW9+f+F31pYvQt4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XQgYFKli6Mf5uciiy2WxU3Z0aQV89Bp9MmO5GboTspMWIhhfRAcy/xIgOxSNFGF5H rpqV+31CtKLAQkYJRfCi/HR3srwp0vP0RO6AtWC2fgRlFIb5O38VjeK8fVt+REpYoQ sWICTfhoH2nkVSjQuqwqdlZnOU0aCpG6mdrQF/jq1wCgJa9vcQShkaDYZbLUNR017C ln8nvT1vXc7qD6ufNBqQwO26ISDZW0dfq7V2KYQRkwWZJPIFIvcm0eg28w4WkDe/XZ 9hMmqza/bHCJg7lvX27ynB+itblE7mOXeUyJj8rYlZJeHpYVUh5dKDZLH84Q6irT0J HV1K26oyGsuDg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 36/38] KVM: arm64: CCA: enable DA in realm create parameters Date: Mon, 28 Jul 2025 19:22:13 +0530 Message-ID: <20250728135216.48084-37-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-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" Now that we have all the required steps for DA in-place, enable DA while creating ralm. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rmi_smc.h | 1 + arch/arm64/kvm/rme.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_= smc.h index ab169b375198..f664954a2a91 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -112,6 +112,7 @@ enum rmi_ripas { #define RMI_REALM_PARAM_FLAG_LPA2 BIT(0) #define RMI_REALM_PARAM_FLAG_SVE BIT(1) #define RMI_REALM_PARAM_FLAG_PMU BIT(2) +#define RMI_REALM_PARAM_FLAG_DA BIT(3) =20 /* * Note many of these fields are smaller than u64 but all fields have u64 diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c index 11c8d47e3e9b..394d1534e6c2 100644 --- a/arch/arm64/kvm/rme.c +++ b/arch/arm64/kvm/rme.c @@ -695,6 +695,8 @@ static int realm_create_rd(struct kvm *kvm) if (r) goto out_undelegate_tables; =20 + /* For now default enable DA */ + params->flags =3D RMI_REALM_PARAM_FLAG_DA; params_phys =3D virt_to_phys(params); =20 if (rmi_realm_create(rd_phys, params_phys)) { --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0071126B74A; Mon, 28 Jul 2025 13:56:17 +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=1753710980; cv=none; b=ozN5B8EYAt/kBFUPKtgoA91lvOchzKvz7EtEyPK4Gvadw1Y9e4Wq8z3IC4XALpqosPDfKeyJ499nHYoFnOQ5CEVmdqcchgzfYz0SNhwl+Cz9omZCJ9Fhl3yRl85dUMLR/YX+s5LwVsOpbYLdro9b/0/GzCvorQUBQcPuX0qaDbw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710980; c=relaxed/simple; bh=8+fCHdn3Uns+Oh6BXNa0Zteex0tK6krOn+9GZide67k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RByeGsy9ksS8kwswNCm/5OfBqs67junPBrE8pvytbDMAMpmEI/fkGWyyVSFMw2j6AIeHfeovokQYn0dJiKzMIiME7YCnK8rfwxzeDZukNx21PXRhvEO35DPC5pfKhniLyHZqxJi02r6v7znh9tvAuAHtO070Yj6VjXD2xuwj6l4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y1geoA6l; 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="Y1geoA6l" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE318C4CEEF; Mon, 28 Jul 2025 13:56:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710977; bh=8+fCHdn3Uns+Oh6BXNa0Zteex0tK6krOn+9GZide67k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y1geoA6leMbw+9D0jt9eF8zWeFNkt4O2OHbAi45jQAPG5w1ugatgPh4ACE+lQL7To 1iUfueuU6Pk6RiEqlW9ZwDCocMmoptgrHn7C2DmowHztL6PwwQrjSWFnef/TTvF5do b37xstGeN36rrnM/aD4yFfeV3I/s33PLgYC+cwLwC/JBVYE8FsnBQ6rUghcqL2lygU 8zx3zgE0P+ongzkqUaW2ZYGWl6xsiNCcsi8zmKOPLQy1md+eCEkVY4rf9rwoYsDvlM bOiTupDCeBfy5aYEB+a+ASAGscX+SfeQSl9VSsgH7Dg0oqL2Z8l2TCZKyrxWNFF27E rEYH5f2Eo+nhg== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 37/38] coco: guest: arm64: Add support for fetching device measurements Date: Mon, 28 Jul 2025 19:22:14 +0530 Message-ID: <20250728135216.48084-38-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fetch device measurements using RSI_RDEV_GET_MEASUREMENTS. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 11 +++++++ arch/arm64/include/asm/rsi_smc.h | 16 ++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.c | 39 ++++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 2 ++ 4 files changed, 68 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 3463d571d7db..42b998f44a0e 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -265,4 +265,15 @@ static inline unsigned long __rsi_rdev_stop(unsigned l= ong vdev_id, unsigned long return res.a0; } =20 +static inline unsigned long __rsi_rdev_get_measurements(unsigned long vdev= _id, + unsigned long inst_id, + phys_addr_t meas) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_GET_MEASUREMENTS, vdev_id, inst_id, mea= s, &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 f6aa647239c0..f051db54cdc3 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -202,6 +202,22 @@ struct rsi_host_call { =20 #define SMC_RSI_RDEV_GET_INTERFACE_REPORT SMC_RSI_FID(0x1a6) =20 +#define RSI_DEV_MEASURE_ALL BIT(0) +#define RSI_DEV_MEASURE_SIGNED BIT(1) +#define RSI_DEV_MEASURE_RAW BIT(2) + +struct rsi_device_measurements_params { + union { + struct { + u64 flags; + u8 indices[32]; + u8 nounce[32]; + }; + u8 padding[0x100]; + }; +}; + +#define SMC_RSI_RDEV_GET_MEASUREMENTS SMC_RSI_FID(0x1a7) #define SMC_RSI_RDEV_LOCK SMC_RSI_FID(0x1a9) #define SMC_RSI_RDEV_START SMC_RSI_FID(0x1aa) #define SMC_RSI_RDEV_STOP SMC_RSI_FID(0x1ab) diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 64034d220e02..6222b10964ee 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.c +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.c @@ -166,10 +166,31 @@ static long rhi_get_report(int vdev_id, int da_object= _type, void **report, int * return ret; } =20 +static inline unsigned long +rsi_rdev_get_measurements(struct pci_dev *pdev, unsigned long vdev_id, + unsigned long inst_id, phys_addr_t meas) +{ + unsigned long ret; + + ret =3D __rsi_rdev_get_measurements(vdev_id, inst_id, meas); + if (ret !=3D RSI_SUCCESS) + return ret; + + do { + ret =3D rsi_rdev_continue(vdev_id, inst_id); + } while (ret =3D=3D RSI_INCOMPLETE); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to communicate with the device (%lu)\n", ret); + return ret; + } + return RSI_SUCCESS; +} + int rsi_device_lock(struct pci_dev *pdev) { unsigned long ret; unsigned long tdisp_version; + struct rsi_device_measurements_params *rsi_dev_meas; struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); @@ -198,6 +219,17 @@ int rsi_device_lock(struct pci_dev *pdev) return -EOPNOTSUPP; } =20 + rsi_dev_meas =3D (struct rsi_device_measurements_params *)__get_free_page= (GFP_KERNEL); + rsi_dev_meas->flags =3D RSI_DEV_MEASURE_ALL; + ret =3D rsi_rdev_get_measurements(pdev, vdev_id, dsm->instance_id, + virt_to_phys(rsi_dev_meas)); + + free_page((unsigned long)rsi_dev_meas); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to get device measurement (%lu)\n", ret); + return -EIO; + } + /* Now make a host call to copy the interface report to guest. */ ret =3D rhi_get_report(vdev_id, RHI_DA_OBJECT_INTERFACE_REPORT, &dsm->interface_report, &dsm->interface_report_size); @@ -213,6 +245,13 @@ int rsi_device_lock(struct pci_dev *pdev) return -EIO; } =20 + ret =3D rhi_get_report(vdev_id, RHI_DA_OBJECT_MEASUREMENT, + &dsm->measurements, &dsm->measurements_size); + if (ret) { + pci_err(pdev, "failed to get device certificate from the host (%lu)\n", = ret); + return -EIO; + } + return ret; } static inline unsigned long rsi_rdev_start(struct pci_dev *pdev, diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index 71ee1edb832e..f26156d9be81 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -40,6 +40,8 @@ struct cca_guest_dsc { int interface_report_size; void *certificate; int certificate_size; + void *measurements; + int measurements_size; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) --=20 2.43.0 From nobody Sun Oct 5 23:40:18 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB79627465B; Mon, 28 Jul 2025 13:56:23 +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=1753710983; cv=none; b=aLxD9HTupQKYTO7uPajqVhtsONEX22yow1is/dnIqFQ5V9FTHP+Zu3dSu7EvljGlTG/Cei1WAP0otO1l3lmdiKxs5SkqKGNn3pI3gtu58hB1RptMJX0dw4Xm5XWlc/N6BomL8JI2odpEZAncBWPZ0nPV9Xy1TuKsVr80N3eRR3M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753710983; c=relaxed/simple; bh=zn8+WC3ldTbm6RNjuQz9vx5QH2UWKPQEGiie3mc/TX0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QAwCUOnW4/9/pPMLYAwkbil8VV6arSqswqmq6Z36SNOpd0vwTcd/BWDFeh6H1wtWEkB2XAl9+lRE7nuQGnttt4AATuO6bQZ8qRe4WPnkKkCjvI0LUJ592a9tx9MyXiIcd/gxCoULDPxNIuyQji967KC71hN8pxSPw6Ptsvm77dI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iwDn3PJK; 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="iwDn3PJK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 363ECC4CEE7; Mon, 28 Jul 2025 13:56:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1753710983; bh=zn8+WC3ldTbm6RNjuQz9vx5QH2UWKPQEGiie3mc/TX0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iwDn3PJKkGU3RyLVl3OxHfdMUwn2VTXCyKVJnN/2hUdDC+s0UE7n84uOsgnCL8we7 kVlyHvgckHYXkaTMT1bY5Jwx7yWqHNc/h6/g0RjNDl8mYOdYTTY6U7jQDkQPG2gpzE Rx076j8OEGtXyTyMq57DxranmZK0MvhRtZSdzo66K5s2r3e2/PHQ6KKvSZkZqYQLBr exsNZsiuLFig4kCbDo0KZf6nApqMGZ+NO+AEVLhV++10wGSMwp9+rz38dN2qM2vN0C +tzTcNyKO0XbctfM0ibZN7vGCvo254LJbJCsm08jMv2l5fJUl88PGu/WDqCDhGd2nD H4rOXAel8FThA== From: "Aneesh Kumar K.V (Arm)" To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, aik@amd.com, lukas@wunner.de, Samuel Ortiz , Xu Yilun , Jason Gunthorpe , Suzuki K Poulose , Steven Price , Catalin Marinas , Marc Zyngier , Will Deacon , Oliver Upton , "Aneesh Kumar K.V (Arm)" Subject: [RFC PATCH v1 38/38] coco: guest: arm64: Add support for fetching device info Date: Mon, 28 Jul 2025 19:22:15 +0530 Message-ID: <20250728135216.48084-39-aneesh.kumar@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250728135216.48084-1-aneesh.kumar@kernel.org> References: <20250728135216.48084-1-aneesh.kumar@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RSI_RDEV_GET_INFO returns different digest hash values, which can be compared with host cached values to ensure the host didn't tamper with the cached data. Signed-off-by: Aneesh Kumar K.V (Arm) --- arch/arm64/include/asm/rsi_cmds.h | 12 +++ arch/arm64/include/asm/rsi_smc.h | 24 +++++ drivers/virt/coco/arm-cca-guest/Kconfig | 2 + drivers/virt/coco/arm-cca-guest/rsi-da.c | 128 +++++++++++++++++++++++ drivers/virt/coco/arm-cca-guest/rsi-da.h | 13 +++ 5 files changed, 179 insertions(+) diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi= _cmds.h index 42b998f44a0e..6b90a6cdd7fb 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -276,4 +276,16 @@ static inline unsigned long __rsi_rdev_get_measurement= s(unsigned long vdev_id, return res.a0; } =20 +static inline unsigned long rsi_rdev_get_info(unsigned long vdev_id, + unsigned long inst_id, + unsigned long digest_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RSI_RDEV_GET_INFO, + vdev_id, inst_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 f051db54cdc3..e2b51cf58bd4 100644 --- a/arch/arm64/include/asm/rsi_smc.h +++ b/arch/arm64/include/asm/rsi_smc.h @@ -125,6 +125,9 @@ =20 #ifndef __ASSEMBLY__ =20 +#define RSI_HASH_SHA_256 0 +#define RSI_HASH_SHA_512 1 + struct realm_config { union { struct { @@ -200,6 +203,27 @@ struct rsi_host_call { #define SMC_RSI_RDEV_GET_INSTANCE_ID SMC_RSI_FID(0x19c) #define SMC_RSI_RDEV_CONTINUE SMC_RSI_FID(0x1a4) =20 +struct rsi_device_info { + union { + struct { + u64 flags; + u64 attest_type; + u64 cert_id; + u8 hash_algo; + }; + u8 padding[0x40]; + }; + union { /* 0x40 */ + struct { + u8 cert_digest[0x40]; + u8 meas_digest[0x40]; + u8 report_digest[0x40]; + }; + u8 padding2[0x200 - 0x40]; + }; +}; + +#define SMC_RSI_RDEV_GET_INFO SMC_RSI_FID(0x1a5) #define SMC_RSI_RDEV_GET_INTERFACE_REPORT SMC_RSI_FID(0x1a6) =20 #define RSI_DEV_MEASURE_ALL BIT(0) diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/ar= m-cca-guest/Kconfig index 410d9c3fb2b3..6fc86c1f3900 100644 --- a/drivers/virt/coco/arm-cca-guest/Kconfig +++ b/drivers/virt/coco/arm-cca-guest/Kconfig @@ -5,6 +5,8 @@ config ARM_CCA_GUEST tristate "Arm CCA Guest driver" depends on ARM64 depends on PCI_TSM + select CRYPTO_SHA256 + select CRYPTO_SHA512 select TSM_REPORTS select TSM help diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.c b/drivers/virt/coco/a= rm-cca-guest/rsi-da.c index 6222b10964ee..a1bb225adb4c 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" =20 @@ -186,11 +187,102 @@ rsi_rdev_get_measurements(struct pci_dev *pdev, unsi= gned long vdev_id, return RSI_SUCCESS; } =20 +static int verify_digests(struct cca_guest_dsc *dsm) +{ + int i; + int ret; + u8 digest[SHA512_DIGEST_SIZE]; + int sdesc_size; + size_t digest_size; + char *hash_alg_name; + struct shash_desc *shash; + struct crypto_shash *alg; + struct pci_dev *pdev =3D dsm->pci.tsm.pdev; + struct { + uint8_t *report; + size_t size; + uint8_t *digest; + } reports[] =3D { + { + dsm->interface_report, + dsm->interface_report_size, + dsm->dev_info.report_digest + }, + { + dsm->certificate, + dsm->certificate_size, + dsm->dev_info.cert_digest + }, + { + dsm->measurements, + dsm->measurements_size, + dsm->dev_info.meas_digest + } + }; + + + if (dsm->dev_info.hash_algo =3D=3D RSI_HASH_SHA_256) { + hash_alg_name =3D "sha256"; + digest_size =3D SHA256_DIGEST_SIZE; + } else if (dsm->dev_info.hash_algo =3D=3D RSI_HASH_SHA_512) { + hash_alg_name =3D "sha512"; + digest_size =3D SHA512_DIGEST_SIZE; + } else { + pci_err(pdev, "unknown realm hash algorithm!\n"); + ret =3D -EINVAL; + goto err_out; + } + + alg =3D crypto_alloc_shash(hash_alg_name, 0, 0); + if (IS_ERR(alg)) { + pci_err(pdev, "cannot allocate %s\n", hash_alg_name); + return PTR_ERR(alg); + } + + sdesc_size =3D sizeof(struct shash_desc) + crypto_shash_descsize(alg); + shash =3D kzalloc(sdesc_size, GFP_KERNEL); + if (!shash) { + pci_err(pdev, "cannot allocate sdesc\n"); + ret =3D -ENOMEM; + goto err_free_shash; + } + shash->tfm =3D alg; + + for (i =3D 0; i < ARRAY_SIZE(reports); i++) { + ret =3D crypto_shash_digest(shash, reports[i].report, + reports[i].size, digest); + if (ret) { + pci_err(pdev, "failed to compute digest, %d\n", ret); + goto err_free_sdesc; + } + + if (memcmp(reports[i].digest, digest, digest_size)) { + pci_err(pdev, "invalid digest\n"); + ret =3D -EINVAL; + goto err_free_sdesc; + } + } + + kfree(shash); + crypto_free_shash(alg); + + pci_info(pdev, "Successfully verified the digests\n"); + return 0; + +err_free_sdesc: + kfree(shash); +err_free_shash: + crypto_free_shash(alg); +err_out: + return ret; +} + int rsi_device_lock(struct pci_dev *pdev) { unsigned long ret; unsigned long tdisp_version; struct rsi_device_measurements_params *rsi_dev_meas; + struct rsi_device_info *dev_info; struct cca_guest_dsc *dsm =3D to_cca_guest_dsc(pdev); int vdev_id =3D (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); @@ -252,8 +344,44 @@ int rsi_device_lock(struct pci_dev *pdev) return -EIO; } =20 + /* RMM expects sizeof(dev_info) (512 bytes) aligned address */ + dev_info =3D kmalloc(sizeof(*dev_info), GFP_KERNEL); + if (!dev_info) { + ret =3D -ENOMEM; + goto err_out; + } + + ret =3D rsi_rdev_get_info(vdev_id, dsm->instance_id, virt_to_phys(dev_inf= o)); + if (ret !=3D RSI_SUCCESS) { + pci_err(pdev, "failed to get device digests (%lu)\n", ret); + ret =3D -EIO; + kfree(dev_info); + goto err_out; + } + + dsm->dev_info.attest_type =3D dev_info->attest_type; + dsm->dev_info.cert_id =3D dev_info->cert_id; + dsm->dev_info.hash_algo =3D dev_info->hash_algo; + memcpy(dsm->dev_info.cert_digest, dev_info->cert_digest, SHA512_DIGEST_SI= ZE); + memcpy(dsm->dev_info.meas_digest, dev_info->meas_digest, SHA512_DIGEST_SI= ZE); + memcpy(dsm->dev_info.report_digest, dev_info->report_digest, SHA512_DIGES= T_SIZE); + + kfree(dev_info); + /* + * Verify that the digests of the provided reports match with the + * digests from RMM + */ + ret =3D verify_digests(dsm); + if (ret) { + pci_err(pdev, "device digest validation failed (%ld)\n", ret); + return ret; + } + + return 0; +err_out: return ret; } + static inline unsigned long rsi_rdev_start(struct pci_dev *pdev, unsigned long vdev_id, unsigned long inst_id) { diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/a= rm-cca-guest/rsi-da.h index f26156d9be81..e8953b8e85a3 100644 --- a/drivers/virt/coco/arm-cca-guest/rsi-da.h +++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h @@ -10,6 +10,7 @@ #include #include #include +#include =20 struct pci_tdisp_device_interface_report { u16 interface_info; @@ -33,6 +34,17 @@ struct pci_tdisp_mmio_range { #define TSM_INTF_REPORT_MMIO_RESERVED GENMASK(15, 4) #define TSM_INTF_REPORT_MMIO_RANGE_ID GENMASK(31, 16) =20 +struct dsm_device_info { + u64 flags; + u64 attest_type; + u64 cert_id; + u64 hash_algo; + u8 cert_digest[SHA512_DIGEST_SIZE]; + u8 meas_digest[SHA512_DIGEST_SIZE]; + u8 report_digest[SHA512_DIGEST_SIZE]; +}; + + struct cca_guest_dsc { struct pci_tsm_pf0 pci; unsigned long instance_id; @@ -42,6 +54,7 @@ struct cca_guest_dsc { int certificate_size; void *measurements; int measurements_size; + struct dsm_device_info dev_info; }; =20 static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev) --=20 2.43.0