All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v12 0/7] arm64: Add IPI for backtraces / kgdb; try to use NMI for some IPIs
@ 2023-08-30 19:11 ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Frederic Weisbecker, Ingo Molnar,
	Josh Poimboeuf, Kees Cook, Philippe Mathieu-Daudé,
	Sami Tolvanen, Valentin Schneider, linux-kernel

This is an attempt to resurrect Sumit's old patch series [1] that
allowed us to use the arm64 pseudo-NMI to get backtraces of CPUs and
also to round up CPUs in kdb/kgdb. The last post from Sumit that I
could find was v7, so I started my series at v8. I haven't copied all
of his old changelongs here, but you can find them from the link.

This patch series targets v6.6. Specifically it can't land in v6.5
since it depends on commit 8d539b84f1e3 ("nmi_backtrace: allow
excluding an arbitrary CPU").

It should be noted that Mark still feels there might be some corner
cases where pseudo-NMI is not production ready [2] [3], but as far as
I'm aware there are no concrete/documented issues. Regardless of
whether this should be enabled for production, though, this series
will be invaluable to anyone trying to debug crashes on arm64
machines.

v12 of this series collects tags, fixes a few small nits in comments
and commit messages from v11 and adds a new (and somewhat unrelated)
small patch to the end of the series. There are no code changes other
than the last patch, which is tiny.

v11 of this series addressed Stephen Boyd's feedback on v10 and added
a missing "static" that the patches robot found.

v10 of this series attempted to address all of Mark's feedback on
v9. As a quick summary:
- It includes his patch to remove IPI_WAKEUP, freeing up an extra IPI.
- It no longer combines the "kgdb" and "backtrace" IPIs. If we need
  another IPI these could always be recombined later.
- It promotes IPI_CPU_STOP and IPI_CPU_CRASH_STOP to NMI.
- It puts nearly all the code directly in smp.c.
- Several of the patches are squashed together.
- Patch #6 ("kgdb: Provide a stub kgdb_nmicallback() if !CONFIG_KGDB")
  was dropped from the series since it landed.

Between v8 and v9, I had cleaned up this patch series by integrating
the 10th patch from v8 [4] into the whole series. As part of this, I
renamed the "NMI IPI" to the "debug IPI" since it could now be backed
by a regular IPI in the case that pseudo NMIs weren't available. With
the fallback, this allowed me to drop some extra patches from the
series. This feels (to me) to be pretty clean and hopefully others
agree. Any patch I touched significantly I removed Masayoshi and
Chen-Yu's tags from.

...also in v8, I reorderd the patches a bit in a way that seemed a
little cleaner to me.

Since v7, I have:
* Addressed the small amount of feedback that was there for v7.
* Rebased.
* Added a new patch that prevents us from spamming the logs with idle
  tasks.
* Added an extra patch to gracefully fall back to regular IPIs if
  pseudo-NMIs aren't there.

It can be noted that this patch series works very well with the recent
"hardlockup" patches that have landed through Andrew Morton's tree and
are currently in mainline. It works especially well with the "buddy"
lockup detector.

[1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg@linaro.org/
[2] https://lore.kernel.org/lkml/ZFvGqD%2F%2Fpm%2FlZb+p@FVFF77S0Q05N.cambridge.arm.com/
[3] https://lore.kernel.org/lkml/ZNDKVP2m-iiZCz3v@FVFF77S0Q05N.cambridge.arm.com
[4] https://lore.kernel.org/r/20230419155341.v8.10.Ic3659997d6243139d0522fc3afcdfd88d7a5f030@changeid/

Changes in v12:
- ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.
- Added a comment about why we account for 16 SGIs when Linux uses 8.
- Minor comment change to add "()" after nmi_trigger_cpumask_backtrace.
- Updated the commit hash of the commit this depends on.

Changes in v11:
- Adjust comment about NR_IPI/MAX_IPI.
- Don't use confusing "backed by" idiom in comment.
- Made arm64_backtrace_ipi() static.
- Updated commit message as per Stephen.
- arch_send_wakeup_ipi() now takes an unsigned int.

Changes in v10:
- ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.
- ("arm64: smp: Remove dedicated wakeup IPI") new for v10.
- Backtrace now directly supported in smp.c
- Don't allocate the cpumask on the stack; just iterate.
- Moved kgdb calls to smp.c to avoid needing to export IPI info.
- Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
- Squash backtrace into patch adding support for pseudo-NMI IPIs.
- kgdb now has its own IPI.

Changes in v9:
- Added comments that we might not be using NMI always.
- Added to commit message that this doesn't catch all cases.
- Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
- Moved header file out of "include" since it didn't need to be there.
- Remove arm64_supports_nmi()
- Remove fallback for when debug IPI isn't available.
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
- arch_trigger_cpumask_backtrace() no longer returns bool

Changes in v8:
- "Tag the arm64 idle functions as __cpuidle" new for v8
- Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
- debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param

Douglas Anderson (6):
  irqchip/gic-v3: Enable support for SGIs to act as NMIs
  arm64: idle: Tag the arm64 idle functions as __cpuidle
  arm64: smp: Add arch support for backtrace using pseudo-NMI
  arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
  arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI
    roundup
  arm64: smp: Mark IPI globals as __ro_after_init

Mark Rutland (1):
  arm64: smp: Remove dedicated wakeup IPI

 arch/arm64/include/asm/irq.h              |   3 +
 arch/arm64/include/asm/smp.h              |   4 +-
 arch/arm64/kernel/acpi_parking_protocol.c |   2 +-
 arch/arm64/kernel/idle.c                  |   4 +-
 arch/arm64/kernel/smp.c                   | 139 +++++++++++++++++-----
 drivers/irqchip/irq-gic-v3.c              |  59 ++++++---
 6 files changed, 160 insertions(+), 51 deletions(-)

-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 0/7] arm64: Add IPI for backtraces / kgdb; try to use NMI for some IPIs
@ 2023-08-30 19:11 ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Frederic Weisbecker, Ingo Molnar,
	Josh Poimboeuf, Kees Cook, Philippe Mathieu-Daudé,
	Sami Tolvanen, Valentin Schneider, linux-kernel

This is an attempt to resurrect Sumit's old patch series [1] that
allowed us to use the arm64 pseudo-NMI to get backtraces of CPUs and
also to round up CPUs in kdb/kgdb. The last post from Sumit that I
could find was v7, so I started my series at v8. I haven't copied all
of his old changelongs here, but you can find them from the link.

This patch series targets v6.6. Specifically it can't land in v6.5
since it depends on commit 8d539b84f1e3 ("nmi_backtrace: allow
excluding an arbitrary CPU").

It should be noted that Mark still feels there might be some corner
cases where pseudo-NMI is not production ready [2] [3], but as far as
I'm aware there are no concrete/documented issues. Regardless of
whether this should be enabled for production, though, this series
will be invaluable to anyone trying to debug crashes on arm64
machines.

v12 of this series collects tags, fixes a few small nits in comments
and commit messages from v11 and adds a new (and somewhat unrelated)
small patch to the end of the series. There are no code changes other
than the last patch, which is tiny.

v11 of this series addressed Stephen Boyd's feedback on v10 and added
a missing "static" that the patches robot found.

v10 of this series attempted to address all of Mark's feedback on
v9. As a quick summary:
- It includes his patch to remove IPI_WAKEUP, freeing up an extra IPI.
- It no longer combines the "kgdb" and "backtrace" IPIs. If we need
  another IPI these could always be recombined later.
- It promotes IPI_CPU_STOP and IPI_CPU_CRASH_STOP to NMI.
- It puts nearly all the code directly in smp.c.
- Several of the patches are squashed together.
- Patch #6 ("kgdb: Provide a stub kgdb_nmicallback() if !CONFIG_KGDB")
  was dropped from the series since it landed.

Between v8 and v9, I had cleaned up this patch series by integrating
the 10th patch from v8 [4] into the whole series. As part of this, I
renamed the "NMI IPI" to the "debug IPI" since it could now be backed
by a regular IPI in the case that pseudo NMIs weren't available. With
the fallback, this allowed me to drop some extra patches from the
series. This feels (to me) to be pretty clean and hopefully others
agree. Any patch I touched significantly I removed Masayoshi and
Chen-Yu's tags from.

...also in v8, I reorderd the patches a bit in a way that seemed a
little cleaner to me.

Since v7, I have:
* Addressed the small amount of feedback that was there for v7.
* Rebased.
* Added a new patch that prevents us from spamming the logs with idle
  tasks.
* Added an extra patch to gracefully fall back to regular IPIs if
  pseudo-NMIs aren't there.

It can be noted that this patch series works very well with the recent
"hardlockup" patches that have landed through Andrew Morton's tree and
are currently in mainline. It works especially well with the "buddy"
lockup detector.

[1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg@linaro.org/
[2] https://lore.kernel.org/lkml/ZFvGqD%2F%2Fpm%2FlZb+p@FVFF77S0Q05N.cambridge.arm.com/
[3] https://lore.kernel.org/lkml/ZNDKVP2m-iiZCz3v@FVFF77S0Q05N.cambridge.arm.com
[4] https://lore.kernel.org/r/20230419155341.v8.10.Ic3659997d6243139d0522fc3afcdfd88d7a5f030@changeid/

Changes in v12:
- ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.
- Added a comment about why we account for 16 SGIs when Linux uses 8.
- Minor comment change to add "()" after nmi_trigger_cpumask_backtrace.
- Updated the commit hash of the commit this depends on.

Changes in v11:
- Adjust comment about NR_IPI/MAX_IPI.
- Don't use confusing "backed by" idiom in comment.
- Made arm64_backtrace_ipi() static.
- Updated commit message as per Stephen.
- arch_send_wakeup_ipi() now takes an unsigned int.

Changes in v10:
- ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.
- ("arm64: smp: Remove dedicated wakeup IPI") new for v10.
- Backtrace now directly supported in smp.c
- Don't allocate the cpumask on the stack; just iterate.
- Moved kgdb calls to smp.c to avoid needing to export IPI info.
- Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
- Squash backtrace into patch adding support for pseudo-NMI IPIs.
- kgdb now has its own IPI.

Changes in v9:
- Added comments that we might not be using NMI always.
- Added to commit message that this doesn't catch all cases.
- Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
- Moved header file out of "include" since it didn't need to be there.
- Remove arm64_supports_nmi()
- Remove fallback for when debug IPI isn't available.
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
- arch_trigger_cpumask_backtrace() no longer returns bool

Changes in v8:
- "Tag the arm64 idle functions as __cpuidle" new for v8
- Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
- debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param

Douglas Anderson (6):
  irqchip/gic-v3: Enable support for SGIs to act as NMIs
  arm64: idle: Tag the arm64 idle functions as __cpuidle
  arm64: smp: Add arch support for backtrace using pseudo-NMI
  arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
  arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI
    roundup
  arm64: smp: Mark IPI globals as __ro_after_init

Mark Rutland (1):
  arm64: smp: Remove dedicated wakeup IPI

 arch/arm64/include/asm/irq.h              |   3 +
 arch/arm64/include/asm/smp.h              |   4 +-
 arch/arm64/kernel/acpi_parking_protocol.c |   2 +-
 arch/arm64/kernel/idle.c                  |   4 +-
 arch/arm64/kernel/smp.c                   | 139 +++++++++++++++++-----
 drivers/irqchip/irq-gic-v3.c              |  59 ++++++---
 6 files changed, 160 insertions(+), 51 deletions(-)

-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	linux-kernel

As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
and use handle_percpu_devid_irq() by default. Unfortunately,
handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
context those should use handle_percpu_devid_fasteoi_nmi().

In order to accomplish this, we just have to make room for SGIs in the
array of refcounts that keeps track of which interrupts are set as
NMI. We also rename the array and create a new indexing scheme that
accounts for SGIs.

Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
as IRQs/NMIs happen as part of this routine.

Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I'll note that this change is a little more black magic to me than
others in this series. I don't have a massive amounts of familiarity
with all the moving parts of gic-v3, so I mostly just followed Mark
Rutland's advice [1]. Please pay extra attention to make sure I didn't
do anything too terrible.

Mark's advice wasn't a full patch and I ended up doing a bit of work
to translate it to reality, so I did not add him as "Co-developed-by"
here. Mark: if you would like this tag then please provide it and your
Signed-off-by. I certainly won't object.

[1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com

Changes in v12:
- Added a comment about why we account for 16 SGIs when Linux uses 8.

Changes in v10:
- Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.

 drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index eedfa8e9f077..8d20122ba0a8 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
 #define GIC_LINE_NR	min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
 #define GIC_ESPI_NR	GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
 
+/*
+ * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
+ * are potentially stolen by the secure side. Some code, especially code dealing
+ * with hwirq IDs, is simplified by accounting for all 16.
+ */
+#define SGI_NR		16
+
 /*
  * The behaviours of RPR and PMR registers differ depending on the value of
  * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
@@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
 		__priority;						\
 	})
 
-/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
-static refcount_t *ppi_nmi_refs;
+/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
+static refcount_t *rdist_nmi_refs;
 
 static struct gic_kvm_info gic_v3_kvm_info __initdata;
 static DEFINE_PER_CPU(bool, has_rss);
@@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
 	}
 }
 
-static u32 gic_get_ppi_index(struct irq_data *d)
+static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
+{
+	switch (__get_intid_range(hwirq)) {
+	case SGI_RANGE:
+	case PPI_RANGE:
+		return hwirq;
+	case EPPI_RANGE:
+		return hwirq - EPPI_BASE_INTID + 32;
+	default:
+		unreachable();
+	}
+}
+
+static u32 gic_get_rdist_idx(struct irq_data *d)
 {
-	return __gic_get_ppi_index(d->hwirq);
+	return __gic_get_rdist_idx(d->hwirq);
 }
 
 static int gic_irq_nmi_setup(struct irq_data *d)
@@ -545,11 +565,14 @@ static int gic_irq_nmi_setup(struct irq_data *d)
 
 	/* desc lock should already be held */
 	if (gic_irq_in_rdist(d)) {
-		u32 idx = gic_get_ppi_index(d);
+		u32 idx = gic_get_rdist_idx(d);
 
-		/* Setting up PPI as NMI, only switch handler for first NMI */
-		if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
-			refcount_set(&ppi_nmi_refs[idx], 1);
+		/*
+		 * Setting up a percpu interrupt as NMI, only switch handler
+		 * for first NMI
+		 */
+		if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
+			refcount_set(&rdist_nmi_refs[idx], 1);
 			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
 		}
 	} else {
@@ -582,10 +605,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
 
 	/* desc lock should already be held */
 	if (gic_irq_in_rdist(d)) {
-		u32 idx = gic_get_ppi_index(d);
+		u32 idx = gic_get_rdist_idx(d);
 
 		/* Tearing down NMI, only switch handler for last NMI */
-		if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
+		if (refcount_dec_and_test(&rdist_nmi_refs[idx]))
 			desc->handle_irq = handle_percpu_devid_irq;
 	} else {
 		desc->handle_irq = handle_fasteoi_irq;
@@ -1279,10 +1302,10 @@ static void gic_cpu_init(void)
 	rbase = gic_data_rdist_sgi_base();
 
 	/* Configure SGIs/PPIs as non-secure Group-1 */
-	for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
+	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
 		writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
 
-	gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
+	gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp);
 
 	/* initialise system registers */
 	gic_cpu_sys_reg_init();
@@ -1939,12 +1962,13 @@ static void gic_enable_nmi_support(void)
 		return;
 	}
 
-	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
-	if (!ppi_nmi_refs)
+	rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,
+				 sizeof(*rdist_nmi_refs), GFP_KERNEL);
+	if (!rdist_nmi_refs)
 		return;
 
-	for (i = 0; i < gic_data.ppi_nr; i++)
-		refcount_set(&ppi_nmi_refs[i], 0);
+	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i++)
+		refcount_set(&rdist_nmi_refs[i], 0);
 
 	pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n",
 		gic_has_relaxed_pmr_sync() ? "relaxed" : "forced");
