Esempio n. 1
0
/* Mapping a segment is a four step process:
 * (1) xemem_get/attach the seg into our aspace
 * (2) invoke aspace_virt_to_phys on the attached region to generate a page
 * frame list 
 * (3) invoke aspace_map_region on the target region in the target
 * aspace
 * (4) detach the xemem attachment (hold onto the apid)
 */
static int
__map_hio_segment(hio_segment_t * seg,
                  id_t            aspace_id)
{
    xemem_apid_t apid;
    void * local_attach;
    uint32_t nr_pages, page_size, i, j;
    int status;

    if (aspace_id == MY_ID)
        aspace_get_myid(&aspace_id);

    /* (1) xemem get/attach */
    {
        struct xemem_addr addr;

        apid = xemem_get(seg->segid, XEMEM_RDWR);
        if (apid == -1) {
            printf("Could not get xemem segid %li\n", seg->segid);
            return -1;
        }

        addr.apid   = apid;
        addr.offset = 0;

        local_attach = xemem_attach(addr, seg->size, NULL);
        if (local_attach == MAP_FAILED) {
            printf("Could not attach xemem apid %li (%s)\n", addr.apid, strerror(errno));
            goto out_attach;
        }
    }

    /* (2) figure out the pfns and (3) map them to the target aspace */
    {
        vaddr_t local_vaddr, target_vaddr;
        paddr_t paddr;
        struct pmem_region region;

        page_size = seg->page_size;
        nr_pages  = seg->size / seg->page_size;

        for (i = 0; i < nr_pages; i++) {
            local_vaddr  = (addr_t)local_attach + (seg->page_size * i);
            target_vaddr = (addr_t)seg->vaddr   + (seg->page_size * i);

            /* (2) */
            status = aspace_virt_to_phys(MY_ID, local_vaddr, &paddr);
            if (status != 0) {
                printf("aspace_virt_to_phys failed (%s)\n", strerror(errno));
                goto out_virt_to_phys;
            }

            /* Temporary hack: add umem so we can use aspace_map_region below.
             * (the kernel won't let us map non-umem memory)
             */
            {
                memset(&region, 0, sizeof(struct pmem_region));

                region.start            = paddr;
                region.end              = paddr + seg->page_size;
                region.type_is_set      = true;
                region.type             = PMEM_TYPE_UMEM;
                region.allocated_is_set = true;
                region.allocated        = true;

                status = pmem_add(&region);
                if (status != 0) {
                    printf("pmem_add failed (%s)\n", strerror(errno));
                    goto out_umem;
                }
            }

            /* (3) */
            status = aspace_map_region(
                    aspace_id, 
                    target_vaddr,
                    seg->page_size,
                    VM_READ | VM_WRITE | VM_USER,
                    seg->page_size,
                    "hio",
                    paddr
                );

            if (status != 0) {
                printf("aspace_map_region failed (%d) (%s)\n",
                    status, strerror(errno));
                goto out_map_pmem;
            }

            /* Remove umem now. Unclear how to do it later */
            pmem_free_umem(&region);
            pmem_del(&region);
        }
    }

    /* (4) teardown local mapping */
    xemem_detach(local_attach);

    return 0;

out_map_pmem:
out_umem:
out_virt_to_phys:
    for (j = 0; j < i; j++) {
        aspace_unmap_region(
            aspace_id, 
            (addr_t)seg->vaddr + (j * seg->page_size), 
            seg->page_size
        );
    }

    xemem_detach(local_attach);

out_attach:
    xemem_release(apid);
    return -1;
}
Esempio n. 2
0
bool App::run( int rankThisNode, id_t pid, uint cpu_id, user_cpumask_t cpumask )
{
    start_state_t   start_state;
    Debug( App, "pid=%d cpu_id=%d\n", pid, cpu_id );
    Debug( App, "argv=%s\n",m_cmdAddr);
    //Debug( App, "envp=%s\n",m_envAddr);

#if DEBUG
    if ( elf_check_hdr( ( elfhdr*) elf_image ) == 0 ) {
        elf_print_elfhdr( (elfhdr*) elf_image );
    }
#endif

    std::string argv = m_cmdAddr;
    std::string name = argv.substr( 0, argv.find(" ") );
    argv = argv.substr( name.size(), argv.size() );

    start_state.cpu_id  = cpu_id;
    start_state.task_id  = pid;
    start_state.user_id  = 1;
    start_state.group_id  = 1;
    start_state.user_id = m_uid;
    start_state.group_id = m_gid;
    //start_state.cpumask = cpumask;

    sprintf(start_state.task_name, "user-%d", pid );

    int rc;

    if ( ( rc = elf_load( 
                    m_elfAddr, 
                    name.c_str(), 
                    pid, // aspace id is the same as the pid 
                    PAGE_SIZE,
                    m_heap_len,
                    m_stack_len,
                    (char*) argv.data(),
                    m_envAddrV[rankThisNode],
                    &start_state,
                    (uintptr_t) &m_allocQ,
                    pmem_alloc) ) ) 
    {
        Warn( App, "elf_load() failed\n");
        return rc;
    }

    if ( aspace_map_region( pid, (vaddr_t) m_runTimeInfo, m_runTimeInfoLen, 
                        (VM_USER|VM_READ), PAGE_SIZE, 
                        "NidPidMap", mem_paddr( (void*) m_runTimeInfo ) ) ) 
    {
        Warn( App, "failed to map nidpidmap in to aspace\n");
        return -1;
    }

    id_t gotId;
    rc = task_create( &start_state, &gotId );
    if ( rc || pid != gotId ) {
        Warn( App, "task_create() failed\n");
        return  -1;
    }
    return 0;
}