summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2020-07-27kill unused dump_fpu() instancesAl Viro
dump_fpu() is used only on the architectures that support elf and have neither CORE_DUMP_USE_REGSET nor ELF_CORE_COPY_FPREGS defined. Currently that's csky, m68k, microblaze, nds32 and unicore32. The rest of the instances are dead code. NB: THIS MUST GO AFTER ELF_FDPIC CONVERSION Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27Merge branch 'work.fdpic' into regset.followupAl Viro
2020-07-27regset: kill user_regset_copyout{,_zero}()Al Viro
no callers left Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27regset(): kill ->get_size()Al Viro
not used anymore Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27regset: kill ->get()Al Viro
no instances left Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27csky: switch to ->regset_get()Al Viro
NB: WTF is fpregs_get() playing at??? Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27xtensa: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27parisc: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27nds32: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27nios2: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27hexagon: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27h8300: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27openrisc: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27riscv: switch to ->regset_get()Al Viro
Note: riscv_fpr_get() used to forget to zero-pad at the end. Not worth -stable... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27c6x: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27ia64: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27arc: switch to ->regset_get()Al Viro
NB: it used to do short store; fix is needed earlier in the series. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27arm: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27sh: convert to ->regset_get()Al Viro
NB: there's a direct call of fpregs_get() left in dump_fpu(). To be taken out once we convert ELF_FDPIC to use of regset. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27arm64: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27mips: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27sparc: switch to ->regset_get()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27s390: switch to ->regset_get()Al Viro
NB: compat NT_S390_LAST_BREAK might be better as compat_long_t rather than long. User-visible ABI, again... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27powerpc: switch to ->regset_get()Al Viro
Note: compat variant of REGSET_TM_CGPR is almost certainly wrong; it claims to be 48*64bit, but just as compat REGSET_GPR it stores 44*32bit of (truncated) registers + 4 32bit zeros... followed by 48 more 32bit zeroes. Might be too late to change - it's a userland ABI, after all ;-/ Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27x86: switch to ->regset_get()Al Viro
All instances of ->get() in arch/x86 switched; that might or might not be worth splitting up. Notes: * for xstateregs_get() the amount we want to store is determined at the boot time; see init_xstate_size() and update_regset_xstate_info() for details. task->thread.fpu.state.xsave ends with a flexible array member and the amount of data in it depends upon the FPU features supported/enabled. * fpregs_get() writes slightly less than full ->thread.fpu.state.fsave (the last word is not copied); we pass the full size of state.fsave and let membuf_write() trim to the amount declared by regset - __regset_get() will make sure that the space in buffer is no more than that. * copy_xstate_to_user() and its helpers are gone now. * fpregs_soft_get() was getting user_regset_copyout() arguments wrong. Since "x86: x86 user_regset math_emu" back in 2008... I really doubt that it's worth splitting out for -stable, though - you need a 486SX box for that to trigger... [Kevin's braino fix for copy_xstate_to_kernel() essentially duplicated here] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27regset: new method and helpers for itAl Viro
->regset_get() takes task+regset+buffer, returns the amount of free space left in the buffer on success and -E... on error. buffer is represented as struct membuf - a pair of (kernel) pointer and amount of space left Primitives for writing to such: * membuf_write(buf, data, size) * membuf_zero(buf, size) * membuf_store(buf, value) These are implemented as inlines (in case of membuf_store - a macro). All writes are sequential; they become no-ops when there's no space left. Return value of all primitives is the amount of space left after the operation, so they can be used as return values of ->regset_get(). Example of use: // stores pt_regs of task + 64 bytes worth of zeroes + 32bit PID of task int foo_get(struct task_struct *task, const struct regset *regset, struct membuf to) { membuf_write(&to, task_pt_regs(task), sizeof(struct pt_regs)); membuf_zero(&to, 64); return membuf_store(&to, (u32)task_tgid_vnr(task)); } regset_get()/regset_get_alloc() taught to use that thing if present. By the end of the series all users of ->get() will be converted; then ->get() and ->get_size() can go. Note that unlike ->get() this thing always starts at offset 0 and, since it only writes to kernel buffer, can't fail on copyout. It can, of course, fail for other reasons, but those tend to be less numerous. The caller guarantees that the buffer size won't be bigger than regset->n * regset->size. That simplifies life for quite a few instances. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27copy_regset_to_user(): do all copyout at once.Al Viro
Turn copy_regset_to_user() into regset_get_alloc() + copy_to_user(). Now all ->get() calls have a kernel buffer as destination. Note that we'd already eliminated the callers of copy_regset_to_user() with non-zero offset; now that argument is simply unused. Uninlined, while we are at it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27Merge branches 'regset.x86', 'regset.ia64', 'regset.sparc' and ↵Al Viro
'regset.arm64' into work.regset
2020-07-27[elf-fdpic] switch coredump to regsetsAl Viro
similar to how elf coredump is working on architectures that have regsets, and all architectures with elf-fdpic support *do* have that. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27[elf-fdpic] use elf_dump_thread_status() for the dumper thread as wellAl Viro
the only reason to have it open-coded for the first (dumper) thread is that coredump has a couple of process-wide notes stuck right after the first (NT_PRSTATUS) note of the first thread. But we don't need to make the data collection side irregular for the first thread to handle that - it's only the logics ordering the calls of writenote() that needs to take care of that. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27[elf-fdpic] move allocation of elf_thread_status into elf_dump_thread_status()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27[elf-fdpic] coredump: don't bother with cyclic list for per-thread objectsAl Viro
plain single-linked list is just fine here... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27kill elf_fpxregs_tAl Viro
all uses are conditional upon ELF_CORE_COPY_XFPREGS, which has not been defined on any architecture since 2010 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27take fdpic-related parts of elf_prstatus outAl Viro
The only architecture where we might end up using both is arm, and there we definitely don't want fdpic-related fields in elf_prstatus - coredump layout of ELF binaries should not depend upon having the kernel built with the support of ELF_FDPIC ones. Just move the fdpic-modified variant into binfmt_elf_fdpic.c (and call it elf_prstatus_fdpic there) [name stolen from nico] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27unexport linux/elfcore.hAl Viro
It's unusable from userland - it uses elf_gregset_t, which is not provided by exported headers. glibc has it in sys/procfs.h, but the same file defines struct elf_prstatus, so linux/elfcore.h can't be included once sys/procfs.h has been pulled. Same goes for uclibc and dietlibc simply doesn't have elf_gregset_t defined anywhere. IOW, no userland source is including that thing. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27introduction of regset ->get() wrappers, switching ELF coredumps to thoseAl Viro
Two new helpers: given a process and regset, dump into a buffer. regset_get() takes a buffer and size, regset_get_alloc() takes size and allocates a buffer. Return value in both cases is the amount of data actually dumped in case of success or -E... on error. In both cases the size is capped by regset->n * regset->size, so ->get() is called with offset 0 and size no more than what regset expects. binfmt_elf.c callers of ->get() are switched to using those; the other caller (copy_regset_to_user()) will need some preparations to switch. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27sparc64: get rid of odd callers of copy_regset_from_user()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-07-27sparc32: get rid of odd callers of copy_regset_from_user()Al Viro
[a couple of unused variables left behind by the previous version spotted by kernel test robot <lkp@intel.com>] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26arm64: sanitize compat_ptrace_write_user()Al Viro
don't bother with copy_regset_from_user() (not to mention set_fs()) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26arm64: get rid of copy_regset_to_user() in compat_ptrace_read_user()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26arm64: take fetching compat reg out of pt_regs into a new helperAl Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26sparc64: get rid of odd callers of copy_regset_to_user()Al Viro
same as for sparc32, and that's it - no more caller of ->get() with non-zero pos. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26sparc32: get rid of odd callers of copy_regset_to_user()Al Viro
the life is much simpler if copy_regset_to_user() (and ->get()) gets called only with pos == 0; sparc32 PTRACE_GETREGS and PTRACE_GETFPREGS are among the few things that use it to fetch pieces of regset _not_ starting at the beginning. It's actually easier to define a separate regset that would provide what we need, rather than trying to cobble that from the one PTRACE_GETREGSET uses. Extra ->get() instances do not amount to much code and once we get the conversion of ->get() to new API (dependent upon the lack of weird callers of ->get()) they'll shrink a lot, along with the rest of ->get() instances... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26sparc64: switch genregs32_get() to use of get_from_target()Al Viro
... for fetching the register window from target's stack, rather than open-coding it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26[ia64] access_uarea(): don't bother with fpregs_[gs]et()Al Viro
similar to previous commit... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26[ia64] access_uarea(): stop bothering with gpregs_[gs]et()Al Viro
We know this won't be called for child == current, so we don't need to bother with callbacks, etc. - just do unw_init_from_blocked_task(), unw_unwind_to_user() and do the payload of gpregs_[gs]et(). For one register. Which is to say, access_elf_reg(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26[ia64] regularize do_gpregs_[gs]et()Al Viro
now access_elf_reg() does the right thing for everything other than r0, we can simplify do_grepgs_[gs]et() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26[ia64] teach elf_access_reg() to handle the missing range (r16..r31)Al Viro
Now it's easy to make elf_access_gpreg() handle the rest of global registers (r16..r31). That gets rid of the hole in the registers elf_access_reg() can handle, which will allow to simplify its callers later in the series. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26[ia64] sanitize elf_access_gpreg()Al Viro
The function takes the register number, finds the corresponding field of pt_regs for registers that are saved there or does the unwind for the registers that end up spilled on the kernel stack. Then it reads from or writes to the resulting location. Unfortunately, finding the required pt_regs field is done by rather horrible switch. It's microoptimized in all the wrong places - it even uses the knowledge that fields for r8..r11 follow each other in pt_regs layout, while r12..r13 are not adjacent to those, etc. All of that is to encode the mapping from register numbers to offsets + the information that r4..r7 are not to be found in pt_regs. It's deeply in nasal demon territory, at that - the games it plays with pointer arithmetics on addresses of structure members are undefined behaviour. Valid C ends up with better code in this case: just initialize a constant array with offsets of relevant pt_regs fields and we don't need that switch anymore. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-26x86: kill dump_fpu()Al Viro
dead since the removal of aout coredump support... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>