Page 1 of 1

Updating TLB

Posted: Sat Sep 28, 2013 9:56 am
by nickie
Hello people. I haven't been here for a while, but in the last fre days I tough I would give osdev a second chance and I really made some progress with my OS.

However I'm stuck at the most stupid problem I have ever had...
I cannot update the tlb. Below you can see my nasm code I call from C after I make some changes in the current paging structures.
I'm becomming paranoid so can you "confirm" if this code is valid?

Code: Select all

flush_pages:
	push ebp
	mov ebp, esp
	mov eax, cr3
	mov cr3, eax
	pop ebp
	ret
Thank you.

Re: Updating TLB

Posted: Sat Sep 28, 2013 10:33 am
by Nable
1. Sorry but it seems to be a bad copy-paste. Why did you add frame-pointer operations when you don't use stack frame?
2. AFAIR, this trick flushes the whole TLB only on 80386. On later CPUs it doesn't flush information about pages with 'global' flag.
3. Complete TLB flush should be avoided as much as possible. It's better to use INVLPG for specific pages.

Re: Updating TLB

Posted: Sun Sep 29, 2013 3:47 am
by sortie
Yep. Reloading CR3 with the same value does clear the TLB (you are effectively reloading the same address space). As Nabie warns, this doesn't clear global pages, but that's the purpose of global pages: That they don't get invalidated when switching address spaces, because they are, you know, global.

Beware the topic name: On some CPUs you manually 'update' the TLB in software, while on x86 this is entirely automatic. This topic should be called 'Invalidating TLB' or 'Flushing TLB' or something.

Re: Updating TLB

Posted: Sun Sep 29, 2013 7:37 am
by nickie
Thank you all.
It seems my tables are being updated. I guess my algorithm is writing at address that is not mapped.
This is not causing fault.

Code: Select all

	void* phys = kalloc_frame();
	set_page(0x2000, phys, get_current_directory());
	int* a = 0x2000;
	*a = 10;
But this is, even if I haven't manually updated the tlb( soon, I will update it with set_page, too ):

Code: Select all

	void* phys = kalloc_frame();
	//set_page(0x2000, phys, get_current_directory());
	int* a = 0x2000;
	*a = 10;