RDMA/uverbs: Expose CoCo DMA bounce requirement to userspace

In CoCo guests, guest memory is encrypted and untrusted (T=0) devices
cannot DMA to it directly; such transfers must go through unencrypted
bounce buffers. RDMA registers user pages for direct device access,
bypassing the DMA layer and thus any bouncing, so registered memory does
not work in this configuration.

Until trusted (T=1) device detection is available, conservatively flag
every device attached to a CoCo guest. Expose the condition to userspace
as IB_UVERBS_DEVICE_CC_DMA_BOUNCE in device_cap_flags_ex so applications
can avoid memory registration and fall back to copying buffers through
send/recv.

Link: https://patch.msgid.link/r/20260517141311.2409230-2-jiri@resnulli.us
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Jiri Pirko 2026-05-17 16:13:10 +02:00 committed by Jason Gunthorpe
parent 93ce776a5b
commit d7a40b5194
4 changed files with 16 additions and 0 deletions

View File

@ -42,6 +42,7 @@
#include <linux/security.h>
#include <linux/notifier.h>
#include <linux/hashtable.h>
#include <linux/cc_platform.h>
#include <rdma/rdma_netlink.h>
#include <rdma/ib_addr.h>
#include <rdma/ib_cache.h>
@ -1419,6 +1420,14 @@ int ib_register_device(struct ib_device *device, const char *name,
*/
WARN_ON(dma_device && !dma_device->dma_parms);
device->dma_device = dma_device;
/*
* In a CoCo guest every device is currently assumed to be untrusted
* (T=0) and therefore subject to DMA bouncing. Once trusted (T=1)
* device detection is wired up, narrow this check to exclude such
* devices.
*/
if (dma_device && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
device->cc_dma_bounce = 1;
ret = setup_device(device);
if (ret)

View File

@ -3584,6 +3584,8 @@ static int ib_uverbs_ex_query_device(struct uverbs_attr_bundle *attrs)
resp.timestamp_mask = attr.timestamp_mask;
resp.hca_core_clock = attr.hca_core_clock;
resp.device_cap_flags_ex = attr.device_cap_flags;
if (ib_dev->cc_dma_bounce)
resp.device_cap_flags_ex |= IB_UVERBS_DEVICE_CC_DMA_BOUNCE;
resp.rss_caps.supported_qpts = attr.rss_caps.supported_qpts;
resp.rss_caps.max_rwq_indirection_tables =
attr.rss_caps.max_rwq_indirection_tables;

View File

@ -275,6 +275,7 @@ enum ib_device_cap_flags {
IB_DEVICE_FLUSH_GLOBAL = IB_UVERBS_DEVICE_FLUSH_GLOBAL,
IB_DEVICE_FLUSH_PERSISTENT = IB_UVERBS_DEVICE_FLUSH_PERSISTENT,
IB_DEVICE_ATOMIC_WRITE = IB_UVERBS_DEVICE_ATOMIC_WRITE,
IB_DEVICE_CC_DMA_BOUNCE = IB_UVERBS_DEVICE_CC_DMA_BOUNCE,
};
enum ib_kernel_cap_flags {
@ -2950,6 +2951,8 @@ struct ib_device {
u16 kverbs_provider:1;
/* CQ adaptive moderation (RDMA DIM) */
u16 use_cq_dim:1;
/* CoCo guest with DMA bounce buffering required */
u16 cc_dma_bounce:1;
u8 node_type;
u32 phys_port_cnt;
struct ib_device_attr attrs;

View File

@ -1368,6 +1368,8 @@ enum ib_uverbs_device_cap_flags {
IB_UVERBS_DEVICE_FLUSH_PERSISTENT = 1ULL << 39,
/* Atomic write attributes */
IB_UVERBS_DEVICE_ATOMIC_WRITE = 1ULL << 40,
/* CoCo guest with DMA bounce buffering required */
IB_UVERBS_DEVICE_CC_DMA_BOUNCE = 1ULL << 41,
};
enum ib_uverbs_raw_packet_caps {