diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-23 06:35:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-23 06:35:01 -0400 |
commit | 17e7637f5947284cd7f41c1b26ff8cbee9a794a4 (patch) | |
tree | 571c0ee5fec7224ba63dded321df818c88fd9994 | |
parent | 5805992184f97b7797f24b74d511825f8992861e (diff) | |
parent | ae65c8510f3319dfb2114cc48d476b81232e27b3 (diff) |
Merge tag 'char-misc-4.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver fixes from Greg KH:
"Here are four small fixes for 4.14-rc6.
Three of them are binder driver fixes for reported issues, and the
last one is a hyperv driver bugfix. Nothing major, but good fixes to
get into 4.14-final.
All of these have been in linux-next with no reported issues"
* tag 'char-misc-4.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
android: binder: Fix null ptr dereference in debug msg
android: binder: Don't get mm from task
vmbus: hvsock: add proper sync for vmbus_hvsock_device_unregister()
binder: call poll_wait() unconditionally.
-rw-r--r-- | drivers/android/binder.c | 11 | ||||
-rw-r--r-- | drivers/android/binder_alloc.c | 24 | ||||
-rw-r--r-- | drivers/android/binder_alloc.h | 1 | ||||
-rw-r--r-- | drivers/hv/channel_mgmt.c | 5 |
4 files changed, 15 insertions, 26 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 0621a95b8597..fddf76ef5bd6 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
@@ -3662,12 +3662,6 @@ static void binder_stat_br(struct binder_proc *proc, | |||
3662 | } | 3662 | } |
3663 | } | 3663 | } |
3664 | 3664 | ||
3665 | static int binder_has_thread_work(struct binder_thread *thread) | ||
3666 | { | ||
3667 | return !binder_worklist_empty(thread->proc, &thread->todo) || | ||
3668 | thread->looper_need_return; | ||
3669 | } | ||
3670 | |||
3671 | static int binder_put_node_cmd(struct binder_proc *proc, | 3665 | static int binder_put_node_cmd(struct binder_proc *proc, |
3672 | struct binder_thread *thread, | 3666 | struct binder_thread *thread, |
3673 | void __user **ptrp, | 3667 | void __user **ptrp, |
@@ -4297,12 +4291,9 @@ static unsigned int binder_poll(struct file *filp, | |||
4297 | 4291 | ||
4298 | binder_inner_proc_unlock(thread->proc); | 4292 | binder_inner_proc_unlock(thread->proc); |
4299 | 4293 | ||
4300 | if (binder_has_work(thread, wait_for_proc_work)) | ||
4301 | return POLLIN; | ||
4302 | |||
4303 | poll_wait(filp, &thread->wait, wait); | 4294 | poll_wait(filp, &thread->wait, wait); |
4304 | 4295 | ||
4305 | if (binder_has_thread_work(thread)) | 4296 | if (binder_has_work(thread, wait_for_proc_work)) |
4306 | return POLLIN; | 4297 | return POLLIN; |
4307 | 4298 | ||
4308 | return 0; | 4299 | return 0; |
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 064f5e31ec55..c2819a3d58a6 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c | |||
@@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, | |||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | if (!vma && need_mm) | 218 | if (!vma && need_mm && mmget_not_zero(alloc->vma_vm_mm)) |
219 | mm = get_task_mm(alloc->tsk); | 219 | mm = alloc->vma_vm_mm; |
220 | 220 | ||
221 | if (mm) { | 221 | if (mm) { |
222 | down_write(&mm->mmap_sem); | 222 | down_write(&mm->mmap_sem); |
223 | vma = alloc->vma; | 223 | vma = alloc->vma; |
224 | if (vma && mm != alloc->vma_vm_mm) { | ||
225 | pr_err("%d: vma mm and task mm mismatch\n", | ||
226 | alloc->pid); | ||
227 | vma = NULL; | ||
228 | } | ||
229 | } | 224 | } |
230 | 225 | ||
231 | if (!vma && need_mm) { | 226 | if (!vma && need_mm) { |
@@ -565,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc, | |||
565 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, | 560 | binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, |
566 | "%d: merge free, buffer %pK do not share page with %pK or %pK\n", | 561 | "%d: merge free, buffer %pK do not share page with %pK or %pK\n", |
567 | alloc->pid, buffer->data, | 562 | alloc->pid, buffer->data, |
568 | prev->data, next->data); | 563 | prev->data, next ? next->data : NULL); |
569 | binder_update_page_range(alloc, 0, buffer_start_page(buffer), | 564 | binder_update_page_range(alloc, 0, buffer_start_page(buffer), |
570 | buffer_start_page(buffer) + PAGE_SIZE, | 565 | buffer_start_page(buffer) + PAGE_SIZE, |
571 | NULL); | 566 | NULL); |
@@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, | |||
720 | barrier(); | 715 | barrier(); |
721 | alloc->vma = vma; | 716 | alloc->vma = vma; |
722 | alloc->vma_vm_mm = vma->vm_mm; | 717 | alloc->vma_vm_mm = vma->vm_mm; |
718 | mmgrab(alloc->vma_vm_mm); | ||
723 | 719 | ||
724 | return 0; | 720 | return 0; |
725 | 721 | ||
@@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc) | |||
795 | vfree(alloc->buffer); | 791 | vfree(alloc->buffer); |
796 | } | 792 | } |
797 | mutex_unlock(&alloc->mutex); | 793 | mutex_unlock(&alloc->mutex); |
794 | if (alloc->vma_vm_mm) | ||
795 | mmdrop(alloc->vma_vm_mm); | ||
798 | 796 | ||
799 | binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE, | 797 | binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE, |
800 | "%s: %d buffers %d, pages %d\n", | 798 | "%s: %d buffers %d, pages %d\n", |
@@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc) | |||
889 | void binder_alloc_vma_close(struct binder_alloc *alloc) | 887 | void binder_alloc_vma_close(struct binder_alloc *alloc) |
890 | { | 888 | { |
891 | WRITE_ONCE(alloc->vma, NULL); | 889 | WRITE_ONCE(alloc->vma, NULL); |
892 | WRITE_ONCE(alloc->vma_vm_mm, NULL); | ||
893 | } | 890 | } |
894 | 891 | ||
895 | /** | 892 | /** |
@@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item, | |||
926 | page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; | 923 | page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; |
927 | vma = alloc->vma; | 924 | vma = alloc->vma; |
928 | if (vma) { | 925 | if (vma) { |
929 | mm = get_task_mm(alloc->tsk); | 926 | if (!mmget_not_zero(alloc->vma_vm_mm)) |
930 | if (!mm) | 927 | goto err_mmget; |
931 | goto err_get_task_mm_failed; | 928 | mm = alloc->vma_vm_mm; |
932 | if (!down_write_trylock(&mm->mmap_sem)) | 929 | if (!down_write_trylock(&mm->mmap_sem)) |
933 | goto err_down_write_mmap_sem_failed; | 930 | goto err_down_write_mmap_sem_failed; |
934 | } | 931 | } |
@@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, | |||
963 | 960 | ||
964 | err_down_write_mmap_sem_failed: | 961 | err_down_write_mmap_sem_failed: |
965 | mmput_async(mm); | 962 | mmput_async(mm); |
966 | err_get_task_mm_failed: | 963 | err_mmget: |
967 | err_page_already_freed: | 964 | err_page_already_freed: |
968 | mutex_unlock(&alloc->mutex); | 965 | mutex_unlock(&alloc->mutex); |
969 | err_get_alloc_mutex_failed: | 966 | err_get_alloc_mutex_failed: |
@@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = { | |||
1002 | */ | 999 | */ |
1003 | void binder_alloc_init(struct binder_alloc *alloc) | 1000 | void binder_alloc_init(struct binder_alloc *alloc) |
1004 | { | 1001 | { |
1005 | alloc->tsk = current->group_leader; | ||
1006 | alloc->pid = current->group_leader->pid; | 1002 | alloc->pid = current->group_leader->pid; |
1007 | mutex_init(&alloc->mutex); | 1003 | mutex_init(&alloc->mutex); |
1008 | INIT_LIST_HEAD(&alloc->buffers); | 1004 | INIT_LIST_HEAD(&alloc->buffers); |
diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index a3a3602c689c..2dd33b6df104 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h | |||
@@ -100,7 +100,6 @@ struct binder_lru_page { | |||
100 | */ | 100 | */ |
101 | struct binder_alloc { | 101 | struct binder_alloc { |
102 | struct mutex mutex; | 102 | struct mutex mutex; |
103 | struct task_struct *tsk; | ||
104 | struct vm_area_struct *vma; | 103 | struct vm_area_struct *vma; |
105 | struct mm_struct *vma_vm_mm; | 104 | struct mm_struct *vma_vm_mm; |
106 | void *buffer; | 105 | void *buffer; |
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 018d2e0f8ec5..379b0df123be 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel *channel) | |||
937 | { | 937 | { |
938 | BUG_ON(!is_hvsock_channel(channel)); | 938 | BUG_ON(!is_hvsock_channel(channel)); |
939 | 939 | ||
940 | channel->rescind = true; | 940 | /* We always get a rescind msg when a connection is closed. */ |
941 | while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind)) | ||
942 | msleep(1); | ||
943 | |||
941 | vmbus_device_unregister(channel->device_obj); | 944 | vmbus_device_unregister(channel->device_obj); |
942 | } | 945 | } |
943 | EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister); | 946 | EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister); |