Merge pull request #415 from brauner/2017-08-18/use_own_major
binder: use own major
This commit is contained in:
commit
a5ead0f075
2 changed files with 135 additions and 37 deletions
|
|
@ -1,2 +1,2 @@
|
||||||
KERNEL=="ashmem", NAME="%k", MODE="0666"
|
KERNEL=="ashmem", NAME="%k", MODE="0666"
|
||||||
KERNEL=="binder", NAME="%k", MODE="0666"
|
KERNEL=="binder*", NAME="%k", MODE="0666"
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,13 @@
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
#include <linux/cdev.h>
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/fdtable.h>
|
#include <linux/fdtable.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/freezer.h>
|
#include <linux/freezer.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/miscdevice.h>
|
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
|
@ -50,12 +51,20 @@
|
||||||
#define BINDER_IPC_32BIT 1
|
#define BINDER_IPC_32BIT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Until I upstream a better version of this patch choose an arbitrary major
|
||||||
|
* number in the high end spectrum that has not yet been given away and is
|
||||||
|
* unlikely to be given away in the near future.
|
||||||
|
*/
|
||||||
|
#define BINDER_DKMS_MAJOR 511
|
||||||
|
#define BINDER_DKMS_MAX_MINOR 1024
|
||||||
|
|
||||||
#include "binder.h"
|
#include "binder.h"
|
||||||
#include "binder_trace.h"
|
#include "binder_trace.h"
|
||||||
|
|
||||||
static DEFINE_MUTEX(binder_main_lock);
|
static DEFINE_MUTEX(binder_main_lock);
|
||||||
static DEFINE_MUTEX(binder_deferred_lock);
|
static DEFINE_MUTEX(binder_deferred_lock);
|
||||||
static DEFINE_MUTEX(binder_mmap_lock);
|
static DEFINE_MUTEX(binder_mmap_lock);
|
||||||
|
static DEFINE_MUTEX(binder_devices_mtx);
|
||||||
|
|
||||||
static HLIST_HEAD(binder_devices);
|
static HLIST_HEAD(binder_devices);
|
||||||
static HLIST_HEAD(binder_procs);
|
static HLIST_HEAD(binder_procs);
|
||||||
|
|
@ -121,8 +130,8 @@ module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
|
||||||
static bool binder_debug_no_lock;
|
static bool binder_debug_no_lock;
|
||||||
module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
|
module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
|
static int binder_devices_param = 1;
|
||||||
module_param_named(devices, binder_devices_param, charp, 0444);
|
module_param_named(num_devices, binder_devices_param, int, 0444);
|
||||||
|
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
|
static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
|
||||||
static int binder_stop_on_user_error;
|
static int binder_stop_on_user_error;
|
||||||
|
|
@ -239,7 +248,8 @@ struct binder_context {
|
||||||
|
|
||||||
struct binder_device {
|
struct binder_device {
|
||||||
struct hlist_node hlist;
|
struct hlist_node hlist;
|
||||||
struct miscdevice miscdev;
|
struct cdev cdev;
|
||||||
|
struct device class_dev;
|
||||||
struct binder_context context;
|
struct binder_context context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -485,7 +495,6 @@ static void binder_set_nice(long nice)
|
||||||
set_user_nice(current, min_nice);
|
set_user_nice(current, min_nice);
|
||||||
if (min_nice <= MAX_NICE)
|
if (min_nice <= MAX_NICE)
|
||||||
return;
|
return;
|
||||||
binder_user_error("%d RLIMIT_NICE not set\n", current->pid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t binder_buffer_size(struct binder_proc *proc,
|
static size_t binder_buffer_size(struct binder_proc *proc,
|
||||||
|
|
@ -3470,6 +3479,8 @@ err_bad_arg:
|
||||||
|
|
||||||
static int binder_open(struct inode *nodp, struct file *filp)
|
static int binder_open(struct inode *nodp, struct file *filp)
|
||||||
{
|
{
|
||||||
|
int minor = iminor(nodp);
|
||||||
|
struct hlist_node *tmp;
|
||||||
struct binder_proc *proc;
|
struct binder_proc *proc;
|
||||||
struct binder_device *binder_dev;
|
struct binder_device *binder_dev;
|
||||||
|
|
||||||
|
|
@ -3484,8 +3495,18 @@ static int binder_open(struct inode *nodp, struct file *filp)
|
||||||
INIT_LIST_HEAD(&proc->todo);
|
INIT_LIST_HEAD(&proc->todo);
|
||||||
init_waitqueue_head(&proc->wait);
|
init_waitqueue_head(&proc->wait);
|
||||||
proc->default_priority = task_nice(current);
|
proc->default_priority = task_nice(current);
|
||||||
binder_dev = container_of(filp->private_data, struct binder_device,
|
|
||||||
miscdev);
|
mutex_lock(&binder_devices_mtx);
|
||||||
|
hlist_for_each_entry_safe(binder_dev, tmp, &binder_devices, hlist) {
|
||||||
|
if (MINOR(binder_dev->cdev.dev) == minor)
|
||||||
|
break;
|
||||||
|
binder_dev = NULL;
|
||||||
|
}
|
||||||
|
mutex_unlock(&binder_devices_mtx);
|
||||||
|
if (!binder_dev)
|
||||||
|
BUG();
|
||||||
|
|
||||||
|
filp->private_data = &binder_dev->class_dev;
|
||||||
proc->context = &binder_dev->context;
|
proc->context = &binder_dev->context;
|
||||||
|
|
||||||
binder_lock(__func__);
|
binder_lock(__func__);
|
||||||
|
|
@ -4200,40 +4221,85 @@ BINDER_DEBUG_ENTRY(stats);
|
||||||
BINDER_DEBUG_ENTRY(transactions);
|
BINDER_DEBUG_ENTRY(transactions);
|
||||||
BINDER_DEBUG_ENTRY(transaction_log);
|
BINDER_DEBUG_ENTRY(transaction_log);
|
||||||
|
|
||||||
static int __init init_binder_device(const char *name)
|
static struct class *binder_class;
|
||||||
|
|
||||||
|
static void binder_device_release(struct device *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init init_binder_device(int idx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
char *name;
|
||||||
|
dev_t devnr;
|
||||||
struct binder_device *binder_device;
|
struct binder_device *binder_device;
|
||||||
|
/* strlen("binder")
|
||||||
|
* +
|
||||||
|
* maximum length of 64 bit int as string
|
||||||
|
*/
|
||||||
|
char numstr[6 + 21] = "binder";
|
||||||
|
|
||||||
binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
|
binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
|
||||||
if (!binder_device)
|
if (!binder_device)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
binder_device->miscdev.fops = &binder_fops;
|
cdev_init(&binder_device->cdev, &binder_fops);
|
||||||
binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
|
binder_device->cdev.owner = THIS_MODULE;
|
||||||
binder_device->miscdev.name = name;
|
|
||||||
|
|
||||||
binder_device->context.binder_context_mgr_uid = INVALID_UID;
|
devnr = MKDEV(BINDER_DKMS_MAJOR, idx);
|
||||||
binder_device->context.name = name;
|
ret = cdev_add(&binder_device->cdev, devnr, 1);
|
||||||
|
if (ret) {
|
||||||
ret = misc_register(&binder_device->miscdev);
|
|
||||||
if (ret < 0) {
|
|
||||||
kfree(binder_device);
|
kfree(binder_device);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlist_add_head(&binder_device->hlist, &binder_devices);
|
if (binder_devices_param > 1)
|
||||||
|
ret = snprintf(numstr, sizeof(numstr), "binder%d", idx);
|
||||||
|
if (ret < 0 || (size_t)ret >= sizeof(numstr)) {
|
||||||
|
cdev_del(&binder_device->cdev);
|
||||||
|
kfree(binder_device);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
name = kzalloc(strlen(numstr) + 1, GFP_KERNEL);
|
||||||
|
if (!name) {
|
||||||
|
cdev_del(&binder_device->cdev);
|
||||||
|
kfree(binder_device);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
strcpy(name, numstr);
|
||||||
|
binder_device->context.name = name;
|
||||||
|
binder_device->context.binder_context_mgr_uid = INVALID_UID;
|
||||||
|
|
||||||
|
binder_device->class_dev.devt = binder_device->cdev.dev;
|
||||||
|
binder_device->class_dev.class = binder_class;
|
||||||
|
binder_device->class_dev.release = binder_device_release;
|
||||||
|
dev_set_name(&binder_device->class_dev, "%s", name);
|
||||||
|
ret = device_register(&binder_device->class_dev);
|
||||||
|
if (ret) {
|
||||||
|
cdev_del(&binder_device->cdev);
|
||||||
|
kfree(binder_device);
|
||||||
|
kfree(name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&binder_devices_mtx);
|
||||||
|
hlist_add_head(&binder_device->hlist, &binder_devices);
|
||||||
|
mutex_unlock(&binder_devices_mtx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init binder_init(void)
|
static int __init binder_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int i, ret;
|
||||||
char *device_name, *device_names;
|
|
||||||
struct binder_device *device;
|
struct binder_device *device;
|
||||||
struct hlist_node *tmp;
|
struct hlist_node *tmp;
|
||||||
|
|
||||||
|
if (binder_devices_param <= 0 ||
|
||||||
|
binder_devices_param > BINDER_DKMS_MAX_MINOR)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
|
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
|
||||||
if (binder_debugfs_dir_entry_root)
|
if (binder_debugfs_dir_entry_root)
|
||||||
binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
|
binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
|
||||||
|
|
@ -4267,19 +4333,17 @@ static int __init binder_init(void)
|
||||||
&binder_transaction_log_fops);
|
&binder_transaction_log_fops);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
ret = register_chrdev_region(MKDEV(BINDER_DKMS_MAJOR, 0),
|
||||||
* Copy the module_parameter string, because we don't want to
|
BINDER_DKMS_MAX_MINOR, "binder");
|
||||||
* tokenize it in-place.
|
if (ret)
|
||||||
*/
|
goto on_error_remove_debugfs;
|
||||||
device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL);
|
|
||||||
if (!device_names) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_alloc_device_names_failed;
|
|
||||||
}
|
|
||||||
strcpy(device_names, binder_devices_param);
|
|
||||||
|
|
||||||
while ((device_name = strsep(&device_names, ","))) {
|
binder_class = class_create(THIS_MODULE, "binder");
|
||||||
ret = init_binder_device(device_name);
|
if (IS_ERR(binder_class))
|
||||||
|
goto on_error_unregister_chrdev_region;
|
||||||
|
|
||||||
|
for (i = 0; i < binder_devices_param; i++) {
|
||||||
|
ret = init_binder_device(i);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_init_binder_device_failed;
|
goto err_init_binder_device_failed;
|
||||||
}
|
}
|
||||||
|
|
@ -4287,18 +4351,52 @@ static int __init binder_init(void)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err_init_binder_device_failed:
|
err_init_binder_device_failed:
|
||||||
|
mutex_lock(&binder_devices_mtx);
|
||||||
hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) {
|
hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) {
|
||||||
misc_deregister(&device->miscdev);
|
cdev_del(&device->cdev);
|
||||||
|
device_unregister(&device->class_dev);
|
||||||
|
kfree(device->context.name);
|
||||||
hlist_del(&device->hlist);
|
hlist_del(&device->hlist);
|
||||||
kfree(device);
|
kfree(device);
|
||||||
}
|
}
|
||||||
err_alloc_device_names_failed:
|
mutex_unlock(&binder_devices_mtx);
|
||||||
|
class_destroy(binder_class);
|
||||||
|
|
||||||
|
on_error_unregister_chrdev_region:
|
||||||
|
unregister_chrdev_region(MKDEV(BINDER_DKMS_MAJOR, 0),
|
||||||
|
BINDER_DKMS_MAX_MINOR);
|
||||||
|
|
||||||
|
on_error_remove_debugfs:
|
||||||
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
|
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
|
||||||
|
|
||||||
return ret;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_initcall(binder_init);
|
static void __exit binder_exit(void)
|
||||||
|
{
|
||||||
|
struct binder_device *device;
|
||||||
|
struct hlist_node *tmp;
|
||||||
|
|
||||||
|
mutex_lock(&binder_devices_mtx);
|
||||||
|
hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) {
|
||||||
|
cdev_del(&device->cdev);
|
||||||
|
device_unregister(&device->class_dev);
|
||||||
|
kfree(device->context.name);
|
||||||
|
hlist_del(&device->hlist);
|
||||||
|
kfree(device);
|
||||||
|
}
|
||||||
|
mutex_unlock(&binder_devices_mtx);
|
||||||
|
|
||||||
|
class_destroy(binder_class);
|
||||||
|
|
||||||
|
unregister_chrdev_region(MKDEV(BINDER_DKMS_MAJOR, 0),
|
||||||
|
BINDER_DKMS_MAX_MINOR);
|
||||||
|
|
||||||
|
debugfs_remove_recursive(binder_debugfs_dir_entry_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(binder_init);
|
||||||
|
module_exit(binder_exit);
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include "binder_trace.h"
|
#include "binder_trace.h"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue