[1/7] KVM: api: add kvm_irq_routing_extended_msi

Message ID 1435592237-17924-2-git-send-email-eric.auger@linaro.org
State New
Headers show

Commit Message

Auger Eric June 29, 2015, 3:37 p.m.
On ARM, the MSI msg (address and data) comes along with
out-of-band device ID information. The device ID encodes the device
that composes the MSI msg. Let's create a new routing entry type,
dubbed KVM_IRQ_ROUTING_EXTENDED_MSI and use the __u32 pad space
to convey the device ID.

Signed-off-by: Eric Auger <eric.auger@linaro.org>

---

RFC -> PATCH
- remove kvm_irq_routing_extended_msi and use union instead
---
 Documentation/virtual/kvm/api.txt | 9 ++++++++-
 include/uapi/linux/kvm.h          | 6 +++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

Comments

Auger Eric July 2, 2015, 2:49 p.m. | #1
Hi Pavel,
On 07/02/2015 09:26 AM, Pavel Fedin wrote:
>  Hello!
> 
>> -----Original Message-----
>> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of Eric Auger
>> Sent: Monday, June 29, 2015 6:37 PM
>> To: eric.auger@st.com; eric.auger@linaro.org; linux-arm-kernel@lists.infradead.org;
>> marc.zyngier@arm.com; christoffer.dall@linaro.org; andre.przywara@arm.com;
>> kvmarm@lists.cs.columbia.edu; kvm@vger.kernel.org
>> Cc: linux-kernel@vger.kernel.org; patches@linaro.org; p.fedin@samsung.com; pbonzini@redhat.com
>> Subject: [PATCH 1/7] KVM: api: add kvm_irq_routing_extended_msi
>>
>> On ARM, the MSI msg (address and data) comes along with
>> out-of-band device ID information. The device ID encodes the device
>> that composes the MSI msg. Let's create a new routing entry type,
>> dubbed KVM_IRQ_ROUTING_EXTENDED_MSI and use the __u32 pad space
>> to convey the device ID.
>>
>> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>>
>> ---
>>
>> RFC -> PATCH
>> - remove kvm_irq_routing_extended_msi and use union instead
>> ---
>>  Documentation/virtual/kvm/api.txt | 9 ++++++++-
>>  include/uapi/linux/kvm.h          | 6 +++++-
>>  2 files changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> index d20fd94..6426ae9 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -1414,7 +1414,10 @@ struct kvm_irq_routing_entry {
>>  	__u32 gsi;
>>  	__u32 type;
>>  	__u32 flags;
>> -	__u32 pad;
>> +	union {
>> +		__u32 pad;
>> +		__u32 devid;
>> +	};
>>  	union {
>>  		struct kvm_irq_routing_irqchip irqchip;
>>  		struct kvm_irq_routing_msi msi;
> 
>  devid is actually a part of MSI bunch. Shouldn't it be a part of struct kvm_irq_routing_msi then?
> It also has reserved pad.
Well this makes sense to me to associate the devid to the msi and put
devid in the pad field of struct kvm_irq_routing_msi.

André, Christoffer, would you agree on this change? - I would like to
avoid doing/undoing things ;-) -

> 
>> @@ -1427,6 +1430,10 @@ struct kvm_irq_routing_entry {
>>  #define KVM_IRQ_ROUTING_IRQCHIP 1
>>  #define KVM_IRQ_ROUTING_MSI 2
>>  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
>> +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
>> +
>> +In case of KVM_IRQ_ROUTING_EXTENDED_MSI routing type, devid is used to convey
>> +the device ID.
>>
>>  No flags are specified so far, the corresponding field must be set to zero.
> 
> What if we use KVM_MSI_VALID_DEVID flag instead of new KVM_IRQ_ROUTING_EXTENDED_MSI definition? I
> believe this would make an API more consistent and introduce less new definitions.
do you mean using type == KVM_IRQ_ROUTING_MSI and flag ==
KVM_MSI_VALID_DEVID? Not sure this is simpler/clearer. s390 paved the
way for new routing entry types. I add a new one here.

Another solution may be to use new KVM_IRQ_ROUTING_EXTENDED_MSI type and
add struct kvm_msi ext_msi in kvm_irq_routing_entry union. It is 8 words
as well. But most probably this is even uglier.

Let's see if this thread is heading to a consensus...

Best Regards

Eric
> 
>>
>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>> index 2a23705..8484681 100644
>> --- a/include/uapi/linux/kvm.h
>> +++ b/include/uapi/linux/kvm.h
>> @@ -841,12 +841,16 @@ struct kvm_irq_routing_s390_adapter {
>>  #define KVM_IRQ_ROUTING_IRQCHIP 1
>>  #define KVM_IRQ_ROUTING_MSI 2
>>  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
>> +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
>>
>>  struct kvm_irq_routing_entry {
>>  	__u32 gsi;
>>  	__u32 type;
>>  	__u32 flags;
>> -	__u32 pad;
>> +	union {
>> +		__u32 pad;
>> +		__u32 devid;
>> +	};
>>  	union {
>>  		struct kvm_irq_routing_irqchip irqchip;
>>  		struct kvm_irq_routing_msi msi;
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
>
Auger Eric July 2, 2015, 2:50 p.m. | #2
On 07/02/2015 10:41 AM, Pavel Fedin wrote:
>  Hello!
> 
>> What if we use KVM_MSI_VALID_DEVID flag instead of new KVM_IRQ_ROUTING_EXTENDED_MSI
>> definition? I
>> believe this would make an API more consistent and introduce less new definitions.
> 
>  I have just found one more flaw in your implementation. If you take a look at irqfd_wakeup()...
> --- cut ---
> 		/* An event has been signaled, inject an interrupt */
> 		if (irq.type == KVM_IRQ_ROUTING_MSI)
> 			kvm_set_msi(&irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1,
> 					false);
> 		else
> 			schedule_work(&irqfd->inject);
> --- cut ---
>  You apparently missed KVM_IRQ_ROUTING_EXTENDED_MSI here, as well as in irqfd_update(). But, if you
> accept my API proposal, this becomes irrelevant.

Hi Pavel,

thanks for spotting this bug. Whatever the user-api API choice I will
respin shortly fixing this  plus the one reported by André.

Thanks for the review.

Best Regards

Eric


> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
>
Auger Eric July 2, 2015, 3:22 p.m. | #3
Hi Andre,
On 07/02/2015 05:14 PM, Andre Przywara wrote:
> Hi Eric,
> 
> On 02/07/15 15:49, Eric Auger wrote:
>> Hi Pavel,
>> On 07/02/2015 09:26 AM, Pavel Fedin wrote:
>>>  Hello!
>>>
>>>> -----Original Message-----
>>>> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of Eric Auger
>>>> Sent: Monday, June 29, 2015 6:37 PM
>>>> To: eric.auger@st.com; eric.auger@linaro.org; linux-arm-kernel@lists.infradead.org;
>>>> marc.zyngier@arm.com; christoffer.dall@linaro.org; andre.przywara@arm.com;
>>>> kvmarm@lists.cs.columbia.edu; kvm@vger.kernel.org
>>>> Cc: linux-kernel@vger.kernel.org; patches@linaro.org; p.fedin@samsung.com; pbonzini@redhat.com
>>>> Subject: [PATCH 1/7] KVM: api: add kvm_irq_routing_extended_msi
>>>>
>>>> On ARM, the MSI msg (address and data) comes along with
>>>> out-of-band device ID information. The device ID encodes the device
>>>> that composes the MSI msg. Let's create a new routing entry type,
>>>> dubbed KVM_IRQ_ROUTING_EXTENDED_MSI and use the __u32 pad space
>>>> to convey the device ID.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>>>>
>>>> ---
>>>>
>>>> RFC -> PATCH
>>>> - remove kvm_irq_routing_extended_msi and use union instead
>>>> ---
>>>>  Documentation/virtual/kvm/api.txt | 9 ++++++++-
>>>>  include/uapi/linux/kvm.h          | 6 +++++-
>>>>  2 files changed, 13 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>>>> index d20fd94..6426ae9 100644
>>>> --- a/Documentation/virtual/kvm/api.txt
>>>> +++ b/Documentation/virtual/kvm/api.txt
>>>> @@ -1414,7 +1414,10 @@ struct kvm_irq_routing_entry {
>>>>  	__u32 gsi;
>>>>  	__u32 type;
>>>>  	__u32 flags;
>>>> -	__u32 pad;
>>>> +	union {
>>>> +		__u32 pad;
>>>> +		__u32 devid;
>>>> +	};
>>>>  	union {
>>>>  		struct kvm_irq_routing_irqchip irqchip;
>>>>  		struct kvm_irq_routing_msi msi;
>>>
>>>  devid is actually a part of MSI bunch. Shouldn't it be a part of struct kvm_irq_routing_msi then?
>>> It also has reserved pad.
>> Well this makes sense to me to associate the devid to the msi and put
>> devid in the pad field of struct kvm_irq_routing_msi.
>>
>> André, Christoffer, would you agree on this change? - I would like to
>> avoid doing/undoing things ;-) -
> 
> Yes, that makes sense to me. TBH I haven't had a closer look at the
> patches yet, but clearly devid belongs into struct kvm_irq_routing_msi.
thanks for your quick reply.
OK so let's go with that change.
> 
>>>
>>>> @@ -1427,6 +1430,10 @@ struct kvm_irq_routing_entry {
>>>>  #define KVM_IRQ_ROUTING_IRQCHIP 1
>>>>  #define KVM_IRQ_ROUTING_MSI 2
>>>>  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
>>>> +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
>>>> +
>>>> +In case of KVM_IRQ_ROUTING_EXTENDED_MSI routing type, devid is used to convey
>>>> +the device ID.
>>>>
>>>>  No flags are specified so far, the corresponding field must be set to zero.
>>>
>>> What if we use KVM_MSI_VALID_DEVID flag instead of new KVM_IRQ_ROUTING_EXTENDED_MSI definition? I
>>> believe this would make an API more consistent and introduce less new definitions.
>> do you mean using type == KVM_IRQ_ROUTING_MSI and flag ==
>> KVM_MSI_VALID_DEVID? Not sure this is simpler/clearer. s390 paved the
>> way for new routing entry types. I add a new one here.
> 
> I tend to agree with Pavel's solution. When hacking IRQ routing support
> into kvmtool I saw that it's nasty being forced to differentiate between
> the two MSI routing types. Actually userland should be able to query the
> kernel about what kind of routing it requires. Also there is the issue
> that we must _not_ set the flag on x86, since that breaks older kernels
> (due to that check that Eric removes in 3/7).
> So from my point of view the cleanest solution would be to always use
> KVM_IRQ_ROUTING_MSI, and add the device ID if the kernel needs it (true
> for ITS guests, false for GICv2M, x86, ...)
> I am looking for a clever solution for this now.
OK thanks for sharing. I need some more time to study qemu code too.

- Eric

> 
> Cheers,
> Andre.
> 
>>
>> Another solution may be to use new KVM_IRQ_ROUTING_EXTENDED_MSI type and
>> add struct kvm_msi ext_msi in kvm_irq_routing_entry union. It is 8 words
>> as well. But most probably this is even uglier.
> 
>>
>> Let's see if this thread is heading to a consensus...
>>
>> Best Regards
>>
>> Eric
>>>
>>>>
>>>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>>>> index 2a23705..8484681 100644
>>>> --- a/include/uapi/linux/kvm.h
>>>> +++ b/include/uapi/linux/kvm.h
>>>> @@ -841,12 +841,16 @@ struct kvm_irq_routing_s390_adapter {
>>>>  #define KVM_IRQ_ROUTING_IRQCHIP 1
>>>>  #define KVM_IRQ_ROUTING_MSI 2
>>>>  #define KVM_IRQ_ROUTING_S390_ADAPTER 3
>>>> +#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
>>>>
>>>>  struct kvm_irq_routing_entry {
>>>>  	__u32 gsi;
>>>>  	__u32 type;
>>>>  	__u32 flags;
>>>> -	__u32 pad;
>>>> +	union {
>>>> +		__u32 pad;
>>>> +		__u32 devid;
>>>> +	};
>>>>  	union {
>>>>  		struct kvm_irq_routing_irqchip irqchip;
>>>>  		struct kvm_irq_routing_msi msi;
>>>> --
>>>> 1.9.1
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>> Kind regards,
>>> Pavel Fedin
>>> Expert Engineer
>>> Samsung Electronics Research center Russia
>>>
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Auger Eric July 2, 2015, 3:41 p.m. | #4
On 07/02/2015 05:39 PM, Pavel Fedin wrote:
>  Hello!
> 
>> OK thanks for sharing. I need some more time to study qemu code too.
> 
>  I am currently working on supporting this in qemu. Not ready yet, need some time. But, with API i
> suggest, things are really much-much simpler.

OK so both of you say the same thing. Will respin accordingly

Eric
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Auger Eric July 3, 2015, 3:42 p.m. | #5
On 07/03/2015 05:29 PM, Pavel Fedin wrote:
>  Hi!
> 
>> OK so both of you say the same thing. Will respin accordingly
> 
>  You may also want to add this:
> Tested-by: Pavel Fedin <p.fedin@samsung.com>

Thanks Pavel for the intent. However since I am going to change the uapi
and correct the bug you spotted out, this will need to be tested again.
T-b is applied when the code is stable and bug-free I think ;-)

Best Regards

Eric
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Christoffer Dall July 6, 2015, 9:30 a.m. | #6
On Mon, Jul 06, 2015 at 09:30:20AM +0100, Andre Przywara wrote:
> Hi Pavel,
> 
> On 06/07/15 07:42, Pavel Fedin wrote:
> >  Hello!
> > 
> >> I like this approach, but it runs into problems:
> >> As you read above the current documentation says that the flags field
> >> must be zero and the current KVM_SET_GSI_ROUTING handler bails out if it
> >> isn't. So userland would need to know whether it's safe to set that
> >> field.
> > 
> >  This problem does not exist because:
> > a) Older platforms do not need this flag, so they expect to get zero.
> > b) ARM64 + GICv3 platform cannot work without this flag.
> > 
> >  This is perfectly OK combination IMO. Userland just knows, whether it needs to supply device ID or
> > not. For example, my modified qemu now has kvm_msi_flags global variable which defaults to 0. ITS
> > code, then, if activated, changes it to KVM_MSI_VALID_DEVID, and qemu starts supplying device IDs to
> > the related calls.
> 
> Well, I had this solution before in kvmtool: If ARM && ITS then set the
> flag. But I wasn't really happy with this, as the IRQ routing, setup and
> injection code is rather architecture agnostic (implementing the generic
> KVM interface), so spraying in some architecture hacks sounded not very
> elegant.
> Also as the flag describes a rather generic feature (provide an unique
> device ID), I'd rather avoid to make this an ARM hack.
> 
> That being said this is not a show stopper for me, so if the others are
> happy with this, I will go down your road.
> 
There must be some way for userspace to discover if it's valid to set
the flag or not; either through a well-defined error-code probing
mechanism for KVM_SET_GSI_ROUTING or through advertising a capability.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Christoffer Dall July 6, 2015, 10:37 a.m. | #7
On Mon, Jul 06, 2015 at 11:05:26AM +0100, Andre Przywara wrote:
> Hi Christoffer,
> 
> On 06/07/15 10:30, Christoffer Dall wrote:
> > On Mon, Jul 06, 2015 at 09:30:20AM +0100, Andre Przywara wrote:
> >> Hi Pavel,
> >>
> >> On 06/07/15 07:42, Pavel Fedin wrote:
> >>>  Hello!
> >>>
> >>>> I like this approach, but it runs into problems:
> >>>> As you read above the current documentation says that the flags field
> >>>> must be zero and the current KVM_SET_GSI_ROUTING handler bails out if it
> >>>> isn't. So userland would need to know whether it's safe to set that
> >>>> field.
> >>>
> >>>  This problem does not exist because:
> >>> a) Older platforms do not need this flag, so they expect to get zero.
> >>> b) ARM64 + GICv3 platform cannot work without this flag.
> >>>
> >>>  This is perfectly OK combination IMO. Userland just knows, whether it needs to supply device ID or
> >>> not. For example, my modified qemu now has kvm_msi_flags global variable which defaults to 0. ITS
> >>> code, then, if activated, changes it to KVM_MSI_VALID_DEVID, and qemu starts supplying device IDs to
> >>> the related calls.
> >>
> >> Well, I had this solution before in kvmtool: If ARM && ITS then set the
> >> flag. But I wasn't really happy with this, as the IRQ routing, setup and
> >> injection code is rather architecture agnostic (implementing the generic
> >> KVM interface), so spraying in some architecture hacks sounded not very
> >> elegant.
> >> Also as the flag describes a rather generic feature (provide an unique
> >> device ID), I'd rather avoid to make this an ARM hack.
> >>
> >> That being said this is not a show stopper for me, so if the others are
> >> happy with this, I will go down your road.
> >>
> > There must be some way for userspace to discover if it's valid to set
> > the flag or not; either through a well-defined error-code probing
> > mechanism for KVM_SET_GSI_ROUTING or through advertising a capability.
> 
> Right, makes sense, I was wondering about this requirement earlier, but
> couldn't find really good prior art in the code (KVM_GET_VCPU_EVENTS
> seems to be bad example).
> So I think we get along with a new VM specific capability like
> KVM_CAP_MSIS_REQUIRE_DEVID. This isn't strictly a "capability" (as it's
> more a requirement), but I guess it fits here anyway. It has to be
> per-VM, as a GICv2M guest does not need it, but an ITS guest does.
> We can use this very flag for both the KVM_SIGNAL_MSI and the
> KVM_SET_GSI_ROUTING ioctl, so interface churn is kept minimal.
> 
> Does that make sense?
> 
> Actually I have implemented this already last week, I will send it out
> along with a v2 of the ITS emulation later this week.
> 
I don't view it as 'the kernel requires this' but as 'the kernel will
not complain with arbitrary error code if you set the devid flag'
capability, and it's up to userspace (as usual) to provide the correct
arguments for things to work, and up to the kernel to ensure we don't
crash the system etc.

Thus, if you want to advertise it as a capability, I would rather call
it KVM_CAP_MSI_DEVID.

The question is if userspace code that sets the devid flag will anyway
depend on some discovery mechanism of whether or not the kernel supports
arm64 irqfd etc. and if so, can we be sure to add the required support
at once in the kernel so that EINVAL never means 'you set the flags
field on the ioctl on an old kernel'?

This smells an awful lot like a capability to me.

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Christoffer Dall July 6, 2015, 12:08 p.m. | #8
On Mon, Jul 06, 2015 at 12:23:19PM +0100, Andre Przywara wrote:
> Hi Paolo,
> 
> thanks for looking at this!
> 
> On 06/07/15 12:07, Paolo Bonzini wrote:
> > 
> > 
> > On 06/07/2015 12:37, Christoffer Dall wrote:
> >> I don't view it as 'the kernel requires this' but as 'the kernel will
> >> not complain with arbitrary error code if you set the devid flag'
> >> capability, and it's up to userspace (as usual) to provide the correct
> >> arguments for things to work, and up to the kernel to ensure we don't
> >> crash the system etc.
> >>
> >> Thus, if you want to advertise it as a capability, I would rather call
> >> it KVM_CAP_MSI_DEVID.
> > 
> > I agree.  Does userspace know that ITS guests always require devid?
> 
> Well, as we are about to implement this: yes. But the issue is that MSI
> injection and GSI routing code is generic PCI code in userland (at least
> in kvmtool, guess in QEMU, too), so I don't want to pull in any kind of
> ARM specific code in there. The idea is to always provide the device ID
> from the PCI code (for PCI devices it's just the B/D/F triplet), but
> only send it to the kernel if needed. Querying a KVM capability is
> perfectly fine for this IMO.
> 
> > I
> > guess it's okay to return -EINVAL if the userspace doesn't set the flag
> > but the virtual hardware requires it.
> 
> Yes, that is what I do in the kernel implementation. And that is
> perfectly fine: the ITS emulation does not work without a device ID, the
> ITS driver in the guest assigns the very same payload (and address) to
> different devices, so there is no way to tell the MSIs apart without a
> unique device ID.
> 
Just so I'm sure I understand: The way the kernel differentiates between
no-devid and devid==0, is whether or not the devid flag is set, correct?

-Christoffer
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Auger Eric July 6, 2015, 3:01 p.m. | #9
Hi all,
On 07/06/2015 03:32 PM, Pavel Fedin wrote:
>  Hi!
> 
>>> Well, as we are about to implement this: yes. But the issue is that MSI
>>> injection and GSI routing code is generic PCI code in userland (at least
>>> in kvmtool, guess in QEMU, too), so I don't want to pull in any kind of
>>> ARM specific code in there. The idea is to always provide the device ID
>>> from the PCI code (for PCI devices it's just the B/D/F triplet), but
>>> only send it to the kernel if needed. Querying a KVM capability is
>>> perfectly fine for this IMO.
>>
>> Yes, I agree.
> 
>  Actually, we already have this capability, it's KVM_CAP_IRQ_ROUTING. If we have this capability,
> and want to use irqfds with GICv3, we need to set KVM_MSI_VALID_DEVID. And there is no other way to
> use irqfds with GICv3.
>  Just for example, this is what i have done in qemu:
> --- cut ---
> int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
> {
>     struct kvm_irq_routing_entry kroute = {};
>     int virq;
> 
>     if (kvm_gsi_direct_mapping()) {
>         return kvm_arch_msi_data_to_gsi(msg.data);
>     }
> 
>     if (!kvm_gsi_routing_enabled()) {
>         return -ENOSYS;
>     }
> 
>     virq = kvm_irqchip_get_virq(s);
>     if (virq < 0) {
>         return virq;
>     }
> 
>     kroute.gsi = virq;
>     kroute.type = KVM_IRQ_ROUTING_MSI;
>     kroute.u.msi.address_lo = (uint32_t)msg.address;
>     kroute.u.msi.address_hi = msg.address >> 32;
>     kroute.u.msi.data = le32_to_cpu(msg.data);
>     kroute.flags = kvm_msi_flags;
>     if (kroute.flags & KVM_MSI_VALID_DEVID) {
>         kroute.u.msi.devid = (pci_bus_num(dev->bus) << 8) | dev->devfn;
>     }
> 
>     if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
>         kvm_irqchip_release_virq(s, virq);
>         return -EINVAL;
>     }
> 
>     kvm_add_routing_entry(s, &kroute);
>     kvm_irqchip_commit_routes(s);
> 
>     return virq;
> }
> --- cut ---
> 
>  ITS code in qemu just does:
> 
> ---cut ---
>     msi_supported = true;
>     kvm_msi_flags = KVM_MSI_VALID_DEVID;
>     kvm_msi_via_irqfd_allowed = kvm_has_gsi_routing();
>     kvm_gsi_routing_allowed = kvm_msi_via_irqfd_allowed;
> --- cut ---
> 
>  I set KVM_MSI_VALID_DEVID unconditionally here just because it will never be checked if
> kvm_msi_via_irqfd_allowed is false, it's just qemu specifics. The more canonical form would perhaps
> be:
> --- cut ---
> if (kvm_has_gsi_routing()) {
>     kvm_msi_flags = KVM_MSI_VALID_DEVID;
Personally I prefer a capability rather than hardcoding a global
variable value in the qemu interrupt controller code. All the more so
typically there is KVM GSI routing cap that could/should? be queried
instead of hardcoding the value I think.

So not sure whether we eventually concluded;-)
- introduce a KVM_CAP_MSI_DEVID capability? All OK except Pavel not
convinced?
- userspaces puts the devid in struct kvm_irq_routing_msi pad field:
consensus (we do not intrduce a new kvm_irq_routing_ext_msi)
- userspace tells it conveyed a devid by setting
A) the kvm_irq_routing_entry's field?
B) the kvm_irq_routing_entry's type
no consensus. If there is a cap, does it really matter?

Best Regards

Eric
>     kvm_gsi_routing_allowed = true;
>     kvm_msi_via_irqfd_allowed = true;
> }
> --- cut ---
> 
>  I can post my sets as RFCs to qemu mailing list, if you want to take a look at the whole change
> set.
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Auger Eric July 6, 2015, 5:02 p.m. | #10
On 07/06/2015 05:52 PM, Andre Przywara wrote:
> Salut Eric,
> 
> ....
> 
>>>  ITS code in qemu just does:
>>>
>>> ---cut ---
>>>     msi_supported = true;
>>>     kvm_msi_flags = KVM_MSI_VALID_DEVID;
>>>     kvm_msi_via_irqfd_allowed = kvm_has_gsi_routing();
>>>     kvm_gsi_routing_allowed = kvm_msi_via_irqfd_allowed;
>>> --- cut ---
>>>
>>>  I set KVM_MSI_VALID_DEVID unconditionally here just because it will never be checked if
>>> kvm_msi_via_irqfd_allowed is false, it's just qemu specifics. The more canonical form would perhaps
>>> be:
>>> --- cut ---
>>> if (kvm_has_gsi_routing()) {
>>>     kvm_msi_flags = KVM_MSI_VALID_DEVID;
>> Personally I prefer a capability rather than hardcoding a global
>> variable value in the qemu interrupt controller code. All the more so
>> typically there is KVM GSI routing cap that could/should? be queried
>> instead of hardcoding the value I think.
>>
>> So not sure whether we eventually concluded;-)
>> - introduce a KVM_CAP_MSI_DEVID capability? All OK except Pavel not
>> convinced?
> 
> OK for me.
> 
>> - userspaces puts the devid in struct kvm_irq_routing_msi pad field:
>> consensus (we do not intrduce a new kvm_irq_routing_ext_msi)
> 
> OK for me.
> 
>> - userspace tells it conveyed a devid by setting
>> A) the kvm_irq_routing_entry's field?
> 
> You mean kvm_irq_routing_entry's "flags" here?
yes!!
> 
>> B) the kvm_irq_routing_entry's type
> 
> So personally I don't like it so much to use the generic flags field to
> specify the meaning within one particular type only. Using a new type
> instead seems to be more consistent, reusing an existing struct for that
> sounds even better.
> As written before (and coded in my branch) we can collapse that into the
> existing MSI type while translating that into the kernel internal
> routing structure to make the kernel code changes minimal.
> 
>> no consensus. If there is a cap, does it really matter?
> 
> I guess not. But I prefer the new type anyway, as it also has a known
> error path for older kernels.
I am fine with the new type too.

