diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/mm/fault.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 73ccb6010c05..9150ffaff9e8 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -112,11 +112,17 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
112 | down_read(&mm->mmap_sem); | 112 | down_read(&mm->mmap_sem); |
113 | 113 | ||
114 | vma = find_vma_prev(mm, address, &prev_vma); | 114 | vma = find_vma_prev(mm, address, &prev_vma); |
115 | if (!vma) | 115 | if (!vma && !prev_vma ) |
116 | goto bad_area; | 116 | goto bad_area; |
117 | 117 | ||
118 | /* find_vma_prev() returns vma such that address < vma->vm_end or NULL */ | 118 | /* |
119 | if (address < vma->vm_start) | 119 | * find_vma_prev() returns vma such that address < vma->vm_end or NULL |
120 | * | ||
121 | * May find no vma, but could be that the last vm area is the | ||
122 | * register backing store that needs to expand upwards, in | ||
123 | * this case vma will be null, but prev_vma will ne non-null | ||
124 | */ | ||
125 | if (( !vma && prev_vma ) || (address < vma->vm_start) ) | ||
120 | goto check_expansion; | 126 | goto check_expansion; |
121 | 127 | ||
122 | good_area: | 128 | good_area: |
@@ -172,6 +178,8 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
172 | 178 | ||
173 | check_expansion: | 179 | check_expansion: |
174 | if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) { | 180 | if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) { |
181 | if (!vma) | ||
182 | goto bad_area; | ||
175 | if (!(vma->vm_flags & VM_GROWSDOWN)) | 183 | if (!(vma->vm_flags & VM_GROWSDOWN)) |
176 | goto bad_area; | 184 | goto bad_area; |
177 | if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start) | 185 | if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start) |