From nobody Tue Dec 16 14:50:01 2025 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 98C6C2DFF19 for ; Sun, 14 Dec 2025 16:36:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765730167; cv=none; b=cJvQiUbJVsRFI1MBfOlCDNdAec0HTSQEsbIAZg7eRM7NJ4ByAu6nKMl8ISRFiv4Duv3s8ECHwId9+VraYj0BPzMuan2fld9o838WGim+n3ebeFurhHaXv4psVDc5XU7G1LoT/AmtPafFyk9KNPzvNNSE+LW0YTPwoI61GcPDdaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765730167; c=relaxed/simple; bh=Gydlh+iup8jO/aNYR3QKidyq5TZb43ybY4tjHG68HtI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gNHh+tHeVuWPUZmAH9Gey4Mto75EYWC8Hnfc0XG+7TVOq+l9YTnMw7gr0tf62N4ZlkaUOH2HVs8BlEYz1bdcCKo/iHYMsdoVeH2ftJmcvUvT2u0Aw19nfvN/2C4RYFbosLGU89+tz0QDGcWgm/PVWrhsTJtatsIvF5I21jojJHs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=R6szi1Mj; arc=none smtp.client-ip=209.85.167.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="R6szi1Mj" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-5943d20f352so3340181e87.0 for ; Sun, 14 Dec 2025 08:36:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765730162; x=1766334962; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aH0zKZXb/Y5gUEGiokm3nZsvrljXzf5GckdYzZU3nLY=; b=R6szi1MjV1OHBCFh+l3noe1dFrVD+/r0+d80RXsLZsTdRqRDIXFSYsXUVt15UAfpCm jze/coo3wuviDGa4R9FNQIYF5jpn0a7BdpHC0h2Yp1MjQYWzzVtSjYyd+jrphklGvkIY tzzAyUh8PhjF4t4Oyq+HIss12WJWXdMC04m2sq+n7b5DzTarYGQTUNSXX/I6ffRlNTIT TqxAFCJYNMv+CUuTNZnVgy0R+THvW+2ZnOmPWrjfZVXPzxM6j6GwNAEe+6A7H0GCqwqA vDr8d1ZLNGx4mGsBkV9cnLg+DqfSmwru0MVzf20lK3Gt0FpotFAN6rHkkzUEmnlGzMpe Vzbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765730162; x=1766334962; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=aH0zKZXb/Y5gUEGiokm3nZsvrljXzf5GckdYzZU3nLY=; b=mRJrWkHp5NuD4bEz0itIRbv8jz7dbu4G5DWRcc+5wyWkDHYtmtzsbCBRRqI0+WKhgd ffQ1lw8iapCJ8uIDAQdQSMD7dFN9aLCE7gX/xk4yPRXjdJo88wIo38ykyAhSZ335X4A+ JiVNRhu1WVD+F7U2CjHtsXe62FxfNQpOiwDU1NKuqUaMafxV/V4OfrHhm/bSwPoQtBnh ny4NtxhjLR+1hXLoUtFWUZDs18ROcQm4LYt835GVxmecpHg/G8yGppPj0BaZPGvU2g+j E37Yd23/5rl5+HxyFxAiS1POScJ3D8StMA3Ny9wYkmkbDfZJeRpoBysvg2EYxwgIbZqS eKuQ== X-Forwarded-Encrypted: i=1; AJvYcCUEYrij6eZ3f4r1t0jIsymuM2pF8Qdmk+QGAD2Rk/KeSYIrxJkN+Oiag0NMC0i2/NrTu0ZHuyB6crvhLME=@vger.kernel.org X-Gm-Message-State: AOJu0YycXPORkhL+mrS1HhcPsHGlt2oprbmM+sY3PJYqZL22foIrno1H mlMLu+z58+3hbZHSmwVJKhV7pHqxHd+EofUbNRokpTqyy/m7FW2A+xJ+ X-Gm-Gg: AY/fxX5FJKsMOmfLK8JV3P6nNyyhUWVLqEypPWlb11EY7On0iVEeJThpaVvSAEiXZ5I 5tLC4DGme6QtaIQhRw7zETx3CI76qi3PckeO7hOcN4uJqpCyy5ExLE7yxVGvT95R/BkFByOwjWH hJVxkTxO0N728K/yvO8jSmnxQAThHL3bXZGBOzAObnG+vbh7WNlKNpJP2ib9QJuICeYl223ym/+ sJcQ03cJWbKIvt1PCXNw6wZkK1E0CgfytnOfrBPF9tTeVWssGLsVbmo12fFdkxu36wWdDrDcNqR fvf4dkjUQPky2FcR6NAjtD0V/aCcSaCumffYoS2vEb7qSPzczzdjnEOCUe4xfmpRp7EeDb/LCn1 il9SjaAKM4e3NjwDXk5HZf9dG2K9i4PfWLN6sdDeHbgy2T3taQHmZcmNwhktzvf9lpTufZVeQ8V 6tVa/EvmMNLLTl X-Google-Smtp-Source: AGHT+IGg2O6UbEA1J9//+XT5+Hs1atMO2Qc+sN+YnLd8rt1bcW3PK1V2c1Ri3kEauyeryHCL6gCzRg== X-Received: by 2002:a05:6512:3d05:b0:597:d5dc:b3e0 with SMTP id 2adb3069b0e04-598faa223bfmr2694122e87.10.1765730161456; Sun, 14 Dec 2025 08:36:01 -0800 (PST) Received: from curiosity ([5.188.167.4]) by smtp.googlemail.com with ESMTPSA id 2adb3069b0e04-598f7717b79sm3789618e87.60.2025.12.14.08.36.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 14 Dec 2025 08:36:00 -0800 (PST) From: Sergey Matyukevich To: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paul Walmsley , Palmer Dabbelt , Alexandre Ghiti , Oleg Nesterov , Shuah Khan , Thomas Huth , Charlie Jenkins , Andy Chiu , Samuel Holland , Joel Granados , Conor Dooley , Yong-Xuan Wang , Heiko Stuebner , Guo Ren , Sergey Matyukevich Subject: [PATCH v5 9/9] selftests: riscv: verify ptrace accepts valid vector csr values Date: Sun, 14 Dec 2025 19:35:13 +0300 Message-ID: <20251214163537.1054292-10-geomatsi@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251214163537.1054292-1-geomatsi@gmail.com> References: <20251214163537.1054292-1-geomatsi@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a test to v_ptrace test suite to verify that ptrace accepts the valid input combinations of vector csr registers. Use kselftest fixture variants to create multiple inputs for the test. The test simulates a debug scenario with three breakpoints: 0. init: let the tracee set up its initial vector configuration 1. 1st bp: modify the tracee's vector csr registers from the debugger - resume the tracee to execute a block without vector instructions 2. 2nd bp: read back the tracees's vector csr registers from the debugger - compare with values set by the debugger - resume the tracee to execute a block with vector instructions 3. 3rd bp: read back the tracess's vector csr registers again - compare with values set by the debugger The last check helps to confirm that ptrace validation check for vector csr registers input values works properly and maintains an accurate view of the tracee's vector context in debugger. Signed-off-by: Sergey Matyukevich --- .../riscv/vector/validate_v_ptrace.c | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) diff --git a/tools/testing/selftests/riscv/vector/validate_v_ptrace.c b/too= ls/testing/selftests/riscv/vector/validate_v_ptrace.c index 623b13e7582e..c72533a331de 100644 --- a/tools/testing/selftests/riscv/vector/validate_v_ptrace.c +++ b/tools/testing/selftests/riscv/vector/validate_v_ptrace.c @@ -654,4 +654,266 @@ TEST_F(v_csr_invalid, ptrace_v_invalid_values) } } =20 +FIXTURE(v_csr_valid) +{ +}; + +FIXTURE_SETUP(v_csr_valid) +{ +} + +FIXTURE_TEARDOWN(v_csr_valid) +{ +} + +/* modifications of the initial vsetvli settings */ +FIXTURE_VARIANT(v_csr_valid) +{ + unsigned long vstart; + unsigned long vl; + unsigned long vtype; + unsigned long vcsr; + unsigned long vlenb_mul; + unsigned long vlenb_min; + unsigned long vlenb_max; + unsigned long spec; +}; + +/* valid for VLEN >=3D 128: LMUL=3D 1/4, SEW =3D 32 */ +FIXTURE_VARIANT_ADD(v_csr_valid, frac_lmul1) +{ + .vstart =3D 0x0, + .vl =3D 0x0, + .vtype =3D 0x16, + .vcsr =3D 0x0, + .vlenb_mul =3D 0x1, + .vlenb_min =3D 0x10, + .vlenb_max =3D 0x0, + .spec =3D VECTOR_1_0, +}; + +/* valid for VLEN >=3D 16: LMUL=3D 2, SEW =3D 32 */ +FIXTURE_VARIANT_ADD(v_csr_valid, int_lmul1) +{ + .vstart =3D 0x0, + .vl =3D 0x0, + .vtype =3D 0x11, + .vcsr =3D 0x0, + .vlenb_mul =3D 0x1, + .vlenb_min =3D 0x2, + .vlenb_max =3D 0x0, + .spec =3D VECTOR_1_0, +}; + +/* valid for XTheadVector VLEN >=3D 16: LMUL=3D 2, SEW =3D 32 */ +FIXTURE_VARIANT_ADD(v_csr_valid, int_lmul2) +{ + .vstart =3D 0x0, + .vl =3D 0x0, + .vtype =3D 0x9, + .vcsr =3D 0x0, + .vlenb_mul =3D 0x1, + .vlenb_min =3D 0x2, + .vlenb_max =3D 0x0, + .spec =3D XTHEAD_VECTOR_0_7, +}; + +/* valid for VLEN >=3D 32: LMUL=3D 2, SEW =3D 32, VL =3D 2 */ +FIXTURE_VARIANT_ADD(v_csr_valid, int_lmul3) +{ + .vstart =3D 0x0, + .vl =3D 0x2, + .vtype =3D 0x11, + .vcsr =3D 0x0, + .vlenb_mul =3D 0x1, + .vlenb_min =3D 0x4, + .vlenb_max =3D 0x0, + .spec =3D VECTOR_1_0, +}; + +TEST_F(v_csr_valid, ptrace_v_valid_values) +{ + unsigned long vlenb; + pid_t pid; + + if (!is_vector_supported() && !is_xtheadvector_supported()) + SKIP(return, "Vectors not supported"); + + if (is_vector_supported() && !vector_test(variant->spec)) + SKIP(return, "Test not supported for Vector"); + + if (is_xtheadvector_supported() && !xthead_test(variant->spec)) + SKIP(return, "Test not supported for XTheadVector"); + + vlenb =3D get_vr_len(); + + if (variant->vlenb_min) { + if (vlenb < variant->vlenb_min) + SKIP(return, "This test does not support VLEN < %lu\n", + variant->vlenb_min * 8); + } + if (variant->vlenb_max) { + if (vlenb > variant->vlenb_max) + SKIP(return, "This test does not support VLEN > %lu\n", + variant->vlenb_max * 8); + } + + chld_lock =3D 1; + pid =3D fork(); + ASSERT_LE(0, pid) + TH_LOG("fork: %m"); + + if (pid =3D=3D 0) { + unsigned long vl; + + while (chld_lock =3D=3D 1) + asm volatile("" : : "g"(chld_lock) : "memory"); + + if (is_xtheadvector_supported()) { + asm volatile ( + // 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli + // vsetvli t4, x0, e16, m2, d1 + ".4byte 0b00000000010100000111111011010111\n" + "mv %[new_vl], t4\n" + : [new_vl] "=3Dr" (vl) : : "t4"); + } else { + asm volatile ( + ".option push\n" + ".option arch, +zve32x\n" + "vsetvli %[new_vl], x0, e16, m2, tu, mu\n" + ".option pop\n" + : [new_vl] "=3Dr"(vl) : : ); + } + + asm volatile ( + ".option push\n" + ".option norvc\n" + ".option arch, +zve32x\n" + "ebreak\n" /* breakpoint 1: apply new V state using ptrace */ + "nop\n" + "ebreak\n" /* breakpoint 2: V state clean - context will not be saved */ + "vmv.v.i v0, -1\n" + "ebreak\n" /* breakpoint 3: V state dirty - context will be saved */ + ".option pop\n"); + } else { + struct __riscv_v_regset_state *regset_data; + struct user_regs_struct regs; + size_t regset_size; + struct iovec iov; + int status; + + /* attach */ + + ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid, NULL, NULL)); + ASSERT_EQ(pid, waitpid(pid, &status, 0)); + ASSERT_TRUE(WIFSTOPPED(status)); + + /* unlock */ + + ASSERT_EQ(0, ptrace(PTRACE_POKEDATA, pid, &chld_lock, 0)); + + /* resume and wait for the 1st ebreak */ + + ASSERT_EQ(0, ptrace(PTRACE_CONT, pid, NULL, NULL)); + ASSERT_EQ(pid, waitpid(pid, &status, 0)); + ASSERT_TRUE(WIFSTOPPED(status)); + + /* read tracee vector csr regs using ptrace GETREGSET */ + + regset_size =3D sizeof(*regset_data) + vlenb * 32; + regset_data =3D calloc(1, regset_size); + + iov.iov_base =3D regset_data; + iov.iov_len =3D regset_size; + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_RISCV_VECTOR, &iov)); + + /* verify initial vsetvli settings */ + + if (is_xtheadvector_supported()) { + EXPECT_EQ(5UL, regset_data->vtype); + } else { + EXPECT_EQ(9UL, regset_data->vtype); + } + + EXPECT_EQ(regset_data->vlenb, regset_data->vl); + EXPECT_EQ(vlenb, regset_data->vlenb); + EXPECT_EQ(0UL, regset_data->vstart); + EXPECT_EQ(0UL, regset_data->vcsr); + + /* apply valid settings from fixture variants */ + + regset_data->vlenb *=3D variant->vlenb_mul; + regset_data->vstart =3D variant->vstart; + regset_data->vtype =3D variant->vtype; + regset_data->vcsr =3D variant->vcsr; + regset_data->vl =3D variant->vl; + + iov.iov_base =3D regset_data; + iov.iov_len =3D regset_size; + + ASSERT_EQ(0, ptrace(PTRACE_SETREGSET, pid, NT_RISCV_VECTOR, &iov)); + + /* skip 1st ebreak, then resume and wait for the 2nd ebreak */ + + iov.iov_base =3D ®s; + iov.iov_len =3D sizeof(regs); + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)); + regs.pc +=3D 4; + ASSERT_EQ(0, ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov)); + + ASSERT_EQ(0, ptrace(PTRACE_CONT, pid, NULL, NULL)); + ASSERT_EQ(pid, waitpid(pid, &status, 0)); + ASSERT_TRUE(WIFSTOPPED(status)); + + /* read tracee vector csr regs using ptrace GETREGSET */ + + iov.iov_base =3D regset_data; + iov.iov_len =3D regset_size; + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_RISCV_VECTOR, &iov)); + + /* verify vector csr regs from tracee context */ + + EXPECT_EQ(regset_data->vstart, variant->vstart); + EXPECT_EQ(regset_data->vtype, variant->vtype); + EXPECT_EQ(regset_data->vcsr, variant->vcsr); + EXPECT_EQ(regset_data->vl, variant->vl); + EXPECT_EQ(regset_data->vlenb, vlenb); + + /* skip 2nd ebreak, then resume and wait for the 3rd ebreak */ + + iov.iov_base =3D ®s; + iov.iov_len =3D sizeof(regs); + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)); + regs.pc +=3D 4; + ASSERT_EQ(0, ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov)); + + ASSERT_EQ(0, ptrace(PTRACE_CONT, pid, NULL, NULL)); + ASSERT_EQ(pid, waitpid(pid, &status, 0)); + ASSERT_TRUE(WIFSTOPPED(status)); + + /* read tracee vector csr regs using ptrace GETREGSET */ + + iov.iov_base =3D regset_data; + iov.iov_len =3D regset_size; + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_RISCV_VECTOR, &iov)); + + /* verify vector csr regs from tracee context */ + + EXPECT_EQ(regset_data->vstart, variant->vstart); + EXPECT_EQ(regset_data->vtype, variant->vtype); + EXPECT_EQ(regset_data->vcsr, variant->vcsr); + EXPECT_EQ(regset_data->vl, variant->vl); + EXPECT_EQ(regset_data->vlenb, vlenb); + + /* cleanup */ + + ASSERT_EQ(0, kill(pid, SIGKILL)); + } +} + TEST_HARNESS_MAIN --=20 2.52.0