Merge commit 'a88f9e27498afaea615ad3e93af4f26df1f84987' into after-upstream-android
[linux-3.10.git] / arch / arm / kernel / process.c
index d12f92e..c86ad0d 100644 (file)
@@ -560,10 +560,11 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
 }
 
 #ifdef CONFIG_MMU
+#ifdef CONFIG_KUSER_HELPERS
 /*
  * The vectors page is always readable from user space for the
- * atomic helpers and the signal restart code. Insert it into the
- * gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
+ * atomic helpers. Insert it into the gate_vma so that it is visible
+ * through ptrace and /proc/<pid>/mem.
  */
 static struct vm_area_struct gate_vma = {
        .vm_start       = 0xffff0000,
@@ -592,9 +593,48 @@ int in_gate_area_no_mm(unsigned long addr)
 {
        return in_gate_area(NULL, addr);
 }
+#define is_gate_vma(vma)       ((vma) = &gate_vma)
+#else
+#define is_gate_vma(vma)       0
+#endif
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-       return (vma == &gate_vma) ? "[vectors]" : NULL;
+       return is_gate_vma(vma) ? "[vectors]" :
+               (vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
+                "[sigpage]" : NULL;
+}
+
+static struct page *signal_page;
+extern struct page *get_signal_page(void);
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+       struct mm_struct *mm = current->mm;
+       unsigned long addr;
+       int ret;
+
+       if (!signal_page)
+               signal_page = get_signal_page();
+       if (!signal_page)
+               return -ENOMEM;
+
+       down_write(&mm->mmap_sem);
+       addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+       if (IS_ERR_VALUE(addr)) {
+               ret = addr;
+               goto up_fail;
+       }
+
+       ret = install_special_mapping(mm, addr, PAGE_SIZE,
+               VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+               &signal_page);
+
+       if (ret == 0)
+               mm->context.sigpage = addr;
+
+ up_fail:
+       up_write(&mm->mmap_sem);
+       return ret;
 }
 #endif