From 6e601ee88fa21e28c910ff4b5a382a362fa5963b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 11 Mar 2007 13:27:42 +0000 Subject: [PATCH] get_memory_map() now panics (and fails) in case it was called on unmapped memory as suggested by Ingo; before it would just fill the physical pages with NULL pointers. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20364 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/vm_translation_map.h | 17 +++++++++++------ .../kernel/arch/x86/arch_vm_translation_map.c | 8 +++++++- src/system/kernel/vm/vm.cpp | 8 ++++++-- src/system/kernel/vm/vm_page.c | 4 +++- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/headers/private/kernel/vm_translation_map.h b/headers/private/kernel/vm_translation_map.h index ccc155be72..fd13a53b50 100644 --- a/headers/private/kernel/vm_translation_map.h +++ b/headers/private/kernel/vm_translation_map.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006, Haiku. All rights reserved. + * Copyright 2002-2007, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -30,15 +30,20 @@ typedef struct vm_translation_map_ops { void (*destroy)(vm_translation_map *map); status_t (*lock)(vm_translation_map *map); status_t (*unlock)(vm_translation_map *map); - status_t (*map)(vm_translation_map *map, addr_t va, addr_t pa, uint32 attributes); + status_t (*map)(vm_translation_map *map, addr_t va, addr_t pa, + uint32 attributes); status_t (*unmap)(vm_translation_map *map, addr_t start, addr_t end); - status_t (*query)(vm_translation_map *map, addr_t va, addr_t *_outPhysical, uint32 *_outFlags); - status_t (*query_interrupt)(vm_translation_map *map, addr_t va, addr_t *_outPhysical); + status_t (*query)(vm_translation_map *map, addr_t va, addr_t *_outPhysical, + uint32 *_outFlags); + status_t (*query_interrupt)(vm_translation_map *map, addr_t va, + addr_t *_outPhysical, uint32 *_outFlags); addr_t (*get_mapped_size)(vm_translation_map*); - status_t (*protect)(vm_translation_map *map, addr_t base, addr_t top, uint32 attributes); + status_t (*protect)(vm_translation_map *map, addr_t base, addr_t top, + uint32 attributes); status_t (*clear_flags)(vm_translation_map *map, addr_t va, uint32 flags); void (*flush)(vm_translation_map *map); - status_t (*get_physical_page)(addr_t physicalAddress, addr_t *_virtualAddress, uint32 flags); + status_t (*get_physical_page)(addr_t physicalAddress, + addr_t *_virtualAddress, uint32 flags); status_t (*put_physical_page)(addr_t virtualAddress); } vm_translation_map_ops; diff --git a/src/system/kernel/arch/x86/arch_vm_translation_map.c b/src/system/kernel/arch/x86/arch_vm_translation_map.c index 8ee1404fb5..ad47a0677a 100644 --- a/src/system/kernel/arch/x86/arch_vm_translation_map.c +++ b/src/system/kernel/arch/x86/arch_vm_translation_map.c @@ -443,7 +443,8 @@ restart: static status_t -query_tmap_interrupt(vm_translation_map *map, addr_t va, addr_t *_physical) +query_tmap_interrupt(vm_translation_map *map, addr_t va, addr_t *_physical, + uint32 *_flags) { page_directory_entry *pd = map->arch_data->pgdir_virt; page_table_entry *pt; @@ -477,6 +478,11 @@ query_tmap_interrupt(vm_translation_map *map, addr_t va, addr_t *_physical) index = VADDR_TO_PTENT(va); *_physical = ADDR_REVERSE_SHIFT(pt[index].addr); + *_flags |= ((pt[index].rw ? B_KERNEL_WRITE_AREA : 0) | B_KERNEL_READ_AREA) + | (pt[index].dirty ? PAGE_MODIFIED : 0) + | (pt[index].accessed ? PAGE_ACCESSED : 0) + | (pt[index].present ? PAGE_PRESENT : 0); + return B_OK; } diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index cf3d603adf..d6853c9f70 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -3875,17 +3875,21 @@ get_memory_map(const void *address, ulong numBytes, physical_entry *table, long while (offset < numBytes) { addr_t bytes = min_c(numBytes - offset, B_PAGE_SIZE); + uint32 flags; if (interrupts) { - uint32 flags; status = map->ops->query(map, (addr_t)address + offset, &physicalAddress, &flags); } else { status = map->ops->query_interrupt(map, (addr_t)address + offset, - &physicalAddress); + &physicalAddress, &flags); } if (status < B_OK) break; + if ((flags & PAGE_PRESENT) == 0) { + panic("get_memory_map() called on unmapped memory!"); + return B_BAD_ADDRESS; + } if (index < 0 && pageOffset > 0) { physicalAddress += pageOffset; diff --git a/src/system/kernel/vm/vm_page.c b/src/system/kernel/vm/vm_page.c index 7c147acaf2..189613c462 100644 --- a/src/system/kernel/vm/vm_page.c +++ b/src/system/kernel/vm/vm_page.c @@ -165,11 +165,13 @@ dump_page(int argc, char **argv) if (index == 2) { if (!physical) { vm_address_space *addressSpace = vm_kernel_address_space(); + uint32 flags; + if (thread_get_current_thread()->team->address_space != NULL) addressSpace = thread_get_current_thread()->team->address_space; addressSpace->translation_map.ops->query_interrupt( - &addressSpace->translation_map, address, &address); + &addressSpace->translation_map, address, &address, &flags); } page = vm_lookup_page(address / B_PAGE_SIZE);