diff mbox

[Xen-devel,RFC,06/19] xen/arm: Implement hypercall PHYSDEVOP_map_pirq

Message ID 1402935486-29136-7-git-send-email-julien.grall@linaro.org
State Superseded, archived
Headers show

Commit Message

Julien Grall June 16, 2014, 4:17 p.m. UTC
The physdev sub-hypercall PHYSDEVOP_map_pirq allow the toolstack to route
a physical IRQ to the guest (via the config options "irqs" for xl).
For now, we allow only SPIs to be mapped to the guest.
The type MAP_PIRQ_TYPE_GSI is used for this purpose.

The virtual IRQ number is equal to the physical one. This will avoid adding
logic in Xen to allocate the vIRQ number. The drawbacks is we allocated
unconditionally the same amount of SPIs as the host. This value will never
be more than 1024 with GICv2.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    I'm wondering if we should introduce an alias of MAP_PIRQ_TYPE_GSI
    for ARM. It's will be less confuse for the user.
---
 xen/arch/arm/physdev.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++--
 xen/arch/arm/vgic.c    |    5 +---
 2 files changed, 76 insertions(+), 6 deletions(-)

Comments

Stefano Stabellini June 18, 2014, 7:24 p.m. UTC | #1
On Mon, 16 Jun 2014, Julien Grall wrote:
> The physdev sub-hypercall PHYSDEVOP_map_pirq allow the toolstack to route
> a physical IRQ to the guest (via the config options "irqs" for xl).
> For now, we allow only SPIs to be mapped to the guest.
> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> 
> The virtual IRQ number is equal to the physical one. This will avoid adding
> logic in Xen to allocate the vIRQ number. The drawbacks is we allocated
> unconditionally the same amount of SPIs as the host. This value will never
> be more than 1024 with GICv2.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> ---
>     I'm wondering if we should introduce an alias of MAP_PIRQ_TYPE_GSI
>     for ARM. It's will be less confuse for the user.
> ---
>  xen/arch/arm/physdev.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++--
>  xen/arch/arm/vgic.c    |    5 +---
>  2 files changed, 76 insertions(+), 6 deletions(-)
> 
> diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c
> index 61b4a18..d17589c 100644
> --- a/xen/arch/arm/physdev.c
> +++ b/xen/arch/arm/physdev.c
> @@ -8,13 +8,86 @@
>  #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;
> +
> +    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\n",
> +                d->domain_id, type);
> +        goto free_domain;
> +    }
> +
> +    if ( !is_routable_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;
> +
> +    ret = route_irq_to_guest(d, irq, "routed IRQ");
> +
> +    /* GSIs are mapped 1:1 to the guest */
> +    if ( !ret )
> +        *pirq_p = irq;
> +
> +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;
> +    default:
> +        ret = -ENOSYS;
> +        break;
> +    }
> +
> +    return ret;
>  }
>  
>  /*
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index e451324..c18b2ca 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -82,10 +82,7 @@ int domain_vgic_init(struct domain *d)
>      /* Currently nr_lines in vgic and gic doesn't have the same meanings
>       * Here nr_lines = number of SPIs
>       */
> -    if ( is_hardware_domain(d) )
> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
> -    else
> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
> +    d->arch.vgic.nr_lines = gic_number_lines() - 32;
>  
>      d->arch.vgic.shared_irqs =
>          xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));

I see what you mean about virq != pirq.

It seems to me that setting d->arch.vgic.nr_lines = gic_number_lines() -
32 for the hardware domain is OK, but it is really a waste for the
others. We could find a way to pass down the info about how many SPIs we
need from libxl. Or we could delay the vgic allocations until the first
SPI is assigned to the domU.

