Merge branch 'mapper_refactor'
This commit is contained in:
		
						commit
						9c35ed4c6b
					
				
					 10 changed files with 223 additions and 172 deletions
				
			
		| 
						 | 
					@ -59,7 +59,8 @@ pub struct DmarDrhd {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl DmarDrhd {
 | 
					impl DmarDrhd {
 | 
				
			||||||
    pub fn get(&self, active_table: &mut ActivePageTable) -> &'static mut Drhd {
 | 
					    pub fn get(&self, active_table: &mut ActivePageTable) -> &'static mut Drhd {
 | 
				
			||||||
        active_table.identity_map(Frame::containing_address(PhysicalAddress::new(self.base as usize)), entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
 | 
					        let result = active_table.identity_map(Frame::containing_address(PhysicalAddress::new(self.base as usize)), entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
 | 
				
			||||||
 | 
					        result.flush(active_table);
 | 
				
			||||||
        unsafe { &mut *(self.base as *mut Drhd) }
 | 
					        unsafe { &mut *(self.base as *mut Drhd) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,8 +52,8 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
 | 
				
			||||||
        let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
 | 
					        let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Map trampoline
 | 
					        // Map trampoline
 | 
				
			||||||
        active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
 | 
					        let result = active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
 | 
				
			||||||
        active_table.flush(trampoline_page);
 | 
					        result.flush(active_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for madt_entry in madt.iter() {
 | 
					        for madt_entry in madt.iter() {
 | 
				
			||||||
            println!("      {:?}", madt_entry);
 | 
					            println!("      {:?}", madt_entry);
 | 
				
			||||||
| 
						 | 
					@ -136,8 +136,8 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Unmap trampoline
 | 
					        // Unmap trampoline
 | 
				
			||||||
        active_table.unmap(trampoline_page);
 | 
					        let result = active_table.unmap(trampoline_page);
 | 
				
			||||||
        active_table.flush(trampoline_page);
 | 
					        result.flush(active_table);
 | 
				
			||||||
    } else if let Some(dmar) = Dmar::new(sdt) {
 | 
					    } else if let Some(dmar) = Dmar::new(sdt) {
 | 
				
			||||||
        println!(": {}: {}", dmar.addr_width, dmar.flags);
 | 
					        println!(": {}: {}", dmar.addr_width, dmar.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,8 +173,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
 | 
				
			||||||
        let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
 | 
					        let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
 | 
				
			||||||
        for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
					        for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
				
			||||||
            let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
 | 
					            let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
 | 
				
			||||||
            active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
 | 
					            let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
 | 
				
			||||||
            active_table.flush(page);
 | 
					            result.flush(active_table);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,8 +184,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
 | 
				
			||||||
            let mapped = if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() {
 | 
					            let mapped = if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() {
 | 
				
			||||||
                let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address));
 | 
					                let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address));
 | 
				
			||||||
                let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
 | 
					                let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
 | 
				
			||||||
                active_table.map_to(sdt_page, sdt_frame, entry::PRESENT | entry::NO_EXECUTE);
 | 
					                let result = active_table.map_to(sdt_page, sdt_frame, entry::PRESENT | entry::NO_EXECUTE);
 | 
				
			||||||
                active_table.flush(sdt_page);
 | 
					                result.flush(active_table);
 | 
				
			||||||
                true
 | 
					                true
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                false
 | 
					                false
 | 
				
			||||||
| 
						 | 
					@ -198,8 +198,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
 | 
				
			||||||
            drop(sdt);
 | 
					            drop(sdt);
 | 
				
			||||||
            if mapped {
 | 
					            if mapped {
 | 
				
			||||||
                let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
 | 
					                let sdt_page = Page::containing_address(VirtualAddress::new(sdt_address));
 | 
				
			||||||
                active_table.unmap(sdt_page);
 | 
					                let result = active_table.unmap(sdt_page);
 | 
				
			||||||
                active_table.flush(sdt_page);
 | 
					                result.flush(active_table);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,8 +236,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) -> Option<Acpi> {
 | 
				
			||||||
        let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
 | 
					        let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
 | 
				
			||||||
        for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
					        for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
				
			||||||
            let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
 | 
					            let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
 | 
				
			||||||
            active_table.unmap(page);
 | 
					            let result = active_table.unmap(page);
 | 
				
			||||||
            active_table.flush(page);
 | 
					            result.flush(active_table);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,8 @@ impl LocalApic {
 | 
				
			||||||
        if ! self.x2 {
 | 
					        if ! self.x2 {
 | 
				
			||||||
            let page = Page::containing_address(VirtualAddress::new(self.address));
 | 
					            let page = Page::containing_address(VirtualAddress::new(self.address));
 | 
				
			||||||
            let frame = Frame::containing_address(PhysicalAddress::new(self.address - ::KERNEL_OFFSET));
 | 
					            let frame = Frame::containing_address(PhysicalAddress::new(self.address - ::KERNEL_OFFSET));
 | 
				
			||||||
            active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
 | 
					            let result = active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
 | 
				
			||||||
 | 
					            result.flush(active_table);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.init_ap();
 | 
					        self.init_ap();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
//! Architecture support for x86_64
 | 
					//! Architecture support for x86_64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#![deny(unused_must_use)]
 | 
				
			||||||
#![feature(asm)]
 | 
					#![feature(asm)]
 | 
				
			||||||
#![feature(concat_idents)]
 | 
					#![feature(concat_idents)]
 | 
				
			||||||
#![feature(const_fn)]
 | 
					#![feature(const_fn)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,81 @@
 | 
				
			||||||
 | 
					use core::mem;
 | 
				
			||||||
use core::ptr::Unique;
 | 
					use core::ptr::Unique;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use memory::{allocate_frame, deallocate_frame, Frame};
 | 
					use memory::{allocate_frame, deallocate_frame, Frame};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{Page, PAGE_SIZE, PhysicalAddress, VirtualAddress};
 | 
					use super::{ActivePageTable, Page, PAGE_SIZE, PhysicalAddress, VirtualAddress};
 | 
				
			||||||
use super::entry::{self, EntryFlags};
 | 
					use super::entry::{self, EntryFlags};
 | 
				
			||||||
use super::table::{self, Table, Level4};
 | 
					use super::table::{self, Table, Level4};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// In order to enforce correct paging operations in the kernel, these types
 | 
				
			||||||
 | 
					/// are returned on any mapping operation to get the code involved to specify
 | 
				
			||||||
 | 
					/// how it intends to flush changes to a page table
 | 
				
			||||||
 | 
					#[must_use = "The page table must be flushed, or the changes unsafely ignored"]
 | 
				
			||||||
 | 
					pub struct MapperFlush(Page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl MapperFlush {
 | 
				
			||||||
 | 
					    /// Create a new page flush promise
 | 
				
			||||||
 | 
					    pub fn new(page: Page) -> MapperFlush {
 | 
				
			||||||
 | 
					        MapperFlush(page)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Flush this page in the active table
 | 
				
			||||||
 | 
					    pub fn flush(self, table: &mut ActivePageTable) {
 | 
				
			||||||
 | 
					        table.flush(self.0);
 | 
				
			||||||
 | 
					        mem::forget(self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Ignore the flush. This is unsafe, and a reason should be provided for use
 | 
				
			||||||
 | 
					    pub unsafe fn ignore(self) {
 | 
				
			||||||
 | 
					        mem::forget(self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A flush cannot be dropped, it must be consumed
 | 
				
			||||||
 | 
					impl Drop for MapperFlush {
 | 
				
			||||||
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
 | 
					        panic!("Mapper flush was not utilized");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// To allow for combining multiple flushes into one, we have a way of flushing
 | 
				
			||||||
 | 
					/// the active table, which can consume MapperFlush structs
 | 
				
			||||||
 | 
					#[must_use = "The page table must be flushed, or the changes unsafely ignored"]
 | 
				
			||||||
 | 
					pub struct MapperFlushAll(bool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl MapperFlushAll {
 | 
				
			||||||
 | 
					    /// Create a new promise to flush all mappings
 | 
				
			||||||
 | 
					    pub fn new() -> MapperFlushAll {
 | 
				
			||||||
 | 
					        MapperFlushAll(false)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Consume a single page flush
 | 
				
			||||||
 | 
					    pub fn consume(&mut self, flush: MapperFlush) {
 | 
				
			||||||
 | 
					        self.0 = true;
 | 
				
			||||||
 | 
					        mem::forget(flush);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Flush the active page table
 | 
				
			||||||
 | 
					    pub fn flush(self, table: &mut ActivePageTable) {
 | 
				
			||||||
 | 
					        if self.0 {
 | 
				
			||||||
 | 
					            table.flush_all();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        mem::forget(self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Ignore the flush. This is unsafe, and a reason should be provided for use
 | 
				
			||||||
 | 
					    pub unsafe fn ignore(self) {
 | 
				
			||||||
 | 
					        mem::forget(self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A flush cannot be dropped, it must be consumed
 | 
				
			||||||
 | 
					impl Drop for MapperFlushAll {
 | 
				
			||||||
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
 | 
					        panic!("Mapper flush all was not utilized");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Mapper {
 | 
					pub struct Mapper {
 | 
				
			||||||
    p4: Unique<Table<Level4>>,
 | 
					    p4: Unique<Table<Level4>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -27,7 +97,7 @@ impl Mapper {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Map a page to a frame
 | 
					    /// Map a page to a frame
 | 
				
			||||||
    pub fn map_to(&mut self, page: Page, frame: Frame, flags: EntryFlags) {
 | 
					    pub fn map_to(&mut self, page: Page, frame: Frame, flags: EntryFlags) -> MapperFlush {
 | 
				
			||||||
        let mut p3 = self.p4_mut().next_table_create(page.p4_index());
 | 
					        let mut p3 = self.p4_mut().next_table_create(page.p4_index());
 | 
				
			||||||
        let mut p2 = p3.next_table_create(page.p3_index());
 | 
					        let mut p2 = p3.next_table_create(page.p3_index());
 | 
				
			||||||
        let mut p1 = p2.next_table_create(page.p2_index());
 | 
					        let mut p1 = p2.next_table_create(page.p2_index());
 | 
				
			||||||
| 
						 | 
					@ -38,31 +108,33 @@ impl Mapper {
 | 
				
			||||||
            p1[page.p1_index()].address().get(), p1[page.p1_index()].flags(),
 | 
					            p1[page.p1_index()].address().get(), p1[page.p1_index()].flags(),
 | 
				
			||||||
            frame.start_address().get(), flags);
 | 
					            frame.start_address().get(), flags);
 | 
				
			||||||
        p1[page.p1_index()].set(frame, flags | entry::PRESENT);
 | 
					        p1[page.p1_index()].set(frame, flags | entry::PRESENT);
 | 
				
			||||||
 | 
					        MapperFlush::new(page)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Map a page to the next free frame
 | 
					    /// Map a page to the next free frame
 | 
				
			||||||
    pub fn map(&mut self, page: Page, flags: EntryFlags) {
 | 
					    pub fn map(&mut self, page: Page, flags: EntryFlags) -> MapperFlush {
 | 
				
			||||||
        let frame = allocate_frame().expect("out of frames");
 | 
					        let frame = allocate_frame().expect("out of frames");
 | 
				
			||||||
        self.map_to(page, frame, flags)
 | 
					        self.map_to(page, frame, flags)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Update flags for a page
 | 
					    /// Update flags for a page
 | 
				
			||||||
    pub fn remap(&mut self, page: Page, flags: EntryFlags) {
 | 
					    pub fn remap(&mut self, page: Page, flags: EntryFlags) -> MapperFlush {
 | 
				
			||||||
        let mut p3 = self.p4_mut().next_table_mut(page.p4_index()).expect("failed to remap: no p3");
 | 
					        let mut p3 = self.p4_mut().next_table_mut(page.p4_index()).expect("failed to remap: no p3");
 | 
				
			||||||
        let mut p2 = p3.next_table_mut(page.p3_index()).expect("failed to remap: no p2");
 | 
					        let mut p2 = p3.next_table_mut(page.p3_index()).expect("failed to remap: no p2");
 | 
				
			||||||
        let mut p1 = p2.next_table_mut(page.p2_index()).expect("failed to remap: no p1");
 | 
					        let mut p1 = p2.next_table_mut(page.p2_index()).expect("failed to remap: no p1");
 | 
				
			||||||
        let frame = p1[page.p1_index()].pointed_frame().expect("failed to remap: not mapped");
 | 
					        let frame = p1[page.p1_index()].pointed_frame().expect("failed to remap: not mapped");
 | 
				
			||||||
        p1[page.p1_index()].set(frame, flags | entry::PRESENT);
 | 
					        p1[page.p1_index()].set(frame, flags | entry::PRESENT);
 | 
				
			||||||
 | 
					        MapperFlush::new(page)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Identity map a frame
 | 
					    /// Identity map a frame
 | 
				
			||||||
    pub fn identity_map(&mut self, frame: Frame, flags: EntryFlags) {
 | 
					    pub fn identity_map(&mut self, frame: Frame, flags: EntryFlags) -> MapperFlush {
 | 
				
			||||||
        let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
 | 
					        let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
 | 
				
			||||||
        self.map_to(page, frame, flags)
 | 
					        self.map_to(page, frame, flags)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Unmap a page
 | 
					    /// Unmap a page
 | 
				
			||||||
    pub fn unmap(&mut self, page: Page) {
 | 
					    pub fn unmap(&mut self, page: Page) -> MapperFlush {
 | 
				
			||||||
        let p1 = self.p4_mut()
 | 
					        let p1 = self.p4_mut()
 | 
				
			||||||
                     .next_table_mut(page.p4_index())
 | 
					                     .next_table_mut(page.p4_index())
 | 
				
			||||||
                     .and_then(|p3| p3.next_table_mut(page.p3_index()))
 | 
					                     .and_then(|p3| p3.next_table_mut(page.p3_index()))
 | 
				
			||||||
| 
						 | 
					@ -72,10 +144,11 @@ impl Mapper {
 | 
				
			||||||
        p1[page.p1_index()].set_unused();
 | 
					        p1[page.p1_index()].set_unused();
 | 
				
			||||||
        // TODO free p(1,2,3) table if empty
 | 
					        // TODO free p(1,2,3) table if empty
 | 
				
			||||||
        deallocate_frame(frame);
 | 
					        deallocate_frame(frame);
 | 
				
			||||||
 | 
					        MapperFlush::new(page)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Unmap a page, return frame without free
 | 
					    /// Unmap a page, return frame without free
 | 
				
			||||||
    pub fn unmap_return(&mut self, page: Page) -> Frame {
 | 
					    pub fn unmap_return(&mut self, page: Page) -> (MapperFlush, Frame) {
 | 
				
			||||||
        let p1 = self.p4_mut()
 | 
					        let p1 = self.p4_mut()
 | 
				
			||||||
                     .next_table_mut(page.p4_index())
 | 
					                     .next_table_mut(page.p4_index())
 | 
				
			||||||
                     .and_then(|p3| p3.next_table_mut(page.p3_index()))
 | 
					                     .and_then(|p3| p3.next_table_mut(page.p3_index()))
 | 
				
			||||||
| 
						 | 
					@ -83,7 +156,7 @@ impl Mapper {
 | 
				
			||||||
                     .expect("unmap_return does not support huge pages");
 | 
					                     .expect("unmap_return does not support huge pages");
 | 
				
			||||||
        let frame = p1[page.p1_index()].pointed_frame().unwrap();
 | 
					        let frame = p1[page.p1_index()].pointed_frame().unwrap();
 | 
				
			||||||
        p1[page.p1_index()].set_unused();
 | 
					        p1[page.p1_index()].set_unused();
 | 
				
			||||||
        frame
 | 
					        (MapperFlush::new(page), frame)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn translate_page(&self, page: Page) -> Option<Frame> {
 | 
					    pub fn translate_page(&self, page: Page) -> Option<Frame> {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,52 +118,56 @@ pub unsafe fn init(cpu_id: usize, stack_start: usize, stack_end: usize) -> (Acti
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    active_table.with(&mut new_table, &mut temporary_page, |mapper| {
 | 
					    active_table.with(&mut new_table, &mut temporary_page, |mapper| {
 | 
				
			||||||
 | 
					        // Map tdata and tbss
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Map tdata and tbss
 | 
					            let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let start = ::KERNEL_PERCPU_OFFSET + ::KERNEL_PERCPU_SIZE * cpu_id;
 | 
					            let start = ::KERNEL_PERCPU_OFFSET + ::KERNEL_PERCPU_SIZE * cpu_id;
 | 
				
			||||||
                let end = start + size;
 | 
					            let end = start + size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let start_page = Page::containing_address(VirtualAddress::new(start));
 | 
					            let start_page = Page::containing_address(VirtualAddress::new(start));
 | 
				
			||||||
                let end_page = Page::containing_address(VirtualAddress::new(end - 1));
 | 
					            let end_page = Page::containing_address(VirtualAddress::new(end - 1));
 | 
				
			||||||
                for page in Page::range_inclusive(start_page, end_page) {
 | 
					            for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                    mapper.map(page, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
					                let result = mapper.map(page, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
				
			||||||
 | 
					                // The flush can be ignored as this is not the active table. See later active_table.switch
 | 
				
			||||||
 | 
					                unsafe { result.ignore(); }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut remap = |start: usize, end: usize, flags: EntryFlags| {
 | 
				
			||||||
 | 
					            if end > start {
 | 
				
			||||||
 | 
					                let start_frame = Frame::containing_address(PhysicalAddress::new(start));
 | 
				
			||||||
 | 
					                let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
 | 
				
			||||||
 | 
					                for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
				
			||||||
 | 
					                    let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET));
 | 
				
			||||||
 | 
					                    let result = mapper.map_to(page, frame, flags);
 | 
				
			||||||
 | 
					                    // The flush can be ignored as this is not the active table. See later active_table.switch
 | 
				
			||||||
 | 
					                    unsafe { result.ignore(); }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let mut remap = |start: usize, end: usize, flags: EntryFlags| {
 | 
					        // Remap stack writable, no execute
 | 
				
			||||||
                if end > start {
 | 
					        remap(stack_start - ::KERNEL_OFFSET, stack_end - ::KERNEL_OFFSET, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
				
			||||||
                    let start_frame = Frame::containing_address(PhysicalAddress::new(start));
 | 
					 | 
				
			||||||
                    let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
 | 
					 | 
				
			||||||
                    for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
					 | 
				
			||||||
                        let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET));
 | 
					 | 
				
			||||||
                        mapper.map_to(page, frame, flags);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Remap stack writable, no execute
 | 
					        // Remap a section with `flags`
 | 
				
			||||||
            remap(stack_start - ::KERNEL_OFFSET, stack_end - ::KERNEL_OFFSET, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
					        let mut remap_section = |start: &u8, end: &u8, flags: EntryFlags| {
 | 
				
			||||||
 | 
					            remap(start as *const _ as usize - ::KERNEL_OFFSET, end as *const _ as usize - ::KERNEL_OFFSET, flags);
 | 
				
			||||||
            // Remap a section with `flags`
 | 
					        };
 | 
				
			||||||
            let mut remap_section = |start: &u8, end: &u8, flags: EntryFlags| {
 | 
					        // Remap text read-only
 | 
				
			||||||
                remap(start as *const _ as usize - ::KERNEL_OFFSET, end as *const _ as usize - ::KERNEL_OFFSET, flags);
 | 
					        remap_section(& __text_start, & __text_end, PRESENT | GLOBAL);
 | 
				
			||||||
            };
 | 
					        // Remap rodata read-only, no execute
 | 
				
			||||||
            // Remap text read-only
 | 
					        remap_section(& __rodata_start, & __rodata_end, PRESENT | GLOBAL | NO_EXECUTE);
 | 
				
			||||||
            remap_section(& __text_start, & __text_end, PRESENT | GLOBAL);
 | 
					        // Remap data writable, no execute
 | 
				
			||||||
            // Remap rodata read-only, no execute
 | 
					        remap_section(& __data_start, & __data_end, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
				
			||||||
            remap_section(& __rodata_start, & __rodata_end, PRESENT | GLOBAL | NO_EXECUTE);
 | 
					        // Remap tdata master writable, no execute
 | 
				
			||||||
            // Remap data writable, no execute
 | 
					        remap_section(& __tdata_start, & __tdata_end, PRESENT | GLOBAL | NO_EXECUTE);
 | 
				
			||||||
            remap_section(& __data_start, & __data_end, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
					        // Remap bss writable, no execute
 | 
				
			||||||
            // Remap tdata master writable, no execute
 | 
					        remap_section(& __bss_start, & __bss_end, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
				
			||||||
            remap_section(& __tdata_start, & __tdata_end, PRESENT | GLOBAL | NO_EXECUTE);
 | 
					 | 
				
			||||||
            // Remap bss writable, no execute
 | 
					 | 
				
			||||||
            remap_section(& __bss_start, & __bss_end, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This switches the active table, which is setup by the bootloader, to a correct table
 | 
				
			||||||
 | 
					    // setup by the lambda above. This will also flush the TLB
 | 
				
			||||||
    active_table.switch(new_table);
 | 
					    active_table.switch(new_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (active_table, init_tcb(cpu_id))
 | 
					    (active_table, init_tcb(cpu_id))
 | 
				
			||||||
| 
						 | 
					@ -200,7 +204,9 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
 | 
				
			||||||
            let start_page = Page::containing_address(VirtualAddress::new(start));
 | 
					            let start_page = Page::containing_address(VirtualAddress::new(start));
 | 
				
			||||||
            let end_page = Page::containing_address(VirtualAddress::new(end - 1));
 | 
					            let end_page = Page::containing_address(VirtualAddress::new(end - 1));
 | 
				
			||||||
            for page in Page::range_inclusive(start_page, end_page) {
 | 
					            for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                mapper.map(page, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
					                let result = mapper.map(page, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
				
			||||||
 | 
					                // The flush can be ignored as this is not the active table. See later active_table.switch
 | 
				
			||||||
 | 
					                unsafe { result.ignore(); }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -210,7 +216,9 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
 | 
				
			||||||
                let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
 | 
					                let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
 | 
				
			||||||
                for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
					                for frame in Frame::range_inclusive(start_frame, end_frame) {
 | 
				
			||||||
                    let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET));
 | 
					                    let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET));
 | 
				
			||||||
                    mapper.map_to(page, frame, flags);
 | 
					                    let result = mapper.map_to(page, frame, flags);
 | 
				
			||||||
 | 
					                    // The flush can be ignored as this is not the active table. See later active_table.switch
 | 
				
			||||||
 | 
					                    unsafe { result.ignore(); }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -219,6 +227,8 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
 | 
				
			||||||
        remap(stack_start - ::KERNEL_OFFSET, stack_end - ::KERNEL_OFFSET, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
					        remap(stack_start - ::KERNEL_OFFSET, stack_end - ::KERNEL_OFFSET, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This switches the active table, which is setup by the bootloader, to a correct table
 | 
				
			||||||
 | 
					    // setup by the lambda above. This will also flush the TLB
 | 
				
			||||||
    active_table.switch(new_table);
 | 
					    active_table.switch(new_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init_tcb(cpu_id)
 | 
					    init_tcb(cpu_id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,8 @@ impl TemporaryPage {
 | 
				
			||||||
    /// Returns the start address of the temporary page.
 | 
					    /// Returns the start address of the temporary page.
 | 
				
			||||||
    pub fn map(&mut self, frame: Frame, flags: EntryFlags, active_table: &mut ActivePageTable) -> VirtualAddress {
 | 
					    pub fn map(&mut self, frame: Frame, flags: EntryFlags, active_table: &mut ActivePageTable) -> VirtualAddress {
 | 
				
			||||||
        assert!(active_table.translate_page(self.page).is_none(), "temporary page is already mapped");
 | 
					        assert!(active_table.translate_page(self.page).is_none(), "temporary page is already mapped");
 | 
				
			||||||
        active_table.map_to(self.page, frame, flags);
 | 
					        let result = active_table.map_to(self.page, frame, flags);
 | 
				
			||||||
 | 
					        result.flush(active_table);
 | 
				
			||||||
        self.page.start_address()
 | 
					        self.page.start_address()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +39,7 @@ impl TemporaryPage {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Unmaps the temporary page in the active table.
 | 
					    /// Unmaps the temporary page in the active table.
 | 
				
			||||||
    pub fn unmap(&mut self, active_table: &mut ActivePageTable) {
 | 
					    pub fn unmap(&mut self, active_table: &mut ActivePageTable) {
 | 
				
			||||||
        active_table.unmap(self.page)
 | 
					        let result = active_table.unmap(self.page);
 | 
				
			||||||
 | 
					        result.flush(active_table);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ use idt;
 | 
				
			||||||
use interrupt;
 | 
					use interrupt;
 | 
				
			||||||
use memory;
 | 
					use memory;
 | 
				
			||||||
use paging::{self, entry, Page, VirtualAddress};
 | 
					use paging::{self, entry, Page, VirtualAddress};
 | 
				
			||||||
 | 
					use paging::mapper::MapperFlushAll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Test of zero values in BSS.
 | 
					/// Test of zero values in BSS.
 | 
				
			||||||
static BSS_TEST_ZERO: usize = 0;
 | 
					static BSS_TEST_ZERO: usize = 0;
 | 
				
			||||||
| 
						 | 
					@ -97,13 +98,18 @@ pub unsafe extern fn kstart() -> ! {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Setup kernel heap
 | 
					        // Setup kernel heap
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Map heap pages
 | 
					            // Map heap pages
 | 
				
			||||||
            let heap_start_page = Page::containing_address(VirtualAddress::new(::KERNEL_HEAP_OFFSET));
 | 
					            let heap_start_page = Page::containing_address(VirtualAddress::new(::KERNEL_HEAP_OFFSET));
 | 
				
			||||||
            let heap_end_page = Page::containing_address(VirtualAddress::new(::KERNEL_HEAP_OFFSET + ::KERNEL_HEAP_SIZE-1));
 | 
					            let heap_end_page = Page::containing_address(VirtualAddress::new(::KERNEL_HEAP_OFFSET + ::KERNEL_HEAP_SIZE-1));
 | 
				
			||||||
            for page in Page::range_inclusive(heap_start_page, heap_end_page) {
 | 
					            for page in Page::range_inclusive(heap_start_page, heap_end_page) {
 | 
				
			||||||
                active_table.map(page, entry::PRESENT | entry::GLOBAL | entry::WRITABLE | entry::NO_EXECUTE);
 | 
					                let result = active_table.map(page, entry::PRESENT | entry::GLOBAL | entry::WRITABLE | entry::NO_EXECUTE);
 | 
				
			||||||
 | 
					                flush_all.consume(result);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            flush_all.flush(&mut active_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Init the allocator
 | 
					            // Init the allocator
 | 
				
			||||||
            allocator::init(::KERNEL_HEAP_OFFSET, ::KERNEL_HEAP_SIZE);
 | 
					            allocator::init(::KERNEL_HEAP_OFFSET, ::KERNEL_HEAP_SIZE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ use spin::Mutex;
 | 
				
			||||||
use arch::memory::Frame;
 | 
					use arch::memory::Frame;
 | 
				
			||||||
use arch::paging::{ActivePageTable, InactivePageTable, Page, PageIter, PhysicalAddress, VirtualAddress};
 | 
					use arch::paging::{ActivePageTable, InactivePageTable, Page, PageIter, PhysicalAddress, VirtualAddress};
 | 
				
			||||||
use arch::paging::entry::{self, EntryFlags};
 | 
					use arch::paging::entry::{self, EntryFlags};
 | 
				
			||||||
 | 
					use arch::paging::mapper::MapperFlushAll;
 | 
				
			||||||
use arch::paging::temporary_page::TemporaryPage;
 | 
					use arch::paging::temporary_page::TemporaryPage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
| 
						 | 
					@ -20,19 +21,17 @@ impl Grant {
 | 
				
			||||||
    pub fn physmap(from: PhysicalAddress, to: VirtualAddress, size: usize, flags: EntryFlags) -> Grant {
 | 
					    pub fn physmap(from: PhysicalAddress, to: VirtualAddress, size: usize, flags: EntryFlags) -> Grant {
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut flush_all = false;
 | 
					        let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let start_page = Page::containing_address(to);
 | 
					        let start_page = Page::containing_address(to);
 | 
				
			||||||
        let end_page = Page::containing_address(VirtualAddress::new(to.get() + size - 1));
 | 
					        let end_page = Page::containing_address(VirtualAddress::new(to.get() + size - 1));
 | 
				
			||||||
        for page in Page::range_inclusive(start_page, end_page) {
 | 
					        for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
            let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get() - to.get() + from.get()));
 | 
					            let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get() - to.get() + from.get()));
 | 
				
			||||||
            active_table.map_to(page, frame, flags);
 | 
					            let result = active_table.map_to(page, frame, flags);
 | 
				
			||||||
            flush_all = true;
 | 
					            flush_all.consume(result);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if flush_all {
 | 
					        flush_all.flush(&mut active_table);
 | 
				
			||||||
            active_table.flush_all();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Grant {
 | 
					        Grant {
 | 
				
			||||||
            start: to,
 | 
					            start: to,
 | 
				
			||||||
| 
						 | 
					@ -59,7 +58,9 @@ impl Grant {
 | 
				
			||||||
            let end_page = Page::containing_address(VirtualAddress::new(to.get() + size - 1));
 | 
					            let end_page = Page::containing_address(VirtualAddress::new(to.get() + size - 1));
 | 
				
			||||||
            for page in Page::range_inclusive(start_page, end_page) {
 | 
					            for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                let frame = frames.pop_front().expect("grant did not find enough frames");
 | 
					                let frame = frames.pop_front().expect("grant did not find enough frames");
 | 
				
			||||||
                mapper.map_to(page, frame, flags);
 | 
					                let result = mapper.map_to(page, frame, flags);
 | 
				
			||||||
 | 
					                // Ignore result due to mapping on inactive table
 | 
				
			||||||
 | 
					                unsafe { result.ignore(); }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,18 +89,16 @@ impl Grant {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut flush_all = false;
 | 
					        let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let start_page = Page::containing_address(self.start);
 | 
					        let start_page = Page::containing_address(self.start);
 | 
				
			||||||
        let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
 | 
					        let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
 | 
				
			||||||
        for page in Page::range_inclusive(start_page, end_page) {
 | 
					        for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
            active_table.unmap_return(page);
 | 
					            let (result, _frame) = active_table.unmap_return(page);
 | 
				
			||||||
            flush_all = true;
 | 
					            flush_all.consume(result);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if flush_all {
 | 
					        flush_all.flush(&mut active_table);
 | 
				
			||||||
            active_table.flush_all();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.mapped = false;
 | 
					        self.mapped = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -113,7 +112,9 @@ impl Grant {
 | 
				
			||||||
            let start_page = Page::containing_address(self.start);
 | 
					            let start_page = Page::containing_address(self.start);
 | 
				
			||||||
            let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
 | 
					            let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
 | 
				
			||||||
            for page in Page::range_inclusive(start_page, end_page) {
 | 
					            for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                mapper.unmap_return(page);
 | 
					                let (result, _frame) = mapper.unmap_return(page);
 | 
				
			||||||
 | 
					                // This is not the active table, so the flush can be ignored
 | 
				
			||||||
 | 
					                unsafe { result.ignore(); }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,14 +165,14 @@ pub struct Memory {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Memory {
 | 
					impl Memory {
 | 
				
			||||||
    pub fn new(start: VirtualAddress, size: usize, flags: EntryFlags, flush: bool, clear: bool) -> Self {
 | 
					    pub fn new(start: VirtualAddress, size: usize, flags: EntryFlags, clear: bool) -> Self {
 | 
				
			||||||
        let mut memory = Memory {
 | 
					        let mut memory = Memory {
 | 
				
			||||||
            start: start,
 | 
					            start: start,
 | 
				
			||||||
            size: size,
 | 
					            size: size,
 | 
				
			||||||
            flags: flags
 | 
					            flags: flags
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        memory.map(flush, clear);
 | 
					        memory.map(clear);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        memory
 | 
					        memory
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -198,150 +199,114 @@ impl Memory {
 | 
				
			||||||
        Page::range_inclusive(start_page, end_page)
 | 
					        Page::range_inclusive(start_page, end_page)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn map(&mut self, flush: bool, clear: bool) {
 | 
					    fn map(&mut self, clear: bool) {
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut flush_all = false;
 | 
					        let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //TODO: Clear pages?
 | 
					 | 
				
			||||||
        for page in self.pages() {
 | 
					        for page in self.pages() {
 | 
				
			||||||
            active_table.map(page, self.flags);
 | 
					            let result = active_table.map(page, self.flags);
 | 
				
			||||||
 | 
					            flush_all.consume(result);
 | 
				
			||||||
            if flush {
 | 
					 | 
				
			||||||
                //active_table.flush(page);
 | 
					 | 
				
			||||||
                flush_all = true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if flush_all {
 | 
					        flush_all.flush(&mut active_table);
 | 
				
			||||||
            active_table.flush_all();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if clear {
 | 
					        if clear {
 | 
				
			||||||
            assert!(flush && self.flags.contains(entry::WRITABLE));
 | 
					            assert!(self.flags.contains(entry::WRITABLE));
 | 
				
			||||||
            unsafe {
 | 
					            unsafe {
 | 
				
			||||||
                intrinsics::write_bytes(self.start_address().get() as *mut u8, 0, self.size);
 | 
					                intrinsics::write_bytes(self.start_address().get() as *mut u8, 0, self.size);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn unmap(&mut self, flush: bool) {
 | 
					    fn unmap(&mut self) {
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut flush_all = false;
 | 
					        let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for page in self.pages() {
 | 
					        for page in self.pages() {
 | 
				
			||||||
            active_table.unmap(page);
 | 
					            let result = active_table.unmap(page);
 | 
				
			||||||
 | 
					            flush_all.consume(result);
 | 
				
			||||||
            if flush {
 | 
					 | 
				
			||||||
                //active_table.flush(page);
 | 
					 | 
				
			||||||
                flush_all = true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if flush_all {
 | 
					        flush_all.flush(&mut active_table);
 | 
				
			||||||
            active_table.flush_all();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// A complicated operation to move a piece of memory to a new page table
 | 
					    /// A complicated operation to move a piece of memory to a new page table
 | 
				
			||||||
    /// It also allows for changing the address at the same time
 | 
					    /// It also allows for changing the address at the same time
 | 
				
			||||||
    pub fn move_to(&mut self, new_start: VirtualAddress, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage, flush: bool) {
 | 
					    pub fn move_to(&mut self, new_start: VirtualAddress, new_table: &mut InactivePageTable, temporary_page: &mut TemporaryPage) {
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut flush_all = false;
 | 
					        let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for page in self.pages() {
 | 
					        for page in self.pages() {
 | 
				
			||||||
            let frame = active_table.unmap_return(page);
 | 
					            let (result, frame) = active_table.unmap_return(page);
 | 
				
			||||||
 | 
					            flush_all.consume(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            active_table.with(new_table, temporary_page, |mapper| {
 | 
					            active_table.with(new_table, temporary_page, |mapper| {
 | 
				
			||||||
                let new_page = Page::containing_address(VirtualAddress::new(page.start_address().get() - self.start.get() + new_start.get()));
 | 
					                let new_page = Page::containing_address(VirtualAddress::new(page.start_address().get() - self.start.get() + new_start.get()));
 | 
				
			||||||
                mapper.map_to(new_page, frame, self.flags);
 | 
					                let result = mapper.map_to(new_page, frame, self.flags);
 | 
				
			||||||
 | 
					                // This is not the active table, so the flush can be ignored
 | 
				
			||||||
 | 
					                unsafe { result.ignore(); }
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if flush {
 | 
					 | 
				
			||||||
                //active_table.flush(page);
 | 
					 | 
				
			||||||
                flush_all = true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if flush_all {
 | 
					        flush_all.flush(&mut active_table);
 | 
				
			||||||
            active_table.flush_all();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.start = new_start;
 | 
					        self.start = new_start;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn remap(&mut self, new_flags: EntryFlags, flush: bool) {
 | 
					    pub fn remap(&mut self, new_flags: EntryFlags) {
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut flush_all = false;
 | 
					        let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for page in self.pages() {
 | 
					        for page in self.pages() {
 | 
				
			||||||
            active_table.remap(page, new_flags);
 | 
					            let result = active_table.remap(page, new_flags);
 | 
				
			||||||
 | 
					            flush_all.consume(result);
 | 
				
			||||||
            if flush {
 | 
					 | 
				
			||||||
                //active_table.flush(page);
 | 
					 | 
				
			||||||
                flush_all = true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if flush_all {
 | 
					        flush_all.flush(&mut active_table);
 | 
				
			||||||
            active_table.flush_all();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.flags = new_flags;
 | 
					        self.flags = new_flags;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn resize(&mut self, new_size: usize, flush: bool, clear: bool) {
 | 
					    pub fn resize(&mut self, new_size: usize, clear: bool) {
 | 
				
			||||||
        let mut active_table = unsafe { ActivePageTable::new() };
 | 
					        let mut active_table = unsafe { ActivePageTable::new() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //TODO: Calculate page changes to minimize operations
 | 
					        //TODO: Calculate page changes to minimize operations
 | 
				
			||||||
        if new_size > self.size {
 | 
					        if new_size > self.size {
 | 
				
			||||||
            let mut flush_all = false;
 | 
					            let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size));
 | 
					            let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size));
 | 
				
			||||||
            let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size - 1));
 | 
					            let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size - 1));
 | 
				
			||||||
            for page in Page::range_inclusive(start_page, end_page) {
 | 
					            for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                if active_table.translate_page(page).is_none() {
 | 
					                if active_table.translate_page(page).is_none() {
 | 
				
			||||||
                    active_table.map(page, self.flags);
 | 
					                    let result = active_table.map(page, self.flags);
 | 
				
			||||||
 | 
					                    flush_all.consume(result);
 | 
				
			||||||
                    if flush {
 | 
					 | 
				
			||||||
                        //active_table.flush(page);
 | 
					 | 
				
			||||||
                        flush_all = true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if flush_all {
 | 
					            flush_all.flush(&mut active_table);
 | 
				
			||||||
                active_table.flush_all();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if clear {
 | 
					            if clear {
 | 
				
			||||||
                assert!(flush);
 | 
					 | 
				
			||||||
                unsafe {
 | 
					                unsafe {
 | 
				
			||||||
                    intrinsics::write_bytes((self.start.get() + self.size) as *mut u8, 0, new_size - self.size);
 | 
					                    intrinsics::write_bytes((self.start.get() + self.size) as *mut u8, 0, new_size - self.size);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if new_size < self.size {
 | 
					        } else if new_size < self.size {
 | 
				
			||||||
            let mut flush_all = false;
 | 
					            let mut flush_all = MapperFlushAll::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size));
 | 
					            let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size));
 | 
				
			||||||
            let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
 | 
					            let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
 | 
				
			||||||
            for page in Page::range_inclusive(start_page, end_page) {
 | 
					            for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                if active_table.translate_page(page).is_some() {
 | 
					                if active_table.translate_page(page).is_some() {
 | 
				
			||||||
                    active_table.unmap(page);
 | 
					                    let result = active_table.unmap(page);
 | 
				
			||||||
 | 
					                    flush_all.consume(result);
 | 
				
			||||||
                    if flush {
 | 
					 | 
				
			||||||
                        //active_table.flush(page);
 | 
					 | 
				
			||||||
                        flush_all = true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if flush_all {
 | 
					            flush_all.flush(&mut active_table);
 | 
				
			||||||
                active_table.flush_all();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.size = new_size;
 | 
					        self.size = new_size;
 | 
				
			||||||
| 
						 | 
					@ -350,7 +315,7 @@ impl Memory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Drop for Memory {
 | 
					impl Drop for Memory {
 | 
				
			||||||
    fn drop(&mut self) {
 | 
					    fn drop(&mut self) {
 | 
				
			||||||
        self.unmap(true);
 | 
					        self.unmap();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ pub fn brk(address: usize) -> Result<usize> {
 | 
				
			||||||
        //TODO: out of memory errors
 | 
					        //TODO: out of memory errors
 | 
				
			||||||
        if let Some(ref heap_shared) = context.heap {
 | 
					        if let Some(ref heap_shared) = context.heap {
 | 
				
			||||||
            heap_shared.with(|heap| {
 | 
					            heap_shared.with(|heap| {
 | 
				
			||||||
                heap.resize(address - arch::USER_HEAP_OFFSET, true, true);
 | 
					                heap.resize(address - arch::USER_HEAP_OFFSET, true);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            panic!("user heap not initialized");
 | 
					            panic!("user heap not initialized");
 | 
				
			||||||
| 
						 | 
					@ -139,7 +139,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                            VirtualAddress::new(memory.start_address().get() + arch::USER_TMP_OFFSET),
 | 
					                            VirtualAddress::new(memory.start_address().get() + arch::USER_TMP_OFFSET),
 | 
				
			||||||
                            memory.size(),
 | 
					                            memory.size(),
 | 
				
			||||||
                            entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
					                            entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
				
			||||||
                            true,
 | 
					 | 
				
			||||||
                            false
 | 
					                            false
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,7 +148,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                                            memory.size());
 | 
					                                            memory.size());
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        new_memory.remap(memory.flags(), true);
 | 
					                        new_memory.remap(memory.flags());
 | 
				
			||||||
                        image.push(new_memory.to_shared());
 | 
					                        image.push(new_memory.to_shared());
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -160,7 +159,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                            VirtualAddress::new(arch::USER_TMP_HEAP_OFFSET),
 | 
					                            VirtualAddress::new(arch::USER_TMP_HEAP_OFFSET),
 | 
				
			||||||
                            heap.size(),
 | 
					                            heap.size(),
 | 
				
			||||||
                            entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
					                            entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
				
			||||||
                            true,
 | 
					 | 
				
			||||||
                            false
 | 
					                            false
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,7 +168,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                                            heap.size());
 | 
					                                            heap.size());
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        new_heap.remap(heap.flags(), true);
 | 
					                        new_heap.remap(heap.flags());
 | 
				
			||||||
                        heap_option = Some(new_heap.to_shared());
 | 
					                        heap_option = Some(new_heap.to_shared());
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -181,7 +179,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                    VirtualAddress::new(arch::USER_TMP_STACK_OFFSET),
 | 
					                    VirtualAddress::new(arch::USER_TMP_STACK_OFFSET),
 | 
				
			||||||
                    stack.size(),
 | 
					                    stack.size(),
 | 
				
			||||||
                    entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
					                    entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
				
			||||||
                    true,
 | 
					 | 
				
			||||||
                    false
 | 
					                    false
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,7 +188,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                                    stack.size());
 | 
					                                    stack.size());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                new_stack.remap(stack.flags(), true);
 | 
					                new_stack.remap(stack.flags());
 | 
				
			||||||
                stack_option = Some(new_stack);
 | 
					                stack_option = Some(new_stack);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,7 +200,6 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                        VirtualAddress::new(arch::USER_TMP_TLS_OFFSET),
 | 
					                        VirtualAddress::new(arch::USER_TMP_TLS_OFFSET),
 | 
				
			||||||
                        tls.mem.size(),
 | 
					                        tls.mem.size(),
 | 
				
			||||||
                        entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
					                        entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
 | 
				
			||||||
                        true,
 | 
					 | 
				
			||||||
                        true
 | 
					                        true
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
| 
						 | 
					@ -214,7 +210,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                                    tls.file_size);
 | 
					                                    tls.file_size);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                new_tls.mem.remap(tls.mem.flags(), true);
 | 
					                new_tls.mem.remap(tls.mem.flags());
 | 
				
			||||||
                tls_option = Some(new_tls);
 | 
					                tls_option = Some(new_tls);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,7 +401,9 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                    for page in Page::range_inclusive(start_page, end_page) {
 | 
					                    for page in Page::range_inclusive(start_page, end_page) {
 | 
				
			||||||
                        let frame = active_table.translate_page(page).expect("kernel percpu not mapped");
 | 
					                        let frame = active_table.translate_page(page).expect("kernel percpu not mapped");
 | 
				
			||||||
                        active_table.with(&mut new_table, &mut temporary_page, |mapper| {
 | 
					                        active_table.with(&mut new_table, &mut temporary_page, |mapper| {
 | 
				
			||||||
                            mapper.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE);
 | 
					                            let result = mapper.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE);
 | 
				
			||||||
 | 
					                            // Ignore result due to operating on inactive table
 | 
				
			||||||
 | 
					                            unsafe { result.ignore(); }
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -414,7 +412,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                for memory_shared in image.iter_mut() {
 | 
					                for memory_shared in image.iter_mut() {
 | 
				
			||||||
                    memory_shared.with(|memory| {
 | 
					                    memory_shared.with(|memory| {
 | 
				
			||||||
                        let start = VirtualAddress::new(memory.start_address().get() - arch::USER_TMP_OFFSET + arch::USER_OFFSET);
 | 
					                        let start = VirtualAddress::new(memory.start_address().get() - arch::USER_TMP_OFFSET + arch::USER_OFFSET);
 | 
				
			||||||
                        memory.move_to(start, &mut new_table, &mut temporary_page, true);
 | 
					                        memory.move_to(start, &mut new_table, &mut temporary_page);
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                context.image = image;
 | 
					                context.image = image;
 | 
				
			||||||
| 
						 | 
					@ -422,7 +420,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
                // Move copy of heap
 | 
					                // Move copy of heap
 | 
				
			||||||
                if let Some(heap_shared) = heap_option {
 | 
					                if let Some(heap_shared) = heap_option {
 | 
				
			||||||
                    heap_shared.with(|heap| {
 | 
					                    heap_shared.with(|heap| {
 | 
				
			||||||
                        heap.move_to(VirtualAddress::new(arch::USER_HEAP_OFFSET), &mut new_table, &mut temporary_page, true);
 | 
					                        heap.move_to(VirtualAddress::new(arch::USER_HEAP_OFFSET), &mut new_table, &mut temporary_page);
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                    context.heap = Some(heap_shared);
 | 
					                    context.heap = Some(heap_shared);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -430,13 +428,13 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Setup user stack
 | 
					            // Setup user stack
 | 
				
			||||||
            if let Some(mut stack) = stack_option {
 | 
					            if let Some(mut stack) = stack_option {
 | 
				
			||||||
                stack.move_to(VirtualAddress::new(arch::USER_STACK_OFFSET), &mut new_table, &mut temporary_page, true);
 | 
					                stack.move_to(VirtualAddress::new(arch::USER_STACK_OFFSET), &mut new_table, &mut temporary_page);
 | 
				
			||||||
                context.stack = Some(stack);
 | 
					                context.stack = Some(stack);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Setup user TLS
 | 
					            // Setup user TLS
 | 
				
			||||||
            if let Some(mut tls) = tls_option {
 | 
					            if let Some(mut tls) = tls_option {
 | 
				
			||||||
                tls.mem.move_to(VirtualAddress::new(arch::USER_TLS_OFFSET), &mut new_table, &mut temporary_page, true);
 | 
					                tls.mem.move_to(VirtualAddress::new(arch::USER_TLS_OFFSET), &mut new_table, &mut temporary_page);
 | 
				
			||||||
                context.tls = Some(tls);
 | 
					                context.tls = Some(tls);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -566,7 +564,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                                VirtualAddress::new(segment.p_vaddr as usize),
 | 
					                                VirtualAddress::new(segment.p_vaddr as usize),
 | 
				
			||||||
                                segment.p_memsz as usize,
 | 
					                                segment.p_memsz as usize,
 | 
				
			||||||
                                entry::NO_EXECUTE | entry::WRITABLE,
 | 
					                                entry::NO_EXECUTE | entry::WRITABLE,
 | 
				
			||||||
                                true,
 | 
					 | 
				
			||||||
                                true
 | 
					                                true
 | 
				
			||||||
                            );
 | 
					                            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -590,7 +587,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                                flags.insert(entry::WRITABLE);
 | 
					                                flags.insert(entry::WRITABLE);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            memory.remap(flags, true);
 | 
					                            memory.remap(flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            context.image.push(memory.to_shared());
 | 
					                            context.image.push(memory.to_shared());
 | 
				
			||||||
                        } else if segment.p_type == program_header::PT_TLS {
 | 
					                        } else if segment.p_type == program_header::PT_TLS {
 | 
				
			||||||
| 
						 | 
					@ -598,7 +595,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                                VirtualAddress::new(arch::USER_TCB_OFFSET),
 | 
					                                VirtualAddress::new(arch::USER_TCB_OFFSET),
 | 
				
			||||||
                                4096,
 | 
					                                4096,
 | 
				
			||||||
                                entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
					                                entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
				
			||||||
                                true,
 | 
					 | 
				
			||||||
                                true
 | 
					                                true
 | 
				
			||||||
                            );
 | 
					                            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -619,7 +615,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                        VirtualAddress::new(arch::USER_HEAP_OFFSET),
 | 
					                        VirtualAddress::new(arch::USER_HEAP_OFFSET),
 | 
				
			||||||
                        0,
 | 
					                        0,
 | 
				
			||||||
                        entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
					                        entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
				
			||||||
                        true,
 | 
					 | 
				
			||||||
                        true
 | 
					                        true
 | 
				
			||||||
                    ).to_shared());
 | 
					                    ).to_shared());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -628,7 +623,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                        VirtualAddress::new(arch::USER_STACK_OFFSET),
 | 
					                        VirtualAddress::new(arch::USER_STACK_OFFSET),
 | 
				
			||||||
                        arch::USER_STACK_SIZE,
 | 
					                        arch::USER_STACK_SIZE,
 | 
				
			||||||
                        entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
					                        entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
				
			||||||
                        true,
 | 
					 | 
				
			||||||
                        true
 | 
					                        true
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -641,7 +635,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                                VirtualAddress::new(arch::USER_TLS_OFFSET),
 | 
					                                VirtualAddress::new(arch::USER_TLS_OFFSET),
 | 
				
			||||||
                                size,
 | 
					                                size,
 | 
				
			||||||
                                entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
					                                entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
 | 
				
			||||||
                                true,
 | 
					 | 
				
			||||||
                                true
 | 
					                                true
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                        };
 | 
					                        };
 | 
				
			||||||
| 
						 | 
					@ -675,7 +668,6 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                            VirtualAddress::new(arch::USER_ARG_OFFSET),
 | 
					                            VirtualAddress::new(arch::USER_ARG_OFFSET),
 | 
				
			||||||
                            arg_size,
 | 
					                            arg_size,
 | 
				
			||||||
                            entry::NO_EXECUTE | entry::WRITABLE,
 | 
					                            entry::NO_EXECUTE | entry::WRITABLE,
 | 
				
			||||||
                            true,
 | 
					 | 
				
			||||||
                            true
 | 
					                            true
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -690,7 +682,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
 | 
				
			||||||
                            arg_offset += arg.len();
 | 
					                            arg_offset += arg.len();
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        memory.remap(entry::NO_EXECUTE | entry::USER_ACCESSIBLE, true);
 | 
					                        memory.remap(entry::NO_EXECUTE | entry::USER_ACCESSIBLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        context.image.push(memory.to_shared());
 | 
					                        context.image.push(memory.to_shared());
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue