Commit ac4812c5ffbb88dd3280a6dacd39fcb73e077fe4

Authored by Martijn Coenen
Committed by Greg Kroah-Hartman
1 parent 14db31814a

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>

Showing 2 changed files with 84 additions and 11 deletions Side-by-side Diff

drivers/android/Kconfig
... ... @@ -19,6 +19,18 @@
19 19 Android process, using Binder to identify, invoke and pass arguments
20 20 between said processes.
21 21  
  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 +
22 34 config ANDROID_BINDER_IPC_32BIT
23 35 bool
24 36 depends on !64BIT && ANDROID_BINDER_IPC
drivers/android/binder.c
... ... @@ -50,6 +50,7 @@
50 50 static DEFINE_MUTEX(binder_deferred_lock);
51 51 static DEFINE_MUTEX(binder_mmap_lock);
52 52  
  53 +static HLIST_HEAD(binder_devices);
53 54 static HLIST_HEAD(binder_procs);
54 55 static HLIST_HEAD(binder_deferred_list);
55 56 static HLIST_HEAD(binder_dead_nodes);
... ... @@ -113,6 +114,9 @@
113 114 static bool binder_debug_no_lock;
114 115 module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
115 116  
  117 +static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
  118 +module_param_named(devices, binder_devices_param, charp, 0444);
  119 +
116 120 static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
117 121 static int binder_stop_on_user_error;
118 122  
... ... @@ -220,9 +224,10 @@
220 224 const char *name;
221 225 };
222 226  
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;
226 231 };
227 232  
228 233 struct binder_work {
... ... @@ -3047,6 +3052,7 @@
3047 3052 static int binder_open(struct inode *nodp, struct file *filp)
3048 3053 {
3049 3054 struct binder_proc *proc;
  3055 + struct binder_device *binder_dev;
3050 3056  
3051 3057 binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
3052 3058 current->group_leader->pid, current->pid);
3053 3059  
... ... @@ -3057,10 +3063,12 @@
3057 3063 get_task_struct(current);
3058 3064 proc->tsk = current;
3059 3065 proc->vma_vm_mm = current->mm;
3060   - proc->context = &global_context;
3061 3066 INIT_LIST_HEAD(&proc->todo);
3062 3067 init_waitqueue_head(&proc->wait);
3063 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 3073 binder_lock(__func__);
3066 3074  
3067 3075  
3068 3076  
3069 3077  
... ... @@ -3767,26 +3775,50 @@
3767 3775 .release = binder_release,
3768 3776 };
3769 3777  
3770   -static struct miscdevice binder_miscdev = {
3771   - .minor = MISC_DYNAMIC_MINOR,
3772   - .name = "binder",
3773   - .fops = &binder_fops
3774   -};
3775   -
3776 3778 BINDER_DEBUG_ENTRY(state);
3777 3779 BINDER_DEBUG_ENTRY(stats);
3778 3780 BINDER_DEBUG_ENTRY(transactions);
3779 3781 BINDER_DEBUG_ENTRY(transaction_log);
3780 3782  
  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 +
3781 3810 static int __init binder_init(void)
3782 3811 {
3783 3812 int ret;
  3813 + char *device_name, *device_names;
  3814 + struct binder_device *device;
  3815 + struct hlist_node *tmp;
3784 3816  
3785 3817 binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
3786 3818 if (binder_debugfs_dir_entry_root)
3787 3819 binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
3788 3820 binder_debugfs_dir_entry_root);
3789   - ret = misc_register(&binder_miscdev);
  3821 +
3790 3822 if (binder_debugfs_dir_entry_root) {
3791 3823 debugfs_create_file("state",
3792 3824 S_IRUGO,
... ... @@ -3814,6 +3846,35 @@
3814 3846 &binder_transaction_log_failed,
3815 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 +
  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 +
3817 3878 return ret;
3818 3879 }
3819 3880