arm64: Fix copy-on-write referencing in HugeTLB
authorSteve Capper <steve.capper@arm.com>
Wed, 3 Aug 2016 14:15:55 +0000 (15:15 +0100)
committerWill Deacon <will.deacon@arm.com>
Thu, 4 Aug 2016 12:41:18 +0000 (13:41 +0100)
commit747a70e60b7234e8fd9c35dd2f2db10ac1db231d
tree5c81c992943a916638781bf2fe3a1f4778bf4457
parent04a848106193b134741672f7e4e444b50c70b631
arm64: Fix copy-on-write referencing in HugeTLB

set_pte_at(.) will set or unset the PTE_RDONLY hardware bit before
writing the entry to the table.

This can cause problems with the copy-on-write logic in hugetlb_cow:
 *) hugetlb_cow(.) called to handle a write fault on read only pte,
 *) Before the copy-on-write updates the new page table a call is
    made to pte_same(huge_ptep_get(ptep), pte)), to check for a race,
 *) Because set_pte_at(.) changed the pte, *ptep != pte, and the
    hugetlb_cow(.) code erroneously assumes that it lost the race,
 *) The new page is subsequently freed without being used.

On arm64 this problem only becomes apparent when we apply:
67961f9 mm/hugetlb: fix huge page reserve accounting for private
mappings

When one runs the libhugetlbfs test suite, there are allocation errors
and hugetlbfs pages become erroneously locked in memory as reserved.
(There is a high HugePages_Rsvd: count).

In this patch we introduce pte_same which ignores the PTE_RDONLY bit,
allowing for the libhugetlbfs test suite to pass as expected and
without leaking any reserved HugeTLB pages.

Reported-by: Huang Shijie <shijie.huang@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/pgtable.h