diff --git a/tools/include/xen-sys/Linux/privcmd.h b/tools/include/xen-sys/Linux/privcmd.h
index 5071ebcc8b..fbdc9aa927 100644
--- a/tools/include/xen-sys/Linux/privcmd.h
+++ b/tools/include/xen-sys/Linux/privcmd.h
@@ -110,6 +110,16 @@ typedef struct privcmd_map_hva_to_gpfns {
 	int add_mapping;
 } privcmd_map_hva_to_gpfns_t;
 
+typedef struct privcmd_p2pdma_distance {
+	__u32 provider_bus;
+	__u32 provider_slot;
+	__u32 provider_func;
+	__u32 client_bus;
+	__u32 client_slot;
+	__u32 client_func;
+	__u32 distance;
+} privcmd_p2pdma_distance_t;
+
 /*
  * @cmd: IOCTL_PRIVCMD_HYPERCALL
  * @arg: &privcmd_hypercall_t
@@ -131,6 +141,8 @@ typedef struct privcmd_map_hva_to_gpfns {
 	_IOC(_IOC_NONE, 'P', 7, sizeof(privcmd_mmap_resource_t))
 #define IOCTL_PRIVCMD_PCIDEV_GET_GSI			\
 	_IOC(_IOC_NONE, 'P', 10, sizeof(privcmd_pcidev_get_gsi_t))
+#define IOCTL_PRIVCMD_P2PDMA_DISTANCE                          \
+	_IOC(_IOC_NONE, 'P', 11, sizeof(privcmd_p2pdma_distance_t))
 #define IOCTL_PRIVCMD_MAP_HVA_TO_GPFNS                         \
 	_IOC(_IOC_NONE, 'P', 13, sizeof(privcmd_map_hva_to_gpfns_t))
 #define IOCTL_PRIVCMD_UNIMPLEMENTED				\
diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 29617585c5..42d15a22b8 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -1654,6 +1654,23 @@ int xc_physdev_unmap_pirq(xc_interface *xch,
 
 int xc_pcidev_get_gsi(xc_interface *xch, uint32_t sbdf);
 
+int xc_physdev_p2pdma_distance(xc_interface *xch,
+                               uint32_t bus,
+                               uint32_t slot,
+                               uint32_t func,
+                               uint32_t c_bus,
+                               uint32_t c_slot,
+                               uint32_t c_func);
+
+int xc_pcidev_p2pdma_distance(xc_interface *xch,
+                              uint32_t bus,
+                              uint32_t slot,
+                              uint32_t func,
+                              uint32_t c_bus,
+                              uint32_t c_slot,
+                              uint32_t c_func);
+
+
 /*
  *  LOGGING AND ERROR REPORTING
  */
diff --git a/tools/libs/ctrl/xc_freebsd.c b/tools/libs/ctrl/xc_freebsd.c
index 9019fc6633..4e0df06b7c 100644
--- a/tools/libs/ctrl/xc_freebsd.c
+++ b/tools/libs/ctrl/xc_freebsd.c
@@ -60,6 +60,17 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size)
     return ptr;
 }
 
+int xc_pcidev_p2pdma_distance(xc_interface *xch,
+                              uint32_t bus,
+                              uint32_t slot,
+                              uint32_t func,
+                              uint32_t c_bus,
+                              uint32_t c_slot,
+                              uint32_t c_func)
+{
+    return -1;
+}
+
 int xc_pcidev_get_gsi(xc_interface *xch, uint32_t sbdf)
 {
     errno = ENOSYS;
diff --git a/tools/libs/ctrl/xc_linux.c b/tools/libs/ctrl/xc_linux.c
index 92591e49a1..9aeff2328f 100644
--- a/tools/libs/ctrl/xc_linux.c
+++ b/tools/libs/ctrl/xc_linux.c
@@ -66,6 +66,30 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size)
     return ptr;
 }
 
