diff options
| author | Kumar Kartikeya Dwivedi <memxor@gmail.com> | 2026-09-04 10:43:19 +0200 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-09-04 07:58:36 -0700 |
| commit | 6668ed271eaefaa63e686bdfbedaeb7b8e492722 (patch) | |
| tree | 58e8288fead484f6755ad0815fc74c3742663761 /arch/m68k/68000/entry.S | |
| download | linux-stable-6668ed271eaefaa63e686bdfbedaeb7b8e492722.tar.gz linux-stable-6668ed271eaefaa63e686bdfbedaeb7b8e492722.zip | |
selftests/bpf: Reject graph kptr use after RCU unlockgrafted
Add a sleepable verifier test that loads a graph-node local kptr in an
explicit RCU read-side critical section, then passes its node to
bpf_rbtree_remove() after the section ends.
Before the verifier fix, the stale NON_OWN_REF flag makes the node look like
a live borrowed reference and the program is accepted. After the fix, the
pointer is demoted without NON_OWN_REF and the graph kfunc argument is
rejected.
Also exercise a graph kptr loaded while a spin lock provides implicit RCU
protection. The pointer must be invalidated when the lock is released, which
guards the required ordering between non-owning-reference invalidation and
RCU demotion.
Update the existing fault-protected load test state description. The
post-unlock pointer no longer carries NON_OWN_REF, but remains readable
because the load is rewritten to use BPF_PROBE_MEM.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904084325.52250-7-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'arch/m68k/68000/entry.S')
| -rw-r--r-- | arch/m68k/68000/entry.S | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/arch/m68k/68000/entry.S b/arch/m68k/68000/entry.S new file mode 100644 index 000000000..c257cc415 --- /dev/null +++ b/arch/m68k/68000/entry.S @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * + * entry.S -- non-mmu 68000 interrupt and exception entry points + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Linux/m68k support by Hamish Macdonald + */ + +#include <linux/linkage.h> +#include <asm/thread_info.h> +#include <asm/unistd.h> +#include <asm/errno.h> +#include <asm/setup.h> +#include <asm/traps.h> +#include <asm/asm-offsets.h> +#include <asm/entry.h> + +.text + +/* get thread_info pointer into a2 */ + .macro getthreadinfo + movel %sp,%d1 + andl #-THREAD_SIZE,%d1 + movel %d1,%a2 + .endm + +.globl system_call +.globl resume +.globl ret_from_exception +.globl sys_call_table +.globl bad_interrupt +.globl inthandler1 +.globl inthandler2 +.globl inthandler3 +.globl inthandler4 +.globl inthandler5 +.globl inthandler6 +.globl inthandler7 + +badsys: + movel #-ENOSYS,%sp@(PT_OFF_D0) + jra ret_from_exception + +do_trace: + movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ + subql #4,%sp + SAVE_SWITCH_STACK + jbsr syscall_trace_enter + RESTORE_SWITCH_STACK + addql #4,%sp + addql #1,%d0 + jeq ret_from_exception + movel %sp@(PT_OFF_ORIG_D0),%d1 + movel #-ENOSYS,%d0 + cmpl #NR_syscalls,%d1 + jcc 1f + lsl #2,%d1 + lea sys_call_table, %a0 + jbsr %a0@(%d1) + +1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ + subql #4,%sp /* dummy return address */ + SAVE_SWITCH_STACK + jbsr syscall_trace_leave + RESTORE_SWITCH_STACK + addql #4,%sp + jra ret_from_exception + +ENTRY(system_call) + SAVE_ALL_SYS + + /* save top of frame*/ + pea %sp@ + jbsr set_esp0 + addql #4,%sp + + movel %sp@(PT_OFF_ORIG_D0),%d0 + + /* Doing a trace ? */ + getthreadinfo + btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) + jne do_trace + cmpl #NR_syscalls,%d0 + jcc badsys + lsl #2,%d0 + lea sys_call_table,%a0 + movel %a0@(%d0), %a0 + jbsr %a0@ + movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ + +ret_from_exception: + btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ + jeq Luser_return /* if so, skip resched, signals*/ + +Lkernel_return: + RESTORE_ALL + +Luser_return: + /* only allow interrupts when we are really the last one on the*/ + /* kernel stack, otherwise stack overflow can occur during*/ + /* heavy interrupt load*/ + andw #ALLOWINT,%sr + + getthreadinfo +1: + /* check if any of the flags are set */ + moveb %a2@(TINFO_FLAGS + 3),%d1 /* thread_info->flags (low 8 bits) */ + jne Lwork_to_do + RESTORE_ALL + +Lwork_to_do: + /* check if reschedule needs to be called */ + btst #TIF_NEED_RESCHED,%d1 + jne reschedule + +Lsignal_return: + subql #4,%sp /* dummy return address*/ + SAVE_SWITCH_STACK + pea %sp@(SWITCH_STACK_SIZE) + bsrw do_notify_resume + addql #4,%sp + RESTORE_SWITCH_STACK + addql #4,%sp + jra 1b + +/* + * This is the main interrupt handler, responsible for calling process_int() + */ +inthandler1: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #65,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler2: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #66,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler3: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #67,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler4: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #68,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler5: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #69,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler6: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #70,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler7: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel #71,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +inthandler: + SAVE_ALL_INT + movew %sp@(PT_OFF_FORMATVEC), %d0 + and #0x3ff, %d0 + + movel %sp,%sp@- + movel %d0,%sp@- /* put vector # on stack*/ + jbsr process_int /* process the IRQ*/ +3: addql #8,%sp /* pop parameters off stack*/ + bra ret_from_exception + +/* + * Handler for uninitialized and spurious interrupts. + */ +ENTRY(bad_interrupt) + addql #1,irq_err_count + rte + +/* + * Beware - when entering resume, prev (the current task) is + * in a0, next (the new task) is in a1, so don't change these + * registers until their contents are no longer needed. + */ +ENTRY(resume) + movel %a0,%d1 /* save prev thread in d1 */ + movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */ + SAVE_SWITCH_STACK + movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */ + movel %usp,%a3 /* save usp */ + movel %a3,%a0@(TASK_THREAD+THREAD_USP) + + movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */ + movel %a3,%usp + movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ + RESTORE_SWITCH_STACK + movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */ + rts + |
