diff mbox

[Xen-devel,RFC,09/14] xen/xsm: flask: MSI is PCI specific

Message ID 1394640969-25583-10-git-send-email-julien.grall@linaro.org
State Accepted, archived
Commit e19ec6c49b72574e4a12b8f30f78306e69328cb4
Headers show

Commit Message

Julien Grall March 12, 2014, 4:16 p.m. UTC
MSI is not yet support on ARM and will break the compilation when XSM_ENABLE=y.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 xen/xsm/flask/hooks.c |   72 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 52 insertions(+), 20 deletions(-)

Comments

Daniel De Graaf March 13, 2014, 2:34 p.m. UTC | #1
On 03/12/2014 12:16 PM, Julien Grall wrote:
> MSI is not yet support on ARM and will break the compilation when XSM_ENABLE=y.
>
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>

I am assuming that IRQs on ARM are generally allocated in a static manner for
a given board, so that a security policy based on their numeric values would
be effective. If IRQs above nr_static_irqs are dynamic as on x86, it may be
necessary to resolve them in some way. Since this resolution would naturally
be split into a separate patch, in either case this patch is

Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>

> ---
>   xen/xsm/flask/hooks.c |   72 +++++++++++++++++++++++++++++++++++--------------
>   1 file changed, 52 insertions(+), 20 deletions(-)
>
> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
> index 65343f3..56c7645 100644
> --- a/xen/xsm/flask/hooks.c
> +++ b/xen/xsm/flask/hooks.c
> @@ -19,7 +19,9 @@
>   #include <xen/errno.h>
>   #include <xen/guest_access.h>
>   #include <xen/xenoprof.h>
> +#ifdef HAS_PCI
>   #include <asm/msi.h>
> +#endif
>   #include <public/xen.h>
>   #include <public/physdev.h>
>   #include <public/platform.h>
> @@ -100,7 +102,6 @@ static int domain_has_xen(struct domain *d, u32 perms)
>
>   static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad)
>   {
> -    struct irq_desc *desc = irq_to_desc(irq);
>       if ( irq >= nr_irqs || irq < 0 )
>           return -EINVAL;
>       if ( irq < nr_static_irqs ) {
> @@ -110,15 +111,21 @@ static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad)
>           }
>           return security_irq_sid(irq, sid);
>       }
> -    if ( desc->msi_desc && desc->msi_desc->dev ) {
> -        struct pci_dev *dev = desc->msi_desc->dev;
> -        u32 sbdf = (dev->seg << 16) | (dev->bus << 8) | dev->devfn;
> -        if (ad) {
> -            AVC_AUDIT_DATA_INIT(ad, DEV);
> -            ad->device = sbdf;
> +#ifdef HAS_PCI
> +    {
> +        struct irq_desc *desc = irq_to_desc(irq);
> +        if ( desc->msi_desc && desc->msi_desc->dev ) {
> +            struct pci_dev *dev = desc->msi_desc->dev;
> +            u32 sbdf = (dev->seg << 16) | (dev->bus << 8) | dev->devfn;
> +            if (ad) {
> +                AVC_AUDIT_DATA_INIT(ad, DEV);
> +                ad->device = sbdf;
> +            }
> +            return security_device_sid(sbdf, sid);
>           }
> -        return security_device_sid(sbdf, sid);
>       }
> +#endif
> +
>       if (ad) {
>           AVC_AUDIT_DATA_INIT(ad, IRQ);
>           ad->irq = irq;
> @@ -825,21 +832,34 @@ static int flask_map_domain_pirq (struct domain *d)
>       return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
>   }
>
> +static int flask_map_domain_msi (struct domain *d, int irq, void *data,
> +                                 u32 *sid, struct avc_audit_data *ad)
> +{
> +#ifdef HAS_PCI
> +    struct msi_info *msi = data;
> +
> +    u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
> +    AVC_AUDIT_DATA_INIT(ad, DEV);
> +    ad->device = machine_bdf;
> +
> +    return security_device_sid(machine_bdf, sid);
> +#else
> +    return -EINVAL;
> +#endif
> +}
> +
>   static int flask_map_domain_irq (struct domain *d, int irq, void *data)
>   {
>       u32 sid, dsid;
>       int rc = -EPERM;
> -    struct msi_info *msi = data;
>       struct avc_audit_data ad;
>
> -    if ( irq >= nr_static_irqs && msi ) {
> -        u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
> -        AVC_AUDIT_DATA_INIT(&ad, DEV);
> -        ad.device = machine_bdf;
> -        rc = security_device_sid(machine_bdf, &sid);
> +    if ( irq >= nr_static_irqs && data ) {
> +        rc = flask_map_domain_msi(d, irq, data, &sid, &ad);
>       } else {
>           rc = get_irq_sid(irq, &sid, &ad);
>       }
> +
>       if ( rc )
>           return rc;
>
> @@ -858,18 +878,30 @@ static int flask_unmap_domain_pirq (struct domain *d)
>       return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
>   }
>
> +static int flask_unmap_domain_msi (struct domain *d, int irq, void *data,
> +                                   u32 *sid, struct avc_audit_data *ad)
> +{
> +#ifdef HAS_PCI
> +    struct msi_info *msi = data;
> +    u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
> +
> +    AVC_AUDIT_DATA_INIT(ad, DEV);
> +    ad->device = machine_bdf;
> +
> +    return security_device_sid(machine_bdf, sid);
> +#else
> +    return -EINVAL;
> +#endif
> +}
> +
>   static int flask_unmap_domain_irq (struct domain *d, int irq, void *data)
>   {
>       u32 sid;
>       int rc = -EPERM;
> -    struct msi_info *msi = data;
>       struct avc_audit_data ad;
>
> -    if ( irq >= nr_static_irqs && msi ) {
> -        u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
> -        AVC_AUDIT_DATA_INIT(&ad, DEV);
> -        ad.device = machine_bdf;
> -        rc = security_device_sid(machine_bdf, &sid);
> +    if ( irq >= nr_static_irqs && data ) {
> +        rc = flask_unmap_domain_msi(d, irq, data, &sid, &ad);
>       } else {
>           rc = get_irq_sid(irq, &sid, &ad);
>       }
>
Julien Grall March 13, 2014, 2:40 p.m. UTC | #2
Hello Daniel,

Thanks for your review.

On 03/13/2014 02:34 PM, Daniel De Graaf wrote:
> On 03/12/2014 12:16 PM, Julien Grall wrote:
>> MSI is not yet support on ARM and will break the compilation when
>> XSM_ENABLE=y.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> 
> I am assuming that IRQs on ARM are generally allocated in a static
> manner for
> a given board, so that a security policy based on their numeric values
> would
> be effective. If IRQs above nr_static_irqs are dynamic as on x86, it may be
> necessary to resolve them in some way. Since this resolution would
> naturally
> be split into a separate patch, in either case this patch is

Right, nr_static_irqs is set to 1024 on ARM. For now every IRQs, are not
higher than this number.

Regards,
Ian Campbell March 14, 2014, 5:25 p.m. UTC | #3
On Thu, 2014-03-13 at 14:40 +0000, Julien Grall wrote:
> Hello Daniel,
> 
> Thanks for your review.
> 
> On 03/13/2014 02:34 PM, Daniel De Graaf wrote:
> > On 03/12/2014 12:16 PM, Julien Grall wrote:
> >> MSI is not yet support on ARM and will break the compilation when
> >> XSM_ENABLE=y.
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> > 
> > I am assuming that IRQs on ARM are generally allocated in a static
> > manner for
> > a given board, so that a security policy based on their numeric values
> > would
> > be effective. If IRQs above nr_static_irqs are dynamic as on x86, it may be
> > necessary to resolve them in some way. Since this resolution would
> > naturally
> > be split into a separate patch, in either case this patch is
> 
> Right, nr_static_irqs is set to 1024 on ARM. For now every IRQs, are not
> higher than this number.

This will change before long though. Would HAVE_MSI_IRQS be a better
name for this particular arch-configurable? After all PCI without MSI is
plausible isn't it? (well, maybe not in the modern world)

Ian
Julien Grall March 14, 2014, 6:15 p.m. UTC | #4
Hi Ian,

On 03/14/2014 05:25 PM, Ian Campbell wrote:
> On Thu, 2014-03-13 at 14:40 +0000, Julien Grall wrote:
>>
>> Right, nr_static_irqs is set to 1024 on ARM. For now every IRQs, are not
>> higher than this number.
> 
> This will change before long though. Would HAVE_MSI_IRQS be a better
> name for this particular arch-configurable? After all PCI without MSI is
> plausible isn't it? (well, maybe not in the modern world)

Most of PCI passthrough code is relying that MSI is also implemented.
Futhermore, I think the plan for ARM is to support both PCI and MSI.
That's why I chose HAS_PCI.

Regards,
Ian Campbell March 17, 2014, 10:13 a.m. UTC | #5
On Fri, 2014-03-14 at 18:15 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 03/14/2014 05:25 PM, Ian Campbell wrote:
> > On Thu, 2014-03-13 at 14:40 +0000, Julien Grall wrote:
> >>
> >> Right, nr_static_irqs is set to 1024 on ARM. For now every IRQs, are not
> >> higher than this number.
> > 
> > This will change before long though. Would HAVE_MSI_IRQS be a better
> > name for this particular arch-configurable? After all PCI without MSI is
> > plausible isn't it? (well, maybe not in the modern world)
> 
> Most of PCI passthrough code is relying that MSI is also implemented.
> Futhermore, I think the plan for ARM is to support both PCI and MSI.

Right, but we might get PCI support first and separately I think?

> That's why I chose HAS_PCI.

I suppose we can revisit it easily enough if it causes problems.

Ian.
Julien Grall March 17, 2014, 12:05 p.m. UTC | #6
Hi Ian,

On 03/17/2014 10:13 AM, Ian Campbell wrote:
> On Fri, 2014-03-14 at 18:15 +0000, Julien Grall wrote:
>> Hi Ian,
>>
>> On 03/14/2014 05:25 PM, Ian Campbell wrote:
>>> On Thu, 2014-03-13 at 14:40 +0000, Julien Grall wrote:
>>>>
>>>> Right, nr_static_irqs is set to 1024 on ARM. For now every IRQs, are not
>>>> higher than this number.
>>>
>>> This will change before long though. Would HAVE_MSI_IRQS be a better
>>> name for this particular arch-configurable? After all PCI without MSI is
>>> plausible isn't it? (well, maybe not in the modern world)
>>
>> Most of PCI passthrough code is relying that MSI is also implemented.
>> Futhermore, I think the plan for ARM is to support both PCI and MSI.
> 
> Right, but we might get PCI support first and separately I think?

Good question, I though it's better to come with PCI and MSI support at
the time.

>> That's why I chose HAS_PCI.
> 
> I suppose we can revisit it easily enough if it causes problems.

If we implement first PCI, we might need to modify a couple of other
place in Xen. I think we can delay HAS_MSI_IRQS and see if we really
need it.

Regards,
diff mbox

Patch

diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 65343f3..56c7645 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -19,7 +19,9 @@ 
 #include <xen/errno.h>
 #include <xen/guest_access.h>
 #include <xen/xenoprof.h>
+#ifdef HAS_PCI
 #include <asm/msi.h>
+#endif
 #include <public/xen.h>
 #include <public/physdev.h>
 #include <public/platform.h>
@@ -100,7 +102,6 @@  static int domain_has_xen(struct domain *d, u32 perms)
 
 static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad)
 {
-    struct irq_desc *desc = irq_to_desc(irq);
     if ( irq >= nr_irqs || irq < 0 )
         return -EINVAL;
     if ( irq < nr_static_irqs ) {
@@ -110,15 +111,21 @@  static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad)
         }
         return security_irq_sid(irq, sid);
     }
-    if ( desc->msi_desc && desc->msi_desc->dev ) {
-        struct pci_dev *dev = desc->msi_desc->dev;
-        u32 sbdf = (dev->seg << 16) | (dev->bus << 8) | dev->devfn;
-        if (ad) {
-            AVC_AUDIT_DATA_INIT(ad, DEV);
-            ad->device = sbdf;
+#ifdef HAS_PCI
+    {
+        struct irq_desc *desc = irq_to_desc(irq);
+        if ( desc->msi_desc && desc->msi_desc->dev ) {
+            struct pci_dev *dev = desc->msi_desc->dev;
+            u32 sbdf = (dev->seg << 16) | (dev->bus << 8) | dev->devfn;
+            if (ad) {
+                AVC_AUDIT_DATA_INIT(ad, DEV);
+                ad->device = sbdf;
+            }
+            return security_device_sid(sbdf, sid);
         }
-        return security_device_sid(sbdf, sid);
     }
+#endif
+
     if (ad) {
         AVC_AUDIT_DATA_INIT(ad, IRQ);
         ad->irq = irq;
@@ -825,21 +832,34 @@  static int flask_map_domain_pirq (struct domain *d)
     return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
 }
 
+static int flask_map_domain_msi (struct domain *d, int irq, void *data,
+                                 u32 *sid, struct avc_audit_data *ad)
+{
+#ifdef HAS_PCI
+    struct msi_info *msi = data;
+
+    u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
+    AVC_AUDIT_DATA_INIT(ad, DEV);
+    ad->device = machine_bdf;
+
+    return security_device_sid(machine_bdf, sid);
+#else
+    return -EINVAL;
+#endif
+}
+
 static int flask_map_domain_irq (struct domain *d, int irq, void *data)
 {
     u32 sid, dsid;
     int rc = -EPERM;
-    struct msi_info *msi = data;
     struct avc_audit_data ad;
 
-    if ( irq >= nr_static_irqs && msi ) {
-        u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
-        AVC_AUDIT_DATA_INIT(&ad, DEV);
-        ad.device = machine_bdf;
-        rc = security_device_sid(machine_bdf, &sid);
+    if ( irq >= nr_static_irqs && data ) {
+        rc = flask_map_domain_msi(d, irq, data, &sid, &ad);
     } else {
         rc = get_irq_sid(irq, &sid, &ad);
     }
+
     if ( rc )
         return rc;
 
@@ -858,18 +878,30 @@  static int flask_unmap_domain_pirq (struct domain *d)
     return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
 }
 
+static int flask_unmap_domain_msi (struct domain *d, int irq, void *data,
+                                   u32 *sid, struct avc_audit_data *ad)
+{
+#ifdef HAS_PCI
+    struct msi_info *msi = data;
+    u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
+
+    AVC_AUDIT_DATA_INIT(ad, DEV);
+    ad->device = machine_bdf;
+
+    return security_device_sid(machine_bdf, sid);
+#else
+    return -EINVAL;
+#endif
+}
+
 static int flask_unmap_domain_irq (struct domain *d, int irq, void *data)
 {
     u32 sid;
     int rc = -EPERM;
-    struct msi_info *msi = data;
     struct avc_audit_data ad;
 
-    if ( irq >= nr_static_irqs && msi ) {
-        u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
-        AVC_AUDIT_DATA_INIT(&ad, DEV);
-        ad.device = machine_bdf;
-        rc = security_device_sid(machine_bdf, &sid);
+    if ( irq >= nr_static_irqs && data ) {
+        rc = flask_unmap_domain_msi(d, irq, data, &sid, &ad);
     } else {
         rc = get_irq_sid(irq, &sid, &ad);
     }