From ac5119631f79c775bec2548fd3db7e48e6e28e4c Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 22 Jan 2025 14:15:19 +0000 Subject: [PATCH] ANDROID: add binder.impl kernel parameter This introduces a new binder.impl parameter for the kernel commandline. The parameter controls whether the device should use the C or Rust implementation of Binder. This patch does not contain the Rust portion of this logic as Rust Binder will be a DDK module for this kernel version. binder_use_rust is exported so that the module can access it when loaded to check whether the driver should be enabled. Note that Rust Binder must be a vendor-boot module for the init sequence to work right. The parameter has already been hooked up to Android userspace. This means that the commands adb shell setprop kcmdline.binder c adb shell setprop kcmdline.binder rust will cause Android to set binder.impl on the kernel commandline next time the phone is rebooted. Since it's infeasible to change the Binder driver used by a running system, this parameter cannot be changed once a Binder driver is loaded. Bug: 388786466 Change-Id: I2ea11cd4110ee86f88ca606c55bb9cc2924d576a Signed-off-by: Alice Ryhl Signed-off-by: Carlos Llamas --- drivers/android/binder.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 4d3df00d368c..63e56c95f79c 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -7157,6 +7157,34 @@ const struct binder_debugfs_entry binder_debugfs_entries[] = { {} /* terminator */ }; +bool binder_use_rust; +EXPORT_SYMBOL_GPL(binder_use_rust); + +static int binder_impl_param_set(const char *buffer, const struct kernel_param *kp) +{ + if (!strcmp(buffer, "rust")) + binder_use_rust = true; + else if (!strcmp(buffer, "c")) + binder_use_rust = false; + else + return -EINVAL; + + return 0; +} + +static int binder_impl_param_get(char *buffer, const struct kernel_param *kp) +{ + /* The buffer is 4k bytes, so this will not overflow. */ + return sprintf(buffer, "%s\n", binder_use_rust ? "rust" : "c"); +} + +static const struct kernel_param_ops binder_impl_param_ops = { + .set = binder_impl_param_set, + .get = binder_impl_param_get, +}; + +module_param_cb(impl, &binder_impl_param_ops, NULL, 0444); + static int __init init_binder_device(const char *name) { int ret; @@ -7195,6 +7223,9 @@ static int __init binder_init(void) char *device_names = NULL; const struct binder_debugfs_entry *db_entry; + if (binder_use_rust) + return 0; + ret = binder_alloc_shrinker_init(); if (ret) return ret;