Similarly to the MMIO hole sizing, I don't think that it would be a
requirement for this patch series but it is something to keep in mind.
Julien Grall June 19, 2014, 11:39 a.m. UTC | #2
On 06/18/2014 08:24 PM, Stefano Stabellini wrote:
>>  /*
>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>> index e451324..c18b2ca 100644
>> --- a/xen/arch/arm/vgic.c
>> +++ b/xen/arch/arm/vgic.c
>> @@ -82,10 +82,7 @@ int domain_vgic_init(struct domain *d)
>>      /* Currently nr_lines in vgic and gic doesn't have the same meanings
>>       * Here nr_lines = number of SPIs
>>       */
>> -    if ( is_hardware_domain(d) )
>> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
>> -    else
>> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
>> +    d->arch.vgic.nr_lines = gic_number_lines() - 32;
>>  
>>      d->arch.vgic.shared_irqs =
>>          xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
> 
> I see what you mean about virq != pirq.
> 
> It seems to me that setting d->arch.vgic.nr_lines = gic_number_lines() -
> 32 for the hardware domain is OK, but it is really a waste for the
> others. We could find a way to pass down the info about how many SPIs we
> need from libxl. Or we could delay the vgic allocations until the first
> SPI is assigned to the domU.

I gave a check on both midway and the versatile express and there is
about 200 lines.

It make the overhead of less than 8K per domain. Which is not too bad.

If the host really support 1024 IRQs that would make an overhead of ~32K.

> Similarly to the MMIO hole sizing, I don't think that it would be a
> requirement for this patch series but it is something to keep in mind.

Handling virq != pirq will be more complex as we need to take into
account of the hotplug solution.

The vgic has a register which provide the number of lines, I suspect
this number can't grow up while the guest is running.

Regards,
Stefano Stabellini June 19, 2014, 12:29 p.m. UTC | #3
On Thu, 19 Jun 2014, Julien Grall wrote:
> On 06/18/2014 08:24 PM, Stefano Stabellini wrote:
> >>  /*
> >> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> >> index e451324..c18b2ca 100644
> >> --- a/xen/arch/arm/vgic.c
> >> +++ b/xen/arch/arm/vgic.c
> >> @@ -82,10 +82,7 @@ int domain_vgic_init(struct domain *d)
> >>      /* Currently nr_lines in vgic and gic doesn't have the same meanings
> >>       * Here nr_lines = number of SPIs
> >>       */
> >> -    if ( is_hardware_domain(d) )
> >> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
> >> -    else
> >> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
> >> +    d->arch.vgic.nr_lines = gic_number_lines() - 32;
> >>  
> >>      d->arch.vgic.shared_irqs =
> >>          xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
> > 
> > I see what you mean about virq != pirq.
> > 
> > It seems to me that setting d->arch.vgic.nr_lines = gic_number_lines() -
> > 32 for the hardware domain is OK, but it is really a waste for the
> > others. We could find a way to pass down the info about how many SPIs we
> > need from libxl. Or we could delay the vgic allocations until the first
> > SPI is assigned to the domU.
> 
> I gave a check on both midway and the versatile express and there is
> about 200 lines.
> 
> It make the overhead of less than 8K per domain. Which is not too bad.
> 
> If the host really support 1024 IRQs that would make an overhead of ~32K.
> 
> > Similarly to the MMIO hole sizing, I don't think that it would be a
> > requirement for this patch series but it is something to keep in mind.
> 
> Handling virq != pirq will be more complex as we need to take into
> account of the hotplug solution.
> 
> The vgic has a register which provide the number of lines, I suspect
> this number can't grow up while the guest is running.

Of course not. But keep in mind that for non-PCI passthrough we would be
fully aware of all the assigned interrupts before starting the VM.

PCI passthrough and MSI-X are the issue because there can be many MSI
per device and the device can be hotplugged into the guest.
Ian Campbell July 3, 2014, 11:27 a.m. UTC | #4
On Thu, 2014-06-19 at 13:29 +0100, Stefano Stabellini wrote:
> On Thu, 19 Jun 2014, Julien Grall wrote:
> > On 06/18/2014 08:24 PM, Stefano Stabellini wrote:
> > >>  /*
> > >> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> > >> index e451324..c18b2ca 100644
> > >> --- a/xen/arch/arm/vgic.c
> > >> +++ b/xen/arch/arm/vgic.c
> > >> @@ -82,10 +82,7 @@ int domain_vgic_init(struct domain *d)
> > >>      /* Currently nr_lines in vgic and gic doesn't have the same meanings
> > >>       * Here nr_lines = number of SPIs
> > >>       */
> > >> -    if ( is_hardware_domain(d) )
> > >> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
> > >> -    else
> > >> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
> > >> +    d->arch.vgic.nr_lines = gic_number_lines() - 32;
> > >>  
> > >>      d->arch.vgic.shared_irqs =
> > >>          xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
> > > 
> > > I see what you mean about virq != pirq.
> > > 
> > > It seems to me that setting d->arch.vgic.nr_lines = gic_number_lines() -
> > > 32 for the hardware domain is OK, but it is really a waste for the
> > > others. We could find a way to pass down the info about how many SPIs we
> > > need from libxl. Or we could delay the vgic allocations until the first
> > > SPI is assigned to the domU.
> > 
> > I gave a check on both midway and the versatile express and there is
> > about 200 lines.
> > 
> > It make the overhead of less than 8K per domain. Which is not too bad.
> > 
> > If the host really support 1024 IRQs that would make an overhead of ~32K.
> > 
> > > Similarly to the MMIO hole sizing, I don't think that it would be a
> > > requirement for this patch series but it is something to keep in mind.
> > 
> > Handling virq != pirq will be more complex as we need to take into
> > account of the hotplug solution.

What's the issue here? Something to do with irqdesc->irq-pending lookup?

Seems like irqdesc needs to store the domain and virq number when the
irq is passed through. I assume it must store the dmain already.


> > The vgic has a register which provide the number of lines, I suspect
> > this number can't grow up while the guest is running.
> 
> Of course not. But keep in mind that for non-PCI passthrough we would be
> fully aware of all the assigned interrupts before starting the VM.

Are we ruling out hotplug of such devices? (I don't have a problem with
that BTW)

> PCI passthrough and MSI-X are the issue because there can be many MSI
> per device and the device can be hotplugged into the guest.

MSI(-X) AKA LPIs are in a different more dynamic number space though
(from 8192 onwards). I think for that specific case we can dynamically
do things.

The bigger issue would be the legacy INT-x interrupts (which I expect
look like SPIs), those would no doubt need exposing somehow.

Do we think it is the case that we are eventually going to need a guest
cfg option pci = 0|1? I think the answer is yes. Assinging a pci device
would cause pci=1, or you can set pci=1 to enable hotplug of pci devices
later (i.e. mmio space is reserved, INTx interrupts are assigned etc).

We already have something not totally different in the e820_host option
on x86.