Eric
> 
> Cheers,
> Andre.
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Auger Eric July 7, 2015, 7:43 a.m. | #11
Hi Pavel,
On 07/07/2015 09:23 AM, Pavel Fedin wrote:
>  Hi!
> 
>> I guess not. But I prefer the new type anyway, as it also has a known
>> error path for older kernels.
> 
>  flags != 0 has known error path too, and it's absolutely the same.
>  Sorry, read this after writing my previous reply, so this is a short addendum.
> 
>  I see lots of people agreed on a new type. If my argument about reusing existing definitions is not
> enough, you can ignore it. Three people beat one definitely. :)
OK. let's move forward and use this new type. I will repost soon so
everyone can re-check the fit at kvmtool/qemu.

Thanks

Eric
>  And yes, since we are talking about it, actually KVM_MSI_VALID_DEVID flag is not yet a part of
> mainline, so it's not set in stone. Then, perhaps you could throw it away completely and invent
> KVM_SIGNAL_EXT_MSI ioctl for sending MSIs with device ID. This would also be consistent IMO.
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Patch

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index d20fd94..6426ae9 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1414,7 +1414,10 @@  struct kvm_irq_routing_entry {
 	__u32 gsi;
 	__u32 type;
 	__u32 flags;
-	__u32 pad;
+	union {
+		__u32 pad;
+		__u32 devid;
+	};
 	union {
 		struct kvm_irq_routing_irqchip irqchip;
 		struct kvm_irq_routing_msi msi;
@@ -1427,6 +1430,10 @@  struct kvm_irq_routing_entry {
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
+
+In case of KVM_IRQ_ROUTING_EXTENDED_MSI routing type, devid is used to convey
+the device ID.
 
 No flags are specified so far, the corresponding field must be set to zero.
 
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 2a23705..8484681 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -841,12 +841,16 @@  struct kvm_irq_routing_s390_adapter {
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
+#define KVM_IRQ_ROUTING_EXTENDED_MSI 4
 
 struct kvm_irq_routing_entry {
 	__u32 gsi;
 	__u32 type;
 	__u32 flags;
-	__u32 pad;
+	union {
+		__u32 pad;
+		__u32 devid;
+	};
 	union {
 		struct kvm_irq_routing_irqchip irqchip;
 		struct kvm_irq_routing_msi msi;