[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <91d6b423-1132-4d85-bdee-de20af5b4844@rivosinc.com>
Date: Mon, 12 May 2025 09:18:11 +0200
From: Clément Léger <cleger@...osinc.com>
To: Alexandre Ghiti <alex@...ti.fr>,
"open list:DOCUMENTATION" <linux-doc@...r.kernel.org>,
open list <linux-kernel@...r.kernel.org>,
"open list:RISC-V ARCHITECTURE" <linux-riscv@...ts.infradead.org>,
"open list:KERNEL SELFTEST FRAMEWORK" <linux-kselftest@...r.kernel.org>
Cc: Jonathan Corbet <corbet@....net>, Paul Walmsley
<paul.walmsley@...ive.com>, Palmer Dabbelt <palmer@...belt.com>,
Albert Ou <aou@...s.berkeley.edu>, Shuah Khan <shuah@...nel.org>,
Andrew Jones <ajones@...tanamicro.com>,
Samuel Holland <samuel.holland@...ive.com>
Subject: Re: [PATCH v2 5/5] selftests: riscv: add misaligned access testing
On 09/05/2025 10:22, Alexandre Ghiti wrote:
> Hi Clément,
>
> On 22/04/2025 18:23, Clément Léger wrote:
>> This selftest tests (almost) all the currently emulated instruction
>> (except for the RV32 compressed ones which are left as a future
>> exercise for a RV32 user). For the FPU instructions, all the FPU
>> registers are tested.
>>
>> Signed-off-by: Clément Léger <cleger@...osinc.com>
>> ---
>> .../selftests/riscv/misaligned/.gitignore | 1 +
>> .../selftests/riscv/misaligned/Makefile | 12 +
>> .../selftests/riscv/misaligned/common.S | 33 +++
>> .../testing/selftests/riscv/misaligned/fpu.S | 180 +++++++++++++
>> tools/testing/selftests/riscv/misaligned/gp.S | 103 +++++++
>> .../selftests/riscv/misaligned/misaligned.c | 254 ++++++++++++++++++
>> 6 files changed, 583 insertions(+)
>> create mode 100644 tools/testing/selftests/riscv/misaligned/.gitignore
>> create mode 100644 tools/testing/selftests/riscv/misaligned/Makefile
>> create mode 100644 tools/testing/selftests/riscv/misaligned/common.S
>> create mode 100644 tools/testing/selftests/riscv/misaligned/fpu.S
>> create mode 100644 tools/testing/selftests/riscv/misaligned/gp.S
>> create mode 100644 tools/testing/selftests/riscv/misaligned/
>> misaligned.c
>>
>> diff --git a/tools/testing/selftests/riscv/misaligned/.gitignore b/
>> tools/testing/selftests/riscv/misaligned/.gitignore
>> new file mode 100644
>> index 000000000000..5eff15a1f981
>> --- /dev/null
>> +++ b/tools/testing/selftests/riscv/misaligned/.gitignore
>> @@ -0,0 +1 @@
>> +misaligned
>> diff --git a/tools/testing/selftests/riscv/misaligned/Makefile b/
>> tools/testing/selftests/riscv/misaligned/Makefile
>> new file mode 100644
>> index 000000000000..1aa40110c50d
>> --- /dev/null
>> +++ b/tools/testing/selftests/riscv/misaligned/Makefile
>> @@ -0,0 +1,12 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021 ARM Limited
>> +# Originally tools/testing/arm64/abi/Makefile
>> +
>> +CFLAGS += -I$(top_srcdir)/tools/include
>> +
>> +TEST_GEN_PROGS := misaligned
>> +
>> +include ../../lib.mk
>> +
>> +$(OUTPUT)/misaligned: misaligned.c fpu.S gp.S
>> + $(CC) -g3 -static -o$@ -march=rv64imafdc $(CFLAGS) $(LDFLAGS) $^
>> diff --git a/tools/testing/selftests/riscv/misaligned/common.S b/
>> tools/testing/selftests/riscv/misaligned/common.S
>> new file mode 100644
>> index 000000000000..8fa00035bd5d
>> --- /dev/null
>> +++ b/tools/testing/selftests/riscv/misaligned/common.S
>> @@ -0,0 +1,33 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2025 Rivos Inc.
>> + *
>> + * Authors:
>> + * Clément Léger <cleger@...osinc.com>
>> + */
>> +
>> +.macro lb_sb temp, offset, src, dst
>> + lb \temp, \offset(\src)
>> + sb \temp, \offset(\dst)
>> +.endm
>> +
>> +.macro copy_long_to temp, src, dst
>> + lb_sb \temp, 0, \src, \dst,
>> + lb_sb \temp, 1, \src, \dst,
>> + lb_sb \temp, 2, \src, \dst,
>> + lb_sb \temp, 3, \src, \dst,
>> + lb_sb \temp, 4, \src, \dst,
>> + lb_sb \temp, 5, \src, \dst,
>> + lb_sb \temp, 6, \src, \dst,
>> + lb_sb \temp, 7, \src, \dst,
>> +.endm
>> +
>> +.macro sp_stack_prologue offset
>> + addi sp, sp, -8
>> + sub sp, sp, \offset
>> +.endm
>> +
>> +.macro sp_stack_epilogue offset
>> + add sp, sp, \offset
>> + addi sp, sp, 8
>> +.endm
>> diff --git a/tools/testing/selftests/riscv/misaligned/fpu.S b/tools/
>> testing/selftests/riscv/misaligned/fpu.S
>> new file mode 100644
>> index 000000000000..d008bff58310
>> --- /dev/null
>> +++ b/tools/testing/selftests/riscv/misaligned/fpu.S
>> @@ -0,0 +1,180 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2025 Rivos Inc.
>> + *
>> + * Authors:
>> + * Clément Léger <cleger@...osinc.com>
>> + */
>> +
>> +#include "common.S"
>> +
>> +#define CASE_ALIGN 4
>> +
>> +.macro fpu_load_inst fpreg, inst, precision, load_reg
>> +.align CASE_ALIGN
>> + \inst \fpreg, 0(\load_reg)
>> + fmv.\precision fa0, \fpreg
>> + j 2f
>> +.endm
>> +
>> +#define flw(__fpreg) fpu_load_inst __fpreg, flw, s, s1
>> +#define fld(__fpreg) fpu_load_inst __fpreg, fld, d, s1
>> +#define c_flw(__fpreg) fpu_load_inst __fpreg, c.flw, s, s1
>> +#define c_fld(__fpreg) fpu_load_inst __fpreg, c.fld, d, s1
>> +#define c_fldsp(__fpreg) fpu_load_inst __fpreg, c.fldsp, d, sp
>> +
>> +.macro fpu_store_inst fpreg, inst, precision, store_reg
>> +.align CASE_ALIGN
>> + fmv.\precision \fpreg, fa0
>> + \inst \fpreg, 0(\store_reg)
>> + j 2f
>> +.endm
>> +
>> +#define fsw(__fpreg) fpu_store_inst __fpreg, fsw, s, s1
>> +#define fsd(__fpreg) fpu_store_inst __fpreg, fsd, d, s1
>> +#define c_fsw(__fpreg) fpu_store_inst __fpreg, c.fsw, s, s1
>> +#define c_fsd(__fpreg) fpu_store_inst __fpreg, c.fsd, d, s1
>> +#define c_fsdsp(__fpreg) fpu_store_inst __fpreg, c.fsdsp, d, sp
>> +
>> +.macro fp_test_prologue
>> + move s1, a1
>> + /*
>> + * Compute jump offset to store the correct FP register since we
>> don't
>> + * have indirect FP register access (or at least we don't use this
>> + * extension so that works on all archs)
>> + */
>> + sll t0, a0, CASE_ALIGN
>> + la t2, 1f
>> + add t0, t0, t2
>> + jr t0
>> +.align CASE_ALIGN
>> +1:
>> +.endm
>> +
>> +.macro fp_test_prologue_compressed
>> + /* FP registers for compressed instructions starts from 8 to 16 */
>> + addi a0, a0, -8
>> + fp_test_prologue
>> +.endm
>> +
>> +#define fp_test_body_compressed(__inst_func) \
>> + __inst_func(f8); \
>> + __inst_func(f9); \
>> + __inst_func(f10); \
>> + __inst_func(f11); \
>> + __inst_func(f12); \
>> + __inst_func(f13); \
>> + __inst_func(f14); \
>> + __inst_func(f15); \
>> +2:
>> +
>> +#define fp_test_body(__inst_func) \
>> + __inst_func(f0); \
>> + __inst_func(f1); \
>> + __inst_func(f2); \
>> + __inst_func(f3); \
>> + __inst_func(f4); \
>> + __inst_func(f5); \
>> + __inst_func(f6); \
>> + __inst_func(f7); \
>> + __inst_func(f8); \
>> + __inst_func(f9); \
>> + __inst_func(f10); \
>> + __inst_func(f11); \
>> + __inst_func(f12); \
>> + __inst_func(f13); \
>> + __inst_func(f14); \
>> + __inst_func(f15); \
>> + __inst_func(f16); \
>> + __inst_func(f17); \
>> + __inst_func(f18); \
>> + __inst_func(f19); \
>> + __inst_func(f20); \
>> + __inst_func(f21); \
>> + __inst_func(f22); \
>> + __inst_func(f23); \
>> + __inst_func(f24); \
>> + __inst_func(f25); \
>> + __inst_func(f26); \
>> + __inst_func(f27); \
>> + __inst_func(f28); \
>> + __inst_func(f29); \
>> + __inst_func(f30); \
>> + __inst_func(f31); \
>> +2:
>> +.text
>> +
>> +#define __gen_test_inst(__inst, __suffix) \
>> +.global test_ ## __inst; \
>> +test_ ## __inst:; \
>> + fp_test_prologue ## __suffix; \
>> + fp_test_body ## __suffix(__inst); \
>> + ret
>> +
>> +#define gen_test_inst_compressed(__inst) \
>> + .option arch,+c; \
>> + __gen_test_inst(c_ ## __inst, _compressed)
>> +
>> +#define gen_test_inst(__inst) \
>> + .balign 16; \
>> + .option push; \
>> + .option arch,-c; \
>> + __gen_test_inst(__inst, ); \
>> + .option pop
>> +
>> +.macro fp_test_prologue_load_compressed_sp
>> + copy_long_to t0, a1, sp
>> +.endm
>> +
>> +.macro fp_test_epilogue_load_compressed_sp
>> +.endm
>> +
>> +.macro fp_test_prologue_store_compressed_sp
>> +.endm
>> +
>> +.macro fp_test_epilogue_store_compressed_sp
>> + copy_long_to t0, sp, a1
>> +.endm
>> +
>> +#define gen_inst_compressed_sp(__inst, __type) \
>> + .global test_c_ ## __inst ## sp; \
>> + test_c_ ## __inst ## sp:; \
>> + sp_stack_prologue a2; \
>> + fp_test_prologue_## __type ## _compressed_sp; \
>> + fp_test_prologue_compressed; \
>> + fp_test_body_compressed(c_ ## __inst ## sp); \
>> + fp_test_epilogue_## __type ## _compressed_sp; \
>> + sp_stack_epilogue a2; \
>> + ret
>> +
>> +#define gen_test_load_compressed_sp(__inst)
>> gen_inst_compressed_sp(__inst, load)
>> +#define gen_test_store_compressed_sp(__inst)
>> gen_inst_compressed_sp(__inst, store)
>> +
>> +/*
>> + * float_fsw_reg - Set a FP register from a register containing the
>> value
>> + * a0 = FP register index to be set
>> + * a1 = addr where to store register value
>> + * a2 = address offset
>> + * a3 = value to be store
>> + */
>> +gen_test_inst(fsw)
>> +
>> +/*
>> + * float_flw_reg - Get a FP register value and return it
>> + * a0 = FP register index to be retrieved
>> + * a1 = addr to load register from
>> + * a2 = address offset
>> + */
>> +gen_test_inst(flw)
>> +
>> +gen_test_inst(fsd)
>> +#ifdef __riscv_compressed
>> +gen_test_inst_compressed(fsd)
>> +gen_test_store_compressed_sp(fsd)
>> +#endif
>> +
>> +gen_test_inst(fld)
>> +#ifdef __riscv_compressed
>> +gen_test_inst_compressed(fld)
>> +gen_test_load_compressed_sp(fld)
>> +#endif
>> diff --git a/tools/testing/selftests/riscv/misaligned/gp.S b/tools/
>> testing/selftests/riscv/misaligned/gp.S
>> new file mode 100644
>> index 000000000000..f53f4c6d81dd
>> --- /dev/null
>> +++ b/tools/testing/selftests/riscv/misaligned/gp.S
>> @@ -0,0 +1,103 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2025 Rivos Inc.
>> + *
>> + * Authors:
>> + * Clément Léger <cleger@...osinc.com>
>> + */
>> +
>> +#include "common.S"
>> +
>> +.text
>> +
>> +.macro __gen_test_inst inst, src_reg
>> + \inst a2, 0(\src_reg)
>> + move a0, a2
>> +.endm
>> +
>> +.macro gen_func_header func_name, rvc
>> + .option arch,\rvc
>> + .global test_\func_name
>> + test_\func_name:
>> +.endm
>> +
>> +.macro gen_test_inst inst
>> + .option push
>> + gen_func_header \inst, -c
>> + __gen_test_inst \inst, a0
>> + .option pop
>> + ret
>> +.endm
>> +
>> +.macro __gen_test_inst_c name, src_reg
>> + .option push
>> + gen_func_header c_\name, +c
>> + __gen_test_inst c.\name, \src_reg
>> + .option pop
>> + ret
>> +.endm
>> +
>> +.macro gen_test_inst_c name
>> + __gen_test_inst_c \name, a0
>> +.endm
>> +
>> +
>> +.macro gen_test_inst_load_c_sp name
>> + .option push
>> + gen_func_header c_\name\()sp, +c
>> + sp_stack_prologue a1
>> + copy_long_to t0, a0, sp
>> + c.ldsp a0, 0(sp)
>> + sp_stack_epilogue a1
>> + .option pop
>> + ret
>> +.endm
>> +
>> +.macro lb_sp_sb_a0 reg, offset
>> + lb_sb \reg, \offset, sp, a0
>> +.endm
>> +
>> +.macro gen_test_inst_store_c_sp inst_name
>> + .option push
>> + gen_func_header c_\inst_name\()sp, +c
>> + /* Misalign stack pointer */
>> + sp_stack_prologue a1
>> + /* Misalign access */
>> + c.sdsp a2, 0(sp)
>> + copy_long_to t0, sp, a0
>> + sp_stack_epilogue a1
>> + .option pop
>> + ret
>> +.endm
>> +
>> +
>> + /*
>> + * a0 = addr to load from
>> + * a1 = address offset
>> + * a2 = value to be loaded
>> + */
>> +gen_test_inst lh
>> +gen_test_inst lhu
>> +gen_test_inst lw
>> +gen_test_inst lwu
>> +gen_test_inst ld
>> +#ifdef __riscv_compressed
>> +gen_test_inst_c lw
>> +gen_test_inst_c ld
>> +gen_test_inst_load_c_sp ld
>> +#endif
>> +
>> +/*
>> + * a0 = addr where to store value
>> + * a1 = address offset
>> + * a2 = value to be stored
>> + */
>> +gen_test_inst sh
>> +gen_test_inst sw
>> +gen_test_inst sd
>> +#ifdef __riscv_compressed
>> +gen_test_inst_c sw
>> +gen_test_inst_c sd
>> +gen_test_inst_store_c_sp sd
>> +#endif
>> +
>> diff --git a/tools/testing/selftests/riscv/misaligned/misaligned.c b/
>> tools/testing/selftests/riscv/misaligned/misaligned.c
>> new file mode 100644
>> index 000000000000..c66aa87ec03e
>> --- /dev/null
>> +++ b/tools/testing/selftests/riscv/misaligned/misaligned.c
>> @@ -0,0 +1,254 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2025 Rivos Inc.
>> + *
>> + * Authors:
>> + * Clément Léger <cleger@...osinc.com>
>> + */
>> +#include <signal.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <linux/ptrace.h>
>> +#include "../../kselftest_harness.h"
>> +
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +#include <stdint.h>
>> +#include <float.h>
>> +#include <errno.h>
>> +#include <math.h>
>> +#include <string.h>
>> +#include <signal.h>
>> +#include <stdbool.h>
>> +#include <unistd.h>
>> +#include <inttypes.h>
>> +#include <ucontext.h>
>> +
>> +#include <sys/prctl.h>
>> +
>> +#define stringify(s) __stringify(s)
>> +#define __stringify(s) #s
>> +
>> +#define VAL16 0x1234
>> +#define VAL32 0xDEADBEEF
>> +#define VAL64 0x45674321D00DF789
>> +
>> +#define VAL_float 78951.234375
>> +#define VAL_double 567890.512396965789589290
>> +
>> +static bool float_equal(float a, float b)
>> +{
>> + float scaled_epsilon;
>> + float difference = fabsf(a - b);
>> +
>> + // Scale to the largest value.
>> + a = fabsf(a);
>> + b = fabsf(b);
>> + if (a > b)
>> + scaled_epsilon = FLT_EPSILON * a;
>> + else
>> + scaled_epsilon = FLT_EPSILON * b;
>> +
>> + return difference <= scaled_epsilon;
>> +}
>> +
>> +static bool double_equal(double a, double b)
>> +{
>> + double scaled_epsilon;
>> + double difference = fabsf(a - b);
>> +
>> + // Scale to the largest value.
>> + a = fabs(a);
>> + b = fabs(b);
>> + if (a > b)
>> + scaled_epsilon = DBL_EPSILON * a;
>> + else
>> + scaled_epsilon = DBL_EPSILON * b;
>> +
>> + return difference <= scaled_epsilon;
>> +}
>> +
>> +#define fpu_load_proto(__inst, __type) \
>> +extern __type test_ ## __inst(unsigned long fp_reg, void *addr,
>> unsigned long offset, __type value)
>> +
>> +fpu_load_proto(flw, float);
>> +fpu_load_proto(fld, double);
>> +fpu_load_proto(c_flw, float);
>> +fpu_load_proto(c_fld, double);
>> +fpu_load_proto(c_fldsp, double);
>> +
>> +#define fpu_store_proto(__inst, __type) \
>> +extern void test_ ## __inst(unsigned long fp_reg, void *addr,
>> unsigned long offset, __type value)
>> +
>> +fpu_store_proto(fsw, float);
>> +fpu_store_proto(fsd, double);
>> +fpu_store_proto(c_fsw, float);
>> +fpu_store_proto(c_fsd, double);
>> +fpu_store_proto(c_fsdsp, double);
>> +
>> +#define gp_load_proto(__inst, __type) \
>> +extern __type test_ ## __inst(void *addr, unsigned long offset,
>> __type value)
>> +
>> +gp_load_proto(lh, uint16_t);
>> +gp_load_proto(lhu, uint16_t);
>> +gp_load_proto(lw, uint32_t);
>> +gp_load_proto(lwu, uint32_t);
>> +gp_load_proto(ld, uint64_t);
>> +gp_load_proto(c_lw, uint32_t);
>> +gp_load_proto(c_ld, uint64_t);
>> +gp_load_proto(c_ldsp, uint64_t);
>> +
>> +#define gp_store_proto(__inst, __type) \
>> +extern void test_ ## __inst(void *addr, unsigned long offset, __type
>> value)
>> +
>> +gp_store_proto(sh, uint16_t);
>> +gp_store_proto(sw, uint32_t);
>> +gp_store_proto(sd, uint64_t);
>> +gp_store_proto(c_sw, uint32_t);
>> +gp_store_proto(c_sd, uint64_t);
>> +gp_store_proto(c_sdsp, uint64_t);
>> +
>> +#define TEST_GP_LOAD(__inst, __type_size) \
>> +TEST(gp_load_ ## __inst) \
>> +{ \
>> + int offset, ret; \
>> + uint8_t buf[16] __attribute__((aligned(16))); \
>> + \
>> + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \
>> + ASSERT_EQ(ret, 0); \
>> + \
>> + for (offset = 1; offset < __type_size / 8; offset++) { \
>> + uint ## __type_size ## _t val = VAL ## __type_size; \
>> + uint ## __type_size ## _t *ptr = (uint ## __type_size ## _t
>> *) (buf + offset); \
>> + memcpy(ptr, &val, sizeof(val)); \
>> + val = test_ ## __inst(ptr, offset, val); \
>> + EXPECT_EQ(VAL ## __type_size, val); \
>> + } \
>> +}
>> +
>> +TEST_GP_LOAD(lh, 16);
>> +TEST_GP_LOAD(lhu, 16);
>> +TEST_GP_LOAD(lw, 32);
>> +TEST_GP_LOAD(lwu, 32);
>> +TEST_GP_LOAD(ld, 64);
>> +#ifdef __riscv_compressed
>> +TEST_GP_LOAD(c_lw, 32);
>> +TEST_GP_LOAD(c_ld, 64);
>> +TEST_GP_LOAD(c_ldsp, 64);
>> +#endif
>> +
>> +#define TEST_GP_STORE(__inst, __type_size) \
>> +TEST(gp_load_ ## __inst) \
>> +{ \
>> + int offset, ret; \
>> + uint8_t buf[16] __attribute__((aligned(16))); \
>> + \
>> + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \
>> + ASSERT_EQ(ret, 0); \
>> + \
>> + for (offset = 1; offset < __type_size / 8; offset++) { \
>> + uint ## __type_size ## _t val = VAL ## __type_size; \
>> + uint ## __type_size ## _t *ptr = (uint ## __type_size ## _t
>> *) (buf + offset); \
>> + memset(ptr, 0, sizeof(val)); \
>> + test_ ## __inst(ptr, offset, val); \
>> + memcpy(&val, ptr, sizeof(val)); \
>> + EXPECT_EQ(VAL ## __type_size, val); \
>> + } \
>> +}
>> +TEST_GP_STORE(sh, 16);
>> +TEST_GP_STORE(sw, 32);
>> +TEST_GP_STORE(sd, 64);
>> +#ifdef __riscv_compressed
>> +TEST_GP_STORE(c_sw, 32);
>> +TEST_GP_STORE(c_sd, 64);
>> +TEST_GP_STORE(c_sdsp, 64);
>> +#endif
>> +
>> +#define __TEST_FPU_LOAD(__type, __inst, __reg_start,
>> __reg_end) \
>> +TEST(fpu_load_ ## __inst) \
>> +{ \
>> + int i, ret, offset, fp_reg; \
>> + uint8_t buf[16] __attribute__((aligned(16))); \
>> + \
>> + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \
>> + ASSERT_EQ(ret, 0); \
>> + \
>> + for (fp_reg = __reg_start; fp_reg < __reg_end; fp_reg++) { \
>> + for (offset = 1; offset < 4; offset++) { \
>> + void *load_addr = (buf + offset); \
>> + __type val = VAL_ ## __type ; \
>> + \
>> + memcpy(load_addr, &val, sizeof(val)); \
>> + val = test_ ## __inst(fp_reg, load_addr, offset, val); \
>> + EXPECT_TRUE(__type ##_equal(val, VAL_## __type)); \
>> + } \
>> + } \
>> +}
>> +#define TEST_FPU_LOAD(__type, __inst) \
>> + __TEST_FPU_LOAD(__type, __inst, 0, 32)
>> +#define TEST_FPU_LOAD_COMPRESSED(__type, __inst) \
>> + __TEST_FPU_LOAD(__type, __inst, 8, 16)
>> +
>> +TEST_FPU_LOAD(float, flw)
>> +TEST_FPU_LOAD(double, fld)
>> +#ifdef __riscv_compressed
>> +TEST_FPU_LOAD_COMPRESSED(double, c_fld)
>> +TEST_FPU_LOAD_COMPRESSED(double, c_fldsp)
>> +#endif
>> +
>> +#define __TEST_FPU_STORE(__type, __inst, __reg_start,
>> __reg_end) \
>> +TEST(fpu_store_ ## __inst) \
>> +{ \
>> + int i, ret, offset, fp_reg; \
>> + uint8_t buf[16] __attribute__((aligned(16))); \
>> + \
>> + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \
>> + ASSERT_EQ(ret, 0); \
>> + \
>> + for (fp_reg = __reg_start; fp_reg < __reg_end; fp_reg++) { \
>> + for (offset = 1; offset < 4; offset++) { \
>> + \
>> + void *store_addr = (buf + offset); \
>> + __type val = VAL_ ## __type ; \
>> + \
>> + test_ ## __inst(fp_reg, store_addr, offset, val); \
>> + memcpy(&val, store_addr, sizeof(val)); \
>> + EXPECT_TRUE(__type ## _equal(val, VAL_## __type)); \
>> + } \
>> + } \
>> +}
>> +#define TEST_FPU_STORE(__type, __inst) \
>> + __TEST_FPU_STORE(__type, __inst, 0, 32)
>> +#define TEST_FPU_STORE_COMPRESSED(__type, __inst) \
>> + __TEST_FPU_STORE(__type, __inst, 8, 16)
>> +
>> +TEST_FPU_STORE(float, fsw)
>> +TEST_FPU_STORE(double, fsd)
>> +#ifdef __riscv_compressed
>> +TEST_FPU_STORE_COMPRESSED(double, c_fsd)
>> +TEST_FPU_STORE_COMPRESSED(double, c_fsdsp)
>> +#endif
>> +
>> +TEST_SIGNAL(gen_sigbus, SIGBUS)
>> +{
>> + uint32_t *ptr;
>> + uint8_t buf[16] __attribute__((aligned(16)));
>> + int ret;
>> +
>> + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_SIGBUS);
>> + ASSERT_EQ(ret, 0);
>> +
>> + ptr = (uint32_t *)(buf + 1);
>> + *ptr = 0xDEADBEEFULL;
>> +}
>> +
>> +int main(int argc, char **argv)
>> +{
>> + int ret, val;
>> +
>> + ret = prctl(PR_GET_UNALIGN, &val);
>> + if (ret == -1 && errno == EINVAL)
>> + ksft_exit_skip("SKIP GET_UNALIGN_CTL not supported\n");
>> +
>> + exit(test_harness_run(argc, argv));
>> +}
>
>
> So I had to add the following to actually compile this selftest along
> with other riscv tests and fix some warnings:
>
> diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/
> selftests/riscv/Makefile
> index 099b8c1f46f89..95a98ceeb3b3a 100644
> --- a/tools/testing/selftests/riscv/Makefile
> +++ b/tools/testing/selftests/riscv/Makefile
> @@ -5,7 +5,7 @@
> ARCH ?= $(shell uname -m 2>/dev/null || echo not)
>
> ifneq (,$(filter $(ARCH),riscv))
> -RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector
> +RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector misaligned
> else
> RISCV_SUBTARGETS :=
> endif
> diff --git a/tools/testing/selftests/riscv/misaligned/misaligned.c b/
> tools/testing/selftests/riscv/misaligned/misaligned.c
> index c66aa87ec03ec..8fa5ad1a93d17 100644
> --- a/tools/testing/selftests/riscv/misaligned/misaligned.c
> +++ b/tools/testing/selftests/riscv/misaligned/misaligned.c
> @@ -167,7 +167,7 @@ TEST_GP_STORE(c_sdsp, 64);
> #define __TEST_FPU_LOAD(__type, __inst, __reg_start,
> __reg_end) \
> TEST(fpu_load_ ##
> __inst) \
> { \
> - int i, ret, offset,
> fp_reg; \
> + int ret, offset,
> fp_reg; \
> uint8_t buf[16]
> __attribute__((aligned(16))); \
> \
> ret = prctl(PR_SET_UNALIGN,
> PR_UNALIGN_NOPRINT); \
> @@ -199,7 +199,7 @@ TEST_FPU_LOAD_COMPRESSED(double, c_fldsp)
> #define __TEST_FPU_STORE(__type, __inst, __reg_start,
> __reg_end) \
> TEST(fpu_store_ ##
> __inst) \
> { \
> - int i, ret, offset,
> fp_reg; \
> + int ret, offset,
> fp_reg; \
> uint8_t buf[16]
> __attribute__((aligned(16))); \
> \
> ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT);
>
>
> I already merged the first 3 commits of this patchset in fixes, so can
> you resend only the last 2 patches with the fixes above?
Yes sure,
Thanks,
Clément
>
> Thanks,
>
> Alex
>
>
Powered by blists - more mailing lists