kernel/vm: also honor page protections on copy-on-write
this fixes #17895 Change-Id: Ide6cb044cf96213b4bae7eb62235f988b73c0fb1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5601 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
90d62fd900
commit
8045bb174e
@@ -2510,15 +2510,18 @@ vm_copy_on_write_area(VMCache* lowerCache,
|
|||||||
tempArea = tempArea->cache_next) {
|
tempArea = tempArea->cache_next) {
|
||||||
// The area must be readable in the same way it was
|
// The area must be readable in the same way it was
|
||||||
// previously writable.
|
// previously writable.
|
||||||
uint32 protection = B_KERNEL_READ_AREA;
|
addr_t address = virtual_page_address(tempArea, page);
|
||||||
if ((tempArea->protection & B_READ_AREA) != 0)
|
uint32 protection = 0;
|
||||||
|
uint32 pageProtection = get_area_page_protection(tempArea, address);
|
||||||
|
if ((pageProtection & B_KERNEL_READ_AREA) != 0)
|
||||||
|
protection |= B_KERNEL_READ_AREA;
|
||||||
|
if ((pageProtection & B_READ_AREA) != 0)
|
||||||
protection |= B_READ_AREA;
|
protection |= B_READ_AREA;
|
||||||
|
|
||||||
VMTranslationMap* map
|
VMTranslationMap* map
|
||||||
= tempArea->address_space->TranslationMap();
|
= tempArea->address_space->TranslationMap();
|
||||||
map->Lock();
|
map->Lock();
|
||||||
map->ProtectPage(tempArea,
|
map->ProtectPage(tempArea, address, protection);
|
||||||
virtual_page_address(tempArea, page), protection);
|
|
||||||
map->Unlock();
|
map->Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2529,9 +2532,32 @@ vm_copy_on_write_area(VMCache* lowerCache,
|
|||||||
// just change the protection of all areas
|
// just change the protection of all areas
|
||||||
for (VMArea* tempArea = upperCache->areas; tempArea != NULL;
|
for (VMArea* tempArea = upperCache->areas; tempArea != NULL;
|
||||||
tempArea = tempArea->cache_next) {
|
tempArea = tempArea->cache_next) {
|
||||||
|
if (tempArea->page_protections != NULL) {
|
||||||
|
// Change the protection of all pages in this area.
|
||||||
|
VMTranslationMap* map = tempArea->address_space->TranslationMap();
|
||||||
|
map->Lock();
|
||||||
|
for (VMCachePagesTree::Iterator it = lowerCache->pages.GetIterator();
|
||||||
|
vm_page* page = it.Next();) {
|
||||||
|
// The area must be readable in the same way it was
|
||||||
|
// previously writable.
|
||||||
|
addr_t address = virtual_page_address(tempArea, page);
|
||||||
|
uint32 protection = 0;
|
||||||
|
uint32 pageProtection = get_area_page_protection(tempArea, address);
|
||||||
|
if ((pageProtection & B_KERNEL_READ_AREA) != 0)
|
||||||
|
protection |= B_KERNEL_READ_AREA;
|
||||||
|
if ((pageProtection & B_READ_AREA) != 0)
|
||||||
|
protection |= B_READ_AREA;
|
||||||
|
|
||||||
|
map->ProtectPage(tempArea, address, protection);
|
||||||
|
}
|
||||||
|
map->Unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// The area must be readable in the same way it was previously
|
// The area must be readable in the same way it was previously
|
||||||
// writable.
|
// writable.
|
||||||
uint32 protection = B_KERNEL_READ_AREA;
|
uint32 protection = 0;
|
||||||
|
if ((tempArea->protection & B_KERNEL_READ_AREA) != 0)
|
||||||
|
protection |= B_KERNEL_READ_AREA;
|
||||||
if ((tempArea->protection & B_READ_AREA) != 0)
|
if ((tempArea->protection & B_READ_AREA) != 0)
|
||||||
protection |= B_READ_AREA;
|
protection |= B_READ_AREA;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user