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 | 72932c7ad2cc309b0ba6149aa31faa26aaee54d5 (patch) | |
tree | 6edd42b7d58943f7030a9adab89c5482422ddffa /arch/x86/mm/pageattr.c | |
parent | edeed30589f5defe63ce6aaae56f2b7c855e4520 (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>
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 87 |
1 files changed, 39 insertions, 48 deletions
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 | */ |
304 | static int change_page_attr_set(unsigned long addr, int numpages, | 304 | static 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 | ||
332 | static 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 | */ |
350 | static int change_page_attr_clear(unsigned long addr, int numpages, | 360 | static 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 | ||
377 | int set_memory_uc(unsigned long addr, int numpages) | 388 | static 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 | |||
398 | int 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 | } |
386 | EXPORT_SYMBOL(set_memory_uc); | 403 | EXPORT_SYMBOL(set_memory_uc); |
387 | 404 | ||
388 | int set_memory_wb(unsigned long addr, int numpages) | 405 | int 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 | } |
397 | EXPORT_SYMBOL(set_memory_wb); | 410 | EXPORT_SYMBOL(set_memory_wb); |
398 | 411 | ||
399 | int set_memory_x(unsigned long addr, int numpages) | 412 | int 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 | } |
408 | EXPORT_SYMBOL(set_memory_x); | 416 | EXPORT_SYMBOL(set_memory_x); |
409 | 417 | ||
410 | int set_memory_nx(unsigned long addr, int numpages) | 418 | int 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 | } |
419 | EXPORT_SYMBOL(set_memory_nx); | 422 | EXPORT_SYMBOL(set_memory_nx); |
420 | 423 | ||
421 | int set_memory_ro(unsigned long addr, int numpages) | 424 | int 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 | ||
431 | int set_memory_rw(unsigned long addr, int numpages) | 429 | int 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 | ||
441 | int set_memory_np(unsigned long addr, int numpages) | 434 | int 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 | ||
451 | int set_pages_uc(struct page *page, int numpages) | 439 | int set_pages_uc(struct page *page, int numpages) |
@@ -500,14 +488,17 @@ int set_pages_rw(struct page *page, int numpages) | |||
500 | static int __set_pages_p(struct page *page, int numpages) | 488 | static 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 | ||
507 | static int __set_pages_np(struct page *page, int numpages) | 496 | static 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 | ||
513 | void kernel_map_pages(struct page *page, int numpages, int enable) | 504 | void kernel_map_pages(struct page *page, int numpages, int enable) |