status_t
vmi_pagetable_lookup(
    vmi_instance_t vmi,
    addr_t pt,
    addr_t vaddr,
    addr_t *paddr)
{
#ifdef ENABLE_SAFETY_CHECKS
    if (!vmi || !paddr)
        return VMI_FAILURE;
#endif
 
    return vmi_pagetable_lookup_cache(vmi, pt, vaddr, paddr);
}
/*
 * Return a status when page_info is not needed, but also use the cache,
 * which vmi_pagetable_lookup_extended() does not do.
 *
 * TODO: Should this eventually replace vmi_pagetable_lookup() in the API?
 */
status_t vmi_pagetable_lookup_cache(
    vmi_instance_t vmi,
    addr_t pt,
    addr_t vaddr,
    addr_t *paddr)
{
    status_t ret = VMI_FAILURE;
#ifdef ENABLE_SAFETY_CHECKS
    if (!vmi || !paddr)
        return ret;
 
    if (!valid_pm(vmi->page_mode))
        return ret;
#endif
 
    page_info_t info = {
        .vaddr = vaddr,
        .pt = pt,
        .pm = vmi->page_mode
    };
 
    *paddr = 0;
 
    /* check if entry exists in the cache */
    if (VMI_SUCCESS == v2p_cache_get(vmi, vaddr, pt, 0, paddr)) {
 
        /* verify that address is still valid */
        uint8_t value = 0;
 
        if (VMI_SUCCESS == vmi_read_8_pa(vmi, *paddr, &value)) {
            return VMI_SUCCESS;
        } else {
            if ( VMI_FAILURE == v2p_cache_del(vmi, vaddr, 0, pt) )
                return VMI_FAILURE;
        }
    }
 
    if (vmi->arch_interface.lookup[vmi->page_mode]) {
        ret = vmi->arch_interface.lookup[vmi->page_mode](vmi, 0, 0, pt, vaddr, &info);
    } else {
        errprint("Invalid paging mode during vmi_pagetable_lookup\n");
        ret = VMI_FAILURE;
    }
 
    /* add this to the cache */
    if (ret == VMI_SUCCESS) {
        *paddr = info.paddr;
        v2p_cache_set(vmi, vaddr, pt, 0, info.paddr);
    }
    return ret;
}

🌱 Back to Garden