Thank you, I understand. Regards, Xiang W
Heinrich Schuchardt <heinrich.schucha...@canonical.com> 于2023年10月31日周二 20:09写道: > > On 10/31/23 09:53, Xiang W wrote: > > setjmp can be called in set_resume. > > Unfortunately this is not possible. A longjmp buffer only stores > register values and not the stack content. > > Let's assume that setjmp() is moved into set_resume(): > > Let a function call set_resume(). The caller's address will be on the > stack. Once the set_resume returns and the caller invokes another > function the original stack content will be overwritten. When an > exception occurs the longjmp will reenter set_resume() with the original > stack pointer value pointing to a stack that does not match the original > call to set_resume and set_resume will return to a random address. > > Best regards > > Heinrich > > > > > 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 > >> >