Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-23 Thread H.J. Lu
On Tue, Sep 22, 2015 at 11:13 AM, Richard Henderson  wrote:
>
> HJ, I think Hal is right.  Providing the data via arguments is vastly superior
> to providing it via builtins.  I had actually been thinking the same thing 
> myself.
>
> It should be easy to check that the function has the correct signature in the
> hook adding the attribute.  It should also be easy to check for the attribute
> at the beginning of ix86_function_arg et al, in order to handle these special
> cases.
>

Thanks for all feedbacks.  Here is the updated spec.

-- 
H.J.
---
The interrupt and exception handlers are called by x86 processors.  X86
hardware pushes information onto stack and calls the handler.  The
requirements are

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.

The design goals of interrupt and exception handlers for x86 processors
are:

1. Support both 32-bit and 64-bit modes.
2. Flexible for compilers to optimize.
3. Easy to use by programmers.

To implement interrupt and exception handlers for x86 processors, a
compiler should support:

'interrupt' attribute

Use this attribute to indicate that the specified function with
mandatory arguments is an interrupt or exception handler.  The compiler
generates function entry and exit sequences suitable for use in an
interrupt handler when this attribute is present.  The 'IRET' instruction,
instead of the 'RET' instruction, is used to return from interrupt or
exception handlers.  All registers, except for the EFLAGS register which
is restored by the 'IRET' instruction, are preserved by the compiler.

Any interruptible-without-stack-switch code must be compiled with
-mno-red-zone since interrupt handlers can and will, because of the
hardware design, touch the red zone.

1. interrupt handler must be declared with a mandatory argument:

#ifdef __x86_64__
typedef unsigned long long int uword_t;
#else
typedef unsigned int uword_t;
#endif

struct interrupt_frame
{
  uword_t ip;
  uword_t cs;
  uword_t flags;
  uword_t sp;
  uword_t ss;
};

__attribute__ ((interrupt))
void
f (struct interrupt_frame *frame)
{
...
}

2. exception handler:

The exception handler is very similar to the interrupt handler with
a different mandatory function signature:

__attribute__ ((interrupt))
void
f (struct interrupt_frame *frame, uword_t error_code)
{
...
}

