lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 30 Nov 2010 10:42:18 -0500
From:	Stephen Caudle <scaudle@...eaurora.org>
To:	linux@....linux.org.uk
CC:	linux-arm-kernel@...ts.infradead.org,
	linux-arm-msm@...r.kernel.org, linux-kernel@...r.kernel.org,
	dwalker@...eaurora.org, adharmap@...eaurora.org, miltonm@....com
Subject: Re: [PATCH v2] [ARM] gic: Unmask private interrupts on all cores
 during IRQ enable

Russell,

Can you pull in this patch or let me know if you want something changed 
with it?

Thanks,
Stephen

On 11/03/2010 05:46 PM, Stephen Caudle wrote:
> Some multi-core ARM chips designate a unique IRQ number for each core for
> private peripheral interrupts (PPIs). Others designate a common IRQ number
> for all cores. In the latter case, requesting/freeing private peripheral
> interrupts currently unmasks/masks the interrupt for only the
> executing core, respectively.
>
> With this change, request_irq will unmask a PPI on all cores so a separate
> call to enable_irq on the other cores is not required. Likewise, free_irq
> will mask a PPI on the other cores. Also, shutdown is implemented instead
> of disable to allow for lazy IRQ disabling.
>
> Signed-off-by: Stephen Caudle<scaudle@...eaurora.org>
> ---
>   arch/arm/Kconfig      |    5 +++
>   arch/arm/common/gic.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 91 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 30ddd06..7f11e31 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1153,6 +1153,11 @@ config SMP
>
>   	  If you don't know what to do here, say N.
>
> +config IRQ_PER_CPU
> +	bool
> +	depends on SMP
> +	default n
> +
>   config HAVE_ARM_SCU
>   	bool
>   	depends on SMP
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index 886daaf..937a33a 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -44,12 +44,25 @@ struct gic_chip_data {
>   	unsigned int wakeup_irqs[32];
>   	unsigned int enabled_irqs[32];
>   #endif
> +#ifdef CONFIG_IRQ_PER_CPU
> +	struct call_single_data ppi_data[NR_CPUS];
> +#endif
>   };
>
>   #ifndef MAX_GIC_NR
>   #define MAX_GIC_NR	1
>   #endif
>
> +#ifdef CONFIG_IRQ_PER_CPU
> +#ifndef GIC_PPI_FIRST
> +#define GIC_PPI_FIRST	16
> +#endif
> +
> +#ifndef GIC_PPI_LAST
> +#define GIC_PPI_LAST	31
> +#endif
> +#endif
> +
>   static struct gic_chip_data gic_data[MAX_GIC_NR];
>
>   static inline void __iomem *gic_dist_base(unsigned int irq)
> @@ -272,6 +285,75 @@ static int gic_set_type(unsigned int irq, unsigned int type)
>   	return 0;
>   }
>
> +#ifdef CONFIG_IRQ_PER_CPU
> +static inline void gic_smp_call_function(struct call_single_data *data)
> +{
> +	int cpu;
> +
> +	/* Make sure data is visible */
> +	smp_mb();
> +
> +	/*
> +	 * Since this function is called with interrupts disabled,
> +	 * smp_call_function can't be used here because it warns (even
> +	 * if wait = 0) when interrupts are disabled.
> +	 *
> +	 * __smp_call_function_single doesn't warn when interrupts are
> +	 * disabled and not waiting, so use it instead.
> +	 */
> +	for_each_online_cpu(cpu)
> +		if (cpu != smp_processor_id())
> +			__smp_call_function_single(cpu, data, 0);
> +}
> +
> +static void gic_mask_ppi(void *info)
> +{
> +	struct irq_desc *desc = info;
> +	gic_mask_irq(desc->irq);
> +}
> +
> +static void gic_unmask_ppi(void *info)
> +{
> +	struct irq_desc *desc = info;
> +	gic_unmask_irq(desc->irq);
> +}
> +
> +static void gic_enable_irq(unsigned int irq)
> +{
> +	struct irq_desc *desc = irq_to_desc(irq);
> +	struct gic_chip_data *gic_data = get_irq_chip_data(irq);
> +	int cpu = smp_processor_id();
> +
> +	if (irq>= GIC_PPI_FIRST&&  irq<= GIC_PPI_LAST) {
> +		gic_data->ppi_data[cpu].func = gic_unmask_ppi;
> +		gic_data->ppi_data[cpu].info = desc;
> +
> +		/* Unmask PPIs on all cores during enable. */
> +		gic_smp_call_function(&gic_data->ppi_data[cpu]);
> +	}
> +
> +	desc->chip->unmask(irq);
> +	desc->status&= ~IRQ_MASKED;
> +}
> +
> +static void gic_shutdown_irq(unsigned int irq)
> +{
> +	struct irq_desc *desc = irq_to_desc(irq);
> +	struct gic_chip_data *gic_data = get_irq_chip_data(irq);
> +	int cpu = smp_processor_id();
> +
> +	if (irq>= GIC_PPI_FIRST&&  irq<= GIC_PPI_LAST) {
> +		gic_data->ppi_data[cpu].func = gic_mask_ppi;
> +		gic_data->ppi_data[cpu].info = desc;
> +
> +		/* Mask PPIs on all cores during disable. */
> +		gic_smp_call_function(&gic_data->ppi_data[cpu]);
> +	}
> +
> +	desc->chip->mask(irq);
> +	desc->status |= IRQ_MASKED;
> +}
> +#endif
>
>   static struct irq_chip gic_chip = {
>   	.name		= "GIC",
> @@ -283,6 +365,10 @@ static struct irq_chip gic_chip = {
>   #endif
>   	.set_type	= gic_set_type,
>   	.set_wake	= gic_set_wake,
> +#ifdef CONFIG_IRQ_PER_CPU
> +	.enable		= gic_enable_irq,
> +	.shutdown	= gic_shutdown_irq,
> +#endif
>   };
>
>   void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)


-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