@@ -2061,6 +2085,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
 
 	gic_dist_init();
 	gic_cpu_init();
+	gic_enable_nmi_support();
 	gic_smp_init();
 	gic_cpu_pm_init();
 
@@ -2073,8 +2098,6 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
 			gicv2m_init(handle, gic_data.domain);
 	}
 
-	gic_enable_nmi_support();
-
 	return 0;
 
 out_free:
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	linux-kernel

As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
and use handle_percpu_devid_irq() by default. Unfortunately,
handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
context those should use handle_percpu_devid_fasteoi_nmi().

In order to accomplish this, we just have to make room for SGIs in the
array of refcounts that keeps track of which interrupts are set as
NMI. We also rename the array and create a new indexing scheme that
accounts for SGIs.

Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
as IRQs/NMIs happen as part of this routine.

Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I'll note that this change is a little more black magic to me than
others in this series. I don't have a massive amounts of familiarity
with all the moving parts of gic-v3, so I mostly just followed Mark
Rutland's advice [1]. Please pay extra attention to make sure I didn't
do anything too terrible.

Mark's advice wasn't a full patch and I ended up doing a bit of work
to translate it to reality, so I did not add him as "Co-developed-by"
here. Mark: if you would like this tag then please provide it and your
Signed-off-by. I certainly won't object.

[1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com

Changes in v12:
- Added a comment about why we account for 16 SGIs when Linux uses 8.

Changes in v10:
- Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.

 drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index eedfa8e9f077..8d20122ba0a8 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
 #define GIC_LINE_NR	min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
 #define GIC_ESPI_NR	GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
 
+/*
+ * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
+ * are potentially stolen by the secure side. Some code, especially code dealing
+ * with hwirq IDs, is simplified by accounting for all 16.
+ */
+#define SGI_NR		16
+
 /*
  * The behaviours of RPR and PMR registers differ depending on the value of
  * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
@@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
 		__priority;						\
 	})
 
-/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
-static refcount_t *ppi_nmi_refs;
+/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
+static refcount_t *rdist_nmi_refs;
 
 static struct gic_kvm_info gic_v3_kvm_info __initdata;
 static DEFINE_PER_CPU(bool, has_rss);
@@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
 	}
 }
 
-static u32 gic_get_ppi_index(struct irq_data *d)
+static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
+{
+	switch (__get_intid_range(hwirq)) {
+	case SGI_RANGE:
+	case PPI_RANGE:
+		return hwirq;
+	case EPPI_RANGE:
+		return hwirq - EPPI_BASE_INTID + 32;
+	default:
+		unreachable();
+	}
+}
+
+static u32 gic_get_rdist_idx(struct irq_data *d)
 {
-	return __gic_get_ppi_index(d->hwirq);
+	return __gic_get_rdist_idx(d->hwirq);
 }
 
 static int gic_irq_nmi_setup(struct irq_data *d)
@@ -545,11 +565,14 @@ static int gic_irq_nmi_setup(struct irq_data *d)
 
 	/* desc lock should already be held */
 	if (gic_irq_in_rdist(d)) {
-		u32 idx = gic_get_ppi_index(d);
+		u32 idx = gic_get_rdist_idx(d);
 
-		/* Setting up PPI as NMI, only switch handler for first NMI */
-		if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
-			refcount_set(&ppi_nmi_refs[idx], 1);
+		/*
+		 * Setting up a percpu interrupt as NMI, only switch handler
+		 * for first NMI
+		 */
+		if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
+			refcount_set(&rdist_nmi_refs[idx], 1);
 			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
 		}
 	} else {
@@ -582,10 +605,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
 
 	/* desc lock should already be held */
 	if (gic_irq_in_rdist(d)) {
-		u32 idx = gic_get_ppi_index(d);
+		u32 idx = gic_get_rdist_idx(d);
 
 		/* Tearing down NMI, only switch handler for last NMI */
-		if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
+		if (refcount_dec_and_test(&rdist_nmi_refs[idx]))
 			desc->handle_irq = handle_percpu_devid_irq;
 	} else {
 		desc->handle_irq = handle_fasteoi_irq;
@@ -1279,10 +1302,10 @@ static void gic_cpu_init(void)
 	rbase = gic_data_rdist_sgi_base();
 
 	/* Configure SGIs/PPIs as non-secure Group-1 */
-	for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
+	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
 		writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
 
-	gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
+	gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp);
 
 	/* initialise system registers */
 	gic_cpu_sys_reg_init();
@@ -1939,12 +1962,13 @@ static void gic_enable_nmi_support(void)
 		return;
 	}
 
-	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
-	if (!ppi_nmi_refs)
+	rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,
+				 sizeof(*rdist_nmi_refs), GFP_KERNEL);
+	if (!rdist_nmi_refs)
 		return;
 
-	for (i = 0; i < gic_data.ppi_nr; i++)
-		refcount_set(&ppi_nmi_refs[i], 0);
+	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i++)
+		refcount_set(&rdist_nmi_refs[i], 0);
 
 	pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n",
 		gic_has_relaxed_pmr_sync() ? "relaxed" : "forced");
@@ -2061,6 +2085,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
 
 	gic_dist_init();
 	gic_cpu_init();
+	gic_enable_nmi_support();
 	gic_smp_init();
 	gic_cpu_pm_init();
 
@@ -2073,8 +2098,6 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
 			gicv2m_init(handle, gic_data.domain);
 	}
 
-	gic_enable_nmi_support();
-
 	return 0;
 
 out_free:
-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 2/7] arm64: idle: Tag the arm64 idle functions as __cpuidle
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	Frederic Weisbecker, Ingo Molnar, linux-kernel

As per the (somewhat recent) comment before the definition of
`__cpuidle`, the tag is like `noinstr` but also marks a function so it
can be identified by cpu_in_idle(). Let's add these markings to arm64
cpuidle functions

With this change we get useful backtraces like:

  NMI backtrace for cpu N skipped: idling at cpu_do_idle+0x94/0x98

instead of useless backtraces when dumping all processors using
nmi_cpu_backtrace().

NOTE: this patch won't make cpu_in_idle() work perfectly for arm64,
but it doesn't hurt and does catch some cases. Specifically an example
that wasn't caught in my testing looked like this:

 gic_cpu_sys_reg_init+0x1f8/0x314
 gic_cpu_pm_notifier+0x40/0x78
 raw_notifier_call_chain+0x5c/0x134
 cpu_pm_notify+0x38/0x64
 cpu_pm_exit+0x20/0x2c
 psci_enter_idle_state+0x48/0x70
 cpuidle_enter_state+0xb8/0x260
 cpuidle_enter+0x44/0x5c
 do_idle+0x188/0x30c

Acked-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Acked-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(no changes since v11)

Changes in v11:
- Updated commit message as per Stephen.

Changes in v9:
- Added to commit message that this doesn't catch all cases.

Changes in v8:
- "Tag the arm64 idle functions as __cpuidle" new for v8

 arch/arm64/kernel/idle.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/idle.c b/arch/arm64/kernel/idle.c
index c1125753fe9b..05cfb347ec26 100644
--- a/arch/arm64/kernel/idle.c
+++ b/arch/arm64/kernel/idle.c
@@ -20,7 +20,7 @@
  *	ensure that interrupts are not masked at the PMR (because the core will
  *	not wake up if we block the wake up signal in the interrupt controller).
  */
-void noinstr cpu_do_idle(void)
+void __cpuidle cpu_do_idle(void)
 {
 	struct arm_cpuidle_irq_context context;
 
@@ -35,7 +35,7 @@ void noinstr cpu_do_idle(void)
 /*
  * This is our default idle handler.
  */
-void noinstr arch_cpu_idle(void)
+void __cpuidle arch_cpu_idle(void)
 {
 	/*
 	 * This should do all the clock switching and wait for interrupt
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 2/7] arm64: idle: Tag the arm64 idle functions as __cpuidle
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	Frederic Weisbecker, Ingo Molnar, linux-kernel

As per the (somewhat recent) comment before the definition of
`__cpuidle`, the tag is like `noinstr` but also marks a function so it
can be identified by cpu_in_idle(). Let's add these markings to arm64
cpuidle functions

With this change we get useful backtraces like:

  NMI backtrace for cpu N skipped: idling at cpu_do_idle+0x94/0x98

instead of useless backtraces when dumping all processors using
nmi_cpu_backtrace().

NOTE: this patch won't make cpu_in_idle() work perfectly for arm64,
but it doesn't hurt and does catch some cases. Specifically an example
that wasn't caught in my testing looked like this:

 gic_cpu_sys_reg_init+0x1f8/0x314
 gic_cpu_pm_notifier+0x40/0x78
 raw_notifier_call_chain+0x5c/0x134
 cpu_pm_notify+0x38/0x64
 cpu_pm_exit+0x20/0x2c
 psci_enter_idle_state+0x48/0x70
 cpuidle_enter_state+0xb8/0x260
 cpuidle_enter+0x44/0x5c
 do_idle+0x188/0x30c

Acked-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Acked-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(no changes since v11)

Changes in v11:
- Updated commit message as per Stephen.

Changes in v9:
- Added to commit message that this doesn't catch all cases.

Changes in v8:
- "Tag the arm64 idle functions as __cpuidle" new for v8

 arch/arm64/kernel/idle.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/idle.c b/arch/arm64/kernel/idle.c
index c1125753fe9b..05cfb347ec26 100644
--- a/arch/arm64/kernel/idle.c
+++ b/arch/arm64/kernel/idle.c
@@ -20,7 +20,7 @@
  *	ensure that interrupts are not masked at the PMR (because the core will
  *	not wake up if we block the wake up signal in the interrupt controller).
  */
-void noinstr cpu_do_idle(void)
+void __cpuidle cpu_do_idle(void)
 {
 	struct arm_cpuidle_irq_context context;
 
@@ -35,7 +35,7 @@ void noinstr cpu_do_idle(void)
 /*
  * This is our default idle handler.
  */
-void noinstr arch_cpu_idle(void)
+void __cpuidle arch_cpu_idle(void)
 {
 	/*
 	 * This should do all the clock switching and wait for interrupt
-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 3/7] arm64: smp: Remove dedicated wakeup IPI
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Kees Cook,
	Philippe Mathieu-Daudé,
	Sami Tolvanen, Valentin Schneider, linux-kernel

From: Mark Rutland <mark.rutland@arm.com>

To enable NMI backtrace and KGDB's NMI cpu roundup, we need to free up
at least one dedicated IPI.

On arm64 the IPI_WAKEUP IPI is only used for the ACPI parking protocol,
which itself is only used on some very early ARMv8 systems which
couldn't implement PSCI.

Remove the IPI_WAKEUP IPI, and rely on the IPI_RESCHEDULE IPI to wake
CPUs from the parked state. This will cause a tiny amonut of redundant
work to check the thread flags, but this is miniscule in relation to the
cost of taking and handling the IPI in the first place. We can safely
handle redundant IPI_RESCHEDULE IPIs, so there should be no functional
impact as a result of this change.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Will Deacon <will@kernel.org>
---
I have no idea how to test this. I just took Mark's patch and jammed
it into my series. Logicially the patch seems reasonable to me.

(no changes since v11)

Changes in v11:
- arch_send_wakeup_ipi() now takes an unsigned int.

Changes in v10:
- ("arm64: smp: Remove dedicated wakeup IPI") new for v10.

 arch/arm64/include/asm/smp.h              |  4 ++--
 arch/arm64/kernel/acpi_parking_protocol.c |  2 +-
 arch/arm64/kernel/smp.c                   | 28 +++++++++--------------
 3 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 9b31e6d0da17..efb13112b408 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -89,9 +89,9 @@ extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
 #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
+extern void arch_send_wakeup_ipi(unsigned int cpu);
 #else
-static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+static inline void arch_send_wakeup_ipi(unsigned int cpu)
 {
 	BUILD_BUG();
 }
diff --git a/arch/arm64/kernel/acpi_parking_protocol.c b/arch/arm64/kernel/acpi_parking_protocol.c
index b1990e38aed0..e1be29e608b7 100644
--- a/arch/arm64/kernel/acpi_parking_protocol.c
+++ b/arch/arm64/kernel/acpi_parking_protocol.c
@@ -103,7 +103,7 @@ static int acpi_parking_protocol_cpu_boot(unsigned int cpu)
 		       &mailbox->entry_point);
 	writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
 
-	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+	arch_send_wakeup_ipi(cpu);
 
 	return 0;
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 960b98b43506..a5848f1ef817 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -72,7 +72,6 @@ enum ipi_msg_type {
 	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
-	IPI_WAKEUP,
 	NR_IPI
 };
 
@@ -764,7 +763,6 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
 	[IPI_CPU_CRASH_STOP]	= "CPU stop (for crash dump) interrupts",
 	[IPI_TIMER]		= "Timer broadcast interrupts",
 	[IPI_IRQ_WORK]		= "IRQ work interrupts",
-	[IPI_WAKEUP]		= "CPU wake-up interrupts",
 };
 
 static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
@@ -797,13 +795,6 @@ void arch_send_call_function_single_ipi(int cpu)
 	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
 }
 
-#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_WAKEUP);
-}
-#endif
-
 #ifdef CONFIG_IRQ_WORK
 void arch_irq_work_raise(void)
 {
@@ -897,14 +888,6 @@ static void do_handle_IPI(int ipinr)
 		break;
 #endif
 
-#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-	case IPI_WAKEUP:
-		WARN_ONCE(!acpi_parking_protocol_valid(cpu),
-			  "CPU%u: Wake-up IPI outside the ACPI parking protocol\n",
-			  cpu);
-		break;
-#endif
-
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
@@ -979,6 +962,17 @@ void arch_smp_send_reschedule(int cpu)
 	smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
 }
 
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+void arch_send_wakeup_ipi(unsigned int cpu)
+{
+	/*
+	 * We use a scheduler IPI to wake the CPU as this avoids the need for a
+	 * dedicated IPI and we can safely handle spurious scheduler IPIs.
+	 */
+	arch_smp_send_reschedule(cpu);
+}
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 void tick_broadcast(const struct cpumask *mask)
 {
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 3/7] arm64: smp: Remove dedicated wakeup IPI
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Kees Cook,
	Philippe Mathieu-Daudé,
	Sami Tolvanen, Valentin Schneider, linux-kernel

From: Mark Rutland <mark.rutland@arm.com>

To enable NMI backtrace and KGDB's NMI cpu roundup, we need to free up
at least one dedicated IPI.

On arm64 the IPI_WAKEUP IPI is only used for the ACPI parking protocol,
which itself is only used on some very early ARMv8 systems which
couldn't implement PSCI.

Remove the IPI_WAKEUP IPI, and rely on the IPI_RESCHEDULE IPI to wake
CPUs from the parked state. This will cause a tiny amonut of redundant
work to check the thread flags, but this is miniscule in relation to the
cost of taking and handling the IPI in the first place. We can safely
handle redundant IPI_RESCHEDULE IPIs, so there should be no functional
impact as a result of this change.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Will Deacon <will@kernel.org>
---
I have no idea how to test this. I just took Mark's patch and jammed
it into my series. Logicially the patch seems reasonable to me.

(no changes since v11)

Changes in v11:
- arch_send_wakeup_ipi() now takes an unsigned int.

Changes in v10:
- ("arm64: smp: Remove dedicated wakeup IPI") new for v10.

 arch/arm64/include/asm/smp.h              |  4 ++--
 arch/arm64/kernel/acpi_parking_protocol.c |  2 +-
 arch/arm64/kernel/smp.c                   | 28 +++++++++--------------
 3 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 9b31e6d0da17..efb13112b408 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -89,9 +89,9 @@ extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
 #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
+extern void arch_send_wakeup_ipi(unsigned int cpu);
 #else
-static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+static inline void arch_send_wakeup_ipi(unsigned int cpu)
 {
 	BUILD_BUG();
 }
diff --git a/arch/arm64/kernel/acpi_parking_protocol.c b/arch/arm64/kernel/acpi_parking_protocol.c
index b1990e38aed0..e1be29e608b7 100644
--- a/arch/arm64/kernel/acpi_parking_protocol.c
+++ b/arch/arm64/kernel/acpi_parking_protocol.c
@@ -103,7 +103,7 @@ static int acpi_parking_protocol_cpu_boot(unsigned int cpu)
 		       &mailbox->entry_point);
 	writel_relaxed(cpu_entry->gic_cpu_id, &mailbox->cpu_id);
 
-	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+	arch_send_wakeup_ipi(cpu);
 
 	return 0;
 }
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 960b98b43506..a5848f1ef817 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -72,7 +72,6 @@ enum ipi_msg_type {
 	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
-	IPI_WAKEUP,
 	NR_IPI
 };
 
@@ -764,7 +763,6 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
 	[IPI_CPU_CRASH_STOP]	= "CPU stop (for crash dump) interrupts",
 	[IPI_TIMER]		= "Timer broadcast interrupts",
 	[IPI_IRQ_WORK]		= "IRQ work interrupts",
-	[IPI_WAKEUP]		= "CPU wake-up interrupts",
 };
 
 static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
