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