@@ -1689,6 +1689,7 @@ int xc_get_hvm_param(xc_interface *handle, uint32_t dom, int param, unsigned lon
int xc_assign_device(xc_interface *xch,
uint32_t domid,
uint32_t machine_sbdf,
+ uint32_t *virtual_sbdf,
uint32_t flag);
int xc_get_device_group(xc_interface *xch,
@@ -1497,18 +1497,28 @@ int xc_assign_device(
xc_interface *xch,
uint32_t domid,
uint32_t machine_sbdf,
+ uint32_t *virtual_sbdf,
uint32_t flags)
{
+ int rc;
struct xen_domctl domctl = {};
domctl.cmd = XEN_DOMCTL_assign_device;
domctl.domain = domid;
domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
- domctl.u.assign_device.u.pci.virtual_sbdf = XEN_DOMCTL_DEV_SDBF_ANY;
+ if (!virtual_sbdf)
+ domctl.u.assign_device.u.pci.virtual_sbdf = XEN_DOMCTL_DEV_SDBF_ANY;
+ else
+ domctl.u.assign_device.u.pci.virtual_sbdf = *virtual_sbdf;
domctl.u.assign_device.flags = flags;
- return do_domctl(xch, &domctl);
+ rc = do_domctl(xch, &domctl);
+
+ if (!rc && virtual_sbdf)
+ *virtual_sbdf = domctl.u.assign_device.u.pci.virtual_sbdf;
+
+ return rc;
}
int xc_get_device_group(
@@ -842,7 +842,7 @@ name:
* so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
* unnecessarily denied.
*/
- rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci),
+ rc = xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci), NULL,
XEN_DOMCTL_DEV_RDM_RELAXED);
if ( rc < 0 ) {
LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func);
@@ -1524,7 +1524,7 @@ out_no_irq:
rc = ERROR_FAIL;
goto out;
}
- r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), flag);
+ r = xc_assign_device(ctx->xch, domid, pci_encode_bdf(pci), NULL, flag);
if (r < 0 && (hvm || errno != ENOSYS)) {
LOGED(ERROR, domainid, "xc_assign_device failed");
rc = ERROR_FAIL;
@@ -1323,7 +1323,7 @@ CAMLprim value stub_xc_domain_assign_device(value xch_val, value domid, value de
func = Int_val(Field(desc, 3));
sbdf = encode_sbdf(domain, bus, dev, func);
- ret = xc_assign_device(xch, Int_val(domid), sbdf,
+ ret = xc_assign_device(xch, Int_val(domid), sbdf, NULL,
XEN_DOMCTL_DEV_RDM_RELAXED);
if (ret < 0)
@@ -587,7 +587,7 @@ static PyObject *pyxc_assign_device(XcObject *self,
sbdf |= (dev & 0x1f) << 3;
sbdf |= (func & 0x7);
- if ( xc_assign_device(self->xc_handle, dom, sbdf, 0) != 0 )
+ if ( xc_assign_device(self->xc_handle, dom, sbdf, NULL, 0) != 0 )
{
if (errno == ENOSYS)
sbdf = -1;
Now, when "assign_device" domctl supports virtual_sbdf option, make it available to libxc users. This is an optional parameter, if it is not provided, xc_assign_device() will ask hypervisor to allocate a free vSBDF. Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com> -- This clearly breaks libxc API. So I wanted to discuss a proper way of doing this. Should I introduce a new xc_assign_device() function with an extra parameter? --- tools/include/xenctrl.h | 1 + tools/libs/ctrl/xc_domain.c | 14 ++++++++++++-- tools/libs/light/libxl_pci.c | 4 ++-- tools/ocaml/libs/xc/xenctrl_stubs.c | 2 +- tools/python/xen/lowlevel/xc/xc.c | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-)