aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-01-30 07:34:08 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:34:08 -0500
commit72932c7ad2cc309b0ba6149aa31faa26aaee54d5 (patch)
tree6edd42b7d58943f7030a9adab89c5482422ddffa
parentedeed30589f5defe63ce6aaae56f2b7c855e4520 (diff)
x86: cpa move the flush into set and clear functions
To avoid the modification of the flush code for the clflush implementation, move the flush into the set and clear functions and provide helper functions for the debugging code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/mm/pageattr-test.c8
-rw-r--r--arch/x86/mm/pageattr.c87
2 files changed, 43 insertions, 52 deletions
diff --git a/arch/x86/mm/pageattr-test.c b/arch/x86/mm/pageattr-test.c
index fe73905d075e..4e8b8c6baccd 100644
--- a/arch/x86/mm/pageattr-test.c
+++ b/arch/x86/mm/pageattr-test.c
@@ -162,8 +162,8 @@ static __init int exercise_pageattr(void)
162 continue; 162 continue;
163 } 163 }
164 164
165 err = change_page_attr_clear(addr[i], len[i], 165 err = __change_page_attr_clear(addr[i], len[i],
166 __pgprot(_PAGE_GLOBAL)); 166 __pgprot(_PAGE_GLOBAL));
167 if (err < 0) { 167 if (err < 0) {
168 printk(KERN_ERR "CPA %d failed %d\n", i, err); 168 printk(KERN_ERR "CPA %d failed %d\n", i, err);
169 failed++; 169 failed++;
@@ -197,8 +197,8 @@ static __init int exercise_pageattr(void)
197 failed++; 197 failed++;
198 continue; 198 continue;
199 } 199 }
200 err = change_page_attr_set(addr[i], len[i], 200 err = __change_page_attr_set(addr[i], len[i],
201 __pgprot(_PAGE_GLOBAL)); 201 __pgprot(_PAGE_GLOBAL));
202 if (err < 0) { 202 if (err < 0) {
203 printk(KERN_ERR "CPA reverting failed: %d\n", err); 203 printk(KERN_ERR "CPA reverting failed: %d\n", err);
204 failed++; 204 failed++;
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 145f5edf488a..55f5b5cdb12e 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -301,8 +301,8 @@ static int change_page_attr_addr(unsigned long address, pgprot_t prot)
301 * This function is different from change_page_attr() in that only selected bits 301 * This function is different from change_page_attr() in that only selected bits
302 * are impacted, all other bits remain as is. 302 * are impacted, all other bits remain as is.
303 */ 303 */
304static int change_page_attr_set(unsigned long addr, int numpages, 304static int __change_page_attr_set(unsigned long addr, int numpages,
305 pgprot_t prot) 305 pgprot_t prot)
306{ 306{
307 pgprot_t current_prot, new_prot; 307 pgprot_t current_prot, new_prot;
308 int level; 308 int level;
@@ -325,9 +325,19 @@ static int change_page_attr_set(unsigned long addr, int numpages,
325 return ret; 325 return ret;
326 addr += PAGE_SIZE; 326 addr += PAGE_SIZE;
327 } 327 }
328
328 return 0; 329 return 0;
329} 330}
330 331
332static int change_page_attr_set(unsigned long addr, int numpages, pgprot_t prot)
333{
334 int ret = __change_page_attr_set(addr, numpages, prot);
335
336 global_flush_tlb();
337 return ret;
338
339}
340
331/** 341/**
332 * change_page_attr_clear - Change page table attributes in the linear mapping. 342 * change_page_attr_clear - Change page table attributes in the linear mapping.
333 * @addr: Virtual address in linear mapping. 343 * @addr: Virtual address in linear mapping.
@@ -347,8 +357,8 @@ static int change_page_attr_set(unsigned long addr, int numpages,
347 * This function is different from change_page_attr() in that only selected bits 357 * This function is different from change_page_attr() in that only selected bits
348 * are impacted, all other bits remain as is. 358 * are impacted, all other bits remain as is.
349 */ 359 */
350static int change_page_attr_clear(unsigned long addr, int numpages, 360static int __change_page_attr_clear(unsigned long addr, int numpages,
351 pgprot_t prot) 361 pgprot_t prot)
352{ 362{
353 pgprot_t current_prot, new_prot; 363 pgprot_t current_prot, new_prot;
354 int level; 364 int level;
@@ -371,81 +381,59 @@ static int change_page_attr_clear(unsigned long addr, int numpages,
371 return ret; 381 return ret;
372 addr += PAGE_SIZE; 382 addr += PAGE_SIZE;
373 } 383 }
384
374 return 0; 385 return 0;
375} 386}
376 387
377int set_memory_uc(unsigned long addr, int numpages) 388static int change_page_attr_clear(unsigned long addr, int numpages,
389 pgprot_t prot)
378{ 390{
379 int err; 391 int ret = __change_page_attr_clear(addr, numpages, prot);
380 392
381 err = change_page_attr_set(addr, numpages,
382 __pgprot(_PAGE_PCD | _PAGE_PWT));
383 global_flush_tlb(); 393 global_flush_tlb();
384 return err; 394 return ret;
395
396}
397
398int set_memory_uc(unsigned long addr, int numpages)
399{
400 return change_page_attr_set(addr, numpages,
401 __pgprot(_PAGE_PCD | _PAGE_PWT));
385} 402}
386EXPORT_SYMBOL(set_memory_uc); 403EXPORT_SYMBOL(set_memory_uc);
387 404
388int set_memory_wb(unsigned long addr, int numpages) 405int set_memory_wb(unsigned long addr, int numpages)
389{ 406{
390 int err; 407 return change_page_attr_clear(addr, numpages,
391 408 __pgprot(_PAGE_PCD | _PAGE_PWT));
392 err = change_page_attr_clear(addr, numpages,
393 __pgprot(_PAGE_PCD | _PAGE_PWT));
394 global_flush_tlb();
395 return err;
396} 409}
397EXPORT_SYMBOL(set_memory_wb); 410EXPORT_SYMBOL(set_memory_wb);
398 411
399int set_memory_x(unsigned long addr, int numpages) 412int set_memory_x(unsigned long addr, int numpages)
400{ 413{
401 int err; 414 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_NX));
402
403 err = change_page_attr_clear(addr, numpages,
404 __pgprot(_PAGE_NX));
405 global_flush_tlb();
406 return err;
407} 415}
408EXPORT_SYMBOL(set_memory_x); 416EXPORT_SYMBOL(set_memory_x);
409 417
410int set_memory_nx(unsigned long addr, int numpages) 418int set_memory_nx(unsigned long addr, int numpages)
411{ 419{
412 int err; 420 return change_page_attr_set(addr, numpages, __pgprot(_PAGE_NX));
413
414 err = change_page_attr_set(addr, numpages,
415 __pgprot(_PAGE_NX));
416 global_flush_tlb();
417 return err;
418} 421}
419EXPORT_SYMBOL(set_memory_nx); 422EXPORT_SYMBOL(set_memory_nx);
420 423
421int set_memory_ro(unsigned long addr, int numpages) 424int set_memory_ro(unsigned long addr, int numpages)
422{ 425{
423 int err; 426 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_RW));
424
425 err = change_page_attr_clear(addr, numpages,
426 __pgprot(_PAGE_RW));
427 global_flush_tlb();
428 return err;
429} 427}
430 428
431int set_memory_rw(unsigned long addr, int numpages) 429int set_memory_rw(unsigned long addr, int numpages)
432{ 430{
433 int err; 431 return change_page_attr_set(addr, numpages, __pgprot(_PAGE_RW));
434
435 err = change_page_attr_set(addr, numpages,
436 __pgprot(_PAGE_RW));
437 global_flush_tlb();
438 return err;
439} 432}
440 433
441int set_memory_np(unsigned long addr, int numpages) 434int set_memory_np(unsigned long addr, int numpages)
442{ 435{
443 int err; 436 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_PRESENT));
444
445 err = change_page_attr_clear(addr, numpages,
446 __pgprot(_PAGE_PRESENT));
447 global_flush_tlb();
448 return err;
449} 437}
450 438
451int set_pages_uc(struct page *page, int numpages) 439int set_pages_uc(struct page *page, int numpages)
@@ -500,14 +488,17 @@ int set_pages_rw(struct page *page, int numpages)
500static int __set_pages_p(struct page *page, int numpages) 488static int __set_pages_p(struct page *page, int numpages)
501{ 489{
502 unsigned long addr = (unsigned long)page_address(page); 490 unsigned long addr = (unsigned long)page_address(page);
503 return change_page_attr_set(addr, numpages, 491
504 __pgprot(_PAGE_PRESENT | _PAGE_RW)); 492 return __change_page_attr_set(addr, numpages,
493 __pgprot(_PAGE_PRESENT | _PAGE_RW));
505} 494}
506 495
507static int __set_pages_np(struct page *page, int numpages) 496static int __set_pages_np(struct page *page, int numpages)
508{ 497{
509 unsigned long addr = (unsigned long)page_address(page); 498 unsigned long addr = (unsigned long)page_address(page);
510 return change_page_attr_clear(addr, numpages, __pgprot(_PAGE_PRESENT)); 499
500 return __change_page_attr_clear(addr, numpages,
501 __pgprot(_PAGE_PRESENT));
511} 502}
512 503
513void kernel_map_pages(struct page *page, int numpages, int enable) 504void kernel_map_pages(struct page *page, int numpages, int enable)