|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Ping: [PATCH v3] passthrough: give XEN_DOMCTL_test_assign_device more sane semantics
>>> On 16.08.17 at 14:20, <JBeulich@xxxxxxxx> wrote:
> So far callers of the libxc interface passed in a domain ID which was
> then ignored in the hypervisor. Instead, make the hypervisor honor it
> (accepting DOMID_INVALID to obtain original behavior), allowing to
> query whether a device can be assigned to a particular domain.
>
> Drop XSM's test_assign_{,dt}device hooks as no longer being
> individually useful.
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> v3: Drop test-assign XSM hooks.
> v2: Alter the semantics to check whether the device can be assigned to
> the passed in domain.
>
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -391,11 +391,15 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
>
> switch ( op->cmd )
> {
> - case XEN_DOMCTL_createdomain:
> case XEN_DOMCTL_test_assign_device:
> + if ( op->domain == DOMID_INVALID )
> + {
> + case XEN_DOMCTL_createdomain:
> case XEN_DOMCTL_gdbsx_guestmemio:
> - d = NULL;
> - break;
> + d = NULL;
> + break;
> + }
> + /* fall through */
> default:
> d = rcu_lock_domain_by_id(op->domain);
> if ( !d && op->cmd != XEN_DOMCTL_getdomaininfo )
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -143,12 +143,15 @@ int iommu_do_dt_domctl(struct xen_domctl
> switch ( domctl->cmd )
> {
> case XEN_DOMCTL_assign_device:
> + ASSERT(d);
> + /* fall through */
> + case XEN_DOMCTL_test_assign_device:
> ret = -ENODEV;
> if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> break;
>
> ret = -EINVAL;
> - if ( d->is_dying || domctl->u.assign_device.flags )
> + if ( (d && d->is_dying) || domctl->u.assign_device.flags )
> break;
>
> ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
> @@ -161,6 +164,17 @@ int iommu_do_dt_domctl(struct xen_domctl
> if ( ret )
> break;
>
> + if ( domctl->cmd == XEN_DOMCTL_test_assign_device )
> + {
> + if ( iommu_dt_device_is_assigned(dev) )
> + {
> + printk(XENLOG_G_ERR "%s already assigned.\n",
> + dt_node_full_name(dev));
> + ret = -EINVAL;
> + }
> + break;
> + }
> +
> ret = iommu_assign_dt_device(d, dev);
>
> if ( ret )
> @@ -194,33 +208,6 @@ int iommu_do_dt_domctl(struct xen_domctl
> dt_node_full_name(dev), d->domain_id, ret);
> break;
>
> - case XEN_DOMCTL_test_assign_device:
> - ret = -ENODEV;
> - 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 ( ret )
> - break;
> -
> - ret = xsm_test_assign_dtdevice(XSM_HOOK, dt_node_full_name(dev));
> - if ( ret )
> - break;
> -
> - if ( iommu_dt_device_is_assigned(dev) )
> - {
> - printk(XENLOG_G_ERR "%s already assigned.\n",
> - dt_node_full_name(dev));
> - ret = -EINVAL;
> - }
> - break;
> -
> default:
> ret = -ENOSYS;
> break;
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -1583,35 +1583,10 @@ int iommu_do_pci_domctl(
> }
> break;
>
> - case XEN_DOMCTL_test_assign_device:
> - ret = -ENODEV;
> - 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 ( ret )
> - break;
> -
> - seg = machine_sbdf >> 16;
> - bus = PCI_BUS(machine_sbdf);
> - devfn = PCI_DEVFN2(machine_sbdf);
> -
> - if ( device_assigned(seg, bus, devfn) )
> - {
> - printk(XENLOG_G_INFO
> - "%04x:%02x:%02x.%u already assigned, or non-existent\n",
> - seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
> - ret = -EINVAL;
> - }
> - break;
> -
> case XEN_DOMCTL_assign_device:
> + ASSERT(d);
> + /* fall through */
> + case XEN_DOMCTL_test_assign_device:
> /* Don't support self-assignment of devices. */
> if ( d == current->domain )
> {
> @@ -1625,7 +1600,9 @@ int iommu_do_pci_domctl(
>
> ret = -EINVAL;
> flags = domctl->u.assign_device.flags;
> - if ( d->is_dying || (flags & ~XEN_DOMCTL_DEV_RDM_RELAXED) )
> + if ( domctl->cmd == XEN_DOMCTL_assign_device
> + ? d->is_dying || (flags & ~XEN_DOMCTL_DEV_RDM_RELAXED)
> + : flags )
> break;
>
> machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
> @@ -1638,8 +1615,20 @@ int iommu_do_pci_domctl(
> bus = PCI_BUS(machine_sbdf);
> devfn = PCI_DEVFN2(machine_sbdf);
>
> - ret = device_assigned(seg, bus, devfn) ?:
> - assign_device(d, seg, bus, devfn, flags);
> + ret = device_assigned(seg, bus, devfn);
> + if ( domctl->cmd == XEN_DOMCTL_test_assign_device )
> + {
> + if ( ret )
> + {
> + printk(XENLOG_G_INFO
> + "%04x:%02x:%02x.%u already assigned, or
> non-existent\n",
> + seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
> + ret = -EINVAL;
> + }
> + break;
> + }
> + if ( !ret )
> + ret = assign_device(d, seg, bus, devfn, flags);
> if ( ret == -ERESTART )
> ret = hypercall_create_continuation(__HYPERVISOR_domctl,
> "h", u_domctl);
> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -506,7 +506,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendt
>
> /* Assign a device to a guest. Sets up IOMMU structures. */
> /* XEN_DOMCTL_assign_device */
> -/* XEN_DOMCTL_test_assign_device */
> +/*
> + * XEN_DOMCTL_test_assign_device: Pass DOMID_INVALID to find out whether
> the
> + * given device is assigned to any DomU at all. Pass a specific domain ID
> to
> + * find out whether the given device can be assigned to that domain.
> + */
> /*
> * XEN_DOMCTL_deassign_device: The behavior of this DOMCTL differs
> * between the different type of device:
> --- a/xen/include/xsm/dummy.h
> +++ b/xen/include/xsm/dummy.h
> @@ -337,12 +337,6 @@ static XSM_INLINE int xsm_get_device_gro
> return xsm_default_action(action, current->domain, NULL);
> }
>
> -static XSM_INLINE int xsm_test_assign_device(XSM_DEFAULT_ARG uint32_t
> machine_bdf)
> -{
> - XSM_ASSERT_ACTION(XSM_HOOK);
> - return xsm_default_action(action, current->domain, NULL);
> -}
> -
> static XSM_INLINE int xsm_assign_device(XSM_DEFAULT_ARG struct domain *d,
> uint32_t machine_bdf)
> {
> XSM_ASSERT_ACTION(XSM_HOOK);
> @@ -358,12 +352,6 @@ static XSM_INLINE int xsm_deassign_devic
> #endif /* HAS_PASSTHROUGH && HAS_PCI */
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
> -static XSM_INLINE int xsm_test_assign_dtdevice(XSM_DEFAULT_ARG const char
> *dtpath)
> -{
> - XSM_ASSERT_ACTION(XSM_HOOK);
> - return xsm_default_action(action, current->domain, NULL);
> -}
> -
> static XSM_INLINE int xsm_assign_dtdevice(XSM_DEFAULT_ARG struct domain *d,
> const char *dtpath)
> {
> --- a/xen/include/xsm/xsm.h
> +++ b/xen/include/xsm/xsm.h
> @@ -109,13 +109,11 @@ struct xsm_operations {
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
> int (*get_device_group) (uint32_t machine_bdf);
> - int (*test_assign_device) (uint32_t machine_bdf);
> int (*assign_device) (struct domain *d, uint32_t machine_bdf);
> int (*deassign_device) (struct domain *d, uint32_t machine_bdf);
> #endif
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
> - int (*test_assign_dtdevice) (const char *dtpath);
> int (*assign_dtdevice) (struct domain *d, const char *dtpath);
> int (*deassign_dtdevice) (struct domain *d, const char *dtpath);
> #endif
> @@ -465,11 +463,6 @@ static inline int xsm_get_device_group(x
> return xsm_ops->get_device_group(machine_bdf);
> }
>
> -static inline int xsm_test_assign_device(xsm_default_t def, uint32_t
> machine_bdf)
> -{
> - return xsm_ops->test_assign_device(machine_bdf);
> -}
> -
> static inline int xsm_assign_device(xsm_default_t def, struct domain *d,
> uint32_t machine_bdf)
> {
> return xsm_ops->assign_device(d, machine_bdf);
> @@ -488,12 +481,6 @@ static inline int xsm_assign_dtdevice(xs
> return xsm_ops->assign_dtdevice(d, dtpath);
> }
>
> -static inline int xsm_test_assign_dtdevice(xsm_default_t def,
> - const char *dtpath)
> -{
> - return xsm_ops->test_assign_dtdevice(dtpath);
> -}
> -
> static inline int xsm_deassign_dtdevice(xsm_default_t def, struct domain
> *d,
> const char *dtpath)
> {
> --- a/xen/xsm/dummy.c
> +++ b/xen/xsm/dummy.c
> @@ -91,13 +91,11 @@ void __init xsm_fixup_ops (struct xsm_op
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
> set_to_dummy_if_null(ops, get_device_group);
> - set_to_dummy_if_null(ops, test_assign_device);
> set_to_dummy_if_null(ops, assign_device);
> set_to_dummy_if_null(ops, deassign_device);
> #endif
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
> - set_to_dummy_if_null(ops, test_assign_dtdevice);
> set_to_dummy_if_null(ops, assign_dtdevice);
> set_to_dummy_if_null(ops, deassign_dtdevice);
> #endif
> --- a/xen/xsm/flask/hooks.c
> +++ b/xen/xsm/flask/hooks.c
> @@ -1278,6 +1281,9 @@ static int flask_assign_device(struct do
> int rc = -EPERM;
> struct avc_audit_data ad;
>
> + if ( !d )
> + return flask_test_assign_device(machine_bdf);
> +
> rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
> if ( rc )
> return rc;
> @@ -1333,6 +1339,9 @@ static int flask_assign_dtdevice(struct
> int rc = -EPERM;
> struct avc_audit_data ad;
>
> + if ( !d )
> + return flask_test_assign_dtdevice(dtpath);
> +
> rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
> if ( rc )
> return rc;
> @@ -1780,13 +1789,11 @@ static struct xsm_operations flask_ops =
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
> .get_device_group = flask_get_device_group,
> - .test_assign_device = flask_test_assign_device,
> .assign_device = flask_assign_device,
> .deassign_device = flask_deassign_device,
> #endif
>
> #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE)
> - .test_assign_dtdevice = flask_test_assign_dtdevice,
> .assign_dtdevice = flask_assign_dtdevice,
> .deassign_dtdevice = flask_deassign_dtdevice,
> #endif
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |