break;
#endif
+#ifdef HAS_PCI
+ case XEN_SYSCTL_pcitopoinfo:
+ {
+ xen_sysctl_pcitopoinfo_t *ti = &op->u.pcitopoinfo;
+ unsigned int i = 0;
+
+ if ( guest_handle_is_null(ti->devs) ||
+ guest_handle_is_null(ti->nodes) )
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ while ( i < ti->num_devs )
+ {
+ physdev_pci_device_t dev;
+ uint32_t node;
+ const struct pci_dev *pdev;
+
+ if ( copy_from_guest_offset(&dev, ti->devs, i, 1) )
+ {
+ ret = -EFAULT;
+ break;
+ }
+
+ spin_lock(&pcidevs_lock);
+ pdev = pci_get_pdev(dev.seg, dev.bus, dev.devfn);
+ if ( !pdev )
+ node = XEN_INVALID_DEV;
+ else if ( pdev->node == NUMA_NO_NODE )
+ node = XEN_INVALID_NODE_ID;
+ else
+ node = pdev->node;
+ spin_unlock(&pcidevs_lock);
+
+ if ( copy_to_guest_offset(ti->nodes, i, &node, 1) )
+ {
+ ret = -EFAULT;
+ break;
+ }
+
+ if ( (++i > 0x3f) && hypercall_preempt_check() )
+ break;
+ }
+
+ if ( !ret && (ti->num_devs != i) )
+ {
+ ti->num_devs = i;
+ if ( __copy_field_to_guest(u_sysctl, op, u.pcitopoinfo.num_devs) )
+ ret = -EFAULT;
+ }
+ break;
+ }
+#endif
+
default:
ret = arch_do_sysctl(op, u_sysctl);
copyback = 0;
#include "xen.h"
#include "domctl.h"
+#include "physdev.h"
#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000C
typedef struct xen_sysctl_psr_cmt_op xen_sysctl_psr_cmt_op_t;
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_psr_cmt_op_t);
+/* XEN_SYSCTL_pcitopoinfo */
+#define XEN_INVALID_DEV (XEN_INVALID_NODE_ID - 1)
+struct xen_sysctl_pcitopoinfo {
+ /*
+ * IN: Number of elements in 'pcitopo' and 'nodes' arrays.
+ * OUT: Number of processed elements of those arrays.
+ */
+ uint32_t num_devs;
+
+ /* IN: list of devices for which node IDs are requested. */
+ XEN_GUEST_HANDLE_64(physdev_pci_device_t) devs;
+
+ /*
+ * OUT: node identifier for each device.
+ * If information for a particular device is not available then
+ * corresponding entry will be set to XEN_INVALID_NODE_ID. If
+ * device is not known to the hypervisor then XEN_INVALID_DEV
+ * will be provided.
+ */
+ XEN_GUEST_HANDLE_64(uint32) nodes;
+};
+typedef struct xen_sysctl_pcitopoinfo xen_sysctl_pcitopoinfo_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_pcitopoinfo_t);
+
struct xen_sysctl {
uint32_t cmd;
#define XEN_SYSCTL_readconsole 1
#define XEN_SYSCTL_scheduler_op 19
#define XEN_SYSCTL_coverage_op 20
#define XEN_SYSCTL_psr_cmt_op 21
+#define XEN_SYSCTL_pcitopoinfo 22
uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
union {
struct xen_sysctl_readconsole readconsole;
struct xen_sysctl_tbuf_op tbuf_op;
struct xen_sysctl_physinfo physinfo;
struct xen_sysctl_cputopoinfo cputopoinfo;
+ struct xen_sysctl_pcitopoinfo pcitopoinfo;
struct xen_sysctl_numainfo numainfo;
struct xen_sysctl_sched_id sched_id;
struct xen_sysctl_perfc_op perfc_op;
case XEN_SYSCTL_physinfo:
case XEN_SYSCTL_cputopoinfo:
case XEN_SYSCTL_numainfo:
+ case XEN_SYSCTL_pcitopoinfo:
return domain_has_xen(current->domain, XEN__PHYSINFO);
case XEN_SYSCTL_psr_cmt_op: