Interrupts are handled incorrectly while the user space work

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Interrupts are handled incorrectly while the user space work

Post by mrjbom »

Hi.
My scheduler successfully passes control to the user program on Ring 3, but when this function is running in user mode, I get an interrupt from PIT, but there are problems in the handler.
For example, the interrupt number is determined incorrectly, just like other information related to the interrupt.

And now I'll tell you more:
The scheduler calls the scheduler_low_thread_switch() function, which stores data from the interrupted current task in current_thread and starts either a new task(next_thread), this function also determines whether the task is a user mode task.

In my case, it successfully runs a custom task in Ring 3 and it works fine(i go to ring 3 using this function), but there is a 32 interrupt from PIT.
In this case, the handler for the interrupt is called, it successfully calls isr_handler(), but the interrupt number is too large, and all other registers fields are invalid.
In addition, the handler tries to print the number of the unprocessed interrupt, but some problem occurs during its processing and because the handler is not completed correctly, the interrupts remain disabled and the system freezes.

Just in case, I recorded it on video, maybe it will be a little clearer there.
At the end of the video, you can see that this interruption is from PIT.
There are 4 of them after setting up multitasking, each time the task is switched.
0(kernel)->1(kernel)
1(kernel)->2(kernel)
2(kernel)->3(user mode)
3(user mode)->0(kernel) <-this is what is being processed incorrectly(int_num invalid)

What could be the problem?
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Interrupts are handled incorrectly while the user space

Post by nullplan »

Code: Select all

void isr_handler(registers_t regs)
Well there's your problem, lady! You pass the registers by value instead of passing a pointer to them. I don't precisely know how the ABI for passing a large structure by value works, but apparently not like this. So change this to

Code: Select all

void isr_handler(registers_t *regs)
And then change the calling code to

Code: Select all

pushl %esp
call isr_handler
addl $4, %esp
Your code should probably also save ES, FS, and GS. Also, you can push and pop segment registers directly, you don't need to go through a GPR first.
Carpe diem!
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Interrupts are handled incorrectly while the user space

Post by mrjbom »

nullplan wrote:

Code: Select all

void isr_handler(registers_t regs)
Well there's your problem, lady! You pass the registers by value instead of passing a pointer to them. I don't precisely know how the ABI for passing a large structure by value works, but apparently not like this. So change this to

Code: Select all

void isr_handler(registers_t *regs)
And then change the calling code to

Code: Select all

pushl %esp
call isr_handler
addl $4, %esp
Your code should probably also save ES, FS, and GS. Also, you can push and pop segment registers directly, you don't need to go through a GPR first.
I changed the code accordingly, but it doesn't solve the problem.
regs now points to an address that is too large(outside of available memory).
In addition, I don't understand why serial_printf() fails, probably for the same reason why I get the wrong address.

In addition, I found a strange behavior with esp, it is also too large.
ESP in isr_common handler
Image

It is not clear why this problem only occurs when an interrupt is triggered in ring 3.

UPD: I noticed that I had a problem in the user_mode_switch function, it did not set the stack to the user task, I fixed this error, but the ESP in the handler still has a strange value.
I believe that for some reason the handler stack is not configured correctly during the call(this is probably why there are problems in serial_printf()).
In all cases of exception handling(until the user program is running), the ESP in the isr_common handler has the correct value. only when an exception occurs when the user code is running, the ESP is corrupted.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Interrupts are handled incorrectly while the user space

Post by nullplan »

Well that would indicate that ESP0 in your TSS is screwed up. Also, if ESP is outside available memory, how did you even get that far? Shouldn't there have been a page fault on the way? Unless you are not using paging, in which case ESP is pointing into some I/O memory. Meaning you just lost your stack, and isr_handler() will be unable to return. That would also explain the funky values you got earlier. Now for the big question: How is your ESP0 screwed up?
Carpe diem!
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Interrupts are handled incorrectly while the user space

Post by mrjbom »

nullplan wrote:Also, if ESP is outside available memory, how did you even get that far? Shouldn't there have been a page fault on the way?
I disabled paging so that it doesn't interfere with debugging.
nullplan wrote:How is your ESP0 screwed up?
I'm also very interested in how this could happen.
Here is my code that configures TSS and I don't see any problems in configuring TSS.
write_tss() loads the normal value in esp0. the value of the stack variable is also ok.
I don't know why ESP0 is recorded incorrectly.
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Interrupts are handled incorrectly while the user space

Post by mrjbom »

The problem is solved. My task switcher incorrectly set tss.esp0.
Thanks for the hint, I guessed that I had some problems with tss, but I didn't think that the esp0 installed there affects the operation of interrupts.
Post Reply