File Index
Files and directories
Sign in
FILE

ptrace-altivec.c

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/kernel/ptrace/ptrace-altivec.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2
  3#include <linux/regset.h>
  4#include <linux/elf.h>
  5
  6#include <asm/switch_to.h>
  7
  8#include "ptrace-decl.h"
  9
 10/*
 11 * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
 12 * The transfer totals 34 quadword.  Quadwords 0-31 contain the
 13 * corresponding vector registers.  Quadword 32 contains the vscr as the
 14 * last word (offset 12) within that quadword.  Quadword 33 contains the
 15 * vrsave as the first word (offset 0) within the quadword.
 16 *
 17 * This definition of the VMX state is compatible with the current PPC32
 18 * ptrace interface.  This allows signal handling and ptrace to use the
 19 * same structures.  This also simplifies the implementation of a bi-arch
 20 * (combined (32- and 64-bit) gdb.
 21 */
 22
 23int vr_active(struct task_struct *target, const struct user_regset *regset)
 24{
 25	flush_altivec_to_thread(target);
 26	return target->thread.used_vr ? regset->n : 0;
 27}
 28
 29/*
 30 * Regardless of transactions, 'vr_state' holds the current running
 31 * value of all the VMX registers and 'ckvr_state' holds the last
 32 * checkpointed value of all the VMX registers for the current
 33 * transaction to fall back on in case it aborts.
 34 *
 35 * Userspace interface buffer layout:
 36 *
 37 * struct data {
 38 *	vector128	vr[32];
 39 *	vector128	vscr;
 40 *	vector128	vrsave;
 41 * };
 42 */
 43int vr_get(struct task_struct *target, const struct user_regset *regset,
 44	   struct membuf to)
 45{
 46	union {
 47		elf_vrreg_t reg;
 48		u32 word;
 49	} vrsave;
 50
 51	flush_altivec_to_thread(target);
 52
 53	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
 54		     offsetof(struct thread_vr_state, vr[32]));
 55
 56	membuf_write(&to, &target->thread.vr_state, 33 * sizeof(vector128));
 57	/*
 58	 * Copy out only the low-order word of vrsave.
 59	 */
 60	memset(&vrsave, 0, sizeof(vrsave));
 61	vrsave.word = target->thread.vrsave;
 62	return membuf_write(&to, &vrsave, sizeof(vrsave));
 63}
 64
 65/*
 66 * Regardless of transactions, 'vr_state' holds the current running
 67 * value of all the VMX registers and 'ckvr_state' holds the last
 68 * checkpointed value of all the VMX registers for the current
 69 * transaction to fall back on in case it aborts.
 70 *
 71 * Userspace interface buffer layout:
 72 *
 73 * struct data {
 74 *	vector128	vr[32];
 75 *	vector128	vscr;
 76 *	vector128	vrsave;
 77 * };
 78 */
 79int vr_set(struct task_struct *target, const struct user_regset *regset,
 80	   unsigned int pos, unsigned int count,
 81	   const void *kbuf, const void __user *ubuf)
 82{
 83	int ret;
 84
 85	flush_altivec_to_thread(target);
 86
 87	BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
 88		     offsetof(struct thread_vr_state, vr[32]));
 89
 90	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 91				 &target->thread.vr_state, 0,
 92				 33 * sizeof(vector128));
 93	if (!ret && count > 0) {
 94		/*
 95		 * We use only the first word of vrsave.
 96		 */
 97		int start, end;
 98		union {
 99			elf_vrreg_t reg;
100			u32 word;
101		} vrsave;
102		memset(&vrsave, 0, sizeof(vrsave));
103
104		vrsave.word = target->thread.vrsave;
105
106		start = 33 * sizeof(vector128);
107		end = start + sizeof(vrsave);
108		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
109					 start, end);
110		if (!ret)
111			target->thread.vrsave = vrsave.word;
112	}
113
114	return ret;
115}
~/ Read-only file preview.