Fri Jan 1 12:58:36 2021 UTC ()
Pull up following revision(s) (requested by rin in ticket #1172):

	sys/arch/aarch64/aarch64/trap.c: revision 1.30
	sys/arch/aarch64/include/ptrace.h: revision 1.10
	sys/arch/aarch64/include/netbsd32_machdep.h: revision 1.4 (patch)
	sys/arch/aarch64/aarch64/netbsd32_machdep.c: revision 1.14
	sys/arch/aarch64/aarch64/netbsd32_machdep.c: revision 1.15

Add support of ptrace(2) for COMPAT_NETBSD32.

Now, GDB for arm32 is usable for debugging 32bit applications.
OK ryo@

For rev 1.14 and before, netbsd32_process_write_regs() returns EINVAL
if non-modifiable bits are set in CPSR.
Instead, mask out non-modifiable bits and make this function success
regardless of value in CPSR. New behavior matches that of arm:
https://nxr.netbsd.org/xref/src/sys/arch/arm/arm/process_machdep.c#187

This fixes lib/libc/sys/t_ptrace_wait*:access_regs6 tests, in which
register contents retrieved by PT_GETREGS are set back by PT_SETREGS.

No new regression is observed in full ATF run.

OK ryo


(martin)
diff -r1.7.2.1 -r1.7.2.2 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c
diff -r1.17.4.3 -r1.17.4.4 src/sys/arch/aarch64/aarch64/trap.c
diff -r1.2 -r1.2.4.1 src/sys/arch/aarch64/include/netbsd32_machdep.h
diff -r1.9 -r1.9.2.1 src/sys/arch/aarch64/include/ptrace.h

cvs diff -r1.7.2.1 -r1.7.2.2 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c (switch to unified diff)

--- src/sys/arch/aarch64/aarch64/netbsd32_machdep.c 2020/05/02 16:26:04 1.7.2.1
+++ src/sys/arch/aarch64/aarch64/netbsd32_machdep.c 2021/01/01 12:58:35 1.7.2.2
@@ -1,559 +1,646 @@ @@ -1,559 +1,646 @@
1/* $NetBSD: netbsd32_machdep.c,v 1.7.2.1 2020/05/02 16:26:04 martin Exp $ */ 1/* $NetBSD: netbsd32_machdep.c,v 1.7.2.2 2021/01/01 12:58:35 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org> 4 * Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7.2.1 2020/05/02 16:26:04 martin Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7.2.2 2021/01/01 12:58:35 martin Exp $");
31 31
32#if defined(_KERNEL_OPT) 32#if defined(_KERNEL_OPT)
33#include "opt_compat_netbsd.h" 33#include "opt_compat_netbsd.h"
34#endif 34#endif
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/core.h> 37#include <sys/core.h>
38#include <sys/exec.h> 38#include <sys/exec.h>
39#include <sys/lwp.h> 39#include <sys/lwp.h>
 40#include <sys/ptrace.h>
40#include <sys/ras.h> 41#include <sys/ras.h>
41#include <sys/signalvar.h> 42#include <sys/signalvar.h>
42#include <sys/syscallargs.h> 43#include <sys/syscallargs.h>
43 44
44#include <uvm/uvm_extern.h> 45#include <uvm/uvm_extern.h>
45 46
46#include <compat/netbsd32/netbsd32.h> 47#include <compat/netbsd32/netbsd32.h>
47#include <compat/netbsd32/netbsd32_exec.h> 48#include <compat/netbsd32/netbsd32_exec.h>
48#include <compat/netbsd32/netbsd32_syscallargs.h> 49#include <compat/netbsd32/netbsd32_syscallargs.h>
49 50
50#include <aarch64/armreg.h> 51#include <aarch64/armreg.h>
51#include <aarch64/cpufunc.h> 52#include <aarch64/cpufunc.h>
52#include <aarch64/frame.h> 53#include <aarch64/frame.h>
53#include <aarch64/machdep.h> 54#include <aarch64/machdep.h>
54#include <aarch64/userret.h> 55#include <aarch64/userret.h>
55 56
56const char machine32[] = MACHINE; 57const char machine32[] = MACHINE;
57#ifdef __AARCH64EB__ 58#ifdef __AARCH64EB__
58const char machine_arch32[] = "earmv7hfeb"; 59const char machine_arch32[] = "earmv7hfeb";
59#else 60#else
60const char machine_arch32[] = "earmv7hf"; 61const char machine_arch32[] = "earmv7hf";
61#endif 62#endif
62 63
63void 64void
64netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 65netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
65{ 66{
66 struct proc * const p = l->l_proc; 67 struct proc * const p = l->l_proc;
67 struct trapframe * const tf = l->l_md.md_utf; 68 struct trapframe * const tf = l->l_md.md_utf;
68 69
69 p->p_flag |= PK_32; 70 p->p_flag |= PK_32;
70 71
71 /* 72 /*
72 * void __start(struct ps_strings *ps_strings, const Obj_Entry *obj, 73 * void __start(struct ps_strings *ps_strings, const Obj_Entry *obj,
73 * void (*cleanup)(void)); 74 * void (*cleanup)(void));
74 */ 75 */
75 memset(tf, 0, sizeof(*tf)); 76 memset(tf, 0, sizeof(*tf));
76 tf->tf_reg[0] = (uint32_t)p->p_psstrp; 77 tf->tf_reg[0] = (uint32_t)p->p_psstrp;
77 tf->tf_reg[12] = stack; /* r12 needed by pre 1.4 crt0.c */ 78 tf->tf_reg[12] = stack; /* r12 needed by pre 1.4 crt0.c */
78 tf->tf_reg[13] = stack; /* sp */ 79 tf->tf_reg[13] = stack; /* sp */
79 tf->tf_reg[14] = pack->ep_entry;/* lr */ 80 tf->tf_reg[14] = pack->ep_entry;/* lr */
80 tf->tf_reg[18] = 0x77777777; /* svc_lr. adjust to arm_machdep.c */ 81 tf->tf_reg[18] = 0x77777777; /* svc_lr. adjust to arm_machdep.c */
81 tf->tf_pc = pack->ep_entry; 82 tf->tf_pc = pack->ep_entry;
82 83
83 84
84 /* set 32bit mode, and same endian as 64bit's */ 85 /* set 32bit mode, and same endian as 64bit's */
85#ifdef __AARCH64EB__ 86#ifdef __AARCH64EB__
86 tf->tf_spsr = SPSR_M_USR32 | SPSR_A32_E; 87 tf->tf_spsr = SPSR_M_USR32 | SPSR_A32_E;
87#else 88#else
88 tf->tf_spsr = SPSR_M_USR32; 89 tf->tf_spsr = SPSR_M_USR32;
89#endif 90#endif
90 91
91 /* THUMB CODE? */ 92 /* THUMB CODE? */
92 if (pack->ep_entry & 1) 93 if (pack->ep_entry & 1)
93 tf->tf_spsr |= SPSR_A32_T; 94 tf->tf_spsr |= SPSR_A32_T;
94} 95}
95 96
 97int
 98netbsd32_ptrace_translate_request(int req)
 99{
 100
 101 switch (req) {
 102 case 0 ... PT_FIRSTMACH - 1:
 103 return req;
 104 case PT32_GETREGS:
 105 return PT_GETREGS;
 106 case PT32_SETREGS:
 107 return PT_SETREGS;
 108 case PT32_GETFPREGS:
 109 return PT_GETFPREGS;
 110 case PT32_SETFPREGS:
 111 return PT_SETFPREGS;
 112 /* not implemented for arm32 */
 113 case PT32_STEP:
 114 case PT32_SETSTEP:
 115 case PT32_CLEARSTEP:
 116 default:
 117 return -1;
 118 }
 119}
 120
96/* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */ 121/* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */
97#define FPSR_BITS \ 122#define FPSR_BITS \
98 (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \ 123 (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \
99 FPSR_IDC|FPSR_IXC|FPSR_UFC|FPSR_OFC|FPSR_DZC|FPSR_IOC) 124 FPSR_IDC|FPSR_IXC|FPSR_UFC|FPSR_OFC|FPSR_DZC|FPSR_IOC)
100#define FPCR_BITS \ 125#define FPCR_BITS \
101 (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \ 126 (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \
102 FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE) 127 FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE)
103 128
104static int 129int
105netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs) 130netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
106{ 131{
107 struct proc * const p = l->l_proc; 132 struct proc * const p = l->l_proc;
108 struct trapframe *tf = l->l_md.md_utf; 133 struct trapframe *tf = l->l_md.md_utf;
109 int i; 134 int i;
110 135
111 if ((p->p_flag & PK_32) == 0) 136 if ((p->p_flag & PK_32) == 0)
112 return EINVAL; 137 return EINVAL;
113 138
114 for (i = 0; i < 13; i++) 139 for (i = 0; i < 13; i++)
115 regs->r[i] = tf->tf_reg[i]; /* r0-r12 */ 140 regs->r[i] = tf->tf_reg[i]; /* r0-r12 */
116 regs->r_sp = tf->tf_reg[13]; /* r13 = sp */ 141 regs->r_sp = tf->tf_reg[13]; /* r13 = sp */
117 regs->r_lr = tf->tf_reg[14]; /* r14 = lr */ 142 regs->r_lr = tf->tf_reg[14]; /* r14 = lr */
118 regs->r_pc = tf->tf_pc; /* r15 = pc */ 143 regs->r_pc = tf->tf_pc; /* r15 = pc */
119 regs->r_cpsr = tf->tf_spsr; 144 regs->r_cpsr = tf->tf_spsr;
120 145
121 /* THUMB CODE? */ 146 /* THUMB CODE? */
122 if (tf->tf_spsr & SPSR_A32_T) 147 if (tf->tf_spsr & SPSR_A32_T)
123 regs->r_pc |= 1; 148 regs->r_pc |= 1;
124 149
125 return 0; 150 return 0;
126} 151}
127 152
128static int 153int
129netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs, 154netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs,
130 size_t *lenp) 155 size_t *lenp)
131{ 156{
132 struct proc * const p = l->l_proc; 157 struct proc * const p = l->l_proc;
133 struct pcb * const pcb = lwp_getpcb(l); 158 struct pcb * const pcb = lwp_getpcb(l);
134 int i; 159 int i;
135 160
136 if ((p->p_flag & PK_32) == 0) 161 if ((p->p_flag & PK_32) == 0)
137 return EINVAL; 162 return EINVAL;
138 163
139 KASSERT(*lenp <= sizeof(*fpregs)); 164 KASSERT(*lenp <= sizeof(*fpregs));
140 fpu_save(l); 165 fpu_save(l);
141 166
142 /* 167 /*
143 * convert from aarch64's struct fpreg to arm's struct fpreg32 168 * convert from aarch64's struct fpreg to arm's struct fpreg32
144 */ 169 */
145#define VFP_FPEXC_EN 0x40000000 /* VFP Enable bit */ 170#define VFP_FPEXC_EN 0x40000000 /* VFP Enable bit */
146#define VFP_FPEXC_VECITR 0x00000700 /* VECtor ITeRation count */ 171#define VFP_FPEXC_VECITR 0x00000700 /* VECtor ITeRation count */
147 fpregs->fpr_vfp.vfp_fpexc = VFP_FPEXC_EN | VFP_FPEXC_VECITR; 172 fpregs->fpr_vfp.vfp_fpexc = VFP_FPEXC_EN | VFP_FPEXC_VECITR;
148 173
149 fpregs->fpr_vfp.vfp_fpscr = 174 fpregs->fpr_vfp.vfp_fpscr =
150 (pcb->pcb_fpregs.fpsr & FPSR_BITS) | 175 (pcb->pcb_fpregs.fpsr & FPSR_BITS) |
151 (pcb->pcb_fpregs.fpcr & FPCR_BITS); 176 (pcb->pcb_fpregs.fpcr & FPCR_BITS);
152 177
153 fpregs->fpr_vfp.vfp_fpinst = 0; 178 fpregs->fpr_vfp.vfp_fpinst = 0;
154 fpregs->fpr_vfp.vfp_fpinst2 = 0; 179 fpregs->fpr_vfp.vfp_fpinst2 = 0;
155 180
156 for (i = 0; i < 32; i++) { 181 for (i = 0; i < 32; i++) {
157#ifdef __AARCH64EB__ 182#ifdef __AARCH64EB__
158 fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[1]; 183 fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[1];
159#else 184#else
160 fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[0]; 185 fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[0];
161#endif 186#endif
162 } 187 }
163 188
164 return 0; 189 return 0;
165} 190}
166 191
167int 192int
 193netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs)
 194{
 195 struct proc * const p = l->l_proc;
 196 struct trapframe *tf = l->l_md.md_utf;
 197 int i;
 198
 199 if ((p->p_flag & PK_32) == 0)
 200 return EINVAL;
 201
 202 if (regs->r_pc >= VM_MAXUSER_ADDRESS32 ||
 203 regs->r_sp >= VM_MAXUSER_ADDRESS32)
 204 return EINVAL;
 205
 206 for (i = 0; i < 13; i++)
 207 tf->tf_reg[i] = regs->r[i]; /* r0-r12 */
 208 tf->tf_reg[13] = regs->r_sp; /* r13 = sp */
 209 tf->tf_reg[14] = regs->r_lr; /* r14 = lr */
 210 tf->tf_pc = regs->r_pc; /* r15 = pc */
 211 tf->tf_spsr &= ~(SPSR_NZCV | SPSR_A32_T);
 212 tf->tf_spsr |= regs->r_cpsr & (SPSR_NZCV | SPSR_A32_T);
 213
 214 /* THUMB CODE? */
 215 if (regs->r_pc & 1)
 216 tf->tf_spsr |= SPSR_A32_T;
 217
 218 return 0;
 219}
 220
 221int
 222netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *fpregs,
 223 size_t len)
 224{
 225 struct proc * const p = l->l_proc;
 226 struct pcb * const pcb = lwp_getpcb(l);
 227 int i;
 228
 229 if ((p->p_flag & PK_32) == 0)
 230 return EINVAL;
 231
 232 KASSERT(len <= sizeof(*fpregs));
 233 fpu_discard(l, true); // set used flag
 234
 235 pcb->pcb_fpregs.fpsr = fpregs->fpr_vfp.vfp_fpscr & FPSR_BITS;
 236 pcb->pcb_fpregs.fpcr = fpregs->fpr_vfp.vfp_fpscr & FPCR_BITS;
 237
 238 CTASSERT(__arraycount(fpregs->fpr_vfp.vfp_regs) ==
 239 __arraycount(pcb->pcb_fpregs.fp_reg) + 1);
 240 for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
 241#ifdef __AARCH64EB__
 242 pcb->pcb_fpregs.fp_reg[i].u64[0] = 0;
 243 pcb->pcb_fpregs.fp_reg[i].u64[1] =
 244#else
 245 pcb->pcb_fpregs.fp_reg[i].u64[1] = 0;
 246 pcb->pcb_fpregs.fp_reg[i].u64[0] =
 247#endif
 248 fpregs->fpr_vfp.vfp_regs[i];
 249 }
 250
 251 return 0;
 252}
 253
 254int
168cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, 255cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
169 struct core32 *chdr) 256 struct core32 *chdr)
170{ 257{
171 struct netbsd32_cpustate md_core32; 258 struct netbsd32_cpustate md_core32;
172 struct coreseg32 cseg; 259 struct coreseg32 cseg;
173 int error; 260 int error;
174 261
175 if (iocookie == NULL) { 262 if (iocookie == NULL) {
176 CORE_SETMAGIC(*chdr, COREMAGIC, MID_ARM6, 0); 263 CORE_SETMAGIC(*chdr, COREMAGIC, MID_ARM6, 0);
177 chdr->c_hdrsize = ALIGN32(sizeof(*chdr)); 264 chdr->c_hdrsize = ALIGN32(sizeof(*chdr));
178 chdr->c_seghdrsize = ALIGN32(sizeof(cseg)); 265 chdr->c_seghdrsize = ALIGN32(sizeof(cseg));
179 chdr->c_cpusize = sizeof(md_core32); 266 chdr->c_cpusize = sizeof(md_core32);
180 chdr->c_nseg++; 267 chdr->c_nseg++;
181 return 0; 268 return 0;
182 } 269 }
183 270
184 error = netbsd32_process_read_regs(l, &md_core32.regs); 271 error = netbsd32_process_read_regs(l, &md_core32.regs);
185 if (error) 272 if (error)
186 return error; 273 return error;
187 274
188 error = netbsd32_process_read_fpregs(l, &md_core32.fpregs, NULL); 275 error = netbsd32_process_read_fpregs(l, &md_core32.fpregs, NULL);
189 if (error) 276 if (error)
190 return error; 277 return error;
191 278
192 CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_ARM6, CORE_CPU); 279 CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_ARM6, CORE_CPU);
193 cseg.c_addr = 0; 280 cseg.c_addr = 0;
194 cseg.c_size = chdr->c_cpusize; 281 cseg.c_size = chdr->c_cpusize;
195 282
196 error = coredump_write(iocookie, UIO_SYSSPACE, 283 error = coredump_write(iocookie, UIO_SYSSPACE,
197 &cseg, chdr->c_seghdrsize); 284 &cseg, chdr->c_seghdrsize);
198 if (error) 285 if (error)
199 return error; 286 return error;
200 287
201 return coredump_write(iocookie, UIO_SYSSPACE, 288 return coredump_write(iocookie, UIO_SYSSPACE,
202 &md_core32, sizeof(md_core32)); 289 &md_core32, sizeof(md_core32));
203} 290}
204 291
205static void 292static void
206netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) 293netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
207{ 294{
208 struct lwp * const l = curlwp; 295 struct lwp * const l = curlwp;
209 struct proc * const p = l->l_proc; 296 struct proc * const p = l->l_proc;
210 struct trapframe * const tf = l->l_md.md_utf; 297 struct trapframe * const tf = l->l_md.md_utf;
211 struct sigaltstack * const ss = &l->l_sigstk; 298 struct sigaltstack * const ss = &l->l_sigstk;
212 const int signo = ksi->ksi_signo; 299 const int signo = ksi->ksi_signo;
213 const struct sigaction * const sa = &SIGACTION(p, signo); 300 const struct sigaction * const sa = &SIGACTION(p, signo);
214 const struct sigact_sigdesc * const sdesc = 301 const struct sigact_sigdesc * const sdesc =
215 &p->p_sigacts->sa_sigdesc[signo]; 302 &p->p_sigacts->sa_sigdesc[signo];
216 const sig_t handler = sa->sa_handler; 303 const sig_t handler = sa->sa_handler;
217 struct netbsd32_sigframe_siginfo *fp, frame; 304 struct netbsd32_sigframe_siginfo *fp, frame;
218 int error; 305 int error;
219 306
220 const bool onstack_p = 307 const bool onstack_p =
221 (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 308 (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
222 (sa->sa_flags & SA_ONSTACK); 309 (sa->sa_flags & SA_ONSTACK);
223 310
224 vaddr_t sp = onstack_p ? 311 vaddr_t sp = onstack_p ?
225 ((vaddr_t)ss->ss_sp + ss->ss_size) : 312 ((vaddr_t)ss->ss_sp + ss->ss_size) :
226 tf->tf_reg[13]; /* r13 = sp on aarch32 */ 313 tf->tf_reg[13]; /* r13 = sp on aarch32 */
227 314
228 fp = (struct netbsd32_sigframe_siginfo *)sp; 315 fp = (struct netbsd32_sigframe_siginfo *)sp;
229 fp = (struct netbsd32_sigframe_siginfo *)STACK_ALIGN(fp - 1, (8 - 1)); 316 fp = (struct netbsd32_sigframe_siginfo *)STACK_ALIGN(fp - 1, (8 - 1));
230 317
231 memset(&frame, 0, sizeof(frame)); 318 memset(&frame, 0, sizeof(frame));
232 319
233 /* XXX: netbsd32_ksi_to_si32 */ 320 /* XXX: netbsd32_ksi_to_si32 */
234 netbsd32_si_to_si32(&frame.sf_si, (const siginfo_t *)&ksi->ksi_info); 321 netbsd32_si_to_si32(&frame.sf_si, (const siginfo_t *)&ksi->ksi_info);
235 322
236 frame.sf_uc.uc_flags = _UC_SIGMASK; 323 frame.sf_uc.uc_flags = _UC_SIGMASK;
237 frame.sf_uc.uc_sigmask = *mask; 324 frame.sf_uc.uc_sigmask = *mask;
238 frame.sf_uc.uc_link = (uint32_t)(uintptr_t)l->l_ctxlink; 325 frame.sf_uc.uc_link = (uint32_t)(uintptr_t)l->l_ctxlink;
239 frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) ? 326 frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) ?
240 _UC_SETSTACK : _UC_CLRSTACK; 327 _UC_SETSTACK : _UC_CLRSTACK;
241 sendsig_reset(l, signo); 328 sendsig_reset(l, signo);
242 329
243 mutex_exit(p->p_lock); 330 mutex_exit(p->p_lock);
244 cpu_getmcontext32(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags); 331 cpu_getmcontext32(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
245 error = copyout(&frame, fp, sizeof(frame)); 332 error = copyout(&frame, fp, sizeof(frame));
246 mutex_enter(p->p_lock); 333 mutex_enter(p->p_lock);
247 334
248 if (error != 0) { 335 if (error != 0) {
249 /* 336 /*
250 * Process has trashed its stack; 337 * Process has trashed its stack;
251 * give it an illegal instruction to halt it in its tracks. 338 * give it an illegal instruction to halt it in its tracks.
252 */ 339 */
253 sigexit(l, SIGILL); 340 sigexit(l, SIGILL);
254 /* NOTREACHED */ 341 /* NOTREACHED */
255 } 342 }
256 343
257 tf->tf_reg[0] = signo; 344 tf->tf_reg[0] = signo;
258 tf->tf_reg[1] = (uint32_t)(uintptr_t)&fp->sf_si; 345 tf->tf_reg[1] = (uint32_t)(uintptr_t)&fp->sf_si;
259 tf->tf_reg[2] = (uint32_t)(uintptr_t)&fp->sf_uc; 346 tf->tf_reg[2] = (uint32_t)(uintptr_t)&fp->sf_uc;
260 347
261 /* the trampoline uses r5 as the uc address */ 348 /* the trampoline uses r5 as the uc address */
262 tf->tf_reg[5] = (uint32_t)(uintptr_t)&fp->sf_uc; 349 tf->tf_reg[5] = (uint32_t)(uintptr_t)&fp->sf_uc;
263 tf->tf_pc = (uint32_t)(uintptr_t)handler; 350 tf->tf_pc = (uint32_t)(uintptr_t)handler;
264 351
265 /* THUMB CODE? */ 352 /* THUMB CODE? */
266 if (((uintptr_t)handler) & 1) 353 if (((uintptr_t)handler) & 1)
267 tf->tf_spsr |= SPSR_A32_T; 354 tf->tf_spsr |= SPSR_A32_T;
268 else 355 else
269 tf->tf_spsr &= ~SPSR_A32_T; 356 tf->tf_spsr &= ~SPSR_A32_T;
270 357
271 tf->tf_reg[13] = (uint32_t)(uintptr_t)fp; /* sp */ 358 tf->tf_reg[13] = (uint32_t)(uintptr_t)fp; /* sp */
272 tf->tf_reg[14] = (uint32_t)(uintptr_t)sdesc->sd_tramp; /* lr */ 359 tf->tf_reg[14] = (uint32_t)(uintptr_t)sdesc->sd_tramp; /* lr */
273 360
274 /* Remember if we'ere now on the signal stack */ 361 /* Remember if we'ere now on the signal stack */
275 if (onstack_p) 362 if (onstack_p)
276 ss->ss_flags |= SS_ONSTACK; 363 ss->ss_flags |= SS_ONSTACK;
277} 364}
278 365
279void 366void
280netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 367netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
281{ 368{
282#ifdef COMPAT_16 369#ifdef COMPAT_16
283#error non EABI generation binaries are not supported 370#error non EABI generation binaries are not supported
284 if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2) 371 if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
285 netbsd32_sendsig_sigcontext(ksi, mask); 372 netbsd32_sendsig_sigcontext(ksi, mask);
286 else 373 else
287#endif 374#endif
288 netbsd32_sendsig_siginfo(ksi, mask); 375 netbsd32_sendsig_siginfo(ksi, mask);
289} 376}
290 377
291void 378void
292startlwp32(void *arg) 379startlwp32(void *arg)
293{ 380{
294 ucontext32_t *uc = arg; 381 ucontext32_t *uc = arg;
295 lwp_t *l = curlwp; 382 lwp_t *l = curlwp;
296 int error __diagused; 383 int error __diagused;
297 384
298 /* 385 /*
299 * entity of *uc is ucontext_t. therefore 386 * entity of *uc is ucontext_t. therefore
300 * ucontext_t must be greater than ucontext32_t 387 * ucontext_t must be greater than ucontext32_t
301 */ 388 */
302 CTASSERT(sizeof(ucontext_t) >= sizeof(ucontext32_t)); 389 CTASSERT(sizeof(ucontext_t) >= sizeof(ucontext32_t));
303 390
304 error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags); 391 error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags);
305 KASSERT(error == 0); 392 KASSERT(error == 0);
306 393
307 /* Note: we are freeing ucontext_t, not ucontext32_t. */ 394 /* Note: we are freeing ucontext_t, not ucontext32_t. */
308 kmem_free(uc, sizeof(ucontext_t)); 395 kmem_free(uc, sizeof(ucontext_t));
309 userret(l); 396 userret(l);
310} 397}
311 398
312int 399int
313cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mcp) 400cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mcp)
314{ 401{
315 struct proc * const p __diagused = l->l_proc; 402 struct proc * const p __diagused = l->l_proc;
316 const uint32_t spsr = mcp->__gregs[_REG_CPSR]; 403 const uint32_t spsr = mcp->__gregs[_REG_CPSR];
317 404
318 KASSERT(p->p_flag & PK_32); 405 KASSERT(p->p_flag & PK_32);
319 406
320 if (__SHIFTOUT(spsr, SPSR_M) != SPSR_M_USR32) 407 if (__SHIFTOUT(spsr, SPSR_M) != SPSR_M_USR32)
321 return EINVAL; 408 return EINVAL;
322 if ((spsr & (SPSR_A64_D|SPSR_A|SPSR_I|SPSR_F)) != 0) 409 if ((spsr & (SPSR_A64_D|SPSR_A|SPSR_I|SPSR_F)) != 0)
323 return EINVAL; 410 return EINVAL;
324 411
325#ifdef __AARCH64EB__ 412#ifdef __AARCH64EB__
326 if ((spsr & SPSR_A32_E) == 0) 413 if ((spsr & SPSR_A32_E) == 0)
327 return EINVAL; 414 return EINVAL;
328#else 415#else
329 if ((spsr & SPSR_A32_E) != 0) 416 if ((spsr & SPSR_A32_E) != 0)
330 return EINVAL; 417 return EINVAL;
331#endif 418#endif
332 419
333 if ((spsr & (SPSR_A|SPSR_I|SPSR_F)) != 0) 420 if ((spsr & (SPSR_A|SPSR_I|SPSR_F)) != 0)
334 return EINVAL; 421 return EINVAL;
335 422
336 return 0; 423 return 0;
337} 424}
338void 425void
339cpu_getmcontext32(struct lwp *l, mcontext32_t *mcp, unsigned int *flagsp) 426cpu_getmcontext32(struct lwp *l, mcontext32_t *mcp, unsigned int *flagsp)
340{ 427{
341 struct trapframe * const tf = l->l_md.md_utf; 428 struct trapframe * const tf = l->l_md.md_utf;
342 __greg32_t *gr = mcp->__gregs; 429 __greg32_t *gr = mcp->__gregs;
343 __greg32_t ras_pc; 430 __greg32_t ras_pc;
344 431
345 gr[_REG_R0] = tf->tf_reg[0]; 432 gr[_REG_R0] = tf->tf_reg[0];
346 gr[_REG_R1] = tf->tf_reg[1]; 433 gr[_REG_R1] = tf->tf_reg[1];
347 gr[_REG_R2] = tf->tf_reg[2]; 434 gr[_REG_R2] = tf->tf_reg[2];
348 gr[_REG_R3] = tf->tf_reg[3]; 435 gr[_REG_R3] = tf->tf_reg[3];
349 gr[_REG_R4] = tf->tf_reg[4]; 436 gr[_REG_R4] = tf->tf_reg[4];
350 gr[_REG_R5] = tf->tf_reg[5]; 437 gr[_REG_R5] = tf->tf_reg[5];
351 gr[_REG_R6] = tf->tf_reg[6]; 438 gr[_REG_R6] = tf->tf_reg[6];
352 gr[_REG_R7] = tf->tf_reg[7]; 439 gr[_REG_R7] = tf->tf_reg[7];
353 gr[_REG_R8] = tf->tf_reg[8]; 440 gr[_REG_R8] = tf->tf_reg[8];
354 gr[_REG_R9] = tf->tf_reg[9]; 441 gr[_REG_R9] = tf->tf_reg[9];
355 gr[_REG_R10] = tf->tf_reg[10]; 442 gr[_REG_R10] = tf->tf_reg[10];
356 gr[_REG_R11] = tf->tf_reg[11]; 443 gr[_REG_R11] = tf->tf_reg[11];
357 gr[_REG_R12] = tf->tf_reg[12]; 444 gr[_REG_R12] = tf->tf_reg[12];
358 gr[_REG_R13] = tf->tf_reg[13]; 445 gr[_REG_R13] = tf->tf_reg[13];
359 gr[_REG_R14] = tf->tf_reg[14]; 446 gr[_REG_R14] = tf->tf_reg[14];
360 gr[_REG_R15] = tf->tf_pc; 447 gr[_REG_R15] = tf->tf_pc;
361 gr[_REG_CPSR] = tf->tf_spsr; 448 gr[_REG_CPSR] = tf->tf_spsr;
362 449
363 if ((ras_pc = (__greg32_t)(uintptr_t)ras_lookup(l->l_proc, 450 if ((ras_pc = (__greg32_t)(uintptr_t)ras_lookup(l->l_proc,
364 (void *)(uintptr_t)gr[_REG_R15])) != -1) { 451 (void *)(uintptr_t)gr[_REG_R15])) != -1) {
365 gr[_REG_R15] = ras_pc; 452 gr[_REG_R15] = ras_pc;
366 } 453 }
367 *flagsp |= _UC_CPU; 454 *flagsp |= _UC_CPU;
368 455
369 /* fpu context */ 456 /* fpu context */
370 if (fpu_used_p(l)) { 457 if (fpu_used_p(l)) {
371 const struct pcb * const pcb = lwp_getpcb(l); 458 const struct pcb * const pcb = lwp_getpcb(l);
372 int i; 459 int i;
373 460
374 fpu_save(l); 461 fpu_save(l);
375 462
376 CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) == 463 CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) ==
377 __arraycount(pcb->pcb_fpregs.fp_reg)); 464 __arraycount(pcb->pcb_fpregs.fp_reg));
378 for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) { 465 for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
379 mcp->__vfpregs.__vfp_fstmx[i] = 466 mcp->__vfpregs.__vfp_fstmx[i] =
380#ifdef __AARCH64EB__ 467#ifdef __AARCH64EB__
381 pcb->pcb_fpregs.fp_reg[i].u64[1]; 468 pcb->pcb_fpregs.fp_reg[i].u64[1];
382#else 469#else
383 pcb->pcb_fpregs.fp_reg[i].u64[0]; 470 pcb->pcb_fpregs.fp_reg[i].u64[0];
384#endif 471#endif
385 } 472 }
386 473
387 mcp->__vfpregs.__vfp_fpscr = 474 mcp->__vfpregs.__vfp_fpscr =
388 (pcb->pcb_fpregs.fpsr & FPSR_BITS) | 475 (pcb->pcb_fpregs.fpsr & FPSR_BITS) |
389 (pcb->pcb_fpregs.fpcr & FPCR_BITS); 476 (pcb->pcb_fpregs.fpcr & FPCR_BITS);
390 mcp->__vfpregs.__vfp_fpsid = 0; /* XXX: build FPSID from MIDR */ 477 mcp->__vfpregs.__vfp_fpsid = 0; /* XXX: build FPSID from MIDR */
391 478
392 *flagsp |= _UC_FPU; 479 *flagsp |= _UC_FPU;
393 } 480 }
394 481
395 mcp->_mc_tlsbase = (uint32_t)(uintptr_t)l->l_private; 482 mcp->_mc_tlsbase = (uint32_t)(uintptr_t)l->l_private;
396 *flagsp |= _UC_TLSBASE; 483 *flagsp |= _UC_TLSBASE;
397} 484}
398 485
399int 486int
400cpu_setmcontext32(struct lwp *l, const mcontext32_t *mcp, unsigned int flags) 487cpu_setmcontext32(struct lwp *l, const mcontext32_t *mcp, unsigned int flags)
401{ 488{
402 struct trapframe * const tf = l->l_md.md_utf; 489 struct trapframe * const tf = l->l_md.md_utf;
403 const __greg32_t * const gr = mcp->__gregs; 490 const __greg32_t * const gr = mcp->__gregs;
404 struct proc * const p = l->l_proc; 491 struct proc * const p = l->l_proc;
405 int error, i; 492 int error, i;
406 493
407 if (flags & _UC_CPU) { 494 if (flags & _UC_CPU) {
408 error = cpu_mcontext32_validate(l, mcp); 495 error = cpu_mcontext32_validate(l, mcp);
409 if (error != 0) 496 if (error != 0)
410 return error; 497 return error;
411 498
412 tf->tf_reg[0] = gr[_REG_R0]; 499 tf->tf_reg[0] = gr[_REG_R0];
413 tf->tf_reg[1] = gr[_REG_R1]; 500 tf->tf_reg[1] = gr[_REG_R1];
414 tf->tf_reg[2] = gr[_REG_R2]; 501 tf->tf_reg[2] = gr[_REG_R2];
415 tf->tf_reg[3] = gr[_REG_R3]; 502 tf->tf_reg[3] = gr[_REG_R3];
416 tf->tf_reg[4] = gr[_REG_R4]; 503 tf->tf_reg[4] = gr[_REG_R4];
417 tf->tf_reg[5] = gr[_REG_R5]; 504 tf->tf_reg[5] = gr[_REG_R5];
418 tf->tf_reg[6] = gr[_REG_R6]; 505 tf->tf_reg[6] = gr[_REG_R6];
419 tf->tf_reg[7] = gr[_REG_R7]; 506 tf->tf_reg[7] = gr[_REG_R7];
420 tf->tf_reg[8] = gr[_REG_R8]; 507 tf->tf_reg[8] = gr[_REG_R8];
421 tf->tf_reg[9] = gr[_REG_R9]; 508 tf->tf_reg[9] = gr[_REG_R9];
422 tf->tf_reg[10] = gr[_REG_R10]; 509 tf->tf_reg[10] = gr[_REG_R10];
423 tf->tf_reg[11] = gr[_REG_R11]; 510 tf->tf_reg[11] = gr[_REG_R11];
424 tf->tf_reg[12] = gr[_REG_R12]; 511 tf->tf_reg[12] = gr[_REG_R12];
425 tf->tf_reg[13] = gr[_REG_R13]; 512 tf->tf_reg[13] = gr[_REG_R13];
426 tf->tf_reg[14] = gr[_REG_R14]; 513 tf->tf_reg[14] = gr[_REG_R14];
427 tf->tf_pc = gr[_REG_R15]; 514 tf->tf_pc = gr[_REG_R15];
428 tf->tf_spsr = gr[_REG_CPSR]; 515 tf->tf_spsr = gr[_REG_CPSR];
429 } 516 }
430 517
431 if (flags & _UC_FPU) { 518 if (flags & _UC_FPU) {
432 struct pcb * const pcb = lwp_getpcb(l); 519 struct pcb * const pcb = lwp_getpcb(l);
433 fpu_discard(l, true); 520 fpu_discard(l, true);
434 521
435 CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) == 522 CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) ==
436 __arraycount(pcb->pcb_fpregs.fp_reg)); 523 __arraycount(pcb->pcb_fpregs.fp_reg));
437 for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) { 524 for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
438#ifdef __AARCH64EB__ 525#ifdef __AARCH64EB__
439 pcb->pcb_fpregs.fp_reg[i].u64[0] = 0; 526 pcb->pcb_fpregs.fp_reg[i].u64[0] = 0;
440 pcb->pcb_fpregs.fp_reg[i].u64[1] = 527 pcb->pcb_fpregs.fp_reg[i].u64[1] =
441#else 528#else
442 pcb->pcb_fpregs.fp_reg[i].u64[1] = 0; 529 pcb->pcb_fpregs.fp_reg[i].u64[1] = 0;
443 pcb->pcb_fpregs.fp_reg[i].u64[0] = 530 pcb->pcb_fpregs.fp_reg[i].u64[0] =
444#endif 531#endif
445 mcp->__vfpregs.__vfp_fstmx[i]; 532 mcp->__vfpregs.__vfp_fstmx[i];
446 } 533 }
447 pcb->pcb_fpregs.fpsr = 534 pcb->pcb_fpregs.fpsr =
448 mcp->__vfpregs.__vfp_fpscr & FPSR_BITS; 535 mcp->__vfpregs.__vfp_fpscr & FPSR_BITS;
449 pcb->pcb_fpregs.fpcr = 536 pcb->pcb_fpregs.fpcr =
450 mcp->__vfpregs.__vfp_fpscr & FPCR_BITS; 537 mcp->__vfpregs.__vfp_fpscr & FPCR_BITS;
451 } 538 }
452 539
453 if (flags &_UC_TLSBASE) 540 if (flags &_UC_TLSBASE)
454 l->l_private = (void *)(uintptr_t)mcp->_mc_tlsbase; 541 l->l_private = (void *)(uintptr_t)mcp->_mc_tlsbase;
455 542
456 mutex_enter(p->p_lock); 543 mutex_enter(p->p_lock);
457 if (flags & _UC_SETSTACK) 544 if (flags & _UC_SETSTACK)
458 l->l_sigstk.ss_flags |= SS_ONSTACK; 545 l->l_sigstk.ss_flags |= SS_ONSTACK;
459 if (flags & _UC_CLRSTACK) 546 if (flags & _UC_CLRSTACK)
460 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 547 l->l_sigstk.ss_flags &= ~SS_ONSTACK;
461 mutex_exit(p->p_lock); 548 mutex_exit(p->p_lock);
462 549
463 return 0; 550 return 0;
464} 551}
465 552
466static int 553static int
467arm32_sync_icache(struct lwp *l, const void *args, register_t *retval) 554arm32_sync_icache(struct lwp *l, const void *args, register_t *retval)
468{ 555{
469 struct netbsd32_arm_sync_icache_args ua; 556 struct netbsd32_arm_sync_icache_args ua;
470 struct faultbuf fb; 557 struct faultbuf fb;
471 int error; 558 int error;
472 559
473 error = copyin(args, &ua, sizeof(ua)); 560 error = copyin(args, &ua, sizeof(ua));
474 if (error != 0) 561 if (error != 0)
475 return error; 562 return error;
476 563
477 if ((vaddr_t)ua.addr + ua.len > VM_MAXUSER_ADDRESS32) 564 if ((vaddr_t)ua.addr + ua.len > VM_MAXUSER_ADDRESS32)
478 return EINVAL; 565 return EINVAL;
479 566
480 /* use cpu_set_onfault() by way of precaution */ 567 /* use cpu_set_onfault() by way of precaution */
481 if ((error = cpu_set_onfault(&fb)) == 0) { 568 if ((error = cpu_set_onfault(&fb)) == 0) {
482 pmap_icache_sync_range( 569 pmap_icache_sync_range(
483 vm_map_pmap(&l->l_proc->p_vmspace->vm_map), 570 vm_map_pmap(&l->l_proc->p_vmspace->vm_map),
484 (vaddr_t)ua.addr, (vaddr_t)ua.addr + ua.len); 571 (vaddr_t)ua.addr, (vaddr_t)ua.addr + ua.len);
485 cpu_unset_onfault(); 572 cpu_unset_onfault();
486 } 573 }
487 574
488 *retval = 0; 575 *retval = 0;
489 return error; 576 return error;
490} 577}
491 578
492static int 579static int
493arm32_drain_writebuf(struct lwp *l, const void *args, register_t *retval) 580arm32_drain_writebuf(struct lwp *l, const void *args, register_t *retval)
494{ 581{
495 aarch64_drain_writebuf(); 582 aarch64_drain_writebuf();
496 583
497 *retval = 0; 584 *retval = 0;
498 return 0; 585 return 0;
499} 586}
500 587
501int 588int
502netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap, 589netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap,
503 register_t *retval) 590 register_t *retval)
504{ 591{
505 /* { 592 /* {
506 syscallarg(int) op; 593 syscallarg(int) op;
507 syscallarg(netbsd32_voidp) parms; 594 syscallarg(netbsd32_voidp) parms;
508 } */ 595 } */
509 int error; 596 int error;
510 597
511 switch (SCARG(uap, op)) { 598 switch (SCARG(uap, op)) {
512 case ARM_SYNC_ICACHE: 599 case ARM_SYNC_ICACHE:
513 error = arm32_sync_icache(l, 600 error = arm32_sync_icache(l,
514 NETBSD32PTR64(SCARG(uap, parms)), retval); 601 NETBSD32PTR64(SCARG(uap, parms)), retval);
515 break; 602 break;
516 case ARM_DRAIN_WRITEBUF: 603 case ARM_DRAIN_WRITEBUF:
517 error = arm32_drain_writebuf(l, 604 error = arm32_drain_writebuf(l,
518 NETBSD32PTR64(SCARG(uap, parms)), retval); 605 NETBSD32PTR64(SCARG(uap, parms)), retval);
519 break; 606 break;
520 case ARM_VFP_FPSCR: 607 case ARM_VFP_FPSCR:
521 printf("%s: ARM_VFP_FPSCR not implemented\n", __func__); 608 printf("%s: ARM_VFP_FPSCR not implemented\n", __func__);
522 error = EINVAL; 609 error = EINVAL;
523 break; 610 break;
524 case ARM_FPU_USED: 611 case ARM_FPU_USED:
525 printf("%s: ARM_FPU_USED not implemented\n", __func__); 612 printf("%s: ARM_FPU_USED not implemented\n", __func__);
526 error = EINVAL; 613 error = EINVAL;
527 break; 614 break;
528 default: 615 default:
529 printf("%s: op=%d: not implemented\n", __func__, 616 printf("%s: op=%d: not implemented\n", __func__,
530 SCARG(uap, op)); 617 SCARG(uap, op));
531 error = EINVAL; 618 error = EINVAL;
532 break; 619 break;
533 } 620 }
534 return error; 621 return error;
535} 622}
536 623
537vaddr_t 624vaddr_t
538netbsd32_vm_default_addr(struct proc *p, vaddr_t base, vsize_t sz, 625netbsd32_vm_default_addr(struct proc *p, vaddr_t base, vsize_t sz,
539 int topdown) 626 int topdown)
540{ 627{
541 if (topdown) 628 if (topdown)
542 return VM_DEFAULT_ADDRESS32_TOPDOWN(base, sz); 629 return VM_DEFAULT_ADDRESS32_TOPDOWN(base, sz);
543 else 630 else
544 return VM_DEFAULT_ADDRESS32_BOTTOMUP(base, sz); 631 return VM_DEFAULT_ADDRESS32_BOTTOMUP(base, sz);
545} 632}
546 633
547void  634void
548netbsd32_machdep_md_init(void) 635netbsd32_machdep_md_init(void)
549{  636{
550  637
551 /* nothing to do */ 638 /* nothing to do */
552} 639}
553  640
554void 641void
555netbsd32_machdep_md_fini(void) 642netbsd32_machdep_md_fini(void)
556{ 643{
557  644
558 /* nothing to do */ 645 /* nothing to do */
559} 646}

