OSDev.org https://forum.osdev.org/ |
|
Interrupts seem to invalidate stack https://forum.osdev.org/viewtopic.php?f=1&t=56425 |
Page 1 of 1 |
Author: | hoiblij [ Sat Aug 13, 2022 5:12 am ] |
Post subject: | Interrupts seem to invalidate stack |
I have an issue where my interrupt code seems to be corrupting the stack, which in very specific cases causes a page fault. This is such a case: Code: 0xffffff8000011fce: mov -0x8(%rbp),%rax 0xffffff8000011fd2: movb $0x0,(%rax) When the return address is the first instruction a page fault is thrown at the second instruction which complains that the address 0x0 is unmapped. These page faults are thrown whenever this pattern occurs in the interrupted code. My assembly interrupt code: Code: mouse_asm: cli sub rsp, 8 push rax push rbx push rcx push rdx push rsp push rbp push rsi push rdi push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 mov ax, ds push rax mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax call _ZN11MouseDriver15HandleInterruptE9int_frame pop rax mov ds, ax mov es, ax mov fs, ax mov gs, ax pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rdi pop rsi pop rbp pop rsp pop rdx pop rcx pop rbx pop rax add rsp, 8 sti iretq (I know not all these registers have to be stored I just did to make sure. Also, I normally use a common stub which is why the stack pointer is incremented by 8 in the beginning.) And the called C++ code: Code: void MouseDriver::HandleInterrupt(int_frame frame){ while(IO::In(0x64) & 0x1) IO::In(0x60); IO::Out(PIC1_COMMAND_PORT, 0x20); IO::Out(PIC2_COMMAND_PORT, 0x20); return; } The page faults also occurs for keyboard and PIT interrupts, I'm just using the mouse for convenience's sake. I can also post the disassembled interrupted code if necessary. I have been stuck on this for a while now so it would be really awesome if this issue were finally resolved, thanks in advance. |
Author: | Octocontrabass [ Sun Aug 14, 2022 7:38 pm ] |
Post subject: | Re: Interrupts seem to invalidate stack |
You're following a buggy tutorial and you've run into one of the bugs. When you pass a struct by value, the contents of the struct may be overwritten by the function. You need to pass a pointer (or perhaps a reference?) to the struct in order to preserve its contents. Also, you shouldn't push/pop RSP. Also, your handler shouldn't start with CLI. If you want interrupts disabled, use an interrupt gate. Also, your handler shouldn't have STI before IRETQ. IRETQ will update RFLAGS.IF according to the value on the stack. Also, you need CLD before you call any C++ functions inside an interrupt handler. Also, you need to ensure your stack is correctly aligned before you call any C++ functions. (The CPU automatically aligns the stack before pushing the return address and return stack pointer, so you can align the stack by making sure you push the right number of values. It might already be correctly aligned - I haven't checked.) |
Author: | hoiblij [ Mon Aug 15, 2022 3:40 am ] |
Post subject: | Re: Interrupts seem to invalidate stack |
I'm not following specifically his tutorial, but bad code seems to be very widespread online if you can't use the struct itself as an argument. I have changed the things you commented on however, and my assembly code now looks like this: Quote: mouse_asm: cli cld PUSHALL mov ax, ds push rax mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov rdi, rsp mov r12, rsp and rsp, -16 call _ZN11MouseDriver15HandleInterruptEP9int_frame mov rsp, r12 pop rax mov ds, ax mov es, ax mov fs, ax mov gs, ax POPALL iretq (PUSHALL and POPALL are macros that push and pop the registers, not including rsp) I still get the same issue I got before however, even now that I'm passing a pointer to the struct. Maybe noteworthy: I used to have the same issue when using GCC's interrupt attribute. It's why I switched to assembly stubs in the first place, but that hasn't changed anything. Could that mean the error isn't in my assembly code? |
Author: | Demindiro [ Mon Aug 15, 2022 4:06 am ] |
Post subject: | Re: Interrupts seem to invalidate stack |
hoiblij wrote: Code: pop rax mov ds, ax mov es, ax mov fs, ax mov gs, ax I keep seeing this so I decided to take a look at the tutorial. AFAICT the tutorial only deals with protected (32-bit) mode, not long (64-bit) mode where setting the segment registers is useless. The exceptions are SS and CS, which are saved and restored by the interrupt and iretq automatically anyways. Please read the Features section on the X86-64 page. Also, a minor nit but you don't need to save all registers if you don't modify them directly and follow the calling conventions. (FWIW, I checked Linux' source and they don't save segment registers in long mode either.) |
Author: | Gigasoft [ Mon Aug 15, 2022 10:10 am ] |
Post subject: | Re: Interrupts seem to invalidate stack |
Never copy code you found online, period. You have no way to know if the author knows what he's doing. This anti-pattern is beyond stupid, and whenever encountered should be an indication to stop wasting your time and close the page: Code: push ds mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax ; just in case I feel like decorating my code with random FS prefixes mov gs, ax ; or GS prefixes, for variety ; do stuff pop eax mov ds, ax mov es, ax ; one segment should be enough for everyone mov fs, ax ; I assume no one was using these for anything important mov gs, ax ; God knows what these registers do anyway This is what happens when code is copied and pasted on the internet indiscriminately. Completely ridiculous and pointless. |
Author: | hoiblij [ Mon Aug 15, 2022 11:51 am ] |
Post subject: | Re: Interrupts seem to invalidate stack |
I was aware that (re)storing the segment registers was likely useless, I just did to be sure. I have removed it from my code, but it is still not working as expected. |
Author: | Octocontrabass [ Mon Aug 15, 2022 11:56 am ] |
Post subject: | Re: Interrupts seem to invalidate stack |
I don't see anything else in your interrupt code that might corrupt the stack. Are you sure the problem is stack corruption and not red zone corruption? |
Author: | hoiblij [ Mon Aug 15, 2022 4:59 pm ] |
Post subject: | Re: Interrupts seem to invalidate stack |
Wow, I had never heard about the red zone at all before. Perhaps it was mentioned on the wiki but I simply missed it. I added the -mno-red-zone flag and the issue is gone now, what a stupid thing to miss. Thanks a ton for all the help tho! |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |