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.
I've noticed recently that my OS is using a lot of the cached entries in the TLB for paging, even after modifying the entry. I did some research and found the INVLPG instruction but I've had trouble with it.
This is my current method for mapping a physical page:
Which flushes the entire TLB. Note that this was on my old kernel, I haven't noticed page-caching problems yet on my new one. Possibly because I have yet to implement copy-on-write...
Yes, but it'll work, which is what the intention was when I wrote it. I've got a //HACK!!!! comment above it so I think I was intending to change it...
As I say, that was my last (test) kernel, I havent implemented it in my current one yet.
the manuals state that invlpg invalidates the tlb entry used when accessing the operand. For that reason, page-invalidating a register does not need to do anything.
"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 ]
__asm__ __volatile__("invlpg (%%eax)" : : "a" (address) );
"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 ]
I'm having somewhat of the same problem. I thought I was going crazy.
I've used the WRITE_CR3(READ_CR3()) suggestion as well as the INVLPG suggestion but I'm still getting errors accessing memory through its virtual address.
I've even written a test function that tests whether my physical address mapper was doing the correct thing... and it looks like it is. The corresponding PDE has the right address of the page table. The PTE in the page table has the correct address of the page. But when I try to access the page through its virtual address... 3rd (13) exception with no resolution! The value in CR2 is pointing right to the virtual address I was sure I had just mapped.
vhg119 wrote:I've even written a test function that tests whether my physical address mapper was doing the correct thing... and it looks like it is. The corresponding PDE has the right address of the page table. The PTE in the page table has the correct address of the page. But when I try to access the page through its virtual address... 3rd (13) exception with no resolution! The value in CR2 is pointing right to the virtual address I was sure I had just mapped.
Start the bochs debugger, breakpoint to the faulting instruction, then dump all registers and memory locations where the page table entries involved are stored, then copy them here. I have a nagging suspicion that it isn't the macro's that are causing you trouble.
"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 ]
vhg119 wrote:I've even written a test function that tests whether my physical address mapper was doing the correct thing... and it looks like it is. The corresponding PDE has the right address of the page table. The PTE in the page table has the correct address of the page. But when I try to access the page through its virtual address... 3rd (13) exception with no resolution! The value in CR2 is pointing right to the virtual address I was sure I had just mapped.
Start the bochs debugger, breakpoint to the faulting instruction, then dump all registers and memory locations where the page table entries involved are stored, then copy them here. I have a nagging suspicion that it isn't the macro's that are causing you trouble.
Crap... I've never used bochs with the debugger and I don't think mine is compiled with the option... (I apt-got it on Ubuntu).
Let me learn how to get the debugger working and I'll get back to you.
I'm mapping 0xA000000 to a newly allocated page. This also requires me to allocate space for a new page table, and create a new entry in the page directory.
so....
I used the last PTE in one of my existing page tables to map the page directory and new page table so that I can write data to them.
When I map the pdir to write the new page table's address, it worked fine.
Then, I used the same PTE to map in the new page table so I can map in a new physical page. This is the problem. I never invalidated the cache so when I thought I was writing to the new page table, I was actually still writing to the page directory.
I had to invalidate the cache between writing to the page dir and writing to the page table.
I hope that makes sense. Please let me know if it doesn't.
the manuals state that invlpg invalidates the tlb entry used when accessing the operand. For that reason, page-invalidating a register does not need to do anything.
These sound exactly like the sort of desperately needed tips that must go into the wiki.
I'm working with long mode page tables, so it may be different, but I certainly don't have to invalidate the tlb between writing to page directories and page tables. I do call invlpg after completing the mapping process.
If you're mapping in the physical address of the page table so you can write to it, then you'll have to call invlpg simply because you altered the page table. It makes no sense that you'd need to reload the page tables before mapping anything new though.
I think he's mapping in the page dir at a certain address, inserts the page table, then remaps that same virtual address address to the page table he just added so he can modify it. His problem was that he forgot to invlpg in-between, so he was writing to the page dir when he thought he was writing to the page table.
He's also doing it in the reversed order I would do it by the way; if I mapped the page dir and page tables in on-demand, I'd make sure to correctly initialize the page table before adding it to the page dir. But since I'm using fractal mapping it's simpler to just map the page table in and write to the correct spot in the upper 4 MB of memory...