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;