Ian.
Julien Grall July 3, 2014, 12:02 p.m. UTC | #5
On 07/03/2014 12:27 PM, Ian Campbell wrote:
> On Thu, 2014-06-19 at 13:29 +0100, Stefano Stabellini wrote:
>> On Thu, 19 Jun 2014, Julien Grall wrote:
>>> On 06/18/2014 08:24 PM, Stefano Stabellini wrote:
>>>>>  /*
>>>>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>>>>> index e451324..c18b2ca 100644
>>>>> --- a/xen/arch/arm/vgic.c
>>>>> +++ b/xen/arch/arm/vgic.c
>>>>> @@ -82,10 +82,7 @@ int domain_vgic_init(struct domain *d)
>>>>>      /* Currently nr_lines in vgic and gic doesn't have the same meanings
>>>>>       * Here nr_lines = number of SPIs
>>>>>       */
>>>>> -    if ( is_hardware_domain(d) )
>>>>> -        d->arch.vgic.nr_lines = gic_number_lines() - 32;
>>>>> -    else
>>>>> -        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
>>>>> +    d->arch.vgic.nr_lines = gic_number_lines() - 32;
>>>>>  
>>>>>      d->arch.vgic.shared_irqs =
>>>>>          xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
>>>>
>>>> I see what you mean about virq != pirq.
>>>>
>>>> It seems to me that setting d->arch.vgic.nr_lines = gic_number_lines() -
>>>> 32 for the hardware domain is OK, but it is really a waste for the
>>>> others. We could find a way to pass down the info about how many SPIs we
>>>> need from libxl. Or we could delay the vgic allocations until the first
>>>> SPI is assigned to the domU.
>>>
>>> I gave a check on both midway and the versatile express and there is
>>> about 200 lines.
>>>
>>> It make the overhead of less than 8K per domain. Which is not too bad.
>>>
>>> If the host really support 1024 IRQs that would make an overhead of ~32K.
>>>
>>>> Similarly to the MMIO hole sizing, I don't think that it would be a
>>>> requirement for this patch series but it is something to keep in mind.
>>>
>>> Handling virq != pirq will be more complex as we need to take into
>>> account of the hotplug solution.
> 
> What's the issue here? Something to do with irqdesc->irq-pending lookup?
> 
> Seems like irqdesc needs to store the domain and virq number when the
> irq is passed through. I assume it must store the dmain already.

The issues are mostly:
	- we need to defer the vGIC IRQs allocation
	- Add a new hypercall to setup the number of IRQs
	- How do we handle hotplug?

>>> The vgic has a register which provide the number of lines, I suspect
>>> this number can't grow up while the guest is running.
>>
>> Of course not. But keep in mind that for non-PCI passthrough we would be
>> fully aware of all the assigned interrupts before starting the VM.
> 
> Are we ruling out hotplug of such devices? (I don't have a problem with
> that BTW)
> 
>> PCI passthrough and MSI-X are the issue because there can be many MSI
>> per device and the device can be hotplugged into the guest.
> 
> MSI(-X) AKA LPIs are in a different more dynamic number space though
> (from 8192 onwards). I think for that specific case we can dynamically
> do things.
> 
> The bigger issue would be the legacy INT-x interrupts (which I expect
> look like SPIs), those would no doubt need exposing somehow.

INT-x is shared between different PCI and this will means lots of rework
in the interrupt code (mostly now with the no maintenance interrupt
series). I hope we won't have to handle them.

> Do we think it is the case that we are eventually going to need a guest
> cfg option pci = 0|1? I think the answer is yes. Assinging a pci device
> would cause pci=1, or you can set pci=1 to enable hotplug of pci devices
> later (i.e. mmio space is reserved, INTx interrupts are assigned etc).

I'm not sure to understand what we would need a "pci" cfg option... For
now, this series doesn't aim to support PCI. So I think we could defer
this problem later.
Ian Campbell July 3, 2014, 12:53 p.m. UTC | #6
On Thu, 2014-07-03 at 13:02 +0100, Julien Grall wrote:
> >>> Handling virq != pirq will be more complex as we need to take into
> >>> account of the hotplug solution.
> > 
> > What's the issue here? Something to do with irqdesc->irq-pending lookup?
> > 
> > Seems like irqdesc needs to store the domain and virq number when the
> > irq is passed through. I assume it must store the dmain already.
> 
> The issues are mostly:
> 	- we need to defer the vGIC IRQs allocation
> 	- Add a new hypercall to setup the number of IRQs
> 	- How do we handle hotplug?

Those all sound like issues with having dynamic numbers of irqs, rather
than with a non-1:1 virq<->pirq mapping per-se.

