setjmp can be called in set_resume. Regards, Xiang W
Heinrich Schuchardt <heinrich.schucha...@canonical.com> 于2023年10月29日周日 16:56写道: > > If CSRs like seed are readable by S-mode, may not be determinable by > S-mode. For safe driver probing allow to resume via a longjmp after an > exception. > > Signed-off-by: Heinrich Schuchardt <heinrich.schucha...@canonical.com> > --- > v2: > new patch > --- > arch/riscv/lib/interrupts.c | 13 +++++++++++++ > include/interrupt.h | 22 ++++++++++++++++++++++ > 2 files changed, 35 insertions(+) > create mode 100644 include/interrupt.h > > diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c > index 02dbcfd423..a26ccc721f 100644 > --- a/arch/riscv/lib/interrupts.c > +++ b/arch/riscv/lib/interrupts.c > @@ -12,6 +12,7 @@ > #include <linux/compat.h> > #include <efi_loader.h> > #include <hang.h> > +#include <interrupt.h> > #include <irq_func.h> > #include <asm/global_data.h> > #include <asm/ptrace.h> > @@ -21,6 +22,13 @@ > > DECLARE_GLOBAL_DATA_PTR; > > +static struct resume_data *resume; > + > +void set_resume(struct resume_data *data) > +{ > + resume = data; > +} > + > static void show_efi_loaded_images(uintptr_t epc) > { > efi_print_image_infos((void *)epc); > @@ -105,6 +113,11 @@ static void _exit_trap(ulong code, ulong epc, ulong > tval, struct pt_regs *regs) > "Store/AMO page fault", > }; > > + if (resume) { > + resume->code = code; > + longjmp(resume->jump, 1); > + } > + > if (code < ARRAY_SIZE(exception_code)) > printf("Unhandled exception: %s\n", exception_code[code]); > else > diff --git a/include/interrupt.h b/include/interrupt.h > new file mode 100644 > index 0000000000..1baa60bcf2 > --- /dev/null > +++ b/include/interrupt.h > @@ -0,0 +1,22 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > + > +#include <asm/setjmp.h> > + > +/** > + * struct resume_data - data for resume after interrupt > + */ > +struct resume_data { > + /** @jump: longjmp buffer */ > + jmp_buf jump; > + /** @code: exception code */ > + ulong code; > +}; > + > +/** > + * set_resume() - set longjmp buffer for resuming after interrupt > + * > + * When resuming the exception code will be returned in @data->code. > + * > + * @data: pointer to structure with longjmp address > + */ > +void set_resume(struct resume_data *data); > -- > 2.40.1 >