Skip to content

Commit f08d08f

Browse files
kvaneeshmpe
authored andcommitted
powerpc/mm/radix: Only need the Nest MMU workaround for R -> RW transition
The Nest MMU workaround is only needed for RW upgrades. Avoid doing that for other PTE updates. We also avoid clearing the PTE while marking it invalid. This is because other page table walkers will find this PTE none and can result in unexpected behaviour due to that. Instead we clear _PAGE_PRESENT and set the software PTE bit _PAGE_INVALID. pte_present() is already updated to check for both bits. This makes sure page table walkers will find the PTE present and things like pte_pfn(pte) returns the right value. Based on an original patch from Benjamin Herrenschmidt <[email protected]> Signed-off-by: Aneesh Kumar K.V <[email protected]> Reviewed-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent bd0dbb7 commit f08d08f

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

arch/powerpc/mm/pgtable-radix.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,20 +1045,22 @@ void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
10451045
struct mm_struct *mm = vma->vm_mm;
10461046
unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
10471047
_PAGE_RW | _PAGE_EXEC);
1048+
1049+
unsigned long change = pte_val(entry) ^ pte_val(*ptep);
10481050
/*
10491051
* To avoid NMMU hang while relaxing access, we need mark
10501052
* the pte invalid in between.
10511053
*/
1052-
if (atomic_read(&mm->context.copros) > 0) {
1054+
if ((change & _PAGE_RW) && atomic_read(&mm->context.copros) > 0) {
10531055
unsigned long old_pte, new_pte;
10541056

1055-
old_pte = __radix_pte_update(ptep, ~0, 0);
1057+
old_pte = __radix_pte_update(ptep, _PAGE_PRESENT, _PAGE_INVALID);
10561058
/*
10571059
* new value of pte
10581060
*/
10591061
new_pte = old_pte | set;
10601062
radix__flush_tlb_page_psize(mm, address, psize);
1061-
__radix_pte_update(ptep, 0, new_pte);
1063+
__radix_pte_update(ptep, _PAGE_INVALID, new_pte);
10621064
} else {
10631065
__radix_pte_update(ptep, 0, set);
10641066
/*

0 commit comments

Comments
 (0)