linux/arch/powerpc/include/asm/book3s/64
Michael Ellerman a58007621b powerpc/64s: Fix possible corruption on big endian due to pgd/pud_present()
In v4.20 we changed our pgd/pud_present() to check for _PAGE_PRESENT
rather than just checking that the value is non-zero, e.g.:

  static inline int pgd_present(pgd_t pgd)
  {
 -       return !pgd_none(pgd);
 +       return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
  }

Unfortunately this is broken on big endian, as the result of the
bitwise & is truncated to int, which is always zero because
_PAGE_PRESENT is 0x8000000000000000ul. This means pgd_present() and
pud_present() are always false at compile time, and the compiler
elides the subsequent code.

Remarkably with that bug present we are still able to boot and run
with few noticeable effects. However under some work loads we are able
to trigger a warning in the ext4 code:

  WARNING: CPU: 11 PID: 29593 at fs/ext4/inode.c:3927 .ext4_set_page_dirty+0x70/0xb0
  CPU: 11 PID: 29593 Comm: debugedit Not tainted 4.20.0-rc1 #1
  ...
  NIP .ext4_set_page_dirty+0x70/0xb0
  LR  .set_page_dirty+0xa0/0x150
  Call Trace:
   .set_page_dirty+0xa0/0x150
   .unmap_page_range+0xbf0/0xe10
   .unmap_vmas+0x84/0x130
   .unmap_region+0xe8/0x190
   .__do_munmap+0x2f0/0x510
   .__vm_munmap+0x80/0x110
   .__se_sys_munmap+0x14/0x30
   system_call+0x5c/0x70

The fix is simple, we need to convert the result of the bitwise & to
an int before returning it.

Thanks to Erhard, Jan Kara and Aneesh for help with debugging.

Fixes: da7ad366b4 ("powerpc/mm/book3s: Update pmd_present to look at _PAGE_PRESENT bit")
Cc: stable@vger.kernel.org # v4.20+
Reported-by: Erhard F. <erhard_f@mailbox.org>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2019-02-17 15:24:45 +11:00
..
hash-4k.h powerpc/mm: Remove very old comment in hash-4k.h 2018-12-22 21:04:27 +11:00
hash-64k.h powerpc/mm/hash: Remove unnecessary do { } while(0) loop 2018-08-10 22:25:57 +10:00
hash.h powerpc: handover page flags with a pgprot_t parameter 2018-10-14 18:04:09 +11:00
hugetlb.h powerpc/mm/hugetlb/book3s: add _PAGE_PRESENT to hugepd pointer. 2018-10-03 15:39:58 +10:00
mmu-hash.h powerpc updates for 4.20 2018-10-26 14:36:21 -07:00
mmu.h powerpc/mm: Move pgtable_t into platform headers 2018-12-04 19:45:01 +11:00
pgalloc.h mm: treewide: remove unused address argument from pte_alloc functions 2019-01-04 13:13:47 -08:00
pgtable-4k.h powerpc/mm/hash/4k: Free hugetlb page table caches correctly. 2018-06-20 09:13:25 +10:00
pgtable-64k.h powerpc/mm/thp: update pmd_trans_huge to check for pmd_present 2018-10-03 15:40:00 +10:00
pgtable.h powerpc/64s: Fix possible corruption on big endian due to pgd/pud_present() 2019-02-17 15:24:45 +11:00
radix-4k.h powerpc/mm: Implement helpers for pagetable fragment support at PMD level 2018-05-15 22:29:12 +10:00
radix-64k.h powerpc/mm: Implement helpers for pagetable fragment support at PMD level 2018-05-15 22:29:12 +10:00
radix.h powerpc/mm/book3s/radix: Add mapping statistics 2018-08-13 16:35:05 +10:00
slice.h powerpc/mm/slice: create header files dedicated to slices 2018-03-06 09:21:22 +11:00
tlbflush-hash.h powerpc/64s: Improve local TLB flush for boot and MCE on POWER9 2018-01-18 00:40:31 +11:00
tlbflush-radix.h KVM: PPC: Book3S HV: Handle page fault for a nested guest 2018-10-09 16:04:27 +11:00
tlbflush.h powerpc/64s/radix: do not flush TLB on spurious fault 2018-06-03 20:40:35 +10:00