Support initializing ProcessState with custom binder window size.

While the binder kernel driver allocates memory lazily, using
a 1MB binder window does mean 1MB of vmalloc address space is lost.
This can be a problem on 32-bit devices, where the address space
available for vmalloc is very limited.

This change allows initializing ProcessState with a custom mmap
size. Note that this API must be called as early as possible in
the process, before any other hwbinder (API) calls or HIDL calls
have been made.

c/p from 32507d340df9c654ae3129ce666c6a2b5d708719

Bug: 129785390
Test: verify kernel output after calling API
Change-Id: I62cdbcb4ffcad1a6d7b3eeae5560eb3e5e602515
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 3798b61..1bc28f2 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -40,7 +40,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
+#define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
 #define DEFAULT_MAX_BINDER_THREADS 15
 
 #ifdef __ANDROID_VNDK__
@@ -77,7 +77,13 @@
     if (gProcess != nullptr) {
         return gProcess;
     }
-    gProcess = new ProcessState(kDefaultDriver);
+    gProcess = new ProcessState(kDefaultDriver, DEFAULT_BINDER_VM_SIZE);
+    return gProcess;
+}
+
+sp<ProcessState> ProcessState::selfOrNull()
+{
+    Mutex::Autolock _l(gProcessMutex);
     return gProcess;
 }
 
@@ -98,13 +104,19 @@
         driver = "/dev/binder";
     }
 
-    gProcess = new ProcessState(driver);
+    gProcess = new ProcessState(driver, DEFAULT_BINDER_VM_SIZE);
     return gProcess;
 }
 
-sp<ProcessState> ProcessState::selfOrNull()
-{
+sp<ProcessState> ProcessState::initWithMmapSize(size_t mmap_size) {
     Mutex::Autolock _l(gProcessMutex);
+    if (gProcess != nullptr) {
+        LOG_ALWAYS_FATAL_IF(mmap_size != gProcess->getMmapSize(),
+                "ProcessState already initialized with a different mmap size.");
+        return gProcess;
+    }
+
+    gProcess = new ProcessState(kDefaultDriver, mmap_size);
     return gProcess;
 }
 
@@ -234,6 +246,10 @@
     return count;
 }
 
+size_t ProcessState::getMmapSize() {
+    return mMmapSize;
+}
+
 void ProcessState::setCallRestriction(CallRestriction restriction) {
     LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull(), "Call restrictions must be set before the threadpool is started.");
 
@@ -418,7 +434,7 @@
     return fd;
 }
 
-ProcessState::ProcessState(const char *driver)
+ProcessState::ProcessState(const char *driver, size_t mmap_size)
     : mDriverName(String8(driver))
     , mDriverFD(open_driver(driver))
     , mVMStart(MAP_FAILED)
@@ -432,11 +448,12 @@
     , mBinderContextUserData(nullptr)
     , mThreadPoolStarted(false)
     , mThreadPoolSeq(1)
+    , mMmapSize(mmap_size)
     , mCallRestriction(CallRestriction::NONE)
 {
     if (mDriverFD >= 0) {
         // mmap the binder, providing a chunk of virtual address space to receive transactions.
-        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
+        mVMStart = mmap(nullptr, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
         if (mVMStart == MAP_FAILED) {
             // *sigh*
             ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
@@ -453,7 +470,7 @@
 {
     if (mDriverFD >= 0) {
         if (mVMStart != MAP_FAILED) {
-            munmap(mVMStart, BINDER_VM_SIZE);
+            munmap(mVMStart, mMmapSize);
         }
         close(mDriverFD);
     }