All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][STABLE 4.9] irqchip/gic: Atomically update affinity
@ 2020-07-07 15:37 Marc Zyngier
  2020-07-09 14:30 ` Sasha Levin
  2020-07-20 12:27 ` Greg KH
  0 siblings, 2 replies; 3+ messages in thread
From: Marc Zyngier @ 2020-07-07 15:37 UTC (permalink / raw)
  To: stable; +Cc: kernel-team

Commit 005c34ae4b44f085120d7f371121ec7ded677761 upstream.

The GIC driver uses a RMW sequence to update the affinity, and
relies on the gic_lock_irqsave/gic_unlock_irqrestore sequences
to update it atomically.

But these sequences only expand into anything meaningful if
the BL_SWITCHER option is selected, which almost never happens.

It also turns out that using a RMW and locks is just as silly,
as the GIC distributor supports byte accesses for the GICD_TARGETRn
registers, which when used make the update atomic by definition.

Drop the terminally broken code and replace it by a byte write.

Fixes: 04c8b0f82c7d ("irqchip/gic: Make locking a BL_SWITCHER only feature")
Cc: stable@vger.kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index d6c404b3584d..006b17593c12 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -324,10 +324,8 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
-	void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
-	unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
-	u32 val, mask, bit;
-	unsigned long flags;
+	void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d);
+	unsigned int cpu;
 
 	if (!force)
 		cpu = cpumask_any_and(mask_val, cpu_online_mask);
@@ -337,12 +335,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 	if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
 		return -EINVAL;
 
-	gic_lock_irqsave(flags);
-	mask = 0xff << shift;
-	bit = gic_cpu_map[cpu] << shift;
-	val = readl_relaxed(reg) & ~mask;
-	writel_relaxed(val | bit, reg);
-	gic_unlock_irqrestore(flags);
+	writeb_relaxed(gic_cpu_map[cpu], reg);
 
 	return IRQ_SET_MASK_OK_DONE;
 }
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH][STABLE 4.9] irqchip/gic: Atomically update affinity
  2020-07-07 15:37 [PATCH][STABLE 4.9] irqchip/gic: Atomically update affinity Marc Zyngier
@ 2020-07-09 14:30 ` Sasha Levin
  2020-07-20 12:27 ` Greg KH
  1 sibling, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2020-07-09 14:30 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: stable, kernel-team

On Tue, Jul 07, 2020 at 04:37:41PM +0100, Marc Zyngier wrote:
>Commit 005c34ae4b44f085120d7f371121ec7ded677761 upstream.
>
>The GIC driver uses a RMW sequence to update the affinity, and
>relies on the gic_lock_irqsave/gic_unlock_irqrestore sequences
>to update it atomically.
>
>But these sequences only expand into anything meaningful if
>the BL_SWITCHER option is selected, which almost never happens.
>
>It also turns out that using a RMW and locks is just as silly,
>as the GIC distributor supports byte accesses for the GICD_TARGETRn
>registers, which when used make the update atomic by definition.
>
>Drop the terminally broken code and replace it by a byte write.
>
>Fixes: 04c8b0f82c7d ("irqchip/gic: Make locking a BL_SWITCHER only feature")
>Cc: stable@vger.kernel.org
>Signed-off-by: Marc Zyngier <maz@kernel.org>

Queued for 4.9, thanks!

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][STABLE 4.9] irqchip/gic: Atomically update affinity
  2020-07-07 15:37 [PATCH][STABLE 4.9] irqchip/gic: Atomically update affinity Marc Zyngier
  2020-07-09 14:30 ` Sasha Levin
@ 2020-07-20 12:27 ` Greg KH
  1 sibling, 0 replies; 3+ messages in thread
From: Greg KH @ 2020-07-20 12:27 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: stable, kernel-team

On Tue, Jul 07, 2020 at 04:37:41PM +0100, Marc Zyngier wrote:
> Commit 005c34ae4b44f085120d7f371121ec7ded677761 upstream.
> 
> The GIC driver uses a RMW sequence to update the affinity, and
> relies on the gic_lock_irqsave/gic_unlock_irqrestore sequences
> to update it atomically.
> 
> But these sequences only expand into anything meaningful if
> the BL_SWITCHER option is selected, which almost never happens.
> 
> It also turns out that using a RMW and locks is just as silly,
> as the GIC distributor supports byte accesses for the GICD_TARGETRn
> registers, which when used make the update atomic by definition.
> 
> Drop the terminally broken code and replace it by a byte write.
> 
> Fixes: 04c8b0f82c7d ("irqchip/gic: Make locking a BL_SWITCHER only feature")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/irqchip/irq-gic.c | 13 +++----------
>  1 file changed, 3 insertions(+), 10 deletions(-)

Thanks for the backport, now queued up.

greg k-h

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-07-20 12:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-07 15:37 [PATCH][STABLE 4.9] irqchip/gic: Atomically update affinity Marc Zyngier
2020-07-09 14:30 ` Sasha Levin
2020-07-20 12:27 ` Greg KH

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.