I'm trying to find the ACPI tables. My kernel maps each area and unmaps it if it can't find the RSDP. It gets only so far before it page faults in QEMU. My kernel maps the memory range F59C0h-F59E4h (size 36). (I've tried to round it up so that it maps the next power of two, but it throws a #gp. If I have it map 4096 pages all the time, the same thing happens; my kernel claims error code 7FFFFFh (according to the AMD manuals, this is a selector index).)
So, what could be causing this? Why is the system claiming a #pf when F59CFh is within the range F59C0h-F59E4h? And is there a better way of handling #gps (other than just reporting it)? I don't have program execution at the moment implemented.
Page fault when searching for ACPI tables
-
- Member
- Posts: 5575
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Page fault when searching for ACPI tables
You can only map whole pages. Does this mean you've mapped one page that covers everything from 0xF5000 to 0xF5FFF?Ethin wrote:My kernel maps the memory range F59C0h-F59E4h (size 36).
That doesn't make sense as a #GP error code, because it claims the fault is due to an external interrupt using an IDT index higher than 255.Ethin wrote:(I've tried to round it up so that it maps the next power of two, but it throws a #gp. If I have it map 4096 pages all the time, the same thing happens; my kernel claims error code 7FFFFFh (according to the AMD manuals, this is a selector index).)
If you're testing your OS on real hardware or using hardware virtualization, page fault reporting may be delayed when there's a valid entry in the TLB that hasn't been flushed yet. If it immediately reports the fault when you turn off hardware virtualization, that's why.Ethin wrote:So, what could be causing this? Why is the system claiming a #pf when F59CFh is within the range F59C0h-F59E4h?
It could also be IRQ6 if you haven't set up interrupts properly.
If your kernel is not intentionally causing #GP, there is nothing you can do besides report it and halt. (I can't think of any reason to intentionally cause #GP off the top of my head, but swapping memory to disk is an example of intentionally causing #PF.)Ethin wrote:And is there a better way of handling #gps (other than just reporting it)?
Re: Page fault when searching for ACPI tables
I'm not exactly sure. My kernel maps 4K pages up to this address. When it maps the range F59C0-F59E4, that is the explicit range it maps; it does not map 4K ranges like it does on every other search.Octocontrabass wrote:You can only map whole pages. Does this mean you've mapped one page that covers everything from 0xF5000 to 0xF5FFF?Ethin wrote:My kernel maps the memory range F59C0h-F59E4h (size 36).
That's the first error code I get. I believe the IDT is configured properly.Octocontrabass wrote:That doesn't make sense as a #GP error code, because it claims the fault is due to an external interrupt using an IDT index higher than 255.Ethin wrote:(I've tried to round it up so that it maps the next power of two, but it throws a #gp. If I have it map 4096 pages all the time, the same thing happens; my kernel claims error code 7FFFFFh (according to the AMD manuals, this is a selector index).)
I'm running this purely in Qemu, no hardware virt.Octocontrabass wrote:If you're testing your OS on real hardware or using hardware virtualization, page fault reporting may be delayed when there's a valid entry in the TLB that hasn't been flushed yet. If it immediately reports the fault when you turn off hardware virtualization, that's why.Ethin wrote:So, what could be causing this? Why is the system claiming a #pf when F59CFh is within the range F59C0h-F59E4h?
It could also be IRQ6 if you haven't set up interrupts properly.
Aha, thanks.Octocontrabass wrote:If your kernel is not intentionally causing #GP, there is nothing you can do besides report it and halt. (I can't think of any reason to intentionally cause #GP off the top of my head, but swapping memory to disk is an example of intentionally causing #PF.)Ethin wrote:And is there a better way of handling #gps (other than just reporting it)?
-
- Member
- Posts: 5575
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Page fault when searching for ACPI tables
Try "info tlb" or "info mem" in the QEMU monitor.Ethin wrote:I'm not exactly sure.
It might be time to double-check that your #GP handler reports errors correctly. For example, load a nonsense selector into a segment register and you should receive #GP with that same selector as the error code. (Note that the lowest two bits will be zero in the error code.)Ethin wrote:That's the first error code I get. I believe the IDT is configured properly.
Re: Page fault when searching for ACPI tables
I just ensured that the address was page-aligned (I had to rebuild my kernel cleanly). I also removed a "push rax" asm instruction in my #gp handler; I had that in because LLVM sometimes had a bug involving register clobbering (not precisely sure what the bug was off the top of my head) on interrupt handlers. After rebuilding my kernel cleanly, neither the page fault or the #gp happen. (Strange how that can happen...)Octocontrabass wrote:Try "info tlb" or "info mem" in the QEMU monitor.Ethin wrote:I'm not exactly sure.
It might be time to double-check that your #GP handler reports errors correctly. For example, load a nonsense selector into a segment register and you should receive #GP with that same selector as the error code. (Note that the lowest two bits will be zero in the error code.)Ethin wrote:That's the first error code I get. I believe the IDT is configured properly.
-
- Member
- Posts: 5575
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Page fault when searching for ACPI tables
Could it have been stack alignment? The System V ABI for x64 requires a 16-byte-aligned stack prior to function calls, and pushing one eight-byte register is enough to fix or break it.Ethin wrote:I also removed a "push rax" asm instruction in my #gp handler; I had that in because LLVM sometimes had a bug involving register clobbering (not precisely sure what the bug was off the top of my head) on interrupt handlers.
For interrupt handlers that intend to return, you have to preserve several registers (including RAX) and either compile your kernel with the red zone disabled or switch to another stack using the IST.
Re: Page fault when searching for ACPI tables
Most likely, though I'm not sure. Removing that asm instruction makes it return error code 0 when it does #gp. But it doesn't seem to be doing that anymore... now I'm suffering the part where I can't find the RSDP. Is there something I have to do to tell QEMU to provide me ACPI tables? According to the QEMU wiki, using -M 1.6 makes it do this, though I'm not sure how up to date the wiki is. I used -M q35 (because I'm going to proceed to PCE after this is done) but I still can't find the RSDP.
-
- Member
- Posts: 5575
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Page fault when searching for ACPI tables
Sounds like you need to add some code to realign the stack. If you're not using the IST to switch to a new stack, you don't know if the stack is aligned correctly when an interrupt occurs.Ethin wrote:Most likely, though I'm not sure.
Not that I know of. If you're using GRUB, it will tell you where to find the ACPI tables. On UEFI systems, searching for the ACPI tables won't work.Ethin wrote:Is there something I have to do to tell QEMU to provide me ACPI tables?
Re: Page fault when searching for ACPI tables
I'm on BIOS and not using Grub -- a custom bootloader (though hopefully I can switch to one that's more well-known around here). The bootloader doesn't provide me much data other than the memory map, and so I have to find the ACPI tables myself.Octocontrabass wrote:Sounds like you need to add some code to realign the stack. If you're not using the IST to switch to a new stack, you don't know if the stack is aligned correctly when an interrupt occurs.Ethin wrote:Most likely, though I'm not sure.
Not that I know of. If you're using GRUB, it will tell you where to find the ACPI tables. On UEFI systems, searching for the ACPI tables won't work.Ethin wrote:Is there something I have to do to tell QEMU to provide me ACPI tables?