Esempio n. 1
0
static errval_t do_single_modify_flags(struct pmap_arm *pmap, genvaddr_t vaddr,
                                       size_t pages, vregion_flags_t flags)
{
    errval_t err = SYS_ERR_OK;
    struct vnode *ptable = find_ptable(pmap, vaddr);
    uint16_t ptentry = ARM_USER_L2_OFFSET(vaddr);
    if (ptable) {
        struct vnode *page = find_vnode(ptable, ptentry);
        if (page) {
            if (inside_region(ptable, ptentry, pages)) {
                // we're modifying part of a valid mapped region
                // arguments to invocation: invoke frame cap, first affected
                // page (as offset from first page in mapping), #affected
                // pages, new flags. Invocation should check compatibility of
                // new set of flags with cap permissions.
                size_t off = ptentry - page->entry;
                uintptr_t pmap_flags = vregion_flags_to_kpi_paging_flags(flags);
                err = invoke_frame_modify_flags(page->u.frame.cap, off, pages, pmap_flags);
                printf("invoke_frame_modify_flags returned error: %s (%"PRIuERRV")\n",
                        err_getstring(err), err);
                return err;
            } else {
                // overlaps some region border
                return LIB_ERR_PMAP_EXISTING_MAPPING;
            }
        }
    }
    return SYS_ERR_OK;
}
Esempio n. 2
0
static errval_t do_single_unmap(struct pmap_arm *pmap, genvaddr_t vaddr,
                                size_t pte_count, bool delete_cap)
{
    errval_t err;
    struct vnode *pt = find_ptable(pmap, vaddr);
    if (pt) {
        // analog to do_single_map we use 10 bits for tracking pages in user space -SG
        struct vnode *page = find_vnode(pt, ARM_USER_L2_OFFSET(vaddr));
        if (page && page->u.frame.pte_count == pte_count) {
            err = vnode_unmap(pt->u.vnode.cap, page->u.frame.cap,
                              page->entry, page->u.frame.pte_count);
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "vnode_unmap");
                return err_push(err, LIB_ERR_VNODE_UNMAP);
            }

            // Free up the resources
            if (delete_cap) {
                err = cap_destroy(page->u.frame.cap);
                if (err_is_fail(err)) {
                    return err_push(err, LIB_ERR_PMAP_DO_SINGLE_UNMAP);
                }
            }
            remove_vnode(pt, page);
            slab_free(&pmap->slab, page);
        }
        else {
            return LIB_ERR_PMAP_FIND_VNODE;
        }
    }

    return SYS_ERR_OK;
}
Esempio n. 3
0
/**
 * \brief Returns the vnode for the pagetable mapping a given vspace address
 */
static errval_t get_ptable(struct pmap_arm  *pmap,
                           genvaddr_t        vaddr,
                           struct vnode    **ptable)
{
    // NB Strictly there are 12 bits in the ARM L1, but allocations unit
    // of L2 is 1 page of L2 entries (4 tables) so we use 10 bits for the L1
    // index here
    uintptr_t index = ARM_USER_L1_OFFSET(vaddr);
    if ((*ptable = find_vnode(&pmap->root, index)) == NULL)
    {
        // L1 table entries point to L2 tables so allocate an L2
        // table for this L1 entry.

        struct vnode *tmp = NULL; // Tmp variable for passing to alloc_vnode

        errval_t err = alloc_vnode(pmap, &pmap->root, ObjType_VNode_ARM_l2,
                                   index, &tmp);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "alloc_vnode");
            return err;
        }
        assert(tmp != NULL);
        *ptable = tmp; // Set argument to received value


        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_PMAP_ALLOC_VNODE);
        }
    }

    return SYS_ERR_OK;
}
Esempio n. 4
0
static struct vnode *find_ptable(struct pmap_arm  *pmap,
                                 genvaddr_t vaddr)
{
    // NB Strictly there are 12 bits in the ARM L1, but allocations unit
    // of L2 is 1 page of L2 entries (4 tables) so
    uintptr_t index = ARM_USER_L1_OFFSET(vaddr);
    return find_vnode(&pmap->root, index);
}
Esempio n. 5
0
vnode_t *get_vnode(uint32_t driver_num, uint32_t inode_num)
{
	vnode_t *vnode = find_vnode(driver_num, inode_num);
	if(!vnode)
	{
		vnode = get_free_vnode();
		vfs_msg_getnode *getnode_msg = (vfs_msg_getnode *)calloc(sizeof(vfs_msg_getnode));
		getnode_msg->msg_type = VFSM_GETNODE;
		getnode_msg->node.driver_num = driver_num;
		getnode_msg->node.inode_num = inode_num;
		send2(driver_num, getnode_msg);
		free(getnode_msg);
		getnode_msg = waitmsg(driver_num,0);
		if(getnode_msg->node.driver_num)
		{
			memcopy((uint8_t *)vnode, (uint8_t *)&getnode_msg->node, sizeof(vnode_t));
		} else {
			_syscall_printf("\nGetnode failed!",0);
		}
		free(getnode_msg);
	}
	return vnode;
}