diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
| -rw-r--r-- | arch/arm/kernel/process.c | 48 | 
1 files changed, 45 insertions, 3 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index d3ca4f6915af..16ed3f7c4980 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -197,6 +197,7 @@ void machine_shutdown(void)   */  void machine_halt(void)  { +	local_irq_disable();  	smp_send_stop();  	local_irq_disable(); @@ -211,6 +212,7 @@ void machine_halt(void)   */  void machine_power_off(void)  { +	local_irq_disable();  	smp_send_stop();  	if (pm_power_off) @@ -230,6 +232,7 @@ void machine_power_off(void)   */  void machine_restart(char *cmd)  { +	local_irq_disable();  	smp_send_stop();  	arm_pm_restart(reboot_mode, cmd); @@ -426,10 +429,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, @@ -458,9 +462,47 @@ 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; +} + +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; +	struct page *page; +	unsigned long addr; +	int ret; + +	page = get_signal_page(); +	if (!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, +		&page); + +	if (ret == 0) +		mm->context.sigpage = addr; + + up_fail: +	up_write(&mm->mmap_sem); +	return ret;  }  #endif  |