KVM Virtual Memory limits?

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
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

KVM Virtual Memory limits?

Post by hgoel »

Today I got to working on some elf loading.
Now in my OS, user code is loaded at virtual address 0x80000000, however there's some strange issue with testing the code.
When I map some memory to the location and attempt to copy code to it (well memset it before copying) I get a page fault at 0x80000000 apparently due to a write. Which is strange because not only do I have the entry set as writeable, I'm still in ring 0.The exact same code when relinked to load at 0x30000000 loads and runs just fine, it has the same physical page assigned to it so I doubt it's something in that part either. I also do make sure to flush the TLB after I updated the page tables.
QEMU's 'info tlb' command shows that the mapping is indeed getting through properly.
Additionally, further testing reveals that I can't access any virtual address above 0x40000000. I have PAE enabled and am in 32bit protected mode. If I disable KVM on QEMU and just use software emulation, everything works fine and I can map to any virtual address in the 4GB range.

I've looked all around on the web and can't find much information about what might be causing this. I'm thinking it might have something to do with my hardware, but that doesn't feel like it makes much sense. I have a relatively recent computer with a Haswell i7-4510.

At this point I'm out of ideas, has anyone encountered this kind of problem before? Is there likely just some small detail about PAE paging that I've been missing? My virtual memory management code is at https://github.com/himanshugoel2797/Ape ... _manager.c
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

Re: KVM Virtual Memory limits?

Post by hgoel »

I figured it out, thought I'd reply so that anyone who encounters a similar issue doesn't have the same problem.
It seems the PDPT entries need to be marked as present from the start? I'm guessing either that or a full TLB flush by writing into CR3 needs to be performed in order to properly update PDPT changes, invlpg I suppose doesn't cut it.

To be more clear, setting the PDPT entries as present before even starting paging fixed the issue.
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
User avatar
iansjack
Member
Member
Posts: 4952
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: KVM Virtual Memory limits?

Post by iansjack »

Actually, INVLPG "cuts it" more than loading CR3 does (think global bit). But you are quite correct in saying that you need to mark entries as being present before the system accepts that they are present. Makes sense really, doesn't it.
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: KVM Virtual Memory limits?

Post by Combuster »

One of the related differences is that with 32-bit PAE enabled, 8000 0000 belongs to a different top level entry than 3000 0000. Also in 32-bit PAE is that all four entries of the top-level table should be copied into the processor cache on the relevant CR* moves and not be reread on INVLPGs. In addition, QEmu is known to be written with dodgy shortcuts all over the place, and it might operate incorrectly in either mode.

So yes, modifying a live PDPT in memory requires reloading CR3 afterwards. (For the full story, see Intel 3A Ch. 4.4.1)
"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 ]
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

Re: KVM Virtual Memory limits?

Post by hgoel »

Combuster wrote:One of the related differences is that with 32-bit PAE enabled, 8000 0000 belongs to a different top level entry than 3000 0000. Also in 32-bit PAE is that all four entries of the top-level table should be copied into the processor cache on the relevant CR* moves and not be reread on INVLPGs. In addition, QEmu is known to be written with dodgy shortcuts all over the place, and it might operate incorrectly in either mode.

So yes, modifying a live PDPT in memory requires reloading CR3 afterwards. (For the full story, see Intel 3A Ch. 4.4.1)
I did read the PAE sections in the manual before asking, but I guess I missed that part. Thanks for pointing it out though.
iansjack wrote:Actually, INVLPG "cuts it" more than loading CR3 does (think global bit). But you are quite correct in saying that you need to mark entries as being present before the system accepts that they are present. Makes sense really, doesn't it.
I knew entries needed to be marked as present, what I didn't know was that PDPT entry changes need a full TLB flush. Thanks though.
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
Post Reply