cvs diff -r1.17.4.3 -r1.17.4.4 src/sys/arch/aarch64/aarch64/trap.c (switch to unified diff)

--- src/sys/arch/aarch64/aarch64/trap.c 2021/01/01 12:31:19 1.17.4.3
+++ src/sys/arch/aarch64/aarch64/trap.c 2021/01/01 12:58:35 1.17.4.4
@@ -1,638 +1,655 @@ @@ -1,638 +1,655 @@
1/* $NetBSD: trap.c,v 1.17.4.3 2021/01/01 12:31:19 martin Exp $ */ 1/* $NetBSD: trap.c,v 1.17.4.4 2021/01/01 12:58:35 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33 33
34__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.3 2021/01/01 12:31:19 martin Exp $"); 34__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.4 2021/01/01 12:58:35 martin Exp $");
35 35
36#include "opt_arm_intr_impl.h" 36#include "opt_arm_intr_impl.h"
37#include "opt_compat_netbsd32.h" 37#include "opt_compat_netbsd32.h"
38#include "opt_dtrace.h" 38#include "opt_dtrace.h"
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/kauth.h> 41#include <sys/kauth.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <sys/atomic.h> 43#include <sys/atomic.h>
44#include <sys/cpu.h> 44#include <sys/cpu.h>
45#ifdef KDB 45#ifdef KDB
46#include <sys/kdb.h> 46#include <sys/kdb.h>
47#endif 47#endif
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/systm.h> 49#include <sys/systm.h>
50#include <sys/signal.h> 50#include <sys/signal.h>
51#include <sys/signalvar.h> 51#include <sys/signalvar.h>
52#include <sys/siginfo.h> 52#include <sys/siginfo.h>
53 53
54#ifdef ARM_INTR_IMPL 54#ifdef ARM_INTR_IMPL
55#include ARM_INTR_IMPL 55#include ARM_INTR_IMPL
56#else 56#else
57#error ARM_INTR_IMPL not defined 57#error ARM_INTR_IMPL not defined
58#endif 58#endif
59 59
60#ifndef ARM_IRQ_HANDLER 60#ifndef ARM_IRQ_HANDLER
61#error ARM_IRQ_HANDLER not defined 61#error ARM_IRQ_HANDLER not defined
62#endif 62#endif
63 63
64#include <aarch64/userret.h> 64#include <aarch64/userret.h>
65#include <aarch64/frame.h> 65#include <aarch64/frame.h>
66#include <aarch64/machdep.h> 66#include <aarch64/machdep.h>
67#include <aarch64/armreg.h> 67#include <aarch64/armreg.h>
68#include <aarch64/locore.h> 68#include <aarch64/locore.h>
69 69
70#ifdef KDB 70#ifdef KDB
71#include <machine/db_machdep.h> 71#include <machine/db_machdep.h>
72#endif 72#endif
73#ifdef DDB 73#ifdef DDB
74#include <ddb/db_output.h> 74#include <ddb/db_output.h>
75#include <machine/db_machdep.h> 75#include <machine/db_machdep.h>
76#endif 76#endif
77#ifdef KDTRACE_HOOKS 77#ifdef KDTRACE_HOOKS
78#include <sys/dtrace_bsd.h> 78#include <sys/dtrace_bsd.h>
79#endif 79#endif
80 80
81#ifdef DDB 81#ifdef DDB
82int sigill_debug = 0; 82int sigill_debug = 0;
83#endif 83#endif
84 84
85#ifdef KDTRACE_HOOKS 85#ifdef KDTRACE_HOOKS
86dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL; 86dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL;
87dtrace_trap_func_t dtrace_trap_func = NULL; 87dtrace_trap_func_t dtrace_trap_func = NULL;
88int (*dtrace_invop_jump_addr)(struct trapframe *); 88int (*dtrace_invop_jump_addr)(struct trapframe *);
89#endif 89#endif
90 90
91const char * const trap_names[] = { 91const char * const trap_names[] = {
92 [ESR_EC_UNKNOWN] = "Unknown Reason (Illegal Instruction)", 92 [ESR_EC_UNKNOWN] = "Unknown Reason (Illegal Instruction)",
93 [ESR_EC_SERROR] = "SError Interrupt", 93 [ESR_EC_SERROR] = "SError Interrupt",
94 [ESR_EC_WFX] = "WFI or WFE instruction execution", 94 [ESR_EC_WFX] = "WFI or WFE instruction execution",
95 [ESR_EC_ILL_STATE] = "Illegal Execution State", 95 [ESR_EC_ILL_STATE] = "Illegal Execution State",
96 96
97 [ESR_EC_SYS_REG] = "MSR/MRS/SYS instruction", 97 [ESR_EC_SYS_REG] = "MSR/MRS/SYS instruction",
98 [ESR_EC_SVC_A64] = "SVC Instruction Execution", 98 [ESR_EC_SVC_A64] = "SVC Instruction Execution",
99 [ESR_EC_HVC_A64] = "HVC Instruction Execution", 99 [ESR_EC_HVC_A64] = "HVC Instruction Execution",
100 [ESR_EC_SMC_A64] = "SMC Instruction Execution", 100 [ESR_EC_SMC_A64] = "SMC Instruction Execution",
101 101
102 [ESR_EC_INSN_ABT_EL0] = "Instruction Abort (EL0)", 102 [ESR_EC_INSN_ABT_EL0] = "Instruction Abort (EL0)",
103 [ESR_EC_INSN_ABT_EL1] = "Instruction Abort (EL1)", 103 [ESR_EC_INSN_ABT_EL1] = "Instruction Abort (EL1)",
104 [ESR_EC_DATA_ABT_EL0] = "Data Abort (EL0)", 104 [ESR_EC_DATA_ABT_EL0] = "Data Abort (EL0)",
105 [ESR_EC_DATA_ABT_EL1] = "Data Abort (EL1)", 105 [ESR_EC_DATA_ABT_EL1] = "Data Abort (EL1)",
106 106
107 [ESR_EC_PC_ALIGNMENT] = "Misaligned PC", 107 [ESR_EC_PC_ALIGNMENT] = "Misaligned PC",
108 [ESR_EC_SP_ALIGNMENT] = "Misaligned SP", 108 [ESR_EC_SP_ALIGNMENT] = "Misaligned SP",
109 109
110 [ESR_EC_FP_ACCESS] = "Access to SIMD/FP Registers", 110 [ESR_EC_FP_ACCESS] = "Access to SIMD/FP Registers",
111 [ESR_EC_FP_TRAP_A64] = "FP Exception", 111 [ESR_EC_FP_TRAP_A64] = "FP Exception",
112 112
113 [ESR_EC_BRKPNT_EL0] = "Breakpoint Exception (EL0)", 113 [ESR_EC_BRKPNT_EL0] = "Breakpoint Exception (EL0)",
114 [ESR_EC_BRKPNT_EL1] = "Breakpoint Exception (EL1)", 114 [ESR_EC_BRKPNT_EL1] = "Breakpoint Exception (EL1)",
115 [ESR_EC_SW_STEP_EL0] = "Software Step (EL0)", 115 [ESR_EC_SW_STEP_EL0] = "Software Step (EL0)",
116 [ESR_EC_SW_STEP_EL1] = "Software Step (EL1)", 116 [ESR_EC_SW_STEP_EL1] = "Software Step (EL1)",
117 [ESR_EC_WTCHPNT_EL0] = "Watchpoint (EL0)", 117 [ESR_EC_WTCHPNT_EL0] = "Watchpoint (EL0)",
118 [ESR_EC_WTCHPNT_EL1] = "Watchpoint (EL1)", 118 [ESR_EC_WTCHPNT_EL1] = "Watchpoint (EL1)",
119 [ESR_EC_BKPT_INSN_A64] = "BKPT Instruction Execution", 119 [ESR_EC_BKPT_INSN_A64] = "BKPT Instruction Execution",
120 120
121 [ESR_EC_CP15_RT] = "A32: MCR/MRC access to CP15", 121 [ESR_EC_CP15_RT] = "A32: MCR/MRC access to CP15",
122 [ESR_EC_CP15_RRT] = "A32: MCRR/MRRC access to CP15", 122 [ESR_EC_CP15_RRT] = "A32: MCRR/MRRC access to CP15",
123 [ESR_EC_CP14_RT] = "A32: MCR/MRC access to CP14", 123 [ESR_EC_CP14_RT] = "A32: MCR/MRC access to CP14",
124 [ESR_EC_CP14_DT] = "A32: LDC/STC access to CP14", 124 [ESR_EC_CP14_DT] = "A32: LDC/STC access to CP14",
125 [ESR_EC_CP14_RRT] = "A32: MRRC access to CP14", 125 [ESR_EC_CP14_RRT] = "A32: MRRC access to CP14",
126 [ESR_EC_SVC_A32] = "A32: SVC Instruction Execution", 126 [ESR_EC_SVC_A32] = "A32: SVC Instruction Execution",
127 [ESR_EC_HVC_A32] = "A32: HVC Instruction Execution", 127 [ESR_EC_HVC_A32] = "A32: HVC Instruction Execution",
128 [ESR_EC_SMC_A32] = "A32: SMC Instruction Execution", 128 [ESR_EC_SMC_A32] = "A32: SMC Instruction Execution",
129 [ESR_EC_FPID] = "A32: MCR/MRC access to CP10", 129 [ESR_EC_FPID] = "A32: MCR/MRC access to CP10",
130 [ESR_EC_FP_TRAP_A32] = "A32: FP Exception", 130 [ESR_EC_FP_TRAP_A32] = "A32: FP Exception",
131 [ESR_EC_BKPT_INSN_A32] = "A32: BKPT Instruction Execution", 131 [ESR_EC_BKPT_INSN_A32] = "A32: BKPT Instruction Execution",
132 [ESR_EC_VECTOR_CATCH] = "A32: Vector Catch Exception" 132 [ESR_EC_VECTOR_CATCH] = "A32: Vector Catch Exception"
133}; 133};
134 134
135const char * 135const char *
136eclass_trapname(uint32_t eclass) 136eclass_trapname(uint32_t eclass)
137{ 137{
138 static char trapnamebuf[sizeof("Unknown trap 0x????????")]; 138 static char trapnamebuf[sizeof("Unknown trap 0x????????")];
139 139
140 if (eclass >= __arraycount(trap_names) || trap_names[eclass] == NULL) { 140 if (eclass >= __arraycount(trap_names) || trap_names[eclass] == NULL) {
141 snprintf(trapnamebuf, sizeof(trapnamebuf), 141 snprintf(trapnamebuf, sizeof(trapnamebuf),
142 "Unknown trap %#02x", eclass); 142 "Unknown trap %#02x", eclass);
143 return trapnamebuf; 143 return trapnamebuf;
144 } 144 }
145 return trap_names[eclass]; 145 return trap_names[eclass];
146} 146}
147 147
148void 148void
149userret(struct lwp *l) 149userret(struct lwp *l)
150{ 150{
151 mi_userret(l); 151 mi_userret(l);
152} 152}
153 153
154void 154void
155trap_doast(struct trapframe *tf) 155trap_doast(struct trapframe *tf)
156{ 156{
157 struct lwp * const l = curlwp; 157 struct lwp * const l = curlwp;
158 158
159 /* 159 /*
160 * allow to have a chance of context switch just prior to user 160 * allow to have a chance of context switch just prior to user
161 * exception return. 161 * exception return.
162 */ 162 */
163#ifdef __HAVE_PREEMPTION 163#ifdef __HAVE_PREEMPTION
164 kpreempt_disable(); 164 kpreempt_disable();
165#endif 165#endif
166 struct cpu_info * const ci = curcpu(); 166 struct cpu_info * const ci = curcpu();
167 167
168 ci->ci_data.cpu_ntrap++; 168 ci->ci_data.cpu_ntrap++;
169 169
170 KDASSERT(ci->ci_cpl == IPL_NONE); 170 KDASSERT(ci->ci_cpl == IPL_NONE);
171 const int want_resched = ci->ci_want_resched; 171 const int want_resched = ci->ci_want_resched;
172#ifdef __HAVE_PREEMPTION 172#ifdef __HAVE_PREEMPTION
173 kpreempt_enable(); 173 kpreempt_enable();
174#endif 174#endif
175 175
176 if (l->l_pflag & LP_OWEUPC) { 176 if (l->l_pflag & LP_OWEUPC) {
177 l->l_pflag &= ~LP_OWEUPC; 177 l->l_pflag &= ~LP_OWEUPC;
178 ADDUPROF(l); 178 ADDUPROF(l);
179 } 179 }
180 180
181 /* Allow a forced task switch. */ 181 /* Allow a forced task switch. */
182 if (want_resched) 182 if (want_resched)
183 preempt(); 183 preempt();
184 userret(l); 184 userret(l);
185} 185}
186 186
187void 187void
188trap_el1h_sync(struct trapframe *tf) 188trap_el1h_sync(struct trapframe *tf)
189{ 189{
190 const uint32_t esr = tf->tf_esr; 190 const uint32_t esr = tf->tf_esr;
191 const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */ 191 const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */
192 192
193 /* re-enable traps and interrupts */ 193 /* re-enable traps and interrupts */
194 if (!(tf->tf_spsr & SPSR_I)) 194 if (!(tf->tf_spsr & SPSR_I))
195 daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F); 195 daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F);
196 else 196 else
197 daif_enable(DAIF_D|DAIF_A); 197 daif_enable(DAIF_D|DAIF_A);
198 198
199#ifdef KDTRACE_HOOKS 199#ifdef KDTRACE_HOOKS
200 if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, eclass)) 200 if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, eclass))
201 return; 201 return;
202#endif 202#endif
203 203
204 switch (eclass) { 204 switch (eclass) {
205 case ESR_EC_INSN_ABT_EL1: 205 case ESR_EC_INSN_ABT_EL1:
206 case ESR_EC_DATA_ABT_EL1: 206 case ESR_EC_DATA_ABT_EL1:
207 data_abort_handler(tf, eclass); 207 data_abort_handler(tf, eclass);
208 break; 208 break;
209 209
210 case ESR_EC_BKPT_INSN_A64: 210 case ESR_EC_BKPT_INSN_A64:
211#ifdef KDTRACE_HOOKS 211#ifdef KDTRACE_HOOKS
212 if (__SHIFTOUT(esr, ESR_ISS) == 0x40d && 212 if (__SHIFTOUT(esr, ESR_ISS) == 0x40d &&
213 dtrace_invop_jump_addr != 0) { 213 dtrace_invop_jump_addr != 0) {
214 (*dtrace_invop_jump_addr)(tf); 214 (*dtrace_invop_jump_addr)(tf);
215 break; 215 break;
216 } 216 }
217 /* FALLTHROUGH */ 217 /* FALLTHROUGH */
218#endif 218#endif
219 case ESR_EC_BRKPNT_EL1: 219 case ESR_EC_BRKPNT_EL1:
220 case ESR_EC_SW_STEP_EL1: 220 case ESR_EC_SW_STEP_EL1:
221 case ESR_EC_WTCHPNT_EL1: 221 case ESR_EC_WTCHPNT_EL1:
222#ifdef DDB 222#ifdef DDB
223 if (eclass == ESR_EC_BRKPNT_EL1) 223 if (eclass == ESR_EC_BRKPNT_EL1)
224 kdb_trap(DB_TRAP_BREAKPOINT, tf); 224 kdb_trap(DB_TRAP_BREAKPOINT, tf);
225 else if (eclass == ESR_EC_BKPT_INSN_A64) 225 else if (eclass == ESR_EC_BKPT_INSN_A64)
226 kdb_trap(DB_TRAP_BKPT_INSN, tf); 226 kdb_trap(DB_TRAP_BKPT_INSN, tf);
227 else if (eclass == ESR_EC_WTCHPNT_EL1) 227 else if (eclass == ESR_EC_WTCHPNT_EL1)
228 kdb_trap(DB_TRAP_WATCHPOINT, tf); 228 kdb_trap(DB_TRAP_WATCHPOINT, tf);
229 else if (eclass == ESR_EC_SW_STEP_EL1) 229 else if (eclass == ESR_EC_SW_STEP_EL1)
230 kdb_trap(DB_TRAP_SW_STEP, tf); 230 kdb_trap(DB_TRAP_SW_STEP, tf);
231 else 231 else
232 kdb_trap(DB_TRAP_UNKNOWN, tf); 232 kdb_trap(DB_TRAP_UNKNOWN, tf);
233#else 233#else
234 panic("No debugger in kernel"); 234 panic("No debugger in kernel");
235#endif 235#endif
236 break; 236 break;
237 237
238 case ESR_EC_FP_ACCESS: 238 case ESR_EC_FP_ACCESS:
239 case ESR_EC_FP_TRAP_A64: 239 case ESR_EC_FP_TRAP_A64:
240 case ESR_EC_PC_ALIGNMENT: 240 case ESR_EC_PC_ALIGNMENT:
241 case ESR_EC_SP_ALIGNMENT: 241 case ESR_EC_SP_ALIGNMENT:
242 case ESR_EC_ILL_STATE: 242 case ESR_EC_ILL_STATE:
243 default: 243 default:
244 panic("Trap: fatal %s: pc=%016" PRIx64 " sp=%016" PRIx64 244 panic("Trap: fatal %s: pc=%016" PRIx64 " sp=%016" PRIx64
245 " esr=%08x", eclass_trapname(eclass), tf->tf_pc, tf->tf_sp, 245 " esr=%08x", eclass_trapname(eclass), tf->tf_pc, tf->tf_sp,
246 esr); 246 esr);
247 break; 247 break;
248 } 248 }
249} 249}
250 250
251void 251void
252trap_el0_sync(struct trapframe *tf) 252trap_el0_sync(struct trapframe *tf)
253{ 253{
254 struct lwp * const l = curlwp; 254 struct lwp * const l = curlwp;
255 const uint32_t esr = tf->tf_esr; 255 const uint32_t esr = tf->tf_esr;
256 const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */ 256 const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */
257 257
258 /* disable trace */ 258 /* disable trace */
259 reg_mdscr_el1_write(reg_mdscr_el1_read() & ~MDSCR_SS); 259 reg_mdscr_el1_write(reg_mdscr_el1_read() & ~MDSCR_SS);
260 /* enable traps and interrupts */ 260 /* enable traps and interrupts */
261 daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F); 261 daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F);
262 262
263 switch (eclass) { 263 switch (eclass) {
264 case ESR_EC_INSN_ABT_EL0: 264 case ESR_EC_INSN_ABT_EL0:
265 case ESR_EC_DATA_ABT_EL0: 265 case ESR_EC_DATA_ABT_EL0:
266 data_abort_handler(tf, eclass); 266 data_abort_handler(tf, eclass);
267 userret(l); 267 userret(l);
268 break; 268 break;
269 269
270 case ESR_EC_SVC_A64: 270 case ESR_EC_SVC_A64:
271 (*l->l_proc->p_md.md_syscall)(tf); 271 (*l->l_proc->p_md.md_syscall)(tf);
272 break; 272 break;
273 case ESR_EC_FP_ACCESS: 273 case ESR_EC_FP_ACCESS:
274 fpu_load(l); 274 fpu_load(l);
275 userret(l); 275 userret(l);
276 break; 276 break;
277 case ESR_EC_FP_TRAP_A64: 277 case ESR_EC_FP_TRAP_A64:
278 do_trapsignal(l, SIGFPE, FPE_FLTUND, NULL, esr); /* XXX */ 278 do_trapsignal(l, SIGFPE, FPE_FLTUND, NULL, esr); /* XXX */
279 userret(l); 279 userret(l);
280 break; 280 break;
281 281
282 case ESR_EC_PC_ALIGNMENT: 282 case ESR_EC_PC_ALIGNMENT:
283 do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_pc, esr); 283 do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_pc, esr);
284 userret(l); 284 userret(l);
285 break; 285 break;
286 case ESR_EC_SP_ALIGNMENT: 286 case ESR_EC_SP_ALIGNMENT:
287 do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_sp, esr); 287 do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_sp, esr);
288 userret(l); 288 userret(l);
289 break; 289 break;
290 290
291 case ESR_EC_BKPT_INSN_A64: 291 case ESR_EC_BKPT_INSN_A64:
292 case ESR_EC_BRKPNT_EL0: 292 case ESR_EC_BRKPNT_EL0:
293 case ESR_EC_WTCHPNT_EL0: 293 case ESR_EC_WTCHPNT_EL0:
294 do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr); 294 do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr);
295 userret(l); 295 userret(l);
296 break; 296 break;
297 case ESR_EC_SW_STEP_EL0: 297 case ESR_EC_SW_STEP_EL0:
298 /* disable trace, and send trace trap */ 298 /* disable trace, and send trace trap */
299 tf->tf_spsr &= ~SPSR_SS; 299 tf->tf_spsr &= ~SPSR_SS;
300 do_trapsignal(l, SIGTRAP, TRAP_TRACE, (void *)tf->tf_pc, esr); 300 do_trapsignal(l, SIGTRAP, TRAP_TRACE, (void *)tf->tf_pc, esr);
301 userret(l); 301 userret(l);
302 break; 302 break;
303 303
304 default: 304 default:
305 case ESR_EC_UNKNOWN: 305 case ESR_EC_UNKNOWN:
306#ifdef DDB 306#ifdef DDB
307 if (sigill_debug) { 307 if (sigill_debug) {
308 /* show illegal instruction */ 308 /* show illegal instruction */
309 printf("TRAP: pid %d (%s), uid %d: %s:" 309 printf("TRAP: pid %d (%s), uid %d: %s:"
310 " esr=0x%lx: pc=0x%lx: %s\n", 310 " esr=0x%lx: pc=0x%lx: %s\n",
311 curlwp->l_proc->p_pid, curlwp->l_proc->p_comm, 311 curlwp->l_proc->p_pid, curlwp->l_proc->p_comm,
312 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1, 312 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1,
313 eclass_trapname(eclass), tf->tf_esr, tf->tf_pc, 313 eclass_trapname(eclass), tf->tf_esr, tf->tf_pc,
314 strdisasm(tf->tf_pc)); 314 strdisasm(tf->tf_pc));
315 } 315 }
316#endif 316#endif
317 /* illegal or not implemented instruction */ 317 /* illegal or not implemented instruction */
318 do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr); 318 do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr);
319 userret(l); 319 userret(l);
320 break; 320 break;
321 } 321 }
322} 322}
323 323
324void 324void
325interrupt(struct trapframe *tf) 325interrupt(struct trapframe *tf)
326{ 326{
327 struct cpu_info * const ci = curcpu(); 327 struct cpu_info * const ci = curcpu();
328 328
329#ifdef STACKCHECKS 329#ifdef STACKCHECKS
330 struct lwp *l = curlwp; 330 struct lwp *l = curlwp;
331 void *sp = (void *)reg_sp_read(); 331 void *sp = (void *)reg_sp_read();
332 if (l->l_addr >= sp) { 332 if (l->l_addr >= sp) {
333 panic("lwp/interrupt stack overflow detected." 333 panic("lwp/interrupt stack overflow detected."
334 " lwp=%p, sp=%p, l_addr=%p", l, sp, l->l_addr); 334 " lwp=%p, sp=%p, l_addr=%p", l, sp, l->l_addr);
335 } 335 }
336#endif 336#endif
337 337
338 /* disable trace */ 338 /* disable trace */
339 reg_mdscr_el1_write(reg_mdscr_el1_read() & ~MDSCR_SS); 339 reg_mdscr_el1_write(reg_mdscr_el1_read() & ~MDSCR_SS);
340 340
341 /* enable traps */ 341 /* enable traps */
342 daif_enable(DAIF_D|DAIF_A); 342 daif_enable(DAIF_D|DAIF_A);
343 343
344 ci->ci_intr_depth++; 344 ci->ci_intr_depth++;
345 ARM_IRQ_HANDLER(tf); 345 ARM_IRQ_HANDLER(tf);
346 ci->ci_intr_depth--; 346 ci->ci_intr_depth--;
347 347
348 cpu_dosoftints(); 348 cpu_dosoftints();
349} 349}
350 350
351#ifdef COMPAT_NETBSD32 351#ifdef COMPAT_NETBSD32
352 352
353/* 353/*
354 * 32-bit length Thumb instruction. See ARMv7 DDI0406A A6.3. 354 * 32-bit length Thumb instruction. See ARMv7 DDI0406A A6.3.
355 */ 355 */
356#define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800)) 356#define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800))
357 357
358static int 358static int
359fetch_arm_insn(struct trapframe *tf, uint32_t *insn) 359fetch_arm_insn(struct trapframe *tf, uint32_t *insn)
360{ 360{
361 361
362 /* THUMB? */ 362 /* THUMB? */
363 if (tf->tf_spsr & SPSR_A32_T) { 363 if (tf->tf_spsr & SPSR_A32_T) {
364 uint16_t *pc = (uint16_t *)(tf->tf_pc & ~1UL); /* XXX */ 364 uint16_t *pc = (uint16_t *)(tf->tf_pc & ~1UL); /* XXX */
365 uint16_t hi, lo; 365 uint16_t hi, lo;
366 366
367 if (ufetch_16(pc, &hi)) 367 if (ufetch_16(pc, &hi))
368 return -1; 368 return -1;
369 369
370 if (!THUMB_32BIT(hi)) { 370 if (!THUMB_32BIT(hi)) {
371 /* 16-bit Thumb instruction */ 371 /* 16-bit Thumb instruction */
372 *insn = hi; 372 *insn = hi;
373 return 2; 373 return 2;
374 } 374 }
375 375
376 /* 32-bit Thumb instruction */ 376 /* 32-bit Thumb instruction */
377 if (ufetch_16(pc + 1, &lo)) 377 if (ufetch_16(pc + 1, &lo))
378 return -1; 378 return -1;
379 379
380 *insn = ((uint32_t)hi << 16) | lo; 380 *insn = ((uint32_t)hi << 16) | lo;
381 return 4; 381 return 4;
382 } 382 }
383 383
384 if (ufetch_32((uint32_t *)tf->tf_pc, insn)) 384 if (ufetch_32((uint32_t *)tf->tf_pc, insn))
385 return -1; 385 return -1;
386 386
387 return 4; 387 return 4;
388} 388}
389 389
390enum emul_arm_result { 390enum emul_arm_result {
391 EMUL_ARM_SUCCESS = 0, 391 EMUL_ARM_SUCCESS = 0,
392 EMUL_ARM_UNKNOWN, 392 EMUL_ARM_UNKNOWN,
393 EMUL_ARM_FAULT, 393 EMUL_ARM_FAULT,
394}; 394};
395 395
396static enum emul_arm_result 396static enum emul_arm_result
397emul_arm_insn(struct trapframe *tf) 397emul_arm_insn(struct trapframe *tf)
398{ 398{
 399 struct lwp * const l = curlwp;
399 uint32_t insn; 400 uint32_t insn;
400 int insn_size; 401 int insn_size;
401 402
402 insn_size = fetch_arm_insn(tf, &insn); 403 insn_size = fetch_arm_insn(tf, &insn);
403 404
404 switch (insn_size) { 405 switch (insn_size) {
405 case 2: 406 case 2:
406 /* T32-16bit instruction */ 407 /* T32-16bit instruction */
407 408
 409 /*
 410 * Breakpoint used by GDB.
 411 */
 412 if (insn == 0xdefe)
 413 goto trap;
 414
408 /* XXX: some T32 IT instruction deprecated should be emulated */ 415 /* XXX: some T32 IT instruction deprecated should be emulated */
409 break; 416 break;
410 case 4: 417 case 4:
411 /* T32-32bit instruction, or A32 instruction */ 418 /* T32-32bit instruction, or A32 instruction */
412 419
413 /* 420 /*
 421 * Breakpoint used by GDB.
 422 */
 423 if (insn == 0xe6000011 || insn == 0xe7ffdefe) {
 424 trap:
 425 do_trapsignal(l, SIGTRAP, TRAP_BRKPT,
 426 (void *)tf->tf_pc, 0);
 427 return 0;
 428 }
 429
 430 /*
414 * Emulate ARMv6 instructions with cache operations 431 * Emulate ARMv6 instructions with cache operations
415 * register (c7), that can be used in user mode. 432 * register (c7), that can be used in user mode.
416 */ 433 */
417 switch (insn & 0x0fff0fff) { 434 switch (insn & 0x0fff0fff) {
418 case 0x0e070f95: 435 case 0x0e070f95:
419 /* 436 /*
420 * mcr p15, 0, <Rd>, c7, c5, 4 437 * mcr p15, 0, <Rd>, c7, c5, 4
421 * (flush prefetch buffer) 438 * (flush prefetch buffer)
422 */ 439 */
423 __asm __volatile("isb sy" ::: "memory"); 440 __asm __volatile("isb sy" ::: "memory");
424 goto emulated; 441 goto emulated;
425 case 0x0e070f9a: 442 case 0x0e070f9a:
426 /* 443 /*
427 * mcr p15, 0, <Rd>, c7, c10, 4 444 * mcr p15, 0, <Rd>, c7, c10, 4
428 * (data synchronization barrier) 445 * (data synchronization barrier)
429 */ 446 */
430 __asm __volatile("dsb sy" ::: "memory"); 447 __asm __volatile("dsb sy" ::: "memory");
431 goto emulated; 448 goto emulated;
432 case 0x0e070fba: 449 case 0x0e070fba:
433 /* 450 /*
434 * mcr p15, 0, <Rd>, c7, c10, 5 451 * mcr p15, 0, <Rd>, c7, c10, 5
435 * (data memory barrier) 452 * (data memory barrier)
436 */ 453 */
437 __asm __volatile("dmb sy" ::: "memory"); 454 __asm __volatile("dmb sy" ::: "memory");
438 goto emulated; 455 goto emulated;
439 default: 456 default:
440 break; 457 break;
441 } 458 }
442 break; 459 break;
443 default: 460 default:
444 return EMUL_ARM_FAULT; 461 return EMUL_ARM_FAULT;
445 } 462 }
446 463
447 /* unknown, or unsupported instruction */ 464 /* unknown, or unsupported instruction */
448 return EMUL_ARM_UNKNOWN; 465 return EMUL_ARM_UNKNOWN;
449 466
450 emulated: 467 emulated:
451 tf->tf_pc += insn_size; 468 tf->tf_pc += insn_size;
452 return EMUL_ARM_SUCCESS; 469 return EMUL_ARM_SUCCESS;
453} 470}
454#endif /* COMPAT_NETBSD32 */ 471#endif /* COMPAT_NETBSD32 */
455 472
456void 473void
457trap_el0_32sync(struct trapframe *tf) 474trap_el0_32sync(struct trapframe *tf)
458{ 475{
459 struct lwp * const l = curlwp; 476 struct lwp * const l = curlwp;
460 const uint32_t esr = tf->tf_esr; 477 const uint32_t esr = tf->tf_esr;
461 const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */ 478 const uint32_t eclass = __SHIFTOUT(esr, ESR_EC); /* exception class */
462 479
463 /* disable trace */ 480 /* disable trace */
464 reg_mdscr_el1_write(reg_mdscr_el1_read() & ~MDSCR_SS); 481 reg_mdscr_el1_write(reg_mdscr_el1_read() & ~MDSCR_SS);
465 /* enable traps and interrupts */ 482 /* enable traps and interrupts */
466 daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F); 483 daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F);
467 484
468 switch (eclass) { 485 switch (eclass) {
469#ifdef COMPAT_NETBSD32 486#ifdef COMPAT_NETBSD32
470 case ESR_EC_INSN_ABT_EL0: 487 case ESR_EC_INSN_ABT_EL0:
471 case ESR_EC_DATA_ABT_EL0: 488 case ESR_EC_DATA_ABT_EL0:
472 data_abort_handler(tf, eclass); 489 data_abort_handler(tf, eclass);
473 userret(l); 490 userret(l);
474 break; 491 break;
475 492
476 case ESR_EC_SVC_A32: 493 case ESR_EC_SVC_A32:
477 (*l->l_proc->p_md.md_syscall)(tf); 494 (*l->l_proc->p_md.md_syscall)(tf);
478 break; 495 break;
479 case ESR_EC_FP_ACCESS: 496 case ESR_EC_FP_ACCESS:
480 fpu_load(l); 497 fpu_load(l);
481 userret(l); 498 userret(l);
482 break; 499 break;
483 case ESR_EC_FP_TRAP_A32: 500 case ESR_EC_FP_TRAP_A32:
484 do_trapsignal(l, SIGFPE, FPE_FLTUND, NULL, esr); /* XXX */ 501 do_trapsignal(l, SIGFPE, FPE_FLTUND, NULL, esr); /* XXX */
485 userret(l); 502 userret(l);
486 break; 503 break;
487 504
488 case ESR_EC_PC_ALIGNMENT: 505 case ESR_EC_PC_ALIGNMENT:
489 do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_pc, esr); 506 do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_pc, esr);
490 userret(l); 507 userret(l);
491 break; 508 break;
492 case ESR_EC_SP_ALIGNMENT: 509 case ESR_EC_SP_ALIGNMENT:
493 do_trapsignal(l, SIGBUS, BUS_ADRALN, 510 do_trapsignal(l, SIGBUS, BUS_ADRALN,
494 (void *)tf->tf_reg[13], esr); /* sp is r13 on AArch32 */ 511 (void *)tf->tf_reg[13], esr); /* sp is r13 on AArch32 */
495 userret(l); 512 userret(l);
496 break; 513 break;
497 514
498 case ESR_EC_BKPT_INSN_A32: 515 case ESR_EC_BKPT_INSN_A32:
499 do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr); 516 do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr);
500 userret(l); 517 userret(l);
501 break; 518 break;
502 519
503 case ESR_EC_UNKNOWN: 520 case ESR_EC_UNKNOWN:
504 switch (emul_arm_insn(tf)) { 521 switch (emul_arm_insn(tf)) {
505 case EMUL_ARM_SUCCESS: 522 case EMUL_ARM_SUCCESS:
506 break; 523 break;
507 case EMUL_ARM_UNKNOWN: 524 case EMUL_ARM_UNKNOWN:
508 goto unknown; 525 goto unknown;
509 case EMUL_ARM_FAULT: 526 case EMUL_ARM_FAULT:
510 do_trapsignal(l, SIGSEGV, SEGV_MAPERR, 527 do_trapsignal(l, SIGSEGV, SEGV_MAPERR,
511 (void *)tf->tf_pc, esr); 528 (void *)tf->tf_pc, esr);
512 break; 529 break;
513 } 530 }
514 userret(l); 531 userret(l);
515 break; 532 break;
516 533
517 case ESR_EC_CP15_RT: 534 case ESR_EC_CP15_RT:
518 case ESR_EC_CP15_RRT: 535 case ESR_EC_CP15_RRT:
519 case ESR_EC_CP14_RT: 536 case ESR_EC_CP14_RT:
520 case ESR_EC_CP14_DT: 537 case ESR_EC_CP14_DT:
521 case ESR_EC_CP14_RRT: 538 case ESR_EC_CP14_RRT:
522unknown: 539unknown:
523#endif /* COMPAT_NETBSD32 */ 540#endif /* COMPAT_NETBSD32 */
524 default: 541 default:
525#ifdef DDB 542#ifdef DDB
526 if (sigill_debug) { 543 if (sigill_debug) {
527 /* show illegal instruction */ 544 /* show illegal instruction */
528 printf("TRAP: pid %d (%s), uid %d: %s:" 545 printf("TRAP: pid %d (%s), uid %d: %s:"
529 " esr=0x%lx: pc=0x%lx: %s\n", 546 " esr=0x%lx: pc=0x%lx: %s\n",
530 curlwp->l_proc->p_pid, curlwp->l_proc->p_comm, 547 curlwp->l_proc->p_pid, curlwp->l_proc->p_comm,
531 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1, 548 l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1,
532 eclass_trapname(eclass), tf->tf_esr, tf->tf_pc, 549 eclass_trapname(eclass), tf->tf_esr, tf->tf_pc,
533 strdisasm_aarch32(tf->tf_pc)); 550 strdisasm_aarch32(tf->tf_pc));
534 } 551 }
535#endif 552#endif
536 /* illegal or not implemented instruction */ 553 /* illegal or not implemented instruction */
537 do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr); 554 do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr);
538 userret(l); 555 userret(l);
539 break; 556 break;
540 } 557 }
541} 558}
542 559
543#define bad_trap_panic(trapfunc) \ 560#define bad_trap_panic(trapfunc) \
544void \ 561void \
545trapfunc(struct trapframe *tf) \ 562trapfunc(struct trapframe *tf) \
546{ \ 563{ \
547 panic("%s", __func__); \ 564 panic("%s", __func__); \
548} 565}
549bad_trap_panic(trap_el1t_sync) 566bad_trap_panic(trap_el1t_sync)
550bad_trap_panic(trap_el1t_irq) 567bad_trap_panic(trap_el1t_irq)
551bad_trap_panic(trap_el1t_fiq) 568bad_trap_panic(trap_el1t_fiq)
552bad_trap_panic(trap_el1t_error) 569bad_trap_panic(trap_el1t_error)
553bad_trap_panic(trap_el1h_fiq) 570bad_trap_panic(trap_el1h_fiq)
554bad_trap_panic(trap_el1h_error) 571bad_trap_panic(trap_el1h_error)
555bad_trap_panic(trap_el0_fiq) 572bad_trap_panic(trap_el0_fiq)
556bad_trap_panic(trap_el0_error) 573bad_trap_panic(trap_el0_error)
557bad_trap_panic(trap_el0_32fiq) 574bad_trap_panic(trap_el0_32fiq)
558bad_trap_panic(trap_el0_32error) 575bad_trap_panic(trap_el0_32error)
559 576
560void 577void
561cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb, int val) 578cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb, int val)
562{ 579{
563 tf->tf_reg[19] = fb->fb_reg[FB_X19]; 580 tf->tf_reg[19] = fb->fb_reg[FB_X19];
564 tf->tf_reg[20] = fb->fb_reg[FB_X20]; 581 tf->tf_reg[20] = fb->fb_reg[FB_X20];
565 tf->tf_reg[21] = fb->fb_reg[FB_X21]; 582 tf->tf_reg[21] = fb->fb_reg[FB_X21];
566 tf->tf_reg[22] = fb->fb_reg[FB_X22]; 583 tf->tf_reg[22] = fb->fb_reg[FB_X22];
567 tf->tf_reg[23] = fb->fb_reg[FB_X23]; 584 tf->tf_reg[23] = fb->fb_reg[FB_X23];
568 tf->tf_reg[24] = fb->fb_reg[FB_X24]; 585 tf->tf_reg[24] = fb->fb_reg[FB_X24];
569 tf->tf_reg[25] = fb->fb_reg[FB_X25]; 586 tf->tf_reg[25] = fb->fb_reg[FB_X25];
570 tf->tf_reg[26] = fb->fb_reg[FB_X26]; 587 tf->tf_reg[26] = fb->fb_reg[FB_X26];
571 tf->tf_reg[27] = fb->fb_reg[FB_X27]; 588 tf->tf_reg[27] = fb->fb_reg[FB_X27];
572 tf->tf_reg[28] = fb->fb_reg[FB_X28]; 589 tf->tf_reg[28] = fb->fb_reg[FB_X28];
573 tf->tf_reg[29] = fb->fb_reg[FB_X29]; 590 tf->tf_reg[29] = fb->fb_reg[FB_X29];
574 tf->tf_sp = fb->fb_reg[FB_SP]; 591 tf->tf_sp = fb->fb_reg[FB_SP];
575 tf->tf_pc = fb->fb_reg[FB_LR]; 592 tf->tf_pc = fb->fb_reg[FB_LR];
576 tf->tf_reg[0] = val; 593 tf->tf_reg[0] = val;
577} 594}
578 595
579#ifdef TRAP_SIGDEBUG 596#ifdef TRAP_SIGDEBUG
580static void 597static void
581frame_dump(const struct trapframe *tf) 598frame_dump(const struct trapframe *tf)
582{ 599{
583 const struct reg *r = &tf->tf_regs; 600 const struct reg *r = &tf->tf_regs;
584 601
585 printf("trapframe %p\n", tf); 602 printf("trapframe %p\n", tf);
586 for (size_t i = 0; i < __arraycount(r->r_reg); i++) { 603 for (size_t i = 0; i < __arraycount(r->r_reg); i++) {
587 printf(" r%.2zu %#018" PRIx64 "%c", i, r->r_reg[i], 604 printf(" r%.2zu %#018" PRIx64 "%c", i, r->r_reg[i],
588 " \n"[i && (i & 1) == 0]); 605 " \n"[i && (i & 1) == 0]);
589 } 606 }
590 607
591 printf("\n"); 608 printf("\n");
592 printf(" sp %#018" PRIx64 " pc %#018" PRIx64 "\n", 609 printf(" sp %#018" PRIx64 " pc %#018" PRIx64 "\n",
593 r->r_sp, r->r_pc); 610 r->r_sp, r->r_pc);
594 printf(" spsr %#018" PRIx64 " tpidr %#018" PRIx64 "\n", 611 printf(" spsr %#018" PRIx64 " tpidr %#018" PRIx64 "\n",
595 r->r_spsr, r->r_tpidr); 612 r->r_spsr, r->r_tpidr);
596 printf(" esr %#018" PRIx64 " far %#018" PRIx64 "\n", 613 printf(" esr %#018" PRIx64 " far %#018" PRIx64 "\n",
597 tf->tf_esr, tf->tf_far); 614 tf->tf_esr, tf->tf_far);
598 615
599 printf("\n"); 616 printf("\n");
600 hexdump(printf, "Stack dump", tf, 256); 617 hexdump(printf, "Stack dump", tf, 256);
601} 618}
602 619
603static void 620static void
604sigdebug(const struct trapframe *tf, const ksiginfo_t *ksi) 621sigdebug(const struct trapframe *tf, const ksiginfo_t *ksi)
605{ 622{
606 struct lwp *l = curlwp; 623 struct lwp *l = curlwp;
607 struct proc *p = l->l_proc; 624 struct proc *p = l->l_proc;
608 const uint32_t eclass = __SHIFTOUT(ksi->ksi_trap, ESR_EC); 625 const uint32_t eclass = __SHIFTOUT(ksi->ksi_trap, ESR_EC);
609 626
610 printf("pid %d.%d (%s): signal %d (trap %#x) " 627 printf("pid %d.%d (%s): signal %d (trap %#x) "
611 "@pc %#" PRIx64 ", addr %p, error=%s\n", 628 "@pc %#" PRIx64 ", addr %p, error=%s\n",
612 p->p_pid, l->l_lid, p->p_comm, ksi->ksi_signo, ksi->ksi_trap, 629 p->p_pid, l->l_lid, p->p_comm, ksi->ksi_signo, ksi->ksi_trap,
613 tf->tf_regs.r_pc, ksi->ksi_addr, eclass_trapname(eclass)); 630 tf->tf_regs.r_pc, ksi->ksi_addr, eclass_trapname(eclass));
614 frame_dump(tf); 631 frame_dump(tf);
615} 632}
616#endif 633#endif
617 634
618void do_trapsignal1( 635void do_trapsignal1(
619#ifdef TRAP_SIGDEBUG 636#ifdef TRAP_SIGDEBUG
620 const char *func, 637 const char *func,
621 size_t line, 638 size_t line,
622 struct trapframe *tf, 639 struct trapframe *tf,
623#endif 640#endif
624 struct lwp *l, int signo, int code, void *addr, int trap) 641 struct lwp *l, int signo, int code, void *addr, int trap)
625{ 642{
626 ksiginfo_t ksi; 643 ksiginfo_t ksi;
627 644
628 KSI_INIT_TRAP(&ksi); 645 KSI_INIT_TRAP(&ksi);
629 ksi.ksi_signo = signo; 646 ksi.ksi_signo = signo;
630 ksi.ksi_code = code; 647 ksi.ksi_code = code;
631 ksi.ksi_addr = addr; 648 ksi.ksi_addr = addr;
632 ksi.ksi_trap = trap; 649 ksi.ksi_trap = trap;
633#ifdef TRAP_SIGDEBUG 650#ifdef TRAP_SIGDEBUG
634 printf("%s, %zu: ", func, line); 651 printf("%s, %zu: ", func, line);
635 sigdebug(tf, &ksi); 652 sigdebug(tf, &ksi);
636#endif 653#endif
637 (*l->l_proc->p_emul->e_trapsignal)(l, &ksi); 654 (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
638} 655}

cvs diff -r1.2 -r1.2.4.1 src/sys/arch/aarch64/include/netbsd32_machdep.h (switch to unified diff)

--- src/sys/arch/aarch64/include/netbsd32_machdep.h 2018/10/12 01:28:58 1.2
+++ src/sys/arch/aarch64/include/netbsd32_machdep.h 2021/01/01 12:58:35 1.2.4.1
@@ -1,110 +1,131 @@ @@ -1,110 +1,131 @@
1/* $NetBSD: netbsd32_machdep.h,v 1.2 2018/10/12 01:28:58 ryo Exp $ */ 1/* $NetBSD: netbsd32_machdep.h,v 1.2.4.1 2021/01/01 12:58:35 martin Exp $ */
2 2
3#ifndef _MACHINE_NETBSD32_H_ 3#ifndef _MACHINE_NETBSD32_H_
4#define _MACHINE_NETBSD32_H_ 4#define _MACHINE_NETBSD32_H_
5 5
6#include <sys/ucontext.h> 6#include <sys/ucontext.h>
7#include <compat/sys/ucontext.h> 7#include <compat/sys/ucontext.h>
8#include <compat/sys/siginfo.h> 8#include <compat/sys/siginfo.h>
9 9
 10/*
 11 * arm ptrace constants
 12 * Please keep in sync with sys/arch/arm/include/ptrace.h.
 13 */
 14#define PT32_STEP (PT_FIRSTMACH + 0) /* Not implemented */
 15#define PT32_GETREGS (PT_FIRSTMACH + 1)
 16#define PT32_SETREGS (PT_FIRSTMACH + 2)
 17#define PT32_GETFPREGS (PT_FIRSTMACH + 5)
 18#define PT32_SETFPREGS (PT_FIRSTMACH + 6)
 19#define PT32_SETSTEP (PT_FIRSTMACH + 7) /* Not implemented */
 20#define PT32_CLEARSTEP (PT_FIRSTMACH + 8) /* Not implemented */
 21
10#define NETBSD32_POINTER_TYPE uint32_t 22#define NETBSD32_POINTER_TYPE uint32_t
11typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t; 23typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t;
12 24
13/* earm has 64bit aligned 64bit integers */ 25/* earm has 64bit aligned 64bit integers */
14#define NETBSD32_INT64_ALIGN __attribute__((__aligned__(8))) 26#define NETBSD32_INT64_ALIGN __attribute__((__aligned__(8)))
15 27
16typedef netbsd32_pointer_t netbsd32_sigcontextp_t; 28typedef netbsd32_pointer_t netbsd32_sigcontextp_t;
17 29
18struct netbsd32_sigcontext13 { 30struct netbsd32_sigcontext13 {
19 int32_t sc_onstack; /* sigstack state to restore */ 31 int32_t sc_onstack; /* sigstack state to restore */
20 int32_t __sc_mask13; /* signal mask to restore (old style) */ 32 int32_t __sc_mask13; /* signal mask to restore (old style) */
21 33
22 uint32_t sc_spsr; 34 uint32_t sc_spsr;
23 uint32_t sc_r0; 35 uint32_t sc_r0;
24 uint32_t sc_r1; 36 uint32_t sc_r1;
25 uint32_t sc_r2; 37 uint32_t sc_r2;
26 uint32_t sc_r3; 38 uint32_t sc_r3;
27 uint32_t sc_r4; 39 uint32_t sc_r4;
28 uint32_t sc_r5; 40 uint32_t sc_r5;
29 uint32_t sc_r6; 41 uint32_t sc_r6;
30 uint32_t sc_r7; 42 uint32_t sc_r7;
31 uint32_t sc_r8; 43 uint32_t sc_r8;
32 uint32_t sc_r9; 44 uint32_t sc_r9;
33 uint32_t sc_r10; 45 uint32_t sc_r10;
34 uint32_t sc_r11; 46 uint32_t sc_r11;
35 uint32_t sc_r12; 47 uint32_t sc_r12;
36 uint32_t sc_usr_sp; 48 uint32_t sc_usr_sp;
37 uint32_t sc_usr_lr; 49 uint32_t sc_usr_lr;
38 uint32_t sc_svc_lr; 50 uint32_t sc_svc_lr;
39 uint32_t sc_pc; 51 uint32_t sc_pc;
40}; 52};
41 53
42struct netbsd32_sigcontext { 54struct netbsd32_sigcontext {
43 int32_t sc_onstack; /* sigstack state to restore */ 55 int32_t sc_onstack; /* sigstack state to restore */
44 int32_t __sc_mask13; /* signal mask to restore (old style) */ 56 int32_t __sc_mask13; /* signal mask to restore (old style) */
45 57
46 uint32_t sc_spsr; 58 uint32_t sc_spsr;
47 uint32_t sc_r0; 59 uint32_t sc_r0;
48 uint32_t sc_r1; 60 uint32_t sc_r1;
49 uint32_t sc_r2; 61 uint32_t sc_r2;
50 uint32_t sc_r3; 62 uint32_t sc_r3;
51 uint32_t sc_r4; 63 uint32_t sc_r4;
52 uint32_t sc_r5; 64 uint32_t sc_r5;
53 uint32_t sc_r6; 65 uint32_t sc_r6;
54 uint32_t sc_r7; 66 uint32_t sc_r7;
55 uint32_t sc_r8; 67 uint32_t sc_r8;
56 uint32_t sc_r9; 68 uint32_t sc_r9;
57 uint32_t sc_r10; 69 uint32_t sc_r10;
58 uint32_t sc_r11; 70 uint32_t sc_r11;
59 uint32_t sc_r12; 71 uint32_t sc_r12;
60 uint32_t sc_usr_sp; 72 uint32_t sc_usr_sp;
61 uint32_t sc_usr_lr; 73 uint32_t sc_usr_lr;
62 uint32_t sc_svc_lr; 74 uint32_t sc_svc_lr;
63 uint32_t sc_pc; 75 uint32_t sc_pc;
64 76
65 sigset_t sc_mask; /* signal mask to restore (new style) */ 77 sigset_t sc_mask; /* signal mask to restore (new style) */
66}; 78};
67 79
68struct netbsd32_sigframe_siginfo { 80struct netbsd32_sigframe_siginfo {
69 siginfo32_t sf_si; 81 siginfo32_t sf_si;
70 ucontext32_t sf_uc; 82 ucontext32_t sf_uc;
71}; 83};
72 84
73struct reg32 { 85struct reg32 {
74 uint32_t r[13]; 86 uint32_t r[13];
75 uint32_t r_sp; 87 uint32_t r_sp;
76 uint32_t r_lr; 88 uint32_t r_lr;
77 uint32_t r_pc; 89 uint32_t r_pc;
78 uint32_t r_cpsr; 90 uint32_t r_cpsr;
79}; 91};
80 92
81struct vfpreg32 { 93struct vfpreg32 {
82 uint32_t vfp_fpexc; 94 uint32_t vfp_fpexc;
83 uint32_t vfp_fpscr; 95 uint32_t vfp_fpscr;
84 uint32_t vfp_fpinst; 96 uint32_t vfp_fpinst;
85 uint32_t vfp_fpinst2; 97 uint32_t vfp_fpinst2;
86 uint64_t vfp_regs[33]; /* In case we need fstmx format. */ 98 uint64_t vfp_regs[33]; /* In case we need fstmx format. */
87}; 99};
88 100
89struct fpreg32 { 101struct fpreg32 {
90 struct vfpreg32 fpr_vfp; 102 struct vfpreg32 fpr_vfp;
91}; 103};
92 104
93/* same as cpustate in arm/arm/core_machdep.c */ 105/* same as cpustate in arm/arm/core_machdep.c */
94struct netbsd32_cpustate { 106struct netbsd32_cpustate {
95 struct reg32 regs; 107 struct reg32 regs;
96 struct fpreg32 fpregs; 108 struct fpreg32 fpregs;
97}; 109};
98 110
99/* compat netbsd/arm sysarch(2) */ 111/* compat netbsd/arm sysarch(2) */
100#define ARM_SYNC_ICACHE 0 112#define ARM_SYNC_ICACHE 0
101#define ARM_DRAIN_WRITEBUF 1 113#define ARM_DRAIN_WRITEBUF 1
102#define ARM_VFP_FPSCR 2 114#define ARM_VFP_FPSCR 2
103#define ARM_FPU_USED 3 115#define ARM_FPU_USED 3
104 116
105struct netbsd32_arm_sync_icache_args { 117struct netbsd32_arm_sync_icache_args {
106 netbsd32_uintptr_t addr; /* Virtual start address */ 118 uint32_t addr; /* Virtual start address */
107 netbsd32_size_t len; /* Region size */ 119 uint32_t len; /* Region size */
108}; 120};
109 121
 122/* Translate ptrace() PT_* request from 32-bit userland to kernel. */
 123int netbsd32_ptrace_translate_request(int);
 124
 125int netbsd32_process_read_regs(struct lwp *, struct reg32 *);
 126int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *);
 127
 128int netbsd32_process_write_regs(struct lwp *, const struct reg32 *);
 129int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t);
 130
