Reland "Depend only on userfaultfd's SIGBUS feature to use it"

This reverts commit fab50833f1787848002bb96a6033f08a8c5212d3.

Reason for revert: Fix the features requested in uffd API ioctl.

Bug: 160737021
Bug: 291694105
Bug: 292449808
Test: On a host kernel < 5.14 run ART_USE_READ_BARRIER=false
art/test/testrunner/testunner.py --host

Change-Id: I41be8f1d080043558ac7125980fef599dadeb6d5
diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc
index 05ca803..85e6a5f 100644
--- a/runtime/gc/collector/mark_compact.cc
+++ b/runtime/gc/collector/mark_compact.cc
@@ -116,17 +116,13 @@
 static constexpr uint64_t kUffdFeaturesForMinorFault =
     UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_MINOR_SHMEM;
 static constexpr uint64_t kUffdFeaturesForSigbus = UFFD_FEATURE_SIGBUS;
+
 // We consider SIGBUS feature necessary to enable this GC as it's superior than
 // threading-based implementation for janks. However, since we have the latter
 // already implemented, for testing purposes, we allow choosing either of the
 // two at boot time in the constructor below.
-// Note that having minor-fault feature implies having SIGBUS feature as the
-// latter was introduced earlier than the former. In other words, having
-// minor-fault feature implies having SIGBUS. We still want minor-fault to be
-// available for making jit-code-cache updation concurrent, which uses shmem.
-static constexpr uint64_t kUffdFeaturesRequired =
-    kUffdFeaturesForMinorFault | kUffdFeaturesForSigbus;
-
+// We may want minor-fault in future to be available for making jit-code-cache
+// updation concurrent, which uses shmem.
 bool KernelSupportsUffd() {
 #ifdef __linux__
   if (gHaveMremapDontunmap) {
@@ -144,8 +140,8 @@
       CHECK_EQ(ioctl(fd, UFFDIO_API, &api), 0) << "ioctl_userfaultfd : API:" << strerror(errno);
       gUffdFeatures = api.features;
       close(fd);
-      // Allow this GC to be used only if minor-fault and sigbus feature is available.
-      return (api.features & kUffdFeaturesRequired) == kUffdFeaturesRequired;
+      // Minimum we need is sigbus feature for using userfaultfd.
+      return (api.features & kUffdFeaturesForSigbus) == kUffdFeaturesForSigbus;
     }
   }
 #endif
@@ -344,8 +340,21 @@
       } else {
         DCHECK(IsValidFd(uffd_));
         // Initialize uffd with the features which are required and available.
-        struct uffdio_api api = {.api = UFFD_API, .features = gUffdFeatures, .ioctls = 0};
-        api.features &= use_uffd_sigbus_ ? kUffdFeaturesRequired : kUffdFeaturesForMinorFault;
+        // Using private anonymous mapping in threading mode is the default,
+        // for which we don't need to ask for any features. Note: this mode
+        // is not used in production.
+        struct uffdio_api api = {.api = UFFD_API, .features = 0, .ioctls = 0};
+        if (use_uffd_sigbus_) {
+          // We should add SIGBUS feature only if we plan on using it as
+          // requesting it here will mean threading mode will not work.
+          CHECK_EQ(gUffdFeatures & kUffdFeaturesForSigbus, kUffdFeaturesForSigbus);
+          api.features |= kUffdFeaturesForSigbus;
+        }
+        if (uffd_minor_fault_supported_) {
+          // NOTE: This option is currently disabled.
+          CHECK_EQ(gUffdFeatures & kUffdFeaturesForMinorFault, kUffdFeaturesForMinorFault);
+          api.features |= kUffdFeaturesForMinorFault;
+        }
         CHECK_EQ(ioctl(uffd_, UFFDIO_API, &api), 0)
             << "ioctl_userfaultfd: API: " << strerror(errno);
       }
@@ -366,7 +375,7 @@
 
 static bool IsSigbusFeatureAvailable() {
   MarkCompact::GetUffdAndMinorFault();
-  return gUffdFeatures & UFFD_FEATURE_SIGBUS;
+  return (gUffdFeatures & kUffdFeaturesForSigbus) == kUffdFeaturesForSigbus;
 }
 
 MarkCompact::MarkCompact(Heap* heap)