From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lj1-f171.google.com (mail-lj1-f171.google.com [209.85.208.171]) (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 B8CDC2BCF6C for ; Sat, 8 Nov 2025 19:42:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762630969; cv=none; b=kr4zruLTA0MMhbACxMnrEeSVkmC4ybJOi+YDkCmfXPpX9iKzUEltPxnxBnpuTbnLwUuIqMEmKpjDYdPXSBXDaIwuMv4JL2LoDmeAKI2qiKnp8XpFs0XdNcMvtU6vIxJjxpCpllE8755vnmQ0OJGK/U/NdK6YoaMQd6qdH0UuIA4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762630969; c=relaxed/simple; bh=NC8kT8H7O9tPSR1GVZ5MkZ/EuwG+lj22RqmD9cDB4w4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fspHBGvuktX5yLeR8Lm7iJM1nqWCX973rS9t0NVIqBdJIj8ma45V+FVm7JrfGd1nf1zhX5488/HOyn0kbT525UCqVBcX4otK7/g5rNn77EupYyMK4A85SiSCBGCEPky4gO1oc6itX5sxR2lshn3Xldc5RdSrKkCvym0zKbaUV1s= 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=iZ5R1dD7; arc=none smtp.client-ip=209.85.208.171 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="iZ5R1dD7" Received: by mail-lj1-f171.google.com with SMTP id 38308e7fff4ca-36295d53a10so14510931fa.0 for ; Sat, 08 Nov 2025 11:42:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762630966; x=1763235766; 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=9MFI8F8MhzTGH2Tkz0Xnk/at+/PFhFqLHCBOZQcDhpQ=; b=iZ5R1dD7AvGBSNrZy0MWtOo3tQZKXl9UhyfjyxxJbeR5xw9CBEXJK7LJUExrWFQmn3 4iAMdd3EQVMu2br/n5T9jsPcfDYBJ3ZYIuou0E0VokSI8UL0BSa7Yx2un4CidHmch6r1 sH3caelH8oAkSS4dd5+dYVTdjRvh1iAxtBeY94X+Q8431z0lI443OrxgpQnE3piEa69s A1xE5rZpbOZSkjkWLoeFsaHtvpHNRoD4vGdwkn/AnuQx8IUNt/MtxVlIQ1hLvktrcx5j 0td+REOP8ksdT6eRtB3Bq7sQxwIVU6harHWVGXvwZEjJzkP+isp2K9LvlYHI2+L82i8E icng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762630966; x=1763235766; 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=9MFI8F8MhzTGH2Tkz0Xnk/at+/PFhFqLHCBOZQcDhpQ=; b=giJWigwSUU27IgExee4RyJJ7xdeYTYgGmurRlHTWkVgRl6IS5M4F6cT5mz1UACz3et TRpUSHIECjmliM7zSqxLBJMw7GznMq9nBr3bv0refz9Rg6MDc35EMtYRIXZy+DzgxKq8 v39GY7E/uvvd89TgGgFj9XjOOAAbe2SoxLHLui+NKSO3vEsr/2VeBsmjy/XSdGspxj7T 4IRdDfqTAUEX+707T6XEdIo2WfQmws78suCMsl/dMG7z/w3gSOVXGYRrW3VDqGi4IkDT 4GfpZ7os8suFwj6ZcWoa9VLwvALRg+HJ9j5U62+r8Af6wGZWvcU2UJABrMCH8aE+bTe3 OFhA== X-Forwarded-Encrypted: i=1; AJvYcCVvKY2HGjklQ2MQHWQrnPcbT+kSpM/2L5VoYV/+5fS8wFOPqdlGt+KXfJElRLipXbh2Ny53wxRYQ6K6jdB0OrE=@vger.kernel.org X-Gm-Message-State: AOJu0YxKJIGkHSqrVvgBBdpHAm+9GO/SSgTo8VhRo6yT19PpNr2MbaFi vh7WKmmKiP7u6WteMhhoLu3DSPfq1r8HK64ZAHZMTGMcH4blAnzOrwbh X-Gm-Gg: ASbGncuhNJcX4xCwdhz1A0bU/jw4qkxTz7kM6oEq3/WSbkIwOtTeGB33nplkQ3LvOmV rd8eNGMgxIzPu1ADJsUo/qujRdYXxDX/mlRQoHkyZq5oB4aA0l8ripyi9Il2w+HJ/6iB0qCs87o 7espt89+fGwI0e8oc1mz/Nq8L2OcqA5zVO1Tkbyy26ILZRz8gG6gOzm4h36HZt+kn+4A6gBfbCe CMVuICihwydp5GffPk8XWAKUOKvmm5ewFD/Qr33vwZgieMNQ27zze7Ty/cuhsPANCmhALvPG+Ym sGXQO2P+o91JRsGjGcw1VeHjX9q9Nr9SvDeOi90Fk2HGASQhWy9p574bWTor1SQrIZzehrl0igK hI3UFvpxXo1y/2YrujCInAV+d7jwZ/hjFet28e8fF9+OWjC5fJdg5YUm8eXPjk6ePE0wQLE29Fa kakw== X-Google-Smtp-Source: AGHT+IHbYn87jHk26NRP1W1uXjBVOyzCstea/e1FIM8sKuFxADbEgxnxI++FMyPzsOedM9+Po12fWQ== X-Received: by 2002:a2e:9bc4:0:b0:336:ca4c:df40 with SMTP id 38308e7fff4ca-37a7b188b62mr7853891fa.12.1762630965754; Sat, 08 Nov 2025 11:42:45 -0800 (PST) Received: from curiosity ([5.188.167.4]) by smtp.googlemail.com with ESMTPSA id 38308e7fff4ca-37a5f0edac3sm22115421fa.38.2025.11.08.11.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 08 Nov 2025 11:42:43 -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 , Sergey Matyukevich Subject: [PATCH v4 8/9] selftests: riscv: verify ptrace accepts valid vector csr values Date: Sat, 8 Nov 2025 22:41:47 +0300 Message-ID: <20251108194207.1257866-9-geomatsi@gmail.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251108194207.1257866-1-geomatsi@gmail.com> References: <20251108194207.1257866-1-geomatsi@gmail.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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: 1. init: let the tracee set up its initial vector configuration 2. 1st bp: modify the tracee's vector csr registers from the debugger - resume the tracee to execute a block without vector instructions 3. 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 4. 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 --- .../testing/selftests/riscv/vector/v_ptrace.c | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/tools/testing/selftests/riscv/vector/v_ptrace.c b/tools/testing/selftests/riscv/vector/v_ptrace.c index 023e1faa84bf..fb371a42de15 100644 --- a/tools/testing/selftests/riscv/vector/v_ptrace.c +++ b/tools/testing/selftests/riscv/vector/v_ptrace.c @@ -421,4 +421,227 @@ TEST_F(v_csr_invalid, ptrace_v_invalid_values) } } +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; +}; + +/* valid for VLEN >= 128: LMUL= 1/4, SEW = 32 */ +FIXTURE_VARIANT_ADD(v_csr_valid, frac_lmul1) +{ + .vstart = 0x0, + .vl = 0x0, + .vtype = 0x16, + .vcsr = 0x0, + .vlenb_mul = 0x1, + .vlenb_min = 0x10, + .vlenb_max = 0x0, +}; + +/* valid for VLEN >= 16: LMUL= 2, SEW = 32 */ +FIXTURE_VARIANT_ADD(v_csr_valid, int_lmul1) +{ + .vstart = 0x0, + .vl = 0x0, + .vtype = 0x11, + .vcsr = 0x0, + .vlenb_mul = 0x1, + .vlenb_min = 0x2, + .vlenb_max = 0x0, +}; + +/* valid for VLEN >= 32: LMUL= 2, SEW = 32, VL = 2 */ +FIXTURE_VARIANT_ADD(v_csr_valid, int_lmul2) +{ + .vstart = 0x0, + .vl = 0x2, + .vtype = 0x11, + .vcsr = 0x0, + .vlenb_mul = 0x1, + .vlenb_min = 0x4, + .vlenb_max = 0x0, +}; + +TEST_F(v_csr_valid, ptrace_v_valid_values) +{ + unsigned long vlenb; + pid_t pid; + + if (!is_vector_supported()) + SKIP(return, "Vector not supported"); + + asm volatile("csrr %[vlenb], vlenb" : [vlenb] "=r"(vlenb)); + 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 = 1; + pid = fork(); + ASSERT_LE(0, pid) + TH_LOG("fork: %m"); + + if (pid == 0) { + unsigned long vl; + + while (chld_lock == 1) + asm volatile("" : : "g"(chld_lock) : "memory"); + + asm(".option arch, +zve32x\n"); + asm(".option arch, +c\n"); + + asm volatile("vsetvli %[new_vl], x0, e16, m2, tu, mu\n" + : [new_vl] "=r"(vl) + : + :); + + while (1) { + asm volatile ("c.ebreak"); + asm volatile ("c.nop"); + /* V state clean: context will not be saved */ + asm volatile ("c.ebreak"); + asm volatile("vmv.v.i v0, -1"); + /* V state dirty: context will be saved */ + } + } 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 c.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 = sizeof(*regset_data) + vlenb * 32; + regset_data = calloc(1, regset_size); + + iov.iov_base = regset_data; + iov.iov_len = regset_size; + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_RISCV_VECTOR, &iov)); + + /* verify initial vsetvli settings */ + + EXPECT_EQ(regset_data->vlenb, regset_data->vl); + EXPECT_EQ(9UL, regset_data->vtype); + 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 *= variant->vlenb_mul; + regset_data->vstart = variant->vstart; + regset_data->vtype = variant->vtype; + regset_data->vcsr = variant->vcsr; + regset_data->vl = variant->vl; + + iov.iov_base = regset_data; + iov.iov_len = regset_size; + + ASSERT_EQ(0, ptrace(PTRACE_SETREGSET, pid, NT_RISCV_VECTOR, &iov)); + + /* skip 1st c.ebreak, then resume and wait for the 2nd c.ebreak */ + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)); + regs.pc += 2; + 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 = regset_data; + iov.iov_len = 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 c.ebreak, then resume and wait for the 3rd c.ebreak */ + + iov.iov_base = ®s; + iov.iov_len = sizeof(regs); + + ASSERT_EQ(0, ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)); + regs.pc += 2; + 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 = regset_data; + iov.iov_len = 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 -- 2.51.0