summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--test/syscalls/linux/BUILD1
-rw-r--r--test/syscalls/linux/rseq.cc6
-rw-r--r--test/syscalls/linux/rseq/rseq.cc87
-rw-r--r--test/syscalls/linux/rseq/test.h28
4 files changed, 68 insertions, 54 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD
index bd1d9584a..3009f5cad 100644
--- a/test/syscalls/linux/BUILD
+++ b/test/syscalls/linux/BUILD
@@ -1972,6 +1972,7 @@ cc_binary(
gtest,
"//test/util:logging",
"//test/util:multiprocess_util",
+ "//test/util:posix_error",
"//test/util:test_main",
"//test/util:test_util",
],
diff --git a/test/syscalls/linux/rseq.cc b/test/syscalls/linux/rseq.cc
index 4bfb1ff56..94f9154a0 100644
--- a/test/syscalls/linux/rseq.cc
+++ b/test/syscalls/linux/rseq.cc
@@ -24,6 +24,7 @@
#include "test/syscalls/linux/rseq/uapi.h"
#include "test/util/logging.h"
#include "test/util/multiprocess_util.h"
+#include "test/util/posix_error.h"
#include "test/util/test_util.h"
namespace gvisor {
@@ -31,6 +32,9 @@ namespace testing {
namespace {
+using ::testing::AnyOf;
+using ::testing::Eq;
+
// Syscall test for rseq (restartable sequences).
//
// We must be very careful about how these tests are written. Each thread may
@@ -98,7 +102,7 @@ void RunChildTest(std::string test_case, int want_status) {
int status = 0;
ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
- ASSERT_EQ(status, want_status);
+ ASSERT_THAT(status, AnyOf(Eq(want_status), Eq(128 + want_status)));
}
// Test that rseq must be aligned.
diff --git a/test/syscalls/linux/rseq/rseq.cc b/test/syscalls/linux/rseq/rseq.cc
index f036db26d..6f5d38bba 100644
--- a/test/syscalls/linux/rseq/rseq.cc
+++ b/test/syscalls/linux/rseq/rseq.cc
@@ -74,84 +74,95 @@ int TestUnaligned() {
// Sanity test that registration works.
int TestRegister() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
return 0;
-};
+}
// Registration can't be done twice.
int TestDoubleRegister() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != EBUSY) {
+ ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != EBUSY) {
return 1;
}
return 0;
-};
+}
// Registration can be done again after unregister.
int TestRegisterUnregister() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != 0) {
+
+ int ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
- if (int ret = sys_rseq(&r, sizeof(r), kRseqFlagUnregister, 0);
- sys_errno(ret) != 0) {
+ ret = sys_rseq(&r, sizeof(r), kRseqFlagUnregister, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != 0) {
+ ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
return 0;
-};
+}
// The pointer to rseq must match on register/unregister.
int TestUnregisterDifferentPtr() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != 0) {
+
+ int ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
struct rseq r2 = {};
- if (int ret = sys_rseq(&r2, sizeof(r2), kRseqFlagUnregister, 0);
- sys_errno(ret) != EINVAL) {
+
+ ret = sys_rseq(&r2, sizeof(r2), kRseqFlagUnregister, 0);
+ if (sys_errno(ret) != EINVAL) {
return 1;
}
return 0;
-};
+}
// The signature must match on register/unregister.
int TestUnregisterDifferentSignature() {
constexpr int kSignature = 0;
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kSignature); sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kSignature);
+ if (sys_errno(ret) != 0) {
return 1;
}
- if (int ret = sys_rseq(&r, sizeof(r), kRseqFlagUnregister, kSignature + 1);
- sys_errno(ret) != EPERM) {
+ ret = sys_rseq(&r, sizeof(r), kRseqFlagUnregister, kSignature + 1);
+ if (sys_errno(ret) != EPERM) {
return 1;
}
return 0;
-};
+}
// The CPU ID is initialized.
int TestCPU() {
struct rseq r = {};
r.cpu_id = kRseqCPUIDUninitialized;
- if (int ret = sys_rseq(&r, sizeof(r), 0, 0); sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, 0);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -163,13 +174,13 @@ int TestCPU() {
}
return 0;
-};
+}
// Critical section is eventually aborted.
int TestAbort() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
- sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -185,13 +196,13 @@ int TestAbort() {
rseq_loop(&r, &cs);
return 0;
-};
+}
// Abort may be before the critical section.
int TestAbortBefore() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
- sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -207,13 +218,13 @@ int TestAbortBefore() {
rseq_loop(&r, &cs);
return 0;
-};
+}
// Signature must match.
int TestAbortSignature() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature + 1);
- sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature + 1);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -229,13 +240,13 @@ int TestAbortSignature() {
rseq_loop(&r, &cs);
return 1;
-};
+}
// Abort must not be in the critical section.
int TestAbortPreCommit() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature + 1);
- sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature + 1);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -251,13 +262,13 @@ int TestAbortPreCommit() {
rseq_loop(&r, &cs);
return 1;
-};
+}
// rseq.rseq_cs is cleared on abort.
int TestAbortClearsCS() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
- sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -277,13 +288,13 @@ int TestAbortClearsCS() {
}
return 0;
-};
+}
// rseq.rseq_cs is cleared on abort outside of critical section.
int TestInvalidAbortClearsCS() {
struct rseq r = {};
- if (int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
- sys_errno(ret) != 0) {
+ int ret = sys_rseq(&r, sizeof(r), 0, kRseqSignature);
+ if (sys_errno(ret) != 0) {
return 1;
}
@@ -306,7 +317,7 @@ int TestInvalidAbortClearsCS() {
}
return 0;
-};
+}
// Exit codes:
// 0 - Pass
diff --git a/test/syscalls/linux/rseq/test.h b/test/syscalls/linux/rseq/test.h
index 3b7bb74b1..ff0dd6e48 100644
--- a/test/syscalls/linux/rseq/test.h
+++ b/test/syscalls/linux/rseq/test.h
@@ -20,22 +20,20 @@ namespace testing {
// Test cases supported by rseq binary.
-inline constexpr char kRseqTestUnaligned[] = "unaligned";
-inline constexpr char kRseqTestRegister[] = "register";
-inline constexpr char kRseqTestDoubleRegister[] = "double-register";
-inline constexpr char kRseqTestRegisterUnregister[] = "register-unregister";
-inline constexpr char kRseqTestUnregisterDifferentPtr[] =
- "unregister-different-ptr";
-inline constexpr char kRseqTestUnregisterDifferentSignature[] =
+constexpr char kRseqTestUnaligned[] = "unaligned";
+constexpr char kRseqTestRegister[] = "register";
+constexpr char kRseqTestDoubleRegister[] = "double-register";
+constexpr char kRseqTestRegisterUnregister[] = "register-unregister";
+constexpr char kRseqTestUnregisterDifferentPtr[] = "unregister-different-ptr";
+constexpr char kRseqTestUnregisterDifferentSignature[] =
"unregister-different-signature";
-inline constexpr char kRseqTestCPU[] = "cpu";
-inline constexpr char kRseqTestAbort[] = "abort";
-inline constexpr char kRseqTestAbortBefore[] = "abort-before";
-inline constexpr char kRseqTestAbortSignature[] = "abort-signature";
-inline constexpr char kRseqTestAbortPreCommit[] = "abort-precommit";
-inline constexpr char kRseqTestAbortClearsCS[] = "abort-clears-cs";
-inline constexpr char kRseqTestInvalidAbortClearsCS[] =
- "invalid-abort-clears-cs";
+constexpr char kRseqTestCPU[] = "cpu";
+constexpr char kRseqTestAbort[] = "abort";
+constexpr char kRseqTestAbortBefore[] = "abort-before";
+constexpr char kRseqTestAbortSignature[] = "abort-signature";
+constexpr char kRseqTestAbortPreCommit[] = "abort-precommit";
+constexpr char kRseqTestAbortClearsCS[] = "abort-clears-cs";
+constexpr char kRseqTestInvalidAbortClearsCS[] = "invalid-abort-clears-cs";
} // namespace testing
} // namespace gvisor