[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 4/5] x86/traps: Drop exception_table[] and use if/else dispatching
On 19.11.2021 19:21, Andrew Cooper wrote: > --- a/xen/arch/x86/x86_64/entry.S > +++ b/xen/arch/x86/x86_64/entry.S > @@ -773,14 +773,48 @@ handle_exception_saved: > sti > 1: movq %rsp,%rdi > movzbl UREGS_entry_vector(%rsp),%eax > - leaq exception_table(%rip),%rdx > #ifdef CONFIG_PERF_COUNTERS > lea per_cpu__perfcounters(%rip), %rcx > add STACK_CPUINFO_FIELD(per_cpu_offset)(%r14), %rcx > incl ASM_PERFC_exceptions * 4(%rcx, %rax, 4) > #endif > - mov (%rdx, %rax, 8), %rdx > - INDIRECT_CALL %rdx > + > + /* > + * Dispatch to appropriate C handlers. > + * > + * The logic is implemented as an if/else chain. DISPATCH() calls > + * need be in frequency order for best performance. > + */ > +#define DISPATCH(vec, handler) \ > + cmp $vec, %al; \ > + jne .L_ ## vec ## _done; \ > + call handler; \ > + jmp .L_exn_dispatch_done; \ > +.L_ ## vec ## _done: > + > + DISPATCH(X86_EXC_PF, do_page_fault) > + DISPATCH(X86_EXC_GP, do_general_protection) > + DISPATCH(X86_EXC_UD, do_invalid_op) > + DISPATCH(X86_EXC_NM, do_device_not_available) > + DISPATCH(X86_EXC_BP, do_int3) > + > + /* Logically "if ( (1 << vec) & MASK ) { do_trap(); }" */ > + mov $(1 << X86_EXC_DE) | (1 << X86_EXC_OF) | (1 << X86_EXC_BR) |\ > + (1 << X86_EXC_NP) | (1 << X86_EXC_SS) | (1 << X86_EXC_MF) |\ > + (1 << X86_EXC_AC) | (1 << X86_EXC_XM), %edx > + bt %eax, %edx > + jnc .L_do_trap_done > + call do_trap > + jmp .L_exn_dispatch_done > +.L_do_trap_done: > + > + DISPATCH(X86_EXC_CP, do_entry_CP) > +#undef DISPATCH The basis for the choice of ordering imo wants spelling out here. For example, despite the data provided in the description I'm not really convinced #BP wants handling ahead of everything going to do_trap(). > @@ -1012,9 +1046,28 @@ handle_ist_exception: > incl ASM_PERFC_exceptions * 4(%rcx, %rax, 4) > #endif > > - leaq exception_table(%rip),%rdx > - mov (%rdx, %rax, 8), %rdx > - INDIRECT_CALL %rdx > + /* > + * Dispatch to appropriate C handlers. > + * > + * The logic is implemented as an if/else chain. DISPATCH() calls > + * need be in frequency order for best performance. > + */ > +#define DISPATCH(vec, handler) \ > + cmp $vec, %al; \ > + jne .L_ ## vec ## _done; \ > + call handler; \ > + jmp .L_ist_dispatch_done; \ > +.L_ ## vec ## _done: > + > + DISPATCH(X86_EXC_NMI, do_nmi) > + DISPATCH(X86_EXC_DB, do_debug) > + DISPATCH(X86_EXC_MC, do_machine_check) > +#undef DISPATCH > + > + call do_unhandled_trap > + BUG /* do_unhandled_trap() shouldn't return. */ While I agree with putting BUG here, I don't see the need for the CALL. Unlike in handle_exception there's no vector left unhandled by the DISPATCH() invocations. The CALL being there give the (wrong) impression there would / might be. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |