summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 08:05:19 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-22 08:05:19 -1000
commitbb2235894a8a604c08b3f93f4e1082b9df03265a (patch)
treec6e58a900d8e77472ecd8d5c7837985f2023055b /arch/powerpc/kernel
parent979fac3eaaa02fa887c7dfe6509248b21dca3872 (diff)
parent129f5d395fd66b6587a5ac156b232cca060d6512 (diff)
downloadlinux-bb2235894a8a604c08b3f93f4e1082b9df03265a.tar.gz
linux-bb2235894a8a604c08b3f93f4e1082b9df03265a.zip
Merge tag 'powerpc-7.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Madhavan Srinivasan: - powerpc/numa: Support coregroup on PowerNV - powerpc/irq: Move __softirq_pending out of irq_stat - powerpc/512x: Remove pdm360ng platform setup in favor of mpc512x_generic - powerpc/ps3: Simplify control flow in ps3_{virq,irq_plug}_setup() - KVM: PPC: Book3S HV: Add preempt_disable() around virtual-mode HPTE bit-lock users - powerpc/syscall: Avoid atomic test_and_clear_thread_flag on fast path - pseries/plpks cleanup and fixes - Misc fixes and cleanup Thanks to Abhishek Dubey, Amit Machhiwal, Anushree Mathur, Bui Nguyen Nhu Quynh, Christophe Leroy (CS GROUP), Dmitry Torokhov, Gaurav Batra, Gautam Menghani, Geert Uytterhoeven, Greg Joyce, Hari Bathini, Harsh Prateek Bora, Karl Mehltretter, Link Mauve, Michal Suchánek, Mukesh Kumar Chaurasiya (IBM), Nayna Jain, Ritesh Harjani (IBM), R Nageswara Sastry, Saket Kumar Bhaskar, Samir Mulani, Shivang Upadhyay, Shrikanth Hegde, Sourabh Jain, Srikar Dronamraju, Srish Srinivasan, Thorsten Blum, Vaibhav Jain (IBM), Venkat Rao Bagalkote, and Yeswanth Krishna Tellakula * tag 'powerpc-7.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (44 commits) powerpc/numa: Support coregroup on PowerNV powerpc/numa: Allow cpu_to_coregroup_id without PPC_SPLPAR powerpc/numa: Simplify find_primary_domain_index powerpc/fadump: collect dump when CPU_STATE_DATA is less than reserved powerpc/syscall: Avoid atomic test_and_clear_thread_flag on fast path powerpc/kasan: fix r2 corruption in mem*() on GENERIC_ENTRY with old compilers powerpc: fix NMI exit ordering: restore soft masks after irqentry_nmi_exit() powerpc/pseries/iommu: Add TCEs for 16GB pages when RAM is pre-mapped KVM: PPC: Book3S HV: Free the queue pages in error path KVM: PPC: Book3S HV: Add missing mappings for tracing exits powerpc/interrupt: Use early_radix_enabled() in NMI real-mode guard KVM: PPC: Fix get_d_signext() 12-bit displacement for paired-single D-form KVM: PPC: Book3S HV: Add preempt_disable() around virtual-mode HPTE bit-lock users KVM: PPC: Book3S HV: Add SRCU protection for virtual-mode HPT hcalls pseries/plpks: update PKS documentation and MAINTAINERS entry pseries/plpks: rename the default wrapping key macro pseries/plpks: make narrowing conversions explicit pseries/plpks: hide wrapping_features when unsupported pseries/plpks: fix self-reference in plpks_var initializer pseries/plpks: clear SED key data after use ...
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/cputable.c14
-rw-r--r--arch/powerpc/kernel/dbell.c2
-rw-r--r--arch/powerpc/kernel/irq.c131
-rw-r--r--arch/powerpc/kernel/prom_init.c10
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh15
-rw-r--r--arch/powerpc/kernel/syscall.c6
-rw-r--r--arch/powerpc/kernel/sysfs.c4
-rw-r--r--arch/powerpc/kernel/time.c6
-rw-r--r--arch/powerpc/kernel/trace/ftrace_entry.S6
-rw-r--r--arch/powerpc/kernel/traps.c11
-rw-r--r--arch/powerpc/kernel/watchdog.c2
11 files changed, 91 insertions, 116 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6f6801da9dc1..4731e27bb7bc 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -35,12 +35,7 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)
struct cpu_spec *t = &the_cpu_spec;
t = PTRRELOC(t);
- /*
- * use memcpy() instead of *t = *s so that GCC replaces it
- * by __memcpy() when KASAN is active
- */
- memcpy(t, s, sizeof(*t));
-
+ *t = *s;
*PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
}
@@ -53,11 +48,8 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
t = PTRRELOC(t);
old = *t;
- /*
- * Copy everything, then do fixups. Use memcpy() instead of *t = *s
- * so that GCC replaces it by __memcpy() when KASAN is active
- */
- memcpy(t, s, sizeof(*t));
+ /* Copy everything, then do fixups. */
+ *t = *s;
/*
* If we are overriding a previous value derived from the real
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index 5712dd846263..f5e298a4c4c0 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -31,7 +31,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
do_hard_irq_enable();
kvmppc_clear_host_ipi(smp_processor_id());
- __this_cpu_inc(irq_stat.doorbell_irqs);
+ inc_irq_stat(DOORBELL);
smp_ipi_demux_relaxed(); /* already performed the barrier */
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 15a3c3fd8e70..bce546931a13 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -73,6 +73,7 @@
DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
EXPORT_PER_CPU_SYMBOL(irq_stat);
+DEFINE_PER_CPU(unsigned int, __softirq_pending);
#ifdef CONFIG_PPC32
atomic_t ppc_n_lost_interrupts;
@@ -83,105 +84,105 @@ u32 tau_interrupts(unsigned long cpu);
#endif
#endif /* CONFIG_PPC32 */
+struct irq_stat_info {
+ const char *symbol;
+ const char *text;
+ int optional;
+};
+
+/* ISE - IRQ STAT ENABLED, ISC - IRQ STAT CONDITIONAL */
+#define ISE(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 0}
+#define ISC(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 1}
+
+
+static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = {
+ ISE(LOC_TIMER, "LOC", " Local timer interrupts for timer event device\n"),
+ ISE(BCT_TIMER, "BCT", " Broadcast timer interrupts for timer event device\n"),
+ ISE(OTHER_TIMER, "LOC", " Local timer interrupts for others\n"),
+ ISE(SPURIOUS, "SPU", " Spurious interrupts\n"),
+ ISE(PMI, "PMI", " Performance monitoring interrupts\n"),
+ ISC(MCE, "MCE", " Machine check exceptions\n"),
+ ISC(NMI_SRESET, "NMI", " System Reset interrupts\n"),
+#ifdef CONFIG_PPC_WATCHDOG
+ ISE(WATCHDOG, "WDG", " Watchdog soft-NMI interrupts\n"),
+#endif
+#ifdef CONFIG_PPC_DOORBELL
+ ISE(DOORBELL, "DBL", " Doorbell interrupts\n"),
+#endif
+};
+
+/*
+ * Used for default disabled counters to increment the stats and to enable the
+ * entry for /proc/interrupts output.
+ */
+static DECLARE_BITMAP(irq_stat_count_show, IRQ_COUNT_MAX) __read_mostly;
+void inc_irq_stat_and_enable(enum irq_stat_counts which)
+{
+ __this_cpu_inc(irq_stat.counts[which]);
+ set_bit(which, irq_stat_count_show);
+}
+
int arch_show_interrupts(struct seq_file *p, int prec)
{
- int j;
+ const struct irq_stat_info *info = irq_stat_info;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) {
+ if (info->optional && !test_bit(i, irq_stat_count_show))
+ continue;
+
+ seq_printf(p, "%*s:", prec, info->symbol);
+ irq_proc_emit_counts(p, &irq_stat.counts[i]);
+ seq_puts(p, info->text);
+ }
#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
if (tau_initialized) {
+ int j;
seq_printf(p, "%*s:", prec, "TAU");
for_each_online_cpu(j)
seq_put_decimal_ull_width(p, " ", tau_interrupts(j), 10);
seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
}
#endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
-
- seq_printf(p, "%*s:", prec, "LOC");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_event, 10);
- seq_printf(p, " Local timer interrupts for timer event device\n");
-
- seq_printf(p, "%*s:", prec, "BCT");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).broadcast_irqs_event, 10);
- seq_printf(p, " Broadcast timer interrupts for timer event device\n");
-
- seq_printf(p, "%*s:", prec, "LOC");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_others, 10);
- seq_printf(p, " Local timer interrupts for others\n");
-
- seq_printf(p, "%*s:", prec, "SPU");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).spurious_irqs, 10);
- seq_printf(p, " Spurious interrupts\n");
-
- seq_printf(p, "%*s:", prec, "PMI");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).pmu_irqs, 10);
- seq_printf(p, " Performance monitoring interrupts\n");
-
- seq_printf(p, "%*s:", prec, "MCE");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).mce_exceptions, 10);
- seq_printf(p, " Machine check exceptions\n");
-
#ifdef CONFIG_PPC_BOOK3S_64
if (cpu_has_feature(CPU_FTR_HVMODE)) {
+ int j;
seq_printf(p, "%*s:", prec, "HMI");
for_each_online_cpu(j)
seq_put_decimal_ull_width(p, " ", paca_ptrs[j]->hmi_irqs, 10);
seq_printf(p, " Hypervisor Maintenance Interrupts\n");
}
#endif
+ return 0;
+}
- seq_printf(p, "%*s:", prec, "NMI");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).sreset_irqs, 10);
- seq_printf(p, " System Reset interrupts\n");
-
-#ifdef CONFIG_PPC_WATCHDOG
- seq_printf(p, "%*s:", prec, "WDG");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).soft_nmi_irqs, 10);
- seq_printf(p, " Watchdog soft-NMI interrupts\n");
-#endif
+static int __init irq_init_stats(void)
+{
+ struct irq_stat_info *info = irq_stat_info;
-#ifdef CONFIG_PPC_DOORBELL
- if (cpu_has_feature(CPU_FTR_DBELL)) {
- seq_printf(p, "%*s:", prec, "DBL");
- for_each_online_cpu(j)
- seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).doorbell_irqs, 10);
- seq_printf(p, " Doorbell interrupts\n");
+ for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) {
+ if (info->optional == 0)
+ set_bit(i, irq_stat_count_show);
}
-#endif
return 0;
}
+late_initcall(irq_init_stats);
/*
* /proc/stat helpers
*/
u64 arch_irq_stat_cpu(unsigned int cpu)
{
- u64 sum = per_cpu(irq_stat, cpu).timer_irqs_event;
+ irq_cpustat_t *p = per_cpu_ptr(&irq_stat, cpu);
+ u64 sum = 0;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++)
+ sum += p->counts[i];
- sum += per_cpu(irq_stat, cpu).broadcast_irqs_event;
- sum += per_cpu(irq_stat, cpu).pmu_irqs;
- sum += per_cpu(irq_stat, cpu).mce_exceptions;
- sum += per_cpu(irq_stat, cpu).spurious_irqs;
- sum += per_cpu(irq_stat, cpu).timer_irqs_others;
#ifdef CONFIG_PPC_BOOK3S_64
sum += paca_ptrs[cpu]->hmi_irqs;
#endif
- sum += per_cpu(irq_stat, cpu).sreset_irqs;
-#ifdef CONFIG_PPC_WATCHDOG
- sum += per_cpu(irq_stat, cpu).soft_nmi_irqs;
-#endif
-#ifdef CONFIG_PPC_DOORBELL
- sum += per_cpu(irq_stat, cpu).doorbell_irqs;
-#endif
-
return sum;
}
@@ -251,7 +252,7 @@ static void __do_irq(struct pt_regs *regs, unsigned long oldsp)
/* And finally process it */
if (unlikely(!irq))
- __this_cpu_inc(irq_stat.spurious_irqs);
+ inc_irq_stat(SPURIOUS);
else
generic_handle_irq(irq);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index eb9f556b0937..e8e071024da5 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1362,14 +1362,8 @@ static void __init prom_check_platform_support(void)
int prop_len = prom_getproplen(prom.chosen,
"ibm,arch-vec-5-platform-support");
- /*
- * First copy the architecture vec template
- *
- * use memcpy() instead of *vec = *vec_template so that GCC replaces it
- * by __memcpy() when KASAN is active
- */
- memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template,
- sizeof(ibm_architecture_vec));
+ /* First copy the architecture vec template */
+ ibm_architecture_vec = ibm_architecture_vec_template;
prom_strscpy_pad(ibm_architecture_vec.vec7.os_id, linux_banner, 256);
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 3090b97258ae..3155cc722e48 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -13,21 +13,8 @@
# If you really need to reference something from prom_init.o add
# it to the list below:
-has_renamed_memintrinsics()
-{
- grep -q "^CONFIG_KASAN=y$" "${KCONFIG_CONFIG}" && \
- ! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" "${KCONFIG_CONFIG}"
-}
-
-if has_renamed_memintrinsics
-then
- MEM_FUNCS="__memcpy __memset"
-else
- MEM_FUNCS="memcpy memset"
-fi
-
WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
-_end enter_prom $MEM_FUNCS reloc_offset __secondary_hold
+_end enter_prom memcpy memset reloc_offset __secondary_hold
__secondary_hold_acknowledge __secondary_hold_spinloop __start
logo_linux_clut224 btext_prepare_BAT
reloc_got2 kernstart_addr memstart_addr linux_banner _stext
diff --git a/arch/powerpc/kernel/syscall.c b/arch/powerpc/kernel/syscall.c
index fbefe1927b10..8529827d697f 100644
--- a/arch/powerpc/kernel/syscall.c
+++ b/arch/powerpc/kernel/syscall.c
@@ -18,14 +18,12 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
long ret;
syscall_fn f;
- if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) {
+ if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0) ||
+ test_thread_flag(TIF_SYSCALL_RET))) {
clear_thread_flag(TIF_SYSCALL_RET);
return syscall_get_error(current, regs);
}
- if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET)))
- return syscall_get_error(current, regs);
-
if (unlikely(r0 >= NR_syscalls)) {
if (unlikely(trap_is_unsupported_scv(regs))) {
/* Unsupported scv vector */
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 329c1690b5ed..2100c5e2c821 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -338,7 +338,7 @@ static ssize_t show_pw20_wait_time(struct device *dev,
time = pw20_wt;
}
- return sysfs_emit(buf, "%llu\n", time > 0 ? time : 0);
+ return sysfs_emit(buf, "%llu\n", time);
}
static void set_pw20_wait_entry_bit(void *val)
@@ -460,7 +460,7 @@ static ssize_t show_altivec_idle_wait_time(struct device *dev,
time = altivec_idle_wt;
}
- return sysfs_emit(buf, "%llu\n", time > 0 ? time : 0);
+ return sysfs_emit(buf, "%llu\n", time);
}
static void set_altivec_idle_wait_entry_bit(void *val)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 11145c40183d..e00dcda8240b 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -615,13 +615,13 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
now = get_tb();
if (now >= *next_tb) {
evt->event_handler(evt);
- __this_cpu_inc(irq_stat.timer_irqs_event);
+ inc_irq_stat(LOC_TIMER);
} else {
now = *next_tb - now;
if (now > decrementer_max)
now = decrementer_max;
set_dec_or_work(now);
- __this_cpu_inc(irq_stat.timer_irqs_others);
+ inc_irq_stat(OTHER_TIMER);
}
trace_timer_interrupt_exit(regs);
@@ -634,7 +634,7 @@ EXPORT_SYMBOL(timer_interrupt);
void timer_broadcast_interrupt(void)
{
tick_receive_broadcast();
- __this_cpu_inc(irq_stat.broadcast_irqs_event);
+ inc_irq_stat(BCT_TIMER);
}
#endif
diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel/trace/ftrace_entry.S
index 6599fe3c6234..5eb8eee32549 100644
--- a/arch/powerpc/kernel/trace/ftrace_entry.S
+++ b/arch/powerpc/kernel/trace/ftrace_entry.S
@@ -220,7 +220,13 @@
/* Restore gprs */
.if \allregs == 1
+#ifdef CONFIG_PPC64
+ REST_GPRS(2, 12, r1)
+ /* Do not restore a stale PACA pointer if the task migrated */
+ REST_GPRS(14, 31, r1)
+#else
REST_GPRS(2, 31, r1)
+#endif
.else
REST_GPRS(3, 10, r1)
#if defined(CONFIG_LIVEPATCH_64) || defined(CONFIG_PPC_FTRACE_OUT_OF_LINE)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 629f2a2d4780..3a8f5416e3f6 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -459,8 +459,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception)
}
hv_nmi_check_nonrecoverable(regs);
-
- __this_cpu_inc(irq_stat.sreset_irqs);
+ inc_irq_stat_and_enable(IRQ_COUNT_NMI_SRESET);
/* See if any machine dependent calls */
if (ppc_md.system_reset_exception) {
@@ -817,7 +816,7 @@ static void __machine_check_exception(struct pt_regs *regs)
{
int recover = 0;
- __this_cpu_inc(irq_stat.mce_exceptions);
+ inc_irq_stat_and_enable(IRQ_COUNT_MCE);
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
@@ -1932,8 +1931,7 @@ DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm)
DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
{
- __this_cpu_inc(irq_stat.pmu_irqs);
-
+ inc_irq_stat(PMI);
perf_irq(regs);
return 0;
@@ -1943,8 +1941,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async)
{
- __this_cpu_inc(irq_stat.pmu_irqs);
-
+ inc_irq_stat(PMI);
perf_irq(regs);
}
diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c
index c40c69368476..582ee3fd71c1 100644
--- a/arch/powerpc/kernel/watchdog.c
+++ b/arch/powerpc/kernel/watchdog.c
@@ -381,7 +381,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt)
if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
return 0;
- __this_cpu_inc(irq_stat.soft_nmi_irqs);
+ inc_irq_stat(WATCHDOG);
tb = get_tb();
if (tb - per_cpu(wd_timer_tb, cpu) >= wd_panic_timeout_tb) {