Lines Matching +full:cs +full:- +full:value +full:- +full:bit
1 // SPDX-License-Identifier: GPL-2.0-only
111 REG_OFFSET_NAME(cs),
119 * regs_query_register_offset() - query register offset from its name
123 * pt_regs from its name. If the name is invalid, this returns -EINVAL;
128 for (roff = regoffset_table; roff->name != NULL; roff++) in regs_query_register_offset()
129 if (!strcmp(roff->name, name)) in regs_query_register_offset()
130 return roff->offset; in regs_query_register_offset()
131 return -EINVAL; in regs_query_register_offset()
135 * regs_query_register_name() - query register name from its offset
144 for (roff = regoffset_table; roff->name != NULL; roff++) in regs_query_register_name()
145 if (roff->offset == offset) in regs_query_register_name()
146 return roff->name; in regs_query_register_name()
166 * Determines whether a value may be installed in a segment register.
168 static inline bool invalid_selector(u16 value) in invalid_selector() argument
170 return unlikely(value != 0 && (value & SEGMENT_RPL_MASK) != USER_RPL); in invalid_selector()
180 return ®s->bx + (regno >> 2); in pt_regs_access()
186 * Returning the value truncates it to 16 bits. in get_segment_reg()
195 retval = task->thread.gs; in get_segment_reg()
201 unsigned long offset, u16 value) in set_segment_reg() argument
204 return -EIO; in set_segment_reg()
207 * The value argument was already truncated to 16 bits. in set_segment_reg()
209 if (invalid_selector(value)) in set_segment_reg()
210 return -EIO; in set_segment_reg()
213 * For %cs and %ss we cannot permit a null selector. in set_segment_reg()
216 * we will never get back to user mode with invalid %cs or %ss in set_segment_reg()
222 case offsetof(struct user_regs_struct, cs): in set_segment_reg()
224 if (unlikely(value == 0)) in set_segment_reg()
225 return -EIO; in set_segment_reg()
229 *pt_regs_access(task_pt_regs(task), offset) = value; in set_segment_reg()
233 task->thread.gs = value; in set_segment_reg()
246 return ®s->r15 + (offset / sizeof(regs->r15)); in pt_regs_access()
252 * Returning the value truncates it to 16 bits. in get_segment_reg()
263 return task->thread.fsindex; in get_segment_reg()
269 return task->thread.gsindex; in get_segment_reg()
275 return task->thread.ds; in get_segment_reg()
281 return task->thread.es; in get_segment_reg()
283 case offsetof(struct user_regs_struct, cs): in get_segment_reg()
291 unsigned long offset, u16 value) in set_segment_reg() argument
294 return -EIO; in set_segment_reg()
297 * The value argument was already truncated to 16 bits. in set_segment_reg()
299 if (invalid_selector(value)) in set_segment_reg()
300 return -EIO; in set_segment_reg()
310 task->thread.fsindex = value; in set_segment_reg()
313 task->thread.gsindex = value; in set_segment_reg()
316 task->thread.ds = value; in set_segment_reg()
319 task->thread.es = value; in set_segment_reg()
323 * Can't actually change these in 64-bit mode. in set_segment_reg()
325 case offsetof(struct user_regs_struct,cs): in set_segment_reg()
326 if (unlikely(value == 0)) in set_segment_reg()
327 return -EIO; in set_segment_reg()
328 task_pt_regs(task)->cs = value; in set_segment_reg()
331 if (unlikely(value == 0)) in set_segment_reg()
332 return -EIO; in set_segment_reg()
333 task_pt_regs(task)->ss = value; in set_segment_reg()
344 unsigned long retval = task_pt_regs(task)->flags; in get_flags()
355 static int set_flags(struct task_struct *task, unsigned long value) in set_flags() argument
360 * If the user value contains TF, mark that in set_flags()
364 if (value & X86_EFLAGS_TF) in set_flags()
367 value |= X86_EFLAGS_TF; in set_flags()
369 regs->flags = (regs->flags & ~FLAG_MASK) | (value & FLAG_MASK); in set_flags()
375 unsigned long offset, unsigned long value) in putreg() argument
378 case offsetof(struct user_regs_struct, cs): in putreg()
384 return set_segment_reg(child, offset, value); in putreg()
387 return set_flags(child, value); in putreg()
391 if (value >= TASK_SIZE_MAX) in putreg()
392 return -EIO; in putreg()
393 x86_fsbase_write_task(child, value); in putreg()
396 if (value >= TASK_SIZE_MAX) in putreg()
397 return -EIO; in putreg()
398 x86_gsbase_write_task(child, value); in putreg()
403 *pt_regs_access(task_pt_regs(child), offset) = value; in putreg()
410 case offsetof(struct user_regs_struct, cs): in getreg()
453 count -= sizeof(*k); in genregs_set()
464 count -= sizeof(*u); in genregs_set()
476 struct thread_struct *thread = &(current->thread); in ptrace_triggered()
483 if (thread->ptrace_bps[i] == bp) in ptrace_triggered()
487 thread->virtual_dr6 |= (DR_TRAP0 << i); in ptrace_triggered()
492 * build the dr7 value on top of their attributes.
502 if (bp[i] && !bp[i]->attr.disabled) { in ptrace_get_dr7()
504 dr7 |= encode_dr7(i, info->len, info->type); in ptrace_get_dr7()
518 attr->bp_len = bp_len; in ptrace_fill_bp_fields()
519 attr->bp_type = bp_type; in ptrace_fill_bp_fields()
520 attr->disabled = disabled; in ptrace_fill_bp_fields()
547 struct perf_event_attr attr = bp->attr; in ptrace_modify_breakpoint()
562 struct thread_struct *thread = &tsk->thread; in ptrace_write_dr7()
568 old_dr7 = ptrace_get_dr7(thread->ptrace_bps); in ptrace_write_dr7()
575 struct perf_event *bp = thread->ptrace_bps[i]; in ptrace_write_dr7()
588 thread->ptrace_bps[i] = bp; in ptrace_write_dr7()
613 struct thread_struct *thread = &tsk->thread; in ptrace_get_debugreg()
618 struct perf_event *bp = thread->ptrace_bps[index]; in ptrace_get_debugreg()
621 val = bp->hw.info.address; in ptrace_get_debugreg()
623 val = thread->virtual_dr6 ^ DR6_RESERVED; /* Flip back to arch polarity */ in ptrace_get_debugreg()
625 val = thread->ptrace_dr7; in ptrace_get_debugreg()
633 struct thread_struct *t = &tsk->thread; in ptrace_set_breakpoint_addr()
634 struct perf_event *bp = t->ptrace_bps[nr]; in ptrace_set_breakpoint_addr()
641 * CHECKME: the previous code returned -EIO if the addr wasn't in ptrace_set_breakpoint_addr()
642 * a valid task virtual addr. The new one will return -EINVAL in in ptrace_set_breakpoint_addr()
644 * -EINVAL may be what we want for in-kernel breakpoints users, in ptrace_set_breakpoint_addr()
645 * but -EIO looks better for ptrace, since we refuse a register in ptrace_set_breakpoint_addr()
655 t->ptrace_bps[nr] = bp; in ptrace_set_breakpoint_addr()
657 struct perf_event_attr attr = bp->attr; in ptrace_set_breakpoint_addr()
672 struct thread_struct *thread = &tsk->thread; in ptrace_set_debugreg()
674 int rc = -EIO; in ptrace_set_debugreg()
679 thread->virtual_dr6 = val ^ DR6_RESERVED; /* Flip to positive polarity */ in ptrace_set_debugreg()
684 thread->ptrace_dr7 = val; in ptrace_set_debugreg()
696 struct io_bitmap *iobm = target->thread.io_bitmap; in ioperm_active()
698 return iobm ? DIV_ROUND_UP(iobm->max, regset->size) : 0; in ioperm_active()
705 struct io_bitmap *iobm = target->thread.io_bitmap; in ioperm_get()
708 return -ENXIO; in ioperm_get()
710 return membuf_write(&to, iobm->bitmap, IO_BITMAP_BYTES); in ioperm_get()
716 * Make sure the single step bit is not set.
737 /* This is native 64-bit ptrace() */ in arch_ptrace()
740 /* This is native 32-bit ptrace() */ in arch_ptrace()
749 ret = -EIO; in arch_ptrace()
750 if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user)) in arch_ptrace()
758 addr -= offsetof(struct user, u_debugreg[0]); in arch_ptrace()
766 ret = -EIO; in arch_ptrace()
767 if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user)) in arch_ptrace()
774 addr -= offsetof(struct user, u_debugreg[0]); in arch_ptrace()
813 datap) ? -EIO : 0; in arch_ptrace()
819 datap) ? -EIO : 0; in arch_ptrace()
825 return -EIO; in arch_ptrace()
832 return -EIO; in arch_ptrace()
839 /* normal 64bit interface to access TLS data. in arch_ptrace()
864 regs->q = value; break
870 value); \
873 static int putreg32(struct task_struct *child, unsigned regno, u32 value) in putreg32() argument
880 SEG32(cs); in putreg32()
885 * A 32-bit ptracer on a 64-bit kernel expects that writing in putreg32()
894 value); in putreg32()
896 child->thread.fsbase = in putreg32()
897 x86_fsgsbase_read_task(child, value); in putreg32()
903 value); in putreg32()
905 child->thread.gsbase = in putreg32()
906 x86_fsgsbase_read_task(child, value); in putreg32()
923 * Warning: bizarre corner case fixup here. A 32-bit in putreg32()
924 * debugger setting orig_eax to -1 wants to disable in putreg32()
926 * restart code sign-extends orig_ax. Also make sure in putreg32()
927 * we interpret the -ERESTART* codes correctly if in putreg32()
928 * loaded into regs->ax in case the task is not in putreg32()
929 * actually still sitting at the exit from a 32-bit in putreg32()
932 regs->orig_ax = value; in putreg32()
933 if (syscall_get_nr(child, regs) != -1) in putreg32()
934 child->thread_info.status |= TS_I386_REGS_POKED; in putreg32()
938 return set_flags(child, value); in putreg32()
942 regno -= offsetof(struct user32, u_debugreg[0]); in putreg32()
943 return ptrace_set_debugreg(child, regno / 4, value); in putreg32()
947 return -EIO; in putreg32()
963 *val = regs->q; break
982 R32(cs, cs); in getreg32()
1001 regno -= offsetof(struct user32, u_debugreg[0]); in getreg32()
1007 return -EIO; in getreg32()
1046 count -= sizeof(*k); in genregs32_set()
1057 count -= sizeof(*u); in genregs32_set()
1147 ret = -EIO; in x32_arch_ptrace()
1148 if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user) || in x32_arch_ptrace()
1149 addr < offsetof(struct user_regs_struct, cs)) in x32_arch_ptrace()
1157 addr -= offsetof(struct user, u_debugreg[0]); in x32_arch_ptrace()
1166 zero-extended. */ in x32_arch_ptrace()
1168 ret = -EIO; in x32_arch_ptrace()
1169 if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user) || in x32_arch_ptrace()
1170 addr < offsetof(struct user_regs_struct, cs)) in x32_arch_ptrace()
1177 addr -= offsetof(struct user, u_debugreg[0]); in x32_arch_ptrace()
1379 * regsets. This is suboptimal if the task is messing around with its CS.L
1386 * PTRACE_GETREGSET depends on the returned CS field (and even the offset
1387 * of the returned CS field depends on its value!) and the data format
1388 * accepted by PTRACE_SETREGSET is determined by the old CS value. The
1412 tsk->thread.trap_nr = X86_TRAP_DB; in send_sigtrap()
1413 tsk->thread.error_code = error_code; in send_sigtrap()
1417 user_mode(regs) ? (void __user *)regs->ip : NULL); in send_sigtrap()