diff options
author | Grant Likely <grant.likely@linaro.org> | 2014-03-04 16:44:10 +0800 |
---|---|---|
committer | Grant Likely <grant.likely@linaro.org> | 2014-03-04 16:44:10 +0800 |
commit | dab2310d9d90eded48625c5382c6a60389bf8ca9 (patch) | |
tree | 9327cc815d69dec23aebf03407e3fa82b6d2fbaa /drivers/staging/android | |
parent | a3dbeb5b45af5b6113385db89fce2a8279278e8b (diff) | |
parent | 0414855fdc4a40da05221fc6062cccbc0c30f169 (diff) | |
download | op-kernel-dev-dab2310d9d90eded48625c5382c6a60389bf8ca9.zip op-kernel-dev-dab2310d9d90eded48625c5382c6a60389bf8ca9.tar.gz |
Merge tag 'v3.14-rc5' into HEAD
Linux 3.14-rc5
Diffstat (limited to 'drivers/staging/android')
-rw-r--r-- | drivers/staging/android/ashmem.c | 45 | ||||
-rw-r--r-- | drivers/staging/android/binder.c | 3 | ||||
-rw-r--r-- | drivers/staging/android/ion/compat_ion.c | 26 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_dummy_driver.c | 12 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_heap.c | 2 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_priv.h | 1 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_system_heap.c | 6 | ||||
-rw-r--r-- | drivers/staging/android/sw_sync.h | 17 | ||||
-rw-r--r-- | drivers/staging/android/sync.c | 14 |
9 files changed, 86 insertions, 40 deletions
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 23948f1..713a972 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -295,21 +295,29 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, /* If size is not set, or set to 0, always return EOF. */ if (asma->size == 0) - goto out; + goto out_unlock; if (!asma->file) { ret = -EBADF; - goto out; + goto out_unlock; } - ret = asma->file->f_op->read(asma->file, buf, len, pos); - if (ret < 0) - goto out; + mutex_unlock(&ashmem_mutex); - /** Update backing file pos, since f_ops->read() doesn't */ - asma->file->f_pos = *pos; + /* + * asma and asma->file are used outside the lock here. We assume + * once asma->file is set it will never be changed, and will not + * be destroyed until all references to the file are dropped and + * ashmem_release is called. + */ + ret = asma->file->f_op->read(asma->file, buf, len, pos); + if (ret >= 0) { + /** Update backing file pos, since f_ops->read() doesn't */ + asma->file->f_pos = *pos; + } + return ret; -out: +out_unlock: mutex_unlock(&ashmem_mutex); return ret; } @@ -498,6 +506,7 @@ out: static int set_name(struct ashmem_area *asma, void __user *name) { + int len; int ret = 0; char local_name[ASHMEM_NAME_LEN]; @@ -510,21 +519,19 @@ static int set_name(struct ashmem_area *asma, void __user *name) * variable that does not need protection and later copy the local * variable to the structure member with lock held. */ - if (copy_from_user(local_name, name, ASHMEM_NAME_LEN)) - return -EFAULT; - + len = strncpy_from_user(local_name, name, ASHMEM_NAME_LEN); + if (len < 0) + return len; + if (len == ASHMEM_NAME_LEN) + local_name[ASHMEM_NAME_LEN - 1] = '\0'; mutex_lock(&ashmem_mutex); /* cannot change an existing mapping's name */ - if (unlikely(asma->file)) { + if (unlikely(asma->file)) ret = -EINVAL; - goto out; - } - memcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, - local_name, ASHMEM_NAME_LEN); - asma->name[ASHMEM_FULL_NAME_LEN-1] = '\0'; -out: - mutex_unlock(&ashmem_mutex); + else + strcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name); + mutex_unlock(&ashmem_mutex); return ret; } diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index eaec1da..1432d95 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -2904,7 +2904,7 @@ static int binder_node_release(struct binder_node *node, int refs) refs++; if (!ref->death) - goto out; + continue; death++; @@ -2917,7 +2917,6 @@ static int binder_node_release(struct binder_node *node, int refs) BUG(); } -out: binder_debug(BINDER_DEBUG_DEAD_BINDER, "node %d now dead, refs %d, death %d\n", node->debug_id, refs, death); diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index af6cd37..ee3a738 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -35,9 +35,14 @@ struct compat_ion_custom_data { compat_ulong_t arg; }; +struct compat_ion_handle_data { + compat_int_t handle; +}; + #define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ struct compat_ion_allocation_data) -#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, \ + struct compat_ion_handle_data) #define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ struct compat_ion_custom_data) @@ -64,6 +69,19 @@ static int compat_get_ion_allocation_data( return err; } +static int compat_get_ion_handle_data( + struct compat_ion_handle_data __user *data32, + struct ion_handle_data __user *data) +{ + compat_int_t i; + int err; + + err = get_user(i, &data32->handle); + err |= put_user(i, &data->handle); + + return err; +} + static int compat_put_ion_allocation_data( struct compat_ion_allocation_data __user *data32, struct ion_allocation_data __user *data) @@ -132,8 +150,8 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } case COMPAT_ION_IOC_FREE: { - struct compat_ion_allocation_data __user *data32; - struct ion_allocation_data __user *data; + struct compat_ion_handle_data __user *data32; + struct ion_handle_data __user *data; int err; data32 = compat_ptr(arg); @@ -141,7 +159,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (data == NULL) return -EFAULT; - err = compat_get_ion_allocation_data(data32, data); + err = compat_get_ion_handle_data(data32, data); if (err) return err; diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c index 55b2002..01cdc8a 100644 --- a/drivers/staging/android/ion/ion_dummy_driver.c +++ b/drivers/staging/android/ion/ion_dummy_driver.c @@ -17,9 +17,11 @@ #include <linux/err.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/init.h> #include <linux/bootmem.h> #include <linux/memblock.h> #include <linux/sizes.h> +#include <linux/io.h> #include "ion.h" #include "ion_priv.h" @@ -57,7 +59,7 @@ struct ion_platform_heap dummy_heaps[] = { }; struct ion_platform_data dummy_ion_pdata = { - .nr = 4, + .nr = ARRAY_SIZE(dummy_heaps), .heaps = dummy_heaps, }; @@ -69,7 +71,7 @@ static int __init ion_dummy_init(void) heaps = kzalloc(sizeof(struct ion_heap *) * dummy_ion_pdata.nr, GFP_KERNEL); if (!heaps) - return PTR_ERR(heaps); + return -ENOMEM; /* Allocate a dummy carveout heap */ @@ -128,6 +130,7 @@ err: } return err; } +device_initcall(ion_dummy_init); static void __exit ion_dummy_exit(void) { @@ -152,7 +155,4 @@ static void __exit ion_dummy_exit(void) return; } - -module_init(ion_dummy_init); -module_exit(ion_dummy_exit); - +__exitcall(ion_dummy_exit); diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 296c74f..37e64d5 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -243,12 +243,12 @@ int ion_heap_init_deferred_free(struct ion_heap *heap) init_waitqueue_head(&heap->waitqueue); heap->task = kthread_run(ion_heap_deferred_free, heap, "%s", heap->name); - sched_setscheduler(heap->task, SCHED_IDLE, ¶m); if (IS_ERR(heap->task)) { pr_err("%s: creating thread for deferred free failed\n", __func__); return PTR_RET(heap->task); } + sched_setscheduler(heap->task, SCHED_IDLE, ¶m); return 0; } diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index d986739..fc2e4fc 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -17,6 +17,7 @@ #ifndef _ION_PRIV_H #define _ION_PRIV_H +#include <linux/device.h> #include <linux/dma-direction.h> #include <linux/kref.h> #include <linux/mm_types.h> diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 7f07291..9849f39 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -124,6 +124,7 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap, info->page = page; info->order = orders[i]; + INIT_LIST_HEAD(&info->list); return info; } kfree(info); @@ -145,12 +146,15 @@ static int ion_system_heap_allocate(struct ion_heap *heap, struct list_head pages; struct page_info *info, *tmp_info; int i = 0; - long size_remaining = PAGE_ALIGN(size); + unsigned long size_remaining = PAGE_ALIGN(size); unsigned int max_order = orders[0]; if (align > PAGE_SIZE) return -EINVAL; + if (size / PAGE_SIZE > totalram_pages / 2) + return -ENOMEM; + INIT_LIST_HEAD(&pages); while (size_remaining > 0) { info = alloc_largest_available(sys_heap, buffer, size_remaining, diff --git a/drivers/staging/android/sw_sync.h b/drivers/staging/android/sw_sync.h index 585040b..5aaf71d 100644 --- a/drivers/staging/android/sw_sync.h +++ b/drivers/staging/android/sw_sync.h @@ -35,10 +35,27 @@ struct sw_sync_pt { u32 value; }; +#if IS_ENABLED(CONFIG_SW_SYNC) struct sw_sync_timeline *sw_sync_timeline_create(const char *name); void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); +#else +static inline struct sw_sync_timeline *sw_sync_timeline_create(const char *name) +{ + return NULL; +} + +static inline void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) +{ +} + +static inline struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, + u32 value) +{ + return NULL; +} +#endif /* IS_ENABLED(CONFIG_SW_SYNC) */ #endif /* __KERNEL __ */ diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 38e5d3b..3d05f662 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -79,27 +79,27 @@ static void sync_timeline_free(struct kref *kref) container_of(kref, struct sync_timeline, kref); unsigned long flags; - if (obj->ops->release_obj) - obj->ops->release_obj(obj); - spin_lock_irqsave(&sync_timeline_list_lock, flags); list_del(&obj->sync_timeline_list); spin_unlock_irqrestore(&sync_timeline_list_lock, flags); + if (obj->ops->release_obj) + obj->ops->release_obj(obj); + kfree(obj); } void sync_timeline_destroy(struct sync_timeline *obj) { obj->destroyed = true; + smp_wmb(); /* - * If this is not the last reference, signal any children - * that their parent is going away. + * signal any children that their parent is going away. */ + sync_timeline_signal(obj); - if (!kref_put(&obj->kref, sync_timeline_free)) - sync_timeline_signal(obj); + kref_put(&obj->kref, sync_timeline_free); } EXPORT_SYMBOL(sync_timeline_destroy); |