Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,7 @@ set(BASIC_TESTS
sysinfo
syslog
arm/tagged_addr_ctrl
arm/sve_vl
tgkill
thread_yield
timer
Expand Down
11 changes: 11 additions & 0 deletions src/kernel_supplement.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,17 @@ enum {
#define BLKGETNRZONES _IOR(0x12, 133, __u32)
#endif

// New in the 4.15 kernel
#ifndef PR_SVE_SET_VL
#define PR_SVE_SET_VL 50
#endif
#ifndef PR_SVE_GET_VL
#define PR_SVE_GET_VL 51
#endif
#ifndef PR_SVE_VL_LEN_MASK
#define PR_SVE_VL_LEN_MASK 0xffff
#endif

// New in the 5.4 kernel
#ifndef PR_SET_TAGGED_ADDR_CTRL
#define PR_SET_TAGGED_ADDR_CTRL 55
Expand Down
2 changes: 2 additions & 0 deletions src/record_syscall.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4792,6 +4792,8 @@ static Switchable rec_prepare_syscall_arch(RecordTask* t,
case PR_GET_SECUREBITS:
case PR_GET_TAGGED_ADDR_CTRL:
case PR_GET_MDWE:
case PR_SVE_GET_VL:
case PR_SVE_SET_VL:
break;

case PR_SET_TAGGED_ADDR_CTRL:
Expand Down
8 changes: 5 additions & 3 deletions src/replay_syscall.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1215,11 +1215,13 @@ static void rep_process_syscall_arch(ReplayTask* t, ReplayTraceStep* step,
case Arch::prctl: {
auto arg1 = t->regs().arg1();
if (sys == Arch::prctl &&
(Arch::arch() != aarch64 || arg1 != PR_SET_SPECULATION_CTRL) &&
(Arch::arch() != aarch64 || (arg1 != PR_SET_SPECULATION_CTRL &&
arg1 != PR_SVE_SET_VL)) &&
((unsigned long)t->regs().arg1() != PR_SET_VMA || trace_regs.syscall_result_signed() == -EINVAL)) {
// On aarch64 PR_SET_SPECULATION_CTRL affects the pstate
// register during the system call, so we need to replay
// it, otherwise we'll get a mismatch there.
// register during the system call, and PR_SVE_SET_VL affects
// the SVE vector length, so we need to replay them, otherwise
// we'll get a mismatch.
// We want to replay PR_SET_VMA as well, but not if it originally failed
// with EINVAL because the recording kernel may not have supported it.
return;
Expand Down
40 changes: 40 additions & 0 deletions src/test/arm/sve_vl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */

#include "util.h"

#include <sys/prctl.h>
#include <errno.h>

#ifndef PR_SVE_SET_VL
#define PR_SVE_SET_VL 50
#endif
#ifndef PR_SVE_GET_VL
#define PR_SVE_GET_VL 51
#endif
#ifndef PR_SVE_VL_LEN_MASK
#define PR_SVE_VL_LEN_MASK 0xffff
#endif

int main(void) {
int vl = prctl(PR_SVE_GET_VL);
/* Skip on hardware without SVE support. */
if (vl == -1 && errno == EINVAL) {
atomic_puts("EXIT-SUCCESS");
return 0;
}
test_assert(vl > 0);
int len = vl & PR_SVE_VL_LEN_MASK;
test_assert(len > 0);

/* Set the same vector length we already have. */
int ret = prctl(PR_SVE_SET_VL, len);
test_assert(ret >= 0);
test_assert((ret & PR_SVE_VL_LEN_MASK) == len);

/* Confirm GET still returns the same value. */
int vl2 = prctl(PR_SVE_GET_VL);
test_assert((vl2 & PR_SVE_VL_LEN_MASK) == len);

atomic_puts("EXIT-SUCCESS");
return 0;
}
Loading