mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
Enable the generic IRQ entry/exit infrastructure on PowerPC by selecting GENERIC_ENTRY and integrating the architecture-specific interrupt and syscall handlers with the generic entry/exit APIs. This change replaces PowerPC’s local interrupt entry/exit handling with calls to the generic irqentry_* helpers, aligning the architecture with the common kernel entry model. The macros that define interrupt, async, and NMI handlers are updated to use irqentry_enter()/irqentry_exit() and irqentry_nmi_enter()/irqentry_nmi_exit() where applicable also convert the PowerPC syscall entry and exit paths to use the generic entry/exit framework and integrating with the common syscall handling routines. Key updates include: - The architecture now selects GENERIC_ENTRY in Kconfig. - Replace interrupt_enter/exit_prepare() with arch_interrupt_* helpers. - Integrate irqentry_enter()/exit() in standard and async interrupt paths. - Integrate irqentry_nmi_enter()/exit() in NMI handlers. - Remove redundant irq_enter()/irq_exit() calls now handled generically. - Use irqentry_exit_cond_resched() for preemption checks. - interrupt.c and syscall.c are simplified to delegate context management and user exit handling to the generic entry path. - The new pt_regs field `exit_flags` introduced earlier is now used to carry per-syscall exit state flags (e.g. _TIF_RESTOREALL). - Remove unused code. This change establishes the necessary wiring for PowerPC to use the generic IRQ entry/exit framework while maintaining existing semantics. This aligns PowerPC with the common entry code used by other architectures and reduces duplicated logic around syscall tracing, context tracking, and signal handling. The performance benchmarks from perf bench basic syscall are below: perf bench syscall usec/op (-ve is improvement) | Syscall | Base | test | change % | | ------- | ----------- | ----------- | -------- | | basic | 0.093543 | 0.093023 | -0.56 | | execve | 446.557781 | 450.107172 | +0.79 | | fork | 1142.204391 | 1156.377214 | +1.24 | | getpgid | 0.097666 | 0.092677 | -5.11 | perf bench syscall ops/sec (+ve is improvement) | Syscall | Base | New | change % | | ------- | -------- | -------- | -------- | | basic | 10690548 | 10750140 | +0.56 | | execve | 2239 | 2221 | -0.80 | | fork | 875 | 864 | -1.26 | | getpgid | 10239026 | 10790324 | +5.38 | IPI latency benchmark (-ve is improvement) | Metric | Base (ns) | New (ns) | % Change | | -------------- | ------------- | ------------- | -------- | | Dry run | 583136.56 | 584136.35 | 0.17% | | Self IPI | 4167393.42 | 4149093.90 | -0.44% | | Normal IPI | 61769347.82 | 61753728.39 | -0.03% | | Broadcast IPI | 2235584825.02 | 2227521401.45 | -0.36% | | Broadcast lock | 2164964433.31 | 2125658641.76 | -1.82% | Thats very close to performance earlier with arch specific handling. Signed-off-by: Mukesh Kumar Chaurasiya <mkchauras@linux.ibm.com> Tested-by: Samir M <samir@linux.ibm.com> Tested-by: David Gow <davidgow@google.com> Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com> Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20260427122742.210074-8-mkchauras@gmail.com
65 lines
1.6 KiB
C
65 lines
1.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <linux/compat.h>
|
|
#include <linux/context_tracking.h>
|
|
#include <linux/randomize_kstack.h>
|
|
#include <linux/entry-common.h>
|
|
|
|
#include <asm/interrupt.h>
|
|
#include <asm/kup.h>
|
|
#include <asm/syscall.h>
|
|
#include <asm/time.h>
|
|
#include <asm/tm.h>
|
|
#include <asm/unistd.h>
|
|
|
|
|
|
/* Has to run notrace because it is entered not completely "reconciled" */
|
|
notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
|
|
{
|
|
long ret;
|
|
syscall_fn f;
|
|
|
|
add_random_kstack_offset();
|
|
r0 = syscall_enter_from_user_mode(regs, r0);
|
|
|
|
if (unlikely(r0 >= NR_syscalls)) {
|
|
if (unlikely(trap_is_unsupported_scv(regs))) {
|
|
/* Unsupported scv vector */
|
|
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
|
|
return regs->gpr[3];
|
|
}
|
|
return -ENOSYS;
|
|
}
|
|
|
|
/* May be faster to do array_index_nospec? */
|
|
barrier_nospec();
|
|
|
|
#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
|
|
// No COMPAT if we have SYSCALL_WRAPPER, see Kconfig
|
|
f = (void *)sys_call_table[r0];
|
|
ret = f(regs);
|
|
#else
|
|
if (unlikely(is_compat_task())) {
|
|
unsigned long r3, r4, r5, r6, r7, r8;
|
|
|
|
f = (void *)compat_sys_call_table[r0];
|
|
|
|
r3 = regs->gpr[3] & 0x00000000ffffffffULL;
|
|
r4 = regs->gpr[4] & 0x00000000ffffffffULL;
|
|
r5 = regs->gpr[5] & 0x00000000ffffffffULL;
|
|
r6 = regs->gpr[6] & 0x00000000ffffffffULL;
|
|
r7 = regs->gpr[7] & 0x00000000ffffffffULL;
|
|
r8 = regs->gpr[8] & 0x00000000ffffffffULL;
|
|
|
|
ret = f(r3, r4, r5, r6, r7, r8);
|
|
} else {
|
|
f = (void *)sys_call_table[r0];
|
|
|
|
ret = f(regs->gpr[3], regs->gpr[4], regs->gpr[5],
|
|
regs->gpr[6], regs->gpr[7], regs->gpr[8]);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|