cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ptrace-altivec.c (3120B)


      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}