@@ -797,13 +795,6 @@ void arch_send_call_function_single_ipi(int cpu)
 	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
 }
 
-#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_WAKEUP);
-}
-#endif
-
 #ifdef CONFIG_IRQ_WORK
 void arch_irq_work_raise(void)
 {
@@ -897,14 +888,6 @@ static void do_handle_IPI(int ipinr)
 		break;
 #endif
 
-#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
-	case IPI_WAKEUP:
-		WARN_ONCE(!acpi_parking_protocol_valid(cpu),
-			  "CPU%u: Wake-up IPI outside the ACPI parking protocol\n",
-			  cpu);
-		break;
-#endif
-
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
@@ -979,6 +962,17 @@ void arch_smp_send_reschedule(int cpu)
 	smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
 }
 
+#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
+void arch_send_wakeup_ipi(unsigned int cpu)
+{
+	/*
+	 * We use a scheduler IPI to wake the CPU as this avoids the need for a
+	 * dedicated IPI and we can safely handle spurious scheduler IPIs.
+	 */
+	arch_smp_send_reschedule(cpu);
+}
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 void tick_broadcast(const struct cpumask *mask)
 {
-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 4/7] arm64: smp: Add arch support for backtrace using pseudo-NMI
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

Enable arch_trigger_cpumask_backtrace() support on arm64. This enables
things much like they are enabled on arm32 (including some of the
funky logic around NR_IPI, nr_ipi, and MAX_IPI) but with the
difference that, unlike arm32, we'll try to enable the backtrace to
use pseudo-NMI.

NOTE: this patch is a squash of the little bit of code adding the
ability to mark an IPI to try to use pseudo-NMI plus the little bit of
code to hook things up for kgdb. This approach was decided upon in the
discussion of v9 [1].

This patch depends on commit 8d539b84f1e3 ("nmi_backtrace: allow
excluding an arbitrary CPU") since that commit changed the prototype
of arch_trigger_cpumask_backtrace(), which this patch implements.

[1] https://lore.kernel.org/r/ZORY51mF4alI41G1@FVFF77S0Q05N

Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Co-developed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Misono Tomohiro <misono.tomohiro@fujitsu.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

Changes in v12:
- Minor comment change to add "()" after nmi_trigger_cpumask_backtrace.
- Updated the commit hash of the commit this depends on.

Changes in v11:
- Adjust comment about NR_IPI/MAX_IPI.
- Don't use confusing "backed by" idiom in comment.
- Made arm64_backtrace_ipi() static.

Changes in v10:
- Backtrace now directly supported in smp.c
- Squash backtrace into patch adding support for pseudo-NMI IPIs.

Changes in v9:
- Added comments that we might not be using NMI always.
- Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
- Moved header file out of "include" since it didn't need to be there.
- Remove arm64_supports_nmi()
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
- arch_trigger_cpumask_backtrace() no longer returns bool

Changes in v8:
- Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
- debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param

 arch/arm64/include/asm/irq.h |  3 ++
 arch/arm64/kernel/smp.c      | 86 +++++++++++++++++++++++++++++++-----
 2 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index fac08e18bcd5..50ce8b697ff3 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -6,6 +6,9 @@
 
 #include <asm-generic/irq.h>
 
+void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu);
+#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
+
 struct pt_regs;
 
 int set_handle_irq(void (*handle_irq)(struct pt_regs *));
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index a5848f1ef817..28c904ca499a 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -33,6 +33,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/kexec.h>
 #include <linux/kvm_host.h>
+#include <linux/nmi.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -72,12 +73,18 @@ enum ipi_msg_type {
 	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
-	NR_IPI
+	NR_IPI,
+	/*
+	 * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
+	 * with trace_ipi_*
+	 */
+	IPI_CPU_BACKTRACE = NR_IPI,
+	MAX_IPI
 };
 
 static int ipi_irq_base __read_mostly;
 static int nr_ipi __read_mostly = NR_IPI;
-static struct irq_desc *ipi_desc[NR_IPI] __read_mostly;
+static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
 
 static void ipi_setup(int cpu);
 
@@ -845,6 +852,22 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs
 #endif
 }
 
+static void arm64_backtrace_ipi(cpumask_t *mask)
+{
+	__ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask);
+}
+
+void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
+{
+	/*
+	 * NOTE: though nmi_trigger_cpumask_backtrace() has "nmi_" in the name,
+	 * nothing about it truly needs to be implemented using an NMI, it's
+	 * just that it's _allowed_ to work with NMIs. If ipi_should_be_nmi()
+	 * returned false our backtrace attempt will just use a regular IPI.
+	 */
+	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
+}
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -888,6 +911,14 @@ static void do_handle_IPI(int ipinr)
 		break;
 #endif
 
+	case IPI_CPU_BACKTRACE:
+		/*
+		 * NOTE: in some cases this _won't_ be NMI context. See the
+		 * comment in arch_trigger_cpumask_backtrace().
+		 */
+		nmi_cpu_backtrace(get_irq_regs());
+		break;
+
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
@@ -909,6 +940,19 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
 	__ipi_send_mask(ipi_desc[ipinr], target);
 }
 
