From patchwork Tue Apr 28 14:32:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 47672 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 8F7492121F for ; Tue, 28 Apr 2015 14:34:54 +0000 (UTC) Received: by wixv7 with SMTP id v7sf6395647wix.0 for ; Tue, 28 Apr 2015 07:34:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:cc:subject:precedence:list-id :list-unsubscribe:list-post:list-help:list-subscribe:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=6Nrb74DLKGdwrpC4P0GMCD6lvtBn3s2ztUzi7kB5Gk4=; b=CoJFk5zWT4NxeZdGQ389fO/ymNerFm+1GrjMaoom8kdSA3WWKRC38aIQufQLZJufRA upH4DfIqPhIJ9MyKIBoJ+Z5XniUQqLXKWBf7lNMaB/u1j1NMrOOrSCVDWlvKn+M4QzPz mgdi+lKscsMexxX6r9Jaee3z5FP+cPKi4utvrwXQAP0S13J3jRrX08x8+nhNBqLsulu2 /ynB+8ZgJMvJLQ5IbqYk0nvagQvYP9eBC/1n5oayGewCKITFdh2l2R9FTY38mmiHBPjL zSXo23Pss1hpIfelnYbfPaOJuaCEkmRavaySSEwJWe16jFAsZDb9vuEDtJlW4LO2aphP DUmg== X-Gm-Message-State: ALoCoQl995crs2/kW9czHhOvhXQbklqwQG+6ad3WLSQtxCLuxDgLLxT4AyuteJdQSd/7heB/HR0J X-Received: by 10.194.143.98 with SMTP id sd2mr10450439wjb.6.1430231693917; Tue, 28 Apr 2015 07:34:53 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.121.98 with SMTP id lj2ls76865lab.94.gmail; Tue, 28 Apr 2015 07:34:53 -0700 (PDT) X-Received: by 10.112.150.100 with SMTP id uh4mr14544962lbb.112.1430231693779; Tue, 28 Apr 2015 07:34:53 -0700 (PDT) Received: from mail-la0-f54.google.com (mail-la0-f54.google.com. [209.85.215.54]) by mx.google.com with ESMTPS id pd4si17201858lbc.40.2015.04.28.07.34.53 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Apr 2015 07:34:53 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.54 as permitted sender) client-ip=209.85.215.54; Received: by laat2 with SMTP id t2so105930441laa.1 for ; Tue, 28 Apr 2015 07:34:53 -0700 (PDT) X-Received: by 10.152.4.72 with SMTP id i8mr3543254lai.32.1430231693615; Tue, 28 Apr 2015 07:34:53 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.67.65 with SMTP id l1csp1924123lbt; Tue, 28 Apr 2015 07:34:52 -0700 (PDT) X-Received: by 10.52.179.71 with SMTP id de7mr5505776vdc.37.1430231683684; Tue, 28 Apr 2015 07:34:43 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id cz17si35246255vdb.38.2015.04.28.07.34.42 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 28 Apr 2015 07:34:43 -0700 (PDT) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Yn6Zp-0007mg-Nx; Tue, 28 Apr 2015 14:33:33 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Yn6Zn-0007lf-NY for xen-devel@lists.xenproject.org; Tue, 28 Apr 2015 14:33:32 +0000 Received: from [85.158.139.211] by server-7.bemta-5.messagelabs.com id B8/E2-02028-A3A9F355; Tue, 28 Apr 2015 14:33:30 +0000 X-Env-Sender: julien.grall@citrix.com X-Msg-Ref: server-16.tower-206.messagelabs.com!1430231604!8366589!5 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 6.13.14; banners=-,-,- X-VirusChecked: Checked Received: (qmail 21969 invoked from network); 28 Apr 2015 14:33:29 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-16.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 28 Apr 2015 14:33:29 -0000 X-IronPort-AV: E=Sophos;i="5.11,663,1422921600"; d="scan'208";a="257345546" From: Julien Grall To: Date: Tue, 28 Apr 2015 15:32:28 +0100 Message-ID: <1430231563-25648-5-git-send-email-julien.grall@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1430231563-25648-1-git-send-email-julien.grall@citrix.com> References: <1430231563-25648-1-git-send-email-julien.grall@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: ian.campbell@citrix.com, Julien Grall , tim@xen.org, stefano.stabellini@citrix.com, Jan Beulich , Daniel De Graaf Subject: [Xen-devel] [PATCH v6 04/19] xen/arm: Implement hypercall DOMCTL_{, un}bind_pt_pirq X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: patch@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.54 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: From: Julien Grall On x86, an IRQ is assigned in 2 steps to an HVM guest: - The toolstack is calling PHYSDEVOP_map_pirq in order to create a guest PIRQ (IRQ bound to an event channel) - The emulator (QEMU) is calling DOMCTL_bind_pt_irq in order to bind the IRQ On ARM, there is no concept of PIRQ as the IRQ can be assigned to a virtual IRQ using the interrupt controller. It's not clear if we will need 2 different hypercalls on ARM to assign IRQ and, for now, only the toolstack will manage IRQ. In order to avoid re-using a fixed ABI hypercall (PHYSDEVOP_*) for a different purpose and allow us more time to figure out the right out, only DOMCTL_{,un}bind_pt_pirq is implemented on ARM. The DOMCTL is extended with a new type PT_IRQ_TYPE_SPI and only IRQ == vIRQ (i.e machine_irq == spi) is supported. In order to keep the same XSM checks done by the 2 hypercalls on x86, call both xsm_map_domain_irq & xsm_bind_pt_irq in the ARM implementation. Note: The toolstack changes for routing an IRQ to a guest will be done in a separate patch. Signed-off-by: Julien Grall Acked-by: Daniel De Graaf Cc: Jan Beulich --- Contrawise PHYSDEV, DOMCTL interface is not fixed. This version is using a DOMCTL in order to let us more to to see if we need a new PHYSDEV op for vIRQ assignation. DOMCTL_unbind_pt_irq has been implemented, although I haven't test it. I'm not sure if we want to keep it. xc_domain_{,un}bind_pt_irq are left unchanged because QEMU upstream & traditional are using them. I will send a follow-up series to drop this 2 functions in order to avoid defering this series while awaiting changes pushed for QEMU upstream. Changes in v6: - Rebase on the latest staging (conflict in xsm/flask/hooks.c with memaccess changes) - Remove obsolete paragraph in the commit message - Fix indentation in libxc - Don't rely on vspi == spi in xc_domain_{,un}bind_pt_spi_irq - Typoes in comment - Add Daniel's ack (XSM part) Changes in v5: - Do the check of XSM PHYSDEVOP_map_pirq in the ARM implementation - Left xc_domain_{,un}bind_pt_irq unchanged - Introduce xc_domain_{,un}bind_pt_spi_irq Changes in v4: - Move the implementation from PHYSDEV to DOMCTL. Reuse DOMCTL_{,un}bind_pt_irq for this purpose. Changes in v3: - Functions to allocate/release/reserved a VIRQ has been moved in a separate patch - Make clear that only MAP_PIRQ_GSI is only supported for now Changes in v2: - Add PHYSDEVOP_unmap_pirq - Rework commit message - Add functions to allocate/release a VIRQ - is_routable_irq has been renamed into is_assignable_irq --- tools/libxc/include/xenctrl.h | 10 ++++++ tools/libxc/xc_domain.c | 60 +++++++++++++++++++++++++++++++-- xen/arch/arm/domctl.c | 78 +++++++++++++++++++++++++++++++++++++++++++ xen/include/public/domctl.h | 4 +++ xen/include/xsm/dummy.h | 24 ++++++------- xen/include/xsm/xsm.h | 28 ++++++++-------- xen/xsm/dummy.c | 4 +-- xen/xsm/flask/hooks.c | 70 +++++++++++++++++++------------------- 8 files changed, 213 insertions(+), 65 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 6994c51..517a25f 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2115,6 +2115,16 @@ int xc_domain_bind_pt_isa_irq(xc_interface *xch, uint32_t domid, uint8_t machine_irq); +int xc_domain_bind_pt_spi_irq(xc_interface *xch, + uint32_t domid, + uint16_t vspi, + uint16_t spi); + +int xc_domain_unbind_pt_spi_irq(xc_interface *xch, + uint32_t domid, + uint16_t vspi, + uint16_t spi); + int xc_domain_set_machine_address_size(xc_interface *xch, uint32_t domid, unsigned int width); diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index d1dec6c..3ca9215 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -1797,7 +1797,7 @@ int xc_domain_unbind_msi_irq( } /* Pass-through: binds machine irq to guests irq */ -int xc_domain_bind_pt_irq( +static int xc_domain_bind_pt_irq_int( xc_interface *xch, uint32_t domid, uint8_t machine_irq, @@ -1805,7 +1805,8 @@ int xc_domain_bind_pt_irq( uint8_t bus, uint8_t device, uint8_t intx, - uint8_t isa_irq) + uint8_t isa_irq, + uint16_t spi) { int rc; xen_domctl_bind_pt_irq_t * bind; @@ -1829,6 +1830,9 @@ int xc_domain_bind_pt_irq( case PT_IRQ_TYPE_ISA: bind->u.isa.isa_irq = isa_irq; break; + case PT_IRQ_TYPE_SPI: + bind->u.spi.spi = spi; + break; default: errno = EINVAL; return -1; @@ -1838,7 +1842,7 @@ int xc_domain_bind_pt_irq( return rc; } -int xc_domain_unbind_pt_irq( +int xc_domain_bind_pt_irq( xc_interface *xch, uint32_t domid, uint8_t machine_irq, @@ -1848,6 +1852,21 @@ int xc_domain_unbind_pt_irq( uint8_t intx, uint8_t isa_irq) { + return xc_domain_bind_pt_irq_int(xch, domid, machine_irq, irq_type, + bus, device, intx, isa_irq, 0); +} + +static int xc_domain_unbind_pt_irq_int( + xc_interface *xch, + uint32_t domid, + uint8_t machine_irq, + uint8_t irq_type, + uint8_t bus, + uint8_t device, + uint8_t intx, + uint8_t isa_irq, + uint8_t spi) +{ int rc; xen_domctl_bind_pt_irq_t * bind; DECLARE_DOMCTL; @@ -1870,6 +1889,8 @@ int xc_domain_unbind_pt_irq( case PT_IRQ_TYPE_ISA: bind->u.isa.isa_irq = isa_irq; break; + case PT_IRQ_TYPE_SPI: + bind->u.spi.spi = spi; default: errno = EINVAL; return -1; @@ -1879,6 +1900,20 @@ int xc_domain_unbind_pt_irq( return rc; } +int xc_domain_unbind_pt_irq( + xc_interface *xch, + uint32_t domid, + uint8_t machine_irq, + uint8_t irq_type, + uint8_t bus, + uint8_t device, + uint8_t intx, + uint8_t isa_irq) +{ + return xc_domain_unbind_pt_irq_int(xch, domid, machine_irq, irq_type, + bus, device, intx, isa_irq, 0); +} + int xc_domain_bind_pt_pci_irq( xc_interface *xch, uint32_t domid, @@ -1902,6 +1937,25 @@ int xc_domain_bind_pt_isa_irq( PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq)); } +int xc_domain_bind_pt_spi_irq( + xc_interface *xch, + uint32_t domid, + uint16_t vspi, + uint16_t spi) +{ + return (xc_domain_bind_pt_irq_int(xch, domid, vspi, + PT_IRQ_TYPE_SPI, 0, 0, 0, 0, spi)); +} + +int xc_domain_unbind_pt_spi_irq(xc_interface *xch, + uint32_t domid, + uint16_t vspi, + uint16_t spi) +{ + return (xc_domain_unbind_pt_irq_int(xch, domid, vspi, + PT_IRQ_TYPE_SPI, 0, 0, 0, 0, spi)); +} + int xc_unmap_domain_meminfo(xc_interface *xch, struct xc_domain_meminfo *minfo) { struct domain_info_context _di = { .guest_width = minfo->guest_width, diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c index 6f30af7..4600019 100644 --- a/xen/arch/arm/domctl.c +++ b/xen/arch/arm/domctl.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include long arch_do_domctl(struct xen_domctl *domctl, struct domain *d, @@ -30,6 +32,82 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d, return p2m_cache_flush(d, s, e); } + case XEN_DOMCTL_bind_pt_irq: + { + int rc; + xen_domctl_bind_pt_irq_t *bind = &domctl->u.bind_pt_irq; + uint32_t irq = bind->u.spi.spi; + uint32_t virq = bind->machine_irq; + + /* We only support PT_IRQ_TYPE_SPI */ + if ( bind->irq_type != PT_IRQ_TYPE_SPI ) + return -EOPNOTSUPP; + + /* + * XXX: For now map the interrupt 1:1. Other support will require to + * modify domain_pirq_to_irq macro. + */ + if ( irq != virq ) + return -EINVAL; + + /* + * ARM doesn't require separating IRQ assignation into 2 + * hypercalls (PHYSDEVOP_map_pirq and DOMCTL_bind_pt_irq). + * + * Call xsm_map_domain_irq in order to keep the same XSM checks + * done by the 2 hypercalls for consistency with other + * architectures. + */ + rc = xsm_map_domain_irq(XSM_HOOK, d, irq, NULL); + if ( rc ) + return rc; + + rc = xsm_bind_pt_irq(XSM_HOOK, d, bind); + if ( rc ) + return rc; + + if ( !irq_access_permitted(current->domain, irq) ) + return -EPERM; + + if ( !vgic_reserve_virq(d, virq) ) + return -EBUSY; + + rc = route_irq_to_guest(d, virq, irq, "routed IRQ"); + if ( rc ) + vgic_free_virq(d, virq); + + return rc; + } + case XEN_DOMCTL_unbind_pt_irq: + { + int rc; + xen_domctl_bind_pt_irq_t *bind = &domctl->u.bind_pt_irq; + uint32_t irq = bind->u.spi.spi; + uint32_t virq = bind->machine_irq; + + /* We only support PT_IRQ_TYPE_SPI */ + if ( bind->irq_type != PT_IRQ_TYPE_SPI ) + return -EOPNOTSUPP; + + /* For now map the interrupt 1:1 */ + if ( irq != virq ) + return -EINVAL; + + rc = xsm_unbind_pt_irq(XSM_HOOK, d, bind); + if ( rc ) + return rc; + + if ( !irq_access_permitted(current->domain, irq) ) + return -EPERM; + + rc = release_guest_irq(d, virq); + if ( rc ) + return rc; + + vgic_free_virq(d, virq); + + return 0; + } default: return subarch_do_domctl(domctl, d, u_domctl); } diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 10b51ef..35ed4f2 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -504,6 +504,7 @@ typedef enum pt_irq_type_e { PT_IRQ_TYPE_ISA, PT_IRQ_TYPE_MSI, PT_IRQ_TYPE_MSI_TRANSLATE, + PT_IRQ_TYPE_SPI, /* ARM: valid range 32-1019 */ } pt_irq_type_t; struct xen_domctl_bind_pt_irq { uint32_t machine_irq; @@ -524,6 +525,9 @@ struct xen_domctl_bind_pt_irq { uint32_t gflags; uint64_aligned_t gtable; } msi; + struct { + uint16_t spi; + } spi; } u; }; typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 16967ed..faeb096 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -445,6 +445,18 @@ static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d) return xsm_default_action(action, current->domain, d); } +static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); +} + +static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); +} + static XSM_INLINE int xsm_unmap_domain_irq(XSM_DEFAULT_ARG struct domain *d, int irq, void *data) { XSM_ASSERT_ACTION(XSM_HOOK); @@ -647,18 +659,6 @@ static XSM_INLINE int xsm_priv_mapping(XSM_DEFAULT_ARG struct domain *d, struct return xsm_default_action(action, d, t); } -static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, current->domain, d); -} - -static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, current->domain, d); -} - static XSM_INLINE int xsm_ioport_permission(XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { XSM_ASSERT_ACTION(XSM_HOOK); diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 49f06c9..bbd4a18 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -107,6 +107,8 @@ struct xsm_operations { int (*map_domain_irq) (struct domain *d, int irq, void *data); int (*unmap_domain_pirq) (struct domain *d); int (*unmap_domain_irq) (struct domain *d, int irq, void *data); + int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); + int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*irq_permission) (struct domain *d, int pirq, uint8_t allow); int (*iomem_permission) (struct domain *d, uint64_t s, uint64_t e, uint8_t allow); int (*iomem_mapping) (struct domain *d, uint64_t s, uint64_t e, uint8_t allow); @@ -178,8 +180,6 @@ struct xsm_operations { int (*mmuext_op) (struct domain *d, struct domain *f); int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte); int (*priv_mapping) (struct domain *d, struct domain *t); - int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); - int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); #endif @@ -428,6 +428,18 @@ static inline int xsm_unmap_domain_irq (xsm_default_t def, struct domain *d, int return xsm_ops->unmap_domain_irq(d, irq, data); } +static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d, + struct xen_domctl_bind_pt_irq *bind) +{ + return xsm_ops->bind_pt_irq(d, bind); +} + +static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d, + struct xen_domctl_bind_pt_irq *bind) +{ + return xsm_ops->unbind_pt_irq(d, bind); +} + static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int pirq, uint8_t allow) { return xsm_ops->irq_permission(d, pirq, allow); @@ -666,18 +678,6 @@ static inline int xsm_priv_mapping(xsm_default_t def, struct domain *d, struct d return xsm_ops->priv_mapping(d, t); } -static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d, - struct xen_domctl_bind_pt_irq *bind) -{ - return xsm_ops->bind_pt_irq(d, bind); -} - -static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d, - struct xen_domctl_bind_pt_irq *bind) -{ - return xsm_ops->unbind_pt_irq(d, bind); -} - static inline int xsm_ioport_permission (xsm_default_t def, struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return xsm_ops->ioport_permission(d, s, e, allow); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 3ddb4f6..041ccf9 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -81,6 +81,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, map_domain_irq); set_to_dummy_if_null(ops, unmap_domain_pirq); set_to_dummy_if_null(ops, unmap_domain_irq); + set_to_dummy_if_null(ops, bind_pt_irq); + set_to_dummy_if_null(ops, unbind_pt_irq); set_to_dummy_if_null(ops, irq_permission); set_to_dummy_if_null(ops, iomem_permission); set_to_dummy_if_null(ops, iomem_mapping); @@ -149,8 +151,6 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, mmuext_op); set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, priv_mapping); - set_to_dummy_if_null(ops, bind_pt_irq); - set_to_dummy_if_null(ops, unbind_pt_irq); set_to_dummy_if_null(ops, ioport_permission); set_to_dummy_if_null(ops, ioport_mapping); #endif diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 6215001..29865d2 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -578,12 +578,14 @@ static int flask_domctl(struct domain *d, int cmd) case XEN_DOMCTL_memory_mapping: case XEN_DOMCTL_set_target: case XEN_DOMCTL_vm_event_op: + + /* These have individual XSM hooks (arch/../domctl.c) */ + case XEN_DOMCTL_bind_pt_irq: + case XEN_DOMCTL_unbind_pt_irq: #ifdef CONFIG_X86 /* These have individual XSM hooks (arch/x86/domctl.c) */ case XEN_DOMCTL_shadow_op: case XEN_DOMCTL_ioport_permission: - case XEN_DOMCTL_bind_pt_irq: - case XEN_DOMCTL_unbind_pt_irq: case XEN_DOMCTL_ioport_mapping: /* These have individual XSM hooks (drivers/passthrough/iommu.c) */ case XEN_DOMCTL_get_device_group: @@ -912,6 +914,36 @@ static int flask_unmap_domain_irq (struct domain *d, int irq, void *data) return rc; } +static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + u32 dsid, rsid; + int rc = -EPERM; + int irq; + struct avc_audit_data ad; + + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); + if ( rc ) + return rc; + + irq = domain_pirq_to_irq(d, bind->machine_irq); + + rc = get_irq_sid(irq, &rsid, &ad); + if ( rc ) + return rc; + + rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad); + if ( rc ) + return rc; + + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); +} + +static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); +} + static int flask_irq_permission (struct domain *d, int pirq, uint8_t access) { /* the PIRQ number is not useful; real IRQ is checked during mapping */ @@ -1483,36 +1515,6 @@ static int flask_priv_mapping(struct domain *d, struct domain *t) { return domain_has_perm(d, t, SECCLASS_MMU, MMU__TARGET_HACK); } - -static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - u32 dsid, rsid; - int rc = -EPERM; - int irq; - struct avc_audit_data ad; - - rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); - if ( rc ) - return rc; - - irq = domain_pirq_to_irq(d, bind->machine_irq); - - rc = get_irq_sid(irq, &rsid, &ad); - if ( rc ) - return rc; - - rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad); - if ( rc ) - return rc; - - dsid = domain_sid(d); - return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); -} - -static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); -} #endif /* CONFIG_X86 */ long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); @@ -1571,6 +1573,8 @@ static struct xsm_operations flask_ops = { .map_domain_irq = flask_map_domain_irq, .unmap_domain_pirq = flask_unmap_domain_pirq, .unmap_domain_irq = flask_unmap_domain_irq, + .bind_pt_irq = flask_bind_pt_irq, + .unbind_pt_irq = flask_unbind_pt_irq, .irq_permission = flask_irq_permission, .iomem_permission = flask_iomem_permission, .iomem_mapping = flask_iomem_mapping, @@ -1640,8 +1644,6 @@ static struct xsm_operations flask_ops = { .mmuext_op = flask_mmuext_op, .update_va_mapping = flask_update_va_mapping, .priv_mapping = flask_priv_mapping, - .bind_pt_irq = flask_bind_pt_irq, - .unbind_pt_irq = flask_unbind_pt_irq, .ioport_permission = flask_ioport_permission, .ioport_mapping = flask_ioport_mapping, #endif