diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-01-30 07:34:08 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:34:08 -0500 |
commit | ff31452b6ea5032f26f16140d45dc6596260cd9c (patch) | |
tree | b18035ad80e0286737490fdac2f037e1451c92a7 /arch/x86/mm/pageattr.c | |
parent | 72932c7ad2cc309b0ba6149aa31faa26aaee54d5 (diff) |
x86: cpa create set_and_clr function
Create a set_and_clr function to avoid the duplicate loops. Allows
also to do combined operations for optimization.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 55f5b5cdb12e..c54832b75069 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -282,6 +282,45 @@ static int change_page_attr_addr(unsigned long address, pgprot_t prot) | |||
282 | return err; | 282 | return err; |
283 | } | 283 | } |
284 | 284 | ||
285 | static int __change_page_attr_set_clr(unsigned long addr, int numpages, | ||
286 | pgprot_t mask_set, pgprot_t mask_clr) | ||
287 | { | ||
288 | pgprot_t new_prot; | ||
289 | int level; | ||
290 | pte_t *pte; | ||
291 | int i, ret; | ||
292 | |||
293 | for (i = 0; i < numpages ; i++) { | ||
294 | |||
295 | pte = lookup_address(addr, &level); | ||
296 | if (!pte) | ||
297 | return -EINVAL; | ||
298 | |||
299 | new_prot = pte_pgprot(*pte); | ||
300 | |||
301 | pgprot_val(new_prot) &= ~pgprot_val(mask_clr); | ||
302 | pgprot_val(new_prot) |= pgprot_val(mask_set); | ||
303 | |||
304 | ret = change_page_attr_addr(addr, new_prot); | ||
305 | if (ret) | ||
306 | return ret; | ||
307 | addr += PAGE_SIZE; | ||
308 | } | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int change_page_attr_set_clr(unsigned long addr, int numpages, | ||
314 | pgprot_t mask_set, pgprot_t mask_clr) | ||
315 | { | ||
316 | int ret = __change_page_attr_set_clr(addr, numpages, mask_set, | ||
317 | mask_clr); | ||
318 | |||
319 | global_flush_tlb(); | ||
320 | |||
321 | return ret; | ||
322 | } | ||
323 | |||
285 | /** | 324 | /** |
286 | * change_page_attr_set - Change page table attributes in the linear mapping. | 325 | * change_page_attr_set - Change page table attributes in the linear mapping. |
287 | * @addr: Virtual address in linear mapping. | 326 | * @addr: Virtual address in linear mapping. |