Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting memory to aarch64 #701

Merged
merged 48 commits into from
Dec 16, 2022

Conversation

NathanRoyer
Copy link
Member

@NathanRoyer NathanRoyer commented Nov 22, 2022

This adds aarch64 support to the memory as well as memory_aarch64 which contains utility functions for MMU management under aarch64.

@NathanRoyer NathanRoyer marked this pull request as ready for review December 6, 2022 17:25
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things:

  1. Can you incorporate the latest changes to the source files in memory (from the main branch) into your copied versions of them in aarch64/kernel/memory/? That will make it a lot easier to see what has changed.
  2. A lot of the arch-specific things in memory have been recently improved in theseus_main so you can probably avoid or move lots of those cfg(target_arch) parts.
  3. In page_table_entry, you're directly modifying PTE flags. Instead of doing it there, move it elsewhere (e.g., into PteFlagsArch::adjust_for_higher_level_pte() or somewhere else in the PteFlagsAarch64 module). Ideally the entire page_table_entry crate would be arch-independent, and any required flags would be handled in the PteFlags<Arch> module.

aarch64/kernel/memory/src/paging/mapper.rs Outdated Show resolved Hide resolved
flags: PteFlags,
active: bool,
) -> Result<(MappedPages, AllocatedFrames), &'static str> {
// On aarch64, P4/P3/P2 should only contain valid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some new changes in the main branch should address this. I've added a function called PteFlagsArch::adjust_for_higher_level_pte() that is the proper place to set these higher_level_flags (previously called top_level_flags)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the aarch64 version of adjust_for_higher_level_pte so that it works; my implementation discards any flag set by the caller, which isn't great

aarch64/kernel/memory/src/paging/mapper.rs Outdated Show resolved Hide resolved
aarch64/kernel/memory/src/paging/table.rs Show resolved Hide resolved
}

/// Installs a page table in the TTBR CPU register
pub fn set_page_table_addr(page_table: PhysicalAddress) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I think this should be called set_as_active_page_table_root or something like that
  2. It should accept a reference to a PageTable to ensure that nobody can just directly call it with some random PhysicalAddress
  3. Add a similar function to memory_x86_64 and use it in PageTable::switch() so that the structure mimics that of aarch64

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One problem with 2: PageTable is defined in memory, which depends on memory_aarch64 and memory_x86_64; we can't use PageTable in them. I'd keep it the way it is for simplicity (I think it would be a bit cumbersome to pull PageTable from memory while keeping the rest of paging there).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, cyclic dependencies strike again. Okay, that's fine for now, we can always change it later.

aarch64/kernel/nano_core/main.rs Outdated Show resolved Hide resolved
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a comment about the adjust_higher_level_pte_flags() function on aarch64.

One major issue is that I don't want to merge in the concept of NextLevelAccess to the memory crate in the main repo. I understand this is necessary because you're currently re-using the UEFI-provided page table, but after we finish merging in support for UEFI on x86, this won't be necessary. Therefore, I don't want to merge in such wide-sweeping, intrusive changes to all of the page translation code, and then have to undo it all later.

So I think it's best to keep those changes in your /aarch64/kernel crates only. We can integrate aarch64 stuff into /kernel/memory after UEFI is complete, and that will also make it easier to implement memory in a mostly arch-agnostic manner, since I don't think most of it will need to change.

If you can remove those changes, I'm happy to accept this PR; everything else looks good.

kernel/pte_flags/src/pte_flags_aarch64.rs Outdated Show resolved Hide resolved
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the changed files seem to be identical to those in the main repo. Can you comment here which ones didn't need to change? That'll make it easier to integrate later.

I left a few other comments. Aside from that, this PR looks good.

aarch64/kernel/memory_aarch64/src/lib.rs Show resolved Hide resolved
aarch64/kernel/memory_aarch64/src/lib.rs Outdated Show resolved Hide resolved
kernel/page_table_entry/src/lib.rs Outdated Show resolved Hide resolved
kernel/page_table_entry/src/lib.rs Outdated Show resolved Hide resolved
kernel/page_table_entry/src/lib.rs Outdated Show resolved Hide resolved
Copy link
Member

@kevinaboos kevinaboos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking all good now! Thanks.

One thing for the future: the set_as_active_page_table_root() fn being both public and safe is not sound, since it allows anyone to change the root page table to any arbitrary PhysicalAddress. All other pub functions in memory_<arch> are safe to expose publicly.

There are a few easy solutions to this:

  • move memory_x86_64 and memory_aarch64 crates into modules within the memory crate and make that fn private or pub(crate)
  • move the logic back into PageTable::switch() and have arch-specific cfg blocks directly in that function
    • This is currently what I have done in this PR
  • any other idea you may have, etc

@kevinaboos kevinaboos merged commit cc62b18 into theseus-os:theseus_main Dec 16, 2022
github-actions bot pushed a commit that referenced this pull request Dec 16, 2022
* aarch64 support for basic paging configuration code, page table creation,
  populating page table entries, and switching page tables.

* Ensure that the recursive P4 table address is canonical;
  on aarch64 this means having the 16 MSBs cleared,
  on x86_64 this means the typical sign-extended canonicalization.

* Ensure MAIR profiles match the index order expected by `pte_flags`.

* Force the correct flags for the recursive P4 entry and all
  higher-level PTEs on aarch64.

* Properly handle `PAGE_DESCRIPTOR` and `ACCESSED` PTE flags
  in all aarch64 PTEs according to Theseus's expectations of
  a 48-bit virtual address and an ASID of 0.

Co-authored-by: Kevin Boos <[email protected]> cc62b18
github-actions bot pushed a commit to tsoutsman/Theseus that referenced this pull request Dec 16, 2022
* aarch64 support for basic paging configuration code, page table creation,
  populating page table entries, and switching page tables.

* Ensure that the recursive P4 table address is canonical;
  on aarch64 this means having the 16 MSBs cleared,
  on x86_64 this means the typical sign-extended canonicalization.

* Ensure MAIR profiles match the index order expected by `pte_flags`.

* Force the correct flags for the recursive P4 entry and all
  higher-level PTEs on aarch64.

* Properly handle `PAGE_DESCRIPTOR` and `ACCESSED` PTE flags
  in all aarch64 PTEs according to Theseus's expectations of
  a 48-bit virtual address and an ASID of 0.

Co-authored-by: Kevin Boos <[email protected]> cc62b18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants