Linux-HyperV List
 help / color / mirror / Atom feed
* [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
@ 2026-08-03  3:35 Tianyu Lan
  2026-08-03  3:53 ` sashiko-bot
  2026-08-03  9:04 ` Aneesh Kumar K.V
  0 siblings, 2 replies; 8+ messages in thread
From: Tianyu Lan @ 2026-08-03  3:35 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli
  Cc: Tianyu Lan, linux-hyperv, linux-kernel, aik, hch, robin.murphy,
	vdso, aneesh.kumar, mhklinux

In CoCo VMs, system memory is encrypted by default.
Device drivers typically rely on the DMA core's
SWIOTLB as a bounce buffer for DMA operations, providing
decrypted memory that can be shared between the guest and
host.

For PCI devices with T-Disp support and Confidential
VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
perform DMA transfers directly with private/encrypted
memory in a CoCo VM.

To support DMA transfer with encrypted memory, Hyper-V
DMA ops are introduced and bypass some API which may
use swiotlb as bounce buffer.

The DMA ops used is global data structure(see get_arch_
dma_ops() and get_dma_ops() for details). There is no
need to set up for each device individually.

Signed-off-by: Tianyu Lan <tiala@microsoft.com>
---
 drivers/hv/Kconfig      |   5 ++
 drivers/hv/Makefile     |   1 +
 drivers/hv/hv_dma_ops.c | 140 ++++++++++++++++++++++++++++++++++++++++
 drivers/hv/vmbus_drv.c  |  14 +++-
 4 files changed, 159 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hv/hv_dma_ops.c

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 2d0b3fcb0ff8..4b50a631fd57 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -7,6 +7,7 @@ config HYPERV
 	depends on (X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
 		|| (ARM64 && !CPU_BIG_ENDIAN)
 	select PARAVIRT
+	select HYPERV_DMA_OPS
 	select X86_HV_CALLBACK_VECTOR if X86
 	select OF_EARLY_FLATTREE if OF
 	select IRQ_MSI_LIB if X86
@@ -14,6 +15,10 @@ config HYPERV
 	  Select this option to run Linux as a Hyper-V client operating
 	  system.
 
+config HYPERV_DMA_OPS
+	bool "Enable Microsoft Hyper-V DMA ops support"
+	depends on ARCH_HAS_DMA_OPS
+
 config HYPERV_VTL_MODE
 	bool "Enable Linux to boot in VTL context"
 	depends on (X86_64 && HAVE_STATIC_CALL) || ARM64
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index 888a748cc7cb..b4d23c88b9eb 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_HYPERV_VMBUS)	+= hv_vmbus.o
 obj-$(CONFIG_HYPERV_UTILS)	+= hv_utils.o
 obj-$(CONFIG_HYPERV_BALLOON)	+= hv_balloon.o
+obj-$(CONFIG_HYPERV_DMA_OPS)	+= hv_dma_ops.o
 obj-$(CONFIG_MSHV_ROOT)		+= mshv_root.o
 obj-$(CONFIG_MSHV_VTL)          += mshv_vtl.o
 
diff --git a/drivers/hv/hv_dma_ops.c b/drivers/hv/hv_dma_ops.c
new file mode 100644
index 000000000000..ef53a42c0450
--- /dev/null
+++ b/drivers/hv/hv_dma_ops.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026, Microsoft Corporation.
+ *
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/hyperv.h>
+#include <linux/smpboot.h>
+
+#include <linux/kernel.h>
+#include <linux/dma-map-ops.h>
+#include <linux/export.h>
+#include <asm/mshyperv.h>
+#include "hyperv_vmbus.h"
+#include "../../kernel/dma/direct.h"
+
+extern const struct dma_map_ops *dma_ops;
+
+extern bool is_vmbus_dev(struct device *dev);
+
+static bool hyperv_private_memory_dma(struct device *dev)
+{
+	struct hv_device *hv_dev = device_to_hv_device(dev);
+
+	if (is_vmbus_dev(dev) && hv_dev && hv_dev->channel
+	    && hv_dev->channel->co_external_memory)
+		return true;
+
+	/* Todo: Check T-Disp capability of PCI device here */
+
+	return false;
+}
+
+static int hyperv_dma_map_sg(struct device *dev, struct scatterlist *sgl,
+		int nelems, enum dma_data_direction dir,
+		unsigned long attrs)
+{
+	struct scatterlist *sg;
+	dma_addr_t dma_addr;
+	int i;
+
+	if (hyperv_private_memory_dma(dev)) {
+		for_each_sg(sgl, sg, nelems, i) {
+			dma_addr = __phys_to_dma(dev, sg_phys(sg));
+			sg_dma_address(sg) = dma_addr;
+			sg_dma_len(sg) = sg->length;
+		}
+
+		return nelems;
+	} else {
+		return dma_direct_map_sg(dev, sgl, nelems, dir, attrs);
+	}
+}
+
+static void hyperv_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
+		int nelems, enum dma_data_direction dir, unsigned long attrs)
+{
+	if (!hyperv_private_memory_dma(dev))
+		dma_direct_unmap_sg(dev, sgl, nelems, dir, attrs);
+}
+
+static int hyperv_dma_supported(struct device *dev, u64 mask)
+{
+	dev->coherent_dma_mask = mask;
+	return 1;
+}
+
+static size_t hyperv_dma_max_mapping_size(struct device *dev)
+{
+	if (hyperv_private_memory_dma(dev))
+		return SIZE_MAX;
+	else
+		return swiotlb_max_mapping_size(dev);
+}
+
+/* allocate and map a coherent mapping */
+static void *
+hyperv_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		    gfp_t flag, unsigned long attrs)
+{
+	phys_addr_t phys;
+	void *ret;
+
+	if (!hyperv_private_memory_dma(dev))
+		return dma_alloc_coherent(dev, size, dma_handle, flag);
+
+	size = ALIGN(size, PAGE_SIZE);
+	ret = (void *)__get_free_pages(flag, get_order(size));
+	if (!ret)
+		return ret;
+	phys = virt_to_phys(ret);
+
+	if (hyperv_private_memory_dma(dev))
+		*dma_handle = dma_addr_encrypted(__phys_to_dma(dev, phys));
+	else
+		*dma_handle = phys_to_dma_unencrypted(dev, phys);
+
+	memset(ret, 0, size);
+	return ret;
+}
+
+/* free a coherent mapping */
+static void
+hyperv_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+		   dma_addr_t dma_addr, unsigned long attrs)
+{
+	if (hyperv_private_memory_dma(dev))
+		dmam_free_coherent(dev, size, vaddr, dma_addr);
+	else
+		free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static dma_addr_t hyperv_dma_map_phys(struct device *dev, phys_addr_t phys,
+		size_t size, enum dma_data_direction dir,
+		unsigned long attrs)
+{
+	if (hyperv_private_memory_dma(dev))
+		return __phys_to_dma(dev, phys);
+	else
+		return dma_direct_map_phys(dev, phys, size, dir, attrs, true);
+}
+
+static void hyperv_dma_unmap_phys(struct device *dev, dma_addr_t dma_handle,
+		size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+	if (!hyperv_private_memory_dma(dev))
+		dma_direct_unmap_phys(dev, dma_handle, size, dir, attrs, true);
+}
+
+const struct dma_map_ops hyperv_dma_ops = {
+	.alloc			= hyperv_dma_alloc_coherent,
+	.free			= hyperv_dma_free_coherent,
+	.map_phys               = hyperv_dma_map_phys,
+	.unmap_phys             = hyperv_dma_unmap_phys,
+	.map_sg                 = hyperv_dma_map_sg,
+	.unmap_sg               = hyperv_dma_unmap_sg,
+	.dma_supported          = hyperv_dma_supported,
+	.max_mapping_size	= hyperv_dma_max_mapping_size,
+};
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index d28ff45d4cfd..d1ce5c107993 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -40,6 +40,10 @@
 #include <clocksource/hyperv_timer.h>
 #include <asm/mshyperv.h>
 #include "hyperv_vmbus.h"
+#include "../../kernel/dma/direct.h"
+
+extern const struct dma_map_ops *dma_ops;
+extern const struct dma_map_ops hyperv_dma_ops;
 
 struct vmbus_dynid {
 	struct list_head node;
@@ -1468,6 +1472,11 @@ static int vmbus_alloc_synic_and_connect(void)
 	return -ENOMEM;
 }
 
+bool is_vmbus_dev(struct device *dev)
+{
+	return dev->bus == &hv_bus;
+}
+
 /*
  * vmbus_bus_init -Main vmbus driver initialization routine.
  *
@@ -1523,8 +1532,11 @@ static int vmbus_bus_init(void)
 	 * doing that on each VP while initializing SynIC's wastes time.
 	 */
 	is_confidential = ms_hyperv.confidential_vmbus_available;
-	if (is_confidential)
+	if (is_confidential) {
+		dma_ops = &hyperv_dma_ops;
 		pr_info("Establishing connection to the confidential VMBus\n");
+	}
+
 	hv_para_set_sint_proxy(!is_confidential);
 	ret = vmbus_alloc_synic_and_connect();
 	if (ret)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-03  3:35 [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM Tianyu Lan
@ 2026-08-03  3:53 ` sashiko-bot
  2026-08-03  9:04 ` Aneesh Kumar K.V
  1 sibling, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-03  3:53 UTC (permalink / raw)
  To: Tianyu Lan; +Cc: linux-hyperv

Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:
- [Critical] The fallback paths in the allocation and deallocation functions recursively call the high-level DMA API, causing infinite loops.
- [Critical] The custom DMA allocator ignores the device's coherent DMA mask, allocating memory above the hardware's addressing limits.
- [Critical] Streaming DMA mappings do not apply the mandatory memory encryption bit to physical addresses.
- [Critical] Bypass of architectural DMA cache synchronization in streaming mappings causes data corruption on non-coherent systems.
- [High] Globally overriding the `dma_ops` pointer breaks DMA for all non-VMBus devices on the system, and fails to restore the state on initialization errors.
- [High] The deallocation logic completely mismatches the allocation APIs, causing memory leaks, WARN_ONs, and skipped DMA unmapping.
- [Medium] The `dma_supported` map op callback incorrectly modifies device state instead of performing a read-only query.
- [Low] Referencing the global `dma_ops` pointer causes an undefined symbol linker error on ARM64.
- [Low] The `else` branch managing unencrypted memory mappings in `hyperv_dma_alloc_coherent` is unreachable.
--

--- Patch [1]: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM ---
commit 7e352d385400a7e2fcde56e56c2991270a9e565d
Author: Tianyu Lan <ltykernel@gmail.com>
Subject: x86/VMBus: DMA transfer with encrypted memory in Coco VM

This commit introduces Hyper-V DMA ops to support DMA transfers directly with
private/encrypted memory in CoCo VMs. It bypasses SWIOTLB bounce buffers for
certain PCI and Confidential VMBus devices.

> diff --git a/drivers/hv/hv_dma_ops.c b/drivers/hv/hv_dma_ops.c
> new file mode 100644
> index 0000000000000..ef53a42c0450b
> --- /dev/null
> +++ b/drivers/hv/hv_dma_ops.c
> @@ -0,0 +1,140 @@
[ ... ]
> +#include <asm/mshyperv.h>
> +#include "hyperv_vmbus.h"
> +#include "../../kernel/dma/direct.h"
> +
> +extern const struct dma_map_ops *dma_ops;

[Severity: Low]
Is this extern declaration safe on ARM64?

The CONFIG_HYPERV option supports ARM64, but the global dma_ops variable is
only exported on certain architectures like x86. On ARM64, this does not exist,
which could result in an undefined symbol linker error.

[ ... ]
> +static int hyperv_dma_map_sg(struct device *dev, struct scatterlist *sgl,
> +		int nelems, enum dma_data_direction dir,
> +		unsigned long attrs)
> +{
> +	struct scatterlist *sg;
> +	dma_addr_t dma_addr;
> +	int i;
> +
> +	if (hyperv_private_memory_dma(dev)) {
> +		for_each_sg(sgl, sg, nelems, i) {
> +			dma_addr = __phys_to_dma(dev, sg_phys(sg));
> +			sg_dma_address(sg) = dma_addr;

[Severity: Critical]
Does this mapping miss the mandatory memory encryption bit?

For private memory transfers in CoCo VMs, physical addresses must be mapped
with a specific encryption bit. Returning the unencrypted physical address
here could cause the hardware to access the memory as shared or decrypted.

[Severity: Critical]
Is it safe to skip cache synchronization here?

By returning early after translation without calling generic wrappers, and
lacking .sync_single_for_cpu and .sync_single_for_device callbacks in the
hyperv_dma_ops structure, this bypasses architectural DMA cache flushing. On
architectures that are not hardware cache-coherent, this could lead to data
corruption.

> +			sg_dma_len(sg) = sg->length;
> +		}
> +
> +		return nelems;
> +	} else {
> +		return dma_direct_map_sg(dev, sgl, nelems, dir, attrs);
> +	}
> +}
[ ... ]
> +static int hyperv_dma_supported(struct device *dev, u64 mask)
> +{
> +	dev->coherent_dma_mask = mask;

[Severity: Medium]
Should a dma_supported callback modify the device state?

The ops->dma_supported callback is strictly a read-only query evaluated by
functions like dma_supported(). Assigning dev->coherent_dma_mask here silently
alters the device state when the driver only intends to query supported
capabilities.

> +	return 1;
> +}
[ ... ]
> +/* allocate and map a coherent mapping */
> +static void *
> +hyperv_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
> +		    gfp_t flag, unsigned long attrs)
> +{
> +	phys_addr_t phys;
> +	void *ret;
> +
> +	if (!hyperv_private_memory_dma(dev))
> +		return dma_alloc_coherent(dev, size, dma_handle, flag);

[Severity: Critical]
Can this fallback path cause an infinite recursion?

If hyperv_private_memory_dma() is false, this calls dma_alloc_coherent().
The core API looks up the device's DMA ops via get_dma_ops(), which now returns
hyperv_dma_ops due to the global override. This would recursively call back into
hyperv_dma_alloc_coherent(), leading to a stack overflow.

> +
> +	size = ALIGN(size, PAGE_SIZE);
> +	ret = (void *)__get_free_pages(flag, get_order(size));

[Severity: Critical]
Could this allocation bypass the device's DMA boundary constraints?

The core DMA API strips memory placement zone flags (like __GFP_DMA32) before
calling ops->alloc, expecting the implementation to allocate from the correct
zone based on dev->coherent_dma_mask. Blindly allocating via __get_free_pages()
here could result in allocating memory above the hardware's addressing limits
for devices with constrained DMA masks.

> +	if (!ret)
> +		return ret;
> +	phys = virt_to_phys(ret);
> +
> +	if (hyperv_private_memory_dma(dev))
> +		*dma_handle = dma_addr_encrypted(__phys_to_dma(dev, phys));
> +	else
> +		*dma_handle = phys_to_dma_unencrypted(dev, phys);

[Severity: Low]
Is this else branch reachable?

The function returns early at the top if hyperv_private_memory_dma(dev) is
false. By the time execution reaches this block, the condition is guaranteed
to be true, making this else branch dead code.

> +
> +	memset(ret, 0, size);
> +	return ret;
> +}
> +
> +/* free a coherent mapping */
> +static void
> +hyperv_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
> +		   dma_addr_t dma_addr, unsigned long attrs)
> +{
> +	if (hyperv_private_memory_dma(dev))
> +		dmam_free_coherent(dev, size, vaddr, dma_addr);

[Severity: Critical]
Can the dmam_free_coherent() call result in infinite recursion?

Since the memory was not allocated via devres, dmam_free_coherent() will fall
back to dma_free_coherent(). This looks up ops->free and infinitely recurses
back into hyperv_dma_free_coherent().

> +	else
> +		free_pages((unsigned long)vaddr, get_order(size));

[Severity: High]
Are the allocation and deallocation APIs correctly paired here?

The branches appear to use inverted APIs. For private memory, it is allocated
via __get_free_pages() but freed using the devres-managed dmam_free_coherent(),
which could fail to find a devres entry.

For non-private memory, it is allocated via dma_alloc_coherent() but
incorrectly freed using free_pages(). Bypassing the DMA API on free skips
SWIOTLB bounce buffer cleanup and IOMMU unmapping, potentially causing resource
leaks.

> +}
> +
> +static dma_addr_t hyperv_dma_map_phys(struct device *dev, phys_addr_t phys,
> +		size_t size, enum dma_data_direction dir,
> +		unsigned long attrs)
> +{
> +	if (hyperv_private_memory_dma(dev))
> +		return __phys_to_dma(dev, phys);

[Severity: Critical]
Does this mapping miss the memory encryption bit?

Similar to hyperv_dma_map_sg, returning the unencrypted physical address for
private memory transfers could cause the hardware to access the memory as shared
or decrypted.

[Severity: Critical]
Is it safe to bypass generic cache synchronization wrappers here?

As with hyperv_dma_map_sg, missing the cache flushing could cause data
corruption on non-coherent architectures.

> +	else
> +		return dma_direct_map_phys(dev, phys, size, dir, attrs, true);
> +}
[ ... ]
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index 6824bd7cb3c4f..3479528d3b963 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -40,6 +40,10 @@
>  #include <clocksource/hyperv_timer.h>
>  #include <asm/mshyperv.h>
>  #include "hyperv_vmbus.h"
> +#include "../../kernel/dma/direct.h"
> +
> +extern const struct dma_map_ops *dma_ops;