+static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
+{
+	if (!system_uses_irq_prio_masking())
+		return false;
+
+	switch (ipi) {
+	case IPI_CPU_BACKTRACE:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static void ipi_setup(int cpu)
 {
 	int i;
@@ -916,8 +960,14 @@ static void ipi_setup(int cpu)
 	if (WARN_ON_ONCE(!ipi_irq_base))
 		return;
 
-	for (i = 0; i < nr_ipi; i++)
-		enable_percpu_irq(ipi_irq_base + i, 0);
+	for (i = 0; i < nr_ipi; i++) {
+		if (ipi_should_be_nmi(i)) {
+			prepare_percpu_nmi(ipi_irq_base + i);
+			enable_percpu_nmi(ipi_irq_base + i, 0);
+		} else {
+			enable_percpu_irq(ipi_irq_base + i, 0);
+		}
+	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -928,8 +978,14 @@ static void ipi_teardown(int cpu)
 	if (WARN_ON_ONCE(!ipi_irq_base))
 		return;
 
-	for (i = 0; i < nr_ipi; i++)
-		disable_percpu_irq(ipi_irq_base + i);
+	for (i = 0; i < nr_ipi; i++) {
+		if (ipi_should_be_nmi(i)) {
+			disable_percpu_nmi(ipi_irq_base + i);
+			teardown_percpu_nmi(ipi_irq_base + i);
+		} else {
+			disable_percpu_irq(ipi_irq_base + i);
+		}
+	}
 }
 #endif
 
@@ -937,15 +993,23 @@ void __init set_smp_ipi_range(int ipi_base, int n)
 {
 	int i;
 
-	WARN_ON(n < NR_IPI);
-	nr_ipi = min(n, NR_IPI);
+	WARN_ON(n < MAX_IPI);
+	nr_ipi = min(n, MAX_IPI);
 
 	for (i = 0; i < nr_ipi; i++) {
 		int err;
 
-		err = request_percpu_irq(ipi_base + i, ipi_handler,
-					 "IPI", &cpu_number);
-		WARN_ON(err);
+		if (ipi_should_be_nmi(i)) {
+			err = request_percpu_nmi(ipi_base + i, ipi_handler,
+						 "IPI", &cpu_number);
+			WARN(err, "Could not request IPI %d as NMI, err=%d\n",
+			     i, err);
+		} else {
+			err = request_percpu_irq(ipi_base + i, ipi_handler,
+						 "IPI", &cpu_number);
+			WARN(err, "Could not request IPI %d as IRQ, err=%d\n",
+			     i, err);
+		}
 
 		ipi_desc[i] = irq_to_desc(ipi_base + i);
 		irq_set_status_flags(ipi_base + i, IRQ_HIDDEN);
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 4/7] arm64: smp: Add arch support for backtrace using pseudo-NMI
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

Enable arch_trigger_cpumask_backtrace() support on arm64. This enables
things much like they are enabled on arm32 (including some of the
funky logic around NR_IPI, nr_ipi, and MAX_IPI) but with the
difference that, unlike arm32, we'll try to enable the backtrace to
use pseudo-NMI.

NOTE: this patch is a squash of the little bit of code adding the
ability to mark an IPI to try to use pseudo-NMI plus the little bit of
code to hook things up for kgdb. This approach was decided upon in the
discussion of v9 [1].

This patch depends on commit 8d539b84f1e3 ("nmi_backtrace: allow
excluding an arbitrary CPU") since that commit changed the prototype
of arch_trigger_cpumask_backtrace(), which this patch implements.

[1] https://lore.kernel.org/r/ZORY51mF4alI41G1@FVFF77S0Q05N

Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Co-developed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Misono Tomohiro <misono.tomohiro@fujitsu.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

Changes in v12:
- Minor comment change to add "()" after nmi_trigger_cpumask_backtrace.
- Updated the commit hash of the commit this depends on.

Changes in v11:
- Adjust comment about NR_IPI/MAX_IPI.
- Don't use confusing "backed by" idiom in comment.
- Made arm64_backtrace_ipi() static.

Changes in v10:
- Backtrace now directly supported in smp.c
- Squash backtrace into patch adding support for pseudo-NMI IPIs.

Changes in v9:
- Added comments that we might not be using NMI always.
- Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
- Moved header file out of "include" since it didn't need to be there.
- Remove arm64_supports_nmi()
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
- arch_trigger_cpumask_backtrace() no longer returns bool

Changes in v8:
- Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
- debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param

 arch/arm64/include/asm/irq.h |  3 ++
 arch/arm64/kernel/smp.c      | 86 +++++++++++++++++++++++++++++++-----
 2 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index fac08e18bcd5..50ce8b697ff3 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -6,6 +6,9 @@
 
 #include <asm-generic/irq.h>
 
+void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu);
+#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
+
 struct pt_regs;
 
 int set_handle_irq(void (*handle_irq)(struct pt_regs *));
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index a5848f1ef817..28c904ca499a 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -33,6 +33,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/kexec.h>
 #include <linux/kvm_host.h>
+#include <linux/nmi.h>
 
 #include <asm/alternative.h>
 #include <asm/atomic.h>
@@ -72,12 +73,18 @@ enum ipi_msg_type {
 	IPI_CPU_CRASH_STOP,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
-	NR_IPI
+	NR_IPI,
+	/*
+	 * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
+	 * with trace_ipi_*
+	 */
+	IPI_CPU_BACKTRACE = NR_IPI,
+	MAX_IPI
 };
 
 static int ipi_irq_base __read_mostly;
 static int nr_ipi __read_mostly = NR_IPI;
-static struct irq_desc *ipi_desc[NR_IPI] __read_mostly;
+static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
 
 static void ipi_setup(int cpu);
 
@@ -845,6 +852,22 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs
 #endif
 }
 
+static void arm64_backtrace_ipi(cpumask_t *mask)
+{
+	__ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask);
+}
+
+void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
+{
+	/*
+	 * NOTE: though nmi_trigger_cpumask_backtrace() has "nmi_" in the name,
+	 * nothing about it truly needs to be implemented using an NMI, it's
+	 * just that it's _allowed_ to work with NMIs. If ipi_should_be_nmi()
+	 * returned false our backtrace attempt will just use a regular IPI.
+	 */
+	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
+}
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -888,6 +911,14 @@ static void do_handle_IPI(int ipinr)
 		break;
 #endif
 
+	case IPI_CPU_BACKTRACE:
+		/*
+		 * NOTE: in some cases this _won't_ be NMI context. See the
+		 * comment in arch_trigger_cpumask_backtrace().
+		 */
+		nmi_cpu_backtrace(get_irq_regs());
+		break;
+
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
@@ -909,6 +940,19 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
 	__ipi_send_mask(ipi_desc[ipinr], target);
 }
 
+static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
+{
+	if (!system_uses_irq_prio_masking())
+		return false;
+
+	switch (ipi) {
+	case IPI_CPU_BACKTRACE:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static void ipi_setup(int cpu)
 {
 	int i;
@@ -916,8 +960,14 @@ static void ipi_setup(int cpu)
 	if (WARN_ON_ONCE(!ipi_irq_base))
 		return;
 
-	for (i = 0; i < nr_ipi; i++)
-		enable_percpu_irq(ipi_irq_base + i, 0);
+	for (i = 0; i < nr_ipi; i++) {
+		if (ipi_should_be_nmi(i)) {
+			prepare_percpu_nmi(ipi_irq_base + i);
+			enable_percpu_nmi(ipi_irq_base + i, 0);
+		} else {
+			enable_percpu_irq(ipi_irq_base + i, 0);
+		}
+	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -928,8 +978,14 @@ static void ipi_teardown(int cpu)
 	if (WARN_ON_ONCE(!ipi_irq_base))
 		return;
 
-	for (i = 0; i < nr_ipi; i++)
-		disable_percpu_irq(ipi_irq_base + i);
+	for (i = 0; i < nr_ipi; i++) {
+		if (ipi_should_be_nmi(i)) {
+			disable_percpu_nmi(ipi_irq_base + i);
+			teardown_percpu_nmi(ipi_irq_base + i);
+		} else {
+			disable_percpu_irq(ipi_irq_base + i);
+		}
+	}
 }
 #endif
 
@@ -937,15 +993,23 @@ void __init set_smp_ipi_range(int ipi_base, int n)
 {
 	int i;
 
-	WARN_ON(n < NR_IPI);
-	nr_ipi = min(n, NR_IPI);
+	WARN_ON(n < MAX_IPI);
+	nr_ipi = min(n, MAX_IPI);
 
 	for (i = 0; i < nr_ipi; i++) {
 		int err;
 
-		err = request_percpu_irq(ipi_base + i, ipi_handler,
-					 "IPI", &cpu_number);
-		WARN_ON(err);
+		if (ipi_should_be_nmi(i)) {
+			err = request_percpu_nmi(ipi_base + i, ipi_handler,
+						 "IPI", &cpu_number);
+			WARN(err, "Could not request IPI %d as NMI, err=%d\n",
+			     i, err);
+		} else {
+			err = request_percpu_irq(ipi_base + i, ipi_handler,
+						 "IPI", &cpu_number);
+			WARN(err, "Could not request IPI %d as IRQ, err=%d\n",
+			     i, err);
+		}
 
 		ipi_desc[i] = irq_to_desc(ipi_base + i);
 		irq_set_status_flags(ipi_base + i, IRQ_HIDDEN);
-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 5/7] arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

There's no reason why IPI_CPU_STOP and IPI_CPU_CRASH_STOP can't be
handled as NMI. They are very simple and everything in them is
NMI-safe. Mark them as things to use NMI for if NMI is available.

Suggested-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Misono Tomohiro <misono.tomohiro@fujitsu.com>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I don't actually have any good way to test/validate this patch. It's
added to the series at Mark's request.

(no changes since v10)

Changes in v10:
- ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.

 arch/arm64/kernel/smp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 28c904ca499a..800c59cf9b64 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -946,6 +946,8 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
 		return false;
 
 	switch (ipi) {
+	case IPI_CPU_STOP:
+	case IPI_CPU_CRASH_STOP:
 	case IPI_CPU_BACKTRACE:
 		return true;
 	default:
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 5/7] arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

There's no reason why IPI_CPU_STOP and IPI_CPU_CRASH_STOP can't be
handled as NMI. They are very simple and everything in them is
NMI-safe. Mark them as things to use NMI for if NMI is available.

Suggested-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Misono Tomohiro <misono.tomohiro@fujitsu.com>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I don't actually have any good way to test/validate this patch. It's
added to the series at Mark's request.

(no changes since v10)

Changes in v10:
- ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.

 arch/arm64/kernel/smp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 28c904ca499a..800c59cf9b64 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -946,6 +946,8 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
 		return false;
 
 	switch (ipi) {
+	case IPI_CPU_STOP:
+	case IPI_CPU_CRASH_STOP:
 	case IPI_CPU_BACKTRACE:
 		return true;
 	default:
-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 6/7] arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI roundup
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

Up until now we've been using the generic (weak) implementation for
kgdb_roundup_cpus() when using kgdb on arm64. Let's move to a custom
one. The advantage here is that, when pseudo-NMI is enabled on a
device, we'll be able to round up CPUs using pseudo-NMI. This allows
us to debug CPUs that are stuck with interrupts disabled. If
pseudo-NMIs are not enabled then we'll fallback to just using an IPI,
which is still slightly better than the generic implementation since
it avoids the potential situation described in the generic
kgdb_call_nmi_hook().

Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I debated whether this should be in "arch/arm64/kernel/smp.c" or if I
should try to find a way for it to go into "arch/arm64/kernel/kgdb.c".
In the end this is so little code that it didn't seem worth it to find
a way to export the IPI defines or to otherwise come up with some API
between kgdb.c and smp.c. If someone has strong feelings and wants
this to change, please shout and give details of your preferred
solution.

FWIW, it seems like ~half the other platforms put this in "smp.c" with
an ifdef for KGDB and the other half put it in "kgdb.c" with an ifdef
for SMP. :-P

(no changes since v10)

Changes in v10:
- Don't allocate the cpumask on the stack; just iterate.
- Moved kgdb calls to smp.c to avoid needing to export IPI info.
- kgdb now has its own IPI.

Changes in v9:
- Remove fallback for when debug IPI isn't available.
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.

 arch/arm64/kernel/smp.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 800c59cf9b64..1a53e57c81d0 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -32,6 +32,7 @@
 #include <linux/irq_work.h>
 #include <linux/kernel_stat.h>
 #include <linux/kexec.h>
+#include <linux/kgdb.h>
 #include <linux/kvm_host.h>
 #include <linux/nmi.h>
 
@@ -79,6 +80,7 @@ enum ipi_msg_type {
 	 * with trace_ipi_*
 	 */
 	IPI_CPU_BACKTRACE = NR_IPI,
+	IPI_KGDB_ROUNDUP,
 	MAX_IPI
 };
 
@@ -868,6 +870,22 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
 	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
 }
 
+#ifdef CONFIG_KGDB
+void kgdb_roundup_cpus(void)
+{
+	int this_cpu = raw_smp_processor_id();
+	int cpu;
+
+	for_each_online_cpu(cpu) {
+		/* No need to roundup ourselves */
+		if (cpu == this_cpu)
+			continue;
+
+		__ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu);
+	}
+}
+#endif
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -919,6 +937,10 @@ static void do_handle_IPI(int ipinr)
 		nmi_cpu_backtrace(get_irq_regs());
 		break;
 
+	case IPI_KGDB_ROUNDUP:
+		kgdb_nmicallback(cpu, get_irq_regs());
+		break;
+
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
@@ -949,6 +971,7 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
 	case IPI_CPU_STOP:
 	case IPI_CPU_CRASH_STOP:
 	case IPI_CPU_BACKTRACE:
+	case IPI_KGDB_ROUNDUP:
 		return true;
 	default:
 		return false;
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 6/7] arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI roundup
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

Up until now we've been using the generic (weak) implementation for
kgdb_roundup_cpus() when using kgdb on arm64. Let's move to a custom
one. The advantage here is that, when pseudo-NMI is enabled on a
device, we'll be able to round up CPUs using pseudo-NMI. This allows
us to debug CPUs that are stuck with interrupts disabled. If
pseudo-NMIs are not enabled then we'll fallback to just using an IPI,
which is still slightly better than the generic implementation since
it avoids the potential situation described in the generic
kgdb_call_nmi_hook().

Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
I debated whether this should be in "arch/arm64/kernel/smp.c" or if I
should try to find a way for it to go into "arch/arm64/kernel/kgdb.c".
In the end this is so little code that it didn't seem worth it to find
a way to export the IPI defines or to otherwise come up with some API
between kgdb.c and smp.c. If someone has strong feelings and wants
this to change, please shout and give details of your preferred
solution.

FWIW, it seems like ~half the other platforms put this in "smp.c" with
an ifdef for KGDB and the other half put it in "kgdb.c" with an ifdef
for SMP. :-P

(no changes since v10)

Changes in v10:
- Don't allocate the cpumask on the stack; just iterate.
- Moved kgdb calls to smp.c to avoid needing to export IPI info.
- kgdb now has its own IPI.

Changes in v9:
- Remove fallback for when debug IPI isn't available.
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.

 arch/arm64/kernel/smp.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 800c59cf9b64..1a53e57c81d0 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -32,6 +32,7 @@
 #include <linux/irq_work.h>
 #include <linux/kernel_stat.h>
 #include <linux/kexec.h>
+#include <linux/kgdb.h>
 #include <linux/kvm_host.h>
 #include <linux/nmi.h>
 
@@ -79,6 +80,7 @@ enum ipi_msg_type {
 	 * with trace_ipi_*
 	 */
 	IPI_CPU_BACKTRACE = NR_IPI,
+	IPI_KGDB_ROUNDUP,
 	MAX_IPI
 };
 
@@ -868,6 +870,22 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
 	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
 }
 
+#ifdef CONFIG_KGDB
+void kgdb_roundup_cpus(void)
+{
+	int this_cpu = raw_smp_processor_id();
+	int cpu;
+
+	for_each_online_cpu(cpu) {
+		/* No need to roundup ourselves */
+		if (cpu == this_cpu)
+			continue;
+
+		__ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu);
+	}
+}
+#endif
+
 /*
  * Main handler for inter-processor interrupts
  */
@@ -919,6 +937,10 @@ static void do_handle_IPI(int ipinr)
 		nmi_cpu_backtrace(get_irq_regs());
 		break;
 
+	case IPI_KGDB_ROUNDUP:
+		kgdb_nmicallback(cpu, get_irq_regs());
+		break;
+
 	default:
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
@@ -949,6 +971,7 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
 	case IPI_CPU_STOP:
 	case IPI_CPU_CRASH_STOP:
 	case IPI_CPU_BACKTRACE:
+	case IPI_KGDB_ROUNDUP:
 		return true;
 	default:
 		return false;
-- 
2.42.0.283.g2d96d420d3-goog


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

* [PATCH v12 7/7] arm64: smp: Mark IPI globals as __ro_after_init
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-30 19:11   ` Douglas Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

Mark the three IPI-related globals in smp.c as "__ro_after_init" since
they are only ever set in set_smp_ipi_range(), which is marked
"__init". This is a better and more secure marking than the old
"__read_mostly".

Suggested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
This patch is almost completely unrelated to the rest of the series
other than the fact that it would cause a merge conflict with the
series if sent separately. I tacked it on to this series in response
to Stephen's feedback on v11 of this series [1]. If someone hates it
(not sure why they would), it could be dropped. If someone loves it,
it could be promoted to the start of the series and/or land on its own
(resolving merge conflicts).

[1] https://lore.kernel.org/r/CAE-0n52iVDgZa8XT8KTMj12c_ESSJt7f7A0fuZ_oAMMqpGcSzA@mail.gmail.com

Changes in v12:
- ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.

 arch/arm64/kernel/smp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1a53e57c81d0..814d9aa93b21 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -84,9 +84,9 @@ enum ipi_msg_type {
 	MAX_IPI
 };
 
-static int ipi_irq_base __read_mostly;
-static int nr_ipi __read_mostly = NR_IPI;
-static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
+static int ipi_irq_base __ro_after_init;
+static int nr_ipi __ro_after_init = NR_IPI;
+static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
 
 static void ipi_setup(int cpu);
 
-- 
2.42.0.283.g2d96d420d3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v12 7/7] arm64: smp: Mark IPI globals as __ro_after_init
@ 2023-08-30 19:11   ` Douglas Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Douglas Anderson @ 2023-08-30 19:11 UTC (permalink / raw)
  To: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier
  Cc: linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, Douglas Anderson,
	D Scott Phillips, Josh Poimboeuf, Valentin Schneider,
	linux-kernel

Mark the three IPI-related globals in smp.c as "__ro_after_init" since
they are only ever set in set_smp_ipi_range(), which is marked
"__init". This is a better and more secure marking than the old
"__read_mostly".

Suggested-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
This patch is almost completely unrelated to the rest of the series
other than the fact that it would cause a merge conflict with the
series if sent separately. I tacked it on to this series in response
to Stephen's feedback on v11 of this series [1]. If someone hates it
(not sure why they would), it could be dropped. If someone loves it,
it could be promoted to the start of the series and/or land on its own
(resolving merge conflicts).

[1] https://lore.kernel.org/r/CAE-0n52iVDgZa8XT8KTMj12c_ESSJt7f7A0fuZ_oAMMqpGcSzA@mail.gmail.com

Changes in v12:
- ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.

 arch/arm64/kernel/smp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1a53e57c81d0..814d9aa93b21 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -84,9 +84,9 @@ enum ipi_msg_type {
 	MAX_IPI
 };
 
-static int ipi_irq_base __read_mostly;
-static int nr_ipi __read_mostly = NR_IPI;
-static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
+static int ipi_irq_base __ro_after_init;
+static int nr_ipi __ro_after_init = NR_IPI;
+static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
 
 static void ipi_setup(int cpu);
 
-- 
2.42.0.283.g2d96d420d3-goog


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

* Re: [PATCH v12 0/7] arm64: Add IPI for backtraces / kgdb; try to use NMI for some IPIs
  2023-08-30 19:11 ` Douglas Anderson
@ 2023-08-31  7:08   ` Chen-Yu Tsai
  -1 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-08-31  7:08 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier, linux-arm-kernel,
	Masayoshi Mizuma, Rafael J . Wysocki, Chen-Yu Tsai,
	Lecopzer Chen, Tomohiro Misono, Stephane Eranian, kgdb-bugreport,
	Peter Zijlstra, Thomas Gleixner, Stephen Boyd, ito-yuichi,
	linux-perf-users, Ard Biesheuvel, D Scott Phillips,
	Frederic Weisbecker, Ingo Molnar, Josh Poimboeuf, Kees Cook,
	Philippe Mathieu-Daudé,
	Sami Tolvanen, Valentin Schneider, linux-kernel

