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
KVM Virtual Memory limits?
- hgoel
- 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?
"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!
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
- hgoel
- 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?
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.
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!
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
Re: KVM Virtual Memory limits?
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.
- Combuster
- 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?
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)
So yes, modifying a live PDPT in memory requires reloading CR3 afterwards. (For the full story, see Intel 3A Ch. 4.4.1)
- hgoel
- 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?
I did read the PAE sections in the manual before asking, but I guess I missed that part. Thanks for pointing it out though.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 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.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.
"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!
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!