Message ID | 1409575968-5329-5-git-send-email-eric.auger@linaro.org |
---|---|
State | New |
Headers | show |
On Mon, Sep 01, 2014 at 02:52:43PM +0200, Eric Auger wrote: > In case the IRQ is forwarded, the VFIO platform IRQ handler does not > need to disable the IRQ anymore. In that mode, when the handler completes add a comma after completes > the IRQ is not deactivated but only its priority is lowered. > > Some other actor (typically a guest) is supposed to deactivate the IRQ, > allowing at that time a new physical IRQ to hit. > > In virtualization use case, the physical IRQ is automatically completed > by the interrupt controller when the guest completes the corresponding > virtual IRQ. > > Signed-off-by: Eric Auger <eric.auger@linaro.org> > --- > drivers/vfio/platform/vfio_platform_irq.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c > index 6768508..1f851b2 100644 > --- a/drivers/vfio/platform/vfio_platform_irq.c > +++ b/drivers/vfio/platform/vfio_platform_irq.c > @@ -88,13 +88,18 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id) > struct vfio_platform_irq *irq_ctx = dev_id; > unsigned long flags; > int ret = IRQ_NONE; > + struct irq_data *d; > + bool is_forwarded; > > spin_lock_irqsave(&irq_ctx->lock, flags); > > if (!irq_ctx->masked) { > ret = IRQ_HANDLED; > + d = irq_get_irq_data(irq_ctx->hwirq); > + is_forwarded = irqd_irq_forwarded(d); > > - if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED) { > + if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED && > + !is_forwarded) { > disable_irq_nosync(irq_ctx->hwirq); > irq_ctx->masked = true; > } > -- > 1.9.1 > It makes sense that these needs to be all controlled in the kernel, but I'm wondering if it would be cleaner / more correct to clear the AUTOMASKED flag when the IRQ is forwarded and have vfio refuse setting this flag as long as the irq is forwarded? -Christoffer
On 09/11/2014 05:10 AM, Christoffer Dall wrote: > On Mon, Sep 01, 2014 at 02:52:43PM +0200, Eric Auger wrote: >> In case the IRQ is forwarded, the VFIO platform IRQ handler does not >> need to disable the IRQ anymore. In that mode, when the handler completes > > add a comma after completes Hi Christoffer, ok > >> the IRQ is not deactivated but only its priority is lowered. >> >> Some other actor (typically a guest) is supposed to deactivate the IRQ, >> allowing at that time a new physical IRQ to hit. >> >> In virtualization use case, the physical IRQ is automatically completed >> by the interrupt controller when the guest completes the corresponding >> virtual IRQ. >> >> Signed-off-by: Eric Auger <eric.auger@linaro.org> >> --- >> drivers/vfio/platform/vfio_platform_irq.c | 7 ++++++- >> 1 file changed, 6 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c >> index 6768508..1f851b2 100644 >> --- a/drivers/vfio/platform/vfio_platform_irq.c >> +++ b/drivers/vfio/platform/vfio_platform_irq.c >> @@ -88,13 +88,18 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id) >> struct vfio_platform_irq *irq_ctx = dev_id; >> unsigned long flags; >> int ret = IRQ_NONE; >> + struct irq_data *d; >> + bool is_forwarded; >> >> spin_lock_irqsave(&irq_ctx->lock, flags); >> >> if (!irq_ctx->masked) { >> ret = IRQ_HANDLED; >> + d = irq_get_irq_data(irq_ctx->hwirq); >> + is_forwarded = irqd_irq_forwarded(d); >> >> - if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED) { >> + if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED && >> + !is_forwarded) { >> disable_irq_nosync(irq_ctx->hwirq); >> irq_ctx->masked = true; >> } >> -- >> 1.9.1 >> > It makes sense that these needs to be all controlled in the kernel, but > I'm wondering if it would be cleaner / more correct to clear the > AUTOMASKED flag when the IRQ is forwarded and have vfio refuse setting > this flag as long as the irq is forwarded? If I am not wrong, even if the user sets AUTOMASKED, this info never is exploited by the vfio platform driver. AUTOMASKED only is set internally to the driver, on init, for level sensitive IRQs. It seems to be the same on PCI (for INTx). I do not see anywhere the user flag curectly copied into a local storage. But I prefer to be careful ;-) If confirmed, although the flag value is exposed in the user API, the user set value never is exploited so this removes the need to check. the forwarded IRQ modality being fully dynamic currently, then I would need to update the irq_ctx->flags on each vfio_irq_handler call. I don't know if its better? Best Regards Eric > > -Christoffer >
On Thu, Sep 11, 2014 at 10:44:02AM +0200, Eric Auger wrote: > On 09/11/2014 05:10 AM, Christoffer Dall wrote: > > On Mon, Sep 01, 2014 at 02:52:43PM +0200, Eric Auger wrote: > >> In case the IRQ is forwarded, the VFIO platform IRQ handler does not > >> need to disable the IRQ anymore. In that mode, when the handler completes > > > > add a comma after completes > Hi Christoffer, > ok > > > >> the IRQ is not deactivated but only its priority is lowered. > >> > >> Some other actor (typically a guest) is supposed to deactivate the IRQ, > >> allowing at that time a new physical IRQ to hit. > >> > >> In virtualization use case, the physical IRQ is automatically completed > >> by the interrupt controller when the guest completes the corresponding > >> virtual IRQ. > >> > >> Signed-off-by: Eric Auger <eric.auger@linaro.org> > >> --- > >> drivers/vfio/platform/vfio_platform_irq.c | 7 ++++++- > >> 1 file changed, 6 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c > >> index 6768508..1f851b2 100644 > >> --- a/drivers/vfio/platform/vfio_platform_irq.c > >> +++ b/drivers/vfio/platform/vfio_platform_irq.c > >> @@ -88,13 +88,18 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id) > >> struct vfio_platform_irq *irq_ctx = dev_id; > >> unsigned long flags; > >> int ret = IRQ_NONE; > >> + struct irq_data *d; > >> + bool is_forwarded; > >> > >> spin_lock_irqsave(&irq_ctx->lock, flags); > >> > >> if (!irq_ctx->masked) { > >> ret = IRQ_HANDLED; > >> + d = irq_get_irq_data(irq_ctx->hwirq); > >> + is_forwarded = irqd_irq_forwarded(d); > >> > >> - if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED) { > >> + if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED && > >> + !is_forwarded) { > >> disable_irq_nosync(irq_ctx->hwirq); > >> irq_ctx->masked = true; > >> } > >> -- > >> 1.9.1 > >> > > It makes sense that these needs to be all controlled in the kernel, but > > I'm wondering if it would be cleaner / more correct to clear the > > AUTOMASKED flag when the IRQ is forwarded and have vfio refuse setting > > this flag as long as the irq is forwarded? > > If I am not wrong, even if the user sets AUTOMASKED, this info never is > exploited by the vfio platform driver. AUTOMASKED only is set internally > to the driver, on init, for level sensitive IRQs. > > It seems to be the same on PCI (for INTx). I do not see anywhere the > user flag curectly copied into a local storage. But I prefer to be > careful ;-) > > If confirmed, although the flag value is exposed in the user API, the > user set value never is exploited so this removes the need to check. > > the forwarded IRQ modality being fully dynamic currently, then I would > need to update the irq_ctx->flags on each vfio_irq_handler call. I don't > know if its better? > I'm not an expert on vfio, so I'll leave that to Alex Williamson to answer, but I'm just worried that we need to special-case the forwarded IRQ here, and if that may get lost elsewhere in the vfio code. If the AUTOMASKED flag covers specifically this behavior, then why don't we simply clear/set that flag when forwarding/unforwarding the specific IRQ? -Christoffer
On Thu, Sep 11, 2014 at 10:44 AM, Eric Auger <eric.auger@linaro.org> wrote: > > On 09/11/2014 05:10 AM, Christoffer Dall wrote: > > On Mon, Sep 01, 2014 at 02:52:43PM +0200, Eric Auger wrote: > >> In case the IRQ is forwarded, the VFIO platform IRQ handler does not > >> need to disable the IRQ anymore. In that mode, when the handler completes > > > > add a comma after completes > Hi Christoffer, > ok > > > >> the IRQ is not deactivated but only its priority is lowered. > >> > >> Some other actor (typically a guest) is supposed to deactivate the IRQ, > >> allowing at that time a new physical IRQ to hit. > >> > >> In virtualization use case, the physical IRQ is automatically completed > >> by the interrupt controller when the guest completes the corresponding > >> virtual IRQ. > >> > >> Signed-off-by: Eric Auger <eric.auger@linaro.org> > >> --- > >> drivers/vfio/platform/vfio_platform_irq.c | 7 ++++++- > >> 1 file changed, 6 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c > >> index 6768508..1f851b2 100644 > >> --- a/drivers/vfio/platform/vfio_platform_irq.c > >> +++ b/drivers/vfio/platform/vfio_platform_irq.c > >> @@ -88,13 +88,18 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id) > >> struct vfio_platform_irq *irq_ctx = dev_id; > >> unsigned long flags; > >> int ret = IRQ_NONE; > >> + struct irq_data *d; > >> + bool is_forwarded; > >> > >> spin_lock_irqsave(&irq_ctx->lock, flags); > >> > >> if (!irq_ctx->masked) { > >> ret = IRQ_HANDLED; > >> + d = irq_get_irq_data(irq_ctx->hwirq); > >> + is_forwarded = irqd_irq_forwarded(d); > >> > >> - if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED) { > >> + if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED && > >> + !is_forwarded) { > >> disable_irq_nosync(irq_ctx->hwirq); > >> irq_ctx->masked = true; > >> } > >> -- > >> 1.9.1 > >> > > It makes sense that these needs to be all controlled in the kernel, but > > I'm wondering if it would be cleaner / more correct to clear the > > AUTOMASKED flag when the IRQ is forwarded and have vfio refuse setting > > this flag as long as the irq is forwarded? > > If I am not wrong, even if the user sets AUTOMASKED, this info never is > exploited by the vfio platform driver. AUTOMASKED only is set internally > to the driver, on init, for level sensitive IRQs. > > It seems to be the same on PCI (for INTx). I do not see anywhere the > user flag curectly copied into a local storage. But I prefer to be > careful ;-) > > If confirmed, although the flag value is exposed in the user API, the > user set value never is exploited so this removes the need to check. > Yeah, the way the API is right now the AUTOMASKED flag is only to be communicated by the kernel to the user, never the other way around. IMHO there shouldn't be a need to change that. The flag is there just to inform the user for the kernel behavior for non-forwarded IRQs (and it's still true if the user unforwards the IRQ later). The user decides the mode of operation, but it might still be a bit of information he wants to know. > the forwarded IRQ modality being fully dynamic currently, then I would > need to update the irq_ctx->flags on each vfio_irq_handler call. I don't > know if its better? > > Best Regards > > Eric > > > > > > -Christoffer > > >
On Thu, 2014-09-11 at 19:05 +0200, Christoffer Dall wrote: > On Thu, Sep 11, 2014 at 10:44:02AM +0200, Eric Auger wrote: > > On 09/11/2014 05:10 AM, Christoffer Dall wrote: > > > On Mon, Sep 01, 2014 at 02:52:43PM +0200, Eric Auger wrote: > > >> In case the IRQ is forwarded, the VFIO platform IRQ handler does not > > >> need to disable the IRQ anymore. In that mode, when the handler completes > > > > > > add a comma after completes > > Hi Christoffer, > > ok > > > > > >> the IRQ is not deactivated but only its priority is lowered. > > >> > > >> Some other actor (typically a guest) is supposed to deactivate the IRQ, > > >> allowing at that time a new physical IRQ to hit. > > >> > > >> In virtualization use case, the physical IRQ is automatically completed > > >> by the interrupt controller when the guest completes the corresponding > > >> virtual IRQ. > > >> > > >> Signed-off-by: Eric Auger <eric.auger@linaro.org> > > >> --- > > >> drivers/vfio/platform/vfio_platform_irq.c | 7 ++++++- > > >> 1 file changed, 6 insertions(+), 1 deletion(-) > > >> > > >> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c > > >> index 6768508..1f851b2 100644 > > >> --- a/drivers/vfio/platform/vfio_platform_irq.c > > >> +++ b/drivers/vfio/platform/vfio_platform_irq.c > > >> @@ -88,13 +88,18 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id) > > >> struct vfio_platform_irq *irq_ctx = dev_id; > > >> unsigned long flags; > > >> int ret = IRQ_NONE; > > >> + struct irq_data *d; > > >> + bool is_forwarded; > > >> > > >> spin_lock_irqsave(&irq_ctx->lock, flags); > > >> > > >> if (!irq_ctx->masked) { > > >> ret = IRQ_HANDLED; > > >> + d = irq_get_irq_data(irq_ctx->hwirq); > > >> + is_forwarded = irqd_irq_forwarded(d); > > >> > > >> - if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED) { > > >> + if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED && > > >> + !is_forwarded) { > > >> disable_irq_nosync(irq_ctx->hwirq); > > >> irq_ctx->masked = true; > > >> } > > >> -- > > >> 1.9.1 > > >> > > > It makes sense that these needs to be all controlled in the kernel, but > > > I'm wondering if it would be cleaner / more correct to clear the > > > AUTOMASKED flag when the IRQ is forwarded and have vfio refuse setting > > > this flag as long as the irq is forwarded? > > > > If I am not wrong, even if the user sets AUTOMASKED, this info never is > > exploited by the vfio platform driver. AUTOMASKED only is set internally > > to the driver, on init, for level sensitive IRQs. > > > > It seems to be the same on PCI (for INTx). I do not see anywhere the > > user flag curectly copied into a local storage. But I prefer to be > > careful ;-) > > > > If confirmed, although the flag value is exposed in the user API, the > > user set value never is exploited so this removes the need to check. > > > > the forwarded IRQ modality being fully dynamic currently, then I would > > need to update the irq_ctx->flags on each vfio_irq_handler call. I don't > > know if its better? > > > I'm not an expert on vfio, so I'll leave that to Alex Williamson to > answer, but I'm just worried that we need to special-case the forwarded > IRQ here, and if that may get lost elsewhere in the vfio code. If the > AUTOMASKED flag covers specifically this behavior, then why don't we > simply clear/set that flag when forwarding/unforwarding the specific > IRQ? The way that VFIO_IRQ_INFO_AUTOMASKED is being used here is unique to the platform device vfio backend. In the rest of VFIO, VFIO_IRQ_INFO_AUTOMASKED is simply a flag bit exposed via VFIO_DEVICE_GET_IRQ_INFO. The flags field of struct vfio_irq_info is output-only. vfio-pci knows by the IRQ index whether it is edge or level. I do agree though that changing the flag bit, or better yet a bool, rather than adding extra tests that need to be handled as each usage seems less error prone. Things could get confusing for userspace though if suddenly VFIO_DEVICE_GET_IRQ_INFO starts calling the index edge triggered once forwarding mode is enabled. Thanks, Alex
diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c index 6768508..1f851b2 100644 --- a/drivers/vfio/platform/vfio_platform_irq.c +++ b/drivers/vfio/platform/vfio_platform_irq.c @@ -88,13 +88,18 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id) struct vfio_platform_irq *irq_ctx = dev_id; unsigned long flags; int ret = IRQ_NONE; + struct irq_data *d; + bool is_forwarded; spin_lock_irqsave(&irq_ctx->lock, flags); if (!irq_ctx->masked) { ret = IRQ_HANDLED; + d = irq_get_irq_data(irq_ctx->hwirq); + is_forwarded = irqd_irq_forwarded(d); - if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED) { + if (irq_ctx->flags & VFIO_IRQ_INFO_AUTOMASKED && + !is_forwarded) { disable_irq_nosync(irq_ctx->hwirq); irq_ctx->masked = true; }
In case the IRQ is forwarded, the VFIO platform IRQ handler does not need to disable the IRQ anymore. In that mode, when the handler completes the IRQ is not deactivated but only its priority is lowered. Some other actor (typically a guest) is supposed to deactivate the IRQ, allowing at that time a new physical IRQ to hit. In virtualization use case, the physical IRQ is automatically completed by the interrupt controller when the guest completes the corresponding virtual IRQ. Signed-off-by: Eric Auger <eric.auger@linaro.org> --- drivers/vfio/platform/vfio_platform_irq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)