1 // SPDX-License-Identifier: GPL-2.0 2 #define __FRAME_OFFSETS 3 #include <linux/errno.h> 4 #include <linux/string.h> 5 #include <sys/ucontext.h> 6 #include <asm/ptrace.h> 7 #include <asm/sigcontext.h> 8 #include <sysdep/ptrace.h> 9 #include <sysdep/mcontext.h> 10 #include <arch.h> 11 12 void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) 13 { 14 #ifdef __i386__ 15 #define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y] 16 #define COPY(X) regs->gp[X] = mc->gregs[REG_##X] 17 #define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff; 18 #define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3; 19 COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS); 20 COPY(EDI); COPY(ESI); COPY(EBP); 21 COPY2(UESP, ESP); /* sic */ 22 COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX); 23 COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS); 24 #undef COPY2 25 #undef COPY 26 #undef COPY_SEG 27 #undef COPY_SEG_CPL3 28 #else 29 #define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y] 30 #define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X] 31 COPY(R8); COPY(R9); COPY(R10); COPY(R11); 32 COPY(R12); COPY(R13); COPY(R14); COPY(R15); 33 COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX); 34 COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP); 35 COPY(RIP); 36 COPY2(EFLAGS, EFL); 37 COPY2(CS, CSGSFS); 38 regs->gp[SS / sizeof(unsigned long)] = mc->gregs[REG_CSGSFS] >> 48; 39 #undef COPY2 40 #undef COPY 41 #endif 42 } 43 44 void mc_set_rip(void *_mc, void *target) 45 { 46 mcontext_t *mc = _mc; 47 48 #ifdef __i386__ 49 mc->gregs[REG_EIP] = (unsigned long)target; 50 #else 51 mc->gregs[REG_RIP] = (unsigned long)target; 52 #endif 53 } 54 55 /* Same thing, but the copy macros are turned around. */ 56 void get_mc_from_regs(struct uml_pt_regs *regs, mcontext_t *mc, int single_stepping) 57 { 58 #ifdef __i386__ 59 #define COPY2(X,Y) mc->gregs[REG_##Y] = regs->gp[X] 60 #define COPY(X) mc->gregs[REG_##X] = regs->gp[X] 61 #define COPY_SEG(X) mc->gregs[REG_##X] = regs->gp[X] & 0xffff; 62 #define COPY_SEG_CPL3(X) mc->gregs[REG_##X] = (regs->gp[X] & 0xffff) | 3; 63 COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS); 64 COPY(EDI); COPY(ESI); COPY(EBP); 65 COPY2(UESP, ESP); /* sic */ 66 COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX); 67 COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS); 68 #else 69 #define COPY2(X,Y) mc->gregs[REG_##Y] = regs->gp[X/sizeof(unsigned long)] 70 #define COPY(X) mc->gregs[REG_##X] = regs->gp[X/sizeof(unsigned long)] 71 COPY(R8); COPY(R9); COPY(R10); COPY(R11); 72 COPY(R12); COPY(R13); COPY(R14); COPY(R15); 73 COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX); 74 COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP); 75 COPY(RIP); 76 COPY2(EFLAGS, EFL); 77 mc->gregs[REG_CSGSFS] = mc->gregs[REG_CSGSFS] & 0xffffffffffffl; 78 mc->gregs[REG_CSGSFS] |= (regs->gp[SS / sizeof(unsigned long)] & 0xffff) << 48; 79 #endif 80 81 if (single_stepping) 82 mc->gregs[REG_EFL] |= X86_EFLAGS_TF; 83 else 84 mc->gregs[REG_EFL] &= ~X86_EFLAGS_TF; 85 } 86 87 #ifdef CONFIG_X86_32 88 struct _xstate_64 { 89 struct _fpstate_64 fpstate; 90 struct _header xstate_hdr; 91 struct _ymmh_state ymmh; 92 /* New processor state extensions go here: */ 93 }; 94 95 /* Not quite the right structures as these contain more information */ 96 int um_i387_from_fxsr(struct _fpstate_32 *i387, 97 const struct _fpstate_64 *fxsave); 98 int um_fxsr_from_i387(struct _fpstate_64 *fxsave, 99 const struct _fpstate_32 *from); 100 #else 101 #define _xstate_64 _xstate 102 #endif 103 104 static struct _fpstate *get_fpstate(struct stub_data *data, 105 mcontext_t *mcontext, 106 int *fp_size) 107 { 108 struct _fpstate *res; 109 110 /* Assume floating point registers are on the same page */ 111 res = (void *)(((unsigned long)mcontext->fpregs & 112 (UM_KERN_PAGE_SIZE - 1)) + 113 (unsigned long)&data->sigstack[0]); 114 115 if ((void *)res + sizeof(struct _fpstate) > 116 (void *)data->sigstack + sizeof(data->sigstack)) 117 return NULL; 118 119 if (res->sw_reserved.magic1 != FP_XSTATE_MAGIC1) { 120 *fp_size = sizeof(struct _fpstate); 121 } else { 122 char *magic2_addr; 123 124 magic2_addr = (void *)res; 125 magic2_addr += res->sw_reserved.extended_size; 126 magic2_addr -= FP_XSTATE_MAGIC2_SIZE; 127 128 /* We still need to be within our stack */ 129 if ((void *)magic2_addr > 130 (void *)data->sigstack + sizeof(data->sigstack)) 131 return NULL; 132 133 /* If we do not read MAGIC2, then we did something wrong */ 134 if (*(__u32 *)magic2_addr != FP_XSTATE_MAGIC2) 135 return NULL; 136 137 /* Remove MAGIC2 from the size, we do not save/restore it */ 138 *fp_size = res->sw_reserved.extended_size - 139 FP_XSTATE_MAGIC2_SIZE; 140 } 141 142 return res; 143 } 144 145 int get_stub_state(struct uml_pt_regs *regs, struct stub_data *data, 146 unsigned long *fp_size_out) 147 { 148 mcontext_t *mcontext; 149 struct _fpstate *fpstate_stub; 150 struct _xstate_64 *xstate_stub; 151 int fp_size, xstate_size; 152 153 /* mctx_offset is verified by wait_stub_done_seccomp */ 154 mcontext = (void *)&data->sigstack[data->mctx_offset]; 155 156 get_regs_from_mc(regs, mcontext); 157 158 fpstate_stub = get_fpstate(data, mcontext, &fp_size); 159 if (!fpstate_stub) 160 return -EINVAL; 161 162 #ifdef CONFIG_X86_32 163 xstate_stub = (void *)&fpstate_stub->_fxsr_env; 164 xstate_size = fp_size - offsetof(struct _fpstate_32, _fxsr_env); 165 #else 166 xstate_stub = (void *)fpstate_stub; 167 xstate_size = fp_size; 168 #endif 169 170 if (fp_size_out) 171 *fp_size_out = xstate_size; 172 173 if (xstate_size > host_fp_size) 174 return -ENOSPC; 175 176 memcpy(®s->fp, xstate_stub, xstate_size); 177 178 /* We do not need to read the x86_64 FS_BASE/GS_BASE registers as 179 * we do not permit userspace to set them directly. 180 */ 181 182 #ifdef CONFIG_X86_32 183 /* Read the i387 legacy FP registers */ 184 if (um_fxsr_from_i387((void *)®s->fp, fpstate_stub)) 185 return -EINVAL; 186 #endif 187 188 return 0; 189 } 190 191 /* Copied because we cannot include regset.h here. */ 192 struct task_struct; 193 struct user_regset; 194 struct membuf { 195 void *p; 196 size_t left; 197 }; 198 199 int fpregs_legacy_get(struct task_struct *target, 200 const struct user_regset *regset, 201 struct membuf to); 202 203 int set_stub_state(struct uml_pt_regs *regs, struct stub_data *data, 204 int single_stepping) 205 { 206 mcontext_t *mcontext; 207 struct _fpstate *fpstate_stub; 208 struct _xstate_64 *xstate_stub; 209 int fp_size, xstate_size; 210 211 /* mctx_offset is verified by wait_stub_done_seccomp */ 212 mcontext = (void *)&data->sigstack[data->mctx_offset]; 213 214 if ((unsigned long)mcontext < (unsigned long)data->sigstack || 215 (unsigned long)mcontext > 216 (unsigned long) data->sigstack + 217 sizeof(data->sigstack) - sizeof(*mcontext)) 218 return -EINVAL; 219 220 get_mc_from_regs(regs, mcontext, single_stepping); 221 222 fpstate_stub = get_fpstate(data, mcontext, &fp_size); 223 if (!fpstate_stub) 224 return -EINVAL; 225 226 #ifdef CONFIG_X86_32 227 xstate_stub = (void *)&fpstate_stub->_fxsr_env; 228 xstate_size = fp_size - offsetof(struct _fpstate_32, _fxsr_env); 229 #else 230 xstate_stub = (void *)fpstate_stub; 231 xstate_size = fp_size; 232 #endif 233 234 memcpy(xstate_stub, ®s->fp, xstate_size); 235 236 #ifdef __i386__ 237 /* 238 * On x86, the GDT entries are updated by arch_set_tls. 239 */ 240 241 /* Store the i387 legacy FP registers which the host will use */ 242 if (um_i387_from_fxsr(fpstate_stub, (void *)®s->fp)) 243 return -EINVAL; 244 #else 245 /* 246 * On x86_64, we need to sync the FS_BASE/GS_BASE registers using the 247 * arch specific data. 248 */ 249 if (data->arch_data.fs_base != regs->gp[FS_BASE / sizeof(unsigned long)]) { 250 data->arch_data.fs_base = regs->gp[FS_BASE / sizeof(unsigned long)]; 251 data->arch_data.sync |= STUB_SYNC_FS_BASE; 252 } 253 if (data->arch_data.gs_base != regs->gp[GS_BASE / sizeof(unsigned long)]) { 254 data->arch_data.gs_base = regs->gp[GS_BASE / sizeof(unsigned long)]; 255 data->arch_data.sync |= STUB_SYNC_GS_BASE; 256 } 257 #endif 258 259 return 0; 260 } 261