diff options
Diffstat (limited to 'arch/powerpc/mm/pgtable-book3s64.c')
| -rw-r--r-- | arch/powerpc/mm/pgtable-book3s64.c | 47 | 
1 files changed, 47 insertions, 0 deletions
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c index f3c31f5e1026..e7da590c7a78 100644 --- a/arch/powerpc/mm/pgtable-book3s64.c +++ b/arch/powerpc/mm/pgtable-book3s64.c @@ -400,3 +400,50 @@ void arch_report_meminfo(struct seq_file *m)  		   atomic_long_read(&direct_pages_count[MMU_PAGE_1G]) << 20);  }  #endif /* CONFIG_PROC_FS */ + +pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, +			     pte_t *ptep) +{ +	unsigned long pte_val; + +	/* +	 * Clear the _PAGE_PRESENT so that no hardware parallel update is +	 * possible. Also keep the pte_present true so that we don't take +	 * wrong fault. +	 */ +	pte_val = pte_update(vma->vm_mm, addr, ptep, _PAGE_PRESENT, _PAGE_INVALID, 0); + +	return __pte(pte_val); + +} + +void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, +			     pte_t *ptep, pte_t old_pte, pte_t pte) +{ +	if (radix_enabled()) +		return radix__ptep_modify_prot_commit(vma, addr, +						      ptep, old_pte, pte); +	set_pte_at(vma->vm_mm, addr, ptep, pte); +} + +/* + * For hash translation mode, we use the deposited table to store hash slot + * information and they are stored at PTRS_PER_PMD offset from related pmd + * location. Hence a pmd move requires deposit and withdraw. + * + * For radix translation with split pmd ptl, we store the deposited table in the + * pmd page. Hence if we have different pmd page we need to withdraw during pmd + * move. + * + * With hash we use deposited table always irrespective of anon or not. + * With radix we use deposited table only for anonymous mapping. + */ +int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, +			   struct spinlock *old_pmd_ptl, +			   struct vm_area_struct *vma) +{ +	if (radix_enabled()) +		return (new_pmd_ptl != old_pmd_ptl) && vma_is_anonymous(vma); + +	return true; +}  |