From patchwork Wed Jun 21 10:08:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9801389 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2E5F960234 for ; Wed, 21 Jun 2017 10:12:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1AF6728581 for ; Wed, 21 Jun 2017 10:12:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0F2272858E; Wed, 21 Jun 2017 10:12:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DBDD02858C for ; Wed, 21 Jun 2017 10:12:27 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dNcZ6-0003Yl-UI; Wed, 21 Jun 2017 10:08:48 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dNcZ5-0003Yf-Mf for xen-devel@lists.xenproject.org; Wed, 21 Jun 2017 10:08:47 +0000 Received: from [85.158.137.68] by server-13.bemta-3.messagelabs.com id 72/8D-17076-EA54A495; Wed, 21 Jun 2017 10:08:46 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCIsWRWlGSWpSXmKPExsXS6fjDS3etq1e kwZTd6hbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8bWC6dYC5q2M1a86dzJ1sC4bQpjFyMnh5BA nsTDiyuYQGxeATuJFVNamUFsCQFDidMLb7KA2CwCqhKfdtwGi7MJqEu0PdvO2sXIwSEiYCBx7 mhSFyMXB7PAfyaJ3sVT2EBqhAVCJSYunsQOMd9OYs7TbkaQel4BQYm/O4RBwsxA4Q3PWtgmMH LPQsjMQpKBsLUkHv66xQJha0ssW/iaGaScWUBaYvk/Doiwg8TDYy/ZUJWA2N4SR1/PYF7AyLG KUaM4tagstUjXyFwvqSgzPaMkNzEzR9fQwFgvN7W4ODE9NScxqVgvOT93EyMwNOsZGBh3MLbs 9TvEKMnBpCTKe0HWK1KILyk/pTIjsTgjvqg0J7X4EKMMB4eSBC8nMNSFBItS01Mr0jJzgFECk 5bg4FES4V1mDpTmLS5IzC3OTIdInWJUlBLnXeIClBAASWSU5sG1wSLzEqOslDAvIwMDgxBPQW pRbmYJqvwrRnEORiVh3giQKTyZeSVw018BLWYCWvziiAfI4pJEhJRUA6OW67UoP/6Y8LoZ9sV dKubVvA/4V7yfeK76hM6iVwKHy1fJfjh0f8ICrnqpe7d9diQdjPB8/of/iUhPZeJ+2fdhhpXH Cr/W6KmdKp9yeteFVdIL9z0oen905R3ptOzPigeUftju3RV4gqtnRXJC3ME2pv4972ST4vOEj WMfzAtjYJvGmpgW8E+JpTgj0VCLuag4EQDo89a4xwIAAA== X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-4.tower-31.messagelabs.com!1498039723!48594814!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.19; banners=-,-,- X-VirusChecked: Checked Received: (qmail 12664 invoked from network); 21 Jun 2017 10:08:45 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-4.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 21 Jun 2017 10:08:45 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Wed, 21 Jun 2017 04:08:42 -0600 Message-Id: <594A61C8020000780016515C@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.2 Date: Wed, 21 Jun 2017 04:08:40 -0600 From: "Jan Beulich" To: "xen-devel" References: <594A61C8020000780016515C@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Stefano Stabellini , Wei Liu , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Daniel de Graaf Subject: [Xen-devel] [PATCH] passthrough: give XEN_DOMCTL_test_assign_device more sane semantics X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 is assigned to a particular domain. Ignore the passed in domain ID at the libxc layer instead, in order to not break existing callers. New libxc functions would need to be added if callers wanted to leverage the new functionality. Signed-off-by: Jan Beulich --- TBD: Would DOMID_IO be a better fit than DOMID_INVALID here? passthrough: give XEN_DOMCTL_test_assign_device more sane semantics 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 is assigned to a particular domain. Ignore the passed in domain ID at the libxc layer instead, in order to not break existing callers. New libxc functions would need to be added if callers wanted to leverage the new functionality. Signed-off-by: Jan Beulich --- TBD: Would DOMID_IO be a better fit than DOMID_INVALID here? --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -1539,13 +1539,13 @@ int xc_get_device_group( int xc_test_assign_device( xc_interface *xch, - uint32_t domid, + uint32_t domid, /* ignored */ uint32_t machine_sbdf) { DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_test_assign_device; - domctl.domain = domid; + domctl.domain = DOMID_INVALID; 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; @@ -1603,7 +1603,7 @@ int xc_assign_dt_device( int xc_test_assign_dt_device( xc_interface *xch, - uint32_t domid, + uint32_t domid, /* ignored */ char *path) { int rc; @@ -1615,7 +1615,7 @@ int xc_test_assign_dt_device( return -1; domctl.cmd = XEN_DOMCTL_test_assign_device; - domctl.domain = (domid_t)domid; + domctl.domain = DOMID_INVALID; domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT; domctl.u.assign_device.u.dt.size = size; --- 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 @@ -93,7 +93,8 @@ fail: return rc; } -static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev) +static bool_t iommu_dt_device_is_assigned(const struct domain *d, + const struct dt_device_node *dev) { bool_t assigned = 0; @@ -101,7 +102,8 @@ static bool_t iommu_dt_device_is_assigne return 0; spin_lock(&dtdevs_lock); - assigned = !list_empty(&dev->domain_list); + assigned = d ? dt_device_used_by(dev) == d->domain_id + : !list_empty(&dev->domain_list); spin_unlock(&dtdevs_lock); return assigned; @@ -209,11 +211,11 @@ int iommu_do_dt_domctl(struct xen_domctl if ( ret ) break; - ret = xsm_test_assign_dtdevice(XSM_HOOK, dt_node_full_name(dev)); + ret = xsm_test_assign_dtdevice(XSM_HOOK, d, dt_node_full_name(dev)); if ( ret ) break; - if ( iommu_dt_device_is_assigned(dev) ) + if ( iommu_dt_device_is_assigned(d, dev) ) { printk(XENLOG_G_ERR "%s already assigned.\n", dt_node_full_name(dev)); --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -522,7 +522,7 @@ struct pci_dev *pci_get_real_pdev(int se } struct pci_dev *pci_get_pdev_by_domain( - struct domain *d, int seg, int bus, int devfn) + const struct domain *d, int seg, int bus, int devfn) { struct pci_seg *pseg = get_pseg(seg); struct pci_dev *pdev = NULL; @@ -1337,12 +1337,12 @@ int iommu_remove_device(struct pci_dev * * If the device isn't owned by the hardware domain, it means it already * has been assigned to other domain, or it doesn't exist. */ -static int device_assigned(u16 seg, u8 bus, u8 devfn) +static int device_assigned(const struct domain *d, u16 seg, u8 bus, u8 devfn) { - struct pci_dev *pdev; + const struct pci_dev *pdev; pcidevs_lock(); - pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn); + pdev = pci_get_pdev_by_domain(d ?: hardware_domain, seg, bus, devfn); pcidevs_unlock(); return pdev ? 0 : -EBUSY; @@ -1590,7 +1590,7 @@ int iommu_do_pci_domctl( machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf; - ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf); + ret = xsm_test_assign_device(XSM_HOOK, d, machine_sbdf); if ( ret ) break; @@ -1598,13 +1598,12 @@ int iommu_do_pci_domctl( bus = PCI_BUS(machine_sbdf); devfn = PCI_DEVFN2(machine_sbdf); - if ( device_assigned(seg, bus, devfn) ) - { + ret = device_assigned(d, seg, bus, devfn); + if ( ret && !d ) 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: @@ -1634,7 +1633,7 @@ int iommu_do_pci_domctl( bus = PCI_BUS(machine_sbdf); devfn = PCI_DEVFN2(machine_sbdf); - ret = device_assigned(seg, bus, devfn) ?: + ret = device_assigned(NULL, seg, bus, devfn) ?: assign_device(d, seg, bus, devfn, flags); if ( ret == -ERESTART ) ret = hypercall_create_continuation(__HYPERVISOR_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 a DomU at all. Pass a specific domain ID to + * find out whether the given device is assigned to that domain. + */ /* * XEN_DOMCTL_deassign_device: The behavior of this DOMCTL differs * between the different type of device: --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -125,8 +125,8 @@ int pci_ro_device(int seg, int bus, int int pci_hide_device(int bus, int devfn); struct pci_dev *pci_get_pdev(int seg, int bus, int devfn); struct pci_dev *pci_get_real_pdev(int seg, int bus, int devfn); -struct pci_dev *pci_get_pdev_by_domain( - struct domain *, int seg, int bus, int devfn); +struct pci_dev *pci_get_pdev_by_domain(const struct domain *, + int seg, int bus, int devfn); void pci_check_disable_device(u16 seg, u8 bus, u8 devfn); uint8_t pci_conf_read8( --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -337,10 +337,11 @@ 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) +static XSM_INLINE int xsm_test_assign_device(XSM_DEFAULT_ARG struct domain *d, + uint32_t machine_bdf) { XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, current->domain, NULL); + return xsm_default_action(action, current->domain, d); } static XSM_INLINE int xsm_assign_device(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf) @@ -358,10 +359,11 @@ 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) +static XSM_INLINE int xsm_test_assign_dtdevice(XSM_DEFAULT_ARG struct domain *d, + const char *dtpath) { XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, current->domain, NULL); + return xsm_default_action(action, current->domain, d); } static XSM_INLINE int xsm_assign_dtdevice(XSM_DEFAULT_ARG struct domain *d, --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -109,13 +109,13 @@ 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 (*test_assign_device) (struct domain *d, 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 (*test_assign_dtdevice) (struct domain *d, const char *dtpath); int (*assign_dtdevice) (struct domain *d, const char *dtpath); int (*deassign_dtdevice) (struct domain *d, const char *dtpath); #endif @@ -465,9 +465,9 @@ 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) +static inline int xsm_test_assign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) { - return xsm_ops->test_assign_device(machine_bdf); + return xsm_ops->test_assign_device(d, machine_bdf); } static inline int xsm_assign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) @@ -488,10 +488,10 @@ 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, +static inline int xsm_test_assign_dtdevice(xsm_default_t def, struct domain *d, const char *dtpath) { - return xsm_ops->test_assign_dtdevice(dtpath); + return xsm_ops->test_assign_dtdevice(d, dtpath); } static inline int xsm_deassign_dtdevice(xsm_default_t def, struct domain *d, --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1260,7 +1260,7 @@ static int flask_get_device_group(uint32 return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); } -static int flask_test_assign_device(uint32_t machine_bdf) +static int flask_test_assign_device(struct domain *d, uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; @@ -1314,7 +1314,7 @@ static int flask_deassign_device(struct #endif /* HAS_PASSTHROUGH && HAS_PCI */ #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE) -static int flask_test_assign_dtdevice(const char *dtpath) +static int flask_test_assign_dtdevice(struct domain *d, const char *dtpath) { u32 rsid; int rc = -EPERM; --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -1539,13 +1539,13 @@ int xc_get_device_group( int xc_test_assign_device( xc_interface *xch, - uint32_t domid, + uint32_t domid, /* ignored */ uint32_t machine_sbdf) { DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_test_assign_device; - domctl.domain = domid; + domctl.domain = DOMID_INVALID; 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; @@ -1603,7 +1603,7 @@ int xc_assign_dt_device( int xc_test_assign_dt_device( xc_interface *xch, - uint32_t domid, + uint32_t domid, /* ignored */ char *path) { int rc; @@ -1615,7 +1615,7 @@ int xc_test_assign_dt_device( return -1; domctl.cmd = XEN_DOMCTL_test_assign_device; - domctl.domain = (domid_t)domid; + domctl.domain = DOMID_INVALID; domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT; domctl.u.assign_device.u.dt.size = size; --- 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 @@ -93,7 +93,8 @@ fail: return rc; } -static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev) +static bool_t iommu_dt_device_is_assigned(const struct domain *d, + const struct dt_device_node *dev) { bool_t assigned = 0; @@ -101,7 +102,8 @@ static bool_t iommu_dt_device_is_assigne return 0; spin_lock(&dtdevs_lock); - assigned = !list_empty(&dev->domain_list); + assigned = d ? dt_device_used_by(dev) == d->domain_id + : !list_empty(&dev->domain_list); spin_unlock(&dtdevs_lock); return assigned; @@ -209,11 +211,11 @@ int iommu_do_dt_domctl(struct xen_domctl if ( ret ) break; - ret = xsm_test_assign_dtdevice(XSM_HOOK, dt_node_full_name(dev)); + ret = xsm_test_assign_dtdevice(XSM_HOOK, d, dt_node_full_name(dev)); if ( ret ) break; - if ( iommu_dt_device_is_assigned(dev) ) + if ( iommu_dt_device_is_assigned(d, dev) ) { printk(XENLOG_G_ERR "%s already assigned.\n", dt_node_full_name(dev)); --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -522,7 +522,7 @@ struct pci_dev *pci_get_real_pdev(int se } struct pci_dev *pci_get_pdev_by_domain( - struct domain *d, int seg, int bus, int devfn) + const struct domain *d, int seg, int bus, int devfn) { struct pci_seg *pseg = get_pseg(seg); struct pci_dev *pdev = NULL; @@ -1337,12 +1337,12 @@ int iommu_remove_device(struct pci_dev * * If the device isn't owned by the hardware domain, it means it already * has been assigned to other domain, or it doesn't exist. */ -static int device_assigned(u16 seg, u8 bus, u8 devfn) +static int device_assigned(const struct domain *d, u16 seg, u8 bus, u8 devfn) { - struct pci_dev *pdev; + const struct pci_dev *pdev; pcidevs_lock(); - pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn); + pdev = pci_get_pdev_by_domain(d ?: hardware_domain, seg, bus, devfn); pcidevs_unlock(); return pdev ? 0 : -EBUSY; @@ -1590,7 +1590,7 @@ int iommu_do_pci_domctl( machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf; - ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf); + ret = xsm_test_assign_device(XSM_HOOK, d, machine_sbdf); if ( ret ) break; @@ -1598,13 +1598,12 @@ int iommu_do_pci_domctl( bus = PCI_BUS(machine_sbdf); devfn = PCI_DEVFN2(machine_sbdf); - if ( device_assigned(seg, bus, devfn) ) - { + ret = device_assigned(d, seg, bus, devfn); + if ( ret && !d ) 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: @@ -1634,7 +1633,7 @@ int iommu_do_pci_domctl( bus = PCI_BUS(machine_sbdf); devfn = PCI_DEVFN2(machine_sbdf); - ret = device_assigned(seg, bus, devfn) ?: + ret = device_assigned(NULL, seg, bus, devfn) ?: assign_device(d, seg, bus, devfn, flags); if ( ret == -ERESTART ) ret = hypercall_create_continuation(__HYPERVISOR_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 a DomU at all. Pass a specific domain ID to + * find out whether the given device is assigned to that domain. + */ /* * XEN_DOMCTL_deassign_device: The behavior of this DOMCTL differs * between the different type of device: --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -125,8 +125,8 @@ int pci_ro_device(int seg, int bus, int int pci_hide_device(int bus, int devfn); struct pci_dev *pci_get_pdev(int seg, int bus, int devfn); struct pci_dev *pci_get_real_pdev(int seg, int bus, int devfn); -struct pci_dev *pci_get_pdev_by_domain( - struct domain *, int seg, int bus, int devfn); +struct pci_dev *pci_get_pdev_by_domain(const struct domain *, + int seg, int bus, int devfn); void pci_check_disable_device(u16 seg, u8 bus, u8 devfn); uint8_t pci_conf_read8( --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -337,10 +337,11 @@ 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) +static XSM_INLINE int xsm_test_assign_device(XSM_DEFAULT_ARG struct domain *d, + uint32_t machine_bdf) { XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, current->domain, NULL); + return xsm_default_action(action, current->domain, d); } static XSM_INLINE int xsm_assign_device(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf) @@ -358,10 +359,11 @@ 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) +static XSM_INLINE int xsm_test_assign_dtdevice(XSM_DEFAULT_ARG struct domain *d, + const char *dtpath) { XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, current->domain, NULL); + return xsm_default_action(action, current->domain, d); } static XSM_INLINE int xsm_assign_dtdevice(XSM_DEFAULT_ARG struct domain *d, --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -109,13 +109,13 @@ 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 (*test_assign_device) (struct domain *d, 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 (*test_assign_dtdevice) (struct domain *d, const char *dtpath); int (*assign_dtdevice) (struct domain *d, const char *dtpath); int (*deassign_dtdevice) (struct domain *d, const char *dtpath); #endif @@ -465,9 +465,9 @@ 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) +static inline int xsm_test_assign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) { - return xsm_ops->test_assign_device(machine_bdf); + return xsm_ops->test_assign_device(d, machine_bdf); } static inline int xsm_assign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) @@ -488,10 +488,10 @@ 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, +static inline int xsm_test_assign_dtdevice(xsm_default_t def, struct domain *d, const char *dtpath) { - return xsm_ops->test_assign_dtdevice(dtpath); + return xsm_ops->test_assign_dtdevice(d, dtpath); } static inline int xsm_deassign_dtdevice(xsm_default_t def, struct domain *d, --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1260,7 +1260,7 @@ static int flask_get_device_group(uint32 return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); } -static int flask_test_assign_device(uint32_t machine_bdf) +static int flask_test_assign_device(struct domain *d, uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; @@ -1314,7 +1314,7 @@ static int flask_deassign_device(struct #endif /* HAS_PASSTHROUGH && HAS_PCI */ #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_DEVICE_TREE) -static int flask_test_assign_dtdevice(const char *dtpath) +static int flask_test_assign_dtdevice(struct domain *d, const char *dtpath) { u32 rsid; int rc = -EPERM;