diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-02-04 10:48:07 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-02-04 10:48:07 -0500 |
commit | f4ae5da0e8e92caa168e7c2a7c4a6c4064b082c2 (patch) | |
tree | f4b3a98c7e9ea6d158bdc5bf5a479eaeb93c6957 /arch/x86 | |
parent | 72e458dfa63b3db7a46f66b0eb19e9ff4e17fc0e (diff) |
x86: cpa, check if we changed anything and tlb flushing is necessary
Flush tlbs only when there was a real change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/mm/pageattr.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index d1c08308ecbb..79a9f1b42ddd 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -21,6 +21,7 @@ struct cpa_data { | |||
21 | int numpages; | 21 | int numpages; |
22 | pgprot_t mask_set; | 22 | pgprot_t mask_set; |
23 | pgprot_t mask_clr; | 23 | pgprot_t mask_clr; |
24 | int flushtlb; | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | static inline int | 27 | static inline int |
@@ -329,11 +330,19 @@ repeat: | |||
329 | * not the memory it points to | 330 | * not the memory it points to |
330 | */ | 331 | */ |
331 | new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot)); | 332 | new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot)); |
332 | set_pte_atomic(kpte, new_pte); | 333 | |
334 | /* | ||
335 | * Do we really change anything ? | ||
336 | */ | ||
337 | if (pte_val(old_pte) != pte_val(new_pte)) { | ||
338 | set_pte_atomic(kpte, new_pte); | ||
339 | cpa->flushtlb = 1; | ||
340 | } | ||
333 | } else { | 341 | } else { |
334 | err = split_large_page(kpte, address); | 342 | err = split_large_page(kpte, address); |
335 | if (!err) | 343 | if (!err) |
336 | goto repeat; | 344 | goto repeat; |
345 | cpa->flushtlb = 1; | ||
337 | } | 346 | } |
338 | return err; | 347 | return err; |
339 | } | 348 | } |
@@ -438,10 +447,17 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, | |||
438 | cpa.numpages = numpages; | 447 | cpa.numpages = numpages; |
439 | cpa.mask_set = mask_set; | 448 | cpa.mask_set = mask_set; |
440 | cpa.mask_clr = mask_clr; | 449 | cpa.mask_clr = mask_clr; |
450 | cpa.flushtlb = 0; | ||
441 | 451 | ||
442 | ret = __change_page_attr_set_clr(&cpa); | 452 | ret = __change_page_attr_set_clr(&cpa); |
443 | 453 | ||
444 | /* | 454 | /* |
455 | * Check whether we really changed something: | ||
456 | */ | ||
457 | if (!cpa.flushtlb) | ||
458 | return ret; | ||
459 | |||
460 | /* | ||
445 | * No need to flush, when we did not set any of the caching | 461 | * No need to flush, when we did not set any of the caching |
446 | * attributes: | 462 | * attributes: |
447 | */ | 463 | */ |