| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/arch/arm/kernel/swp_emulate.c |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2009 ARM Limited |
|---|
| 5 | 6 | * __user_* functions adapted from include/asm/uaccess.h |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | * |
|---|
| 11 | 8 | * Implements emulation of the SWP/SWPB instructions using load-exclusive and |
|---|
| 12 | 9 | * store-exclusive for processors that have them disabled (or future ones that |
|---|
| .. | .. |
|---|
| 98 | 95 | */ |
|---|
| 99 | 96 | static void set_segfault(struct pt_regs *regs, unsigned long addr) |
|---|
| 100 | 97 | { |
|---|
| 101 | | - siginfo_t info; |
|---|
| 98 | + int si_code; |
|---|
| 102 | 99 | |
|---|
| 103 | | - clear_siginfo(&info); |
|---|
| 104 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 100 | + mmap_read_lock(current->mm); |
|---|
| 105 | 101 | if (find_vma(current->mm, addr) == NULL) |
|---|
| 106 | | - info.si_code = SEGV_MAPERR; |
|---|
| 102 | + si_code = SEGV_MAPERR; |
|---|
| 107 | 103 | else |
|---|
| 108 | | - info.si_code = SEGV_ACCERR; |
|---|
| 109 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 110 | | - |
|---|
| 111 | | - info.si_signo = SIGSEGV; |
|---|
| 112 | | - info.si_errno = 0; |
|---|
| 113 | | - info.si_addr = (void *) instruction_pointer(regs); |
|---|
| 104 | + si_code = SEGV_ACCERR; |
|---|
| 105 | + mmap_read_unlock(current->mm); |
|---|
| 114 | 106 | |
|---|
| 115 | 107 | pr_debug("SWP{B} emulation: access caused memory abort!\n"); |
|---|
| 116 | | - arm_notify_die("Illegal memory access", regs, &info, 0, 0); |
|---|
| 108 | + arm_notify_die("Illegal memory access", regs, |
|---|
| 109 | + SIGSEGV, si_code, |
|---|
| 110 | + (void __user *)instruction_pointer(regs), |
|---|
| 111 | + 0, 0); |
|---|
| 117 | 112 | |
|---|
| 118 | 113 | abtcounter++; |
|---|
| 119 | 114 | } |
|---|
| .. | .. |
|---|
| 200 | 195 | destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data); |
|---|
| 201 | 196 | |
|---|
| 202 | 197 | /* Check access in reasonable access range for both SWP and SWPB */ |
|---|
| 203 | | - if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) { |
|---|
| 198 | + if (!access_ok((void __user *)(address & ~3), 4)) { |
|---|
| 204 | 199 | pr_debug("SWP{B} emulation: access to %p not allowed!\n", |
|---|
| 205 | 200 | (void *)address); |
|---|
| 206 | 201 | res = -EFAULT; |
|---|