[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq



On Tue, 13 Jan 2015, Julien Grall wrote:
> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
> assign/deassign a physical IRQ to the guest (via the config options "irqs"
> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
> channel). As ARM doesn't have a such concept, we could reuse it to bound
> a physical IRQ to a virtual IRQ.
> 
> For now, we allow only SPIs to be mapped to the guest.
> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> 
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
> Cc: Jan Beulich <jbeulich@xxxxxxxx>
> 
> ---
>     I'm not sure it's the best solution to reuse hypercalls for a
>     different purpose. If x86 plan to have a such concept (i.e binding a
>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>     Any thoughs?

I think it is OK, as long as we write down very clearly what we are
doing.


>     TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
>     handle it correctly on the next version.

Why do you say that? From the code in this patch it looks like it
supports vIRQ != IRQ already.


>     Changes in v3:
>         - Functions to allocate/release/reserved a VIRQ has been moved
>         in a separate patch

That might be a good idea, but then you need to move that patch before
this one, otherwise it won't compile. As is it would break the build.


>         - 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
> ---
>  xen/arch/arm/physdev.c | 136 
> ++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 134 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c
> index 61b4a18..0cf9bbd 100644
> --- a/xen/arch/arm/physdev.c
> +++ b/xen/arch/arm/physdev.c
> @@ -8,13 +8,145 @@
>  #include <xen/types.h>
>  #include <xen/lib.h>
>  #include <xen/errno.h>
> +#include <xen/iocap.h>
> +#include <xen/guest_access.h>
> +#include <xsm/xsm.h>
> +#include <asm/current.h>
>  #include <asm/hypercall.h>
> +#include <public/physdev.h>
>  
> +static int physdev_map_pirq(domid_t domid, int type, int index, int *pirq_p)
> +{
> +    struct domain *d;
> +    int ret;
> +    int irq = index;
> +    int virq;
> +
> +    d = rcu_lock_domain_by_any_id(domid);
> +    if ( d == NULL )
> +        return -ESRCH;
> +
> +    ret = xsm_map_domain_pirq(XSM_TARGET, d);
> +    if ( ret )
> +        goto free_domain;
> +
> +    /* For now we only suport GSI */
> +    if ( type != MAP_PIRQ_TYPE_GSI )
> +    {
> +        ret = -EINVAL;
> +        dprintk(XENLOG_G_ERR,
> +                "dom%u: wrong map_pirq type 0x%x, only MAP_PIRQ_TYPE_GSI is 
> supported.\n",
> +                d->domain_id, type);
> +        goto free_domain;
> +    }
> +
> +    if ( !is_assignable_irq(irq) )
> +    {
> +        ret = -EINVAL;
> +        dprintk(XENLOG_G_ERR, "IRQ%u is not routable to a guest\n", irq);
> +        goto free_domain;
> +    }
> +
> +    ret = -EPERM;
> +    if ( !irq_access_permitted(current->domain, irq) )
> +        goto free_domain;
> +
> +    if ( *pirq_p < 0 )
> +    {



> +        BUG_ON(irq < 16);   /* is_assignable_irq already denies SGIs */
> +        virq = vgic_allocate_virq(d, (irq >= 32));
> +
> +        ret = -ENOSPC;
> +        if ( virq < 0 )
> +            goto free_domain;
> +    }
> +    else
> +    {
> +        ret = -EBUSY;
> +        virq = *pirq_p;
> +
> +        if ( !vgic_reserve_virq(d, virq) )
> +            goto free_domain;
> +    }
> +
> +    gdprintk(XENLOG_DEBUG, "irq = %u virq = %u\n", irq, virq);
> +
> +    ret = route_irq_to_guest(d, virq, irq, "routed IRQ");
> +
> +    if ( !ret )
> +        *pirq_p = virq;
> +    else
> +        vgic_free_virq(d, virq);
> +
> +free_domain:
> +    rcu_unlock_domain(d);
> +
> +    return ret;
> +}
> +
> +int physdev_unmap_pirq(domid_t domid, int pirq)
> +{
> +    struct domain *d;
> +    int ret;
> +
> +    d = rcu_lock_domain_by_any_id(domid);
> +    if ( d == NULL )
> +        return -ESRCH;
> +
> +    ret = xsm_unmap_domain_pirq(XSM_TARGET, d);
> +    if ( ret )
> +        goto free_domain;
> +
> +    ret = release_guest_irq(d, pirq);
> +    if ( ret )
> +        goto free_domain;
> +
> +    vgic_free_virq(d, pirq);
> +
> +free_domain:
> +    rcu_unlock_domain(d);
> +
> +    return ret;
> +}
>  
>  int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>  {
> -    printk("%s %d cmd=%d: not implemented yet\n", __func__, __LINE__, cmd);
> -    return -ENOSYS;
> +    int ret;
> +
> +    switch ( cmd )
> +    {
> +    case PHYSDEVOP_map_pirq:
> +        {
> +            physdev_map_pirq_t map;
> +
> +            ret = -EFAULT;
> +            if ( copy_from_guest(&map, arg, 1) != 0 )
> +                break;
> +
> +            ret = physdev_map_pirq(map.domid, map.type, map.index, 
> &map.pirq);
> +
> +            if ( __copy_to_guest(arg, &map, 1) )
> +                ret = -EFAULT;
> +        }
> +        break;
> +
> +    case PHYSDEVOP_unmap_pirq:
> +        {
> +            physdev_unmap_pirq_t unmap;
> +
> +            ret = -EFAULT;
> +            if ( copy_from_guest(&unmap, arg, 1) != 0 )
> +                break;
> +
> +            ret = physdev_unmap_pirq(unmap.domid, unmap.pirq);
> +        }
> +
> +    default:
> +        ret = -ENOSYS;
> +        break;
> +    }
> +
> +    return ret;
>  }
>  
>  /*
> -- 
> 2.1.4
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.