提交 1b93142d 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

compare-and-swap for installing page tables

上级 39b1cf6b
...@@ -62,9 +62,11 @@ walkpgdir(pde_t *pgdir, const void *va, int create) ...@@ -62,9 +62,11 @@ walkpgdir(pde_t *pgdir, const void *va, int create)
pde_t *pde; pde_t *pde;
pte_t *pgtab; pte_t *pgtab;
retry:
pde = &pgdir[PDX(va)]; pde = &pgdir[PDX(va)];
if(*pde & PTE_P){ pde_t pdev = *pde;
pgtab = (pte_t*)PTE_ADDR(*pde); if(pdev & PTE_P){
pgtab = (pte_t*)PTE_ADDR(pdev);
} else { } else {
if(!create || (pgtab = (pte_t*)kalloc()) == 0) if(!create || (pgtab = (pte_t*)kalloc()) == 0)
return 0; return 0;
...@@ -73,7 +75,10 @@ walkpgdir(pde_t *pgdir, const void *va, int create) ...@@ -73,7 +75,10 @@ walkpgdir(pde_t *pgdir, const void *va, int create)
// The permissions here are overly generous, but they can // The permissions here are overly generous, but they can
// be further restricted by the permissions in the page table // be further restricted by the permissions in the page table
// entries, if necessary. // entries, if necessary.
*pde = PADDR(pgtab) | PTE_P | PTE_W | PTE_U; if (!__sync_bool_compare_and_swap(pde, pdev, PADDR(pgtab) | PTE_P | PTE_W | PTE_U)) {
kfree((void*) pgtab);
goto retry;
}
} }
return &pgtab[PTX(va)]; return &pgtab[PTX(va)];
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论