OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Jun 20, 2019 2:13 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: System hangs when writing to address range
PostPosted: Mon Feb 04, 2019 1:45 am 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
I'm developing an amd64 kernel, specifically it's a multiboot2 kernel with the AMD64_EFI tag in its header so it's loaded into long mode with identity mapped paging and UEFI boot services enabled. After some setup my kernel will exit boot services and then zero all memory of types EfiBootServicesCode, EfiBootServicesData, and EfiConventionalMemory. Zeroing the memory is strictly being done to make sure that the memory is safe to trample on now to minimize unexpected issues while implementing my memory allocator and will be removed as I know it's incredibly slow on systems with large amounts of memory. One of the ranges returned is 0x3ED8A000-0x3FA1B000 with type EfiBootServicesData. Within that range any attempt to write to 0x3F000000-0x3F1FFFFF will hang the system. Addresses 0x3ED8A000-0xEFFFFFF and 0x3F200000-0x3FA1B000 can be written to without a problem. The system I'm testing on is a qemu virtual machine with OVMF as the firmware. It has 1GiB of memory. Specifically the system doesn't seem to hang so much as jump to an address outside my kernel where it stays until the system is powered off. I assume the location it's jumping to is the UEFI exception handler but that's just an educated guess. Does someone with more experience than I have any ideas of what the issue could be?


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Mon Feb 04, 2019 4:02 am 
Offline
Member
Member
User avatar

Joined: Tue Dec 27, 2011 7:57 am
Posts: 350
I suggest setting up rudimentary output (the serial port is good one -- you can tell QEMU to print it to the console) immediately after calling ExitBootServices(). More importantly however, you want to set an IDT and at least handle all the CPU exceptions and have the handler output some information (eg. RIP, CR2, etc). From what I can remember, you're not supposed to override the firmware-provided IDT until *after* exiting boot services, so it should be one of the very first things you set up.

There's very little information to go on here with what you've posted. According to my experiments, the memory type is '4', aka EfiBootServicesData. I'm not sure what's exactly in there, but I have a hunch: it could be the page tables that the firmware set up (that identity map the stuff), and you're trampling all over it without setting your own CR3 first.

At the very least having an IDT setup with proper output on CPU exceptions will let us discover what the actual problem is. Also, I do believe that you might be jumping to the UEFI exception handler (which unhelpfully prints nothing and just hangs the entire system), as I've experienced that before (actually doing anything wrongly like calling FreePool on non-pool memory will do that too... maybe it's just OVMF)

_________________
[nx] kernel: http://github.com/requimrar/nx


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Mon Feb 04, 2019 1:02 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
zhiayang wrote:
I suggest setting up rudimentary output (the serial port is good one -- you can tell QEMU to print it to the console) immediately after calling ExitBootServices(). More importantly however, you want to set an IDT and at least handle all the CPU exceptions and have the handler output some information (eg. RIP, CR2, etc). From what I can remember, you're not supposed to override the firmware-provided IDT until *after* exiting boot services, so it should be one of the very first things you set up.

There's very little information to go on here with what you've posted. According to my experiments, the memory type is '4', aka EfiBootServicesData. I'm not sure what's exactly in there, but I have a hunch: it could be the page tables that the firmware set up (that identity map the stuff), and you're trampling all over it without setting your own CR3 first.

At the very least having an IDT setup with proper output on CPU exceptions will let us discover what the actual problem is. Also, I do believe that you might be jumping to the UEFI exception handler (which unhelpfully prints nothing and just hangs the entire system), as I've experienced that before (actually doing anything wrongly like calling FreePool on non-pool memory will do that too... maybe it's just OVMF)

I actually already have a printf function that uses EFI_GOP with fonts from the HII database to print to the screen so would serial output be substantially more helpful? Also I'll try setting up an IDT and my own page table as I actually haven't done that yet but you might be right. It didn't occur to me that the page table would be in EfiBootServicesData but that's the most logical place to put it.


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Mon Feb 04, 2019 8:42 pm 
Offline
Member
Member
User avatar

Joined: Tue Dec 27, 2011 7:57 am
Posts: 350
Ah, if you already have working text output then serial won't be that useful in this case (but still useful in general!). I presumed you relied on the BootServices to print text and had not initialised your own framebuffer-based printing yet.

EDIT: actually, an easier way to verify my theory is to use the QEMU monitor, get the value of CR3, and dump the (pyhsical) memory there; your symptoms indicate the page tables are contiguously allocated, so you shouldn't need to jump around too much; if they are indeed page tables (or the value of CR3 falls in the range 0x3F000000-0x3F1FFFFF) then you know you're trampling them.

_________________
[nx] kernel: http://github.com/requimrar/nx


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Tue Feb 05, 2019 1:43 am 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
zhiayang wrote:
Ah, if you already have working text output then serial won't be that useful in this case (but still useful in general!). I presumed you relied on the BootServices to print text and had not initialised your own framebuffer-based printing yet.

EDIT: actually, an easier way to verify my theory is to use the QEMU monitor, get the value of CR3, and dump the (pyhsical) memory there; your symptoms indicate the page tables are contiguously allocated, so you shouldn't need to jump around too much; if they are indeed page tables (or the value of CR3 falls in the range 0x3F000000-0x3F1FFFFF) then you know you're trampling them.

Well it doesn't look like it's the page table. The value of CR3 is 0x3FC01000 so I suppose I'll need to setup an IDT to figure out what's actually going on.


Last edited by Scoopta on Sun Feb 10, 2019 5:20 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sat Feb 09, 2019 4:08 am 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
zhiayang wrote:
Ah, if you already have working text output then serial won't be that useful in this case (but still useful in general!). I presumed you relied on the BootServices to print text and had not initialised your own framebuffer-based printing yet.

EDIT: actually, an easier way to verify my theory is to use the QEMU monitor, get the value of CR3, and dump the (pyhsical) memory there; your symptoms indicate the page tables are contiguously allocated, so you shouldn't need to jump around too much; if they are indeed page tables (or the value of CR3 falls in the range 0x3F000000-0x3F1FFFFF) then you know you're trampling them.

Just a quick update to this. I finally got my GDT and IDT setup and writing to that address gives a page fault(interrupt 0xE) with an error code of 0b11 which is a page protection violation caused by a write. I still haven't quite tracked down exactly what's there though.


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sat Feb 09, 2019 6:31 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 421
Do you have your project online to view?


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 12:52 am 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
MichaelPetch wrote:
Do you have your project online to view?

Not currently no. I can put it up though.


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 3:05 am 
Offline
Member
Member
User avatar

Joined: Tue Dec 27, 2011 7:57 am
Posts: 350
I think putting it up somewhere would be helpful (maybe not now, but definitely in the future if you need assistance on here again). Meanwhile, the fact that the page is marked present but not writeable led me to investigate the UEFI spec, which says:

Quote:
Paging mode is enabled and any memory space defined by the UEFI memory map is identity
mapped (virtual address equals physical address), although the attributes of certain regions
may not have all read, write, and execute attributes or be unmarked for purposes of platform
protection


This is in section 2.3.4 - x64 Platforms of the UEFI spec. From my experience, the firmware does not set the WP bit in CR0, so even ring0 code cannot write to pages mapped without the PAGE_WRITE flag (0x2). Again, I have no clue what is actually in those pages (if you were able to write to the page pointed to by CR3, it’s unlike the physical page tables were mapped as read-only — so it’s probably not paging structures?).

If you wish to pursue this (I am personally quite curious what’s in there) feel free, but otherwise my current advice is: 1. just accept that the firmware marks this as read-only; 2. if you wish to set all memory to 0, do it after setting up your own page tables; 3. don’t bother zeroing all memory.

(for 3: you can do it selectively, like zeroing our stack space and memory allocated by kmalloc and your page frame allocator — you certainly don’t want to do it for all of physical memory)

_________________
[nx] kernel: http://github.com/requimrar/nx


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 11:22 am 
Offline
Member
Member
User avatar

Joined: Mon Jul 13, 2009 5:52 am
Posts: 93
Location: Rome
zhiayang wrote:
From my experience, the firmware does not set the WP bit in CR0, so even ring0 code cannot write to pages mapped without the PAGE_WRITE flag (0x2).


I believe it's the other way around. When CR0.WP is cleared, then Ring 0 is allowed to write to read-only pages.


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 1:19 pm 
Offline
Member
Member
User avatar

Joined: Tue Dec 27, 2011 7:57 am
Posts: 350
zity wrote:
zhiayang wrote:
From my experience, the firmware does not set the WP bit in CR0, so even ring0 code cannot write to pages mapped without the PAGE_WRITE flag (0x2).


I believe it's the other way around. When CR0.WP is cleared, then Ring 0 is allowed to write to read-only pages.



My bad, you’re right — firmware sets CR0.WP.

_________________
[nx] kernel: http://github.com/requimrar/nx


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 5:19 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
zhiayang wrote:
I think putting it up somewhere would be helpful (maybe not now, but definitely in the future if you need assistance on here again). Meanwhile, the fact that the page is marked present but not writeable led me to investigate the UEFI spec, which says:

Quote:
Paging mode is enabled and any memory space defined by the UEFI memory map is identity
mapped (virtual address equals physical address), although the attributes of certain regions
may not have all read, write, and execute attributes or be unmarked for purposes of platform
protection


