The lock_memory() hack now plays a bit nicer and will not map memory

that has already been mapped before.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12258 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-04-05 19:07:45 +00:00
parent 108953a630
commit d73bf8eb9f
1 changed files with 31 additions and 1 deletions

View File

@ -2705,6 +2705,8 @@ user_memset(void *s, char c, size_t count)
long
lock_memory(void *address, ulong numBytes, ulong flags)
{
vm_address_space *aspace = NULL;
struct vm_translation_map *map;
addr_t base = (addr_t)address;
addr_t end = base + numBytes;
bool isUser = IS_USER_ADDRESS(address);
@ -2722,15 +2724,43 @@ lock_memory(void *address, ulong numBytes, ulong flags)
if (base >= KERNEL_BASE + IOSPACE_SIZE && base + numBytes < KERNEL_BASE + 2 * IOSPACE_SIZE)
return B_OK;
if (isUser)
aspace = vm_get_current_user_aspace();
else
aspace = vm_get_kernel_aspace();
if (aspace == NULL)
return B_ERROR;
map = &aspace->translation_map;
for (; base < end; base += B_PAGE_SIZE) {
status_t status = vm_soft_fault(base, (flags & B_READ_DEVICE) != 0, isUser);
addr_t physicalAddress;
uint32 protection;
status_t status;
map->ops->lock(map);
map->ops->query(map, base, &physicalAddress, &protection);
map->ops->unlock(map);
if ((protection & PAGE_PRESENT) != 0) {
// if B_READ_DEVICE is set, the caller intents to write to the locked
// memory, so if it hasn't been mapped writable, we'll try the soft
// fault anyway
if ((flags & B_READ_DEVICE) == 0
|| (protection & (B_WRITE_AREA | B_KERNEL_WRITE_AREA)) != 0)
continue;
}
status = vm_soft_fault(base, (flags & B_READ_DEVICE) != 0, isUser);
if (status != B_OK) {
dprintf("lock_memory(address = %p, numBytes = %lu, flags = %lu) failed: %s\n",
address, numBytes, flags, strerror(status));
vm_put_aspace(aspace);
return status;
}
}
vm_put_aspace(aspace);
return B_OK;
}