On Wed, Mar 25, 2026 at 03:56:49AM -0400, Tianyu Lan wrote: > Hyper-V provides Confidential VMBus to communicate between > device model and device guest driver via encrypted/private > memory in Confidential VM. The device model is in OpenHCL > (https://openvmm.dev/guide/user_guide/openhcl.html) that > plays the paravisor role. > > For a VMBus device, there are two communication methods to > talk with Host/Hypervisor. 1) VMBUS Ring buffer 2) Dynamic > DMA transfer. > > The Confidential VMBus Ring buffer has been upstreamed by > Roman Kisel(commit 6802d8af47d1). > > The dynamic DMA transition of VMBus device normally goes > through DMA core and it uses SWIOTLB as bounce buffer in > a CoCo VM. > > The Confidential VMBus device can do DMA directly to > private/encrypted memory. Because the swiotlb is decrypted > memory, the DMA transfer must not be bounced through the > swiotlb, so as to preserve confidentiality. This is different > from the default for Linux CoCo VMs, so disable the VMBus > device's use of swiotlb. > > Expose swiotlb_dev_disable() from DMA Core to disable > bounce buffer for device.
It feels awkward and like a layering violation to let arbitrary kernel drivers manipulate SWIOTLB, which sits beneath the DMA core. Thanks > > Suggested-by: Michael Kelley <[email protected]> > Signed-off-by: Tianyu Lan <[email protected]> > --- > drivers/hv/vmbus_drv.c | 6 +++++- > include/linux/swiotlb.h | 5 +++++ > 2 files changed, 10 insertions(+), 1 deletion(-) > > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c > index 3d1a58b667db..84e6971fc90f 100644 > --- a/drivers/hv/vmbus_drv.c > +++ b/drivers/hv/vmbus_drv.c > @@ -2184,11 +2184,15 @@ int vmbus_device_register(struct hv_device > *child_device_obj) > child_device_obj->device.dma_mask = &child_device_obj->dma_mask; > dma_set_mask(&child_device_obj->device, DMA_BIT_MASK(64)); > > + device_initialize(&child_device_obj->device); > + if (child_device_obj->channel->co_external_memory) > + swiotlb_dev_disable(&child_device_obj->device); > + > /* > * Register with the LDM. This will kick off the driver/device > * binding...which will eventually call vmbus_match() and vmbus_probe() > */ > - ret = device_register(&child_device_obj->device); > + ret = device_add(&child_device_obj->device); > if (ret) { > pr_err("Unable to register child device\n"); > put_device(&child_device_obj->device); > diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h > index 3dae0f592063..7c572570d5d9 100644 > --- a/include/linux/swiotlb.h > +++ b/include/linux/swiotlb.h > @@ -169,6 +169,11 @@ static inline struct io_tlb_pool > *swiotlb_find_pool(struct device *dev, > return NULL; > } > > +static inline bool swiotlb_dev_disable(struct device *dev) > +{ > + return dev->dma_io_tlb_mem == NULL; > +} > + > static inline bool is_swiotlb_force_bounce(struct device *dev) > { > struct io_tlb_mem *mem = dev->dma_io_tlb_mem; > -- > 2.50.1 > >

