diff options
author | Martijn Coenen <maco@google.com> | 2017-02-03 17:40:48 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-02-10 10:00:01 -0500 |
commit | ac4812c5ffbb88dd3280a6dacd39fcb73e077fe4 (patch) | |
tree | 01fd627d2ae32289d06dd3af5bbc2d924100bfe0 | |
parent | 14db31814a9a21cf343e71d6773e7683a5b3f64d (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/Kconfig | 12 | ||||
-rw-r--r-- | drivers/android/binder.c | 83 |
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 | ||
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 | config ANDROID_BINDER_IPC_32BIT | 34 | config 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); | |||
50 | static DEFINE_MUTEX(binder_deferred_lock); | 50 | static DEFINE_MUTEX(binder_deferred_lock); |
51 | static DEFINE_MUTEX(binder_mmap_lock); | 51 | static DEFINE_MUTEX(binder_mmap_lock); |
52 | 52 | ||
53 | static HLIST_HEAD(binder_devices); | ||
53 | static HLIST_HEAD(binder_procs); | 54 | static HLIST_HEAD(binder_procs); |
54 | static HLIST_HEAD(binder_deferred_list); | 55 | static HLIST_HEAD(binder_deferred_list); |
55 | static HLIST_HEAD(binder_dead_nodes); | 56 | static HLIST_HEAD(binder_dead_nodes); |
@@ -113,6 +114,9 @@ module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); | |||
113 | static bool binder_debug_no_lock; | 114 | static bool binder_debug_no_lock; |
114 | module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO); | 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 | static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); | 120 | static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); |
117 | static int binder_stop_on_user_error; | 121 | static 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 | ||
223 | static struct binder_context global_context = { | 227 | struct 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 | ||
228 | struct binder_work { | 233 | struct binder_work { |
@@ -3047,6 +3052,7 @@ err_bad_arg: | |||
3047 | static int binder_open(struct inode *nodp, struct file *filp) | 3052 | static 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 | ||
3770 | static struct miscdevice binder_miscdev = { | ||
3771 | .minor = MISC_DYNAMIC_MINOR, | ||
3772 | .name = "binder", | ||
3773 | .fops = &binder_fops | ||
3774 | }; | ||
3775 | |||
3776 | BINDER_DEBUG_ENTRY(state); | 3778 | BINDER_DEBUG_ENTRY(state); |
3777 | BINDER_DEBUG_ENTRY(stats); | 3779 | BINDER_DEBUG_ENTRY(stats); |
3778 | BINDER_DEBUG_ENTRY(transactions); | 3780 | BINDER_DEBUG_ENTRY(transactions); |
3779 | BINDER_DEBUG_ENTRY(transaction_log); | 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 | static int __init binder_init(void) | 3810 | static 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 | |||
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 | return ret; | 3878 | return ret; |
3818 | } | 3879 | } |
3819 | 3880 | ||