110#endif /* _MACHINE_NETBSD32_H_ */ 131#endif /* _MACHINE_NETBSD32_H_ */

cvs diff -r1.9 -r1.9.2.1 src/sys/arch/aarch64/include/ptrace.h (switch to unified diff)

--- src/sys/arch/aarch64/include/ptrace.h 2019/06/18 21:18:11 1.9
+++ src/sys/arch/aarch64/include/ptrace.h 2021/01/01 12:58:35 1.9.2.1
@@ -1,75 +1,94 @@ @@ -1,75 +1,94 @@
1/* $NetBSD: ptrace.h,v 1.9 2019/06/18 21:18:11 kamil Exp $ */ 1/* $NetBSD: ptrace.h,v 1.9.2.1 2021/01/01 12:58:35 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry. 8 * by Matt Thomas of 3am Software Foundry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#ifndef _AARCH64_PTRACE_H_ 32#ifndef _AARCH64_PTRACE_H_
33#define _AARCH64_PTRACE_H_ 33#define _AARCH64_PTRACE_H_
34 34
35#ifdef __aarch64__ 35#ifdef __aarch64__
36 36
37/* 37/*
38 * AARCH64-dependent ptrace definitions. 38 * AARCH64-dependent ptrace definitions.
39 */ 39 */
40#define PT_GETREGS (PT_FIRSTMACH + 0) 40#define PT_GETREGS (PT_FIRSTMACH + 0)
41#define PT_SETREGS (PT_FIRSTMACH + 1) 41#define PT_SETREGS (PT_FIRSTMACH + 1)
42#define PT_GETFPREGS (PT_FIRSTMACH + 2) 42#define PT_GETFPREGS (PT_FIRSTMACH + 2)
43#define PT_SETFPREGS (PT_FIRSTMACH + 3) 43#define PT_SETFPREGS (PT_FIRSTMACH + 3)
44#define PT_STEP (PT_FIRSTMACH + 4) 44#define PT_STEP (PT_FIRSTMACH + 4)
45#define PT_SETSTEP (PT_FIRSTMACH + 5) 45#define PT_SETSTEP (PT_FIRSTMACH + 5)
46#define PT_CLEARSTEP (PT_FIRSTMACH + 6) 46#define PT_CLEARSTEP (PT_FIRSTMACH + 6)
47 47
48#define PT_MACHDEP_STRINGS \ 48#define PT_MACHDEP_STRINGS \
49 "PT_GETREGS", \ 49 "PT_GETREGS", \
50 "PT_SETREGS", \ 50 "PT_SETREGS", \
51 "PT_GETFPREGS", \ 51 "PT_GETFPREGS", \
52 "PT_SETFPREGS", \ 52 "PT_SETFPREGS", \
53 "PT_STEP", \ 53 "PT_STEP", \
54 "PT_SETSTEP", \ 54 "PT_SETSTEP", \
55 "PT_CLEARSTEP", 55 "PT_CLEARSTEP",
56 56
57 57
58#include <machine/reg.h> 58#include <machine/reg.h>
59#define PTRACE_REG_PC(r) (r)->r_pc 59#define PTRACE_REG_PC(r) (r)->r_pc
60#define PTRACE_REG_FP(r) (r)->r_reg[29] 60#define PTRACE_REG_FP(r) (r)->r_reg[29]
61#define PTRACE_REG_SET_PC(r, v) (r)->r_pc = (v) 61#define PTRACE_REG_SET_PC(r, v) (r)->r_pc = (v)
62#define PTRACE_REG_SP(r) (r)->r_sp 62#define PTRACE_REG_SP(r) (r)->r_sp
63#define PTRACE_REG_INTRV(r) (r)->r_reg[0] 63#define PTRACE_REG_INTRV(r) (r)->r_reg[0]
64 64
65#define PTRACE_BREAKPOINT ((const uint8_t[]) { 0xa0, 0x01, 0x20, 0xd4 }) 65#define PTRACE_BREAKPOINT ((const uint8_t[]) { 0xa0, 0x01, 0x20, 0xd4 })
66#define PTRACE_BREAKPOINT_ASM __asm __volatile("brk #13" ::: "memory") 66#define PTRACE_BREAKPOINT_ASM __asm __volatile("brk #13" ::: "memory")
67#define PTRACE_BREAKPOINT_SIZE 4 67#define PTRACE_BREAKPOINT_SIZE 4
68 68
 69#ifdef _KERNEL_OPT
 70#include "opt_compat_netbsd32.h"
 71#endif
 72
 73#ifdef COMPAT_NETBSD32
 74#include <machine/netbsd32_machdep.h>
 75
 76#define process_read_regs32 netbsd32_process_read_regs
 77#define process_read_fpregs32 netbsd32_process_read_fpregs
 78
 79#define process_write_regs32 netbsd32_process_write_regs
 80#define process_write_fpregs32 netbsd32_process_write_fpregs
 81
 82#define process_reg32 struct reg32
 83#define process_fpreg32 struct fpreg32
 84
 85#define PTRACE_TRANSLATE_REQUEST32(x) netbsd32_ptrace_translate_request(x)
 86#endif /* COMPAT_NETBSD32 */
 87
69#elif defined(__arm__) 88#elif defined(__arm__)
70 89
71#include <arm/ptrace.h> 90#include <arm/ptrace.h>
72 91
73#endif 92#endif
74 93
75#endif /* _AARCH64_PTRACE_H_ */ 94#endif /* _AARCH64_PTRACE_H_ */