On Thu, Aug 31, 2023 at 3:14 AM Douglas Anderson <dianders@chromium.org> wrote:
>
> This is an attempt to resurrect Sumit's old patch series [1] that
> allowed us to use the arm64 pseudo-NMI to get backtraces of CPUs and
> also to round up CPUs in kdb/kgdb. The last post from Sumit that I
> could find was v7, so I started my series at v8. I haven't copied all
> of his old changelongs here, but you can find them from the link.
>
> This patch series targets v6.6. Specifically it can't land in v6.5
> since it depends on commit 8d539b84f1e3 ("nmi_backtrace: allow
> excluding an arbitrary CPU").
>
> It should be noted that Mark still feels there might be some corner
> cases where pseudo-NMI is not production ready [2] [3], but as far as
> I'm aware there are no concrete/documented issues. Regardless of
> whether this should be enabled for production, though, this series
> will be invaluable to anyone trying to debug crashes on arm64
> machines.
>
> v12 of this series collects tags, fixes a few small nits in comments
> and commit messages from v11 and adds a new (and somewhat unrelated)
> small patch to the end of the series. There are no code changes other
> than the last patch, which is tiny.
>
> v11 of this series addressed Stephen Boyd's feedback on v10 and added
> a missing "static" that the patches robot found.
>
> v10 of this series attempted to address all of Mark's feedback on
> v9. As a quick summary:
> - It includes his patch to remove IPI_WAKEUP, freeing up an extra IPI.
> - It no longer combines the "kgdb" and "backtrace" IPIs. If we need
>   another IPI these could always be recombined later.
> - It promotes IPI_CPU_STOP and IPI_CPU_CRASH_STOP to NMI.
> - It puts nearly all the code directly in smp.c.
> - Several of the patches are squashed together.
> - Patch #6 ("kgdb: Provide a stub kgdb_nmicallback() if !CONFIG_KGDB")
>   was dropped from the series since it landed.
>
> Between v8 and v9, I had cleaned up this patch series by integrating
> the 10th patch from v8 [4] into the whole series. As part of this, I
> renamed the "NMI IPI" to the "debug IPI" since it could now be backed
> by a regular IPI in the case that pseudo NMIs weren't available. With
> the fallback, this allowed me to drop some extra patches from the
> series. This feels (to me) to be pretty clean and hopefully others
> agree. Any patch I touched significantly I removed Masayoshi and
> Chen-Yu's tags from.
>
> ...also in v8, I reorderd the patches a bit in a way that seemed a
> little cleaner to me.
>
> Since v7, I have:
> * Addressed the small amount of feedback that was there for v7.
> * Rebased.
> * Added a new patch that prevents us from spamming the logs with idle
>   tasks.
> * Added an extra patch to gracefully fall back to regular IPIs if
>   pseudo-NMIs aren't there.
>
> It can be noted that this patch series works very well with the recent
> "hardlockup" patches that have landed through Andrew Morton's tree and
> are currently in mainline. It works especially well with the "buddy"
> lockup detector.
>
> [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg@linaro.org/
> [2] https://lore.kernel.org/lkml/ZFvGqD%2F%2Fpm%2FlZb+p@FVFF77S0Q05N.cambridge.arm.com/
> [3] https://lore.kernel.org/lkml/ZNDKVP2m-iiZCz3v@FVFF77S0Q05N.cambridge.arm.com
> [4] https://lore.kernel.org/r/20230419155341.v8.10.Ic3659997d6243139d0522fc3afcdfd88d7a5f030@changeid/
>
> Changes in v12:
> - ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.
> - Added a comment about why we account for 16 SGIs when Linux uses 8.
> - Minor comment change to add "()" after nmi_trigger_cpumask_backtrace.
> - Updated the commit hash of the commit this depends on.
>
> Changes in v11:
> - Adjust comment about NR_IPI/MAX_IPI.
> - Don't use confusing "backed by" idiom in comment.
> - Made arm64_backtrace_ipi() static.
> - Updated commit message as per Stephen.
> - arch_send_wakeup_ipi() now takes an unsigned int.
>
> Changes in v10:
> - ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.
> - ("arm64: smp: Remove dedicated wakeup IPI") new for v10.
> - Backtrace now directly supported in smp.c
> - Don't allocate the cpumask on the stack; just iterate.
> - Moved kgdb calls to smp.c to avoid needing to export IPI info.
> - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> - Squash backtrace into patch adding support for pseudo-NMI IPIs.
> - kgdb now has its own IPI.
>
> Changes in v9:
> - Added comments that we might not be using NMI always.
> - Added to commit message that this doesn't catch all cases.
> - Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
> - Moved header file out of "include" since it didn't need to be there.
> - Remove arm64_supports_nmi()
> - Remove fallback for when debug IPI isn't available.
> - Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
> - arch_trigger_cpumask_backtrace() no longer returns bool
>
> Changes in v8:
> - "Tag the arm64 idle functions as __cpuidle" new for v8
> - Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
> - debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param
>
> Douglas Anderson (6):
>   irqchip/gic-v3: Enable support for SGIs to act as NMIs
>   arm64: idle: Tag the arm64 idle functions as __cpuidle
>   arm64: smp: Add arch support for backtrace using pseudo-NMI
>   arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
>   arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI
>     roundup
>   arm64: smp: Mark IPI globals as __ro_after_init
>
> Mark Rutland (1):
>   arm64: smp: Remove dedicated wakeup IPI

Whole series is

Tested-by: Chen-Yu Tsai <wenst@chromium.org>

on SolidRun i.MX8MM Hummingboard Pulse by injecting HARDLOCKUP with lkdtm.

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

* Re: [PATCH v12 0/7] arm64: Add IPI for backtraces / kgdb; try to use NMI for some IPIs
@ 2023-08-31  7:08   ` Chen-Yu Tsai
  0 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-08-31  7:08 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Mark Rutland, Catalin Marinas, Will Deacon, Sumit Garg,
	Daniel Thompson, Marc Zyngier, linux-arm-kernel,
	Masayoshi Mizuma, Rafael J . Wysocki, Chen-Yu Tsai,
	Lecopzer Chen, Tomohiro Misono, Stephane Eranian, kgdb-bugreport,
	Peter Zijlstra, Thomas Gleixner, Stephen Boyd, ito-yuichi,
	linux-perf-users, Ard Biesheuvel, D Scott Phillips,
	Frederic Weisbecker, Ingo Molnar, Josh Poimboeuf, Kees Cook,
	Philippe Mathieu-Daudé,
	Sami Tolvanen, Valentin Schneider, linux-kernel

On Thu, Aug 31, 2023 at 3:14 AM Douglas Anderson <dianders@chromium.org> wrote:
>
> This is an attempt to resurrect Sumit's old patch series [1] that
> allowed us to use the arm64 pseudo-NMI to get backtraces of CPUs and
> also to round up CPUs in kdb/kgdb. The last post from Sumit that I
> could find was v7, so I started my series at v8. I haven't copied all
> of his old changelongs here, but you can find them from the link.
>
> This patch series targets v6.6. Specifically it can't land in v6.5
> since it depends on commit 8d539b84f1e3 ("nmi_backtrace: allow
> excluding an arbitrary CPU").
>
> It should be noted that Mark still feels there might be some corner
> cases where pseudo-NMI is not production ready [2] [3], but as far as
> I'm aware there are no concrete/documented issues. Regardless of
> whether this should be enabled for production, though, this series
> will be invaluable to anyone trying to debug crashes on arm64
> machines.
>
> v12 of this series collects tags, fixes a few small nits in comments
> and commit messages from v11 and adds a new (and somewhat unrelated)
> small patch to the end of the series. There are no code changes other
> than the last patch, which is tiny.
>
> v11 of this series addressed Stephen Boyd's feedback on v10 and added
> a missing "static" that the patches robot found.
>
> v10 of this series attempted to address all of Mark's feedback on
> v9. As a quick summary:
> - It includes his patch to remove IPI_WAKEUP, freeing up an extra IPI.
> - It no longer combines the "kgdb" and "backtrace" IPIs. If we need
>   another IPI these could always be recombined later.
> - It promotes IPI_CPU_STOP and IPI_CPU_CRASH_STOP to NMI.
> - It puts nearly all the code directly in smp.c.
> - Several of the patches are squashed together.
> - Patch #6 ("kgdb: Provide a stub kgdb_nmicallback() if !CONFIG_KGDB")
>   was dropped from the series since it landed.
>
> Between v8 and v9, I had cleaned up this patch series by integrating
> the 10th patch from v8 [4] into the whole series. As part of this, I
> renamed the "NMI IPI" to the "debug IPI" since it could now be backed
> by a regular IPI in the case that pseudo NMIs weren't available. With
> the fallback, this allowed me to drop some extra patches from the
> series. This feels (to me) to be pretty clean and hopefully others
> agree. Any patch I touched significantly I removed Masayoshi and
> Chen-Yu's tags from.
>
> ...also in v8, I reorderd the patches a bit in a way that seemed a
> little cleaner to me.
>
> Since v7, I have:
> * Addressed the small amount of feedback that was there for v7.
> * Rebased.
> * Added a new patch that prevents us from spamming the logs with idle
>   tasks.
> * Added an extra patch to gracefully fall back to regular IPIs if
>   pseudo-NMIs aren't there.
>
> It can be noted that this patch series works very well with the recent
> "hardlockup" patches that have landed through Andrew Morton's tree and
> are currently in mainline. It works especially well with the "buddy"
> lockup detector.
>
> [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg@linaro.org/
> [2] https://lore.kernel.org/lkml/ZFvGqD%2F%2Fpm%2FlZb+p@FVFF77S0Q05N.cambridge.arm.com/
> [3] https://lore.kernel.org/lkml/ZNDKVP2m-iiZCz3v@FVFF77S0Q05N.cambridge.arm.com
> [4] https://lore.kernel.org/r/20230419155341.v8.10.Ic3659997d6243139d0522fc3afcdfd88d7a5f030@changeid/
>
> Changes in v12:
> - ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.
> - Added a comment about why we account for 16 SGIs when Linux uses 8.
> - Minor comment change to add "()" after nmi_trigger_cpumask_backtrace.
> - Updated the commit hash of the commit this depends on.
>
> Changes in v11:
> - Adjust comment about NR_IPI/MAX_IPI.
> - Don't use confusing "backed by" idiom in comment.
> - Made arm64_backtrace_ipi() static.
> - Updated commit message as per Stephen.
> - arch_send_wakeup_ipi() now takes an unsigned int.
>
> Changes in v10:
> - ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.
> - ("arm64: smp: Remove dedicated wakeup IPI") new for v10.
> - Backtrace now directly supported in smp.c
> - Don't allocate the cpumask on the stack; just iterate.
> - Moved kgdb calls to smp.c to avoid needing to export IPI info.
> - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> - Squash backtrace into patch adding support for pseudo-NMI IPIs.
> - kgdb now has its own IPI.
>
> Changes in v9:
> - Added comments that we might not be using NMI always.
> - Added to commit message that this doesn't catch all cases.
> - Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
> - Moved header file out of "include" since it didn't need to be there.
> - Remove arm64_supports_nmi()
> - Remove fallback for when debug IPI isn't available.
> - Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
> - arch_trigger_cpumask_backtrace() no longer returns bool
>
> Changes in v8:
> - "Tag the arm64 idle functions as __cpuidle" new for v8
> - Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
> - debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param
>
> Douglas Anderson (6):
>   irqchip/gic-v3: Enable support for SGIs to act as NMIs
>   arm64: idle: Tag the arm64 idle functions as __cpuidle
>   arm64: smp: Add arch support for backtrace using pseudo-NMI
>   arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
>   arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI
>     roundup
>   arm64: smp: Mark IPI globals as __ro_after_init
>
> Mark Rutland (1):
>   arm64: smp: Remove dedicated wakeup IPI

Whole series is

Tested-by: Chen-Yu Tsai <wenst@chromium.org>

on SolidRun i.MX8MM Hummingboard Pulse by injecting HARDLOCKUP with lkdtm.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
  2023-08-30 19:11   ` Douglas Anderson
@ 2023-08-31  8:53     ` Mark Rutland
  -1 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31  8:53 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, linux-kernel

On Wed, Aug 30, 2023 at 12:11:22PM -0700, Douglas Anderson wrote:
> As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> and use handle_percpu_devid_irq() by default. Unfortunately,
> handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> context those should use handle_percpu_devid_fasteoi_nmi().
> 
> In order to accomplish this, we just have to make room for SGIs in the
> array of refcounts that keeps track of which interrupts are set as
> NMI. We also rename the array and create a new indexing scheme that
> accounts for SGIs.
> 
> Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> as IRQs/NMIs happen as part of this routine.
> 
> Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I'll note that this change is a little more black magic to me than
> others in this series. I don't have a massive amounts of familiarity
> with all the moving parts of gic-v3, so I mostly just followed Mark
> Rutland's advice [1]. Please pay extra attention to make sure I didn't
> do anything too terrible.
> 
> Mark's advice wasn't a full patch and I ended up doing a bit of work
> to translate it to reality, so I did not add him as "Co-developed-by"
> here. Mark: if you would like this tag then please provide it and your
> Signed-off-by. I certainly won't object.

That's all reasonable, and I'm perfectly happy without a tag.

I have one trivial nit below, but with or without that fixed up:

Acked-by: Mark Rutland <mark.rutland@arm.com>

> 
> [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
> 
> Changes in v12:
> - Added a comment about why we account for 16 SGIs when Linux uses 8.
> 
> Changes in v10:
> - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> 
>  drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
>  1 file changed, 41 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index eedfa8e9f077..8d20122ba0a8 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
>  #define GIC_LINE_NR	min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
>  #define GIC_ESPI_NR	GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
>  
> +/*
> + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
> + * are potentially stolen by the secure side. Some code, especially code dealing
> + * with hwirq IDs, is simplified by accounting for all 16.
> + */
> +#define SGI_NR		16
> +
>  /*
>   * The behaviours of RPR and PMR registers differ depending on the value of
>   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
>  		__priority;						\
>  	})
>  
> -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> -static refcount_t *ppi_nmi_refs;
> +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> +static refcount_t *rdist_nmi_refs;
>  
>  static struct gic_kvm_info gic_v3_kvm_info __initdata;
>  static DEFINE_PER_CPU(bool, has_rss);
> @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
>  	}
>  }
>  
> -static u32 gic_get_ppi_index(struct irq_data *d)
> +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> +{
> +	switch (__get_intid_range(hwirq)) {
> +	case SGI_RANGE:
> +	case PPI_RANGE:
> +		return hwirq;
> +	case EPPI_RANGE:
> +		return hwirq - EPPI_BASE_INTID + 32;
> +	default:
> +		unreachable();
> +	}
> +}
> +
> +static u32 gic_get_rdist_idx(struct irq_data *d)
>  {
> -	return __gic_get_ppi_index(d->hwirq);
> +	return __gic_get_rdist_idx(d->hwirq);
>  }

Nit: It would be nicer to call this gic_get_rdist_index() to match
gic_get_ppi_index(); likewise with __gic_get_rdist_index().

That's my fault given I suggested the gic_get_rdist_idx() name in:

  https://lore.kernel.org/linux-arm-kernel/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com/

... so sorry about that!

Mark.

>  
>  static int gic_irq_nmi_setup(struct irq_data *d)
> @@ -545,11 +565,14 @@ static int gic_irq_nmi_setup(struct irq_data *d)
>  
>  	/* desc lock should already be held */
>  	if (gic_irq_in_rdist(d)) {
> -		u32 idx = gic_get_ppi_index(d);
> +		u32 idx = gic_get_rdist_idx(d);
>  
> -		/* Setting up PPI as NMI, only switch handler for first NMI */
> -		if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
> -			refcount_set(&ppi_nmi_refs[idx], 1);
> +		/*
> +		 * Setting up a percpu interrupt as NMI, only switch handler
> +		 * for first NMI
> +		 */
> +		if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
> +			refcount_set(&rdist_nmi_refs[idx], 1);
>  			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
>  		}
>  	} else {
> @@ -582,10 +605,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
>  
>  	/* desc lock should already be held */
>  	if (gic_irq_in_rdist(d)) {
> -		u32 idx = gic_get_ppi_index(d);
> +		u32 idx = gic_get_rdist_idx(d);
>  
>  		/* Tearing down NMI, only switch handler for last NMI */
> -		if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
> +		if (refcount_dec_and_test(&rdist_nmi_refs[idx]))
>  			desc->handle_irq = handle_percpu_devid_irq;
>  	} else {
>  		desc->handle_irq = handle_fasteoi_irq;
> @@ -1279,10 +1302,10 @@ static void gic_cpu_init(void)
>  	rbase = gic_data_rdist_sgi_base();
>  
>  	/* Configure SGIs/PPIs as non-secure Group-1 */
> -	for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
> +	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
>  		writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
>  
> -	gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
> +	gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp);
>  
>  	/* initialise system registers */
>  	gic_cpu_sys_reg_init();
> @@ -1939,12 +1962,13 @@ static void gic_enable_nmi_support(void)
>  		return;
>  	}
>  
> -	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
> -	if (!ppi_nmi_refs)
> +	rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,
> +				 sizeof(*rdist_nmi_refs), GFP_KERNEL);
> +	if (!rdist_nmi_refs)
>  		return;
>  
> -	for (i = 0; i < gic_data.ppi_nr; i++)
> -		refcount_set(&ppi_nmi_refs[i], 0);
> +	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i++)
> +		refcount_set(&rdist_nmi_refs[i], 0);
>  
>  	pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n",
>  		gic_has_relaxed_pmr_sync() ? "relaxed" : "forced");
> @@ -2061,6 +2085,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
>  
>  	gic_dist_init();
>  	gic_cpu_init();
> +	gic_enable_nmi_support();
>  	gic_smp_init();
>  	gic_cpu_pm_init();
>  
> @@ -2073,8 +2098,6 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
>  			gicv2m_init(handle, gic_data.domain);
>  	}
>  
> -	gic_enable_nmi_support();
> -
>  	return 0;
>  
>  out_free:
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

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

* Re: [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
@ 2023-08-31  8:53     ` Mark Rutland
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31  8:53 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, linux-kernel

On Wed, Aug 30, 2023 at 12:11:22PM -0700, Douglas Anderson wrote:
> As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> and use handle_percpu_devid_irq() by default. Unfortunately,
> handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> context those should use handle_percpu_devid_fasteoi_nmi().
> 
> In order to accomplish this, we just have to make room for SGIs in the
> array of refcounts that keeps track of which interrupts are set as
> NMI. We also rename the array and create a new indexing scheme that
> accounts for SGIs.
> 
> Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> as IRQs/NMIs happen as part of this routine.
> 
> Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I'll note that this change is a little more black magic to me than
> others in this series. I don't have a massive amounts of familiarity
> with all the moving parts of gic-v3, so I mostly just followed Mark
> Rutland's advice [1]. Please pay extra attention to make sure I didn't
> do anything too terrible.
> 
> Mark's advice wasn't a full patch and I ended up doing a bit of work
> to translate it to reality, so I did not add him as "Co-developed-by"
> here. Mark: if you would like this tag then please provide it and your
> Signed-off-by. I certainly won't object.

That's all reasonable, and I'm perfectly happy without a tag.

I have one trivial nit below, but with or without that fixed up:

Acked-by: Mark Rutland <mark.rutland@arm.com>

> 
> [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
> 
> Changes in v12:
> - Added a comment about why we account for 16 SGIs when Linux uses 8.
> 
> Changes in v10:
> - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> 
>  drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
>  1 file changed, 41 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index eedfa8e9f077..8d20122ba0a8 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
>  #define GIC_LINE_NR	min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
>  #define GIC_ESPI_NR	GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
>  
> +/*
> + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
> + * are potentially stolen by the secure side. Some code, especially code dealing
> + * with hwirq IDs, is simplified by accounting for all 16.
> + */
> +#define SGI_NR		16
> +
>  /*
>   * The behaviours of RPR and PMR registers differ depending on the value of
>   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
>  		__priority;						\
>  	})
>  
> -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> -static refcount_t *ppi_nmi_refs;
> +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> +static refcount_t *rdist_nmi_refs;
>  
>  static struct gic_kvm_info gic_v3_kvm_info __initdata;
>  static DEFINE_PER_CPU(bool, has_rss);
> @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
>  	}
>  }
>  
> -static u32 gic_get_ppi_index(struct irq_data *d)
> +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> +{
> +	switch (__get_intid_range(hwirq)) {
> +	case SGI_RANGE:
> +	case PPI_RANGE:
> +		return hwirq;
> +	case EPPI_RANGE:
> +		return hwirq - EPPI_BASE_INTID + 32;
> +	default:
> +		unreachable();
> +	}
> +}
> +
> +static u32 gic_get_rdist_idx(struct irq_data *d)
>  {
> -	return __gic_get_ppi_index(d->hwirq);
> +	return __gic_get_rdist_idx(d->hwirq);
>  }

Nit: It would be nicer to call this gic_get_rdist_index() to match
gic_get_ppi_index(); likewise with __gic_get_rdist_index().

That's my fault given I suggested the gic_get_rdist_idx() name in:

  https://lore.kernel.org/linux-arm-kernel/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com/

... so sorry about that!

Mark.

>  
>  static int gic_irq_nmi_setup(struct irq_data *d)
> @@ -545,11 +565,14 @@ static int gic_irq_nmi_setup(struct irq_data *d)
>  
>  	/* desc lock should already be held */
>  	if (gic_irq_in_rdist(d)) {
> -		u32 idx = gic_get_ppi_index(d);
> +		u32 idx = gic_get_rdist_idx(d);
>  
> -		/* Setting up PPI as NMI, only switch handler for first NMI */
> -		if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
> -			refcount_set(&ppi_nmi_refs[idx], 1);
> +		/*
> +		 * Setting up a percpu interrupt as NMI, only switch handler
> +		 * for first NMI
> +		 */
> +		if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
> +			refcount_set(&rdist_nmi_refs[idx], 1);
>  			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
>  		}
>  	} else {
> @@ -582,10 +605,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
>  
>  	/* desc lock should already be held */
>  	if (gic_irq_in_rdist(d)) {
> -		u32 idx = gic_get_ppi_index(d);
> +		u32 idx = gic_get_rdist_idx(d);
>  
>  		/* Tearing down NMI, only switch handler for last NMI */
> -		if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
> +		if (refcount_dec_and_test(&rdist_nmi_refs[idx]))
>  			desc->handle_irq = handle_percpu_devid_irq;
>  	} else {
>  		desc->handle_irq = handle_fasteoi_irq;
> @@ -1279,10 +1302,10 @@ static void gic_cpu_init(void)
>  	rbase = gic_data_rdist_sgi_base();
>  
>  	/* Configure SGIs/PPIs as non-secure Group-1 */
> -	for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
> +	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
>  		writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
>  
> -	gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
> +	gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp);
>  
>  	/* initialise system registers */
>  	gic_cpu_sys_reg_init();
> @@ -1939,12 +1962,13 @@ static void gic_enable_nmi_support(void)
>  		return;
>  	}
>  
> -	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
> -	if (!ppi_nmi_refs)
> +	rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,
> +				 sizeof(*rdist_nmi_refs), GFP_KERNEL);
> +	if (!rdist_nmi_refs)
>  		return;
>  
> -	for (i = 0; i < gic_data.ppi_nr; i++)
> -		refcount_set(&ppi_nmi_refs[i], 0);
> +	for (i = 0; i < gic_data.ppi_nr + SGI_NR; i++)
> +		refcount_set(&rdist_nmi_refs[i], 0);
>  
>  	pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n",
>  		gic_has_relaxed_pmr_sync() ? "relaxed" : "forced");
> @@ -2061,6 +2085,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
>  
>  	gic_dist_init();
>  	gic_cpu_init();
> +	gic_enable_nmi_support();
>  	gic_smp_init();
>  	gic_cpu_pm_init();
>  
> @@ -2073,8 +2098,6 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
>  			gicv2m_init(handle, gic_data.domain);
>  	}
>  
> -	gic_enable_nmi_support();
> -
>  	return 0;
>  
>  out_free:
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v12 5/7] arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
  2023-08-30 19:11   ` Douglas Anderson
@ 2023-08-31 10:12     ` Mark Rutland
  -1 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 10:12 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, D Scott Phillips, Josh Poimboeuf,
	Valentin Schneider, linux-kernel

