Exemplo n.º 1
0
static int fetch_file_page(struct filemap *fm, void *addr) {
    struct file *filp;
    unsigned long pfn;
    unsigned long pos;
    int rc;

    filp = (struct file *) olock(fm->file, OBJECT_FILE);
    if (!filp) return -EBADF;

    pfn = alloc_pageframe('FMAP');
    if (pfn == 0xFFFFFFFF) {
        orel(filp);
        return -ENOMEM;
    }

    map_page(addr, pfn, PT_WRITABLE | PT_PRESENT);

    pos = (char *) addr - fm->addr;
    rc = pread(filp, addr, PAGESIZE, fm->offset + pos);
    if (rc < 0) {
        orel(filp);
        unmap_page(addr);
        free_pageframe(pfn);
        return rc;
    }

    pfdb[pfn].owner = fm->self;
    map_page(addr, pfn, fm->protect | PT_PRESENT);

    orel(filp);
    return 0;
}
Exemplo n.º 2
0
Arquivo: hndl.c Projeto: HarryR/sanos
static int expand_htab() {
  unsigned long pfn;
  handle_t h;

  if (htabsize == HTABSIZE / sizeof(struct object *)) return -ENFILE;
  pfn = alloc_pageframe('HTAB');
  map_page(htab + htabsize, pfn, PT_WRITABLE | PT_PRESENT);

  for (h = htabsize + HANDLES_PER_PAGE - 1; h >= htabsize; h--) {
    htab[h] = hfreelist;
    hfreelist = h;
  }

  htabsize += HANDLES_PER_PAGE;
  return 0;
}
Exemplo n.º 3
0
int guard_page_handler(void *addr) {
    unsigned long pfn;
    struct thread *t = self();

    if (!t->tib) return -EFAULT;

    if (addr < t->tib->stacklimit || addr >= t->tib->stacktop) return -EFAULT;
    if (t->tib->stacklimit <= t->tib->stackbase) return -EFAULT;

    pfn = alloc_pageframe('STK');
    if (pfn == 0xFFFFFFFF) return -ENOMEM;

    t->tib->stacklimit = (char *) t->tib->stacklimit - PAGESIZE;
    map_page(t->tib->stacklimit, pfn, PT_GUARD | PT_WRITABLE | PT_PRESENT);
    memset(t->tib->stacklimit, 0, PAGESIZE);

    return 0;
}
Exemplo n.º 4
0
Arquivo: pdir.c Projeto: HarryR/sanos
void map_page(void *vaddr, unsigned long pfn, unsigned long flags) {
  // Allocate page table if not already done
  if ((GET_PDE(vaddr) & PT_PRESENT) == 0) {
    unsigned long pdfn;

    pdfn = alloc_pageframe('PTAB');
    if (USERSPACE(vaddr)) {
      SET_PDE(vaddr, PTOB(pdfn) | PT_PRESENT | PT_WRITABLE | PT_USER);
    } else {
      SET_PDE(vaddr, PTOB(pdfn) | PT_PRESENT | PT_WRITABLE);
    }

    memset(ptab + PDEIDX(vaddr) * PTES_PER_PAGE, 0, PAGESIZE);
    register_page_table(pdfn);
  }

  // Map page frame into address space
  SET_PTE(vaddr, PTOB(pfn) | flags);
}
Exemplo n.º 5
0
void *vmalloc(void *addr, unsigned long size, int type, int protect, unsigned long tag, int *rc) {
    int pages = PAGES(size);
    unsigned long flags = pte_flags_from_protect(protect);
    int i;

    if (rc) *rc = 0;
    if (size == 0) {
        if (rc) *rc = -EINVAL;
        return NULL;
    }
    if ((type & MEM_COMMIT) != 0 && flags == 0xFFFFFFFF) {
        if (rc) *rc = -EINVAL;
        return NULL;
    }
    addr = (void *) PAGEADDR(addr);
    if (!addr && (type & MEM_COMMIT) != 0) type |= MEM_RESERVE;
    if (!tag) tag = 'VM';

    if (type & MEM_RESERVE) {
        if (addr == NULL) {
            if (type & MEM_ALIGN64K) {
                addr = (void *) PTOB(rmap_alloc_align(vmap, pages, 64 * 1024 / PAGESIZE));
            } else {
                addr = (void *) PTOB(rmap_alloc(vmap, pages));
            }

            if (addr == NULL) {
                if (rc) *rc = -ENOMEM;
                return NULL;
            }
        } else {
            if (rmap_reserve(vmap, BTOP(addr), pages)) {
                if (rc) *rc = -ENOMEM;
                return NULL;
            }
        }
    } else {
        if (!valid_range(addr, size)) {
            if (rc) *rc = -EFAULT;
            return NULL;
        }
    }

    if (type & MEM_COMMIT) {
        char *vaddr;
        unsigned long pfn;

        vaddr = (char *) addr;
        for (i = 0; i < pages; i++) {
            if (page_mapped(vaddr)) {
                set_page_flags(vaddr, flags | PT_PRESENT);
            } else {
                pfn = alloc_pageframe(tag);
                if (pfn == 0xFFFFFFFF) {
                    if (rc) *rc = -ENOMEM;
                    return NULL;
                }

                map_page(vaddr, pfn, flags | PT_PRESENT);
                memset(vaddr, 0, PAGESIZE);
            }
            vaddr += PAGESIZE;
        }
    }

    return addr;
}