aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2017-02-03 17:40:48 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-10 10:00:01 -0500
commitac4812c5ffbb88dd3280a6dacd39fcb73e077fe4 (patch)
tree01fd627d2ae32289d06dd3af5bbc2d924100bfe0
parent14db31814a9a21cf343e71d6773e7683a5b3f64d (diff)
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 <gregkh@linuxfoundation.org> Cc: Martijn Coenen <maco@google.com> Cc: Arve Hjønnevåg <arve@android.com> Cc: Amit Pundir <amit.pundir@linaro.org> Cc: Serban Constantinescu <serban.constantinescu@arm.com> Cc: Dmitry Shmidt <dimitrysh@google.com> Cc: Rom Lemarchand <romlem@google.com> Cc: Android Kernel Team <kernel-team@android.com> Signed-off-by: Martijn Coenen <maco@google.com> [jstultz: minor checkpatch warning fix] Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/android/Kconfig12
-rw-r--r--drivers/android/binder.c83
2 files changed, 84 insertions, 11 deletions
diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig
index bdfc6c6f4f5a..a82fc022d34b 100644
--- a/drivers/android/Kconfig
+++ b/drivers/android/Kconfig
@@ -19,6 +19,18 @@ config ANDROID_BINDER_IPC
19 Android process, using Binder to identify, invoke and pass arguments 19 Android process, using Binder to identify, invoke and pass arguments
20 between said processes. 20 between said processes.
21 21
22config 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
22config ANDROID_BINDER_IPC_32BIT 34config ANDROID_BINDER_IPC_32BIT
23 bool 35 bool
24 depends on !64BIT && ANDROID_BINDER_IPC 36 depends on !64BIT && ANDROID_BINDER_IPC
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 97e4ed424932..705caf55005e 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -50,6 +50,7 @@ static DEFINE_MUTEX(binder_main_lock);
50static DEFINE_MUTEX(binder_deferred_lock); 50static DEFINE_MUTEX(binder_deferred_lock);
51static DEFINE_MUTEX(binder_mmap_lock); 51static DEFINE_MUTEX(binder_mmap_lock);
52 52
53static HLIST_HEAD(binder_devices);
53static HLIST_HEAD(binder_procs); 54static HLIST_HEAD(binder_procs);
54static HLIST_HEAD(binder_deferred_list); 55static HLIST_HEAD(binder_deferred_list);
55static HLIST_HEAD(binder_dead_nodes); 56static HLIST_HEAD(binder_dead_nodes);
@@ -113,6 +114,9 @@ module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
113static bool binder_debug_no_lock; 114static bool binder_debug_no_lock;
114module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO); 115module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
115 116
117static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
118module_param_named(devices, binder_devices_param, charp, 0444);
119
116static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); 120static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
117static int binder_stop_on_user_error; 121static int binder_stop_on_user_error;
118 122
@@ -220,9 +224,10 @@ struct binder_context {
220 const char *name; 224 const char *name;
221}; 225};
222 226
223static struct binder_context global_context = { 227struct binder_device {
224 .binder_context_mgr_uid = INVALID_UID, 228 struct hlist_node hlist;
225 .name = "binder", 229 struct miscdevice miscdev;
230 struct binder_context context;
226}; 231};
227 232
228struct binder_work { 233struct binder_work {
@@ -3047,6 +3052,7 @@ err_bad_arg:
3047static int binder_open(struct inode *nodp, struct file *filp) 3052static int binder_open(struct inode *nodp, struct file *filp)
3048{ 3053{
3049 struct binder_proc *proc; 3054 struct binder_proc *proc;
3055 struct binder_device *binder_dev;
3050 3056
3051 binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", 3057 binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
3052 current->group_leader->pid, current->pid); 3058 current->group_leader->pid, current->pid);
@@ -3057,10 +3063,12 @@ static int binder_open(struct inode *nodp, struct file *filp)
3057 get_task_struct(current); 3063 get_task_struct(current);
3058 proc->tsk = current; 3064 proc->tsk = current;
3059 proc->vma_vm_mm = current->mm; 3065 proc->vma_vm_mm = current->mm;
3060 proc->context = &global_context;
3061 INIT_LIST_HEAD(&proc->todo); 3066 INIT_LIST_HEAD(&proc->todo);
3062 init_waitqueue_head(&proc->wait); 3067 init_waitqueue_head(&proc->wait);
3063 proc->default_priority = task_nice(current); 3068 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;
3064 3072
3065 binder_lock(__func__); 3073 binder_lock(__func__);
3066 3074
@@ -3767,26 +3775,50 @@ static const struct file_operations binder_fops = {
3767 .release = binder_release, 3775 .release = binder_release,
3768}; 3776};
3769 3777
3770static struct miscdevice binder_miscdev = {
3771 .minor = MISC_DYNAMIC_MINOR,
3772 .name = "binder",
3773 .fops = &binder_fops
3774};
3775
3776BINDER_DEBUG_ENTRY(state); 3778BINDER_DEBUG_ENTRY(state);
3777BINDER_DEBUG_ENTRY(stats); 3779BINDER_DEBUG_ENTRY(stats);
3778BINDER_DEBUG_ENTRY(transactions); 3780BINDER_DEBUG_ENTRY(transactions);
3779BINDER_DEBUG_ENTRY(transaction_log); 3781BINDER_DEBUG_ENTRY(transaction_log);
3780 3782
3783static 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
3781static int __init binder_init(void) 3810static int __init binder_init(void)
3782{ 3811{
3783 int ret; 3812 int ret;
3813 char *device_name, *device_names;
3814 struct binder_device *device;
3815 struct hlist_node *tmp;
3784 3816
3785 binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); 3817 binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
3786 if (binder_debugfs_dir_entry_root) 3818 if (binder_debugfs_dir_entry_root)
3787 binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", 3819 binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
3788 binder_debugfs_dir_entry_root); 3820 binder_debugfs_dir_entry_root);
3789 ret = misc_register(&binder_miscdev); 3821
3790 if (binder_debugfs_dir_entry_root) { 3822 if (binder_debugfs_dir_entry_root) {
3791 debugfs_create_file("state", 3823 debugfs_create_file("state",
3792 S_IRUGO, 3824 S_IRUGO,
@@ -3814,6 +3846,35 @@ static int __init binder_init(void)
3814 &binder_transaction_log_failed, 3846 &binder_transaction_log_failed,
3815 &binder_transaction_log_fops); 3847 &binder_transaction_log_fops);
3816 } 3848 }
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
3869err_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 }
3875err_alloc_device_names_failed:
3876 debugfs_remove_recursive(binder_debugfs_dir_entry_root);
3877
3817 return ret; 3878 return ret;
3818} 3879}
3819 3880