Sun Nov 1 20:56:24 2020 UTC ()
Typo in a trap name


(skrll)
diff -r1.7 -r1.8 src/sys/arch/riscv/riscv/trap.c

cvs diff -r1.7 -r1.8 src/sys/arch/riscv/riscv/trap.c (switch to unified diff)

--- src/sys/arch/riscv/riscv/trap.c 2020/06/30 16:20:02 1.7
+++ src/sys/arch/riscv/riscv/trap.c 2020/11/01 20:56:24 1.8
@@ -1,556 +1,556 @@ @@ -1,556 +1,556 @@
1/*- 1/*-
2 * Copyright (c) 2014 The NetBSD Foundation, Inc. 2 * Copyright (c) 2014 The NetBSD Foundation, Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This code is derived from software contributed to The NetBSD Foundation 5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Matt Thomas of 3am Software Foundry. 6 * by Matt Thomas of 3am Software Foundry.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31 31
32#define __PMAP_PRIVATE 32#define __PMAP_PRIVATE
33#define __UFETCHSTORE_PRIVATE 33#define __UFETCHSTORE_PRIVATE
34 34
35__RCSID("$NetBSD: trap.c,v 1.7 2020/06/30 16:20:02 maxv Exp $"); 35__RCSID("$NetBSD: trap.c,v 1.8 2020/11/01 20:56:24 skrll Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/atomic.h> 39#include <sys/atomic.h>
40 40
41#include <sys/signal.h> 41#include <sys/signal.h>
42#include <sys/signalvar.h> 42#include <sys/signalvar.h>
43#include <sys/siginfo.h> 43#include <sys/siginfo.h>
44 44
45#include <uvm/uvm.h> 45#include <uvm/uvm.h>
46 46
47#include <riscv/locore.h> 47#include <riscv/locore.h>
48 48
49#define INSTRUCTION_TRAP_MASK (__BIT(CAUSE_PRIVILEGED_INSTRUCTION) \ 49#define INSTRUCTION_TRAP_MASK (__BIT(CAUSE_PRIVILEGED_INSTRUCTION) \
50 |__BIT(CAUSE_ILLEGAL_INSTRUCTION)) 50 |__BIT(CAUSE_ILLEGAL_INSTRUCTION))
51 51
52#define FAULT_TRAP_MASK (__BIT(CAUSE_FAULT_FETCH) \ 52#define FAULT_TRAP_MASK (__BIT(CAUSE_FAULT_FETCH) \
53 |__BIT(CAUSE_FAULT_LOAD) \ 53 |__BIT(CAUSE_FAULT_LOAD) \
54 |__BIT(CAUSE_FAULT_STORE)) 54 |__BIT(CAUSE_FAULT_STORE))
55 55
56#define MISALIGNED_TRAP_MASK (__BIT(CAUSE_MISALIGNED_FETCH) \ 56#define MISALIGNED_TRAP_MASK (__BIT(CAUSE_MISALIGNED_FETCH) \
57 |__BIT(CAUSE_MISALIGNED_LOAD) \ 57 |__BIT(CAUSE_MISALIGNED_LOAD) \
58 |__BIT(CAUSE_MISALIGNED_STORE)) 58 |__BIT(CAUSE_MISALIGNED_STORE))
59 59
60static const char * const causenames[] = { 60static const char * const causenames[] = {
61 [CAUSE_MISALIGNED_FETCH] = "misaligned fetch", 61 [CAUSE_MISALIGNED_FETCH] = "misaligned fetch",
62 [CAUSE_MISALIGNED_LOAD] = "mialigned load", 62 [CAUSE_MISALIGNED_LOAD] = "misaligned load",
63 [CAUSE_MISALIGNED_STORE] = "misaligned store", 63 [CAUSE_MISALIGNED_STORE] = "misaligned store",
64 [CAUSE_FAULT_FETCH] = "fetch", 64 [CAUSE_FAULT_FETCH] = "fetch",
65 [CAUSE_FAULT_LOAD] = "load", 65 [CAUSE_FAULT_LOAD] = "load",
66 [CAUSE_FAULT_STORE] = "store", 66 [CAUSE_FAULT_STORE] = "store",
67 [CAUSE_FP_DISABLED] = "fp disabled", 67 [CAUSE_FP_DISABLED] = "fp disabled",
68 [CAUSE_ILLEGAL_INSTRUCTION] = "illegal instruction", 68 [CAUSE_ILLEGAL_INSTRUCTION] = "illegal instruction",
69 [CAUSE_PRIVILEGED_INSTRUCTION] = "privileged instruction", 69 [CAUSE_PRIVILEGED_INSTRUCTION] = "privileged instruction",
70 [CAUSE_BREAKPOINT] = "breakpoint", 70 [CAUSE_BREAKPOINT] = "breakpoint",
71}; 71};
72 72
73void 73void
74cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb) 74cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb)
75{ 75{
76 tf->tf_a0 = fb->fb_reg[FB_A0]; 76 tf->tf_a0 = fb->fb_reg[FB_A0];
77 tf->tf_ra = fb->fb_reg[FB_RA]; 77 tf->tf_ra = fb->fb_reg[FB_RA];
78 tf->tf_s0 = fb->fb_reg[FB_S0]; 78 tf->tf_s0 = fb->fb_reg[FB_S0];
79 tf->tf_s1 = fb->fb_reg[FB_S1]; 79 tf->tf_s1 = fb->fb_reg[FB_S1];
80 tf->tf_s2 = fb->fb_reg[FB_S2]; 80 tf->tf_s2 = fb->fb_reg[FB_S2];
81 tf->tf_s3 = fb->fb_reg[FB_S3]; 81 tf->tf_s3 = fb->fb_reg[FB_S3];
82 tf->tf_s4 = fb->fb_reg[FB_S4]; 82 tf->tf_s4 = fb->fb_reg[FB_S4];
83 tf->tf_s5 = fb->fb_reg[FB_S5]; 83 tf->tf_s5 = fb->fb_reg[FB_S5];
84 tf->tf_s6 = fb->fb_reg[FB_S6]; 84 tf->tf_s6 = fb->fb_reg[FB_S6];
85 tf->tf_s7 = fb->fb_reg[FB_S7]; 85 tf->tf_s7 = fb->fb_reg[FB_S7];
86 tf->tf_s8 = fb->fb_reg[FB_S8]; 86 tf->tf_s8 = fb->fb_reg[FB_S8];
87 tf->tf_s9 = fb->fb_reg[FB_S9]; 87 tf->tf_s9 = fb->fb_reg[FB_S9];
88 tf->tf_s10 = fb->fb_reg[FB_S10]; 88 tf->tf_s10 = fb->fb_reg[FB_S10];
89 tf->tf_s11 = fb->fb_reg[FB_S11]; 89 tf->tf_s11 = fb->fb_reg[FB_S11];
90} 90}
91 91
92int 92int
93copyin(const void *uaddr, void *kaddr, size_t len) 93copyin(const void *uaddr, void *kaddr, size_t len)
94{ 94{
95 struct faultbuf fb; 95 struct faultbuf fb;
96 int error; 96 int error;
97 97
98 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) { 98 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) {
99 memcpy(kaddr, uaddr, len); 99 memcpy(kaddr, uaddr, len);
100 cpu_unset_onfault(); 100 cpu_unset_onfault();
101 } 101 }
102 return error; 102 return error;
103} 103}
104 104
105int 105int
106copyout(const void *kaddr, void *uaddr, size_t len) 106copyout(const void *kaddr, void *uaddr, size_t len)
107{ 107{
108 struct faultbuf fb; 108 struct faultbuf fb;
109 int error; 109 int error;
110 110
111 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) { 111 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) {
112 memcpy(uaddr, kaddr, len); 112 memcpy(uaddr, kaddr, len);
113 cpu_unset_onfault(); 113 cpu_unset_onfault();
114 } 114 }
115 return error; 115 return error;
116} 116}
117 117
118int 118int
119kcopy(const void *kfaddr, void *kdaddr, size_t len) 119kcopy(const void *kfaddr, void *kdaddr, size_t len)
120{ 120{
121 struct faultbuf fb; 121 struct faultbuf fb;
122 int error; 122 int error;
123 123
124 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) { 124 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) {
125 memcpy(kdaddr, kfaddr, len); 125 memcpy(kdaddr, kfaddr, len);
126 cpu_unset_onfault(); 126 cpu_unset_onfault();
127 } 127 }
128 return error; 128 return error;
129} 129}
130 130
131int 131int
132copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 132copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
133{ 133{
134 struct faultbuf fb; 134 struct faultbuf fb;
135 int error; 135 int error;
136 136
137 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) { 137 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) {
138 len = strlcpy(kaddr, uaddr, len); 138 len = strlcpy(kaddr, uaddr, len);
139 cpu_unset_onfault(); 139 cpu_unset_onfault();
140 if (done != NULL) { 140 if (done != NULL) {
141 *done = len; 141 *done = len;
142 } 142 }
143 } 143 }
144 return error; 144 return error;
145} 145}
146 146
147int 147int
148copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done) 148copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done)
149{ 149{
150 struct faultbuf fb; 150 struct faultbuf fb;
151 int error; 151 int error;
152 152
153 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) { 153 if ((error = cpu_set_onfault(&fb, EFAULT)) == 0) {
154 len = strlcpy(uaddr, kaddr, len); 154 len = strlcpy(uaddr, kaddr, len);
155 cpu_unset_onfault(); 155 cpu_unset_onfault();
156 if (done != NULL) { 156 if (done != NULL) {
157 *done = len; 157 *done = len;
158 } 158 }
159 } 159 }
160 return error; 160 return error;
161} 161}
162 162
163static void 163static void
164dump_trapframe(const struct trapframe *tf, void (*pr)(const char *, ...)) 164dump_trapframe(const struct trapframe *tf, void (*pr)(const char *, ...))
165{ 165{
166 const char *causestr = "?"; 166 const char *causestr = "?";
167 if (tf->tf_cause < __arraycount(causenames) 167 if (tf->tf_cause < __arraycount(causenames)
168 && causenames[tf->tf_cause] != NULL) 168 && causenames[tf->tf_cause] != NULL)
169 causestr = causenames[tf->tf_cause]; 169 causestr = causenames[tf->tf_cause];
170 (*pr)("Trapframe @ %p " 170 (*pr)("Trapframe @ %p "
171 "(cause=%d (%s), status=%#x, pc=%#16"PRIxREGISTER 171 "(cause=%d (%s), status=%#x, pc=%#16"PRIxREGISTER
172 ", va=%#"PRIxREGISTER"):\n", 172 ", va=%#"PRIxREGISTER"):\n",
173 tf, tf->tf_cause, causestr, tf->tf_sr, tf->tf_pc, tf->tf_badaddr); 173 tf, tf->tf_cause, causestr, tf->tf_sr, tf->tf_pc, tf->tf_badaddr);
174 (*pr)("ra=%#16"PRIxREGISTER", sp=%#16"PRIxREGISTER 174 (*pr)("ra=%#16"PRIxREGISTER", sp=%#16"PRIxREGISTER
175 ", gp=%#16"PRIxREGISTER", tp=%#16"PRIxREGISTER"\n", 175 ", gp=%#16"PRIxREGISTER", tp=%#16"PRIxREGISTER"\n",
176 tf->tf_ra, tf->tf_sp, tf->tf_gp, tf->tf_tp); 176 tf->tf_ra, tf->tf_sp, tf->tf_gp, tf->tf_tp);
177 (*pr)("s0=%#16"PRIxREGISTER", s1=%#16"PRIxREGISTER 177 (*pr)("s0=%#16"PRIxREGISTER", s1=%#16"PRIxREGISTER
178 ", s2=%#16"PRIxREGISTER", s3=%#16"PRIxREGISTER"\n", 178 ", s2=%#16"PRIxREGISTER", s3=%#16"PRIxREGISTER"\n",
179 tf->tf_s0, tf->tf_s1, tf->tf_s2, tf->tf_s3); 179 tf->tf_s0, tf->tf_s1, tf->tf_s2, tf->tf_s3);
180 (*pr)("s4=%#16"PRIxREGISTER", s5=%#16"PRIxREGISTER 180 (*pr)("s4=%#16"PRIxREGISTER", s5=%#16"PRIxREGISTER
181 ", s5=%#16"PRIxREGISTER", s3=%#16"PRIxREGISTER"\n", 181 ", s5=%#16"PRIxREGISTER", s3=%#16"PRIxREGISTER"\n",
182 tf->tf_s4, tf->tf_s5, tf->tf_s2, tf->tf_s3); 182 tf->tf_s4, tf->tf_s5, tf->tf_s2, tf->tf_s3);
183 (*pr)("s8=%#16"PRIxREGISTER", s9=%#16"PRIxREGISTER 183 (*pr)("s8=%#16"PRIxREGISTER", s9=%#16"PRIxREGISTER
184 ", s10=%#16"PRIxREGISTER", s11=%#16"PRIxREGISTER"\n", 184 ", s10=%#16"PRIxREGISTER", s11=%#16"PRIxREGISTER"\n",
185 tf->tf_s8, tf->tf_s9, tf->tf_s10, tf->tf_s11); 185 tf->tf_s8, tf->tf_s9, tf->tf_s10, tf->tf_s11);
186 (*pr)("a0=%#16"PRIxREGISTER", a1=%#16"PRIxREGISTER 186 (*pr)("a0=%#16"PRIxREGISTER", a1=%#16"PRIxREGISTER
187 ", a2=%#16"PRIxREGISTER", a3=%#16"PRIxREGISTER"\n", 187 ", a2=%#16"PRIxREGISTER", a3=%#16"PRIxREGISTER"\n",
188 tf->tf_a0, tf->tf_a1, tf->tf_a2, tf->tf_a3); 188 tf->tf_a0, tf->tf_a1, tf->tf_a2, tf->tf_a3);
189 (*pr)("a4=%#16"PRIxREGISTER", a5=%#16"PRIxREGISTER 189 (*pr)("a4=%#16"PRIxREGISTER", a5=%#16"PRIxREGISTER
190 ", a5=%#16"PRIxREGISTER", a7=%#16"PRIxREGISTER"\n", 190 ", a5=%#16"PRIxREGISTER", a7=%#16"PRIxREGISTER"\n",
191 tf->tf_a4, tf->tf_a5, tf->tf_a6, tf->tf_a7); 191 tf->tf_a4, tf->tf_a5, tf->tf_a6, tf->tf_a7);
192 (*pr)("t0=%#16"PRIxREGISTER", t1=%#16"PRIxREGISTER 192 (*pr)("t0=%#16"PRIxREGISTER", t1=%#16"PRIxREGISTER
193 ", t2=%#16"PRIxREGISTER", t3=%#16"PRIxREGISTER"\n", 193 ", t2=%#16"PRIxREGISTER", t3=%#16"PRIxREGISTER"\n",
194 tf->tf_t0, tf->tf_t1, tf->tf_t2, tf->tf_t3); 194 tf->tf_t0, tf->tf_t1, tf->tf_t2, tf->tf_t3);
195 (*pr)("t4=%#16"PRIxREGISTER", t5=%#16"PRIxREGISTER 195 (*pr)("t4=%#16"PRIxREGISTER", t5=%#16"PRIxREGISTER
196 ", t6=%#16"PRIxREGISTER"\n", 196 ", t6=%#16"PRIxREGISTER"\n",
197 tf->tf_t4, tf->tf_t5, tf->tf_t6); 197 tf->tf_t4, tf->tf_t5, tf->tf_t6);
198} 198}
199 199
200static inline void 200static inline void
201trap_ksi_init(ksiginfo_t *ksi, int signo, int code, vaddr_t addr, 201trap_ksi_init(ksiginfo_t *ksi, int signo, int code, vaddr_t addr,
202 register_t cause) 202 register_t cause)
203{ 203{
204 KSI_INIT_TRAP(ksi); 204 KSI_INIT_TRAP(ksi);
205 ksi->ksi_signo = signo; 205 ksi->ksi_signo = signo;
206 ksi->ksi_code = code; 206 ksi->ksi_code = code;
207 ksi->ksi_addr = (void *)addr; 207 ksi->ksi_addr = (void *)addr;
208 ksi->ksi_trap = cause; 208 ksi->ksi_trap = cause;
209} 209}
210 210
211static void 211static void
212cpu_trapsignal(struct trapframe *tf, ksiginfo_t *ksi) 212cpu_trapsignal(struct trapframe *tf, ksiginfo_t *ksi)
213{ 213{
214 if (cpu_printfataltraps) { 214 if (cpu_printfataltraps) {
215 dump_trapframe(tf, printf); 215 dump_trapframe(tf, printf);
216 } 216 }
217 (*curlwp->l_proc->p_emul->e_trapsignal)(curlwp, ksi); 217 (*curlwp->l_proc->p_emul->e_trapsignal)(curlwp, ksi);
218} 218}
219 219
220static inline vm_prot_t 220static inline vm_prot_t
221get_faulttype(register_t cause) 221get_faulttype(register_t cause)
222{ 222{
223 if (cause == CAUSE_FAULT_LOAD) 223 if (cause == CAUSE_FAULT_LOAD)
224 return VM_PROT_READ; 224 return VM_PROT_READ;
225 if (cause == CAUSE_FAULT_STORE) 225 if (cause == CAUSE_FAULT_STORE)
226 return VM_PROT_READ | VM_PROT_WRITE; 226 return VM_PROT_READ | VM_PROT_WRITE;
227 KASSERT(cause == CAUSE_FAULT_FETCH); 227 KASSERT(cause == CAUSE_FAULT_FETCH);
228 return VM_PROT_READ | VM_PROT_EXECUTE; 228 return VM_PROT_READ | VM_PROT_EXECUTE;
229} 229}
230 230
231static bool 231static bool
232trap_pagefault_fixup(struct trapframe *tf, struct pmap *pmap, register_t cause, 232trap_pagefault_fixup(struct trapframe *tf, struct pmap *pmap, register_t cause,
233 intptr_t addr) 233 intptr_t addr)
234{ 234{
235 pt_entry_t * const ptep = pmap_pte_lookup(pmap, addr); 235 pt_entry_t * const ptep = pmap_pte_lookup(pmap, addr);
236 struct vm_page *pg; 236 struct vm_page *pg;
237 237
238 if (ptep == NULL) 238 if (ptep == NULL)
239 return false; 239 return false;
240 240
241 pt_entry_t opte = *ptep; 241 pt_entry_t opte = *ptep;
242 pt_entry_t npte; 242 pt_entry_t npte;
243 u_int attr; 243 u_int attr;
244 do { 244 do {
245 if ((opte & ~PTE_G) == 0) 245 if ((opte & ~PTE_G) == 0)
246 return false; 246 return false;
247 247
248 pg = PHYS_TO_VM_PAGE(pte_to_paddr(opte)); 248 pg = PHYS_TO_VM_PAGE(pte_to_paddr(opte));
249 if (pg == NULL) 249 if (pg == NULL)
250 return false; 250 return false;
251 251
252 attr = 0; 252 attr = 0;
253 npte = opte; 253 npte = opte;
254 if ((npte & PTE_V) == 0) { 254 if ((npte & PTE_V) == 0) {
255 npte |= PTE_V; 255 npte |= PTE_V;
256 attr |= VM_PAGEMD_REFERENCED; 256 attr |= VM_PAGEMD_REFERENCED;
257 } 257 }
258#if 0 /* XXX Outdated */ 258#if 0 /* XXX Outdated */
259 if (cause == CAUSE_FAULT_STORE) { 259 if (cause == CAUSE_FAULT_STORE) {
260 if ((npte & PTE_NW) != 0) { 260 if ((npte & PTE_NW) != 0) {
261 npte &= ~PTE_NW; 261 npte &= ~PTE_NW;
262 attr |= VM_PAGEMD_MODIFIED; 262 attr |= VM_PAGEMD_MODIFIED;
263 } 263 }
264 } else if (cause == CAUSE_FAULT_FETCH) { 264 } else if (cause == CAUSE_FAULT_FETCH) {
265 if ((npte & PTE_NX) != 0) { 265 if ((npte & PTE_NX) != 0) {
266 npte &= ~PTE_NX; 266 npte &= ~PTE_NX;
267 attr |= VM_PAGEMD_EXECPAGE; 267 attr |= VM_PAGEMD_EXECPAGE;
268 } 268 }
269 } 269 }
270#endif 270#endif
271 if (attr == 0) 271 if (attr == 0)
272 return false; 272 return false;
273 273
274 } while (opte != atomic_cas_pte(ptep, opte, npte)); 274 } while (opte != atomic_cas_pte(ptep, opte, npte));
275 275
276 pmap_page_set_attributes(VM_PAGE_TO_MD(pg), attr); 276 pmap_page_set_attributes(VM_PAGE_TO_MD(pg), attr);
277 pmap_tlb_update_addr(pmap, addr, npte, 0); 277 pmap_tlb_update_addr(pmap, addr, npte, 0);
278 278
279 if (attr & VM_PAGEMD_EXECPAGE) 279 if (attr & VM_PAGEMD_EXECPAGE)
280 pmap_md_page_syncicache(pg, curcpu()->ci_data.cpu_kcpuset); 280 pmap_md_page_syncicache(pg, curcpu()->ci_data.cpu_kcpuset);
281 281
282 return true; 282 return true;
283} 283}
284 284
285static bool 285static bool
286trap_pagefault(struct trapframe *tf, register_t epc, register_t status, 286trap_pagefault(struct trapframe *tf, register_t epc, register_t status,
287 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi) 287 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi)
288{ 288{
289 struct proc * const p = curlwp->l_proc; 289 struct proc * const p = curlwp->l_proc;
290 const intptr_t addr = trunc_page(badaddr); 290 const intptr_t addr = trunc_page(badaddr);
291 291
292 if (__predict_false(usertrap_p 292 if (__predict_false(usertrap_p
293 && (false 293 && (false
294 // Make this address is not trying to access kernel space. 294 // Make this address is not trying to access kernel space.
295 || addr < 0 295 || addr < 0
296#ifdef _LP64 296#ifdef _LP64
297 // If this is a process using a 32-bit address space, make 297 // If this is a process using a 32-bit address space, make
298 // sure the address is a signed 32-bit number. 298 // sure the address is a signed 32-bit number.
299 || ((p->p_flag & PK_32) && (int32_t) addr != addr) 299 || ((p->p_flag & PK_32) && (int32_t) addr != addr)
300#endif 300#endif
301 || false))) { 301 || false))) {
302 trap_ksi_init(ksi, SIGSEGV, SEGV_MAPERR, addr, cause); 302 trap_ksi_init(ksi, SIGSEGV, SEGV_MAPERR, addr, cause);
303 return false; 303 return false;
304 } 304 }
305 305
306 struct vm_map * const map = (addr >= 0 ? &p->p_vmspace->vm_map : kernel_map); 306 struct vm_map * const map = (addr >= 0 ? &p->p_vmspace->vm_map : kernel_map);
307 307
308 // See if this fault is for reference/modified/execpage tracking 308 // See if this fault is for reference/modified/execpage tracking
309 if (trap_pagefault_fixup(tf, map->pmap, cause, addr)) 309 if (trap_pagefault_fixup(tf, map->pmap, cause, addr))
310 return true; 310 return true;
311 311
312 const vm_prot_t ftype = get_faulttype(cause); 312 const vm_prot_t ftype = get_faulttype(cause);
313 313
314 if (usertrap_p) { 314 if (usertrap_p) {
315 int error = uvm_fault(&p->p_vmspace->vm_map, addr, ftype); 315 int error = uvm_fault(&p->p_vmspace->vm_map, addr, ftype);
316 if (error) { 316 if (error) {
317 trap_ksi_init(ksi, SIGSEGV, 317 trap_ksi_init(ksi, SIGSEGV,
318 error == EACCES ? SEGV_ACCERR : SEGV_MAPERR, 318 error == EACCES ? SEGV_ACCERR : SEGV_MAPERR,
319 (intptr_t)badaddr, cause); 319 (intptr_t)badaddr, cause);
320 return false; 320 return false;
321 } 321 }
322 uvm_grow(p, addr); 322 uvm_grow(p, addr);
323 return true; 323 return true;
324 } 324 }
325 325
326 // Page fault are not allowed while dealing with interrupts 326 // Page fault are not allowed while dealing with interrupts
327 if (cpu_intr_p()) 327 if (cpu_intr_p())
328 return false; 328 return false;
329 329
330 struct faultbuf * const fb = cpu_disable_onfault(); 330 struct faultbuf * const fb = cpu_disable_onfault();
331 int error = uvm_fault(map, addr, ftype); 331 int error = uvm_fault(map, addr, ftype);
332 cpu_enable_onfault(fb); 332 cpu_enable_onfault(fb);
333 if (error == 0) { 333 if (error == 0) {
334 if (map != kernel_map) { 334 if (map != kernel_map) {
335 uvm_grow(p, addr); 335 uvm_grow(p, addr);
336 } 336 }
337 return true; 337 return true;
338 } 338 }
339 339
340 if (fb == NULL) { 340 if (fb == NULL) {
341 return false; 341 return false;
342 } 342 }
343 343
344 cpu_jump_onfault(tf, fb); 344 cpu_jump_onfault(tf, fb);
345 return true; 345 return true;
346} 346}
347 347
348static bool 348static bool
349trap_instruction(struct trapframe *tf, register_t epc, register_t status, 349trap_instruction(struct trapframe *tf, register_t epc, register_t status,
350 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi) 350 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi)
351{ 351{
352 const bool prvopc_p = (cause == CAUSE_PRIVILEGED_INSTRUCTION); 352 const bool prvopc_p = (cause == CAUSE_PRIVILEGED_INSTRUCTION);
353 if (usertrap_p) { 353 if (usertrap_p) {
354 trap_ksi_init(ksi, SIGILL, prvopc_p ? ILL_PRVOPC : ILL_ILLOPC, 354 trap_ksi_init(ksi, SIGILL, prvopc_p ? ILL_PRVOPC : ILL_ILLOPC,
355 (intptr_t)badaddr, cause); 355 (intptr_t)badaddr, cause);
356 } 356 }
357 return false; 357 return false;
358} 358}
359 359
360static bool 360static bool
361trap_misalignment(struct trapframe *tf, register_t epc, register_t status, 361trap_misalignment(struct trapframe *tf, register_t epc, register_t status,
362 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi) 362 register_t cause, register_t badaddr, bool usertrap_p, ksiginfo_t *ksi)
363{ 363{
364 if (usertrap_p) { 364 if (usertrap_p) {
365 trap_ksi_init(ksi, SIGBUS, BUS_ADRALN, 365 trap_ksi_init(ksi, SIGBUS, BUS_ADRALN,
366 (intptr_t)badaddr, cause); 366 (intptr_t)badaddr, cause);
367 } 367 }
368 return false; 368 return false;
369} 369}
370 370
371void 371void
372cpu_trap(struct trapframe *tf, register_t epc, register_t status, 372cpu_trap(struct trapframe *tf, register_t epc, register_t status,
373 register_t cause, register_t badaddr) 373 register_t cause, register_t badaddr)
374{ 374{
375 const u_int fault_mask = 1U << cause; 375 const u_int fault_mask = 1U << cause;
376 const intptr_t addr = badaddr; 376 const intptr_t addr = badaddr;
377 const bool usertrap_p = (status & SR_PS) == 0; 377 const bool usertrap_p = (status & SR_PS) == 0;
378 bool ok = true; 378 bool ok = true;
379 ksiginfo_t ksi; 379 ksiginfo_t ksi;
380 380
381 if (__predict_true(fault_mask & FAULT_TRAP_MASK)) { 381 if (__predict_true(fault_mask & FAULT_TRAP_MASK)) {
382#ifndef _LP64 382#ifndef _LP64
383 // This fault may be cause the kernel's page table got a new 383 // This fault may be cause the kernel's page table got a new
384 // page table page and this pmap's page table doesn't know 384 // page table page and this pmap's page table doesn't know
385 // about it. See 385 // about it. See
386 struct pmap * const pmap = curlwp->l_proc->p_vmspace->vm_map.pmap; 386 struct pmap * const pmap = curlwp->l_proc->p_vmspace->vm_map.pmap;
387 if ((intptr_t) addr < 0 387 if ((intptr_t) addr < 0
388 && pmap != pmap_kernel() 388 && pmap != pmap_kernel()
389 && pmap_pdetab_fixup(pmap, addr)) { 389 && pmap_pdetab_fixup(pmap, addr)) {
390 return; 390 return;
391 } 391 }
392#endif 392#endif
393 ok = trap_pagefault(tf, epc, status, cause, addr, 393 ok = trap_pagefault(tf, epc, status, cause, addr,
394 usertrap_p, &ksi); 394 usertrap_p, &ksi);
395 } else if (fault_mask & INSTRUCTION_TRAP_MASK) { 395 } else if (fault_mask & INSTRUCTION_TRAP_MASK) {
396 ok = trap_instruction(tf, epc, status, cause, addr, 396 ok = trap_instruction(tf, epc, status, cause, addr,
397 usertrap_p, &ksi); 397 usertrap_p, &ksi);
398 } else if (fault_mask && __BIT(CAUSE_FP_DISABLED)) { 398 } else if (fault_mask && __BIT(CAUSE_FP_DISABLED)) {
399 if (!usertrap_p) { 399 if (!usertrap_p) {
400 panic("%s: fp used @ %#"PRIxREGISTER" in kernel!", 400 panic("%s: fp used @ %#"PRIxREGISTER" in kernel!",
401 __func__, tf->tf_pc); 401 __func__, tf->tf_pc);
402 } 402 }
403 fpu_load(); 403 fpu_load();
404 } else if (fault_mask & MISALIGNED_TRAP_MASK) { 404 } else if (fault_mask & MISALIGNED_TRAP_MASK) {
405 ok = trap_misalignment(tf, epc, status, cause, addr, 405 ok = trap_misalignment(tf, epc, status, cause, addr,
406 usertrap_p, &ksi); 406 usertrap_p, &ksi);
407 } else { 407 } else {
408 dump_trapframe(tf, printf); 408 dump_trapframe(tf, printf);
409 panic("%s: unknown kernel trap", __func__); 409 panic("%s: unknown kernel trap", __func__);
410 } 410 }
411 411
412 if (usertrap_p) { 412 if (usertrap_p) {
413 if (!ok) 413 if (!ok)
414 cpu_trapsignal(tf, &ksi); 414 cpu_trapsignal(tf, &ksi);
415 userret(curlwp); 415 userret(curlwp);
416 } else if (!ok) { 416 } else if (!ok) {
417 dump_trapframe(tf, printf); 417 dump_trapframe(tf, printf);
418 panic("%s: fatal kernel trap", __func__); 418 panic("%s: fatal kernel trap", __func__);
419 } 419 }
420} 420}
421 421
422void 422void
423cpu_ast(struct trapframe *tf) 423cpu_ast(struct trapframe *tf)
424{ 424{
425 struct cpu_info * const ci = curcpu(); 425 struct cpu_info * const ci = curcpu();
426 426
427 atomic_swap_uint(&curlwp->l_md.md_astpending, 0); 427 atomic_swap_uint(&curlwp->l_md.md_astpending, 0);
428 428
429 if (curlwp->l_pflag & LP_OWEUPC) { 429 if (curlwp->l_pflag & LP_OWEUPC) {
430 curlwp->l_pflag &= ~LP_OWEUPC; 430 curlwp->l_pflag &= ~LP_OWEUPC;
431 ADDUPROF(curlwp); 431 ADDUPROF(curlwp);
432 } 432 }
433} 433}
434 434
435void 435void
436cpu_intr(struct trapframe *tf, register_t epc, register_t status, 436cpu_intr(struct trapframe *tf, register_t epc, register_t status,
437 register_t cause) 437 register_t cause)
438{ 438{
439 /* XXX */ 439 /* XXX */
440} 440}
441 441
442static int 442static int
443fetch_user_data(const void *uaddr, void *valp, size_t size) 443fetch_user_data(const void *uaddr, void *valp, size_t size)
444{ 444{
445 struct faultbuf fb; 445 struct faultbuf fb;
446 int error; 446 int error;
447 447
448 if ((error = cpu_set_onfault(&fb, 1)) != 0) 448 if ((error = cpu_set_onfault(&fb, 1)) != 0)
449 return error; 449 return error;
450 450
451 switch (size) { 451 switch (size) {
452 case 1: 452 case 1:
453 *(uint8_t *)valp = *(volatile const uint8_t *)uaddr; 453 *(uint8_t *)valp = *(volatile const uint8_t *)uaddr;
454 break; 454 break;
455 case 2: 455 case 2:
456 *(uint16_t *)valp = *(volatile const uint16_t *)uaddr; 456 *(uint16_t *)valp = *(volatile const uint16_t *)uaddr;
457 break; 457 break;
458 case 4: 458 case 4:
459 *(uint32_t *)valp = *(volatile const uint32_t *)uaddr; 459 *(uint32_t *)valp = *(volatile const uint32_t *)uaddr;
460 break; 460 break;
461#ifdef _LP64 461#ifdef _LP64
462 case 8: 462 case 8:
463 *(uint64_t *)valp = *(volatile const uint64_t *)uaddr; 463 *(uint64_t *)valp = *(volatile const uint64_t *)uaddr;
464 break; 464 break;
465#endif /* _LP64 */ 465#endif /* _LP64 */
466 default: 466 default:
467 error = EINVAL; 467 error = EINVAL;
468 } 468 }
469 469
470 cpu_unset_onfault(); 470 cpu_unset_onfault();
471 return error; 471 return error;
472} 472}
473 473
474int 474int
475_ufetch_8(const uint8_t *uaddr, uint8_t *valp) 475_ufetch_8(const uint8_t *uaddr, uint8_t *valp)
476{ 476{
477 return fetch_user_data(uaddr, valp, sizeof(*valp)); 477 return fetch_user_data(uaddr, valp, sizeof(*valp));
478} 478}
479 479
480int 480int
481_ufetch_16(const uint16_t *uaddr, uint16_t *valp) 481_ufetch_16(const uint16_t *uaddr, uint16_t *valp)
482{ 482{
483 return fetch_user_data(uaddr, valp, sizeof(*valp)); 483 return fetch_user_data(uaddr, valp, sizeof(*valp));
484} 484}
485 485
486int 486int
487_ufetch_32(const uint32_t *uaddr, uint32_t *valp) 487_ufetch_32(const uint32_t *uaddr, uint32_t *valp)
488{ 488{
489 return fetch_user_data(uaddr, valp, sizeof(*valp)); 489 return fetch_user_data(uaddr, valp, sizeof(*valp));
490} 490}
491 491
492#ifdef _LP64 492#ifdef _LP64
493int 493int
494_ufetch_64(const uint64_t *uaddr, uint64_t *valp) 494_ufetch_64(const uint64_t *uaddr, uint64_t *valp)
495{ 495{
496 return fetch_user_data(uaddr, valp, sizeof(*valp)); 496 return fetch_user_data(uaddr, valp, sizeof(*valp));
497} 497}
498#endif /* _LP64 */ 498#endif /* _LP64 */
499 499
500static int 500static int
501store_user_data(void *uaddr, const void *valp, size_t size) 501store_user_data(void *uaddr, const void *valp, size_t size)
502{ 502{
503 struct faultbuf fb; 503 struct faultbuf fb;
504 int error; 504 int error;
505 505
506 if ((error = cpu_set_onfault(&fb, 1)) != 0) 506 if ((error = cpu_set_onfault(&fb, 1)) != 0)
507 return error; 507 return error;
508 508
509 switch (size) { 509 switch (size) {
510 case 1: 510 case 1:
511 *(volatile uint8_t *)uaddr = *(const uint8_t *)valp; 511 *(volatile uint8_t *)uaddr = *(const uint8_t *)valp;
512 break; 512 break;
513 case 2: 513 case 2:
514 *(volatile uint16_t *)uaddr = *(const uint8_t *)valp; 514 *(volatile uint16_t *)uaddr = *(const uint8_t *)valp;
515 break; 515 break;
516 case 4: 516 case 4:
517 *(volatile uint32_t *)uaddr = *(const uint32_t *)valp; 517 *(volatile uint32_t *)uaddr = *(const uint32_t *)valp;
518 break; 518 break;
519#ifdef _LP64 519#ifdef _LP64
520 case 8: 520 case 8:
521 *(volatile uint64_t *)uaddr = *(const uint64_t *)valp; 521 *(volatile uint64_t *)uaddr = *(const uint64_t *)valp;
522 break; 522 break;
523#endif /* _LP64 */ 523#endif /* _LP64 */
524 default: 524 default:
525 error = EINVAL; 525 error = EINVAL;
526 } 526 }
527 527
528 cpu_unset_onfault(); 528 cpu_unset_onfault();
529 return error; 529 return error;
530} 530}
531 531
532int 532int
533_ustore_8(uint8_t *uaddr, uint8_t val) 533_ustore_8(uint8_t *uaddr, uint8_t val)
534{ 534{
535 return store_user_data(uaddr, &val, sizeof(val)); 535 return store_user_data(uaddr, &val, sizeof(val));
536} 536}
537 537
538int 538int
539_ustore_16(uint16_t *uaddr, uint16_t val) 539_ustore_16(uint16_t *uaddr, uint16_t val)
540{ 540{
541 return store_user_data(uaddr, &val, sizeof(val)); 541 return store_user_data(uaddr, &val, sizeof(val));
542} 542}
543 543
544int 544int
545_ustore_32(uint32_t *uaddr, uint32_t val) 545_ustore_32(uint32_t *uaddr, uint32_t val)
546{ 546{
547 return store_user_data(uaddr, &val, sizeof(val)); 547 return store_user_data(uaddr, &val, sizeof(val));
548} 548}
549 549
550#ifdef _LP64 550#ifdef _LP64
551int 551int
552_ustore_64(uint64_t *uaddr, uint64_t val) 552_ustore_64(uint64_t *uaddr, uint64_t val)
553{ 553{
554 return store_user_data(uaddr, &val, sizeof(val)); 554 return store_user_data(uaddr, &val, sizeof(val));
555} 555}
556#endif /* _LP64 */ 556#endif /* _LP64 */