X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=kernel%2Fmem%2Faddrspace.cc;h=78cbe5e6b573aa5c2429fcbd70ee5392cf478d9b;hp=6cff1f2d602635c1b8fbb145153baddb999d5539;hb=1ac390fe1e18444008857b056c947710be9621a8;hpb=77bf9a95a836b14a243953e1fbd28c7c1106c59a diff --git a/kernel/mem/addrspace.cc b/kernel/mem/addrspace.cc index 6cff1f2..78cbe5e 100644 --- a/kernel/mem/addrspace.cc +++ b/kernel/mem/addrspace.cc @@ -21,10 +21,13 @@ #include #include +#include #include #include #include #include +#include +#include extern int roshared_start, roshared_page_end; extern int rwshared_start, rwshared_page_end; @@ -43,7 +46,7 @@ namespace Mem { void create(Object *obj) { - *obj = static_cast(*(new AddrSpace(false))); + *obj = static_cast(*(new AddrSpace)); } }; @@ -58,7 +61,7 @@ namespace Mem { void create(Object *obj) { - AddrSpace *as = new AddrSpace(true); + AddrSpace *as = new ProcAddrSpace; Region region; MapFlags mf = 0; u64 vstart; @@ -70,7 +73,8 @@ namespace Mem { mf.access_IDLNS_Read = 1; mf.access_IDLNS_Exec = 1; - as->map(physmem, region, &vstart, mf, AddrSpace::map_protected); + as->map(physmem, region, &vstart, mf, + PTEFlags::protectedmap | PTEFlags::addressonly); region.start = kvirt_to_phys(&rwshared_start); region.end = kvirt_to_phys(&rwshared_page_end); @@ -79,16 +83,16 @@ namespace Mem { mf.access_IDLNS_Write = 1; mf.CopyOnWrite = 1; - as->map(physmem, region, &vstart, mf, AddrSpace::map_protected); + as->map(physmem, region, &vstart, mf, + PTEFlags::protectedmap | PTEFlags::addressonly); // Leave the stack no-exec by default. region.start = vstart = Arch::stack_bottom; region.end = Arch::stack_top; mf.CopyOnWrite = 0; - printf("vstart %llx\n", vstart); as->map(anonmem, region, &vstart, mf); - *obj = static_cast(*(as)); + *obj = static_cast(*as); } }; @@ -98,34 +102,32 @@ namespace Mem { AddrSpaceFactory real_addrspace_factory; Factory addr_space_factory = real_addrspace_factory; - AddrSpace::AddrSpace(bool process) : mappable(this) + AddrSpace::AddrSpace(PageTable *ptbl) : mappable(this) { init_iface(); - is_process = process; + is_process = false; + page_table = ptbl; - // OPT: Allow optional use of the native PTE for stacked aspaces, - // either because the native PTE is 64-bit, or because it's an - // embedded system which does not need 64-bit storage. - - if (process) - page_table = new PageTableImpl(true); - else + if (!ptbl) page_table = new PageTableImpl(false); cached_free_region = Arch::user_start + Arch::page_size; } + ProcAddrSpace::ProcAddrSpace() : + AddrSpace(new PageTableImpl(true)) + { + is_process = true; + } + // This should only be used once during bootup to initialize the // kernel's address space with a static initial page table. - AddrSpace::AddrSpace(void *ptbl_toplevel) : mappable(this) + ProcAddrSpace::ProcAddrSpace(void *ptbl_toplevel) : + AddrSpace(new PageTableImpl(ptbl_toplevel)) { - init_iface(); + // FIXME: set cached_free_region to kernel virtual space is_process = true; - page_table = new PageTableImpl(ptbl_toplevel); - - // FIXME: should be kernel virtual space - cached_free_region = Arch::user_start + Arch::page_size; } void AddrSpace::get_mappable(IMappable *ma) @@ -139,7 +141,7 @@ namespace Mem { *addrspace = NULL; } - bool AddrSpace::handle_fault(ulong vaddr, bool write, bool exec, bool user) + int AddrSpace::handle_fault(ulong vaddr, bool write, bool exec, bool user) { if (lock.held_by_curthread()) return false; @@ -164,12 +166,10 @@ namespace Mem { } catch (BadPageFault &bpf) { - // FIXME: retain info about nature of bpf - // to throw to user? - return false; + return bpf.cause; } - return true; + return -1; } bool AddrSpace::check_overlap(Region region, VirtualArea *&va) @@ -408,10 +408,10 @@ namespace Mem { VirtualArea *va = aspace->varea_tree.find(vaddr); if (!va) - throw BadPageFault(); + throw BadPageFault(MemoryFault_ns::Cause::Unmapped); if ((va->flags & reqflags) != reqflags) - throw BadPageFault(); + throw BadPageFault(MemoryFault_ns::Cause::Protected); if (aspace->map(va, vaddr, reqflags)) break; @@ -560,7 +560,7 @@ namespace Mem { } void AddrSpace::map(IMappable ma, Region region, u64 *vstart, - MapFlags mflags, int map_type) + MapFlags mflags, PTEFlags set, PTEFlags clear) { // FIXME: check alignment for VIPT caches // FIXME: Implement the "Replace" map flag @@ -625,12 +625,13 @@ namespace Mem { newva->region() = vregion; newva->flags.Valid = 1; - newva->flags.User = map_type != map_kernel; + newva->flags.User = 1; newva->flags.Readable = mflags.access_IDLNS_Read; newva->flags.Writeable = mflags.access_IDLNS_Write; newva->flags.Executable = mflags.access_IDLNS_Exec; newva->flags.FaultOnWrite = mflags.CopyOnWrite; - newva->flags.Protected = map_type != map_user; + newva->flags.raw |= set; + newva->flags.raw &= ~clear; newva->ma = cma; newva->offset = region.start - vregion.start; @@ -749,6 +750,11 @@ namespace Mem { { *min_align = Arch::page_mapping_min_align; } + + void AddrSpace::get_size(u64 *size) + { + page_table->get_size(size); + } void Mappable::map(VirtualArea *varea) { @@ -787,9 +793,6 @@ namespace Mem { oldpage->release(); } - // FIXME: Add a special PTE flag to indicate that PhysMem mappings - // don't mess with page refcounts. - class PhysMem : public Mappable { public: void get_size(u64 *size) @@ -802,8 +805,6 @@ namespace Mem { void pagein(u64 vaddr, PTEFlags reqflags) { - // Doesn't need to do anything yet, though it may later - // once high memory support is added. } void get_mapping(u64 addr, u64 *phys, PTEFlags *flags) @@ -815,6 +816,7 @@ namespace Mem { flags->Writeable = 1; flags->Executable = 1; flags->User = 1; + flags->AddressOnly = 1; } }; @@ -833,8 +835,6 @@ namespace Mem { void pagein(u64 vaddr, PTEFlags reqflags) { - // Doesn't need to do anything yet, though it may later - // once high memory support is added. } void get_mapping(u64 addr, u64 *phys, PTEFlags *flags)