All of lore.kernel.org
 help / color / mirror / Atom feed
From: Charlie Jenkins <charlie@rivosinc.com>
To: Andy Chiu <andybnac@gmail.com>
Cc: Yong-Xuan Wang <yongxuan.wang@sifive.com>,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	greentime.hu@sifive.com, vincent.chen@sifive.com,
	Shuah Khan <shuah@kernel.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>,
	linux-kselftest@vger.kernel.org
Subject: Re: [PATCH v 2/2] selftests: riscv: Add test for the Vector ptrace interface
Date: Wed, 1 Oct 2025 22:59:07 -0700	[thread overview]
Message-ID: <aN4UqyjyW-CFH5PE@ghost> (raw)
In-Reply-To: <CAFTtA3MB0Oxe5Wy_Bq-uhijz2h6o0ZWezvoJPiXdjEmcGd6S4A@mail.gmail.com>

On Thu, Oct 02, 2025 at 12:53:13AM -0500, Andy Chiu wrote:
> Hi Yong-Xuan,
> 
> I found some issues which deserve a re-roll:
> 
> On Wed, Oct 1, 2025 at 6:15 AM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
> >
> > Add a test case that does some basic verification of the Vector ptrace
> > interface. This forks a child process then using ptrace to inspect and
> > manipulate the v31 register of the child.
> >
> > Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
> > ---
> >  tools/testing/selftests/riscv/vector/Makefile |   5 +-
> >  .../selftests/riscv/vector/vstate_ptrace.c    | 132 ++++++++++++++++++
> >  2 files changed, 136 insertions(+), 1 deletion(-)
> >  create mode 100644 tools/testing/selftests/riscv/vector/vstate_ptrace.c
> >
> > diff --git a/tools/testing/selftests/riscv/vector/Makefile b/tools/testing/selftests/riscv/vector/Makefile
> > index 6f7497f4e7b3..45f25e9dd264 100644
> > --- a/tools/testing/selftests/riscv/vector/Makefile
> > +++ b/tools/testing/selftests/riscv/vector/Makefile
> > @@ -2,7 +2,7 @@
> >  # Copyright (C) 2021 ARM Limited
> >  # Originally tools/testing/arm64/abi/Makefile
> >
> > -TEST_GEN_PROGS := v_initval vstate_prctl
> > +TEST_GEN_PROGS := v_initval vstate_prctl vsate_ptrace
> 
> Please s/vsate_ptrace/vstate_ptrace
> 
> Otherwise we will not get the program compiled
> 
> >  TEST_GEN_PROGS_EXTENDED := vstate_exec_nolibc v_exec_initval_nolibc
> >
> >  include ../../lib.mk
> > @@ -26,3 +26,6 @@ $(OUTPUT)/v_initval: v_initval.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpers.o
> >  $(OUTPUT)/v_exec_initval_nolibc: v_exec_initval_nolibc.c
> >         $(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \
> >                 -Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc
> > +
> > +$(OUTPUT)/vstate_ptrace: vstate_ptrace.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpers.o
> > +       $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
> > diff --git a/tools/testing/selftests/riscv/vector/vstate_ptrace.c b/tools/testing/selftests/riscv/vector/vstate_ptrace.c
> > new file mode 100644
> > index 000000000000..8a7bcf318e59
> > --- /dev/null
> > +++ b/tools/testing/selftests/riscv/vector/vstate_ptrace.c
> > @@ -0,0 +1,132 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <asm/ptrace.h>
> > +#include <linux/elf.h>
> > +#include <sys/ptrace.h>
> > +#include <sys/uio.h>
> > +#include <sys/wait.h>
> > +#include "../../kselftest.h"
> > +#include "v_helpers.h"
> > +
> > +int parent_set_val, child_set_val;
> > +
> > +static long do_ptrace(enum __ptrace_request op, pid_t pid, long type, size_t size, void *data)
> > +{
> > +       struct iovec v_iovec = {
> > +               .iov_len = size,
> > +               .iov_base = data
> > +       };
> > +
> > +       return ptrace(op, pid, type, &v_iovec);
> > +}
> > +
> > +static int do_child(void)
> > +{
> > +       int out;
> > +
> > +       if (ptrace(PTRACE_TRACEME, -1, NULL, NULL)) {
> > +               ksft_perror("PTRACE_TRACEME failed\n");
> > +               return EXIT_FAILURE;
> > +       }
> > +
> > +       asm volatile (".option push\n\t"
> > +               ".option        arch, +v\n\t"
> 
> As mentioned before, please use ".option arch, +v,-c\n\t" or ".option
> norvc\n\t" and +=4 when advancing the pc

arch -c should be avoided, there are cases when it does not always avoid
using all compressed instructions. norvc should always do the right
thing though. There is discussion at [1] about deprecating it (along with
all variants of -ext).

[1] https://inbox.sourceware.org/binutils/7ecdc846-0822-4666-957f-ff818786fb44@iscas.ac.cn/T/#t

- Charlie

> 
> > +               "vsetivli       x0, 1, e32, m1, ta, ma\n\t"
> > +               "vmv.s.x        v31, %[in]\n\t"
> > +               "ebreak\n\t"
> > +               "vmv.x.s        %[out], v31\n\t"
> > +               ".option pop\n\t"
> > +               : [out] "=r" (out)
> > +               : [in] "r" (child_set_val));
> > +
> > +       if (out != parent_set_val)
> > +               return EXIT_FAILURE;
> > +
> > +       return EXIT_SUCCESS;
> > +}
> > +
> > +static void do_parent(pid_t child)
> > +{
> > +       int status;
> > +       void *data = NULL;
> > +
> > +       /* Attach to the child */
> > +       while (waitpid(child, &status, 0)) {
> > +               if (WIFEXITED(status)) {
> > +                       ksft_test_result(WEXITSTATUS(status) == 0, "SETREGSET vector\n");
> > +                       goto out;
> > +               } else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) {
> > +                       size_t size, t;
> 
> unused variable t
> 
> > +                       void *data, *v31;
> > +                       struct __riscv_v_regset_state *v_regset_hdr;
> > +                       struct user_regs_struct *gpreg;
> > +
> > +                       size = sizeof(*v_regset_hdr);
> > +                       data = malloc(size);
> > +                       if (!data)
> > +                               goto out;
> > +                       v_regset_hdr = (struct __riscv_v_regset_state *)data;
> > +
> > +                       if (do_ptrace(PTRACE_GETREGSET, child, NT_RISCV_VECTOR, size, data))
> > +                               goto out;
> > +
> > +                       ksft_print_msg("vlenb %ld\n", v_regset_hdr->vlenb);
> > +                       data = realloc(data, size + v_regset_hdr->vlenb * 32);
> 
> realloc may give a new pointer so v_regset_hdr has to be updated here
> before the next use
> 
> > +                       if (!data)
> > +                               goto out;
> > +                       v31 = (void *)(data + size + v_regset_hdr->vlenb * 31);
> > +                       size += v_regset_hdr->vlenb * 32;
> > +
> > +                       if (do_ptrace(PTRACE_GETREGSET, child, NT_RISCV_VECTOR, size, data))
> > +                               goto out;
> > +
> > +                       ksft_test_result(*(int *)v31 == child_set_val, "GETREGSET vector\n");
> > +
> > +                       *(int *)v31 = parent_set_val;
> > +                       if (do_ptrace(PTRACE_SETREGSET, child, NT_RISCV_VECTOR, size, data))
> > +                               goto out;
> > +
> > +                       /* move the pc forward */
> > +                       size = sizeof(*gpreg);
> > +                       data = realloc(data, size);
> > +                       gpreg = (struct user_regs_struct *)data;
> > +
> > +                       if (do_ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, size, data))
> > +                               goto out;
> > +
> > +                       gpreg->pc += 2;
> > +                       if (do_ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, size, data))
> > +                               goto out;
> > +               }
> > +
> > +               ptrace(PTRACE_CONT, child, NULL, NULL);
> > +       }
> > +
> > +out:
> > +       free(data);
> > +}
> > +
> > +int main(void)
> > +{
> > +       pid_t child;
> > +
> > +       ksft_set_plan(2);
> > +       if (!is_vector_supported() && !is_xtheadvector_supported())
> > +               ksft_exit_skip("Vector not supported\n");
> > +
> > +       srandom(getpid());
> > +       parent_set_val = rand();
> > +       child_set_val = rand();
> > +
> > +       child = fork();
> > +       if (child < 0)
> > +               ksft_exit_fail_msg("Fork failed %d\n", child);
> > +
> > +       if (!child)
> > +               return do_child();
> > +
> > +       do_parent(child);
> > +
> > +       ksft_finished();
> > +}
> > --
> > 2.43.0
> >
> 
> Thanks,
> Andy

