X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fmem%2Faddrspace.cc;h=3280adde37e39109d696237810f4ee9cf7bc285e;hb=bac1d18b0bd376af8e9fdc8020e3a2132988b569;hp=eb92a6a98590adf4aeb28392b304eaf5ade71915;hpb=db11b9a38323d994d42303c6149c9e06ff29b7d2;p=polintos%2Fscott%2Fpriv.git diff --git a/kernel/mem/addrspace.cc b/kernel/mem/addrspace.cc index eb92a6a..3280add 100644 --- a/kernel/mem/addrspace.cc +++ b/kernel/mem/addrspace.cc @@ -73,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); @@ -82,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); @@ -140,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; @@ -165,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) @@ -409,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; @@ -561,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) { @@ -584,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; @@ -600,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)) @@ -613,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; } @@ -626,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; @@ -793,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) @@ -819,6 +816,7 @@ namespace Mem { flags->Writeable = 1; flags->Executable = 1; flags->User = 1; + flags->AddressOnly = 1; } };