mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 04:28:10 -04:00
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
This commit is contained in:
@@ -21,6 +21,8 @@ CFLAGS += $(KHDR_INCLUDES)
|
||||
|
||||
CFLAGS += -I$(top_srcdir)/tools/include
|
||||
|
||||
OUTPUT ?= $(CURDIR)
|
||||
|
||||
export CFLAGS
|
||||
export top_srcdir
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -439,10 +439,17 @@ static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
|
||||
pass = false;
|
||||
}
|
||||
|
||||
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;
|
||||
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! */
|
||||
@@ -515,10 +522,17 @@ static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
|
||||
pass = false;
|
||||
}
|
||||
|
||||
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;
|
||||
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! */
|
||||
@@ -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,12 +960,7 @@ 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;
|
||||
fpmr_expected = fpmr_in;
|
||||
} else {
|
||||
fpmr_in = 0;
|
||||
fpmr_expected = 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)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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));
|
||||
|
||||
Reference in New Issue
Block a user