X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fmem%2Faddrspace.cc;h=3280adde37e39109d696237810f4ee9cf7bc285e;hb=bac1d18b0bd376af8e9fdc8020e3a2132988b569;hp=20a46fb04d09c6997e87ee2669e94cabefb494b6;hpb=b4bfc871337ca32ce83407916a87db2524729ca9;p=polintos%2Fscott%2Fpriv.git diff --git a/kernel/mem/addrspace.cc b/kernel/mem/addrspace.cc index 20a46fb..3280add 100644 --- a/kernel/mem/addrspace.cc +++ b/kernel/mem/addrspace.cc @@ -26,6 +26,8 @@ #include #include #include +#include +#include extern int roshared_start, roshared_page_end; extern int rwshared_start, rwshared_page_end; @@ -71,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); @@ -80,13 +83,13 @@ 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); @@ -138,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; @@ -163,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) @@ -407,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; @@ -559,14 +560,14 @@ 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 if (mflags.Replace) throw_idl(InvalidArgument, 3, - countarray("Replace unimplemented")); + countarray("Replace unimplemented")); Mappable *cma = Mappable::classptr(ma); if (!cma) { @@ -582,10 +583,10 @@ namespace Mem { mflags.Fixed = 1; if (!page_aligned(region.start)) - throw_idl(InvalidArgument, 1, countarray("unaligned start")); + throw_idl(InvalidArgument, 1, countarray("unaligned start")); if (!page_aligned(region.end + 1)) - throw_idl(InvalidArgument, 1, countarray("unaligned end")); + throw_idl(InvalidArgument, 1, countarray("unaligned end")); Lock::AutoLock autolock(lock); Region vregion; @@ -598,11 +599,11 @@ namespace Mem { if (is_process) { if (!valid_addr(vregion.start)) throw_idl(InvalidArgument, 2, - countarray("invalid virtual start")); + countarray("invalid virtual start")); if (!valid_addr(vregion.end)) throw_idl(InvalidArgument, 2, - countarray("invalid virtual end")); + countarray("invalid virtual end")); } if (check_overlap(vregion, prev)) @@ -611,10 +612,10 @@ namespace Mem { if (*vstart == System::Mem::AddrSpace_ns::unspecified_start) { if (fixed) - throw_idl(ResourceBusy, 2, countarray("varea overlap")); + throw_idl(ResourceBusy, 2, countarray("varea overlap")); if (!get_free_region(region.end - region.start + 1, vregion, prev)) - throw_idl(OutOfSpace, countarray("out of vspace")); + throw_idl(OutOfSpace, countarray("out of vspace")); *vstart = vregion.start; } @@ -624,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; @@ -791,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) @@ -817,6 +816,7 @@ namespace Mem { flags->Writeable = 1; flags->Executable = 1; flags->User = 1; + flags->AddressOnly = 1; } };