Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

Feature/process #49

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Feature/process #49

wants to merge 7 commits into from

Conversation

jjgarzella
Copy link
Contributor

Add address space creation options, along with some testing and debug utilities for page tables.

Right now, the copying the higher half is optional because there is some sort of a bug in the higher half of the original p4 that we have. Code to trigger it is in the fixme.

Make a new module for creation of processes,
and in that module, create a new page table
that will become the address space for our
new process

Copy p3 entries to new p4 table

Copy the kernel (in the higher half) into
the new address space. Many memory-module
functions are made public to allow this.
Done so that the code in process can be
factored into the paging mod, removing the
necessecity for everything to be public.
Add a method that copies a table into a new frame,
copying the higher half of the entries.
Fix the copy_higher_half() method of Table
to map the table before using it

Found bug(?) in recursive mapping of original
table, put in a fixme

Add testing for copy_higher_half()

Derive a few traits to help with debugging of
entries. Also, wrote print_entries() method on
Table

Remove the now unused src/process.rs file

Finally, add the option to copy the higher half
upon creation of an InactivePageTable. This is not
default behavior because of the aforementioned bug.
@jjgarzella jjgarzella requested a review from 4e554c4c June 8, 2018 15:58
@@ -12,6 +12,7 @@ use multiboot2::ElfSection;
use memory::Frame;

/// A representation of a page table entry.
#[derive(Clone,PartialEq,Debug)]
Copy link
Contributor

Choose a reason for hiding this comment

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

How will we make sure this doesn't result in a double free?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know how it would cause a double free... can you explain?

Copy link
Contributor

Choose a reason for hiding this comment

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

An entry owns a physical frame, and when it's deallocated so is it's backing frame. If Entrys are clone, then a frame that is in use could be cloned and freed to the allocator, leading to memory corruption. There was a hack around this with Frames in phil's blog.

pub fn clone_higher_half_into<A>(&self, table: &mut Table<A>)
where A: TableLevel
{
let mut i = 0b1_0000_0000; // == 0x100 == 256
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer 1 << 8 or 0x100

"Higher half not identical to previous p4 (bottom)");
tap.assert_tap(new_p4[0b1_0000_1000] == active_p4[0b1_0000_1000],
"Higher half not identical to previous p4 (random)");
tap.assert_tap(new_p4[510] == active_p4[510],
Copy link
Contributor

Choose a reason for hiding this comment

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

The recursive mapping /should not/ be the same between table copies. If it is, then trying to modify the new table will change the old one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm all use cases, yes this is necessary. However, this is just a unit test, and the method just copies the higher half. In InactivePageTable, where this is used, it is recursively mapped properly. Technically, the function has the desired behavior and the unit test tests that. Do you think we should fold the recursive mapping functionality into here?

tap.assert_tap(new_p4[0b0_1111_1111].is_unused(),
"Lower half not zeroed on copied p4 (top of lower half)");

tap.assert_tap(new_p4[0b1_0000_0000] == active_p4[0b1_0000_0000],
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto here & below

// in this original p4 is not recursively mapped correctly.
// This code triggers that.
//
//serial_println!("About to try to map at 511th p4, 510th p3, 0th p2");
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this print statement. there is only one p4 table. Also we recurvisely map at the 510th index, not 511

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's the address in binary: 1111111111111111 | 1 1111 1111 | 1 1111 1110 | 0 0000 0000 | 1 0000 0001 | 0000 0000 0000

First, we get the last p4, then we recursively go through the p3, then we get the very first page (zero). However, through debugging I found that the 'p3' table and 'p2' tables were not identical... concluding that the p3 is not recursively mapped.

Copy link
Contributor

Choose a reason for hiding this comment

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

the p3 at 511 shouldn't be recursively mapped

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If that's true, then that's the answer to the other problems we've been having then. The 511th p3 isn't recursively mapped. When we created a new p4 from scratch, when it mapped the kernel it just created new tables at the 511th position, but when I had it copying in the old p4 entries on the higher half, it tried to map something to that non-recursively-mapped page, causing a problem. The solution is to just not copy the entries over in this situation.

//serial_println!("About to try to map at 511th p4, 510th p3, 0th p2");
//let frame = allocator.allocate_frame().unwrap();
//let page = Page::containing_address(0xffffffff80101000);
//active_table.mapper.map_to(page, frame, EntryFlags::PRESENT, &mut allocator).expect("Unable to map sample page");
Copy link
Contributor

Choose a reason for hiding this comment

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

This probably pagefaults because 0xffffffff80101000 is literally the first kernel page

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done before remap_the_kernel does anything to the pages... the original bug was that the OS was trying to remap the kernel into this page and it pagefaulted.

Copy link
Contributor

Choose a reason for hiding this comment

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

odd. If it's faulting while remapping the kernel we can't merge until that's fixed.

@4e554c4c
Copy link
Contributor

Just so we're on the same page. Are we merging this in or keeping process work on the feature/process branch?

@jjgarzella
Copy link
Contributor Author

We can merge this in. It's relatively self-contained, but there are obviously two or three outstanding issues.

src/lib.rs Outdated
@@ -106,6 +108,8 @@ pub extern "C" fn rust_main(multiboot_info_address: usize) -> ! {
println!("Try to write some things!");
vga_buffer::change_color(vga_buffer::Color::White, vga_buffer::Color::Black);

// process::create_process();

#[cfg(feature = "test")] {
run_tests();
Copy link
Contributor

Choose a reason for hiding this comment

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

Changes in lib.rs don't seem needed

@@ -12,6 +12,7 @@ use multiboot2::ElfSection;
use memory::Frame;

/// A representation of a page table entry.
#[derive(Clone,PartialEq,Debug)]
Copy link
Contributor

Choose a reason for hiding this comment

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

An entry owns a physical frame, and when it's deallocated so is it's backing frame. If Entrys are clone, then a frame that is in use could be cloned and freed to the allocator, leading to memory corruption. There was a hack around this with Frames in phil's blog.

// in this original p4 is not recursively mapped correctly.
// This code triggers that.
//
//serial_println!("About to try to map at 511th p4, 510th p3, 0th p2");
Copy link
Contributor

Choose a reason for hiding this comment

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

the p3 at 511 shouldn't be recursively mapped

//serial_println!("About to try to map at 511th p4, 510th p3, 0th p2");
//let frame = allocator.allocate_frame().unwrap();
//let page = Page::containing_address(0xffffffff80101000);
//active_table.mapper.map_to(page, frame, EntryFlags::PRESENT, &mut allocator).expect("Unable to map sample page");
Copy link
Contributor

Choose a reason for hiding this comment

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

odd. If it's faulting while remapping the kernel we can't merge until that's fixed.

use tap::TestGroup;

pub fn run() {

Copy link
Contributor

Choose a reason for hiding this comment

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

extra newline

"Higher half not identical to previous p4 (bottom)");
tap.assert_tap(new_p4[0x108] == active_p4[0x108],
"Higher half not identical to previous p4 (random)");
tap.assert_tap(new_p4[510] == active_p4[510],
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should test something like a kernel page rather than the recursive mapping because this will be overwritten when the new table is used.

Remove references to deleted process.rs

Add note about macros in lib.rs

Small visual fixes

Check kernel table instead of recursively mapped
one in tests of clone_higher_half()

Make entry not have the clone type, simply a clone
method that could be unsafe.
The recursive mapping error has been
deemed a non-issue, so the comment with
the fixme has been removed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants