Ejemplo n.º 1
0
static int VBoxGuestSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
{
    LogFlow((DEVICE_NAME "::Close pid=%d\n", (int)RTProcSelf()));

    PVBOXGUESTSESSION pSession = NULL;
    vboxguest_state_t *pState = ddi_get_soft_state(g_pVBoxGuestSolarisState, getminor(Dev));
    if (!pState)
    {
        Log((DEVICE_NAME "::Close: failed to get pState.\n"));
        return EFAULT;
    }

    proc_unref(pState->pvProcRef);
    pSession = pState->pSession;
    pState->pSession = NULL;
    Log((DEVICE_NAME "::Close: pSession=%p pState=%p\n", pSession, pState));
    ddi_soft_state_free(g_pVBoxGuestSolarisState, getminor(Dev));
    if (!pSession)
    {
        Log((DEVICE_NAME "::Close: failed to get pSession.\n"));
        return EFAULT;
    }

    /*
     * Close the session.
     */
    VBoxGuestCloseSession(&g_DevExt, pSession);
    return 0;
}
Ejemplo n.º 2
0
struct buf * geteblk_special(size_t size, uint32_t control)
{
    struct proc_info * proc = proc_ref(0);
    const uintptr_t kvaddr = get_ksect_addr(size);
    struct buf * buf;
    int err;

    KASSERT(proc, "Can't get the PCB of pid 0");
    proc_unref(proc);

    if (kvaddr == 0) {
        KERROR_DBG("Returned kvaddr is NULL\n");
        return NULL;
    }

    buf = vm_newsect(kvaddr, size, VM_PROT_READ | VM_PROT_WRITE);
    if (!buf) {
        KERROR_DBG("vm_newsect() failed\n");
        return NULL;
    }

    buf->b_mmu.control = control;

    err = vm_insert_region(proc, buf, VM_INSOP_MAP_REG);
    if (err < 0) {
        panic("Mapping a kernel special buffer failed");
    }

    buf->b_data = buf->b_mmu.vaddr; /* Should be same as kvaddr */

    return buf;
}
Ejemplo n.º 3
0
static int vgdrvSolarisClose(dev_t Dev, int flag, int fType, cred_t *pCred)
{
    LogFlow(("vgdrvSolarisClose: pid=%d\n", (int)RTProcSelf()));

    PVBOXGUESTSESSION pSession = NULL;
    vboxguest_state_t *pState = ddi_get_soft_state(g_pvgdrvSolarisState, getminor(Dev));
    if (!pState)
    {
        Log(("vgdrvSolarisClose: failed to get pState.\n"));
        return EFAULT;
    }

    if (pState->pvProcRef != NULL)
    {
        proc_unref(pState->pvProcRef);
        pState->pvProcRef = NULL;
    }
    pSession = pState->pSession;
    pState->pSession = NULL;
    Log(("vgdrvSolarisClose: pSession=%p pState=%p\n", pSession, pState));
    ddi_soft_state_free(g_pvgdrvSolarisState, getminor(Dev));
    if (!pSession)
    {
        Log(("vgdrvSolarisClose: failed to get pSession.\n"));
        return EFAULT;
    }

    /*
     * Close the session.
     */
    if (pSession)
        VGDrvCommonCloseSession(&g_DevExt, pSession);
    return 0;
}
Ejemplo n.º 4
0
static int procfs_updatedir(vnode_t * dir)
{
    int err = 0;

    if (dir == vn_procfs) {
        PROC_LOCK();

        /*
         * This is the procfs root.
         *
         * Now we just try to create a directory for every process in the system
         * regardless whether it already exist or not and try to remove
         * directories that should not exist anymore.
         */
        for (int i = 0; i <= configMAXPROC; i++) {
            struct proc_info * proc = proc_ref_locked(i);

            if (proc) {
                err = procfs_mkentry(proc);
                proc_unref(proc);
            } else {
                procfs_rmentry(i);
            }
        }

        PROC_UNLOCK();
    }

    return err;
}
Ejemplo n.º 5
0
Archivo: kinit.c Proyecto: Zeke-OS/zeke
static void mount_tmp_rootfs(void)
{
    const char failed[] = "Failed to mount rootfs";
    vnode_t * tmp = NULL;
    struct proc_info * kernel_proc;
    int ret;

    kernel_proc = proc_ref(0);
    if (!kernel_proc) {
        panic(failed);
    }
    /* No need to keep the ref because it won't go away. */
    proc_unref(kernel_proc);

    /* Root dir */
    tmp = kzalloc_crit(sizeof(vnode_t));
    kernel_proc->croot = tmp;
    kernel_proc->croot->vn_next_mountpoint = kernel_proc->croot;
    kernel_proc->croot->vn_prev_mountpoint = kernel_proc->croot;
    mtx_init(&tmp->vn_lock, MTX_TYPE_SPIN, 0);
    vrefset(kernel_proc->croot, 2);

    ret = fs_mount(kernel_proc->croot, "", "ramfs", 0, "", 1);
    if (ret) {
        KERROR(KERROR_ERR, "%s : %i\n", failed, ret);
        goto out;
    }

    kernel_proc->croot->vn_next_mountpoint->vn_prev_mountpoint =
        kernel_proc->croot->vn_next_mountpoint;
    kernel_proc->croot = kernel_proc->croot->vn_next_mountpoint;
    kernel_proc->cwd = kernel_proc->croot;

out:
    kfree(tmp);
}
Ejemplo n.º 6
0
Archivo: kinit.c Proyecto: Zeke-OS/zeke
static pthread_t create_uinit_main(void * stack_addr)
{
    struct _sched_pthread_create_args init_ds = {
        .param.sched_policy = SCHED_OTHER,
        .param.sched_priority = NZERO,
        .stack_addr = stack_addr,
        .stack_size = configUSRINIT_SSIZE,
        .flags      = 0,
        .start      = uinit, /* We have to first get into user space to use exec
                              * and mount the rootfs.
                              */
        .arg1       = (uintptr_t)rootfs,
        .del_thread = (void (*)(void *))uinit_exit,
    };

    return thread_create(&init_ds, THREAD_MODE_PRIV);
}