[Severity: Low]
Would this extern declaration cause build issues on ARM64?

The global dma_ops pointer does not exist on ARM64, which may result in a linker
error on architectures that do not export it.

[ ... ]
> @@ -1518,8 +1527,11 @@ static int vmbus_bus_init(void)
>  	 * doing that on each VP while initializing SynIC's wastes time.
>  	 */
>  	is_confidential = ms_hyperv.confidential_vmbus_available;
> -	if (is_confidential)
> +	if (is_confidential) {
> +		dma_ops = &hyperv_dma_ops;

[Severity: High]
Could overriding the global dma_ops pointer affect other devices?

Setting the system-wide dma_ops pointer forces all standard non-VMBus devices
to use these Hyper-V DMA ops. Additionally, if vmbus_alloc_synic_and_connect()
fails later, this global pointer is left hijacked on the error path, which could
lead to system failures for non-VMBus devices.

>  		pr_info("Establishing connection to the confidential VMBus\n");
> +	}
> +
>  	hv_para_set_sint_proxy(!is_confidential);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260803033520.12930-1-tiala@microsoft.com?part=1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-03  3:35 [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM Tianyu Lan
  2026-08-03  3:53 ` sashiko-bot
@ 2026-08-03  9:04 ` Aneesh Kumar K.V
  2026-08-04  9:22   ` Tianyu Lan
  1 sibling, 1 reply; 8+ messages in thread
From: Aneesh Kumar K.V @ 2026-08-03  9:04 UTC (permalink / raw)
  To: Tianyu Lan, kys, haiyangz, wei.liu, decui, longli
  Cc: Tianyu Lan, linux-hyperv, linux-kernel, aik, hch, robin.murphy,
	vdso, mhklinux

Tianyu Lan <ltykernel@gmail.com> writes:

> In CoCo VMs, system memory is encrypted by default.
> Device drivers typically rely on the DMA core's
> SWIOTLB as a bounce buffer for DMA operations, providing
> decrypted memory that can be shared between the guest and
> host.
>
> For PCI devices with T-Disp support and Confidential
> VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
> perform DMA transfers directly with private/encrypted
> memory in a CoCo VM.
>
> To support DMA transfer with encrypted memory, Hyper-V
> DMA ops are introduced and bypass some API which may
> use swiotlb as bounce buffer.
>
> The DMA ops used is global data structure(see get_arch_
> dma_ops() and get_dma_ops() for details). There is no
> need to set up for each device individually.
>

Can we use __DMA_ATTR_ALLOC_CC_SHARED instead of checking
hyperv_private_memory_dma(dev) directly? Also, would it be possible to
encapsulate this logic in something like force_dma_encrypted(dev)?

Looking at functions such as hyperv_dma_alloc_coherent(), how does this
differ from dma_direct_alloc()? 

-aneesh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-03  9:04 ` Aneesh Kumar K.V
@ 2026-08-04  9:22   ` Tianyu Lan
  2026-08-05 10:11     ` Aneesh Kumar K.V
  0 siblings, 1 reply; 8+ messages in thread
From: Tianyu Lan @ 2026-08-04  9:22 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: kys, haiyangz, wei.liu, decui, longli, Tianyu Lan, linux-hyperv,
	linux-kernel, aik, hch, robin.murphy, vdso, mhklinux

On Mon, Aug 3, 2026 at 5:04 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>
> Tianyu Lan <ltykernel@gmail.com> writes:
>
> > In CoCo VMs, system memory is encrypted by default.
> > Device drivers typically rely on the DMA core's
> > SWIOTLB as a bounce buffer for DMA operations, providing
> > decrypted memory that can be shared between the guest and
> > host.
> >
> > For PCI devices with T-Disp support and Confidential
> > VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
> > perform DMA transfers directly with private/encrypted
> > memory in a CoCo VM.
> >
> > To support DMA transfer with encrypted memory, Hyper-V
> > DMA ops are introduced and bypass some API which may
> > use swiotlb as bounce buffer.
> >
> > The DMA ops used is global data structure(see get_arch_
> > dma_ops() and get_dma_ops() for details). There is no
> > need to set up for each device individually.
> >
>
> Can we use __DMA_ATTR_ALLOC_CC_SHARED instead of checking
> hyperv_private_memory_dma(dev) directly? Also, would it be possible to
> encapsulate this logic in something like force_dma_encrypted(dev)?
>

Hi Aneesh:
      Thanks for your review. I go through your patchset “dma-mapping: Use
DMA_ATTR_CC_SHARED”(https://lkml.org/lkml/2026/6/4/588). This patch
is compatible with your DMA_ATTR_CC_SHARED attr work in dma-mapping
layer. Once dma ops callbacks get DMA_ATTR_CC_SHARED attr flag and
it may use the flag to replace hyperv_private_memory_dma().

> Looking at functions such as hyperv_dma_alloc_coherent(), how does this
> differ from dma_direct_alloc()?
>
hyperv_dma_alloc_coherent() is to allocate memory and returns encrypted
memory address directly when hyperv_private_memory_dma() is ture.
This change is to keep all changes under Hyper-V subsystem and it's
also compatible with existing solution which changes DMA core with minor
changes.
--
Thanks


Tianyu Lan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-04  9:22   ` Tianyu Lan
@ 2026-08-05 10:11     ` Aneesh Kumar K.V
  2026-08-06 14:21       ` Tianyu Lan
  0 siblings, 1 reply; 8+ messages in thread
From: Aneesh Kumar K.V @ 2026-08-05 10:11 UTC (permalink / raw)
  To: Tianyu Lan
  Cc: kys, haiyangz, wei.liu, decui, longli, Tianyu Lan, linux-hyperv,
	linux-kernel, aik, hch, robin.murphy, vdso, mhklinux

Tianyu Lan <ltykernel@gmail.com> writes:

> On Mon, Aug 3, 2026 at 5:04 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>>
>> Tianyu Lan <ltykernel@gmail.com> writes:
>>
>> > In CoCo VMs, system memory is encrypted by default.
>> > Device drivers typically rely on the DMA core's
>> > SWIOTLB as a bounce buffer for DMA operations, providing
>> > decrypted memory that can be shared between the guest and
>> > host.
>> >
>> > For PCI devices with T-Disp support and Confidential
>> > VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
>> > perform DMA transfers directly with private/encrypted
>> > memory in a CoCo VM.
>> >
>> > To support DMA transfer with encrypted memory, Hyper-V
>> > DMA ops are introduced and bypass some API which may
>> > use swiotlb as bounce buffer.
>> >
>> > The DMA ops used is global data structure(see get_arch_
>> > dma_ops() and get_dma_ops() for details). There is no
>> > need to set up for each device individually.
>> >
>>
>> Can we use __DMA_ATTR_ALLOC_CC_SHARED instead of checking
>> hyperv_private_memory_dma(dev) directly? Also, would it be possible to
>> encapsulate this logic in something like force_dma_encrypted(dev)?
>>
>
> Hi Aneesh:
>       Thanks for your review. I go through your patchset “dma-mapping: Use
> DMA_ATTR_CC_SHARED”(https://lkml.org/lkml/2026/6/4/588). This patch
> is compatible with your DMA_ATTR_CC_SHARED attr work in dma-mapping
> layer. Once dma ops callbacks get DMA_ATTR_CC_SHARED attr flag and
> it may use the flag to replace hyperv_private_memory_dma().
>

Can we rework this patch to use that? 

>
>> Looking at functions such as hyperv_dma_alloc_coherent(), how does this
>> differ from dma_direct_alloc()?
>>
> hyperv_dma_alloc_coherent() is to allocate memory and returns encrypted
> memory address directly when hyperv_private_memory_dma() is ture.
> This change is to keep all changes under Hyper-V subsystem and it's
> also compatible with existing solution which changes DMA core with minor
> changes.


If we update force_dma_unencrypted(dev) to return false when an
encrypted memory address is required, wouldn't the existing DMA-direct
support handle this case? Or are there issues with the existing code? If
so, could you explain them in more detail?

-aneesh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-05 10:11     ` Aneesh Kumar K.V
@ 2026-08-06 14:21       ` Tianyu Lan
  2026-08-06 15:14         ` Robin Murphy
  0 siblings, 1 reply; 8+ messages in thread
From: Tianyu Lan @ 2026-08-06 14:21 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: kys, haiyangz, wei.liu, decui, longli, Tianyu Lan, linux-hyperv,
	linux-kernel, aik, hch, robin.murphy, vdso, mhklinux

On Wed, Aug 5, 2026 at 6:11 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>
> Tianyu Lan <ltykernel@gmail.com> writes:
>
> > On Mon, Aug 3, 2026 at 5:04 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
> >>
> >> Tianyu Lan <ltykernel@gmail.com> writes:
> >>
> >> > In CoCo VMs, system memory is encrypted by default.
> >> > Device drivers typically rely on the DMA core's
> >> > SWIOTLB as a bounce buffer for DMA operations, providing
> >> > decrypted memory that can be shared between the guest and
> >> > host.
> >> >
> >> > For PCI devices with T-Disp support and Confidential
> >> > VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
> >> > perform DMA transfers directly with private/encrypted
> >> > memory in a CoCo VM.
> >> >
> >> > To support DMA transfer with encrypted memory, Hyper-V
> >> > DMA ops are introduced and bypass some API which may
> >> > use swiotlb as bounce buffer.
> >> >
> >> > The DMA ops used is global data structure(see get_arch_
> >> > dma_ops() and get_dma_ops() for details). There is no
> >> > need to set up for each device individually.
> >> >
> >>
> >> Can we use __DMA_ATTR_ALLOC_CC_SHARED instead of checking
> >> hyperv_private_memory_dma(dev) directly? Also, would it be possible to
> >> encapsulate this logic in something like force_dma_encrypted(dev)?
> >>
> >
> > Hi Aneesh:
> >       Thanks for your review. I go through your patchset “dma-mapping: Use
> > DMA_ATTR_CC_SHARED”(https://lkml.org/lkml/2026/6/4/588). This patch
> > is compatible with your DMA_ATTR_CC_SHARED attr work in dma-mapping
> > layer. Once dma ops callbacks get DMA_ATTR_CC_SHARED attr flag and
> > it may use the flag to replace hyperv_private_memory_dma().
> >
> >
> >> Looking at functions such as hyperv_dma_alloc_coherent(), how does this
> >> differ from dma_direct_alloc()?
> >>
> > hyperv_dma_alloc_coherent() is to allocate memory and returns encrypted
> > memory address directly when hyperv_private_memory_dma() is ture.
> > This change is to keep all changes under Hyper-V subsystem and it's
> > also compatible with existing solution which changes DMA core with minor
> > changes.
>
>
> If we update force_dma_unencrypted(dev) to return false when an
> encrypted memory address is required, wouldn't the existing DMA-direct
> support handle this case? Or are there issues with the existing code? If
> so, could you explain them in more detail?
>

Hyper-V Coco VM with T-disp scenario is to run a paravior(lightweight L1
hypervisor) with normal guest (Detail please see 13.2. OpenHCL Architecture
https://openvmmdev/guide/user_guide/openhcl.html). The paravisor is in charge
of talking with hardware to accept PCI devices for Normal guest.

When PCI device is assigned to normal guest, __device_cc_accepted() should
always return true for this device.  Then, DMA core will not use
bounce buffer and
unencrypted memory address for the device.

However, __device_cc_accepted() is based on TSM framework and Hyper-V
doesn't support it. This means normal guest will not use TSM guest driver
and so current code doesn't work. It's necessary to introduce an API for
platforms without TSM support to mask the PCI device to be "accepted".

>
> Can we rework this patch to use that(DMA_ATTR_CC_SHARED )?
>

I think the change is simple. The issue here is how to set the attr flag for
platforms without TSM support. This patch is to make Hyper-V T-Disp case
work without changing DMA core and PCI layer.

In parallel, we may co-work to add non-TSM platform support in your DMA
CC SHARED patchset and "PCI/TSM: Core infrastructure" patchset.

--
Thanks
Tianyu Lan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-06 14:21       ` Tianyu Lan
@ 2026-08-06 15:14         ` Robin Murphy
  2026-08-07 14:32           ` Tianyu Lan
  0 siblings, 1 reply; 8+ messages in thread
From: Robin Murphy @ 2026-08-06 15:14 UTC (permalink / raw)
  To: Tianyu Lan, Aneesh Kumar K.V
  Cc: kys, haiyangz, wei.liu, decui, longli, Tianyu Lan, linux-hyperv,
	linux-kernel, aik, hch, vdso, mhklinux

On 2026-08-06 3:21 pm, Tianyu Lan wrote:
> On Wed, Aug 5, 2026 at 6:11 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>>
>> Tianyu Lan <ltykernel@gmail.com> writes:
>>
>>> On Mon, Aug 3, 2026 at 5:04 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>>>>
>>>> Tianyu Lan <ltykernel@gmail.com> writes:
>>>>
>>>>> In CoCo VMs, system memory is encrypted by default.
>>>>> Device drivers typically rely on the DMA core's
>>>>> SWIOTLB as a bounce buffer for DMA operations, providing
>>>>> decrypted memory that can be shared between the guest and
>>>>> host.
>>>>>
>>>>> For PCI devices with T-Disp support and Confidential
>>>>> VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
>>>>> perform DMA transfers directly with private/encrypted
>>>>> memory in a CoCo VM.
>>>>>
>>>>> To support DMA transfer with encrypted memory, Hyper-V
>>>>> DMA ops are introduced and bypass some API which may
>>>>> use swiotlb as bounce buffer.
>>>>>
>>>>> The DMA ops used is global data structure(see get_arch_
>>>>> dma_ops() and get_dma_ops() for details). There is no
>>>>> need to set up for each device individually.
>>>>>
>>>>
>>>> Can we use __DMA_ATTR_ALLOC_CC_SHARED instead of checking
>>>> hyperv_private_memory_dma(dev) directly? Also, would it be possible to
>>>> encapsulate this logic in something like force_dma_encrypted(dev)?
>>>>
>>>
>>> Hi Aneesh:
>>>        Thanks for your review. I go through your patchset “dma-mapping: Use
>>> DMA_ATTR_CC_SHARED”(https://lkml.org/lkml/2026/6/4/588). This patch
>>> is compatible with your DMA_ATTR_CC_SHARED attr work in dma-mapping
>>> layer. Once dma ops callbacks get DMA_ATTR_CC_SHARED attr flag and
>>> it may use the flag to replace hyperv_private_memory_dma().
>>>
>>>
>>>> Looking at functions such as hyperv_dma_alloc_coherent(), how does this
>>>> differ from dma_direct_alloc()?
>>>>
>>> hyperv_dma_alloc_coherent() is to allocate memory and returns encrypted
>>> memory address directly when hyperv_private_memory_dma() is ture.
>>> This change is to keep all changes under Hyper-V subsystem and it's
>>> also compatible with existing solution which changes DMA core with minor
>>> changes.
>>
>>
>> If we update force_dma_unencrypted(dev) to return false when an
>> encrypted memory address is required, wouldn't the existing DMA-direct
>> support handle this case? Or are there issues with the existing code? If
>> so, could you explain them in more detail?
>>
> 
> Hyper-V Coco VM with T-disp scenario is to run a paravior(lightweight L1
> hypervisor) with normal guest (Detail please see 13.2. OpenHCL Architecture
> https://openvmmdev/guide/user_guide/openhcl.html). The paravisor is in charge
> of talking with hardware to accept PCI devices for Normal guest.
> 
> When PCI device is assigned to normal guest, __device_cc_accepted() should
> always return true for this device.  Then, DMA core will not use
> bounce buffer and
> unencrypted memory address for the device.
> 
> However, __device_cc_accepted() is based on TSM framework and Hyper-V
> doesn't support it. This means normal guest will not use TSM guest driver
> and so current code doesn't work. It's necessary to introduce an API for
> platforms without TSM support to mask the PCI device to be "accepted".
> 
>>
>> Can we rework this patch to use that(DMA_ATTR_CC_SHARED )?
>>
> 
> I think the change is simple. The issue here is how to set the attr flag for
> platforms without TSM support. This patch is to make Hyper-V T-Disp case
> work without changing DMA core and PCI layer.

I don't see why Hyper-V would need to change any other layer. We're 
proposing a generic notion of device_cc_accepted() which requires the 
bus code to decide what it means to "accept" a device - TSM will be 
PCI's standard way to do that; meanwhile VMbus should be free to call 
device_cc_accept() for whatever VMbus devices it fancies. That would be 
this patch done already.

And similarly if you also want to auto-accept PCI devices via some 
Hyper-V-specific non-TDISP mechanism, I'd expect there to be some way of 
doing that from the pci-hyperv driver without needing to hack or 
reimplement common code.

Thanks,
Robin.

> In parallel, we may co-work to add non-TSM platform support in your DMA
> CC SHARED patchset and "PCI/TSM: Core infrastructure" patchset.
> 
> --
> Thanks
> Tianyu Lan


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM
  2026-08-06 15:14         ` Robin Murphy
@ 2026-08-07 14:32           ` Tianyu Lan
  0 siblings, 0 replies; 8+ messages in thread
From: Tianyu Lan @ 2026-08-07 14:32 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Aneesh Kumar K.V, kys, haiyangz, wei.liu, decui, longli,
	Tianyu Lan, linux-hyperv, linux-kernel, aik, hch, vdso, mhklinux

On Thu, Aug 6, 2026 at 11:14 PM Robin Murphy <robin.murphy@arm.com> wrote:
>
> On 2026-08-06 3:21 pm, Tianyu Lan wrote:
> > On Wed, Aug 5, 2026 at 6:11 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
> >>
> >> Tianyu Lan <ltykernel@gmail.com> writes:
> >>
> >>> On Mon, Aug 3, 2026 at 5:04 PM Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
> >>>>
> >>>> Tianyu Lan <ltykernel@gmail.com> writes:
> >>>>
> >>>>> In CoCo VMs, system memory is encrypted by default.
> >>>>> Device drivers typically rely on the DMA core's
> >>>>> SWIOTLB as a bounce buffer for DMA operations, providing
> >>>>> decrypted memory that can be shared between the guest and
> >>>>> host.
> >>>>>
> >>>>> For PCI devices with T-Disp support and Confidential
> >>>>> VMBus devices (https://lkml.org/lkml/2026/7/27/1733) can
> >>>>> perform DMA transfers directly with private/encrypted
> >>>>> memory in a CoCo VM.
> >>>>>
> >>>>> To support DMA transfer with encrypted memory, Hyper-V
> >>>>> DMA ops are introduced and bypass some API which may
> >>>>> use swiotlb as bounce buffer.
> >>>>>
> >>>>> The DMA ops used is global data structure(see get_arch_
> >>>>> dma_ops() and get_dma_ops() for details). There is no
> >>>>> need to set up for each device individually.
> >>>>>
> >>>>
> >>>> Can we use __DMA_ATTR_ALLOC_CC_SHARED instead of checking
> >>>> hyperv_private_memory_dma(dev) directly? Also, would it be possible to
> >>>> encapsulate this logic in something like force_dma_encrypted(dev)?
> >>>>
> >>>
> >>> Hi Aneesh:
> >>>        Thanks for your review. I go through your patchset “dma-mapping: Use
> >>> DMA_ATTR_CC_SHARED”(https://lkml.org/lkml/2026/6/4/588). This patch
> >>> is compatible with your DMA_ATTR_CC_SHARED attr work in dma-mapping
> >>> layer. Once dma ops callbacks get DMA_ATTR_CC_SHARED attr flag and
> >>> it may use the flag to replace hyperv_private_memory_dma().
> >>>
> >>>
> >>>> Looking at functions such as hyperv_dma_alloc_coherent(), how does this
> >>>> differ from dma_direct_alloc()?
> >>>>
> >>> hyperv_dma_alloc_coherent() is to allocate memory and returns encrypted
> >>> memory address directly when hyperv_private_memory_dma() is ture.
> >>> This change is to keep all changes under Hyper-V subsystem and it's
> >>> also compatible with existing solution which changes DMA core with minor
> >>> changes.
> >>
> >>
> >> If we update force_dma_unencrypted(dev) to return false when an
> >> encrypted memory address is required, wouldn't the existing DMA-direct
> >> support handle this case? Or are there issues with the existing code? If
> >> so, could you explain them in more detail?
> >>
> >
> > Hyper-V Coco VM with T-disp scenario is to run a paravior(lightweight L1
> > hypervisor) with normal guest (Detail please see 13.2. OpenHCL Architecture
> > https://openvmmdev/guide/user_guide/openhcl.html). The paravisor is in charge
> > of talking with hardware to accept PCI devices for Normal guest.
> >
> > When PCI device is assigned to normal guest, __device_cc_accepted() should
> > always return true for this device.  Then, DMA core will not use
> > bounce buffer and
> > unencrypted memory address for the device.
> >
> > However, __device_cc_accepted() is based on TSM framework and Hyper-V
> > doesn't support it. This means normal guest will not use TSM guest driver
> > and so current code doesn't work. It's necessary to introduce an API for
> > platforms without TSM support to mask the PCI device to be "accepted".
> >
> >>
> >> Can we rework this patch to use that(DMA_ATTR_CC_SHARED )?
> >>
> >
> > I think the change is simple. The issue here is how to set the attr flag for
> > platforms without TSM support. This patch is to make Hyper-V T-Disp case
> > work without changing DMA core and PCI layer.
>
> I don't see why Hyper-V would need to change any other layer. We're
> proposing a generic notion of device_cc_accepted() which requires the
> bus code to decide what it means to "accept" a device - TSM will be
> PCI's standard way to do that; meanwhile VMbus should be free to call
> device_cc_accept() for whatever VMbus devices it fancies. That would be
> this patch done already.
>

Hi Robin:
      Thanks for your review. For Confidential VMBus device, we may call
device_cc_accept() in VMBus driver code directly to mark the device "accepted"
when it's enumerated..

> And similarly if you also want to auto-accept PCI devices via some
> Hyper-V-specific non-TDISP mechanism, I'd expect there to be some way of
> doing that from the pci-hyperv driver without needing to hack or
> reimplement common code.
>

For PCI devices with T-Disp, Hyper-V case will be different and the T-Disp
code(e.g, TSM) will be in the paravior. So it will not run TSM code in
the normal
guest. I think it may work via registering a PCI bus notification
event in Hyper-V
PCI driver and mark the device to be "accepted" when get a new device event.
I will have a try.

These changes will depend on "DMA CC SHARED" and "PCI/TSM: Core
infrastructure" patchset. device_cc_accept() seems to be reworked in the
latest TSM patch.

Hyper-V dma ops patch is to keep all changes in Hyper-V subsystem and
may combine with "PCI/TSM: Core infrastructure" and "PCI/TSM: Core
infrastructure" according to the upstream process. The dma ops call also may
device->p->tcb/accept field to choose bounce buffer or encrypt memory.
--
Thanks
Tianyu Lan

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-08-07 14:32 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03  3:35 [RFC PATCH 1/1] x86/VMBus: DMA transfer with encrypted memory in Coco VM Tianyu Lan
2026-08-03  3:53 ` sashiko-bot
2026-08-03  9:04 ` Aneesh Kumar K.V
2026-08-04  9:22   ` Tianyu Lan
2026-08-05 10:11     ` Aneesh Kumar K.V
2026-08-06 14:21       ` Tianyu Lan
2026-08-06 15:14         ` Robin Murphy
2026-08-07 14:32           ` Tianyu Lan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox