[llvm] [llvm-exegesis][AArch64] Check for PAC keys before disabling them (PR #138643)

Anatoly Trosinenko via llvm-commits llvm-commits at lists.llvm.org
Mon May 12 02:19:02 PDT 2025


================
@@ -207,15 +213,38 @@ class ExegesisAArch64Target : public ExegesisTarget {
 
     if (isPointerAuth(Opcode)) {
 #if defined(__aarch64__) && defined(__linux__)
+
+      // For some systems with existing PAC keys set, it is better to
+      // check the existing state of the key before setting it.
+      // For systems without PAC, this is a No-op but with PAC, it is
+      // safer to check the existing key state and then disable/enable them.
+      // Hence the guard for switching.
+      errno = 0;
+      unsigned long PacKeys = prctl_wrapper(PR_PAC_GET_ENABLED_KEYS,
+                                            0,  // unused
+                                            0,  // unused
+                                            0,  // unused
+                                            0); // unused
+      if ((long)PacKeys < 0) {
+        if (errno == EINVAL) {
+          return "PAuth not supported on this system";
+        }
+        return "Failed to get PAC key status";
+      }
+
       // Disable all PAC keys. Note that while we expect the measurements to
       // be the same with PAC keys disabled, they could potentially be lower
       // since authentication checks are bypassed.
-      if (prctl(PR_PAC_SET_ENABLED_KEYS,
-                PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY |
-                    PR_PAC_APDBKEY, // all keys
-                0,                  // disable all
-                0, 0) < 0) {
-        return "Failed to disable PAC keys";
+      if ((long)PacKeys != 0) {
+        if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS,
+                          PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY |
+                              PR_PAC_APDBKEY, // all keys
+                          0,                  // disable all
+                          0,                  // unused
+                          0)                  // unused
+            < 0) {
----------------
atrosinenko wrote:

Aside from dropping the unused arguments, what do you think on defining a few named variables for the sake of readability, something like
```suggestion
        // Operate on all keys.
        const long KeysToControl = 
            PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY;
        // Disable all.
        const long EnabledBitMask = 0;
        if (prctl_wrapper(PR_PAC_SET_ENABLED_KEYS, KeysToControl, 
                          EnabledBitMask) < 0) {
```
If I understand [kernel sources](https://github.com/torvalds/linux/blob/d76bb1ebb5587f66b0f8b8099bfbb44722bc08b3/arch/arm64/kernel/pointer_auth.c#L67) correctly, this `prctl` operation accepts two arguments and **both** are bit masks, which was a bit surprising to me. As PAuth-related `prctl` operations seem to be less documented compared to more common system calls, let's provide a bit more explanation here :)

https://github.com/llvm/llvm-project/pull/138643


More information about the llvm-commits mailing list