On Mon, Sep 21, 2015 at 2:23 PM, John Criswell <jtcris...@gmail.com> wrote: > On 9/21/15 4:45 PM, H.J. Lu wrote: >> >> On Mon, Sep 21, 2015 at 11:52 AM, John Criswell <jtcris...@gmail.com> >> wrote: >>> >>> On 9/21/15 12:27 PM, H.J. Lu via cfe-dev wrote: >>>> >>>> On Thu, Sep 17, 2015 at 12:26 PM, H.J. Lu <hjl.to...@gmail.com> wrote: >>>>> >>>>> On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu <hjl.to...@gmail.com> wrote: >>>>>>> >>>>>>> To implement interrupt and exception handlers for x86 processors, a >>>>>>> compiler should support: >>>>>>> >>>>>>> 1. void * __builtin_ia32_interrupt_data (void) >>>>>> >>>>>> I got a feedback on the name of this builtin function. Since >>>>>> it also works for 64-bit, we should avoid ia32 in its name. >>>>>> We'd like to change it to >>>>>> >>>>>> void * __builtin_interrupt_data (void) >>>>>> >>>>> Here is the updated spec. >>>>> >>>> This updated spec adds >>>> >>>> unsigned int __builtin_exception_error (void) >>>> unsigned long long int __builtin_exception_error (void) >>>> >>>> This function returns the exception error code pushed onto the stack by >>>> processor. Its return value is 64 bits in 64-bit mode and 32 bits in >>>> 32-bit mode. This function can only be used in exception handler. >>> >>> >>> Exception handlers can, in general, call regular functions which, in >>> turn, >>> might want to access the error code. Given that operating system kernels >>> are always entered via an interrupt, trap, or system call, there should >>> always be an error code available (on x86, non-error-code interrupts can >>> just make up an error code). >>> >>>> It also changes the definition of >>>> >>>> void * __builtin_interrupt_data (void) >>>> >>>> so that it returns a pointer to the data layout pushed onto stack >>>> by processor for both interrupt and exception handlers. >>>> >>>> >>> You might want to have a look at Secure Virtual Architecture (SVA). One >>> of >> >> I believe my x86 interrupt attribute is unrelated to SVA. > > > Actually, I really think that it is. Part of the SVA work extended the LLVM > IR to support an operating system kernel. Your design for interrupt > handlers and accessing interrupted program state looks very similar to my > first draft of those extensions and has the exact same limitations (plus at > least one limitation that my design did not have). It's pretty clear to me > that you're redesigning a subset of the SVA-OS extensions from scratch; I > find that unfortunate because you are literally reinventing the wheel. > >> >>> If the implementation is useful, SVA is publicly available at >>> https://github.com/jtcriswell/SVA. >>> >>> Finally, to echo Joerg's concerns, it's not clear that having >>> exception/interrupt handlers declared as a special type is really >>> helpful. >>> It's not immediately obvious that you get a benefit from doing that vs. >>> doing what most system software does (having assembly code that saves >>> processor state and calls a C function). I think you should do some >>> experiments to demonstrate the benefit that one can get with your method >>> to >>> see if it is worth adding complexity to the compiler. >>> >> The main purpose of x86 interrupt attribute is to allow programmers >> to write x86 interrupt/exception handlers in C WITHOUT assembly >> stubs to avoid extra branch from assembly stubs to C functions. I >> want to keep the number of new intrinsics to minimum without sacrificing >> handler performance. I leave faking error code in interrupt handler to >> the programmer. >> > > If you want to do that, there is another approach that should work just as > well and will require only localized changes to the compiler. > > Interrupt handlers are typically registered to some interrupt vector number > using a registration function. In FreeBSD, it's setidt(), and in Linux, I > think it's set_gate(). You can write a compiler transform that looks for > these registration functions, determines the function that is registered as > an interrupt handler, and generate the more efficient code for that > interrupt handler function as you describe. > > This solution avoids language extensions to the C/C++ front-end (which > requires getting approval from the Clang developers) yet should get you the > performance that you want (provided that it does improve performance, for > which I'm a little skeptical but open to convincing via performance > measurements). You can probably write this transform as a single LLVM > MachineFunctionPass that your patched version of Clang runs during code > generation.
We may discuss different things here. My proposal covers writing interrupt/exception handlers in C. It doesn't deal with interrupt/exception handler registration at all. There are couple issues of writing x86 nterrupt/exception handlers in C: 1. Both interrupt and exception handlers must use the 'IRET' instruction, instead of the 'RET' instruction, to return from the handlers. 2. All registers are callee-saved in interrupt and exception handlers. 3. The difference between interrupt and exception handlers is the exception handler must pop 'ERROR_CODE' off the stack before the 'IRET' instruction. You need a way to tell compiler about them. -- H.J.