xc_interface *xch,
uint32_t domid,
uint32_t machine_sbdf,
- uint32_t flag)
+ uint32_t flags)
{
DECLARE_DOMCTL;
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.flag = flag;
+ domctl.u.assign_device.flags = flags;
return do_domctl(xch, &domctl);
}
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.flags = 0;
return do_domctl(xch, &domctl);
}
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.flags = 0;
return do_domctl(xch, &domctl);
}
* DT doesn't own any RDM so actually DT has nothing to do
* for any flag and here just fix that as 0.
*/
- domctl.u.assign_device.flag = 0;
+ domctl.u.assign_device.flags = 0;
set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
rc = do_domctl(xch, &domctl);
domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
domctl.u.assign_device.u.dt.size = size;
set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
+ domctl.u.assign_device.flags = 0;
rc = do_domctl(xch, &domctl);
domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
domctl.u.assign_device.u.dt.size = size;
set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
+ domctl.u.assign_device.flags = 0;
rc = do_domctl(xch, &domctl);
if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
break;
- if ( unlikely(d->is_dying) )
- {
- ret = -EINVAL;
+ ret = -EINVAL;
+ if ( d->is_dying || domctl->u.assign_device.flags )
break;
- }
ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
domctl->u.assign_device.u.dt.size,
if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
break;
+ ret = -EINVAL;
+ if ( domctl->u.assign_device.flags )
+ break;
+
ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
domctl->u.assign_device.u.dt.size,
&dev);
if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
break;
+ ret = -EINVAL;
+ if ( domctl->u.assign_device.flags )
+ break;
+
ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
domctl->u.assign_device.u.dt.size,
&dev);
{
u16 seg;
u8 bus, devfn;
- u32 flag;
int ret = 0;
uint32_t machine_sbdf;
switch ( domctl->cmd )
{
+ unsigned int flags;
+
case XEN_DOMCTL_get_device_group:
{
u32 max_sdevs;
if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
break;
+ ret = -EINVAL;
+ if ( domctl->u.assign_device.flags )
+ break;
+
machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf);
if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
break;
- if ( unlikely(d->is_dying) )
- {
- ret = -EINVAL;
+ ret = -EINVAL;
+ flags = domctl->u.assign_device.flags;
+ if ( d->is_dying || (flags & ~XEN_DOMCTL_DEV_RDM_RELAXED) )
break;
- }
machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
seg = machine_sbdf >> 16;
bus = PCI_BUS(machine_sbdf);
devfn = PCI_DEVFN2(machine_sbdf);
- flag = domctl->u.assign_device.flag;
- if ( flag & ~XEN_DOMCTL_DEV_RDM_RELAXED )
- {
- ret = -EINVAL;
- break;
- }
ret = device_assigned(seg, bus, devfn) ?:
- assign_device(d, seg, bus, devfn, flag);
+ assign_device(d, seg, bus, devfn, flags);
if ( ret == -ERESTART )
ret = hypercall_create_continuation(__HYPERVISOR_domctl,
"h", u_domctl);
if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
break;
+ ret = -EINVAL;
+ if ( domctl->u.assign_device.flags )
+ break;
+
machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
ret = xsm_deassign_device(XSM_HOOK, d, machine_sbdf);
* XEN_DOMCTL_deassign_device: The behavior of this DOMCTL differs
* between the different type of device:
* - PCI device (XEN_DOMCTL_DEV_PCI) will be reassigned to DOM0
- * - DT device (XEN_DOMCTL_DT_PCI) will left unassigned. DOM0
+ * - DT device (XEN_DOMCTL_DEV_DT) will left unassigned. DOM0
* will have to call XEN_DOMCTL_assign_device in order to use the
* device.
*/
#define XEN_DOMCTL_DEV_PCI 0
#define XEN_DOMCTL_DEV_DT 1
struct xen_domctl_assign_device {
+ /* IN */
uint32_t dev; /* XEN_DOMCTL_DEV_* */
+ uint32_t flags;
+#define XEN_DOMCTL_DEV_RDM_RELAXED 1 /* assign only */
union {
struct {
uint32_t machine_sbdf; /* machine PCI ID of assigned device */
XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
} dt;
} u;
- /* IN */
-#define XEN_DOMCTL_DEV_RDM_RELAXED 1
- uint32_t flag; /* flag of assigned device */
};
typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);