Пример #1
0
status_t vmi_translate_uv2p (vmi_instance_t vmi, addr_t virt_address, vmi_pid_t pid, addr_t *paddr)
{
    status_t ret = VMI_FAILURE;
    addr_t dtb = 0;
    if ( VMI_FAILURE == vmi_pid_to_dtb(vmi, pid, &dtb) || !dtb ) {
        dbprint(VMI_DEBUG_PTLOOKUP, "--early bail on v2p lookup because dtb not found\n");
        return VMI_FAILURE;
    }

    ret = vmi_pagetable_lookup_cache(vmi, dtb, virt_address, paddr);

    if ( VMI_FAILURE == ret) {
        if ( VMI_FAILURE == pid_cache_del(vmi, pid) )
            return VMI_FAILURE;

        ret = vmi_pid_to_dtb(vmi, pid, &dtb);
        if (VMI_SUCCESS == ret) {
            page_info_t info = {0};
            /* _extended() skips the v2p_cache lookup that must have already failed */
            ret = vmi_pagetable_lookup_extended(vmi, dtb, virt_address, &info);

            if ( VMI_SUCCESS == ret )
                *paddr = info.paddr;
        }
    }

    return ret;
}
Пример #2
0
addr_t vmi_translate_uv2p (vmi_instance_t vmi, addr_t virt_address, vmi_pid_t pid)
{
    addr_t paddr = 0;
    addr_t dtb = vmi_pid_to_dtb(vmi, pid);

    if (!dtb) {
        dbprint(VMI_DEBUG_PTLOOKUP, "--early bail on v2p lookup because dtb is zero\n");
        return 0;
    }

    if (VMI_SUCCESS != vmi_pagetable_lookup_cache(vmi, dtb, virt_address, &paddr)) {
        if ( VMI_FAILURE == pid_cache_del(vmi, pid) )
            return 0;

        dtb = vmi_pid_to_dtb(vmi, pid);
        if (dtb) {
            page_info_t info = {0};
            /* _extended() skips the v2p_cache lookup that must have already failed */
            if (VMI_SUCCESS == vmi_pagetable_lookup_extended(vmi, dtb, virt_address, &info)) {
                paddr = info.paddr;
            }
        }
    }
    return paddr;
}
Пример #3
0
addr_t vmi_pagetable_lookup (vmi_instance_t vmi, addr_t dtb, addr_t vaddr)
{
    addr_t paddr = 0;

    status_t status = vmi_pagetable_lookup_cache(vmi, dtb, vaddr, &paddr);

    if (status != VMI_SUCCESS) {
        return 0;
    }

    return paddr;
}
Пример #4
0
status_t vmi_pagetable_lookup (vmi_instance_t vmi, addr_t dtb, addr_t vaddr, addr_t *paddr)
{
    return vmi_pagetable_lookup_cache(vmi, dtb, vaddr, paddr);
}
Пример #5
0
///////////////////////////////////////////////////////////
// Classic read functions for access to memory
status_t
vmi_read(
    vmi_instance_t vmi,
    const access_context_t *ctx,
    size_t count,
    void *buf,
    size_t *bytes_read)
{
    status_t ret = VMI_FAILURE;
    unsigned char *memory = NULL;
    addr_t start_addr = 0;
    addr_t paddr = 0;
    addr_t pfn = 0;
    addr_t offset = 0;
    addr_t dtb = 0;
    size_t buf_offset = 0;

#ifdef ENABLE_SAFETY_CHECKS
    if (NULL == vmi) {
        dbprint(VMI_DEBUG_READ, "--%s: vmi passed as NULL, returning without read\n", __FUNCTION__);
        goto done;
    }

    if (NULL == ctx) {
        dbprint(VMI_DEBUG_READ, "--%s: ctx passed as NULL, returning without read\n", __FUNCTION__);
        goto done;
    }

    if (NULL == buf) {
        dbprint(VMI_DEBUG_READ, "--%s: buf passed as NULL, returning without read\n", __FUNCTION__);
        goto done;
    }
#endif

    switch (ctx->translate_mechanism) {
        case VMI_TM_NONE:
            start_addr = ctx->addr;
            break;
        case VMI_TM_KERNEL_SYMBOL:
#ifdef ENABLE_SAFETY_CHECKS
            if (!vmi->arch_interface || !vmi->os_interface || !vmi->kpgd)
                goto done;
#endif
            dtb = vmi->kpgd;
            if ( VMI_FAILURE == vmi_translate_ksym2v(vmi, ctx->ksym, &start_addr) )
                goto done;
            break;
        case VMI_TM_PROCESS_PID:
#ifdef ENABLE_SAFETY_CHECKS
            if (!vmi->arch_interface || !vmi->os_interface)
                goto done;
#endif

            if ( !ctx->pid )
                dtb = vmi->kpgd;
            else if (ctx->pid > 0) {
                if ( VMI_FAILURE == vmi_pid_to_dtb(vmi, ctx->pid, &dtb) )
                    goto done;
            }

            if (!dtb)
                goto done;

            start_addr = ctx->addr;
            break;
        case VMI_TM_PROCESS_DTB:
#ifdef ENABLE_SAFETY_CHECKS
            if (!vmi->arch_interface)
                goto done;
#endif

            dtb = ctx->dtb;
            start_addr = ctx->addr;
            break;
        default:
            errprint("%s error: translation mechanism is not defined.\n", __FUNCTION__);
            goto done;
    }


    while (count > 0) {
        size_t read_len = 0;

        if (dtb) {
            if (VMI_SUCCESS != vmi_pagetable_lookup_cache(vmi, dtb, start_addr + buf_offset, &paddr))
                goto done;
        } else {
            paddr = start_addr + buf_offset;
        }


        /* access the memory */
        pfn = paddr >> vmi->page_shift;
        offset = (vmi->page_size - 1) & paddr;
        memory = vmi_read_page(vmi, pfn);
        if (NULL == memory)
            goto done;

        /* determine how much we can read */
        if ((offset + count) > vmi->page_size) {
            read_len = vmi->page_size - offset;
        } else {
            read_len = count;
        }

        /* do the read */
        memcpy(((char *) buf) + (addr_t) buf_offset, memory + (addr_t) offset, read_len);

        /* set variables for next loop */
        count -= read_len;
        buf_offset += read_len;
    }

    ret = VMI_SUCCESS;

done:
    if ( bytes_read )
        *bytes_read = buf_offset;

    return ret;
}
Пример #6
0
///////////////////////////////////////////////////////////
// Classic write functions for access to memory
size_t
vmi_write(
    vmi_instance_t vmi,
    const access_context_t *ctx,
    void *buf,
    size_t count)
{
    addr_t start_addr = 0;
    addr_t dtb = 0;
    addr_t paddr = 0;
    addr_t offset = 0;
    size_t buf_offset = 0;

    if (NULL == buf) {
        dbprint(VMI_DEBUG_WRITE, "--%s: buf passed as NULL, returning without write\n",
                __FUNCTION__);
        return 0;
    }

    if (NULL == ctx) {
        dbprint(VMI_DEBUG_WRITE, "--%s: ctx passed as NULL, returning without write\n",
                __FUNCTION__);
        return 0;
    }

    switch (ctx->translate_mechanism) {
        case VMI_TM_NONE:
            start_addr = ctx->addr;
            break;
        case VMI_TM_KERNEL_SYMBOL:
            if (!vmi->arch_interface || !vmi->os_interface || !vmi->kpgd)
              return 0;

            dtb = vmi->kpgd;
            start_addr = vmi_translate_ksym2v(vmi, ctx->ksym);
            break;
        case VMI_TM_PROCESS_PID:
            if (!vmi->arch_interface || !vmi->os_interface) {
              return 0;
            }
            if(ctx->pid) {
                dtb = vmi_pid_to_dtb(vmi, ctx->pid);
            } else {
                dtb = vmi->kpgd;
            }
            if (!dtb) {
                return 0;
            }
            start_addr = ctx->addr;
            break;
        case VMI_TM_PROCESS_DTB:
            if (!vmi->arch_interface) {
              return 0;
            }
            dtb = ctx->dtb;
            start_addr = ctx->addr;
            break;
        default:
            errprint("%s error: translation mechanism is not defined.\n", __FUNCTION__);
            return 0;
    }

    while (count > 0) {
        size_t write_len = 0;

        if(dtb) {
            if (VMI_SUCCESS != vmi_pagetable_lookup_cache(vmi, dtb, start_addr + buf_offset, &paddr)) {
                return buf_offset;
            }
        } else {
            paddr = start_addr + buf_offset;
        }

        /* determine how much we can write to this page */
        offset = (vmi->page_size - 1) & paddr;
        if ((offset + count) > vmi->page_size) {
            write_len = vmi->page_size - offset;
        }
        else {
            write_len = count;
        }

        /* do the write */
        if (VMI_FAILURE ==
            driver_write(vmi, paddr,
                         ((char *) buf + (addr_t) buf_offset),
                         write_len)) {
            return buf_offset;
        }

        /* set variables for next loop */
        count -= write_len;
        buf_offset += write_len;
    }

    return buf_offset;
}