Re: [pok-devel] Re: switch to user space and back during ISR |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/pok-devel Archives
]
Hi,
I think have a solution that might work, but it is a dirty hack.
I jump in after the kernel handler.
- Copy interrupt_frame from kernel stack to user stack
- prepare user stack to look like a normal function call occurred
(ARG2,ARG1,EIP)
- Set ds+es to user space values
- delete everything up to the error code
- modify the EIP in that was pushed by the interrupt to point to the
user space handler
- modify eflags to enable interrupts on iret
- iret
- user-space handler works as if it was called normally
- right before return from the handler, a piece of inline asm code
recovers the interrupt frame from the stack and restores all missing
values (not restored by iret) and after cleaning up the stack it places
the right EIP and EBP on the stack.
- The following leave,ret of the normal function execution will return
to the point of interrupt.
Question:
What happens if the interrupt occurred while in kernel space and the
EIP, CS,DS,etc. point into the kernel? --> *kramboom*
If the irq occurred in the kernel, I could check for that and do a
syscall passing the interrupt frame along to get to the right point, but
I think this will lead to dead memory on the user stack. The interrupt
frame on the user stack isn't cleaned up after the syscall.
Maybe I can do this from the kernel.
It feels like I opened the gates of hell just a little bit more.
Thoughts?
Cheers
Philipp
On 09/09/2013 09:50 PM, Julien Delange wrote:
> Hi Philipp,
>
> The design you suggest seems to make sense, I do not foresee any
> potential issue. Sounds very specific to one arch but on the other hand,
> this is more a proof-of-concept rather than a clean implementation ... I
> would suggest to proceed and try and see what is going on when you start
> to implement it ...
>
>
> On Mon, Sep 9, 2013 at 9:46 AM, Philipp Eppelt
> <philipp.eppelt@xxxxxxxxxxxxxxxxxxxxx
> <mailto:philipp.eppelt@xxxxxxxxxxxxxxxxxxxxx>> wrote:
>
> Hi,
>
> I have two handlers for an ISR which should be invoked during an ISR.
> The first handler is the kernel handler which is called fine. Then I
> have a handler, which is registered from user space.
> To call this handler I first need to switch to the user space
> environment. I am doing this by loading the CS,DS,SS and ESP - saved in
> the interrupt frame by the interrupt entry. The EIP should point to the
> instruction after the following 'iret'.
>
> "pushl %2 \t\n"
> "pushl %3 \t\n"
> "pushf \t\n"
> "pushl %1 \t\n"
> "push $1f \t\n"
> "iret \t\n"
> "1: \t\n"
> (with: 2->ss, 3->esp, 1->cs)
>
> This is a snippet from the inline asm block. The code should now be
> executed in user space environment. So the handler should be able to use
> and modify variables in the user space environment.
>
> Now I need to switch back to the kernel mode to finish the interrupt
> service routine and get back to the point of interruption.
>
> Can someone help me out here?
>
> The control flow is as follows:
> - irq 0
> - irq prolog 0
> - isr handler
> -- c isr handler
> --- kernel handler for irq 0
> -- inline asm code to switch to user space
> --- user space handler for irq 0
> -- inline asm code to switch to kernel space
> - isr handler cont'd.
> -- update tss
> - isr handler cont'd.
> - final iret
>
> By now I doubt that design will work, but I haven't come up with a way
> to invoke a user space handler and return to the point of
> interruption, yet.
>
> Any thoughts on this?
>
> Cheers,
> Philipp
>
>