Page 3 of 6

Re: Issues with interrupts

Posted: Fri Aug 05, 2022 11:51 pm
by Techflash
nullplan wrote:Far jump in AT&T syntax uses a different mnemonic:

Code: Select all

ljmp $<seg>, <label>
So for example:

Code: Select all

ljmp $8, 1f
1:
Indirect far jump uses the same mnemonic, but has a memory reference as operand, and requires a * to be placed in front of that operand (like indirect near jump).
As said previously:
Octocontrabass wrote: There's no way to encode a far JMP with a 64-bit destination in long mode, so you'll have to use something else (far RET is the usual choice).
So a far jump won't work. Still working on that part.

UPDATE: Not sure if this would work or not, but potentially:

Code: Select all

retf $0
might

UPDATE 2: Nope, it just barfs this:

Code: Select all

check_cs(0xffff): not a valid code segment !
interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0
interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0
(0).[7580933978] [0x000000113f75] 0008:ffffffffffe02f75 (unk. ctxt): retf 0x0000               ; ca0000
then triple faults.

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 12:16 am
by Octocontrabass
Techflash wrote:

Code: Select all

07416545692e[CPU0  ] iret64: return CS selector null
It's time to install and debug your exception handlers. I'd start by getting rid of the unnecessary duplicate RSP in this struct, and then fix this assembly to match the struct, pass a pointer to the struct, align the stack correctly, and clear the direction flag. (Most of those changes are to satisfy the System V ABI.)

Oh, and get rid of CLI. If you want interrupts disabled upon entry to your ISR, install interrupt gates in your IDT.
Techflash wrote:

Code: Select all

retf $0
As with IRETQ, you need to write RETFQ to get the 64-bit instruction (or LRETQ if your assembler is picky about following AT&T syntax). Also, when the operand is 0, you can remove it to make your code smaller without changing its behavior.

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 12:21 am
by Techflash
Octocontrabass wrote:
Techflash wrote:

Code: Select all

07416545692e[CPU0  ] iret64: return CS selector null
It's time to install and debug your exception handlers. I'd start by getting rid of the unnecessary duplicate RSP in this struct, and then fix this assembly to match the struct, pass a pointer to the struct, align the stack correctly, and clear the direction flag. (Most of those changes are to satisfy the System V ABI.)

Oh, and get rid of CLI. If you want interrupts disabled upon entry to your ISR, install interrupt gates in your IDT.
Techflash wrote:

Code: Select all

retf $0
As with IRETQ, you need to write RETFQ to get the 64-bit instruction (or LRETQ if your assembler is picky about following AT&T syntax). Also, when the operand is 0, you can remove it to make your code smaller without changing its behavior.
To be clear, the "unnecessary" RSP is the one on the line you highlighted, not the "userRsp" below, right?

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 12:28 am
by Octocontrabass
Techflash wrote:To be clear, the "unnecessary" RSP is the one on the line you highlighted, not the "userRsp" below, right?
Yes. It's one of several mistakes you copied from a tutorial. (Since there's no PUSHA/POPA in 64-bit mode, you don't even need a placeholder.)

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 12:40 am
by Techflash
Octocontrabass wrote:
Techflash wrote:To be clear, the "unnecessary" RSP is the one on the line you highlighted, not the "userRsp" below, right?
Yes. It's one of several mistakes you copied from a tutorial. (Since there's no PUSHA/POPA in 64-bit mode, you don't even need a placeholder.)
Yes, I did look at that page (for example, my ISR 17 and 21 do use the pushed error code). I just didn't catch that one.
Also I'm not sure if this push and pop asm looks correct or not... https://github.com/techflashYT/Techflas ... SRASM.S#L8 Testing now.

UPDATE: seems to crash at the "retfq":

Code: Select all

return_protected: CS selector null
interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0
interrupt(long mode): IDT entry extended attributes DWORD4 TYPE != 0
*triple faults*

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 1:12 am
by nullplan
Techflash wrote:As said previously:
Octocontrabass wrote: There's no way to encode a far JMP with a 64-bit destination in long mode, so you'll have to use something else (far RET is the usual choice).
So a far jump won't work. Still working on that part.

UPDATE: Not sure if this would work or not, but potentially:

Code: Select all

retf $0
might
Well, OK, I forgot about that. Yes, there is no direct far jump in 64-bit mode. But you can make an indirect far jump, or a far return. BTW, that is "lret" in AT&T. I have no idea what "retf" does, but not what you want for sure. In the position you have, I would encode it as this:

Code: Select all

  pushq $8       /* push CS selector to stack */
  pushq 8(%rsp)  /* now the return address from the function call */
  lretq $8       /* now return there, clearing the old return address from the stack */
Since the number 8 makes an appearance multiple times here: The 8 in the first push is actually the CS selector. In the second push, it is the offset to the return address (which was 0 before the first push). And finally, in the lretq it gives the amount to adjust the stack pointer after removing the far pointer from the stack. After the two pushes, the stack is "<return address> - 8 - <return address>", and you need to clear that all out when returning. A normal lretq without operand would leave the old return address on stack, so increase the stack pointer by another 8 before returning. Thank god I used to write assembler programs for Windows, which is how I knew of the version of return with immediate operand.

