Load modules from _16K dir when running on 16K kernel

Test: th
Bug: 293313353
Change-Id: Ie58e57174545e4def5ebc33ac29f1adb12bf06a6
diff --git a/toolbox/modprobe.cpp b/toolbox/modprobe.cpp
index 45dd9b8..b0e76ea 100644
--- a/toolbox/modprobe.cpp
+++ b/toolbox/modprobe.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <ctype.h>
+#include <fcntl.h>
 #include <getopt.h>
 #include <stdlib.h>
 
@@ -27,6 +28,7 @@
 #include <modprobe/modprobe.h>
 
 #include <sys/utsname.h>
+#include <unistd.h>
 
 namespace {
 
@@ -105,6 +107,11 @@
     return 0;
 }
 
+std::string GetPageSizeSuffix() {
+    static const size_t page_size = sysconf(_SC_PAGE_SIZE);
+    return android::base::StringPrintf("_%zuk", page_size / 1024);
+}
+
 }  // anonymous namespace
 
 extern "C" int modprobe_main(int argc, char** argv) {
@@ -233,6 +240,19 @@
         // Allow modules to be directly inside /lib/modules
         mod_dirs.emplace_back(LIB_MODULES_PREFIX);
     }
+    if (getpagesize() != 4096) {
+        struct utsname uts {};
+        if (uname(&uts)) {
+            PLOG(FATAL) << "Failed to get kernel version";
+        }
+        const auto module_dir = android::base::StringPrintf("/lib/modules/%s%s", uts.release,
+                                                            GetPageSizeSuffix().c_str());
+        struct stat st {};
+        if (stat(module_dir.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
+            mod_dirs.clear();
+            mod_dirs.emplace_back(module_dir);
+        }
+    }
 
     LOG(DEBUG) << "mode is " << mode;
     LOG(DEBUG) << "mod_dirs is: " << android::base::Join(mod_dirs, " ");