OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 8:09 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Switching CR3 to new page directory triple faults
PostPosted: Thu Dec 02, 2021 7:56 pm 
Offline

Joined: Thu Nov 25, 2021 7:11 pm
Posts: 17
I've made a function to create a new page directory, but switching to it causes a triple fault. I copy entry 0 (and 1022) from the original, and set entry 1023 to recursive page at the copy. Somehow this doesn't work.

The code in question
Code:
uint32_t mkpdir()
{
    uint32_t pd = phys_zalloc_start();
    if(!pd) return 0;
    ((uint32_t*)TEMP_ADDR)[0] = (*MAKE_PGD_ADDR(PGD_RECURSE,0) & 0xfffff000) | 3;
    ((uint32_t*)TEMP_ADDR)[PGD_TEMP] = (*MAKE_PGD_ADDR(PGD_RECURSE,PGD_TEMP) & 0xfffff000) | 3;
    ((uint32_t*)TEMP_ADDR)[PGD_RECURSE] = pd | 3;
    asm("" ::: "memory");
    phys_zalloc_end();
    return pd;
}

The other functions and macros
Code:
#define PGD_TEMP 1022
#define PGD_RECURSE 1023
#define MAKE_PGD_ADDR(pgi, pti) ((uint32_t*)(PGD_RECURSE << 22 | pgi << 12 | pti << 2))
#define TEMP_ADDR ((void*)(PGD_TEMP << 22))
#define PAGE_SIZE 4096
uint32_t phys_zalloc_start() {
    uint32_t pg = phys_alloc();
    if (!pg) return 0;
    *MAKE_PGD_ADDR(PGD_TEMP, 0) = pg | 3;
    memset(TEMP_ADDR, 0, PAGE_SIZE);
    return pg;
}
void phys_zalloc_end() {
    *MAKE_PGD_ADDR(PGD_TEMP, 0) = 0;
    uint32_t ta=(uint32_t)TEMP_ADDR;
    asm("invlpg %0" :: "m"(ta) : "memory");
}


Top
 Profile  
 
 Post subject: Re: Switching CR3 to new page directory triple faults
PostPosted: Fri Dec 03, 2021 8:15 am 
Offline

Joined: Thu Nov 25, 2021 7:11 pm
Posts: 17
I peeked at the memory at TEMP_ADDR, and it never got written to?
I know I needed to have that asm("" ::: "memory") because GCC was reordering the statements below phys_zalloc_end(), but it looks like those statements still have no effect. They should, here's GDB's disassembly.
Code:
0x100640 <mkpdir>:           sub    $0x1c,%esp
0x100643 <mkpdir+3>:         call   0x100220 <phys_zalloc_start>
0x100648 <mkpdir+8>:         test   %eax,%eax
0x10064a <mkpdir+10>:        je     0x100698 <mkpdir+88>
0x10064c <mkpdir+12>:        mov    0xfffff000,%edx
0x100652 <mkpdir+18>:        and    $0xfffff000,%edx
0x100658 <mkpdir+24>:        or     $0x3,%edx
0x10065b <mkpdir+27>:        mov    %edx,0xff800000
0x100661 <mkpdir+33>:        mov    0xfffffff8,%edx
0x100667 <mkpdir+39>:        and    $0xfffff000,%edx
0x10066d <mkpdir+45>:        or     $0x3,%edx
0x100670 <mkpdir+48>:        mov    %edx,0xff800ff8
0x100676 <mkpdir+54>:        mov    %eax,%edx
0x100678 <mkpdir+56>:        or     $0x3,%edx
0x10067b <mkpdir+59>:        mov    %edx,0xff800ffc
0x100681 <mkpdir+65>:        movl   $0x0,0xffffe000
0x10068b <mkpdir+75>:        movl   $0xff800000,0xc(%esp)
0x100693 <mkpdir+83>:        invlpg 0xc(%esp)
0x100698 <mkpdir+88>:        add    $0x1c,%esp
0x10069b <mkpdir+91>:        ret


Top
 Profile  
 
 Post subject: Re: Switching CR3 to new page directory triple faults
PostPosted: Fri Dec 03, 2021 11:20 am 
Offline
Member
Member
User avatar

Joined: Sun Feb 18, 2007 7:28 pm
Posts: 1564
Hi,

Are we to assume then based on previous posts that this question is for switching to a new task address space and that the initial paging setup code is fine now and kernel space is in place? Or is this post still about setting up kernel space initially and paging is disabled?

_________________
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}


Top
 Profile  
 
 Post subject: Re: Switching CR3 to new page directory triple faults
PostPosted: Fri Dec 03, 2021 11:52 am 
Offline

Joined: Thu Nov 25, 2021 7:11 pm
Posts: 17
Yes, this is about switching to a new task address space, and paging is enabled.


Top
 Profile  
 
 Post subject: Re: Switching CR3 to new page directory triple faults
PostPosted: Mon Dec 06, 2021 1:58 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
sed4906h wrote:
Code:
0x100693 <mkpdir+83>:        invlpg 0xc(%esp)

That doesn't look right. Try this instead:

Code:
asm("invlpg %0" :: "m"(*(char *)TEMP_ADDR) : "memory");


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], SemrushBot [Bot] and 66 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group