+int xc_pcidev_p2pdma_distance(xc_interface *xch,
+                              uint32_t bus,
+                              uint32_t slot,
+                              uint32_t func,
+                              uint32_t c_bus,
+                              uint32_t c_slot,
+                              uint32_t c_func)
+{
+    privcmd_p2pdma_distance_t p2pdma_distance = {
+        .provider_bus = bus,
+        .provider_slot = slot,
+        .provider_func = func,
+        .client_bus = c_bus,
+        .client_slot = c_slot,
+        .client_func = c_func,
+        .distance = -1,
+    };
+    if (!ioctl(xencall_fd(xch->xcall), IOCTL_PRIVCMD_P2PDMA_DISTANCE, &p2pdma_distance)) {
+	return p2pdma_distance.distance;
+    }
+
+    return -1;
+}
+
 int xc_pcidev_get_gsi(xc_interface *xch, uint32_t sbdf)
 {
     int ret;
diff --git a/tools/libs/ctrl/xc_minios.c b/tools/libs/ctrl/xc_minios.c
index 462af827b3..4698cca5ea 100644
--- a/tools/libs/ctrl/xc_minios.c
+++ b/tools/libs/ctrl/xc_minios.c
@@ -47,6 +47,17 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size)
     return memalign(alignment, size);
 }
 
+int  xc_pcidev_p2pdma_distance(xc_interface *xch,
+                               uint32_t bus,
+                               uint32_t slot,
+                               uint32_t func,
+                               uint32_t c_bus,
+                               uint32_t c_slot,
+                               uint32_t c_func)
+{
+    return -1;
+}
+
 int xc_pcidev_get_gsi(xc_interface *xch, uint32_t sbdf)
 {
     errno = ENOSYS;
diff --git a/tools/libs/ctrl/xc_netbsd.c b/tools/libs/ctrl/xc_netbsd.c
index 1318d4d906..7e0ee8417e 100644
--- a/tools/libs/ctrl/xc_netbsd.c
+++ b/tools/libs/ctrl/xc_netbsd.c
@@ -63,6 +63,17 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size)
     return valloc(size);
 }
 
+int xc_pcidev_p2pdma_distance(xc_interface *xch,
+                              uint32_t bus,
+                              uint32_t slot,
+                              uint32_t func,
+                              uint32_t c_bus,
+                              uint32_t c_slot,
+                              uint32_t c_func)
+{
+    return -1;
+}
+
 int xc_pcidev_get_gsi(xc_interface *xch, uint32_t sbdf)
 {
     errno = ENOSYS;
diff --git a/tools/libs/ctrl/xc_physdev.c b/tools/libs/ctrl/xc_physdev.c
index 25e686d7b3..4ee8f39e09 100644
--- a/tools/libs/ctrl/xc_physdev.c
+++ b/tools/libs/ctrl/xc_physdev.c
@@ -138,3 +138,15 @@ int xc_physdev_unmap_pirq(xc_interface *xch,
     return rc;
 }
 
+int xc_physdev_p2pdma_distance(xc_interface *xch,
+                               uint32_t bus,
+                               uint32_t slot,
+                               uint32_t func,
+                               uint32_t c_bus,
+                               uint32_t c_slot,
+                               uint32_t c_func)
+{
+    return xc_pcidev_p2pdma_distance(xch, bus, slot, func,
+                                     c_bus, c_slot, c_func);
+}
+
diff --git a/tools/libs/ctrl/xc_solaris.c b/tools/libs/ctrl/xc_solaris.c
index 049e28d55c..a054b40b31 100644
--- a/tools/libs/ctrl/xc_solaris.c
+++ b/tools/libs/ctrl/xc_solaris.c
@@ -32,6 +32,17 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size)
     return memalign(alignment, size);
 }
 
+int xc_pcidev_p2pdma_distance(xc_interface *xch,
+                              uint32_t bus,
+                              uint32_t slot,
+                              uint32_t func,
+                              uint32_t c_bus,
+                              uint32_t c_slot,
+                              uint32_t c_func)
+{
+    return -1;
+}
+
 int xc_pcidev_get_gsi(xc_interface *xch, uint32_t sbdf)
 {
     errno = ENOSYS;
