lkml.org 
[lkml]   [2020]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 06/13] powerpc/ptrace: split out ALTIVEC related functions.
    Date
    Move CONFIG_ALTIVEC functions out of ptrace.c, into
    ptrace-altivec.c

    Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
    ---
    v4: add missing ptrace_decl.h
    v5: that's ptrace-decl.h in fact
    ---
    arch/powerpc/kernel/ptrace/Makefile | 1 +
    arch/powerpc/kernel/ptrace/ptrace-altivec.c | 128 ++++++++++++++++++++
    arch/powerpc/kernel/ptrace/ptrace-decl.h | 9 ++
    arch/powerpc/kernel/ptrace/ptrace.c | 124 -------------------
    4 files changed, 138 insertions(+), 124 deletions(-)
    create mode 100644 arch/powerpc/kernel/ptrace/ptrace-altivec.c

    diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile
    index 238c27189078..522e6fd0b5b8 100644
    --- a/arch/powerpc/kernel/ptrace/Makefile
    +++ b/arch/powerpc/kernel/ptrace/Makefile
    @@ -11,3 +11,4 @@ obj-$(CONFIG_VSX) += ptrace-vsx.o
    ifneq ($(CONFIG_VSX),y)
    obj-y += ptrace-novsx.o
    endif
    +obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
    diff --git a/arch/powerpc/kernel/ptrace/ptrace-altivec.c b/arch/powerpc/kernel/ptrace/ptrace-altivec.c
    new file mode 100644
    index 000000000000..dd8b75dfbd06
    --- /dev/null
    +++ b/arch/powerpc/kernel/ptrace/ptrace-altivec.c
    @@ -0,0 +1,128 @@
    +// SPDX-License-Identifier: GPL-2.0-or-later
    +
    +#include <linux/regset.h>
    +#include <linux/elf.h>
    +
    +#include <asm/switch_to.h>
    +
    +#include "ptrace-decl.h"
    +
    +/*
    + * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
    + * The transfer totals 34 quadword. Quadwords 0-31 contain the
    + * corresponding vector registers. Quadword 32 contains the vscr as the
    + * last word (offset 12) within that quadword. Quadword 33 contains the
    + * vrsave as the first word (offset 0) within the quadword.
    + *
    + * This definition of the VMX state is compatible with the current PPC32
    + * ptrace interface. This allows signal handling and ptrace to use the
    + * same structures. This also simplifies the implementation of a bi-arch
    + * (combined (32- and 64-bit) gdb.
    + */
    +
    +int vr_active(struct task_struct *target, const struct user_regset *regset)
    +{
    + flush_altivec_to_thread(target);
    + return target->thread.used_vr ? regset->n : 0;
    +}
    +
    +/*
    + * Regardless of transactions, 'vr_state' holds the current running
    + * value of all the VMX registers and 'ckvr_state' holds the last
    + * checkpointed value of all the VMX registers for the current
    + * transaction to fall back on in case it aborts.
    + *
    + * Userspace interface buffer layout:
    + *
    + * struct data {
    + * vector128 vr[32];
    + * vector128 vscr;
    + * vector128 vrsave;
    + * };
    + */
    +int vr_get(struct task_struct *target, const struct user_regset *regset,
    + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
    +{
    + int ret;
    +
    + flush_altivec_to_thread(target);
    +
    + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
    + offsetof(struct thread_vr_state, vr[32]));
    +
    + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
    + &target->thread.vr_state, 0,
    + 33 * sizeof(vector128));
    + if (!ret) {
    + /*
    + * Copy out only the low-order word of vrsave.
    + */
    + int start, end;
    + union {
    + elf_vrreg_t reg;
    + u32 word;
    + } vrsave;
    + memset(&vrsave, 0, sizeof(vrsave));
    +
    + vrsave.word = target->thread.vrsave;
    +
    + start = 33 * sizeof(vector128);
    + end = start + sizeof(vrsave);
    + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
    + start, end);
    + }
    +
    + return ret;
    +}
    +
    +/*
    + * Regardless of transactions, 'vr_state' holds the current running
    + * value of all the VMX registers and 'ckvr_state' holds the last
    + * checkpointed value of all the VMX registers for the current
    + * transaction to fall back on in case it aborts.
    + *
    + * Userspace interface buffer layout:
    + *
    + * struct data {
    + * vector128 vr[32];
    + * vector128 vscr;
    + * vector128 vrsave;
    + * };
    + */
    +int vr_set(struct task_struct *target, const struct user_regset *regset,
    + unsigned int pos, unsigned int count,
    + const void *kbuf, const void __user *ubuf)
    +{
    + int ret;
    +
    + flush_altivec_to_thread(target);
    +
    + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
    + offsetof(struct thread_vr_state, vr[32]));
    +
    + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
    + &target->thread.vr_state, 0,
    + 33 * sizeof(vector128));
    + if (!ret && count > 0) {
    + /*
    + * We use only the first word of vrsave.
    + */
    + int start, end;
    + union {
    + elf_vrreg_t reg;
    + u32 word;
    + } vrsave;
    + memset(&vrsave, 0, sizeof(vrsave));
    +
    + vrsave.word = target->thread.vrsave;
    +
    + start = 33 * sizeof(vector128);
    + end = start + sizeof(vrsave);
    + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
    + start, end);
    + if (!ret)
    + target->thread.vrsave = vrsave.word;
    + }
    +
    + return ret;
    +}
    diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
    index 764df4ee9362..0f9282cb52fc 100644
    --- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
    +++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
    @@ -17,6 +17,15 @@ int vsr_set(struct task_struct *target, const struct user_regset *regset,
    unsigned int pos, unsigned int count,
    const void *kbuf, const void __user *ubuf);

    +/* ptrace-altivec */
    +
    +int vr_active(struct task_struct *target, const struct user_regset *regset);
    +int vr_get(struct task_struct *target, const struct user_regset *regset,
    + unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
    +int vr_set(struct task_struct *target, const struct user_regset *regset,
    + unsigned int pos, unsigned int count,
    + const void *kbuf, const void __user *ubuf);
    +
    /* ptrace */

    #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
    diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
    index ead33b74e1f3..c383325db4a6 100644
    --- a/arch/powerpc/kernel/ptrace/ptrace.c
    +++ b/arch/powerpc/kernel/ptrace/ptrace.c
    @@ -403,130 +403,6 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
    return ret;
    }

    -#ifdef CONFIG_ALTIVEC
    -/*
    - * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
    - * The transfer totals 34 quadword. Quadwords 0-31 contain the
    - * corresponding vector registers. Quadword 32 contains the vscr as the
    - * last word (offset 12) within that quadword. Quadword 33 contains the
    - * vrsave as the first word (offset 0) within the quadword.
    - *
    - * This definition of the VMX state is compatible with the current PPC32
    - * ptrace interface. This allows signal handling and ptrace to use the
    - * same structures. This also simplifies the implementation of a bi-arch
    - * (combined (32- and 64-bit) gdb.
    - */
    -
    -static int vr_active(struct task_struct *target,
    - const struct user_regset *regset)
    -{
    - flush_altivec_to_thread(target);
    - return target->thread.used_vr ? regset->n : 0;
    -}
    -
    -/*
    - * Regardless of transactions, 'vr_state' holds the current running
    - * value of all the VMX registers and 'ckvr_state' holds the last
    - * checkpointed value of all the VMX registers for the current
    - * transaction to fall back on in case it aborts.
    - *
    - * Userspace interface buffer layout:
    - *
    - * struct data {
    - * vector128 vr[32];
    - * vector128 vscr;
    - * vector128 vrsave;
    - * };
    - */
    -static int vr_get(struct task_struct *target, const struct user_regset *regset,
    - unsigned int pos, unsigned int count,
    - void *kbuf, void __user *ubuf)
    -{
    - int ret;
    -
    - flush_altivec_to_thread(target);
    -
    - BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
    - offsetof(struct thread_vr_state, vr[32]));
    -
    - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
    - &target->thread.vr_state, 0,
    - 33 * sizeof(vector128));
    - if (!ret) {
    - /*
    - * Copy out only the low-order word of vrsave.
    - */
    - int start, end;
    - union {
    - elf_vrreg_t reg;
    - u32 word;
    - } vrsave;
    - memset(&vrsave, 0, sizeof(vrsave));
    -
    - vrsave.word = target->thread.vrsave;
    -
    - start = 33 * sizeof(vector128);
    - end = start + sizeof(vrsave);
    - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
    - start, end);
    - }
    -
    - return ret;
    -}
    -
    -/*
    - * Regardless of transactions, 'vr_state' holds the current running
    - * value of all the VMX registers and 'ckvr_state' holds the last
    - * checkpointed value of all the VMX registers for the current
    - * transaction to fall back on in case it aborts.
    - *
    - * Userspace interface buffer layout:
    - *
    - * struct data {
    - * vector128 vr[32];
    - * vector128 vscr;
    - * vector128 vrsave;
    - * };
    - */
    -static int vr_set(struct task_struct *target, const struct user_regset *regset,
    - unsigned int pos, unsigned int count,
    - const void *kbuf, const void __user *ubuf)
    -{
    - int ret;
    -
    - flush_altivec_to_thread(target);
    -
    - BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
    - offsetof(struct thread_vr_state, vr[32]));
    -
    - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
    - &target->thread.vr_state, 0,
    - 33 * sizeof(vector128));
    - if (!ret && count > 0) {
    - /*
    - * We use only the first word of vrsave.
    - */
    - int start, end;
    - union {
    - elf_vrreg_t reg;
    - u32 word;
    - } vrsave;
    - memset(&vrsave, 0, sizeof(vrsave));
    -
    - vrsave.word = target->thread.vrsave;
    -
    - start = 33 * sizeof(vector128);
    - end = start + sizeof(vrsave);
    - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
    - start, end);
    - if (!ret)
    - target->thread.vrsave = vrsave.word;
    - }
    -
    - return ret;
    -}
    -#endif /* CONFIG_ALTIVEC */
    -
    #ifdef CONFIG_SPE

    /*
    --
    2.25.0
    \
     
     \ /
      Last update: 2020-02-28 01:19    [W:2.983 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site