This is in section 2.3.4 - x64 Platforms of the UEFI spec. From my experience, the firmware does not set the WP bit in CR0, so even ring0 code cannot write to pages mapped without the PAGE_WRITE flag (0x2). Again, I have no clue what is actually in those pages (if you were able to write to the page pointed to by CR3, it’s unlike the physical page tables were mapped as read-only — so it’s probably not paging structures?).

If you wish to pursue this (I am personally quite curious what’s in there) feel free, but otherwise my current advice is: 1. just accept that the firmware marks this as read-only; 2. if you wish to set all memory to 0, do it after setting up your own page tables; 3. don’t bother zeroing all memory.

(for 3: you can do it selectively, like zeroing our stack space and memory allocated by kmalloc and your page frame allocator — you certainly don’t want to do it for all of physical memory)

As I said in my original post I don't plan on zeroing all memory long term. It was just to find if there was any weird memory regions. I am also personally curious as to what's there so I do plan on pursuing this further. I will try writing to the PML4 to see if it also page faults as all I did last time was check to make sure it didn't reside in that mysterious address range. The reason my source code isn't public is because I don't usually make projects I'm not 100% sure I'll stick with public although while kernel dev is a PITA it is rather fun so I'll probably throw this up on my bitbucket(I like mercurial) and link it here after I go through and put the GPL header on all the files.


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 5:38 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
MichaelPetch wrote:
Do you have your project online to view?

Don't judge the name lol. https://bitbucket.org/Scoopta/nekos/src/default/


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Sun Feb 10, 2019 9:27 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
zhiayang wrote:
I think putting it up somewhere would be helpful (maybe not now, but definitely in the future if you need assistance on here again). Meanwhile, the fact that the page is marked present but not writeable led me to investigate the UEFI spec, which says:

Quote:
Paging mode is enabled and any memory space defined by the UEFI memory map is identity
mapped (virtual address equals physical address), although the attributes of certain regions
may not have all read, write, and execute attributes or be unmarked for purposes of platform
protection


This is in section 2.3.4 - x64 Platforms of the UEFI spec. From my experience, the firmware does not set the WP bit in CR0, so even ring0 code cannot write to pages mapped without the PAGE_WRITE flag (0x2). Again, I have no clue what is actually in those pages (if you were able to write to the page pointed to by CR3, it’s unlike the physical page tables were mapped as read-only — so it’s probably not paging structures?).

If you wish to pursue this (I am personally quite curious what’s in there) feel free, but otherwise my current advice is: 1. just accept that the firmware marks this as read-only; 2. if you wish to set all memory to 0, do it after setting up your own page tables; 3. don’t bother zeroing all memory.

(for 3: you can do it selectively, like zeroing our stack space and memory allocated by kmalloc and your page frame allocator — you certainly don’t want to do it for all of physical memory)

I tried writing to 0x3FC01000 which is the base address in CR3 << 12 and I get the same page fault with error code 0b11 and it does fall in a range with type EfiBootServicesData so maybe other paging structures show up in the earlier range I was having issues with. I'll have to traverse the entire page structure to find out though.


Top
 Profile  
 
 Post subject: Re: System hangs when writing to address range
PostPosted: Thu Feb 14, 2019 1:53 pm 
Offline

Joined: Tue Jun 13, 2017 3:17 am
Posts: 13
zhiayang wrote:
I think putting it up somewhere would be helpful (maybe not now, but definitely in the future if you need assistance on here again). Meanwhile, the fact that the page is marked present but not writeable led me to investigate the UEFI spec, which says:

Quote:
Paging mode is enabled and any memory space defined by the UEFI memory map is identity
mapped (virtual address equals physical address), although the attributes of certain regions
may not have all read, write, and execute attributes or be unmarked for purposes of platform
protection


This is in section 2.3.4 - x64 Platforms of the UEFI spec. From my experience, the firmware does not set the WP bit in CR0, so even ring0 code cannot write to pages mapped without the PAGE_WRITE flag (0x2). Again, I have no clue what is actually in those pages (if you were able to write to the page pointed to by CR3, it’s unlike the physical page tables were mapped as read-only — so it’s probably not paging structures?).

If you wish to pursue this (I am personally quite curious what’s in there) feel free, but otherwise my current advice is: 1. just accept that the firmware marks this as read-only; 2. if you wish to set all memory to 0, do it after setting up your own page tables; 3. don’t bother zeroing all memory.

(for 3: you can do it selectively, like zeroing our stack space and memory allocated by kmalloc and your page frame allocator — you certainly don’t want to do it for all of physical memory)

I'm trying to go through the page tables but I'm getting some weird results and I'm wondering if I'm actually reading them correctly. The code I'm using to read them is here https://bitbucket.org/snippets/Scoopta/qexzpy/pagingc


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Monax and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group