Commit f92f17a7 authored by Will Deacon's avatar Will Deacon
Browse files

Merge branch 'for-next/selftests' into for-next/core

* for-next/selftests:
  kselftest/arm64: Set default OUTPUT path when undefined
  kselftest/arm64: fp-ptrace: Adjust to new inactive mode behaviour
  kselftest/arm64: fp-ptrace: Adjust to new VL change behaviour
  kselftest/arm64: tpidr2: Adjust to new clone() behaviour
  kselftest/arm64: fp-ptrace: Fix expected FPMR value when PSTATE.SM is changed
parents 3b9552cf b225219a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ CFLAGS += $(KHDR_INCLUDES)

CFLAGS += -I$(top_srcdir)/tools/include

OUTPUT ?= $(CURDIR)

export CFLAGS
export top_srcdir

+12 −2
Original line number Diff line number Diff line
@@ -169,8 +169,10 @@ static int sys_clone(unsigned long clone_flags, unsigned long newsp,
			   child_tidptr);
}

#define __STACK_SIZE (8 * 1024 * 1024)

/*
 * If we clone with CLONE_SETTLS then the value in the parent should
 * If we clone with CLONE_VM then the value in the parent should
 * be unchanged and the child should start with zero and be able to
 * set its own value.
 */
@@ -179,11 +181,19 @@ static int write_clone_read(void)
	int parent_tid, child_tid;
	pid_t parent, waiting;
	int ret, status;
	void *stack;

	parent = getpid();
	set_tpidr2(parent);

	ret = sys_clone(CLONE_SETTLS, 0, &parent_tid, 0, &child_tid);
	stack = malloc(__STACK_SIZE);
	if (!stack) {
		putstr("# malloc() failed\n");
		return 0;
	}

	ret = sys_clone(CLONE_VM, (unsigned long)stack + __STACK_SIZE,
			&parent_tid, 0, &child_tid);
	if (ret == -1) {
		putstr("# clone() failed\n");
		putnum(errno);
+26 −36
Original line number Diff line number Diff line
@@ -439,11 +439,18 @@ static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
		pass = false;
	}

	if (svcr_in & SVCR_SM) {
		if (sve->size != sizeof(sve)) {
			ksft_print_msg("NT_ARM_SVE reports data with PSTATE.SM\n");
			pass = false;
		}
	} else {
		if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
			ksft_print_msg("Mismatch in SVE header size: %d != %lu\n",
				       sve->size, SVE_PT_SIZE(vq, sve->flags));
			pass = false;
		}
	}

	/* The registers might be in completely different formats! */
	if (sve->flags & SVE_PT_REGS_SVE) {
@@ -515,11 +522,18 @@ static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
		pass = false;
	}

	if (!(svcr_in & SVCR_SM)) {
		if (sve->size != sizeof(sve)) {
			ksft_print_msg("NT_ARM_SSVE reports data without PSTATE.SM\n");
			pass = false;
		}
	} else {
		if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
			ksft_print_msg("Mismatch in SSVE header size: %d != %lu\n",
				       sve->size, SVE_PT_SIZE(vq, sve->flags));
			pass = false;
		}
	}

	/* The registers might be in completely different formats! */
	if (sve->flags & SVE_PT_REGS_SVE) {
@@ -891,18 +905,11 @@ static void set_initial_values(struct test_config *config)
{
	int vq = __sve_vq_from_vl(vl_in(config));
	int sme_vq = __sve_vq_from_vl(config->sme_vl_in);
	bool sm_change;

	svcr_in = config->svcr_in;
	svcr_expected = config->svcr_expected;
	svcr_out = 0;

	if (sme_supported() &&
	    (svcr_in & SVCR_SM) != (svcr_expected & SVCR_SM))
		sm_change = true;
	else
		sm_change = false;

	fill_random(&v_in, sizeof(v_in));
	memcpy(v_expected, v_in, sizeof(v_in));
	memset(v_out, 0, sizeof(v_out));
@@ -953,11 +960,6 @@ static void set_initial_values(struct test_config *config)
	if (fpmr_supported()) {
		fill_random(&fpmr_in, sizeof(fpmr_in));
		fpmr_in &= FPMR_SAFE_BITS;

		/* Entering or exiting streaming mode clears FPMR */
		if (sm_change)
			fpmr_expected = 0;
		else
		fpmr_expected = fpmr_in;
	} else {
		fpmr_in = 0;
@@ -1195,18 +1197,8 @@ static void sve_write(pid_t child, struct test_config *config)

static bool za_write_supported(struct test_config *config)
{
	if (config->sme_vl_in != config->sme_vl_expected) {
		/* Changing the SME VL exits streaming mode. */
		if (config->svcr_expected & SVCR_SM) {
			return false;
		}
	} else {
		/* Otherwise we can't change streaming mode */
		if ((config->svcr_in & SVCR_SM) !=
		    (config->svcr_expected & SVCR_SM)) {
	if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
		return false;
		}
	}

	return true;
}
@@ -1224,10 +1216,8 @@ static void za_write_expected(struct test_config *config)
		memset(zt_expected, 0, sizeof(zt_expected));
	}

	/* Changing the SME VL flushes ZT, SVE state and exits SM */
	/* Changing the SME VL flushes ZT, SVE state */
	if (config->sme_vl_in != config->sme_vl_expected) {
		svcr_expected &= ~SVCR_SM;

		sve_vq = __sve_vq_from_vl(vl_expected(config));
		memset(z_expected, 0, __SVE_ZREGS_SIZE(sve_vq));
		memset(p_expected, 0, __SVE_PREGS_SIZE(sve_vq));