diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-12-17 10:25:48 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-12-17 10:25:56 -0500 |
commit | 0d01792300c4d7425eabac9095c603cdb411d2a5 (patch) | |
tree | 91c84873a7ece09888542d612a928e54c2fba6a3 /include | |
parent | da8cadb31b82c9d41fc593c8deab6aa20b162d6b (diff) |
[S390] pud_present/pmd_present bug.
Git commit 3610cce87af0693603db171d5b6f6735f5e3dc5b (yeah my own :-/)
introduced a bug in regard to pud/pmd table entries.
If the address of the page table refered to by a pud/pmd value happens
to have zeroes in the lower 32 bits, pud_present and pmd_present return
false. The obvious effect is that this triggers the BUG_ON in exit_mmap
because some ptes will not get released on process end. Worse is that
the next fault for memory covered by that pud/pmd will allocate another
pmd/pte table and populate the pud/pmd entry. The old page table
entries hanging below this entry are lost!
The fix is simple, properly check against 0. The check is added for
pud_none/pmd_none as well even if these two functions work because
the invalid bit is in the lower 32 bits.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-s390/pgtable.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index f2cc25b74adf..1f530f8a6280 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h | |||
@@ -453,12 +453,12 @@ static inline int pgd_bad(pgd_t pgd) { return 0; } | |||
453 | 453 | ||
454 | static inline int pud_present(pud_t pud) | 454 | static inline int pud_present(pud_t pud) |
455 | { | 455 | { |
456 | return pud_val(pud) & _REGION_ENTRY_ORIGIN; | 456 | return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; |
457 | } | 457 | } |
458 | 458 | ||
459 | static inline int pud_none(pud_t pud) | 459 | static inline int pud_none(pud_t pud) |
460 | { | 460 | { |
461 | return pud_val(pud) & _REGION_ENTRY_INV; | 461 | return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; |
462 | } | 462 | } |
463 | 463 | ||
464 | static inline int pud_bad(pud_t pud) | 464 | static inline int pud_bad(pud_t pud) |
@@ -471,12 +471,12 @@ static inline int pud_bad(pud_t pud) | |||
471 | 471 | ||
472 | static inline int pmd_present(pmd_t pmd) | 472 | static inline int pmd_present(pmd_t pmd) |
473 | { | 473 | { |
474 | return pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN; | 474 | return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; |
475 | } | 475 | } |
476 | 476 | ||
477 | static inline int pmd_none(pmd_t pmd) | 477 | static inline int pmd_none(pmd_t pmd) |
478 | { | 478 | { |
479 | return pmd_val(pmd) & _SEGMENT_ENTRY_INV; | 479 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; |
480 | } | 480 | } |
481 | 481 | ||
482 | static inline int pmd_bad(pmd_t pmd) | 482 | static inline int pmd_bad(pmd_t pmd) |