> >>> The vgic has a register which provide the number of lines, I suspect
> >>> this number can't grow up while the guest is running.
> >>
> >> Of course not. But keep in mind that for non-PCI passthrough we would be
> >> fully aware of all the assigned interrupts before starting the VM.
> > 
> > Are we ruling out hotplug of such devices? (I don't have a problem with
> > that BTW)
> > 
> >> PCI passthrough and MSI-X are the issue because there can be many MSI
> >> per device and the device can be hotplugged into the guest.
> > 
> > MSI(-X) AKA LPIs are in a different more dynamic number space though
> > (from 8192 onwards). I think for that specific case we can dynamically
> > do things.
> > 
> > The bigger issue would be the legacy INT-x interrupts (which I expect
> > look like SPIs), those would no doubt need exposing somehow.
> 
> INT-x is shared between different PCI and this will means lots of rework
> in the interrupt code (mostly now with the no maintenance interrupt
> series). I hope we won't have to handle them.

I've no idea what PCI on ARM is going to be like in this respect. Xgene
PCI controller exports them though and I suppose if the h/w wants to
support all PCI devices it might be needed.

Not sure how PCI-X changes that though.

> 
> > Do we think it is the case that we are eventually going to need a guest
> > cfg option pci = 0|1? I think the answer is yes. Assinging a pci device
> > would cause pci=1, or you can set pci=1 to enable hotplug of pci devices
> > later (i.e. mmio space is reserved, INTx interrupts are assigned etc).
> 
> I'm not sure to understand what we would need a "pci" cfg option... For
> now, this series doesn't aim to support PCI. So I think we could defer
> this problem later.

Yeah, we got onto PCI somehow.

So long as we are happy not being able to hotplug platform devices I
think we don't need an equivalent option (the point would be to only
setup huge numbers of SPIs, reserve MMIO space etc if it was going to be
used).
Julien Grall July 15, 2014, 1:01 p.m. UTC | #7
Hi Ian,

Sorry I forgot to answer to this mail.

On 03/07/14 13:53, Ian Campbell wrote:
> On Thu, 2014-07-03 at 13:02 +0100, Julien Grall wrote:
>>>>> Handling virq != pirq will be more complex as we need to take into
>>>>> account of the hotplug solution.
>>>
>>> What's the issue here? Something to do with irqdesc->irq-pending lookup?
>>>
>>> Seems like irqdesc needs to store the domain and virq number when the
>>> irq is passed through. I assume it must store the dmain already.
>>
>> The issues are mostly:
>> 	- we need to defer the vGIC IRQs allocation
>> 	- Add a new hypercall to setup the number of IRQs
>> 	- How do we handle hotplug?
>
> Those all sound like issues with having dynamic numbers of irqs, rather
> than with a non-1:1 virq<->pirq mapping per-se.

Yes. I will stick on a static allocation and 1:1 mapping for this first 
version. We could rework it when PCI passthrough will be added.

>>
>>> Do we think it is the case that we are eventually going to need a guest
>>> cfg option pci = 0|1? I think the answer is yes. Assinging a pci device
>>> would cause pci=1, or you can set pci=1 to enable hotplug of pci devices
>>> later (i.e. mmio space is reserved, INTx interrupts are assigned etc).
>>
>> I'm not sure to understand what we would need a "pci" cfg option... For
>> now, this series doesn't aim to support PCI. So I think we could defer
>> this problem later.
>
> Yeah, we got onto PCI somehow.
>
> So long as we are happy not being able to hotplug platform devices I
> think we don't need an equivalent option (the point would be to only
> setup huge numbers of SPIs, reserve MMIO space etc if it was going to be
> used).

We can reuse the number of IRQs used by the HW. The current series 
allocates SPIs for guest even if we don't plan to passthrough a device. 
Are we fine with this drawback for Xen 4.5?

