Page 1 of 1

[ SOLVED ] Page fault on interrupt when using IST

Posted: Sat Feb 20, 2021 7:07 am
by austanss
I'm attempting to set up an IST for my interrupts.

I have the IST stacks set up in my TSS:

Code: Select all

void cpu::tss::tss_install(int num_cpu, uint64_t stack) {
    isr_stack = (memory::paging::allocation::request_page() + 0x1000);
    irq_stack = (memory::paging::allocation::request_page() + 0x1000);
    sgi_stack = (memory::paging::allocation::request_page() + 0x1000);


    uint64_t tss_base = (uint64_t)&s_tss_descriptors[num_cpu];
    memory::operations::memset((void *)tss_base, 0, sizeof(cpu::tss::tss_t));

    cpu::gdt::gdt_install_tss(tss_base, sizeof(cpu::tss::tss_t));

    s_tss_descriptors[num_cpu].rsp[0] = stack;
    s_tss_descriptors[num_cpu].io_map = sizeof(cpu::tss::tss_t);
    s_tss_descriptors[num_cpu].ist[0] = (uint64_t)isr_stack;
    s_tss_descriptors[num_cpu].ist[1] = (uint64_t)irq_stack;
    s_tss_descriptors[num_cpu].ist[2] = (uint64_t)sgi_stack;

    cpu::tss::load_tss(0x28);
}
And I configure my IDT to use the IST, like this:

Code: Select all

void idt_set(uint8_t number, uint64_t base, uint16_t selector, uint8_t flags) {
	/* Set Base Address */
	idt_s[number].baseLow = base & 0xFFFF;
	idt_s[number].baseMid = (base >> 16) & 0xFFFF;
	idt_s[number].baseHigh = (base >> 32) & 0xFFFFFFFF;

	/* Set Selector */
	idt_s[number].selector = selector;
	idt_s[number].flags = flags;

	/* Set IST */
	if (number < 32)
		idt_s[number].reservedIst = 1;
	else if (number < 48)
		idt_s[number].reservedIst = 2;	
	else
		idt_s[number].reservedIst = 3;

	/* Set Reserved Areas to Zero */
	idt_s[number].reserved = 0;
}
When I run it, I get a page fault on the first interrupt, error code 2 (write access | page not present), CR2=fffffffffffffff8, RSP is default kernel stack.

What am I missing?

I am pretty sure my TSS is valid, because I can switch context to/fro the kernel without the ISTs in the interrupts.

Re: Page fault on interrupt when using IST

Posted: Mon Feb 22, 2021 10:12 pm
by austanss
I still have not resolved this issue.

I did realize, though, that I needed to move the TSS initialization before the IDT, but even then, it still doesn't work.

I pushed my code to my GitHub, link in signature,

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 9:57 am
by thewrongchristian
rizxt wrote:I still have not resolved this issue.

I did realize, though, that I needed to move the TSS initialization before the IDT, but even then, it still doesn't work.

I pushed my code to my GitHub, link in signature,
Is it the same error?
rizxt wrote: When I run it, I get a page fault on the first interrupt, error code 2 (write access | page not present), CR2=fffffffffffffff8, RSP is default kernel stack.
Because that CR2 looks suspiciously like a NULL pointer used for a new RSP, which is trying to push a 64-bit value (pre-decremented to fffffffffffffff8, then page fault on write)

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 10:54 am
by austanss
thewrongchristian wrote:
rizxt wrote:I still have not resolved this issue.

I did realize, though, that I needed to move the TSS initialization before the IDT, but even then, it still doesn't work.

I pushed my code to my GitHub, link in signature,
Is it the same error?
rizxt wrote: When I run it, I get a page fault on the first interrupt, error code 2 (write access | page not present), CR2=fffffffffffffff8, RSP is default kernel stack.
Because that CR2 looks suspiciously like a NULL pointer used for a new RSP, which is trying to push a 64-bit value (pre-decremented to fffffffffffffff8, then page fault on write)
OK, so I did notice a bug here where I overrided the IST to zero after I used it... so the page fault was actually the fault of the IST not being used.

But with the IST now, I get this error:

Code: Select all

  140: v=0e e=0000 i=0 cpl=0 IP=0008:0000000000105b5b pc=0000000000105b5b SP=0010:0000000000113b98 CR2=00000010c0e00200
Where IP points to

Code: Select all

  105b5b:	4c 8d 35 42 fe ff ff 	lea    r14,[rip+0xfffffffffffffe42]        # 1059a4 <isr_common_stub>

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 12:43 pm
by thewrongchristian
rizxt wrote: But with the IST now, I get this error:

