* [PATCH v2] xen/arm: introduce PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI
@ 2014-07-02 15:33 Stefano Stabellini
2014-07-02 15:39 ` Julien Grall
2014-07-03 9:29 ` Stefano Stabellini
0 siblings, 2 replies; 3+ messages in thread
From: Stefano Stabellini @ 2014-07-02 15:33 UTC (permalink / raw)
To: xen-devel
Cc: julien.grall, apatel, Ian.Campbell, psawargaonkar,
stefano.stabellini
GICH_LR_HW doesn't work as expected on X-Gene: request maintenance
interrupts and perform EOIs in the hypervisor as a workaround.
Trigger this behaviour with a per platform option.
This patch assumes that GICC_DIR can be written on any pcpu for a given
IRQ, not matter where GICC_IAR has been read before.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: psawargaonkar@apm.com
CC: apatel@apm.com
---
Changes in v2:
- s/PLATFORM_QUIRK_NEED_EOI/PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI/g;
- improved commit message.
---
xen/arch/arm/gic.c | 13 ++++++++++++-
xen/arch/arm/platforms/xgene-storm.c | 2 +-
xen/include/asm-arm/platform.h | 5 +++++
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 1965f86..3e58c9c 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -577,7 +577,9 @@ static inline void gic_set_lr(int lr, struct pending_irq *p,
lr_val = state | (GIC_PRI_TO_GUEST(p->priority) << GICH_LR_PRIORITY_SHIFT) |
((p->irq & GICH_LR_VIRTUAL_MASK) << GICH_LR_VIRTUAL_SHIFT);
- if ( p->desc != NULL )
+ if ( platform_has_quirk(PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI) )
+ lr_val |= GICH_LR_MAINTENANCE_IRQ;
+ else if ( p->desc != NULL )
lr_val |= GICH_LR_HW | (p->desc->irq << GICH_LR_PHYSICAL_SHIFT);
GICH[GICH_LR + lr] = lr_val;
@@ -656,6 +658,11 @@ void gic_raise_guest_irq(struct vcpu *v, unsigned int virtual_irq,
gic_add_to_lr_pending(v, irq_to_pending(v, virtual_irq));
}
+static void gic_irq_eoi(int irq)
+{
+ GICC[GICC_DIR] = irq;
+}
+
static void gic_update_one_lr(struct vcpu *v, int i)
{
struct pending_irq *p;
@@ -692,7 +699,11 @@ static void gic_update_one_lr(struct vcpu *v, int i)
clear_bit(i, &this_cpu(lr_mask));
if ( p->desc != NULL )
+ {
p->desc->status &= ~IRQ_INPROGRESS;
+ if ( platform_has_quirk(PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI) )
+ gic_irq_eoi(p->irq);
+ }
clear_bit(GIC_IRQ_GUEST_VISIBLE, &p->status);
clear_bit(GIC_IRQ_GUEST_ACTIVE, &p->status);
p->lr = GIC_INVALID_LR;
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index c9dd63c..837d8e6 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -37,7 +37,7 @@ static bool reset_vals_valid = false;
static uint32_t xgene_storm_quirks(void)
{
- return PLATFORM_QUIRK_GIC_64K_STRIDE;
+ return PLATFORM_QUIRK_GIC_64K_STRIDE|PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI;
}
static int map_one_mmio(struct domain *d, const char *what,
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index bcd2097..eefaca6 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -55,6 +55,11 @@ struct platform_desc {
*/
#define PLATFORM_QUIRK_GIC_64K_STRIDE (1 << 0)
+/*
+ * Quirk for platforms where GICH_LR_HW does not work as expected.
+ */
+#define PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI (1 << 1)
+
void __init platform_init(void);
int __init platform_init_time(void);
int __init platform_specific_mapping(struct domain *d);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] xen/arm: introduce PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI
2014-07-02 15:33 [PATCH v2] xen/arm: introduce PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI Stefano Stabellini
@ 2014-07-02 15:39 ` Julien Grall
2014-07-03 9:29 ` Stefano Stabellini
1 sibling, 0 replies; 3+ messages in thread
From: Julien Grall @ 2014-07-02 15:39 UTC (permalink / raw)
To: Stefano Stabellini, xen-devel; +Cc: apatel, Ian.Campbell, psawargaonkar
Hi Stefano,
Sorry I didn't think about it before. Ian has pushed Vijay GICv2 rework
today. So you patch won't apply correctly.
On 07/02/2014 04:33 PM, Stefano Stabellini wrote:
> GICH_LR_HW doesn't work as expected on X-Gene: request maintenance
> interrupts and perform EOIs in the hypervisor as a workaround.
> Trigger this behaviour with a per platform option.
>
> This patch assumes that GICC_DIR can be written on any pcpu for a given
> IRQ, not matter where GICC_IAR has been read before.
I would replace IRQ by SGIs as if it's an SPI/PPI we are screwed. In
practice it doesn't happen :).
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] xen/arm: introduce PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI
2014-07-02 15:33 [PATCH v2] xen/arm: introduce PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI Stefano Stabellini
2014-07-02 15:39 ` Julien Grall
@ 2014-07-03 9:29 ` Stefano Stabellini
1 sibling, 0 replies; 3+ messages in thread
From: Stefano Stabellini @ 2014-07-03 9:29 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel, apatel, Ian.Campbell, julien.grall, psawargaonkar
On Wed, 2 Jul 2014, Stefano Stabellini wrote:
> GICH_LR_HW doesn't work as expected on X-Gene: request maintenance
> interrupts and perform EOIs in the hypervisor as a workaround.
> Trigger this behaviour with a per platform option.
>
> This patch assumes that GICC_DIR can be written on any pcpu for a given
> IRQ, not matter where GICC_IAR has been read before.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> CC: psawargaonkar@apm.com
> CC: apatel@apm.com
> ---
>
> Changes in v2:
> - s/PLATFORM_QUIRK_NEED_EOI/PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI/g;
> - improved commit message.
>
> ---
>
> xen/arch/arm/gic.c | 13 ++++++++++++-
> xen/arch/arm/platforms/xgene-storm.c | 2 +-
> xen/include/asm-arm/platform.h | 5 +++++
> 3 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 1965f86..3e58c9c 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -577,7 +577,9 @@ static inline void gic_set_lr(int lr, struct pending_irq *p,
>
> lr_val = state | (GIC_PRI_TO_GUEST(p->priority) << GICH_LR_PRIORITY_SHIFT) |
> ((p->irq & GICH_LR_VIRTUAL_MASK) << GICH_LR_VIRTUAL_SHIFT);
> - if ( p->desc != NULL )
> + if ( platform_has_quirk(PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI) )
> + lr_val |= GICH_LR_MAINTENANCE_IRQ;
> + else if ( p->desc != NULL )
> lr_val |= GICH_LR_HW | (p->desc->irq << GICH_LR_PHYSICAL_SHIFT);
Actually I had a better idea: we could still avoid maintenance
interrupts for virtual interrupts (vtimer and evtchn_irq).
I'll resubmit.
> GICH[GICH_LR + lr] = lr_val;
> @@ -656,6 +658,11 @@ void gic_raise_guest_irq(struct vcpu *v, unsigned int virtual_irq,
> gic_add_to_lr_pending(v, irq_to_pending(v, virtual_irq));
> }
>
> +static void gic_irq_eoi(int irq)
> +{
> + GICC[GICC_DIR] = irq;
> +}
> +
> static void gic_update_one_lr(struct vcpu *v, int i)
> {
> struct pending_irq *p;
> @@ -692,7 +699,11 @@ static void gic_update_one_lr(struct vcpu *v, int i)
> clear_bit(i, &this_cpu(lr_mask));
>
> if ( p->desc != NULL )
> + {
> p->desc->status &= ~IRQ_INPROGRESS;
> + if ( platform_has_quirk(PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI) )
> + gic_irq_eoi(p->irq);
> + }
> clear_bit(GIC_IRQ_GUEST_VISIBLE, &p->status);
> clear_bit(GIC_IRQ_GUEST_ACTIVE, &p->status);
> p->lr = GIC_INVALID_LR;
> diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
> index c9dd63c..837d8e6 100644
> --- a/xen/arch/arm/platforms/xgene-storm.c
> +++ b/xen/arch/arm/platforms/xgene-storm.c
> @@ -37,7 +37,7 @@ static bool reset_vals_valid = false;
>
> static uint32_t xgene_storm_quirks(void)
> {
> - return PLATFORM_QUIRK_GIC_64K_STRIDE;
> + return PLATFORM_QUIRK_GIC_64K_STRIDE|PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI;
> }
>
> static int map_one_mmio(struct domain *d, const char *what,
> diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
> index bcd2097..eefaca6 100644
> --- a/xen/include/asm-arm/platform.h
> +++ b/xen/include/asm-arm/platform.h
> @@ -55,6 +55,11 @@ struct platform_desc {
> */
> #define PLATFORM_QUIRK_GIC_64K_STRIDE (1 << 0)
>
> +/*
> + * Quirk for platforms where GICH_LR_HW does not work as expected.
> + */
> +#define PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI (1 << 1)
> +
> void __init platform_init(void);
> int __init platform_init_time(void);
> int __init platform_specific_mapping(struct domain *d);
> --
> 1.7.10.4
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-07-03 9:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-02 15:33 [PATCH v2] xen/arm: introduce PLATFORM_QUIRK_GUEST_PIRQ_NEED_EOI Stefano Stabellini
2014-07-02 15:39 ` Julien Grall
2014-07-03 9:29 ` Stefano Stabellini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.