Regards,
Ian Campbell July 15, 2014, 1:03 p.m. UTC | #8
On Tue, 2014-07-15 at 14:01 +0100, Julien Grall wrote:
> >>> Do we think it is the case that we are eventually going to need a guest
> >>> cfg option pci = 0|1? I think the answer is yes. Assinging a pci device
> >>> would cause pci=1, or you can set pci=1 to enable hotplug of pci devices
> >>> later (i.e. mmio space is reserved, INTx interrupts are assigned etc).
> >>
> >> I'm not sure to understand what we would need a "pci" cfg option... For
> >> now, this series doesn't aim to support PCI. So I think we could defer
> >> this problem later.
> >
> > Yeah, we got onto PCI somehow.
> >
> > So long as we are happy not being able to hotplug platform devices I
> > think we don't need an equivalent option (the point would be to only
> > setup huge numbers of SPIs, reserve MMIO space etc if it was going to be
> > used).
> 
> We can reuse the number of IRQs used by the HW. The current series 
> allocates SPIs for guest even if we don't plan to passthrough a device. 
> Are we fine with this drawback for Xen 4.5?

I meant no need for an equivalent user facing option. I'd much prefer it
if the toolstack did the Right Thing and configured the number of SPIs
for each guest at domain build time, based on its knowledge of the
devices configured for passthrough.

Ian.
Andrii Tseglytskyi Aug. 18, 2014, 7:20 p.m. UTC | #9
Hi All,

Could someone answer - what is the future of this patch series? Are
you going to post patches as non RFC ? Will it be merged to Xen 4.5 ?
I'm asking because it is *very useful* for development we have in
GlobalLogic. In our current state we need to route some HW irqs to
domainU (Android) and we need them 1 to 1.

For now we use similar patch series -
http://lists.xen.org/archives/html/xen-devel/2013-07/msg01146.html but
looks like it will not be merged

Regards,
Andri

On Tue, Jul 15, 2014 at 4:03 PM, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> On Tue, 2014-07-15 at 14:01 +0100, Julien Grall wrote:
>> >>> Do we think it is the case that we are eventually going to need a guest
>> >>> cfg option pci = 0|1? I think the answer is yes. Assinging a pci device
>> >>> would cause pci=1, or you can set pci=1 to enable hotplug of pci devices
>> >>> later (i.e. mmio space is reserved, INTx interrupts are assigned etc).
>> >>
>> >> I'm not sure to understand what we would need a "pci" cfg option... For
>> >> now, this series doesn't aim to support PCI. So I think we could defer
>> >> this problem later.
>> >
>> > Yeah, we got onto PCI somehow.
>> >
>> > So long as we are happy not being able to hotplug platform devices I
>> > think we don't need an equivalent option (the point would be to only
>> > setup huge numbers of SPIs, reserve MMIO space etc if it was going to be
>> > used).
>>
>> We can reuse the number of IRQs used by the HW. The current series
>> allocates SPIs for guest even if we don't plan to passthrough a device.
>> Are we fine with this drawback for Xen 4.5?
>
> I meant no need for an equivalent user facing option. I'd much prefer it
> if the toolstack did the Right Thing and configured the number of SPIs
> for each guest at domain build time, based on its knowledge of the
> devices configured for passthrough.
>
> Ian.
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
Julien Grall Aug. 18, 2014, 9:55 p.m. UTC | #10
On 18/08/14 14:20, Andrii Tseglytskyi wrote:
> Hi All,

Hello,

> Could someone answer - what is the future of this patch series? Are
> you going to post patches as non RFC ?

I've sent a v2 a couple of weeks ago:

https://patches.linaro.org/34666/

 > Will it be merged to Xen 4.5 ?

I hope so. If I can't get the whole series in Xen 4.5, I will at least 
try to get the interrupt assignment in it.

> I'm asking because it is *very useful* for development we have in
> GlobalLogic. In our current state we need to route some HW irqs to
> domainU (Android) and we need them 1 to 1.

The new approach allocate dynamically the virtual IRQ number. I chose 
this solution because otherwise Xen is allocating memory which is never 
used.

You could hack this patch to support 1:1 (see vgic_allocate_virq and 
vgic_free_virq).

