OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 12:45 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Portability of page attributes / flags
PostPosted: Wed Sep 14, 2016 3:07 am 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1110
Location: Tartu, Estonia
In my kernel design, I have a separation between different levels of memory management: There is a physical page frame allocator ("chunker", because it manages chunks of memory, think of a buddy allocator, for example), a page table manager ("pager") and then there are "users" of these managers, such as the kernel heap, process / address space creation... In the last days, I was contemplating about the portability of page attributes / flags (access rights, caching policy, dirty / accessed), and the question: How should the pager (which manages virtual to physical memory mappings) communicate these flags to its "users" in such a way, that it can be ported between different architectures? For example, I had these thoughts:

  • Expose the hardware flags to the "users" of the pager and let them pick the flags they want / need. Something like this:
    Code:
    // User of the pager

    // INC_ARCH is a macro defined in config.h, which is generated at configure time, which the target architecture is chosen.
    #include INC_ARCH(Flags.h)

    Pager::Map(virt_addr, phys_addr, PAGE_USER || PAGE_RW);

    Code:
    // arch/x86/ia32/Flags.h

    Enum PageFlags {
    // Flags such as PAGE_USER for IA32 architecture.
    }
  • Define a set of abstract page flags (something like user readable / writeable / executable, supervisor readable / writeable / executable, write-back / write-through / uncached, dirty / accessed, global...), use them as parameters / return values of pager functions and let the pager translate between these abstract flags and whatever flags are supported by the underlying hardware. (IIRC, this is the way Linux handles it.)
  • Define a set of specific, abstract memory types (user code / data, supervisor code / data, MMIO...), use them as parameters / return values of pager functions and let the pager choose appropriate flags.
  • Let the pager provide specific functions to grant / revoke access rights, enable / disable caching, query dirty / accessed status...

So, out of curiosity, which way would you choose and why? Keep in mind that there are x86 and ARM page tables, MIPS, different page table layouts and the messy PPC paging mechanism, and the users of the pager should not be concerned with any of these. For example, the heap code invoking the pager should look exactly the same on these architectures, and the pager should do all the dirty work of dealing with different paging mechanisms.

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Wed Sep 14, 2016 4:07 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

XenOS wrote:
So, out of curiosity, which way would you choose and why?


I would have "virtual types" that user-space uses; that have nothing to do with the CPU's types in the first place. For example, a page might be using the "read/write data type" (as far as user-space knows and cares), and that physical page might be mapped into the virtual address space as "read/write"; however it might also be "not present" because it's been sent to swap space, or "read-only" because it's full of zeros (and the page fault handler is doing an "allocate on write" thing), or "read-only" because it's part of a memory mapped file or the result of "fork()" (and page fault handler is doing a "copy on write" thing), or...


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Wed Sep 14, 2016 4:53 am 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1110
Location: Tartu, Estonia
Brendan wrote:
I would have "virtual types" that user-space uses; that have nothing to do with the CPU's types in the first place.

I like this idea :D This not only abstracts from the underlying hardware, but also from the way the pager implements these page types.

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Thu Sep 15, 2016 12:09 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
Have you thought about adding the count parameter? At first glance, it looks like "Pager::Map" method will be called quite many times. Different page sizes might be another issue, e.g. what requirements will be set for virt_addr and phys_addr alignments? Would it make sense if you used page indices instead of addresses?

Code:
Pager::Map(virt_page_index, phys_page_index, PAGE_USER | PAGE_RW);


There is a big disadvantage, however, because this assumes the page size is constant but perhaps this could be abstracted, e.g. always using the 4 KiB (or 8 KiB?) page size, even though the mapper could internally handle "4 KiB / 4 MiB" on x86 or "4 KiB/ 2 MiB" on x64 whenever it makes sense.

A lot of questions but no correct answers from me. :D

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Thu Sep 15, 2016 1:37 am 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1110
Location: Tartu, Estonia
Actually in my code I do have parameters both for page size and number of pager to be mapped ;) (Or rather in my design document, I haven't coded this part yet, at least not for the new version of my paging code.) I was just a bit lazy when making the forum post, so I used just the most simple call I could think of.

Another interesting thing to keep in mind is that ARM offers access level flags on a more fine-grained level than pages. You can have 4kB pages, where each 1kB subpage has different access rights.

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Thu Sep 15, 2016 3:35 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
As for the page size, it is interesting to note that UEFI embraces 4 KiB granularity in its interfaces. It does not matter after boot phases, of course, but this gives some long-term guidelines for what we could expect and rely on. What I mean is that perhaps we can rely on the assumption that at least the order of magnitude for a "granule" is something like "a few kilobytes" even in the distant future.

It is definitely interesting if an ARM-like, more fine-grained, approach becomes more common. Perhaps the only thing we can safely rely on is byte-granularity so maybe the virtual address space should be composed of "addr, size_in_bytes" areas and let the mapper handle granularities and roundings. In some (typical) cases it means "just less safe" but in some other cases it could mean "impossible".

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Thu Sep 15, 2016 4:06 am 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1110
Location: Tartu, Estonia
Antti wrote:
Perhaps the only thing we can safely rely on is byte-granularity so maybe the virtual address space should be composed of "addr, size_in_bytes" areas and let the mapper handle granularities and roundings.

That's a good point, so the mapper should rather expose a function like this:
Code:
bool Map(virt_addr, phys_addr, length_in_bytes, flags);

I also have some constexpr MinPageSize() and constexpr IsValidPageSize(log_2_number_of_bytes) exposed by the mapper, so that it's users can decide to partition their memory appropriately.

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: Portability of page attributes / flags
PostPosted: Thu Sep 15, 2016 11:24 pm 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
I am not sure whether the page size is the most on-topic detail but one note about it could be in order. We all know what happened with the disk sector size and how it effectively became a constant value. Although it is possible for users to partition their memory appropriately, it helps a lot if there really are some other sizes in use so code gets tested in practice. As a practical example (on x86 and x64), perhaps there could be a test build or a run-time flag that makes the OS use huge page sizes and everything should still work. It would be really inefficient, e.g. a lot of slack space, but the reason for that would simply be to prove robustness.

If you support many architectures from early on, this problem does not exist. :)

_________________
Undefined behavior since 2012


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 40 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