aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/fault-armv.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/fault-armv.c')
-rw-r--r--arch/arm/mm/fault-armv.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 9b906dec1ca1..56036ff04deb 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -65,6 +65,30 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
65 return ret; 65 return ret;
66} 66}
67 67
68#if USE_SPLIT_PTLOCKS
69/*
70 * If we are using split PTE locks, then we need to take the page
71 * lock here. Otherwise we are using shared mm->page_table_lock
72 * which is already locked, thus cannot take it.
73 */
74static inline void do_pte_lock(spinlock_t *ptl)
75{
76 /*
77 * Use nested version here to indicate that we are already
78 * holding one similar spinlock.
79 */
80 spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
81}
82
83static inline void do_pte_unlock(spinlock_t *ptl)
84{
85 spin_unlock(ptl);
86}
87#else /* !USE_SPLIT_PTLOCKS */
88static inline void do_pte_lock(spinlock_t *ptl) {}
89static inline void do_pte_unlock(spinlock_t *ptl) {}
90#endif /* USE_SPLIT_PTLOCKS */
91
68static int adjust_pte(struct vm_area_struct *vma, unsigned long address, 92static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
69 unsigned long pfn) 93 unsigned long pfn)
70{ 94{
@@ -89,11 +113,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
89 */ 113 */
90 ptl = pte_lockptr(vma->vm_mm, pmd); 114 ptl = pte_lockptr(vma->vm_mm, pmd);
91 pte = pte_offset_map_nested(pmd, address); 115 pte = pte_offset_map_nested(pmd, address);
92 spin_lock(ptl); 116 do_pte_lock(ptl);
93 117
94 ret = do_adjust_pte(vma, address, pfn, pte); 118 ret = do_adjust_pte(vma, address, pfn, pte);
95 119
96 spin_unlock(ptl); 120 do_pte_unlock(ptl);
97 pte_unmap_nested(pte); 121 pte_unmap_nested(pte);
98 122
99 return ret; 123 return ret;