vm_test_map_{modification|activation}(), vm_clear_map_flags(), and

vm_remove_all_page_mappings() all computed the wrong virtual address for the
page in question, and would therefore return incorrect data!
Introduced a virtual_page_address() function that is now used by all of them.
So that's why we were still "losing" modified flags - it took me some hours
to find those (sometimes processes died after stealing pages)...


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22498 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-10-10 09:58:25 +00:00
parent 1f48250890
commit 013f781f47
+16 -9
View File
@@ -2379,6 +2379,14 @@ vm_get_page_mapping(team_id team, addr_t vaddr, addr_t *paddr)
}
static inline addr_t
virtual_page_address(vm_area *area, vm_page *page)
{
return area->base
+ ((page->cache_offset << PAGE_SHIFT) - area->cache_offset);
}
bool
vm_test_map_modification(vm_page *page)
{
@@ -2393,8 +2401,8 @@ vm_test_map_modification(vm_page *page)
addr_t physicalAddress;
uint32 flags;
map->ops->lock(map);
addr_t address = area->base + (page->cache_offset << PAGE_SHIFT);
map->ops->query_interrupt(map, address, &physicalAddress, &flags);
map->ops->query(map, virtual_page_address(area, page),
&physicalAddress, &flags);
map->ops->unlock(map);
if (flags & PAGE_MODIFIED)
@@ -2422,8 +2430,8 @@ vm_test_map_activation(vm_page *page, bool *_modified)
addr_t physicalAddress;
uint32 flags;
map->ops->lock(map);
addr_t address = area->base + (page->cache_offset << PAGE_SHIFT);
map->ops->query_interrupt(map, address, &physicalAddress, &flags);
map->ops->query(map, virtual_page_address(area, page),
&physicalAddress, &flags);
map->ops->unlock(map);
if (flags & PAGE_ACCESSED)
@@ -2451,8 +2459,7 @@ vm_clear_map_flags(vm_page *page, uint32 flags)
vm_translation_map *map = &area->address_space->translation_map;
map->ops->lock(map);
addr_t address = area->base + (page->cache_offset << PAGE_SHIFT);
map->ops->clear_flags(map, address, flags);
map->ops->clear_flags(map, virtual_page_address(area, page), flags);
map->ops->unlock(map);
}
}
@@ -2480,10 +2487,10 @@ vm_remove_all_page_mappings(vm_page *page, uint32 *_flags)
uint32 flags;
map->ops->lock(map);
addr_t base = area->base + (page->cache_offset << PAGE_SHIFT);
map->ops->unmap(map, base, base + (B_PAGE_SIZE - 1));
addr_t address = virtual_page_address(area, page);
map->ops->unmap(map, address, address + (B_PAGE_SIZE - 1));
map->ops->flush(map);
map->ops->query(map, base, &physicalAddress, &flags);
map->ops->query(map, address, &physicalAddress, &flags);
map->ops->unlock(map);
area->mappings.Remove(mapping);