From nobody Thu Dec 18 16:18:12 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6C269239068 for ; Thu, 27 Feb 2025 14:42:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740667329; cv=none; b=OQGky9aaKp8rALK6I/4aK3or8CeQVgDDJH0/15e42Tk75UW+8A6NgGTaiwPoVirHex6b7x4pdSWVAxXzj8qIQHBIy9SPy59CGwE9tS1ZgFn9D+IWbzHtoPUXeqAI6k8qICnSAcj8xwZLt4KFHX0eB8KrLGbXVFIEX8wYkIm021E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740667329; c=relaxed/simple; bh=VMZ4G/Qk9feImgRx/uvQjb+L57UakZsvNsrD6JwcBws=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V6PzWUvY7NkYMshDkvU6JPCZIkJCfTM0nD6o7ZbBE6dA4+wuowjHmjCJm3pbOLSdViFSok+AFHNOZa5Ev5Sr3Nk/PCFh1HwqFrcG6VpZWqjSxHoPTs4mEbdp8AUmyujEgfK/WyOpjTb4rNK/dkIeE8rKgUNhhb52Q6SDTXbm1MQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5182D2BCC; Thu, 27 Feb 2025 06:42:22 -0800 (PST) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.1.197.1]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1E7753F673; Thu, 27 Feb 2025 06:42:05 -0800 (PST) From: Suzuki K Poulose To: linux-kernel@vger.kernel.org Cc: will@kernel.org, catalin.marinas@arm.com, maz@kernel.org, steven.price@arm.com, aneesh.kumar@kernel.org, gshan@redhat.com, robin.murphy@arm.com, linux-arm-kernel@lists.infradead.org, Suzuki K Poulose , Jean-Philippe Brucker , Christoph Hellwig , Marek Szyprowski , Tom Lendacky Subject: [PATCH v3 1/3] dma: Fix encryption bit clearing for dma_to_phys Date: Thu, 27 Feb 2025 14:41:48 +0000 Message-ID: <20250227144150.1667735-2-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250227144150.1667735-1-suzuki.poulose@arm.com> References: <20250227144150.1667735-1-suzuki.poulose@arm.com> 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" phys_to_dma() sets the encryption bit on the translated DMA address. But dma_to_phys() clears the encryption bit after it has been translated back to the physical address, which could fail if the device uses DMA ranges. AMD SME doesn't use the DMA ranges and thus this is harmless. But as we are about to add support for other architectures, let us fix this. Reported-by: Aneesh Kumar K.V Link: https://lkml.kernel.org/r/yq5amsen9stc.fsf@kernel.org Cc: Will Deacon Cc: Jean-Philippe Brucker Cc: Catalin Marinas Cc: Robin Murphy Cc: Steven Price Cc: Christoph Hellwig Cc: Marek Szyprowski Cc: Tom Lendacky Reviewed-by: Robin Murphy Acked-by: Tom Lendacky Signed-off-by: Suzuki K Poulose Acked-by: Marek Szyprowski Acked-by: Will Deacon Reviewed-by: Gavin Shan --- include/linux/dma-direct.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index d7e30d4f7503..d20ecc24cb0f 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h @@ -101,12 +101,13 @@ static inline phys_addr_t dma_to_phys(struct device *= dev, dma_addr_t dma_addr) { phys_addr_t paddr; =20 + dma_addr =3D __sme_clr(dma_addr); if (dev->dma_range_map) paddr =3D translate_dma_to_phys(dev, dma_addr); else paddr =3D dma_addr; =20 - return __sme_clr(paddr); + return paddr; } #endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */ =20 --=20 2.43.0 From nobody Thu Dec 18 16:18:12 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4DF5E23C8AA for ; Thu, 27 Feb 2025 14:42:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740667330; cv=none; b=gfFz5o//PRvEjHn4jYkdFYhkLXcF8ETd15O3Dqay86iZMadLW2gtp9HiVKUOp9Nk/UxcjklyDTBnN9KpluHTlzXfGAUYca3q1/lo5JRYHXgJTipmNy03a4lcZRwbXm2brI6xJ1FfrCYvTOJ7YLhzRSKfklP5sxknM47X8c856+Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740667330; c=relaxed/simple; bh=+tRGgKNs/lw69/8JOfyQngAEocgcBi+SMzNEREVm+ig=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=egwE/hqOzD+oyn9ByNxnyF6eSbv6PKtc5d6MrkHy+f0Oxn52Fu4wpczZbuBk8NVctfEdOV6ysWy3fCBxJhNtt8p1J+ZyvM1ohfO8drNwo24y1MBgKiQrq2Qg4nz/Qzrnd6wEpPXwpFXSiKipEjhY0+p9w4Vtgz3i+Xk/vBarKhk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3D21B2C3A; Thu, 27 Feb 2025 06:42:24 -0800 (PST) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.1.197.1]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 095A53F673; Thu, 27 Feb 2025 06:42:06 -0800 (PST) From: Suzuki K Poulose To: linux-kernel@vger.kernel.org Cc: will@kernel.org, catalin.marinas@arm.com, maz@kernel.org, steven.price@arm.com, aneesh.kumar@kernel.org, gshan@redhat.com, robin.murphy@arm.com, linux-arm-kernel@lists.infradead.org, Suzuki K Poulose , Jean-Philippe Brucker , Christoph Hellwig , Marek Szyprowski , Tom Lendacky Subject: [PATCH v3 2/3] dma: Introduce generic dma_addr_*crypted helpers Date: Thu, 27 Feb 2025 14:41:49 +0000 Message-ID: <20250227144150.1667735-3-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250227144150.1667735-1-suzuki.poulose@arm.com> References: <20250227144150.1667735-1-suzuki.poulose@arm.com> 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" AMD SME added __sme_set/__sme_clr primitives to modify the DMA address for encrypted/decrypted traffic. However this doesn't fit in with other models, e.g., Arm CCA where the meanings are the opposite. i.e., "decrypted" traffic has a bit set and "encrypted" traffic has the top bit cleared. In preparation for adding the support for Arm CCA DMA conversions, convert = the existing primitives to more generic ones that can be provided by the backen= ds. i.e., add helpers to 1. dma_addr_encrypted - Convert a DMA address to "encrypted" [ =3D=3D __sm= e_set() ] 2. dma_addr_unencrypted - Convert a DMA address to "decrypted" [ None exis= ts today ] 3. dma_addr_canonical - Clear any "encryption"/"decryption" bits from DMA address [ SME uses __sme_clr() ] and convert to a canonical DMA address. Since the original __sme_xxx helpers come from linux/mem_encrypt.h, use that as the home for the new definitions and provide dummy ones when none is pro= vided by the architectures. With the above, phys_to_dma_unencrypted() uses the newly added dma_addr_une= ncrypted() helper and to make it a bit more easier to read and avoid double conversion, provide __phys_to_dma(). Suggested-by: Robin Murphy Cc: Will Deacon Cc: Jean-Philippe Brucker Cc: Catalin Marinas Cc: Robin Murphy Cc: Steven Price Cc: Christoph Hellwig Cc: Marek Szyprowski Cc: Tom Lendacky Cc: Aneesh Kumar K.V Signed-off-by: Suzuki K Poulose Acked-by: Marek Szyprowski Acked-by: Will Deacon Reviewed-by: Gavin Shan Reviewed-by: Robin Murphy --- Changes since v2: - Rename helpers- s/dma_*crypted/dma_addr_*crypted (Robin) --- include/linux/dma-direct.h | 12 ++++++++---- include/linux/mem_encrypt.h | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index d20ecc24cb0f..f3bc0bcd7098 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h @@ -78,14 +78,18 @@ static inline dma_addr_t dma_range_map_max(const struct= bus_dma_region *map) #define phys_to_dma_unencrypted phys_to_dma #endif #else -static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev, - phys_addr_t paddr) +static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pad= dr) { if (dev->dma_range_map) return translate_phys_to_dma(dev, paddr); return paddr; } =20 +static inline dma_addr_t phys_to_dma_unencrypted(struct device *dev, + phys_addr_t paddr) +{ + return dma_addr_unencrypted(__phys_to_dma(dev, paddr)); +} /* * If memory encryption is supported, phys_to_dma will set the memory encr= yption * bit in the DMA address, and dma_to_phys will clear it. @@ -94,14 +98,14 @@ static inline dma_addr_t phys_to_dma_unencrypted(struct= device *dev, */ static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { - return __sme_set(phys_to_dma_unencrypted(dev, paddr)); + return dma_addr_encrypted(__phys_to_dma(dev, paddr)); } =20 static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_a= ddr) { phys_addr_t paddr; =20 - dma_addr =3D __sme_clr(dma_addr); + dma_addr =3D dma_addr_canonical(dma_addr); if (dev->dma_range_map) paddr =3D translate_dma_to_phys(dev, dma_addr); else diff --git a/include/linux/mem_encrypt.h b/include/linux/mem_encrypt.h index ae4526389261..07584c5e36fb 100644 --- a/include/linux/mem_encrypt.h +++ b/include/linux/mem_encrypt.h @@ -26,11 +26,34 @@ */ #define __sme_set(x) ((x) | sme_me_mask) #define __sme_clr(x) ((x) & ~sme_me_mask) + +#define dma_addr_encrypted(x) __sme_set(x) +#define dma_addr_canonical(x) __sme_clr(x) + #else #define __sme_set(x) (x) #define __sme_clr(x) (x) #endif =20 +/* + * dma_addr_encrypted() and dma_addr_unencrypted() are for converting a gi= ven DMA + * address to the respective type of addressing. + * + * dma_addr_canonical() is used to reverse any conversions for encrypted/d= ecrypted + * back to the canonical address. + */ +#ifndef dma_addr_encrypted +#define dma_addr_encrypted(x) (x) +#endif + +#ifndef dma_addr_unencrypted +#define dma_addr_unencrypted(x) (x) +#endif + +#ifndef dma_addr_canonical +#define dma_addr_canonical(x) (x) +#endif + #endif /* __ASSEMBLY__ */ =20 #endif /* __MEM_ENCRYPT_H__ */ --=20 2.43.0 From nobody Thu Dec 18 16:18:12 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 35FA123CEF0 for ; Thu, 27 Feb 2025 14:42:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740667332; cv=none; b=O075WmCzlm3dwAaya9LSg+UNbYArR4HR8h74mvAwx4jsCJWh46d/h1GZqvl4z/2Ef3cV8GEZSynCbXUgkmOa9dlFQV9B5Cj/Iy3GOaNP5xhbhqjo4ClgPpvdopPsi0LMWa1lPgI99PX80ZFWciG4nE/sM3GNkOZHcU9aiCWoBk8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740667332; c=relaxed/simple; bh=KGfjGgNglULtwKNBSYbC76MripoE1VrbD6UN9FeUQhg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tHCPR7nYb4jJ9CSan7WK8Dm90vs919zaQn/e9kiM3xzFw2nIjZAa+e27zubv8+HFETtaXwJa5Ze33P9cqV0SyrDfR7AGf5L3RzfP4S/l6ANI8mo/mvUnwMVER99pNXOPV9oExsAZ4jJR455T1BUhTJxBNVKX+28Mgb/Je+E/myI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 28A722C3D; Thu, 27 Feb 2025 06:42:26 -0800 (PST) Received: from ewhatever.cambridge.arm.com (ewhatever.cambridge.arm.com [10.1.197.1]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E88453F673; Thu, 27 Feb 2025 06:42:08 -0800 (PST) From: Suzuki K Poulose To: linux-kernel@vger.kernel.org Cc: will@kernel.org, catalin.marinas@arm.com, maz@kernel.org, steven.price@arm.com, aneesh.kumar@kernel.org, gshan@redhat.com, robin.murphy@arm.com, linux-arm-kernel@lists.infradead.org, Suzuki K Poulose , Jean-Philippe Brucker , Christoph Hellwig , Marek Szyprowski , Tom Lendacky Subject: [PATCH v3 3/3] arm64: realm: Use aliased addresses for device DMA to shared buffers Date: Thu, 27 Feb 2025 14:41:50 +0000 Message-ID: <20250227144150.1667735-4-suzuki.poulose@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250227144150.1667735-1-suzuki.poulose@arm.com> References: <20250227144150.1667735-1-suzuki.poulose@arm.com> 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" When a device performs DMA to a shared buffer using physical addresses, (without Stage1 translation), the device must use the "{I}PA address" with = the top bit set in Realm. This is to make sure that a trusted device will be ab= le to write to shared buffers as well as the protected buffers. Thus, a Realm = must always program the full address including the "protection" bit, like AMD SME encryption bits. Enable this by providing arm64 specific dma_addr_{encrypted, canonical} helpers for Realms. Please note that the VMM needs to similarly make sure t= hat the SMMU Stage2 in the Non-secure world is setup accordingly to map IPA at = the unprotected alias. Cc: Will Deacon Cc: Jean-Philippe Brucker Cc: Catalin Marinas Cc: Robin Murphy Cc: Steven Price Cc: Christoph Hellwig Cc: Marek Szyprowski Cc: Tom Lendacky Cc: Aneesh Kumar K.V Signed-off-by: Suzuki K Poulose Acked-by: Catalin Marinas Acked-by: Marek Szyprowski Acked-by: Will Deacon Reviewed-by: Gavin Shan Reviewed-by: Robin Murphy --- Changes since v2: - Drop dma_addr_encrypted() helper, which is a NOP for CCA ( Aneesh ) - Only mask the "top" IPA bit and not all the bits beyond top bit. ( Robin= ) - Use PROT_NS_SHARED, now that we only set/clear top bit. (Gavin) --- arch/arm64/include/asm/mem_encrypt.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/= mem_encrypt.h index f8f78f622dd2..a2a1eeb36d4b 100644 --- a/arch/arm64/include/asm/mem_encrypt.h +++ b/arch/arm64/include/asm/mem_encrypt.h @@ -21,4 +21,15 @@ static inline bool force_dma_unencrypted(struct device *= dev) return is_realm_world(); } =20 +/* + * For Arm CCA guests, canonical addresses are "encrypted", so no changes + * required for dma_addr_encrypted(). + * The unencrypted DMA buffers must be accessed via the unprotected IPA, + * "top IPA bit" set. + */ +#define dma_addr_unencrypted(x) ((x) | PROT_NS_SHARED) + +/* Clear the "top" IPA bit while converting back */ +#define dma_addr_canonical(x) ((x) & ~PROT_NS_SHARED) + #endif /* __ASM_MEM_ENCRYPT_H */ --=20 2.43.0