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?
Interrupts are handled incorrectly while the user space work
Re: Interrupts are handled incorrectly while the user space
Code: Select all
void isr_handler(registers_t regs)
Code: Select all
void isr_handler(registers_t *regs)
Code: Select all
pushl %esp
call isr_handler
addl $4, %esp
Carpe diem!
Re: Interrupts are handled incorrectly while the user space
I changed the code accordingly, but it doesn't solve the problem.nullplan wrote: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 toCode: Select all
void isr_handler(registers_t regs)
And then change the calling code toCode: Select all
void isr_handler(registers_t *regs)
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.Code: Select all
pushl %esp call isr_handler addl $4, %esp
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
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.
Re: Interrupts are handled incorrectly while the user space
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!
Re: Interrupts are handled incorrectly while the user space
I disabled paging so that it doesn't interfere with debugging.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'm also very interested in how this could happen.nullplan wrote:How is your ESP0 screwed up?
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.
Re: Interrupts are handled incorrectly while the user space
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.
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.