and compiler pops `ERROR_CODE' off stack before the 'IRET' instruction.

The exception handler should only be used for exceptions which push an
error code and all other exceptions must use the interrupt handler.
The system will crash if the wrong handler is used.


Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread H. Peter Anvin
On 09/22/15 04:52, David Chisnall wrote:
> On 22 Sep 2015, at 12:47, H.J. Lu  wrote:
>>
>> since __builtin_exception_error () is the same as
>> __builtin_return_address (0) and __builtin_interrupt_data () is
>> address of __builtin_exception_error () + size of register.
> 
> Except that they’re *not*.  __builtin_return_address(0) is guaranteed to be 
> the same for the duration of the function.  __builtin_exception_error() needs 
> to either:
> 
> 1) Fetch the values early with interrupts disabled, store them in a
> well-known location, and load them from this place when the intrinsic
> is called, or
> 
> 2) Force any function that calls the intrinsic (and wants a
> meaningful result) to run with interrupts disabled, which is
> something that the compiler can’t verify without knowing the full
> chain of code from the interrupt handler to the current point (and
> therefore prone to error).
> 
> It is trivial to write a little bit of inline assembly that reads
> these values from the CPU and expose that for C code.  There is a
> good reason why no one does this.
> 

This is why it makes no sense for the intrinsics to be callable from
anywhere except inside the interrupt handler.  It is really nothing
other than a way to pass arguments -- whether or not it is simpler for
the compilers to implement than supporting a different function
signature is beyond my scope of expertise.

-hpa



Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread H. Peter Anvin
On 09/22/15 04:44, David Chisnall wrote:
> On 22 Sep 2015, at 12:39, H.J. Lu via cfe-dev  wrote:
>>
>> The center piece of my proposal is not to change how parameters
>> are passed in compiler.  As for user experience, the feedbacks on
>> my proposal from our users are very positive.
> 
> Implementing the intrinsics for getting the current interrupt
> requires a lot of support code for it to actually be useful.  For it
> to be useful, you are requiring all of the C code to be run with
> interrupts disabled (and even that doesn’t work if you get a NMI in
> the middle).  Most implementations use a small amount of assembly to
> capture the interrupt cause and the register state on entry to the
> handler, then reenable interrupts while the C code runs.  This means
> that any interrupts (e.g. page faults, illegal instruction traps,
> whatever) that happen while the C code is running do not mask the
> values.  Accessing these values from *existing* C code is simply a
> matter of loading a field from a structure.
> 
> I’m really unconvinced by something that something with such a narrow
> use case (and one that encourages writing bad code) belongs in the
> compiler.
> 

You seem to not understand how x86 works, nor have noted how this is
nearly universally supported by various architectures; x86 is the
exception here.

x86 stores its interrupt state on the stack, not in a register which can
be clobbered.  Also, a lot of your assertions about "most
implementations" only apply to full-scale operating systems.

-hpa




Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread H. Peter Anvin
On 09/22/15 01:41, David Chisnall wrote:
> On 21 Sep 2015, at 21:45, H.J. Lu via cfe-dev  wrote:
>>
>> 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.
> 
> The assembly stubs have to come from somewhere.  You either put them
> in an assembly file (most people doing embedded x86 stuff steal the
> ones from NetBSD), or you put them in the compiler where they can be
> inlined.  In terms of user interface, there’s not much difference in
> complexity.  Having written this kind of code in the past, I can
> honestly say that using the assembly stubs was the least difficult
> part of getting them right.  In terms of compiler complexity, there’s
> a big difference: in one case the compiler contains nothing, in the
> other it contains something special for a single use case.  In terms
> of performance, the compiler version has the potential to be faster,
> but if we’re going to pay for the complexity then I think that we’d
> need to see some strong evidence that someone else is getting a
> noticeable benefit.
> 

It is worth noting that most architectures has this support for a reason.

-hpa



Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread Richard Henderson
On 09/21/2015 04:03 PM, Hal Finkel wrote:
> - Original Message -
>> From: "H.J. Lu" <hjl.to...@gmail.com>
>> To: "Hal Finkel" <hfin...@anl.gov>
>> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> Sent: Monday, September 21, 2015 5:57:36 PM
>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>>
>> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfin...@anl.gov> wrote:
>>> - Original Message -
>>>> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
>>>> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>>>> Sent: Monday, September 21, 2015 11:27:18 AM
>>>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
>>>> handlers
>>>>
>>>> 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.
>>>>
>>>> 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.
>>>>
>>>>
>>>> --
>>>> H.J.
>>>> ---
>>>> The interrupt and exception handlers are called by x86 processors.
>>>>  X86
>>>> hardware pushes information onto stack and calls the handler.  The
>>>> requirements are
>>>>
>>>> 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.
>>>>
>>>> The design goals of interrupt and exception handlers for x86
>>>> processors
>>>> are:
>>>>
>>>> 1. No new calling convention in compiler.
>>>> 2. Support both 32-bit and 64-bit modes.
>>>> 3. Flexible for compilers to optimize.
>>>> 4. Easy to use by programmers.
>>>>
>>>> To implement interrupt and exception handlers for x86 processors,
>>>> a
>>>> compiler should support:
>>>>
>>>> 1. void * __builtin_interrupt_data (void)
>>>>
>>>> This function returns a pointer to the return address pushed onto
>>>> the
>>>> stack by processor.
>>>>
>>>> The __builtin_frame_address builtin isn't suitable for interrupt
>>>> and
>>>> exception handlers since it returns the stack frame address on the
>>>> callee side and compiler may generate a new stack frame for stack
>>>> alignment.
>>>>
>>>> 2. unsigned int __builtin_exception_error (void)
>>>>unsigned long long int __builtin_exception_error (void)
>>>>
>>>> This function returns the exception error code pushed onto the
>&g

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread Hal Finkel
- Original Message -
> From: "H.J. Lu" <hjl.to...@gmail.com>
> To: "Hal Finkel" <hfin...@anl.gov>
> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
> Sent: Monday, September 21, 2015 7:17:20 PM
> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
> 
> On Mon, Sep 21, 2015 at 4:03 PM, Hal Finkel <hfin...@anl.gov> wrote:
> > - Original Message -
> >> From: "H.J. Lu" <hjl.to...@gmail.com>
> >> To: "Hal Finkel" <hfin...@anl.gov>
> >> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
> >> Sent: Monday, September 21, 2015 5:57:36 PM
> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
> >> handlers
> >>
> >> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfin...@anl.gov>
> >> wrote:
> >> > - Original Message -
> >> >> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
> >> >> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
> >> >> Sent: Monday, September 21, 2015 11:27:18 AM
> >> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
> >> >> handlers
> >> >>
> >> >> 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.
> >> >>
> >> >> 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.
> >> >>
> >> >>
> >> >> --
> >> >> H.J.
> >> >> ---
> >> >> The interrupt and exception handlers are called by x86
> >> >> processors.
> >> >>  X86
> >> >> hardware pushes information onto stack and calls the handler.
> >> >>  The
> >> >> requirements are
> >> >>
> >> >> 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.
> >> >>
> >> >> The design goals of interrupt and exception handlers for x86
> >> >> processors
> >> >> are:
> >> >>
> >> >> 1. No new calling convention in compiler.
> >&

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread David Chisnall
On 21 Sep 2015, at 21:45, H.J. Lu via cfe-dev  wrote:
> 
> 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.

The assembly stubs have to come from somewhere.  You either put them in an 
assembly file (most people doing embedded x86 stuff steal the ones from 
NetBSD), or you put them in the compiler where they can be inlined.  In terms 
of user interface, there’s not much difference in complexity.  Having written 
this kind of code in the past, I can honestly say that using the assembly stubs 
was the least difficult part of getting them right.  In terms of compiler 
complexity, there’s a big difference: in one case the compiler contains 
nothing, in the other it contains something special for a single use case.  In 
terms of performance, the compiler version has the potential to be faster, but 
if we’re going to pay for the complexity then I think that we’d need to see 
some strong evidence that someone else is getting a noticeable benefit.

David



Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread H.J. Lu
On Tue, Sep 22, 2015 at 1:11 AM, Hal Finkel <hfin...@anl.gov> wrote:
> - Original Message -
>> From: "H.J. Lu" <hjl.to...@gmail.com>
>> To: "Hal Finkel" <hfin...@anl.gov>
>> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> Sent: Monday, September 21, 2015 7:17:20 PM
>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>>
>> On Mon, Sep 21, 2015 at 4:03 PM, Hal Finkel <hfin...@anl.gov> wrote:
>> > - Original Message -
>> >> From: "H.J. Lu" <hjl.to...@gmail.com>
>> >> To: "Hal Finkel" <hfin...@anl.gov>
>> >> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> >> Sent: Monday, September 21, 2015 5:57:36 PM
>> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
>> >> handlers
>> >>
>> >> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfin...@anl.gov>
>> >> wrote:
>> >> > - Original Message -
>> >> >> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
>> >> >> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> >> >> Sent: Monday, September 21, 2015 11:27:18 AM
>> >> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
>> >> >> handlers
>> >> >>
>> >> >> 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.
>> >> >>
>> >> >> 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.
>> >> >>
>> >> >>
>> >> >> --
>> >> >> H.J.
>> >> >> ---
>> >> >> The interrupt and exception handlers are called by x86
>> >> >> processors.
>> >> >>  X86
>> >> >> hardware pushes information onto stack and calls the handler.
>> >> >>  The
>> >> >> requirements are
>> >> >>
>> >> >> 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
>> >&

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread H.J. Lu
On Tue, Sep 22, 2015 at 1:41 AM, David Chisnall
 wrote:
> On 21 Sep 2015, at 21:45, H.J. Lu via cfe-dev  wrote:
>>
>> 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.
>
> The assembly stubs have to come from somewhere.  You either put them in an 
> assembly file (most people doing embedded x86 stuff steal the ones from 
> NetBSD), or you put them in the compiler where they can be inlined.  In terms 
> of user interface, there’s not much difference in complexity.  Having written 
> this kind of code in the past, I can honestly say that using the assembly 
> stubs was the least difficult part of getting them right.  In terms of 
> compiler complexity, there’s a big difference: in one case the compiler 
> contains nothing, in the other it contains something special for a single use 
> case.  In terms of performance, the compiler version has the potential to be 
> faster, but if we’re going to pay for the complexity then I think that we’d 
> need to see some strong evidence that someone else is getting a noticeable 
> benefit.

I understand your concern.  IA MCU users want to write interrupt/exception
handlers in C, just like many embedded processors.  The goals are to
save code space and improve performance.  Using builtin functions,
instead of adding a new way to pass parameters,  makes compiler
change much simpler, since __builtin_exception_error () is the same as
 __builtin_return_address (0) and __builtin_interrupt_data () is
address of __builtin_exception_error () + size of register.


-- 
H.J.


Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread H.J. Lu
On Tue, Sep 22, 2015 at 4:44 AM, David Chisnall
 wrote:
> On 22 Sep 2015, at 12:39, H.J. Lu via cfe-dev  wrote:
>>
>> The center piece of my proposal is not to change how parameters
>> are passed in compiler.  As for user experience, the feedbacks on
>> my proposal from our users are very positive.
>
> Implementing the intrinsics for getting the current interrupt requires a lot 
> of support code for it to actually be useful.  For it to be useful, you are 
> requiring all of the C code to be run with interrupts disabled (and even that 
> doesn’t work if you get a NMI in the middle).  Most implementations use a 
> small amount of assembly to capture the interrupt cause and the register 
> state on entry to the handler, then reenable interrupts while the C code 
> runs.  This means that any interrupts (e.g. page faults, illegal instruction 
> traps, whatever) that happen while the C code is running do not mask the 
> values.  Accessing these values from *existing* C code is simply a matter of 
> loading a field from a structure.

The above applies to with and without intrinsics.

> I’m really unconvinced by something that something with such a narrow use 
> case (and one that encourages writing bad code) belongs in the compiler.
>
> David



-- 
H.J.


Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread David Chisnall
On 22 Sep 2015, at 12:39, H.J. Lu via cfe-dev  wrote:
> 
> The center piece of my proposal is not to change how parameters
> are passed in compiler.  As for user experience, the feedbacks on
> my proposal from our users are very positive.

Implementing the intrinsics for getting the current interrupt requires a lot of 
support code for it to actually be useful.  For it to be useful, you are 
requiring all of the C code to be run with interrupts disabled (and even that 
doesn’t work if you get a NMI in the middle).  Most implementations use a small 
amount of assembly to capture the interrupt cause and the register state on 
entry to the handler, then reenable interrupts while the C code runs.  This 
means that any interrupts (e.g. page faults, illegal instruction traps, 
whatever) that happen while the C code is running do not mask the values.  
Accessing these values from *existing* C code is simply a matter of loading a 
field from a structure.

I’m really unconvinced by something that something with such a narrow use case 
(and one that encourages writing bad code) belongs in the compiler.

David

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-22 Thread David Chisnall
On 22 Sep 2015, at 12:47, H.J. Lu  wrote:
> 
> since __builtin_exception_error () is the same as
> __builtin_return_address (0) and __builtin_interrupt_data () is
> address of __builtin_exception_error () + size of register.

Except that they’re *not*.  __builtin_return_address(0) is guaranteed to be the 
same for the duration of the function.  __builtin_exception_error() needs to 
either:

1) Fetch the values early with interrupts disabled, store them in a well-known 
location, and load them from this place when the intrinsic is called, or

2) Force any function that calls the intrinsic (and wants a meaningful result) 
to run with interrupts disabled, which is something that the compiler can’t 
verify without knowing the full chain of code from the interrupt handler to the 
current point (and therefore prone to error).

It is trivial to write a little bit of inline assembly that reads these values 
from the CPU and expose that for C code.  There is a good reason why no one 
does this.

Without a better programmer model, you are not simplifying things, you are just 
providing more ways for introducing errors.

David



Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread H.J. Lu
On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfin...@anl.gov> wrote:
> - Original Message -
>> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
>> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> Sent: Monday, September 21, 2015 11:27:18 AM
>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>>
>> 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.
>>
>> 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.
>>
>>
>> --
>> H.J.
>> ---
>> The interrupt and exception handlers are called by x86 processors.
>>  X86
>> hardware pushes information onto stack and calls the handler.  The
>> requirements are
>>
>> 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.
>>
>> The design goals of interrupt and exception handlers for x86
>> processors
>> are:
>>
>> 1. No new calling convention in compiler.
>> 2. Support both 32-bit and 64-bit modes.
>> 3. Flexible for compilers to optimize.
>> 4. Easy to use by programmers.
>>
>> To implement interrupt and exception handlers for x86 processors, a
>> compiler should support:
>>
>> 1. void * __builtin_interrupt_data (void)
>>
>> This function returns a pointer to the return address pushed onto the
>> stack by processor.
>>
>> The __builtin_frame_address builtin isn't suitable for interrupt and
>> exception handlers since it returns the stack frame address on the
>> callee side and compiler may generate a new stack frame for stack
>> alignment.
>>
>> 2. 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.
>
> Instead of adding more builtins for these, why not simply model this by 
> giving the handler function a non-trivial signature? So, for example, the 
> interrupt handler would be:
>
>  void handler(void *);
>
> and the exception handler would be:
>
>   void handler(size_t);
>

Since x86 interrupt/exception handlers don't conform to any x86 psABI,
you need to modify compiler to generate proper codes for

void handler(void *);

Please take a look at interrupt/exception handlers section in Intel SDM
vol 3.

-- 
H.J.


Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread Hal Finkel
- Original Message -
> From: "H.J. Lu" <hjl.to...@gmail.com>
> To: "Hal Finkel" <hfin...@anl.gov>
> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
> Sent: Monday, September 21, 2015 5:57:36 PM
> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
> 
> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfin...@anl.gov> wrote:
> > - Original Message -
> >> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
> >> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
> >> Sent: Monday, September 21, 2015 11:27:18 AM
> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
> >> handlers
> >>
> >> 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.
> >>
> >> 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.
> >>
> >>
> >> --
> >> H.J.
> >> ---
> >> The interrupt and exception handlers are called by x86 processors.
> >>  X86
> >> hardware pushes information onto stack and calls the handler.  The
> >> requirements are
> >>
> >> 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.
> >>
> >> The design goals of interrupt and exception handlers for x86
> >> processors
> >> are:
> >>
> >> 1. No new calling convention in compiler.
> >> 2. Support both 32-bit and 64-bit modes.
> >> 3. Flexible for compilers to optimize.
> >> 4. Easy to use by programmers.
> >>
> >> To implement interrupt and exception handlers for x86 processors,
> >> a
> >> compiler should support:
> >>
> >> 1. void * __builtin_interrupt_data (void)
> >>
> >> This function returns a pointer to the return address pushed onto
> >> the
> >> stack by processor.
> >>
> >> The __builtin_frame_address builtin isn't suitable for interrupt
> >> and
> >> exception handlers since it returns the stack frame address on the
> >> callee side and compiler may generate a new stack frame for stack
> >> alignment.
> >>
> >> 2. 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.
> >
> > Instead of adding more builtins for these, why not simply model
> > this by giving the handler function a non-trivial signature? So,
> > for example, the interrupt handler would be:
> >
> >  void handler(void *);
> >
> > and the exception handler would be:
> >
> >   void handler(size_t);
> >
> 
> Since x86 interrupt/exception handlers don't conform to any x86
> psABI,
> you need to modify compiler to generate proper codes for
> 
> void handler(void *);
> 
> Please take a look at interrupt/exception handlers section in Intel
> SDM
> vol 3.

Yes, I understand that. But we already would need to customize the 
call-frame-lowering code for these functions, and since this already requires 
customization, what's the advantage of the builtins over adding special logic 
to make these parameters correspond to the appropriate stack locations and/or 
registers?

 -Hal

> 
> --
> H.J.
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory


Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread H.J. Lu
On Mon, Sep 21, 2015 at 4:03 PM, Hal Finkel <hfin...@anl.gov> wrote:
> - Original Message -
>> From: "H.J. Lu" <hjl.to...@gmail.com>
>> To: "Hal Finkel" <hfin...@anl.gov>
>> Cc: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> Sent: Monday, September 21, 2015 5:57:36 PM
>> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
>>
>> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel <hfin...@anl.gov> wrote:
>> > - Original Message -
>> >> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
>> >> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
>> >> Sent: Monday, September 21, 2015 11:27:18 AM
>> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception
>> >> handlers
>> >>
>> >> 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.
>> >>
>> >> 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.
>> >>
>> >>
>> >> --
>> >> H.J.
>> >> ---
>> >> The interrupt and exception handlers are called by x86 processors.
>> >>  X86
>> >> hardware pushes information onto stack and calls the handler.  The
>> >> requirements are
>> >>
>> >> 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.
>> >>
>> >> The design goals of interrupt and exception handlers for x86
>> >> processors
>> >> are:
>> >>
>> >> 1. No new calling convention in compiler.
>> >> 2. Support both 32-bit and 64-bit modes.
>> >> 3. Flexible for compilers to optimize.
>> >> 4. Easy to use by programmers.
>> >>
>> >> To implement interrupt and exception handlers for x86 processors,
>> >> a
>> >> compiler should support:
>> >>
>> >> 1. void * __builtin_interrupt_data (void)
>> >>
>> >> This function returns a pointer to the return address pushed onto
>> >> the
>> >> stack by processor.
>> >>
>> >> The __builtin_frame_address builtin isn't suitable for interrupt
>> >> and
>> >> exception handlers since it returns the stack frame address on the
>> >> callee side and compiler may generate a new stack frame for stack
>> >> alignment.
>> >>
>> >> 2. unsigned int __builtin_exception_error (void)
>> >>unsigned long lon

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread Hal Finkel
- Original Message -
> From: "H.J. Lu via cfe-dev" <cfe-...@lists.llvm.org>
> To: "GCC Development" <gcc@gcc.gnu.org>, cfe-...@lists.llvm.org
> Sent: Monday, September 21, 2015 11:27:18 AM
> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
> 
> 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.
> 
> 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.
> 
> 
> --
> H.J.
> ---
> The interrupt and exception handlers are called by x86 processors.
>  X86
> hardware pushes information onto stack and calls the handler.  The
> requirements are
> 
> 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.
> 
> The design goals of interrupt and exception handlers for x86
> processors
> are:
> 
> 1. No new calling convention in compiler.
> 2. Support both 32-bit and 64-bit modes.
> 3. Flexible for compilers to optimize.
> 4. Easy to use by programmers.
> 
> To implement interrupt and exception handlers for x86 processors, a
> compiler should support:
> 
> 1. void * __builtin_interrupt_data (void)
> 
> This function returns a pointer to the return address pushed onto the
> stack by processor.
> 
> The __builtin_frame_address builtin isn't suitable for interrupt and
> exception handlers since it returns the stack frame address on the
> callee side and compiler may generate a new stack frame for stack
> alignment.
> 
> 2. 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.

Instead of adding more builtins for these, why not simply model this by giving 
the handler function a non-trivial signature? So, for example, the interrupt 
handler would be:

 void handler(void *);

and the exception handler would be:

  void handler(size_t);

 -Hal

> 
> 3. 'interrupt' attribute
> 
> Use this attribute to indicate that the specified void function
> without
> arguments is an interrupt handler.  The compiler generates function
> entry
> and exit sequences suitable for use in an interrupt handler when this
> attribute is present.  The 'IRET' instruction, instead of the
> 'RET' instruction, is used to return from interrupt handlers.  All
> registers, except for the EFLAGS register which is restored by the
> 'IRET' instruction, are preserved by the compiler.  The red zone
> isn't supported in the interrupted function; that is an interrupt
> handler may access stack within 128 bytes of the current stack
> pointer.
> 
> You can use the builtin '__builtin_interrupt_data' function to access
> the interrupt data pushed onto the stack by processor:
> 
> void
> f () __attribute__ ((interrupt))
> {
>   void *p = __builtin_interrupt_data ();
>   ...
> }
> 
> 4. 'exception' attribute
> 
> Use 'exception' instead of 'interrupt' for handlers intended to be
> used for 'exception' (i.e. those that must pop 'ERROR_CODE' off the
> stack before the 'IRET' instruction).
> 
> You can use the builtin '__bu

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread H.J. Lu
On Mon, Sep 21, 2015 at 2:23 PM, John Criswell  wrote:
> On 9/21/15 4:45 PM, H.J. Lu wrote:
>>
>> On Mon, Sep 21, 2015 at 11:52 AM, John Criswell 
>> 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  wrote:
>
> On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu  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 

Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread H.J. Lu
On Mon, Sep 21, 2015 at 11:52 AM, John Criswell  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  wrote:
>>>
>>> On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu  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.

> 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.

-- 
H.J.


Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread John Criswell

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  wrote:

On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu  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 the things we discovered is that commodity operating systems access 
the most recently used interrupt data (which SVA calls an "interrupt 
context").  Over the years, we figured out that it's better to provide 
intrinsics (i.e., builtins) that implicitly access the top-most 
interrupt context.  We also found that we could limit the operations 
performed on interrupt contexts so that we could safely implement signal 
handlers and exception recovery without letting the operating system 
kernel have pointers to the interrupt context which would need to be 
checked.  In short, despite common belief, the OS does not need to do 
whatever it wants with interrupted program state.


I recommend you take a look at Appendix A of my dissertation 
(https://www.ideals.illinois.edu/handle/2142/50547).  It describes the 
SVA-OS instructions used to abstract away the hardware details. You'll 
also notice that the design is pretty processor transparent (MMU 
notwithstanding), so designing your builtins based on SVA may make them 
more portable if you decide to use another processor later on.  Chapter 
2 describes some of the rationale behind the design, though it's for the 
first version of SVA (Appendix A is the final instruction set after 4 
papers).


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.


Regards,

John Criswell

--
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell



Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers

2015-09-21 Thread John Criswell

On 9/21/15 4:45 PM, H.J. Lu wrote:

On Mon, Sep 21, 2015 at 11:52 AM, John Criswell  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  wrote:

On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu  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.


In any event, that's my two cents.

Regards,

John Criswell

--
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell