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:
+31
-1
@@ -2705,6 +2705,8 @@ user_memset(void *s, char c, size_t count)
|
|||||||
long
|
long
|
||||||
lock_memory(void *address, ulong numBytes, ulong flags)
|
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 base = (addr_t)address;
|
||||||
addr_t end = base + numBytes;
|
addr_t end = base + numBytes;
|
||||||
bool isUser = IS_USER_ADDRESS(address);
|
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)
|
if (base >= KERNEL_BASE + IOSPACE_SIZE && base + numBytes < KERNEL_BASE + 2 * IOSPACE_SIZE)
|
||||||
return B_OK;
|
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) {
|
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) {
|
if (status != B_OK) {
|
||||||
dprintf("lock_memory(address = %p, numBytes = %lu, flags = %lu) failed: %s\n",
|
dprintf("lock_memory(address = %p, numBytes = %lu, flags = %lu) failed: %s\n",
|
||||||
address, numBytes, flags, strerror(status));
|
address, numBytes, flags, strerror(status));
|
||||||
|
vm_put_aspace(aspace);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm_put_aspace(aspace);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user