WARNING: multiple messages have this Message-ID (diff)
From: Charlie Jenkins <charlie@rivosinc.com>
To: Andy Chiu <andybnac@gmail.com>
Cc: Yong-Xuan Wang <yongxuan.wang@sifive.com>,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	greentime.hu@sifive.com, vincent.chen@sifive.com,
	Shuah Khan <shuah@kernel.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>,
	linux-kselftest@vger.kernel.org
Subject: Re: [PATCH v 2/2] selftests: riscv: Add test for the Vector ptrace interface
Date: Wed, 1 Oct 2025 22:59:07 -0700	[thread overview]
Message-ID: <aN4UqyjyW-CFH5PE@ghost> (raw)
In-Reply-To: <CAFTtA3MB0Oxe5Wy_Bq-uhijz2h6o0ZWezvoJPiXdjEmcGd6S4A@mail.gmail.com>

On Thu, Oct 02, 2025 at 12:53:13AM -0500, Andy Chiu wrote:
> Hi Yong-Xuan,
> 
> I found some issues which deserve a re-roll:
> 
> On Wed, Oct 1, 2025 at 6:15 AM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
> >
> > Add a test case that does some basic verification of the Vector ptrace
> > interface. This forks a child process then using ptrace to inspect and
> > manipulate the v31 register of the child.
> >
> > Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
> > ---
> >  tools/testing/selftests/riscv/vector/Makefile |   5 +-
> >  .../selftests/riscv/vector/vstate_ptrace.c    | 132 ++++++++++++++++++
> >  2 files changed, 136 insertions(+), 1 deletion(-)
> >  create mode 100644 tools/testing/selftests/riscv/vector/vstate_ptrace.c
> >
> > diff --git a/tools/testing/selftests/riscv/vector/Makefile b/tools/testing/selftests/riscv/vector/Makefile
> > index 6f7497f4e7b3..45f25e9dd264 100644
> > --- a/tools/testing/selftests/riscv/vector/Makefile
> > +++ b/tools/testing/selftests/riscv/vector/Makefile
> > @@ -2,7 +2,7 @@
> >  # Copyright (C) 2021 ARM Limited
> >  # Originally tools/testing/arm64/abi/Makefile
> >
> > -TEST_GEN_PROGS := v_initval vstate_prctl
> > +TEST_GEN_PROGS := v_initval vstate_prctl vsate_ptrace
> 
> Please s/vsate_ptrace/vstate_ptrace
> 
> Otherwise we will not get the program compiled
> 
> >  TEST_GEN_PROGS_EXTENDED := vstate_exec_nolibc v_exec_initval_nolibc
> >
> >  include ../../lib.mk
> > @@ -26,3 +26,6 @@ $(OUTPUT)/v_initval: v_initval.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpers.o
> >  $(OUTPUT)/v_exec_initval_nolibc: v_exec_initval_nolibc.c
> >         $(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \
> >                 -Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc
> > +
> > +$(OUTPUT)/vstate_ptrace: vstate_ptrace.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpers.o
> > +       $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
> > diff --git a/tools/testing/selftests/riscv/vector/vstate_ptrace.c b/tools/testing/selftests/riscv/vector/vstate_ptrace.c
> > new file mode 100644
> > index 000000000000..8a7bcf318e59
> > --- /dev/null
> > +++ b/tools/testing/selftests/riscv/vector/vstate_ptrace.c
> > @@ -0,0 +1,132 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <asm/ptrace.h>
> > +#include <linux/elf.h>
> > +#include <sys/ptrace.h>
> > +#include <sys/uio.h>
> > +#include <sys/wait.h>
> > +#include "../../kselftest.h"
> > +#include "v_helpers.h"
> > +
> > +int parent_set_val, child_set_val;
> > +
> > +static long do_ptrace(enum __ptrace_request op, pid_t pid, long type, size_t size, void *data)
> > +{
> > +       struct iovec v_iovec = {
> > +               .iov_len = size,
> > +               .iov_base = data
> > +       };
> > +
> > +       return ptrace(op, pid, type, &v_iovec);
> > +}
> > +
> > +static int do_child(void)
> > +{
> > +       int out;
> > +
> > +       if (ptrace(PTRACE_TRACEME, -1, NULL, NULL)) {
> > +               ksft_perror("PTRACE_TRACEME failed\n");
> > +               return EXIT_FAILURE;
> > +       }
> > +
> > +       asm volatile (".option push\n\t"
> > +               ".option        arch, +v\n\t"
> 
> As mentioned before, please use ".option arch, +v,-c\n\t" or ".option
> norvc\n\t" and +=4 when advancing the pc

arch -c should be avoided, there are cases when it does not always avoid
using all compressed instructions. norvc should always do the right
thing though. There is discussion at [1] about deprecating it (along with
all variants of -ext).

[1] https://inbox.sourceware.org/binutils/7ecdc846-0822-4666-957f-ff818786fb44@iscas.ac.cn/T/#t

- Charlie

> 
> > +               "vsetivli       x0, 1, e32, m1, ta, ma\n\t"
> > +               "vmv.s.x        v31, %[in]\n\t"
> > +               "ebreak\n\t"
> > +               "vmv.x.s        %[out], v31\n\t"
> > +               ".option pop\n\t"
> > +               : [out] "=r" (out)
> > +               : [in] "r" (child_set_val));
> > +
> > +       if (out != parent_set_val)
> > +               return EXIT_FAILURE;
> > +
> > +       return EXIT_SUCCESS;
> > +}
> > +
> > +static void do_parent(pid_t child)
> > +{
> > +       int status;
> > +       void *data = NULL;
> > +
> > +       /* Attach to the child */
> > +       while (waitpid(child, &status, 0)) {
> > +               if (WIFEXITED(status)) {
> > +                       ksft_test_result(WEXITSTATUS(status) == 0, "SETREGSET vector\n");
> > +                       goto out;
> > +               } else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) {
> > +                       size_t size, t;
> 
> unused variable t
> 
> > +                       void *data, *v31;
> > +                       struct __riscv_v_regset_state *v_regset_hdr;
> > +                       struct user_regs_struct *gpreg;
> > +
> > +                       size = sizeof(*v_regset_hdr);
> > +                       data = malloc(size);
> > +                       if (!data)
> > +                               goto out;
> > +                       v_regset_hdr = (struct __riscv_v_regset_state *)data;
> > +
> > +                       if (do_ptrace(PTRACE_GETREGSET, child, NT_RISCV_VECTOR, size, data))
> > +                               goto out;
> > +
> > +                       ksft_print_msg("vlenb %ld\n", v_regset_hdr->vlenb);
> > +                       data = realloc(data, size + v_regset_hdr->vlenb * 32);
> 
> realloc may give a new pointer so v_regset_hdr has to be updated here
> before the next use
> 
> > +                       if (!data)
> > +                               goto out;
> > +                       v31 = (void *)(data + size + v_regset_hdr->vlenb * 31);
> > +                       size += v_regset_hdr->vlenb * 32;
> > +
> > +                       if (do_ptrace(PTRACE_GETREGSET, child, NT_RISCV_VECTOR, size, data))
> > +                               goto out;
> > +
> > +                       ksft_test_result(*(int *)v31 == child_set_val, "GETREGSET vector\n");
> > +
> > +                       *(int *)v31 = parent_set_val;
> > +                       if (do_ptrace(PTRACE_SETREGSET, child, NT_RISCV_VECTOR, size, data))
> > +                               goto out;
> > +
> > +                       /* move the pc forward */
> > +                       size = sizeof(*gpreg);
> > +                       data = realloc(data, size);
> > +                       gpreg = (struct user_regs_struct *)data;
> > +
> > +                       if (do_ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, size, data))
> > +                               goto out;
> > +
> > +                       gpreg->pc += 2;
> > +                       if (do_ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, size, data))
> > +                               goto out;
> > +               }
> > +
> > +               ptrace(PTRACE_CONT, child, NULL, NULL);
> > +       }
> > +
> > +out:
> > +       free(data);
> > +}
> > +
> > +int main(void)
> > +{
> > +       pid_t child;
> > +
> > +       ksft_set_plan(2);
> > +       if (!is_vector_supported() && !is_xtheadvector_supported())
> > +               ksft_exit_skip("Vector not supported\n");
> > +
> > +       srandom(getpid());
> > +       parent_set_val = rand();
> > +       child_set_val = rand();
> > +
> > +       child = fork();
> > +       if (child < 0)
> > +               ksft_exit_fail_msg("Fork failed %d\n", child);
> > +
> > +       if (!child)
> > +               return do_child();
> > +
> > +       do_parent(child);
> > +
> > +       ksft_finished();
> > +}
> > --
> > 2.43.0
> >
> 
> Thanks,
> Andy

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2025-10-02  5:59 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-01 11:14 [PATCH v 0/2] Optimize the allocation of vector regset Yong-Xuan Wang
2025-10-01 11:14 ` Yong-Xuan Wang
2025-10-01 11:14 ` [PATCH v 1/2] riscv: ptrace: " Yong-Xuan Wang
2025-10-01 11:14   ` Yong-Xuan Wang
2025-10-01 14:50   ` Andy Chiu
2025-10-01 14:50     ` Andy Chiu
2025-10-01 11:14 ` [PATCH v 2/2] selftests: riscv: Add test for the Vector ptrace interface Yong-Xuan Wang
2025-10-01 11:14   ` Yong-Xuan Wang
2025-10-01 15:12   ` Andy Chiu
2025-10-01 15:12     ` Andy Chiu
2025-10-02  5:53   ` Andy Chiu
2025-10-02  5:53     ` Andy Chiu
2025-10-02  5:59     ` Charlie Jenkins [this message]
2025-10-02  5:59       ` Charlie Jenkins

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aN4UqyjyW-CFH5PE@ghost \
    --to=charlie@rivosinc.com \
    --cc=alex@ghiti.fr \
    --cc=andybnac@gmail.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=greentime.hu@sifive.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    --cc=shuah@kernel.org \
    --cc=vincent.chen@sifive.com \
    --cc=yongxuan.wang@sifive.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.