Code: Select all

  140: v=0e e=0000 i=0 cpl=0 IP=0008:0000000000105b5b pc=0000000000105b5b SP=0010:0000000000113b98 CR2=00000010c0e00200
Where IP points to

Code: Select all

  105b5b:	4c 8d 35 42 fe ff ff 	lea    r14,[rip+0xfffffffffffffe42]        # 1059a4 <isr_common_stub>
Compiling locally, I can't see this instruction sequence (debian/gcc 8.3.0). So you'll have to look up where this code lives in your binary, which function does it live in? I find objdump invaluable:

Code: Select all

$ objdump -S bin/microCORE.kernel | less 
Then just search for the above faulting code.

Skimming your code, the only references to isr_common_stub are in your interrupt handlers. Does your git repo match your current code?

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 12:55 pm
by austanss
thewrongchristian wrote:
rizxt wrote: But with the IST now, I get this error:

Code: Select all

  140: v=0e e=0000 i=0 cpl=0 IP=0008:0000000000105b5b pc=0000000000105b5b SP=0010:0000000000113b98 CR2=00000010c0e00200
Where IP points to

Code: Select all

  105b5b:	4c 8d 35 42 fe ff ff 	lea    r14,[rip+0xfffffffffffffe42]        # 1059a4 <isr_common_stub>
Compiling locally, I can't see this instruction sequence (debian/gcc 8.3.0). So you'll have to look up where this code lives in your binary, which function does it live in? I find objdump invaluable:

Code: Select all

$ objdump -S bin/microCORE.kernel | less 
Then just search for the above faulting code.

Skimming your code, the only references to isr_common_stub are in your interrupt handlers. Does your git repo match your current code?
No. But, I have updated the code to the latest. Also, make sure you are viewing the non-default branch.

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 3:33 pm
by austanss
I re-arranged interrupts.asm and now I am getting an error back when unmask IRQ 0,

so I still believe this is a stack issue.

Code: Select all

    139: v=20 e=0000 i=0 cpl=0 IP=0008:0000000000101253 pc=0000000000101253 SP=0010:0000000000114b50 env->regs[R_EAX]=00000000000000fe
RAX=00000000000000fe RBX=000000000000005b RCX=0000000000000000 RDX=0000000000000021
RSI=00000000000000fe RDI=0000000000000021 RBP=0000000000114b68 RSP=0000000000114b50
R8 =0000000000108380 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000004
R12=000000000000005b R13=000000001ea68018 R14=00000000001077f9 R15=000000001fb4c018
RIP=0000000000101253 RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000fff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0028 000000000010f0e0 00000068 00008900 DPL=0 TSS64-avl
GDT=     0000000000110000 0000007f
IDT=     00000010e0c00000 00000fff
CR0=80000033 CR2=0000000000000000 CR3=0000000000116000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000008 CCD=0000000000114b38 CCO=SUBQ    
EFER=0000000000000d00

check_exception old: 0xffffffff new 0xe
   140: v=0e e=0000 i=0 cpl=0 IP=0008:0000000000101253 pc=0000000000101253 SP=0010:0000000000114b50 CR2=00000010e0c00200
RAX=00000000000000fe RBX=000000000000005b RCX=0000000000000000 RDX=0000000000000021
RSI=00000000000000fe RDI=0000000000000021 RBP=0000000000114b68 RSP=0000000000114b50
R8 =0000000000108380 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000004
R12=000000000000005b R13=000000001ea68018 R14=00000000001077f9 R15=000000001fb4c018
RIP=0000000000101253 RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000fff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0028 000000000010f0e0 00000068 00008900 DPL=0 TSS64-avl
GDT=     0000000000110000 0000007f
IDT=     00000010e0c00000 00000fff
CR0=80000033 CR2=00000010e0c00200 CR3=0000000000116000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000008 CCD=0000000000114b38 CCO=SUBQ    
EFER=0000000000000d00

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 5:52 pm
by Octocontrabass
rizxt wrote:

Code: Select all

    139: v=20

IDT=     00000010e0c00000 00000fff

check_exception old: 0xffffffff new 0xe
   140: v=0e ... CR2=00000010e0c00200
Looks like your IDTR is filled with garbage.

Are you sure that's the right type?

Re: Page fault on interrupt when using IST

Posted: Tue Feb 23, 2021 6:35 pm
by austanss
Octocontrabass wrote:
rizxt wrote:

Code: Select all

    139: v=20

IDT=     00000010e0c00000 00000fff

check_exception old: 0xffffffff new 0xe
   140: v=0e ... CR2=00000010e0c00200
Looks like your IDTR is filled with garbage.

Are you sure that's the right type?
Wow, I can't believe the error was that simple. :facepalm:
I mix up words and dwords a bit. Thanks for your help, I would've never noticed that!