memory address space conversion

Sean McNeil sean at mcneil.com
Tue Nov 18 12:49:45 PST 2003


Hello all,

I ask a while ago a question and received great response.  I'm hoping to
repeat the experience :)

I have a driver that I cannot change the ioctl API to.  Unfortunately,
it has a peculiar need to return a user-space address based on the
physical address.  Here is the scenario:

user calls mmap and gets a user-space mapping to a chunk of memory.
user calls an ioctl that passes an array of user-space addresses inside
that mapping.

I had a hack working for the case of a single-threaded process, but it
will not work in a threaded environment.  Here is what I came up with:

static vm_map_entry_t find_entry (vm_map_t map, vm_paddr_t address)
{
    vm_map_entry_t entry;
    int i;

    for (i = 0, entry = &map->header;
	 i < map->nentries;
	 i++, entry = entry->next)
    {
	vm_page_t page;
	vm_paddr_t paddr;

	if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
	{
	    vm_map_entry_t sub_entry =
		find_entry (entry->object.sub_map, address);

	    if (! sub_entry) continue;

	    entry = sub_entry;
	    break;
	}

	if (entry->object.vm_object == NULL)
	    continue;

	VM_OBJECT_LOCK (entry->object.vm_object);
	page = vm_page_lookup (entry->object.vm_object,
			       OFF_TO_IDX(MMAP_OFFSET));
	paddr = (page) ? VM_PAGE_TO_PHYS (page) : 0;
	VM_OBJECT_UNLOCK (entry->object.vm_object);

	if (paddr == address) break;
    }

    return (i < map->nentries) ? entry : NULL;
}

where MMAP_OFFSET is 0x40000000.  This was the offset passed in by the
mmap call.

Does anyone know of a more proper mechanism that will work for the
threaded model?  Any and all assistance will be greatly appreciated.

TIA,
Sean




More information about the freebsd-hackers mailing list