Skip to content

Commit ac4812c

Browse files
Martijn Coenengregkh
Martijn Coenen
authored andcommitted
binder: Support multiple /dev instances
Add a new module parameter 'devices', that can be used to specify the names of the binder device nodes we want to populate in /dev. Each device node has its own context manager, and is therefore logically separated from all the other device nodes. The config option CONFIG_ANDROID_BINDER_DEVICES can be used to set the default value of the parameter. This approach was favored over using IPC namespaces, mostly because we require a single process to be a part of multiple binder contexts, which seemed harder to achieve with namespaces. Cc: Greg Kroah-Hartman <[email protected]> Cc: Martijn Coenen <[email protected]> Cc: Arve Hjønnevåg <[email protected]> Cc: Amit Pundir <[email protected]> Cc: Serban Constantinescu <[email protected]> Cc: Dmitry Shmidt <[email protected]> Cc: Rom Lemarchand <[email protected]> Cc: Android Kernel Team <[email protected]> Signed-off-by: Martijn Coenen <[email protected]> [jstultz: minor checkpatch warning fix] Signed-off-by: John Stultz <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 14db318 commit ac4812c

File tree

2 files changed

+84
-11
lines changed

2 files changed

+84
-11
lines changed

drivers/android/Kconfig

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ config ANDROID_BINDER_IPC
1919
Android process, using Binder to identify, invoke and pass arguments
2020
between said processes.
2121

22+
config ANDROID_BINDER_DEVICES
23+
string "Android Binder devices"
24+
depends on ANDROID_BINDER_IPC
25+
default "binder"
26+
---help---
27+
Default value for the binder.devices parameter.
28+
29+
The binder.devices parameter is a comma-separated list of strings
30+
that specifies the names of the binder device nodes that will be
31+
created. Each binder device has its own context manager, and is
32+
therefore logically separated from the other devices.
33+
2234
config ANDROID_BINDER_IPC_32BIT
2335
bool
2436
depends on !64BIT && ANDROID_BINDER_IPC

drivers/android/binder.c

+72-11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static DEFINE_MUTEX(binder_main_lock);
5050
static DEFINE_MUTEX(binder_deferred_lock);
5151
static DEFINE_MUTEX(binder_mmap_lock);
5252

53+
static HLIST_HEAD(binder_devices);
5354
static HLIST_HEAD(binder_procs);
5455
static HLIST_HEAD(binder_deferred_list);
5556
static HLIST_HEAD(binder_dead_nodes);
@@ -113,6 +114,9 @@ module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
113114
static bool binder_debug_no_lock;
114115
module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
115116

117+
static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
118+
module_param_named(devices, binder_devices_param, charp, 0444);
119+
116120
static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
117121
static int binder_stop_on_user_error;
118122

@@ -220,9 +224,10 @@ struct binder_context {
220224
const char *name;
221225
};
222226

223-
static struct binder_context global_context = {
224-
.binder_context_mgr_uid = INVALID_UID,
225-
.name = "binder",
227+
struct binder_device {
228+
struct hlist_node hlist;
229+
struct miscdevice miscdev;
230+
struct binder_context context;
226231
};
227232

228233
struct binder_work {
@@ -3047,6 +3052,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
30473052
static int binder_open(struct inode *nodp, struct file *filp)
30483053
{
30493054
struct binder_proc *proc;
3055+
struct binder_device *binder_dev;
30503056

30513057
binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
30523058
current->group_leader->pid, current->pid);
@@ -3057,10 +3063,12 @@ static int binder_open(struct inode *nodp, struct file *filp)
30573063
get_task_struct(current);
30583064
proc->tsk = current;
30593065
proc->vma_vm_mm = current->mm;
3060-
proc->context = &global_context;
30613066
INIT_LIST_HEAD(&proc->todo);
30623067
init_waitqueue_head(&proc->wait);
30633068
proc->default_priority = task_nice(current);
3069+
binder_dev = container_of(filp->private_data, struct binder_device,
3070+
miscdev);
3071+
proc->context = &binder_dev->context;
30643072

30653073
binder_lock(__func__);
30663074

@@ -3767,26 +3775,50 @@ static const struct file_operations binder_fops = {
37673775
.release = binder_release,
37683776
};
37693777

3770-
static struct miscdevice binder_miscdev = {
3771-
.minor = MISC_DYNAMIC_MINOR,
3772-
.name = "binder",
3773-
.fops = &binder_fops
3774-
};
3775-
37763778
BINDER_DEBUG_ENTRY(state);
37773779
BINDER_DEBUG_ENTRY(stats);
37783780
BINDER_DEBUG_ENTRY(transactions);
37793781
BINDER_DEBUG_ENTRY(transaction_log);
37803782

3783+
static int __init init_binder_device(const char *name)
3784+
{
3785+
int ret;
3786+
struct binder_device *binder_device;
3787+
3788+
binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
3789+
if (!binder_device)
3790+
return -ENOMEM;
3791+
3792+
binder_device->miscdev.fops = &binder_fops;
3793+
binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
3794+
binder_device->miscdev.name = name;
3795+
3796+
binder_device->context.binder_context_mgr_uid = INVALID_UID;
3797+
binder_device->context.name = name;
3798+
3799+
ret = misc_register(&binder_device->miscdev);
3800+
if (ret < 0) {
3801+
kfree(binder_device);
3802+
return ret;
3803+
}
3804+
3805+
hlist_add_head(&binder_device->hlist, &binder_devices);
3806+
3807+
return ret;
3808+
}
3809+
37813810
static int __init binder_init(void)
37823811
{
37833812
int ret;
3813+
char *device_name, *device_names;
3814+
struct binder_device *device;
3815+
struct hlist_node *tmp;
37843816

37853817
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
37863818
if (binder_debugfs_dir_entry_root)
37873819
binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
37883820
binder_debugfs_dir_entry_root);
3789-
ret = misc_register(&binder_miscdev);
3821+
37903822
if (binder_debugfs_dir_entry_root) {
37913823
debugfs_create_file("state",
37923824
S_IRUGO,
@@ -3814,6 +3846,35 @@ static int __init binder_init(void)
38143846
&binder_transaction_log_failed,
38153847
&binder_transaction_log_fops);
38163848
}
3849+
3850+
/*
3851+
* Copy the module_parameter string, because we don't want to
3852+
* tokenize it in-place.
3853+
*/
3854+
device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL);
3855+
if (!device_names) {
3856+
ret = -ENOMEM;
3857+
goto err_alloc_device_names_failed;
3858+
}
3859+
strcpy(device_names, binder_devices_param);
3860+
3861+
while ((device_name = strsep(&device_names, ","))) {
3862+
ret = init_binder_device(device_name);
3863+
if (ret)
3864+
goto err_init_binder_device_failed;
3865+
}
3866+
3867+
return ret;
3868+
3869+
err_init_binder_device_failed:
3870+
hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) {
3871+
misc_deregister(&device->miscdev);
3872+
hlist_del(&device->hlist);
3873+
kfree(device);
3874+
}
3875+
err_alloc_device_names_failed:
3876+
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
3877+
38173878
return ret;
38183879
}
38193880

0 commit comments

Comments
 (0)