switch to user mode fails when paging is enabled

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
UX
Posts: 15
Joined: Sun May 08, 2011 2:21 pm

switch to user mode fails when paging is enabled

Post by UX »

Hello,

I cannot switch to user mode while paging is enabled. Only then...but when it's disabled it works just fine. I have been struggling with this for a long time but cannot figure it out so I'm asking you guys for help.
Here's paging code:

Code: Select all

#include <stdint.h>
#include <print.h>
#include <compiler.h>
#include <mem.h>


#define PAGE_SIZE	4096

/* PDE */
typedef struct pde_structure {
	uint32_t present 	:	1;
	uint32_t rw		:	1;
	uint32_t us		:	1;
	uint32_t pwt		:	1;
        uint32_t pcd		:	1;
        uint32_t accessed	:	1;
        uint32_t unused		:	6;
	uint32_t address	:	20;
} pde_t;

/* PTE */
typedef struct pte_structure {
	uint32_t present	:	1;
	uint32_t rw		:	1;
	uint32_t us		:	1;
	uint32_t pwt		:	1;
	uint32_t pcd		:	1;
	uint32_t accessed	:	1;
	uint32_t dirty		:	1;
	uint32_t unused		:	5;
	uint32_t address	:	20;
} pte_t;

/* page directory */
pde_t current_pd[1024] __ALIGNED(PAGE_SIZE);

/* page table */
pte_t current_pt[1024] __ALIGNED(PAGE_SIZE);

void install_handler();

void init_paging()
{
	int i;
	uint32_t address = 0;

	memset(current_pt, 0, sizeof(current_pt));
	memset(current_pd, 0, sizeof(current_pd));

	install_handler(14, page_fault_handler);

	address = (uint32_t)&current_pt>>12;

	/* set kernel PD */
	current_pd[0].present = 1;
	current_pd[0].rw = 1;
	current_pd[0].us = 1;
	current_pd[0].address = address;

	address = 0;

	/* first 4MB identity mapped */
	for (i = 0; i != 1024; i++) {
		current_pt[i].present = 1;
		current_pt[i].rw = 1;
		current_pt[i].address = address>>12;
		address += PAGE_SIZE;
	}

	init_msg(Initializing paging);

	/*
	 * Intel, Vol 3a, ch. 19.30.3
	 */
	asm volatile("movl %0, %%eax; movl %%eax, %%cr3;"
		::"r"(&current_pd):);

	asm volatile(
		"movl %cr0, %eax;"
		"orl $0x80000000, %eax;"
		"movl %eax, %cr0;"
		"jmp 1f; 1:"
		);
}
Please, request more if needed...I red the manual over and over, but apparently I'm missing something (probably stupid).

Thank you, best regards!
UX
Posts: 15
Joined: Sun May 08, 2011 2:21 pm

Re: switch to user mode fails when paging is enabled

Post by UX »

No message, it just reboots. Tested on Qemu.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: switch to user mode fails when paging is enabled

Post by Combuster »

Have you checked that pd.us/rw/present and pt.us/rw/present are set for all pages that are directly accessed from userland? The posted code does not do that.

Also, run your OS in bochs for more helpful crash messages (and dumps).
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
UX
Posts: 15
Joined: Sun May 08, 2011 2:21 pm

Re: switch to user mode fails when paging is enabled

Post by UX »

Yes! You were right...I forgot to set US in PD. Damn, that bit cost me a lot of free time. One can never be careful enough.
[solved]

Thank you alot! Regards.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: switch to user mode fails when paging is enabled

Post by Combuster »

I didn't get the impression that a lack of effort was in place:
- he knew the point of error
- he knew the circumstances that contributed to the error
- he tried match the symptoms with information from the intel manuals.
TBH, that is more than you'd expect from the average newbie, let alone the occasional failures we have to endure.

Luckily for you that isn't his only problem as a pagefault alone should not result in a crash. And luckily for you, bochs gives pretty verbose messages for that class of problems.

@OP: that was a hint :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: switch to user mode fails when paging is enabled

Post by HugeCode »

Sorry for ressurecting 3-days-to-2-years old (or 2 beacuse of 29.2.2012, am I right?) topic.

I had same problem and this post helped me, but I'm just curious. Page Fault that didn't occur in his and also my case.
My code passes to user mode and it causes PF, because the "user" bit is set to 0. Why didn't PF occur? Is it because my PF handler is also located in page without "user" bit set? Or because interrupt entry has ring0 set?

Thanks.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: switch to user mode fails when paging is enabled

Post by Combuster »

You're looking for a very specific fact regarding the CPU. Shame on you for not reading the manual.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply