Allowing querying whether libc support rseq
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 31 Oct 2022 14:45:32 +0000 (10:45 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 31 Oct 2022 14:45:32 +0000 (10:45 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I903ca816e3ebbaf9c4fff55431b50f58d0090a8c

include/rseq/rseq.h
src/rseq.c
tests/basic_percpu_ops_test.c
tests/basic_test.c
tests/param_test.c

index ac5078232b03bee766aabd4e960e0ce60c121303..95146d9697cfb70bfe9e715a14c310dbcd0e621b 100644 (file)
@@ -141,7 +141,15 @@ int rseq_unregister_current_thread(void);
  */
 int32_t rseq_fallback_current_cpu(void);
 
-int rseq_available(void);
+enum rseq_available_query {
+       RSEQ_AVAILABLE_QUERY_KERNEL = 0,
+       RSEQ_AVAILABLE_QUERY_LIBC = 1,
+};
+
+/*
+ * Returns true if rseq is supported.
+ */
+bool rseq_available(unsigned int query);
 
 /*
  * Values returned can be either the current CPU number, -1 (rseq is
index 7fafc08b17b7cc396194f82ab1d8d50f6f89d77f..25386a98830ca55fb51cda5caa45c377825b968b 100644 (file)
@@ -59,21 +59,31 @@ static int sys_rseq(struct rseq_abi *rseq_abi, uint32_t rseq_len,
        return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
 }
 
-int rseq_available(void)
+bool rseq_available(unsigned int query)
 {
        int rc;
 
-       rc = sys_rseq(NULL, 0, 0, 0);
-       if (rc != -1)
-               abort();
-       switch (errno) {
-       case ENOSYS:
-               return 0;
-       case EINVAL:
-               return 1;
+       switch (query) {
+       case RSEQ_AVAILABLE_QUERY_KERNEL:
+               rc = sys_rseq(NULL, 0, 0, 0);
+               if (rc != -1)
+                       abort();
+               switch (errno) {
+               case ENOSYS:
+               default:
+                       break;
+               case EINVAL:
+                       return true;
+               }
+               break;
+       case RSEQ_AVAILABLE_QUERY_LIBC:
+               if (rseq_size && !rseq_ownership)
+                       return true;
+               break;
        default:
-               abort();
+               break;
        }
+       return false;
 }
 
 int rseq_register_current_thread(void)
@@ -119,7 +129,7 @@ void rseq_init(void)
                rseq_flags = *libc_rseq_flags_p;
                return;
        }
-       if (!rseq_available())
+       if (!rseq_available(RSEQ_AVAILABLE_QUERY_KERNEL))
                return;
        rseq_ownership = 1;
        rseq_offset = (void *)&__rseq_abi - rseq_thread_pointer();
index 23d733cd137d0cc041d8c9ba51332734dddef187..3d4334ecbf1867c1e420a5bdf8bcd51d0a90d63e 100644 (file)
@@ -306,7 +306,7 @@ int main(void)
 {
        plan_tests(NR_TESTS);
 
-       if (!rseq_available()) {
+       if (!rseq_available(RSEQ_AVAILABLE_QUERY_KERNEL)) {
                skip(NR_TESTS, "The rseq syscall is unavailable");
                goto end;
        }
index 2cf3f95c868777ab9e3f06d256468964bc6a2fe7..e0c2de0be59e595d5513d4769e9210c8efb89fc5 100644 (file)
@@ -52,7 +52,7 @@ int main(void)
        /*
         * Skip all tests if the rseq syscall is unavailable
         */
-       if (rseq_available()) {
+       if (rseq_available(RSEQ_AVAILABLE_QUERY_KERNEL)) {
                plan_no_plan();
        } else {
                plan_skip_all("The rseq syscall is unavailable");
index bea725be46dbab8871f3d787090a68c02835ec36..82cf68fb147f3a69a73c38da548d726691f68f25 100644 (file)
@@ -1571,7 +1571,7 @@ int main(int argc, char **argv)
                        opt_mb = 1;
                        break;
                case 'c':
-                       if (rseq_available()) {
+                       if (rseq_available(RSEQ_AVAILABLE_QUERY_KERNEL)) {
                                printf_verbose("The rseq syscall is available.\n");
                                goto end;
                        } else {
This page took 0.030042 seconds and 4 git commands to generate.