lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <80edd225-046e-4ef4-9e71-7059aa523e3a@ghiti.fr>
Date: Fri, 9 May 2025 10:22:03 +0200
From: Alexandre Ghiti <alex@...ti.fr>
To: Clément Léger <cleger@...osinc.com>,
 "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

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?

Thanks,

Alex



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