Message ID | 1457072152-16128-17-git-send-email-zhaoshenglong@huawei.com |
---|---|
State | Superseded |
Headers | show |
On 2016年03月04日 19:26, Stefano Stabellini wrote: > On Fri, 4 Mar 2016, Shannon Zhao wrote: >> > From: Shannon Zhao <shannon.zhao@linaro.org> >> > >> > Interrupt information is described in DSDT and is not available at the >> > time of booting. Check if the interrupt is permitted to access and set >> > the interrupt type, route it to guest dynamically only for SPI >> > and Dom0. >> > >> > Signed-off-by: Parth Dixit <parth.dixit@linaro.org> >> > Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org> >> > --- >> > v5: add a small function to get the irq type from ICFG >> > --- >> > xen/arch/arm/vgic.c | 38 ++++++++++++++++++++++++++++++++++++++ >> > 1 file changed, 38 insertions(+) >> > >> > diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c >> > index ee35683..52378a3 100644 >> > --- a/xen/arch/arm/vgic.c >> > +++ b/xen/arch/arm/vgic.c >> > @@ -25,6 +25,8 @@ >> > #include <xen/irq.h> >> > #include <xen/sched.h> >> > #include <xen/perfc.h> >> > +#include <xen/iocap.h> >> > +#include <xen/acpi.h> >> > >> > #include <asm/current.h> >> > >> > @@ -334,6 +336,21 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) >> > } >> > } >> > >> > +#ifdef CONFIG_ACPI >> > +#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) ) > remove spaces: ^ ^ ^ ^ > >> > +static unsigned int get_the_irq_type(struct vcpu *v, int n, int index) > static inline > > >> > +{ >> > + struct vgic_irq_rank *vr = vgic_get_rank(v, n); >> > + uint32_t tr = vr->icfg[index >> 4]; >> > + >> > + if ( tr & VGIC_ICFG_MASK(index) ) >> > + return IRQ_TYPE_EDGE_BOTH; >> > + else >> > + return IRQ_TYPE_LEVEL_MASK; >> > +} >> > +#endif >> > + >> > void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) >> > { >> > const unsigned long mask = r; >> > @@ -342,9 +359,30 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) >> > unsigned long flags; >> > int i = 0; >> > struct vcpu *v_target; >> > +#ifdef CONFIG_ACPI >> > + struct domain *d = v->domain; >> > + int ret; >> > +#endif >> > >> > while ( (i = find_next_bit(&mask, 32, i)) < 32 ) { >> > irq = i + (32 * n); >> > +#ifdef CONFIG_ACPI >> > + /* Set the irq type and route it to guest only for SPI and Dom0 */ >> > + if( irq_access_permitted(d, irq) && is_hardware_domain(d) && >> > + ( irq >= 32 ) && ( !acpi_disabled ) ) > Is there a reason why we need to have this code inside an ifdef? It > looks like we can remove all ifdefs from this patch. > > Ah, right! Will remove it. Thanks,
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index ee35683..52378a3 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -25,6 +25,8 @@ #include <xen/irq.h> #include <xen/sched.h> #include <xen/perfc.h> +#include <xen/iocap.h> +#include <xen/acpi.h> #include <asm/current.h> @@ -334,6 +336,21 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) } } +#ifdef CONFIG_ACPI +#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) ) + +static unsigned int get_the_irq_type(struct vcpu *v, int n, int index) +{ + struct vgic_irq_rank *vr = vgic_get_rank(v, n); + uint32_t tr = vr->icfg[index >> 4]; + + if ( tr & VGIC_ICFG_MASK(index) ) + return IRQ_TYPE_EDGE_BOTH; + else + return IRQ_TYPE_LEVEL_MASK; +} +#endif + void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) { const unsigned long mask = r; @@ -342,9 +359,30 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) unsigned long flags; int i = 0; struct vcpu *v_target; +#ifdef CONFIG_ACPI + struct domain *d = v->domain; + int ret; +#endif while ( (i = find_next_bit(&mask, 32, i)) < 32 ) { irq = i + (32 * n); +#ifdef CONFIG_ACPI + /* Set the irq type and route it to guest only for SPI and Dom0 */ + if( irq_access_permitted(d, irq) && is_hardware_domain(d) && + ( irq >= 32 ) && ( !acpi_disabled ) ) + { + ret = irq_set_spi_type(irq, get_the_irq_type(v, n, i)); + if ( ret ) + printk(XENLOG_WARNING "The irq type is not correct\n"); + + vgic_reserve_virq(d, irq); + + ret = route_irq_to_guest(d, irq, irq, NULL); + if ( ret ) + printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n", + irq, d->domain_id); + } +#endif v_target = __vgic_get_target_vcpu(v, irq); p = irq_to_pending(v_target, irq); set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);