/**
 * Map vmstack to proc.
 */
static void map_vmstack2proc(struct proc_info * proc, struct buf * vmstack)
{
    struct vm_pt * vpt;

    (*proc->mm.regions)[MM_STACK_REGION] = vmstack;
    vm_updateusr_ap(vmstack);

    vpt = ptlist_get_pt(&proc->mm, vmstack->b_mmu.vaddr,
                        MMU_PGSIZE_COARSE, VM_PT_CREAT);
    if (vpt == 0)
        panic("Couldn't get vpt for init stack");

    vmstack->b_mmu.pt = &(vpt->pt);
    vm_map_region(vmstack, vpt);
}

/**
 * Create init process.
 */
int __kinit__ kinit(void)
{
    SUBSYS_DEP(sched_init);
    SUBSYS_DEP(proc_init);
    SUBSYS_DEP(ramfs_init);
    SUBSYS_DEP(sysctl_init);
    SUBSYS_INIT("kinit");

    char strbuf[80]; /* Buffer for panic messages. */
    struct buf * init_vmstack;
    pthread_t tid;
    pid_t pid;
    struct thread_info * init_thread;
    struct proc_info * init_proc;


    /*
     * FIXME Memory allocation, protection or manipulation bug!
     * There is a critical bug causing random crashes in userland. I suspect
     * something is overwriting user space allocation from the kernel space.
     * Allocating some memory before init is executed seems to fix this issue,
     * however naturally this is not the proper way to fix the bug.
     * Without the allocation here the issue is sometimes seen in init or
     * usually after couple of fork + exec + exit cycles. The usual symptom is
     * that the userland app first calls some 0:0 syscalls and then tries to
     * execute undefined instruction, which probably means that either some
     * jump table in the heap or some part of the executable code is modified
     * by a bad access in kernel mode just before this happens.
     */
    (void)geteblk(MMU_PGSIZE_COARSE * 10);


    mount_tmp_rootfs();

    /*
     * User stack for init
     */
    init_vmstack = create_vmstack();
    if (!init_vmstack)
        panic("Can't allocate a stack for init");

    /*
     * Create a thread for init
     */
    tid = create_uinit_main((void *)(init_vmstack->b_mmu.paddr));
    if (tid < 0) {
        ksprintf(strbuf, sizeof(strbuf), "Can't create a thread for init. %i",
                 tid);
        panic(strbuf);
    }

    /*
     * pid of init
     */
    pid = proc_fork();
    if (pid <= 0) {
        ksprintf(strbuf, sizeof(strbuf), "Can't fork a process for init. %i",
                 pid);
        panic(strbuf);
    }

    init_thread = thread_lookup(tid);
    if (!init_thread) {
        panic("Can't get thread descriptor of init_thread!");
    }

    init_proc = proc_ref(pid);
    if (!init_proc || (init_proc->state == PROC_STATE_INITIAL)) {
        panic("Failed to get proc struct or invalid struct");
    }

    init_thread->pid_owner = pid;
    init_thread->curr_mpt = &init_proc->mm.mpt;

    /*
     * Map the previously created user stack with init process page table.
     */
    map_vmstack2proc(init_proc, init_vmstack);

    /*
     * Map tkstack of init with vm_pagetable_system.
     */
    mmu_map_region(&init_thread->kstack_region->b_mmu);
    init_proc->main_thread = init_thread;

    KERROR_DBG("Init created with pid: %u, tid: %u, stack: %p\n",
               pid, tid, (void *)init_vmstack->b_mmu.vaddr);

    proc_unref(init_proc);

    return 0;
}