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