diff options
author | Dave Airlie <airlied@redhat.com> | 2015-04-20 04:32:26 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-04-20 06:05:20 +0300 |
commit | 2c33ce009ca2389dbf0535d0672214d09738e35e (patch) | |
tree | 6186a6458c3c160385d794a23eaf07c786a9e61b /arch/tile/mm | |
parent | cec32a47010647e8b0603726ebb75b990a4057a4 (diff) | |
parent | 09d51602cf84a1264946711dd4ea0dddbac599a1 (diff) | |
download | linux-2c33ce009ca2389dbf0535d0672214d09738e35e.tar.xz |
Merge Linus master into drm-next
The merge is clean, but the arm build fails afterwards,
due to API changes in the regulator tree.
I've included the patch into the merge to fix the build.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'arch/tile/mm')
-rw-r--r-- | arch/tile/mm/elf.c | 47 | ||||
-rw-r--r-- | arch/tile/mm/fault.c | 10 | ||||
-rw-r--r-- | arch/tile/mm/init.c | 7 |
3 files changed, 41 insertions, 23 deletions
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c index 23f044e8a7ab..f7ddae3725a4 100644 --- a/arch/tile/mm/elf.c +++ b/arch/tile/mm/elf.c @@ -17,6 +17,7 @@ #include <linux/binfmts.h> #include <linux/compat.h> #include <linux/mman.h> +#include <linux/file.h> #include <linux/elf.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> @@ -39,30 +40,34 @@ static void sim_notify_exec(const char *binary_name) static int notify_exec(struct mm_struct *mm) { + int ret = 0; char *buf, *path; struct vm_area_struct *vma; + struct file *exe_file; if (!sim_is_simulator()) return 1; - if (mm->exe_file == NULL) - return 0; - - for (vma = current->mm->mmap; ; vma = vma->vm_next) { - if (vma == NULL) - return 0; - if (vma->vm_file == mm->exe_file) - break; - } - buf = (char *) __get_free_page(GFP_KERNEL); if (buf == NULL) return 0; - path = d_path(&mm->exe_file->f_path, buf, PAGE_SIZE); - if (IS_ERR(path)) { - free_page((unsigned long)buf); - return 0; + exe_file = get_mm_exe_file(mm); + if (exe_file == NULL) + goto done_free; + + path = d_path(&exe_file->f_path, buf, PAGE_SIZE); + if (IS_ERR(path)) + goto done_put; + + down_read(&mm->mmap_sem); + for (vma = current->mm->mmap; ; vma = vma->vm_next) { + if (vma == NULL) { + up_read(&mm->mmap_sem); + goto done_put; + } + if (vma->vm_file == exe_file) + break; } /* @@ -80,14 +85,20 @@ static int notify_exec(struct mm_struct *mm) __insn_mtspr(SPR_SIM_CONTROL, (SIM_CONTROL_DLOPEN | (c << _SIM_CONTROL_OPERATOR_BITS))); - if (c == '\0') + if (c == '\0') { + ret = 1; /* success */ break; + } } } + up_read(&mm->mmap_sem); sim_notify_exec(path); +done_put: + fput(exe_file); +done_free: free_page((unsigned long)buf); - return 1; + return ret; } /* Notify a running simulator, if any, that we loaded an interpreter. */ @@ -109,8 +120,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, struct mm_struct *mm = current->mm; int retval = 0; - down_write(&mm->mmap_sem); - /* * Notify the simulator that an exec just occurred. * If we can't find the filename of the mapping, just use @@ -119,6 +128,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, if (!notify_exec(mm)) sim_notify_exec(bprm->filename); + down_write(&mm->mmap_sem); + retval = setup_vdso_pages(); #ifndef __tilegx__ diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c index 0f61a73534e6..e83cc999da02 100644 --- a/arch/tile/mm/fault.c +++ b/arch/tile/mm/fault.c @@ -35,6 +35,7 @@ #include <linux/syscalls.h> #include <linux/uaccess.h> #include <linux/kdebug.h> +#include <linux/context_tracking.h> #include <asm/pgalloc.h> #include <asm/sections.h> @@ -702,6 +703,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, unsigned long address, unsigned long write) { int is_page_fault; + enum ctx_state prev_state = exception_enter(); #ifdef CONFIG_KPROBES /* @@ -711,7 +713,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num, */ if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1, regs->faultnum, SIGSEGV) == NOTIFY_STOP) - return; + goto done; #endif #ifdef __tilegx__ @@ -750,7 +752,6 @@ void do_page_fault(struct pt_regs *regs, int fault_num, current->comm, current->pid, pc, address); show_regs(regs); do_group_exit(SIGKILL); - return; } } #else @@ -834,12 +835,15 @@ void do_page_fault(struct pt_regs *regs, int fault_num, async->is_fault = is_page_fault; async->is_write = write; async->address = address; - return; + goto done; } } #endif handle_page_fault(regs, fault_num, is_page_fault, address, write); + +done: + exception_exit(prev_state); } diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index ace32d7d3864..5bd252e3fdc5 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c @@ -233,9 +233,12 @@ static pgprot_t __init init_pgprot(ulong address) if (kdata_huge) return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); - /* We map the aliased pages of permanent text inaccessible. */ + /* + * We map the aliased pages of permanent text so we can + * update them if necessary, for ftrace, etc. + */ if (address < (ulong) _sinittext - CODE_DELTA) - return PAGE_NONE; + return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); /* We map read-only data non-coherent for performance. */ if ((address >= (ulong) __start_rodata && |