You can of course also do something like

Code: Select all

  pushq $8
  leaq 1f(%rip), %rax
  pushq %rax
  ljmpq *(%rsp)
1:
  addq $16, %rsp
But that is longer and doesn't return from the function, so you need to add that as well. Ultimately your call.

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 1:20 am
by Techflash
nullplan wrote:BTW, that is "lret" in AT&T. I have no idea what "retf" does, but not what you want for sure.
According to before, retf is just unnofficial syntax for lret.

UPDATE: It KINDA works now!
Less errors!

Code: Select all

access_read_linear(): canonical failure
17 more of those follow...
*triple faults*
Btw it's almost 1am for me I gtg. I'll read anything anyone responds with tomorrow.
UPDATE: Back. Still no idea what that error is.

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 1:42 pm
by Octocontrabass
Techflash wrote:Also I'm not sure if this push and pop asm looks correct or not...
It doesn't match your struct. On x86, the stack grows down, so you need to push the last element first.

You're also not passing a pointer to the struct, not clearing the direction flag, not using your POPALL macro, and not adjusting the stack pointer to remove the interrupt number and error code before IRETQ.
Techflash wrote:UPDATE: seems to crash at the "retfq":
Did you push appropriate values onto the stack for it to pop?

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 1:51 pm
by Techflash
Octocontrabass wrote:
Techflash wrote:Also I'm not sure if this push and pop asm looks correct or not...
It doesn't match your struct. On x86, the stack grows down, so you need to push the last element first.

You're also not passing a pointer to the struct, not clearing the direction flag, not using your POPALL macro, and not adjusting the stack pointer to remove the interrupt number and error code before IRETQ.
Techflash wrote:UPDATE: seems to crash at the "retfq":
Did you push appropriate values onto the stack for it to pop?
Alright, I did most of those now, except pass a pointer to the struct (pointers in asm are even more confusing than in C, this might take some time for me to figure out)
The changes are live now on GitHub if you want to see what I did.

UPDATE: Ok this is even more confusing than I thought. How would I get the address of the "struct" that we fill out using that PUSHALL macro? Would I just push the current address of the stack pointer before the macro?

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 1:57 pm
by Octocontrabass
Techflash wrote:except pass a pointer to the struct (pointers in asm are even more confusing than in C, this might take some time for me to figure out)
Here's a hint: the instruction you want is "mov $rsp, $rdi".
Techflash wrote:The changes are live now on GitHub if you want to see what I did.
Why did you set the direction flag right before IRETQ? It's just going to pop RFLAGS from the stack anyway, so it doesn't matter what the direction flag is at that point.

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 2:03 pm
by Techflash
Octocontrabass wrote:
Techflash wrote:except pass a pointer to the struct (pointers in asm are even more confusing than in C, this might take some time for me to figure out)
Here's a hint: the instruction you want is "mov $rsp, $rdi".
Techflash wrote:The changes are live now on GitHub if you want to see what I did.
Why did you set the direction flag right before IRETQ? It's just going to pop RFLAGS from the stack anyway, so it doesn't matter what the direction flag is at that point.
Alright, I fixed it, testing it now.

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 2:05 pm
by Octocontrabass

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 2:12 pm
by Techflash
Octocontrabass wrote:On x86, the stack grows down.
Yes. What's wrong with that instruction? It copies the stack pointer into RDI, then ISRHandler uses that pointer to view the stuff in the struct. I already reversed the order of the PUSHALL and POPALL macros to match the fact that the stack grows downwards.

Also, after updating the function to actually treat the argument as a pointer:

Code: Select all

fetch_raw_descriptor: GDT: index (f007) 1e00 > limit (27)
access_read_linear(): canonical failure
iret64: SS.rpl != CS.rpl
iret64: SS.rpl != CS.rpl
access_read_linear(): canonical failure
....
*triple fault*

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 2:18 pm
by Octocontrabass
RSP is the stack pointer. It changes as you push and pop things from the stack.

When will it point to the first element of the struct?

Re: Issues with interrupts

Posted: Sat Aug 06, 2022 2:25 pm
by Techflash
Octocontrabass wrote:RSP is the stack pointer. It changes as you push and pop things from the stack.

When will it point to the first element of the struct?
Wait now I'm confused. Yes I understand RSP stands for "Register Stack Pointer", and I get that it changes. But now my brain hurts, doesn't it always (without directly modifying it with something like add or sub), point to the next byte of the stack? Or does it always point to the last pushed item? Hang on, let me try putting the mov instruction into the macro quick, after the first push. And I'll see what happens.

UPDATE: After testing it out with that method:

Code: Select all

07589910147e[CPU0  ] fetch_raw_descriptor: GDT: index (f007) 1e00 > limit (27)
07589910207e[CPU0  ] iret64: SS.rpl != CS.rpl
*that last line repeats 53 more times*
*triple fault*
So it gives a different error this time, but still an error. It seems like it happens at the "iretq" instruction. Something about the segment registers. Not sure what the "RPL" means in this case.
UPDATE 2: Also tried it at the end of the macro too, almost same thing happens. This time it's one "access_read_linear(): canonical failure" and 55 of the "iret64: SS.rpl != CS.rpl"