On Wed, Aug 30, 2023 at 12:11:26PM -0700, Douglas Anderson wrote:
> There's no reason why IPI_CPU_STOP and IPI_CPU_CRASH_STOP can't be
> handled as NMI. They are very simple and everything in them is
> NMI-safe. Mark them as things to use NMI for if NMI is available.
> 
> Suggested-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Reviewed-by: Misono Tomohiro <misono.tomohiro@fujitsu.com>
> Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I don't actually have any good way to test/validate this patch. It's
> added to the series at Mark's request.

I've just sent out an LKDTM test that can be used to test this:

  http://lore.kernel.org/lkml/20230831101026.3122590-1-mark.rutland@arm.com

So FWIW:

Acked-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> (no changes since v10)
> 
> Changes in v10:
> - ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.
> 
>  arch/arm64/kernel/smp.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 28c904ca499a..800c59cf9b64 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -946,6 +946,8 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
>  		return false;
>  
>  	switch (ipi) {
> +	case IPI_CPU_STOP:
> +	case IPI_CPU_CRASH_STOP:
>  	case IPI_CPU_BACKTRACE:
>  		return true;
>  	default:
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

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

* Re: [PATCH v12 5/7] arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI
@ 2023-08-31 10:12     ` Mark Rutland
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 10:12 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, D Scott Phillips, Josh Poimboeuf,
	Valentin Schneider, linux-kernel

On Wed, Aug 30, 2023 at 12:11:26PM -0700, Douglas Anderson wrote:
> There's no reason why IPI_CPU_STOP and IPI_CPU_CRASH_STOP can't be
> handled as NMI. They are very simple and everything in them is
> NMI-safe. Mark them as things to use NMI for if NMI is available.
> 
> Suggested-by: Mark Rutland <mark.rutland@arm.com>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Reviewed-by: Misono Tomohiro <misono.tomohiro@fujitsu.com>
> Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I don't actually have any good way to test/validate this patch. It's
> added to the series at Mark's request.

I've just sent out an LKDTM test that can be used to test this:

  http://lore.kernel.org/lkml/20230831101026.3122590-1-mark.rutland@arm.com

So FWIW:

Acked-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> (no changes since v10)
> 
> Changes in v10:
> - ("IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI") new for v10.
> 
>  arch/arm64/kernel/smp.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 28c904ca499a..800c59cf9b64 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -946,6 +946,8 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
>  		return false;
>  
>  	switch (ipi) {
> +	case IPI_CPU_STOP:
> +	case IPI_CPU_CRASH_STOP:
>  	case IPI_CPU_BACKTRACE:
>  		return true;
>  	default:
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v12 6/7] arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI roundup
  2023-08-30 19:11   ` Douglas Anderson
@ 2023-08-31 10:14     ` Mark Rutland
  -1 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 10:14 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, D Scott Phillips, Josh Poimboeuf,
	Valentin Schneider, linux-kernel

On Wed, Aug 30, 2023 at 12:11:27PM -0700, Douglas Anderson wrote:
> Up until now we've been using the generic (weak) implementation for
> kgdb_roundup_cpus() when using kgdb on arm64. Let's move to a custom
> one. The advantage here is that, when pseudo-NMI is enabled on a
> device, we'll be able to round up CPUs using pseudo-NMI. This allows
> us to debug CPUs that are stuck with interrupts disabled. If
> pseudo-NMIs are not enabled then we'll fallback to just using an IPI,
> which is still slightly better than the generic implementation since
> it avoids the potential situation described in the generic
> kgdb_call_nmi_hook().
> 
> Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I debated whether this should be in "arch/arm64/kernel/smp.c" or if I
> should try to find a way for it to go into "arch/arm64/kernel/kgdb.c".
> In the end this is so little code that it didn't seem worth it to find
> a way to export the IPI defines or to otherwise come up with some API
> between kgdb.c and smp.c. If someone has strong feelings and wants
> this to change, please shout and give details of your preferred
> solution.

Putting this in smp.c seems fine to me.

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> FWIW, it seems like ~half the other platforms put this in "smp.c" with
> an ifdef for KGDB and the other half put it in "kgdb.c" with an ifdef
> for SMP. :-P
> 
> (no changes since v10)
> 
> Changes in v10:
> - Don't allocate the cpumask on the stack; just iterate.
> - Moved kgdb calls to smp.c to avoid needing to export IPI info.
> - kgdb now has its own IPI.
> 
> Changes in v9:
> - Remove fallback for when debug IPI isn't available.
> - Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
> 
>  arch/arm64/kernel/smp.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 800c59cf9b64..1a53e57c81d0 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -32,6 +32,7 @@
>  #include <linux/irq_work.h>
>  #include <linux/kernel_stat.h>
>  #include <linux/kexec.h>
> +#include <linux/kgdb.h>
>  #include <linux/kvm_host.h>
>  #include <linux/nmi.h>
>  
> @@ -79,6 +80,7 @@ enum ipi_msg_type {
>  	 * with trace_ipi_*
>  	 */
>  	IPI_CPU_BACKTRACE = NR_IPI,
> +	IPI_KGDB_ROUNDUP,
>  	MAX_IPI
>  };
>  
> @@ -868,6 +870,22 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
>  	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
>  }
>  
> +#ifdef CONFIG_KGDB
> +void kgdb_roundup_cpus(void)
> +{
> +	int this_cpu = raw_smp_processor_id();
> +	int cpu;
> +
> +	for_each_online_cpu(cpu) {
> +		/* No need to roundup ourselves */
> +		if (cpu == this_cpu)
> +			continue;
> +
> +		__ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu);
> +	}
> +}
> +#endif
> +
>  /*
>   * Main handler for inter-processor interrupts
>   */
> @@ -919,6 +937,10 @@ static void do_handle_IPI(int ipinr)
>  		nmi_cpu_backtrace(get_irq_regs());
>  		break;
>  
> +	case IPI_KGDB_ROUNDUP:
> +		kgdb_nmicallback(cpu, get_irq_regs());
> +		break;
> +
>  	default:
>  		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
>  		break;
> @@ -949,6 +971,7 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
>  	case IPI_CPU_STOP:
>  	case IPI_CPU_CRASH_STOP:
>  	case IPI_CPU_BACKTRACE:
> +	case IPI_KGDB_ROUNDUP:
>  		return true;
>  	default:
>  		return false;
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

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

* Re: [PATCH v12 6/7] arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI roundup
@ 2023-08-31 10:14     ` Mark Rutland
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 10:14 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, D Scott Phillips, Josh Poimboeuf,
	Valentin Schneider, linux-kernel

On Wed, Aug 30, 2023 at 12:11:27PM -0700, Douglas Anderson wrote:
> Up until now we've been using the generic (weak) implementation for
> kgdb_roundup_cpus() when using kgdb on arm64. Let's move to a custom
> one. The advantage here is that, when pseudo-NMI is enabled on a
> device, we'll be able to round up CPUs using pseudo-NMI. This allows
> us to debug CPUs that are stuck with interrupts disabled. If
> pseudo-NMIs are not enabled then we'll fallback to just using an IPI,
> which is still slightly better than the generic implementation since
> it avoids the potential situation described in the generic
> kgdb_call_nmi_hook().
> 
> Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> I debated whether this should be in "arch/arm64/kernel/smp.c" or if I
> should try to find a way for it to go into "arch/arm64/kernel/kgdb.c".
> In the end this is so little code that it didn't seem worth it to find
> a way to export the IPI defines or to otherwise come up with some API
> between kgdb.c and smp.c. If someone has strong feelings and wants
> this to change, please shout and give details of your preferred
> solution.

Putting this in smp.c seems fine to me.

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> FWIW, it seems like ~half the other platforms put this in "smp.c" with
> an ifdef for KGDB and the other half put it in "kgdb.c" with an ifdef
> for SMP. :-P
> 
> (no changes since v10)
> 
> Changes in v10:
> - Don't allocate the cpumask on the stack; just iterate.
> - Moved kgdb calls to smp.c to avoid needing to export IPI info.
> - kgdb now has its own IPI.
> 
> Changes in v9:
> - Remove fallback for when debug IPI isn't available.
> - Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
> 
>  arch/arm64/kernel/smp.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 800c59cf9b64..1a53e57c81d0 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -32,6 +32,7 @@
>  #include <linux/irq_work.h>
>  #include <linux/kernel_stat.h>
>  #include <linux/kexec.h>
> +#include <linux/kgdb.h>
>  #include <linux/kvm_host.h>
>  #include <linux/nmi.h>
>  
> @@ -79,6 +80,7 @@ enum ipi_msg_type {
>  	 * with trace_ipi_*
>  	 */
>  	IPI_CPU_BACKTRACE = NR_IPI,
> +	IPI_KGDB_ROUNDUP,
>  	MAX_IPI
>  };
>  
> @@ -868,6 +870,22 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
>  	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, arm64_backtrace_ipi);
>  }
>  
> +#ifdef CONFIG_KGDB
> +void kgdb_roundup_cpus(void)
> +{
> +	int this_cpu = raw_smp_processor_id();
> +	int cpu;
> +
> +	for_each_online_cpu(cpu) {
> +		/* No need to roundup ourselves */
> +		if (cpu == this_cpu)
> +			continue;
> +
> +		__ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu);
> +	}
> +}
> +#endif
> +
>  /*
>   * Main handler for inter-processor interrupts
>   */
> @@ -919,6 +937,10 @@ static void do_handle_IPI(int ipinr)
>  		nmi_cpu_backtrace(get_irq_regs());
>  		break;
>  
> +	case IPI_KGDB_ROUNDUP:
> +		kgdb_nmicallback(cpu, get_irq_regs());
> +		break;
> +
>  	default:
>  		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
>  		break;
> @@ -949,6 +971,7 @@ static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
>  	case IPI_CPU_STOP:
>  	case IPI_CPU_CRASH_STOP:
>  	case IPI_CPU_BACKTRACE:
> +	case IPI_KGDB_ROUNDUP:
>  		return true;
>  	default:
>  		return false;
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v12 7/7] arm64: smp: Mark IPI globals as __ro_after_init
  2023-08-30 19:11   ` Douglas Anderson
@ 2023-08-31 10:15     ` Mark Rutland
  -1 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 10:15 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, D Scott Phillips, Josh Poimboeuf,
	Valentin Schneider, linux-kernel