OOI, why do you need Virtual IRQ == Physical IRQ?

> For now we use similar patch series -
> http://lists.xen.org/archives/html/xen-devel/2013-07/msg01146.html but
> looks like it will not be merged

IIRC, there was few comments in the v2 and no v3 has been sent after.

Regards,
Andrii Tseglytskyi Aug. 19, 2014, 9:11 a.m. UTC | #11
Hi Julien,

On Tue, Aug 19, 2014 at 12:55 AM, Julien Grall <julien.grall@linaro.org> wrote:
>
>
> On 18/08/14 14:20, Andrii Tseglytskyi wrote:
>>
>> Hi All,
>
>
> Hello,
>
>
>> Could someone answer - what is the future of this patch series? Are
>> you going to post patches as non RFC ?
>
>
> I've sent a v2 a couple of weeks ago:
>
> https://patches.linaro.org/34666/
>
>
>> Will it be merged to Xen 4.5 ?
>
> I hope so. If I can't get the whole series in Xen 4.5, I will at least try
> to get the interrupt assignment in it.
>

Sounds great. Thank you.

>
>> I'm asking because it is *very useful* for development we have in
>> GlobalLogic. In our current state we need to route some HW irqs to
>> domainU (Android) and we need them 1 to 1.
>
>
> The new approach allocate dynamically the virtual IRQ number. I chose this
> solution because otherwise Xen is allocating memory which is never used.
>
> You could hack this patch to support 1:1 (see vgic_allocate_virq and
> vgic_free_virq).
>
> OOI, why do you need Virtual IRQ == Physical IRQ?
>

Because I have few devices in DomU, which use hardcoded IRQ numbers.

BTW - which code allocates IRQ number dynamically? My code is almost
the same and I have 1 to 1 in domU ?

Regards,
Andrii

>
>> For now we use similar patch series -
>> http://lists.xen.org/archives/html/xen-devel/2013-07/msg01146.html but
>> looks like it will not be merged
>
>
> IIRC, there was few comments in the v2 and no v3 has been sent after.
>
> Regards,
>
> --
> Julien Grall
Julien Grall Aug. 19, 2014, 2:24 p.m. UTC | #12
Hello Andrii,


On 19/08/14 04:11, Andrii Tseglytskyi wrote:
>> OOI, why do you need Virtual IRQ == Physical IRQ?
>>
>
> Because I have few devices in DomU, which use hardcoded IRQ numbers.
>
> BTW - which code allocates IRQ number dynamically? My code is almost
> the same and I have 1 to 1 in domU ?

With this series, the toolstack is deciding the number of SPIs (see 
xen_domctl_configure_domain domctl).

Then when map_pirq is called, the function vgic_allocate_irq allocates 
the SPIs number.

Regards,
diff mbox

Patch

diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c
index 61b4a18..d17589c 100644
--- a/xen/arch/arm/physdev.c
+++ b/xen/arch/arm/physdev.c
@@ -8,13 +8,86 @@ 
 #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;
+
+    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\n",
+                d->domain_id, type);
+        goto free_domain;
+    }
+
+    if ( !is_routable_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;
+
+    ret = route_irq_to_guest(d, irq, "routed IRQ");
+
+    /* GSIs are mapped 1:1 to the guest */
+    if ( !ret )
+        *pirq_p = irq;
+
+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;
+    default:
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
 }
 
 /*
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index e451324..c18b2ca 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -82,10 +82,7 @@  int domain_vgic_init(struct domain *d)
     /* Currently nr_lines in vgic and gic doesn't have the same meanings
      * Here nr_lines = number of SPIs
      */
-    if ( is_hardware_domain(d) )
-        d->arch.vgic.nr_lines = gic_number_lines() - 32;
-    else
-        d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
+    d->arch.vgic.nr_lines = gic_number_lines() - 32;
 
     d->arch.vgic.shared_irqs =
         xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));