From 7c3d0ba1f53c80ca6d2d307e68877a82d7d135b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 6 Jun 2004 16:39:03 +0000 Subject: [PATCH] get_memory_map() didn't take page offsets into account (i.e. didn't work correctly). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7762 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/vm/vm.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/kernel/core/vm/vm.c b/src/kernel/core/vm/vm.c index db534c2597..d20aa96c6d 100755 --- a/src/kernel/core/vm/vm.c +++ b/src/kernel/core/vm/vm.c @@ -2146,15 +2146,15 @@ vm_virtual_map_lookup(vm_virtual_map *map, addr address) // check the region_list region first region = map->region_hint; - if(region && region->base <= address && (region->base + region->size) > address) + if (region && region->base <= address && (region->base + region->size) > address) return region; - for(region = map->region_list; region != NULL; region = region->aspace_next) { - if(region->base <= address && (region->base + region->size) > address) + for (region = map->region_list; region != NULL; region = region->aspace_next) { + if (region->base <= address && (region->base + region->size) > address) break; } - if(region) + if (region) map->region_hint = region; return region; } @@ -2245,10 +2245,12 @@ long get_memory_map(const void *address, ulong numBytes, physical_entry *table, long numEntries) { vm_address_space *addressSpace; + addr_t virtualAddress = (addr_t)address; + addr_t pageOffset = virtualAddress & (B_PAGE_SIZE - 1); addr_t physicalAddress; status_t status = B_OK; int32 index = -1; - addr_t offset; + addr_t offset = 0; int flags; TRACE(("get_memory_map(%p, %lu bytes, %ld entries)\n", address, numBytes, numEntries)); @@ -2257,7 +2259,7 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long return B_BAD_VALUE; // in which address space is the address to be found? - if ((addr_t)address < KERNEL_BASE) + if (virtualAddress < KERNEL_BASE) addressSpace = vm_get_current_user_aspace(); else addressSpace = vm_get_kernel_aspace(); @@ -2267,7 +2269,7 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long (*addressSpace->translation_map.ops->lock)(&addressSpace->translation_map); - for (offset = 0; offset < numBytes; offset += B_PAGE_SIZE) { + while (offset < numBytes) { addr_t bytes = min(numBytes - offset, B_PAGE_SIZE); status = (*addressSpace->translation_map.ops->query)(&addressSpace->translation_map, @@ -2275,6 +2277,12 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long if (status < 0) break; + if (index < 0 && pageOffset > 0) { + physicalAddress += pageOffset; + if (bytes > B_PAGE_SIZE - pageOffset) + bytes = B_PAGE_SIZE - pageOffset; + } + // need to switch to the next physical_entry? if (index < 0 || (addr_t)table[index].address != physicalAddress - table[index].size) { if (++index + 1 > numEntries) { @@ -2288,6 +2296,8 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long // page does fit in current entry table[index].size += bytes; } + + offset += bytes; } (*addressSpace->translation_map.ops->unlock)(&addressSpace->translation_map);