Fix poor VMM locking leading to subtle race conditions
This commit is contained in:
@ -51,9 +51,7 @@ void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint3
|
|||||||
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2);
|
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2);
|
||||||
uint64_t *pte = &pml1[pi.pml1];
|
uint64_t *pte = &pml1[pi.pml1];
|
||||||
|
|
||||||
spinlock_acquire(&spinlock);
|
|
||||||
*pte = (physaddr & ~0xFFF) | (flags & 0x7);
|
*pte = (physaddr & ~0xFFF) | (flags & 0x7);
|
||||||
spinlock_release(&spinlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) {
|
void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) {
|
||||||
@ -64,9 +62,7 @@ void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) {
|
|||||||
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2);
|
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2);
|
||||||
uint64_t *pte = &pml1[pi.pml1];
|
uint64_t *pte = &pml1[pi.pml1];
|
||||||
|
|
||||||
spinlock_acquire(&spinlock);
|
|
||||||
*pte &= ~HAL_PG_PRESENT;
|
*pte &= ~HAL_PG_PRESENT;
|
||||||
spinlock_release(&spinlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags) {
|
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags) {
|
||||||
@ -74,11 +70,13 @@ void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t si
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&spinlock);
|
||||||
uint8_t *vaddr = virtstart, *paddr = physstart;
|
uint8_t *vaddr = virtstart, *paddr = physstart;
|
||||||
|
|
||||||
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
||||||
hal_vmm_map_page(cr3, (uint64_t)vaddr, (uint64_t)paddr, flags);
|
hal_vmm_map_page(cr3, (uint64_t)vaddr, (uint64_t)paddr, flags);
|
||||||
}
|
}
|
||||||
|
spinlock_release(&spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size) {
|
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size) {
|
||||||
@ -86,11 +84,13 @@ void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&spinlock);
|
||||||
uint8_t *vaddr = virtstart, *paddr = physstart;
|
uint8_t *vaddr = virtstart, *paddr = physstart;
|
||||||
|
|
||||||
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
||||||
hal_vmm_unmap_page(cr3, (uint64_t)vaddr, (uint64_t)paddr);
|
hal_vmm_unmap_page(cr3, (uint64_t)vaddr, (uint64_t)paddr);
|
||||||
}
|
}
|
||||||
|
spinlock_release(&spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_vmm_map_kern(PgTable *cr3) {
|
void hal_vmm_map_kern(PgTable *cr3) {
|
||||||
|
Reference in New Issue
Block a user