diff options
author | Alan Cox <alc@FreeBSD.org> | 2008-08-07 04:56:29 +0000 |
---|---|---|
committer | Alan Cox <alc@FreeBSD.org> | 2008-08-07 04:56:29 +0000 |
commit | 517abd0e4e2405a281f7b8f9d0d8218ed00ab806 (patch) | |
tree | 345b1256fbecffa8cf7bf7f55ed1abf5560c573c /sys/amd64 | |
parent | 5a97b29aa5afc08c4d9bb1426fd52b0fb86b7ccd (diff) | |
download | src-517abd0e4e2405a281f7b8f9d0d8218ed00ab806.tar.gz src-517abd0e4e2405a281f7b8f9d0d8218ed00ab806.zip |
Introduce pmap_change_attr_locked().
Notes
Notes:
svn path=/head/; revision=181356
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index c72711d88ded..cde54efa9269 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -221,6 +221,7 @@ static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va); static int pmap_pvh_wired_mappings(struct md_page *pvh, int count); +static int pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode); static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); static boolean_t pmap_demote_pdpe(pmap_t pmap, pdp_entry_t *pdpe, vm_offset_t va); @@ -4419,6 +4420,17 @@ pmap_demote_pdpe(pmap_t pmap, pdp_entry_t *pdpe, vm_offset_t va) int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) { + int error; + + PMAP_LOCK(kernel_pmap); + error = pmap_change_attr_locked(va, size, mode); + PMAP_UNLOCK(kernel_pmap); + return (error); +} + +static int +pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) +{ vm_offset_t base, offset, tmpva; pdp_entry_t *pdpe; pd_entry_t *pde; @@ -4426,6 +4438,7 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) int cache_bits_pte, cache_bits_pde; boolean_t changed; + PMAP_LOCK_ASSERT(kernel_pmap, MA_OWNED); base = trunc_page(va); offset = va & PAGE_MASK; size = roundup(offset + size, PAGE_SIZE); @@ -4444,13 +4457,10 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) * Pages that aren't mapped aren't supported. Also break down 2MB pages * into 4KB pages if required. */ - PMAP_LOCK(kernel_pmap); for (tmpva = base; tmpva < base + size; ) { pdpe = pmap_pdpe(kernel_pmap, tmpva); - if (*pdpe == 0) { - PMAP_UNLOCK(kernel_pmap); + if (*pdpe == 0) return (EINVAL); - } if (*pdpe & PG_PS) { /* * If the current 1GB page already has the required @@ -4474,16 +4484,12 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) tmpva += NBPDP; continue; } - if (!pmap_demote_pdpe(kernel_pmap, pdpe, tmpva)) { - PMAP_UNLOCK(kernel_pmap); + if (!pmap_demote_pdpe(kernel_pmap, pdpe, tmpva)) return (ENOMEM); - } } pde = pmap_pdpe_to_pde(pdpe, tmpva); - if (*pde == 0) { - PMAP_UNLOCK(kernel_pmap); + if (*pde == 0) return (EINVAL); - } if (*pde & PG_PS) { /* * If the current 2MB page already has the required @@ -4507,19 +4513,14 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) tmpva += NBPDR; continue; } - if (!pmap_demote_pde(kernel_pmap, pde, tmpva)) { - PMAP_UNLOCK(kernel_pmap); + if (!pmap_demote_pde(kernel_pmap, pde, tmpva)) return (ENOMEM); - } } pte = vtopte(tmpva); - if (*pte == 0) { - PMAP_UNLOCK(kernel_pmap); + if (*pte == 0) return (EINVAL); - } tmpva += PAGE_SIZE; } - PMAP_UNLOCK(kernel_pmap); /* * Ok, all the pages exist, so run through them updating their |