On Sun, Oct 4, 2015 at 3:29 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Sun, Oct 4, 2015 at 7:23 AM, Yulia Koval <vaalfr...@gmail.com> wrote:
>> Hi,
>>
>> Here is the last version of the patch. Regtested/bootstraped for
>> Linux/i686 and Linux/x86_64.
>>
>> Date: Fri, 4 Sep 2015 08:53:23 -0700
>> Subject: [PATCH] Implement x86 interrupt attribute
>>
>> 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 pointer argument:
>>
>> struct interrupt_frame;
>>
>> __attribute__ ((interrupt))
>> void
>> f (struct interrupt_frame *frame)
>> {
>> ...
>> }
>>
>> and user must properly define the structure the pointer pointing to.
>>
>> 2. exception handler:
>>
>> The exception handler is very similar to the interrupt handler with
>> a different mandatory function signature:
>>
>> typedef unsigned long long int uword_t;
>> typedef unsigned int uword_t;
>>
>> struct interrupt_frame;
>>
>> __attribute__ ((interrupt))
>> void
>> f (struct interrupt_frame *frame, uword_t error_code)
>> {
>> ...
>> }
>>
>> and compiler pops the 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.
>>
>> To be feature complete, compiler may implement the optional
>> 'no_caller_saved_registers' attribute:
>>
>> Use this attribute to indicate that the specified function has no
>> caller-saved registers.  That is, all registers are callee-saved.
>> The compiler generates proper function entry and exit sequences to
>> save and restore any modified registers.
>>
>> The user can call functions specified with 'no_caller_saved_registers'
>> attribute from an interrupt handler without saving and restoring all
>> call clobbered registers.
>
> Looking a bit deeper into the code, it looks that we want to realign
> the stack in the interrupt handler. Let's assume that interrupt
> handler is calling some other function that saves SSE vector regs to
> the stack. According to the x86 ABI, incoming stack of the called
> function is assumed to be aligned to 16 bytes. But, interrupt handler
> violates this assumption, since the stack could be aligned to only 4
> bytes for 32bit and 8 bytes for 64bit targets. Entering the called
> function with stack, aligned to less than 16 bytes will certainly
> violate ABI.
>
> So, it looks to me that we need to realign the stack in the interrupt
> handler unconditionally to 16bytes. In this case, we also won't need
> the following changes:
>

Current stack alignment implementation requires at least
one, maybe two, scratch registers:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67841

Extend it to the interrupt handler, which doesn't have any scratch
registers may require significant changes in backend as well as
register allocator.

-- 
H.J.

Reply via email to