On Wed, Aug 30, 2023 at 12:11:28PM -0700, Douglas Anderson wrote:
> Mark the three IPI-related globals in smp.c as "__ro_after_init" since
> they are only ever set in set_smp_ipi_range(), which is marked
> "__init". This is a better and more secure marking than the old
> "__read_mostly".
> 
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> This patch is almost completely unrelated to the rest of the series
> other than the fact that it would cause a merge conflict with the
> series if sent separately. I tacked it on to this series in response
> to Stephen's feedback on v11 of this series [1]. If someone hates it
> (not sure why they would), it could be dropped. If someone loves it,
> it could be promoted to the start of the series and/or land on its own
> (resolving merge conflicts).
> 
> [1] https://lore.kernel.org/r/CAE-0n52iVDgZa8XT8KTMj12c_ESSJt7f7A0fuZ_oAMMqpGcSzA@mail.gmail.com

This looks reasonable to me, so:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> Changes in v12:
> - ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.
> 
>  arch/arm64/kernel/smp.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 1a53e57c81d0..814d9aa93b21 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -84,9 +84,9 @@ enum ipi_msg_type {
>  	MAX_IPI
>  };
>  
> -static int ipi_irq_base __read_mostly;
> -static int nr_ipi __read_mostly = NR_IPI;
> -static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
> +static int ipi_irq_base __ro_after_init;
> +static int nr_ipi __ro_after_init = NR_IPI;
> +static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
>  
>  static void ipi_setup(int cpu);
>  
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

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

* Re: [PATCH v12 7/7] arm64: smp: Mark IPI globals as __ro_after_init
@ 2023-08-31 10:15     ` Mark Rutland
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 10:15 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, D Scott Phillips, Josh Poimboeuf,
	Valentin Schneider, linux-kernel

On Wed, Aug 30, 2023 at 12:11:28PM -0700, Douglas Anderson wrote:
> Mark the three IPI-related globals in smp.c as "__ro_after_init" since
> they are only ever set in set_smp_ipi_range(), which is marked
> "__init". This is a better and more secure marking than the old
> "__read_mostly".
> 
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> This patch is almost completely unrelated to the rest of the series
> other than the fact that it would cause a merge conflict with the
> series if sent separately. I tacked it on to this series in response
> to Stephen's feedback on v11 of this series [1]. If someone hates it
> (not sure why they would), it could be dropped. If someone loves it,
> it could be promoted to the start of the series and/or land on its own
> (resolving merge conflicts).
> 
> [1] https://lore.kernel.org/r/CAE-0n52iVDgZa8XT8KTMj12c_ESSJt7f7A0fuZ_oAMMqpGcSzA@mail.gmail.com

This looks reasonable to me, so:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

> 
> Changes in v12:
> - ("arm64: smp: Mark IPI globals as __ro_after_init") new for v12.
> 
>  arch/arm64/kernel/smp.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 1a53e57c81d0..814d9aa93b21 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -84,9 +84,9 @@ enum ipi_msg_type {
>  	MAX_IPI
>  };
>  
> -static int ipi_irq_base __read_mostly;
> -static int nr_ipi __read_mostly = NR_IPI;
> -static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
> +static int ipi_irq_base __ro_after_init;
> +static int nr_ipi __ro_after_init = NR_IPI;
> +static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
>  
>  static void ipi_setup(int cpu);
>  
> -- 
> 2.42.0.283.g2d96d420d3-goog
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
  2023-08-31  8:53     ` Mark Rutland
@ 2023-08-31 15:31       ` Doug Anderson
  -1 siblings, 0 replies; 30+ messages in thread
From: Doug Anderson @ 2023-08-31 15:31 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, linux-kernel

Hi,

On Thu, Aug 31, 2023 at 1:53 AM Mark Rutland <mark.rutland@arm.com> wrote:
>
> On Wed, Aug 30, 2023 at 12:11:22PM -0700, Douglas Anderson wrote:
> > As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> > handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> > and use handle_percpu_devid_irq() by default. Unfortunately,
> > handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> > context those should use handle_percpu_devid_fasteoi_nmi().
> >
> > In order to accomplish this, we just have to make room for SGIs in the
> > array of refcounts that keeps track of which interrupts are set as
> > NMI. We also rename the array and create a new indexing scheme that
> > accounts for SGIs.
> >
> > Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> > as IRQs/NMIs happen as part of this routine.
> >
> > Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> > I'll note that this change is a little more black magic to me than
> > others in this series. I don't have a massive amounts of familiarity
> > with all the moving parts of gic-v3, so I mostly just followed Mark
> > Rutland's advice [1]. Please pay extra attention to make sure I didn't
> > do anything too terrible.
> >
> > Mark's advice wasn't a full patch and I ended up doing a bit of work
> > to translate it to reality, so I did not add him as "Co-developed-by"
> > here. Mark: if you would like this tag then please provide it and your
> > Signed-off-by. I certainly won't object.
>
> That's all reasonable, and I'm perfectly happy without a tag.
>
> I have one trivial nit below, but with or without that fixed up:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
>
> >
> > [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
> >
> > Changes in v12:
> > - Added a comment about why we account for 16 SGIs when Linux uses 8.
> >
> > Changes in v10:
> > - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> >
> >  drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
> >  1 file changed, 41 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > index eedfa8e9f077..8d20122ba0a8 100644
> > --- a/drivers/irqchip/irq-gic-v3.c
> > +++ b/drivers/irqchip/irq-gic-v3.c
> > @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
> >  #define GIC_LINE_NR  min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
> >  #define GIC_ESPI_NR  GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
> >
> > +/*
> > + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
> > + * are potentially stolen by the secure side. Some code, especially code dealing
> > + * with hwirq IDs, is simplified by accounting for all 16.
> > + */
> > +#define SGI_NR               16
> > +
> >  /*
> >   * The behaviours of RPR and PMR registers differ depending on the value of
> >   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> > @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
> >               __priority;                                             \
> >       })
> >
> > -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> > -static refcount_t *ppi_nmi_refs;
> > +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> > +static refcount_t *rdist_nmi_refs;
> >
> >  static struct gic_kvm_info gic_v3_kvm_info __initdata;
> >  static DEFINE_PER_CPU(bool, has_rss);
> > @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
> >       }
> >  }
> >
> > -static u32 gic_get_ppi_index(struct irq_data *d)
> > +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> > +{
> > +     switch (__get_intid_range(hwirq)) {
> > +     case SGI_RANGE:
> > +     case PPI_RANGE:
> > +             return hwirq;
> > +     case EPPI_RANGE:
> > +             return hwirq - EPPI_BASE_INTID + 32;
> > +     default:
> > +             unreachable();
> > +     }
> > +}
> > +
> > +static u32 gic_get_rdist_idx(struct irq_data *d)
> >  {
> > -     return __gic_get_ppi_index(d->hwirq);
> > +     return __gic_get_rdist_idx(d->hwirq);
> >  }
>
> Nit: It would be nicer to call this gic_get_rdist_index() to match
> gic_get_ppi_index(); likewise with __gic_get_rdist_index().
>
> That's my fault given I suggested the gic_get_rdist_idx() name in:
>
>   https://lore.kernel.org/linux-arm-kernel/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com/
>
> ... so sorry about that!

Yeah, I kept the name you suggested even though it seemed a little
inconsistent. I'll happily send a v13 with that fixed up, though I'll
probably wait a little bit just to avoid spamming new versions too
quickly. It's not like the patches can land in the middle of the merge
window anyway.

Unless someone says otherwise, I guess this series is in good shape to
land then. Does anyone have any plans for the details of how to land
it? I guess this would be something that Marc, Catalin and Will would
need to hash out since the first patch would ideally go through a
different tree than the others.

-Doug

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

* Re: [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
@ 2023-08-31 15:31       ` Doug Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Doug Anderson @ 2023-08-31 15:31 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	Marc Zyngier, linux-arm-kernel, Masayoshi Mizuma,
	Rafael J . Wysocki, Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono,
	Stephane Eranian, kgdb-bugreport, Peter Zijlstra,
	Thomas Gleixner, Stephen Boyd, ito-yuichi, linux-perf-users,
	Ard Biesheuvel, linux-kernel

Hi,

On Thu, Aug 31, 2023 at 1:53 AM Mark Rutland <mark.rutland@arm.com> wrote:
>
> On Wed, Aug 30, 2023 at 12:11:22PM -0700, Douglas Anderson wrote:
> > As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> > handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> > and use handle_percpu_devid_irq() by default. Unfortunately,
> > handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> > context those should use handle_percpu_devid_fasteoi_nmi().
> >
> > In order to accomplish this, we just have to make room for SGIs in the
> > array of refcounts that keeps track of which interrupts are set as
> > NMI. We also rename the array and create a new indexing scheme that
> > accounts for SGIs.
> >
> > Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> > as IRQs/NMIs happen as part of this routine.
> >
> > Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> > I'll note that this change is a little more black magic to me than
> > others in this series. I don't have a massive amounts of familiarity
> > with all the moving parts of gic-v3, so I mostly just followed Mark
> > Rutland's advice [1]. Please pay extra attention to make sure I didn't
> > do anything too terrible.
> >
> > Mark's advice wasn't a full patch and I ended up doing a bit of work
> > to translate it to reality, so I did not add him as "Co-developed-by"
> > here. Mark: if you would like this tag then please provide it and your
> > Signed-off-by. I certainly won't object.
>
> That's all reasonable, and I'm perfectly happy without a tag.
>
> I have one trivial nit below, but with or without that fixed up:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
>
> >
> > [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
> >
> > Changes in v12:
> > - Added a comment about why we account for 16 SGIs when Linux uses 8.
> >
> > Changes in v10:
> > - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> >
> >  drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
> >  1 file changed, 41 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > index eedfa8e9f077..8d20122ba0a8 100644
> > --- a/drivers/irqchip/irq-gic-v3.c
> > +++ b/drivers/irqchip/irq-gic-v3.c
> > @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
> >  #define GIC_LINE_NR  min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
> >  #define GIC_ESPI_NR  GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
> >
> > +/*
> > + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
> > + * are potentially stolen by the secure side. Some code, especially code dealing
> > + * with hwirq IDs, is simplified by accounting for all 16.
> > + */
> > +#define SGI_NR               16
> > +
> >  /*
> >   * The behaviours of RPR and PMR registers differ depending on the value of
> >   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> > @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
> >               __priority;                                             \
> >       })
> >
> > -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> > -static refcount_t *ppi_nmi_refs;
> > +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> > +static refcount_t *rdist_nmi_refs;
> >
> >  static struct gic_kvm_info gic_v3_kvm_info __initdata;
> >  static DEFINE_PER_CPU(bool, has_rss);
> > @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
> >       }
> >  }
> >
> > -static u32 gic_get_ppi_index(struct irq_data *d)
> > +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> > +{
> > +     switch (__get_intid_range(hwirq)) {
> > +     case SGI_RANGE:
> > +     case PPI_RANGE:
> > +             return hwirq;
> > +     case EPPI_RANGE:
> > +             return hwirq - EPPI_BASE_INTID + 32;
> > +     default:
> > +             unreachable();
> > +     }
> > +}
> > +
> > +static u32 gic_get_rdist_idx(struct irq_data *d)
> >  {
> > -     return __gic_get_ppi_index(d->hwirq);
> > +     return __gic_get_rdist_idx(d->hwirq);
> >  }
>
> Nit: It would be nicer to call this gic_get_rdist_index() to match
> gic_get_ppi_index(); likewise with __gic_get_rdist_index().
>
> That's my fault given I suggested the gic_get_rdist_idx() name in:
>
>   https://lore.kernel.org/linux-arm-kernel/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com/
>
> ... so sorry about that!

Yeah, I kept the name you suggested even though it seemed a little
inconsistent. I'll happily send a v13 with that fixed up, though I'll
probably wait a little bit just to avoid spamming new versions too
quickly. It's not like the patches can land in the middle of the merge
window anyway.

Unless someone says otherwise, I guess this series is in good shape to
land then. Does anyone have any plans for the details of how to land
it? I guess this would be something that Marc, Catalin and Will would
need to hash out since the first patch would ideally go through a
different tree than the others.

-Doug

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
  2023-08-31 15:31       ` Doug Anderson
@ 2023-08-31 15:45         ` Mark Rutland
  -1 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 15:45 UTC (permalink / raw)
  To: Doug Anderson, Marc Zyngier
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, linux-kernel

On Thu, Aug 31, 2023 at 08:31:37AM -0700, Doug Anderson wrote:
> Hi,
> 
> On Thu, Aug 31, 2023 at 1:53 AM Mark Rutland <mark.rutland@arm.com> wrote:
> >
> > On Wed, Aug 30, 2023 at 12:11:22PM -0700, Douglas Anderson wrote:
> > > As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> > > handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> > > and use handle_percpu_devid_irq() by default. Unfortunately,
> > > handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> > > context those should use handle_percpu_devid_fasteoi_nmi().
> > >
> > > In order to accomplish this, we just have to make room for SGIs in the
> > > array of refcounts that keeps track of which interrupts are set as
> > > NMI. We also rename the array and create a new indexing scheme that
> > > accounts for SGIs.
> > >
> > > Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> > > as IRQs/NMIs happen as part of this routine.
> > >
> > > Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> > > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > > ---
> > > I'll note that this change is a little more black magic to me than
> > > others in this series. I don't have a massive amounts of familiarity
> > > with all the moving parts of gic-v3, so I mostly just followed Mark
> > > Rutland's advice [1]. Please pay extra attention to make sure I didn't
> > > do anything too terrible.
> > >
> > > Mark's advice wasn't a full patch and I ended up doing a bit of work
> > > to translate it to reality, so I did not add him as "Co-developed-by"
> > > here. Mark: if you would like this tag then please provide it and your
> > > Signed-off-by. I certainly won't object.
> >
> > That's all reasonable, and I'm perfectly happy without a tag.
> >
> > I have one trivial nit below, but with or without that fixed up:
> >
> > Acked-by: Mark Rutland <mark.rutland@arm.com>
> >
> > >
> > > [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
> > >
> > > Changes in v12:
> > > - Added a comment about why we account for 16 SGIs when Linux uses 8.
> > >
> > > Changes in v10:
> > > - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> > >
> > >  drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
> > >  1 file changed, 41 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > index eedfa8e9f077..8d20122ba0a8 100644
> > > --- a/drivers/irqchip/irq-gic-v3.c
> > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
> > >  #define GIC_LINE_NR  min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
> > >  #define GIC_ESPI_NR  GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
> > >
> > > +/*
> > > + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
> > > + * are potentially stolen by the secure side. Some code, especially code dealing
> > > + * with hwirq IDs, is simplified by accounting for all 16.
> > > + */
> > > +#define SGI_NR               16
> > > +
> > >  /*
> > >   * The behaviours of RPR and PMR registers differ depending on the value of
> > >   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> > > @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
> > >               __priority;                                             \
> > >       })
> > >
> > > -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> > > -static refcount_t *ppi_nmi_refs;
> > > +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> > > +static refcount_t *rdist_nmi_refs;
> > >
> > >  static struct gic_kvm_info gic_v3_kvm_info __initdata;
> > >  static DEFINE_PER_CPU(bool, has_rss);
> > > @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
> > >       }
> > >  }
> > >
> > > -static u32 gic_get_ppi_index(struct irq_data *d)
> > > +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> > > +{
> > > +     switch (__get_intid_range(hwirq)) {
> > > +     case SGI_RANGE:
> > > +     case PPI_RANGE:
> > > +             return hwirq;
> > > +     case EPPI_RANGE:
> > > +             return hwirq - EPPI_BASE_INTID + 32;
> > > +     default:
> > > +             unreachable();
> > > +     }
> > > +}
> > > +
> > > +static u32 gic_get_rdist_idx(struct irq_data *d)
> > >  {
> > > -     return __gic_get_ppi_index(d->hwirq);
> > > +     return __gic_get_rdist_idx(d->hwirq);
> > >  }
> >
> > Nit: It would be nicer to call this gic_get_rdist_index() to match
> > gic_get_ppi_index(); likewise with __gic_get_rdist_index().
> >
> > That's my fault given I suggested the gic_get_rdist_idx() name in:
> >
> >   https://lore.kernel.org/linux-arm-kernel/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com/
> >
> > ... so sorry about that!
> 
> Yeah, I kept the name you suggested even though it seemed a little
> inconsistent. I'll happily send a v13 with that fixed up, though I'll
> probably wait a little bit just to avoid spamming new versions too
> quickly. It's not like the patches can land in the middle of the merge
> window anyway.
> 
> Unless someone says otherwise, I guess this series is in good shape to
> land then. 

I think so, yes.

> Does anyone have any plans for the details of how to land it? I guess this
> would be something that Marc, Catalin and Will would need to hash out since
> the first patch would ideally go through a different tree than the others.

I suspect that as long as the GIC patch doesn't conflict with anything in the
irqchip tree (and assuming Marc's happy with it), we could route this all
through the arm64 tree as that's what we did when we added support for
pseudo-NMI in the first place.

Marc, thoughts?

Mark.

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

* Re: [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs
@ 2023-08-31 15:45         ` Mark Rutland
  0 siblings, 0 replies; 30+ messages in thread
From: Mark Rutland @ 2023-08-31 15:45 UTC (permalink / raw)
  To: Doug Anderson, Marc Zyngier
  Cc: Catalin Marinas, Will Deacon, Sumit Garg, Daniel Thompson,
	linux-arm-kernel, Masayoshi Mizuma, Rafael J . Wysocki,
	Chen-Yu Tsai, Lecopzer Chen, Tomohiro Misono, Stephane Eranian,
	kgdb-bugreport, Peter Zijlstra, Thomas Gleixner, Stephen Boyd,
	ito-yuichi, linux-perf-users, Ard Biesheuvel, linux-kernel

On Thu, Aug 31, 2023 at 08:31:37AM -0700, Doug Anderson wrote:
> Hi,
> 
> On Thu, Aug 31, 2023 at 1:53 AM Mark Rutland <mark.rutland@arm.com> wrote:
> >
> > On Wed, Aug 30, 2023 at 12:11:22PM -0700, Douglas Anderson wrote:
> > > As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> > > handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> > > and use handle_percpu_devid_irq() by default. Unfortunately,
> > > handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> > > context those should use handle_percpu_devid_fasteoi_nmi().
> > >
> > > In order to accomplish this, we just have to make room for SGIs in the
> > > array of refcounts that keeps track of which interrupts are set as
> > > NMI. We also rename the array and create a new indexing scheme that
> > > accounts for SGIs.
> > >
> > > Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> > > as IRQs/NMIs happen as part of this routine.
> > >
> > > Co-developed-by: Sumit Garg <sumit.garg@linaro.org>
> > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
> > > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > > ---
> > > I'll note that this change is a little more black magic to me than
> > > others in this series. I don't have a massive amounts of familiarity
> > > with all the moving parts of gic-v3, so I mostly just followed Mark
> > > Rutland's advice [1]. Please pay extra attention to make sure I didn't
> > > do anything too terrible.
> > >
> > > Mark's advice wasn't a full patch and I ended up doing a bit of work
> > > to translate it to reality, so I did not add him as "Co-developed-by"
> > > here. Mark: if you would like this tag then please provide it and your
> > > Signed-off-by. I certainly won't object.
> >
> > That's all reasonable, and I'm perfectly happy without a tag.
> >
> > I have one trivial nit below, but with or without that fixed up:
> >
> > Acked-by: Mark Rutland <mark.rutland@arm.com>
> >
> > >
> > > [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
> > >
> > > Changes in v12:
> > > - Added a comment about why we account for 16 SGIs when Linux uses 8.
> > >
> > > Changes in v10:
> > > - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
> > >
> > >  drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++-----------
> > >  1 file changed, 41 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > > index eedfa8e9f077..8d20122ba0a8 100644
> > > --- a/drivers/irqchip/irq-gic-v3.c
> > > +++ b/drivers/irqchip/irq-gic-v3.c
> > > @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
> > >  #define GIC_LINE_NR  min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
> > >  #define GIC_ESPI_NR  GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
> > >
> > > +/*
> > > + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 SGIs
> > > + * are potentially stolen by the secure side. Some code, especially code dealing
> > > + * with hwirq IDs, is simplified by accounting for all 16.
> > > + */
> > > +#define SGI_NR               16
> > > +
> > >  /*
> > >   * The behaviours of RPR and PMR registers differ depending on the value of
> > >   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> > > @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
> > >               __priority;                                             \
> > >       })
> > >
> > > -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> > > -static refcount_t *ppi_nmi_refs;
> > > +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> > > +static refcount_t *rdist_nmi_refs;
> > >
> > >  static struct gic_kvm_info gic_v3_kvm_info __initdata;
> > >  static DEFINE_PER_CPU(bool, has_rss);
> > > @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
> > >       }
> > >  }
> > >
> > > -static u32 gic_get_ppi_index(struct irq_data *d)
> > > +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> > > +{
> > > +     switch (__get_intid_range(hwirq)) {
> > > +     case SGI_RANGE:
> > > +     case PPI_RANGE:
> > > +             return hwirq;
> > > +     case EPPI_RANGE:
> > > +             return hwirq - EPPI_BASE_INTID + 32;
> > > +     default:
> > > +             unreachable();
> > > +     }
> > > +}
> > > +
> > > +static u32 gic_get_rdist_idx(struct irq_data *d)
> > >  {
> > > -     return __gic_get_ppi_index(d->hwirq);
> > > +     return __gic_get_rdist_idx(d->hwirq);
> > >  }
> >
> > Nit: It would be nicer to call this gic_get_rdist_index() to match
> > gic_get_ppi_index(); likewise with __gic_get_rdist_index().
> >
> > That's my fault given I suggested the gic_get_rdist_idx() name in:
> >
> >   https://lore.kernel.org/linux-arm-kernel/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com/
> >
> > ... so sorry about that!
> 
> Yeah, I kept the name you suggested even though it seemed a little
> inconsistent. I'll happily send a v13 with that fixed up, though I'll
> probably wait a little bit just to avoid spamming new versions too
> quickly. It's not like the patches can land in the middle of the merge
> window anyway.
> 
> Unless someone says otherwise, I guess this series is in good shape to
> land then. 

I think so, yes.

> Does anyone have any plans for the details of how to land it? I guess this
> would be something that Marc, Catalin and Will would need to hash out since
> the first patch would ideally go through a different tree than the others.

I suspect that as long as the GIC patch doesn't conflict with anything in the
irqchip tree (and assuming Marc's happy with it), we could route this all
through the arm64 tree as that's what we did when we added support for
pseudo-NMI in the first place.

Marc, thoughts?

Mark.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2023-08-31 15:46 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-30 19:11 [PATCH v12 0/7] arm64: Add IPI for backtraces / kgdb; try to use NMI for some IPIs Douglas Anderson
2023-08-30 19:11 ` Douglas Anderson
2023-08-30 19:11 ` [PATCH v12 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-31  8:53   ` Mark Rutland
2023-08-31  8:53     ` Mark Rutland
2023-08-31 15:31     ` Doug Anderson
2023-08-31 15:31       ` Doug Anderson
2023-08-31 15:45       ` Mark Rutland
2023-08-31 15:45         ` Mark Rutland
2023-08-30 19:11 ` [PATCH v12 2/7] arm64: idle: Tag the arm64 idle functions as __cpuidle Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-30 19:11 ` [PATCH v12 3/7] arm64: smp: Remove dedicated wakeup IPI Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-30 19:11 ` [PATCH v12 4/7] arm64: smp: Add arch support for backtrace using pseudo-NMI Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-30 19:11 ` [PATCH v12 5/7] arm64: smp: IPI_CPU_STOP and IPI_CPU_CRASH_STOP should try for NMI Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-31 10:12   ` Mark Rutland
2023-08-31 10:12     ` Mark Rutland
2023-08-30 19:11 ` [PATCH v12 6/7] arm64: kgdb: Implement kgdb_roundup_cpus() to enable pseudo-NMI roundup Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-31 10:14   ` Mark Rutland
2023-08-31 10:14     ` Mark Rutland
2023-08-30 19:11 ` [PATCH v12 7/7] arm64: smp: Mark IPI globals as __ro_after_init Douglas Anderson
2023-08-30 19:11   ` Douglas Anderson
2023-08-31 10:15   ` Mark Rutland
2023-08-31 10:15     ` Mark Rutland
2023-08-31  7:08 ` [PATCH v12 0/7] arm64: Add IPI for backtraces / kgdb; try to use NMI for some IPIs Chen-Yu Tsai
2023-08-31  7:08   ` Chen-Yu Tsai

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.