diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-29 14:19:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-29 14:19:02 -0400 |
commit | 2a290036a1e4c813ee913154cd0334bd07330582 (patch) | |
tree | 8ec1300dfd7a3e38a62046960b5ff8fc84efda55 | |
parent | c636e176d8e5afe2f3b3e3f1de33ec13f1cee308 (diff) | |
parent | a7d5afe82d4931289250d6e807e35db3885b3b12 (diff) |
Merge tag 'char-misc-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver fixes from Greg KH:
"Here are a few small char/misc driver fixes for reported issues.
The "biggest" are two binder fixes for reported issues that have been
shipping in Android phones for a while now, the others are various
fixes for reported problems.
And there's a MAINTAINERS update for good measure.
All have been in linux-next with no reported issues"
* tag 'char-misc-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
MAINTAINERS: Add entry for genwqe driver
VMCI: Doorbell create and destroy fixes
GenWQE: Fix bad page access during abort of resource allocation
vme: vme_get_size potentially returning incorrect value on failure
extcon: qcom-spmi-misc: Sync the extcon state on interrupt
hv: do not lose pending heartbeat vmbus packets
mei: txe: don't clean an unprocessed interrupt cause.
ANDROID: binder: Clear binder and cookie when setting handle in flat binder struct
ANDROID: binder: Add strong ref checks
-rw-r--r-- | MAINTAINERS | 6 | ||||
-rw-r--r-- | drivers/android/binder.c | 35 | ||||
-rw-r--r-- | drivers/extcon/extcon-qcom-spmi-misc.c | 2 | ||||
-rw-r--r-- | drivers/hv/hv_util.c | 10 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_utils.c | 12 | ||||
-rw-r--r-- | drivers/misc/mei/hw-txe.c | 6 | ||||
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_doorbell.c | 8 | ||||
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_driver.c | 2 | ||||
-rw-r--r-- | drivers/vme/vme.c | 4 |
9 files changed, 67 insertions, 18 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index f30b8ea700fd..464d2c885f96 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5287,6 +5287,12 @@ M: Joe Perches <joe@perches.com> | |||
5287 | S: Maintained | 5287 | S: Maintained |
5288 | F: scripts/get_maintainer.pl | 5288 | F: scripts/get_maintainer.pl |
5289 | 5289 | ||
5290 | GENWQE (IBM Generic Workqueue Card) | ||
5291 | M: Frank Haverkamp <haver@linux.vnet.ibm.com> | ||
5292 | M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> | ||
5293 | S: Supported | ||
5294 | F: drivers/misc/genwqe/ | ||
5295 | |||
5290 | GFS2 FILE SYSTEM | 5296 | GFS2 FILE SYSTEM |
5291 | M: Steven Whitehouse <swhiteho@redhat.com> | 5297 | M: Steven Whitehouse <swhiteho@redhat.com> |
5292 | M: Bob Peterson <rpeterso@redhat.com> | 5298 | M: Bob Peterson <rpeterso@redhat.com> |
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 562af94bec35..3c71b982bf2a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
@@ -1002,7 +1002,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal) | |||
1002 | 1002 | ||
1003 | 1003 | ||
1004 | static struct binder_ref *binder_get_ref(struct binder_proc *proc, | 1004 | static struct binder_ref *binder_get_ref(struct binder_proc *proc, |
1005 | uint32_t desc) | 1005 | u32 desc, bool need_strong_ref) |
1006 | { | 1006 | { |
1007 | struct rb_node *n = proc->refs_by_desc.rb_node; | 1007 | struct rb_node *n = proc->refs_by_desc.rb_node; |
1008 | struct binder_ref *ref; | 1008 | struct binder_ref *ref; |
@@ -1010,12 +1010,16 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc, | |||
1010 | while (n) { | 1010 | while (n) { |
1011 | ref = rb_entry(n, struct binder_ref, rb_node_desc); | 1011 | ref = rb_entry(n, struct binder_ref, rb_node_desc); |
1012 | 1012 | ||
1013 | if (desc < ref->desc) | 1013 | if (desc < ref->desc) { |
1014 | n = n->rb_left; | 1014 | n = n->rb_left; |
1015 | else if (desc > ref->desc) | 1015 | } else if (desc > ref->desc) { |
1016 | n = n->rb_right; | 1016 | n = n->rb_right; |
1017 | else | 1017 | } else if (need_strong_ref && !ref->strong) { |
1018 | binder_user_error("tried to use weak ref as strong ref\n"); | ||
1019 | return NULL; | ||
1020 | } else { | ||
1018 | return ref; | 1021 | return ref; |
1022 | } | ||
1019 | } | 1023 | } |
1020 | return NULL; | 1024 | return NULL; |
1021 | } | 1025 | } |
@@ -1285,7 +1289,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, | |||
1285 | } break; | 1289 | } break; |
1286 | case BINDER_TYPE_HANDLE: | 1290 | case BINDER_TYPE_HANDLE: |
1287 | case BINDER_TYPE_WEAK_HANDLE: { | 1291 | case BINDER_TYPE_WEAK_HANDLE: { |
1288 | struct binder_ref *ref = binder_get_ref(proc, fp->handle); | 1292 | struct binder_ref *ref; |
1293 | |||
1294 | ref = binder_get_ref(proc, fp->handle, | ||
1295 | fp->type == BINDER_TYPE_HANDLE); | ||
1289 | 1296 | ||
1290 | if (ref == NULL) { | 1297 | if (ref == NULL) { |
1291 | pr_err("transaction release %d bad handle %d\n", | 1298 | pr_err("transaction release %d bad handle %d\n", |
@@ -1380,7 +1387,7 @@ static void binder_transaction(struct binder_proc *proc, | |||
1380 | if (tr->target.handle) { | 1387 | if (tr->target.handle) { |
1381 | struct binder_ref *ref; | 1388 | struct binder_ref *ref; |
1382 | 1389 | ||
1383 | ref = binder_get_ref(proc, tr->target.handle); | 1390 | ref = binder_get_ref(proc, tr->target.handle, true); |
1384 | if (ref == NULL) { | 1391 | if (ref == NULL) { |
1385 | binder_user_error("%d:%d got transaction to invalid handle\n", | 1392 | binder_user_error("%d:%d got transaction to invalid handle\n", |
1386 | proc->pid, thread->pid); | 1393 | proc->pid, thread->pid); |
@@ -1577,7 +1584,9 @@ static void binder_transaction(struct binder_proc *proc, | |||
1577 | fp->type = BINDER_TYPE_HANDLE; | 1584 | fp->type = BINDER_TYPE_HANDLE; |
1578 | else | 1585 | else |
1579 | fp->type = BINDER_TYPE_WEAK_HANDLE; | 1586 | fp->type = BINDER_TYPE_WEAK_HANDLE; |
1587 | fp->binder = 0; | ||
1580 | fp->handle = ref->desc; | 1588 | fp->handle = ref->desc; |
1589 | fp->cookie = 0; | ||
1581 | binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, | 1590 | binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, |
1582 | &thread->todo); | 1591 | &thread->todo); |
1583 | 1592 | ||
@@ -1589,7 +1598,10 @@ static void binder_transaction(struct binder_proc *proc, | |||
1589 | } break; | 1598 | } break; |
1590 | case BINDER_TYPE_HANDLE: | 1599 | case BINDER_TYPE_HANDLE: |
1591 | case BINDER_TYPE_WEAK_HANDLE: { | 1600 | case BINDER_TYPE_WEAK_HANDLE: { |
1592 | struct binder_ref *ref = binder_get_ref(proc, fp->handle); | 1601 | struct binder_ref *ref; |
1602 | |||
1603 | ref = binder_get_ref(proc, fp->handle, | ||
1604 | fp->type == BINDER_TYPE_HANDLE); | ||
1593 | 1605 | ||
1594 | if (ref == NULL) { | 1606 | if (ref == NULL) { |
1595 | binder_user_error("%d:%d got transaction with invalid handle, %d\n", | 1607 | binder_user_error("%d:%d got transaction with invalid handle, %d\n", |
@@ -1624,7 +1636,9 @@ static void binder_transaction(struct binder_proc *proc, | |||
1624 | return_error = BR_FAILED_REPLY; | 1636 | return_error = BR_FAILED_REPLY; |
1625 | goto err_binder_get_ref_for_node_failed; | 1637 | goto err_binder_get_ref_for_node_failed; |
1626 | } | 1638 | } |
1639 | fp->binder = 0; | ||
1627 | fp->handle = new_ref->desc; | 1640 | fp->handle = new_ref->desc; |
1641 | fp->cookie = 0; | ||
1628 | binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); | 1642 | binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); |
1629 | trace_binder_transaction_ref_to_ref(t, ref, | 1643 | trace_binder_transaction_ref_to_ref(t, ref, |
1630 | new_ref); | 1644 | new_ref); |
@@ -1678,6 +1692,7 @@ static void binder_transaction(struct binder_proc *proc, | |||
1678 | binder_debug(BINDER_DEBUG_TRANSACTION, | 1692 | binder_debug(BINDER_DEBUG_TRANSACTION, |
1679 | " fd %d -> %d\n", fp->handle, target_fd); | 1693 | " fd %d -> %d\n", fp->handle, target_fd); |
1680 | /* TODO: fput? */ | 1694 | /* TODO: fput? */ |
1695 | fp->binder = 0; | ||
1681 | fp->handle = target_fd; | 1696 | fp->handle = target_fd; |
1682 | } break; | 1697 | } break; |
1683 | 1698 | ||
@@ -1800,7 +1815,9 @@ static int binder_thread_write(struct binder_proc *proc, | |||
1800 | ref->desc); | 1815 | ref->desc); |
1801 | } | 1816 | } |
1802 | } else | 1817 | } else |
1803 | ref = binder_get_ref(proc, target); | 1818 | ref = binder_get_ref(proc, target, |
1819 | cmd == BC_ACQUIRE || | ||
1820 | cmd == BC_RELEASE); | ||
1804 | if (ref == NULL) { | 1821 | if (ref == NULL) { |
1805 | binder_user_error("%d:%d refcount change on invalid ref %d\n", | 1822 | binder_user_error("%d:%d refcount change on invalid ref %d\n", |
1806 | proc->pid, thread->pid, target); | 1823 | proc->pid, thread->pid, target); |
@@ -1996,7 +2013,7 @@ static int binder_thread_write(struct binder_proc *proc, | |||
1996 | if (get_user(cookie, (binder_uintptr_t __user *)ptr)) | 2013 | if (get_user(cookie, (binder_uintptr_t __user *)ptr)) |
1997 | return -EFAULT; | 2014 | return -EFAULT; |
1998 | ptr += sizeof(binder_uintptr_t); | 2015 | ptr += sizeof(binder_uintptr_t); |
1999 | ref = binder_get_ref(proc, target); | 2016 | ref = binder_get_ref(proc, target, false); |
2000 | if (ref == NULL) { | 2017 | if (ref == NULL) { |
2001 | binder_user_error("%d:%d %s invalid ref %d\n", | 2018 | binder_user_error("%d:%d %s invalid ref %d\n", |
2002 | proc->pid, thread->pid, | 2019 | proc->pid, thread->pid, |
diff --git a/drivers/extcon/extcon-qcom-spmi-misc.c b/drivers/extcon/extcon-qcom-spmi-misc.c index ca957a5f4291..b8cde096a808 100644 --- a/drivers/extcon/extcon-qcom-spmi-misc.c +++ b/drivers/extcon/extcon-qcom-spmi-misc.c | |||
@@ -51,7 +51,7 @@ static void qcom_usb_extcon_detect_cable(struct work_struct *work) | |||
51 | if (ret) | 51 | if (ret) |
52 | return; | 52 | return; |
53 | 53 | ||
54 | extcon_set_state(info->edev, EXTCON_USB_HOST, !id); | 54 | extcon_set_state_sync(info->edev, EXTCON_USB_HOST, !id); |
55 | } | 55 | } |
56 | 56 | ||
57 | static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id) | 57 | static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id) |
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 4aa3cb63fd41..bcd06306f3e8 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c | |||
@@ -314,10 +314,14 @@ static void heartbeat_onchannelcallback(void *context) | |||
314 | u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; | 314 | u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; |
315 | struct icmsg_negotiate *negop = NULL; | 315 | struct icmsg_negotiate *negop = NULL; |
316 | 316 | ||
317 | vmbus_recvpacket(channel, hbeat_txf_buf, | 317 | while (1) { |
318 | PAGE_SIZE, &recvlen, &requestid); | 318 | |
319 | vmbus_recvpacket(channel, hbeat_txf_buf, | ||
320 | PAGE_SIZE, &recvlen, &requestid); | ||
321 | |||
322 | if (!recvlen) | ||
323 | break; | ||
319 | 324 | ||
320 | if (recvlen > 0) { | ||
321 | icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ | 325 | icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ |
322 | sizeof(struct vmbuspipe_hdr)]; | 326 | sizeof(struct vmbuspipe_hdr)]; |
323 | 327 | ||
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 8a679ecc8fd1..fc2794b513fa 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c | |||
@@ -352,17 +352,27 @@ int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, | |||
352 | if (copy_from_user(sgl->lpage, user_addr + user_size - | 352 | if (copy_from_user(sgl->lpage, user_addr + user_size - |
353 | sgl->lpage_size, sgl->lpage_size)) { | 353 | sgl->lpage_size, sgl->lpage_size)) { |
354 | rc = -EFAULT; | 354 | rc = -EFAULT; |
355 | goto err_out1; | 355 | goto err_out2; |
356 | } | 356 | } |
357 | } | 357 | } |
358 | return 0; | 358 | return 0; |
359 | 359 | ||
360 | err_out2: | ||
361 | __genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage, | ||
362 | sgl->lpage_dma_addr); | ||
363 | sgl->lpage = NULL; | ||
364 | sgl->lpage_dma_addr = 0; | ||
360 | err_out1: | 365 | err_out1: |
361 | __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage, | 366 | __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage, |
362 | sgl->fpage_dma_addr); | 367 | sgl->fpage_dma_addr); |
368 | sgl->fpage = NULL; | ||
369 | sgl->fpage_dma_addr = 0; | ||
363 | err_out: | 370 | err_out: |
364 | __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl, | 371 | __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl, |
365 | sgl->sgl_dma_addr); | 372 | sgl->sgl_dma_addr); |
373 | sgl->sgl = NULL; | ||
374 | sgl->sgl_dma_addr = 0; | ||
375 | sgl->sgl_size = 0; | ||
366 | return -ENOMEM; | 376 | return -ENOMEM; |
367 | } | 377 | } |
368 | 378 | ||
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index e6e5e55a12ed..60415a2bfcbd 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c | |||
@@ -981,11 +981,13 @@ static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack) | |||
981 | hisr = mei_txe_br_reg_read(hw, HISR_REG); | 981 | hisr = mei_txe_br_reg_read(hw, HISR_REG); |
982 | 982 | ||
983 | aliveness = mei_txe_aliveness_get(dev); | 983 | aliveness = mei_txe_aliveness_get(dev); |
984 | if (hhisr & IPC_HHIER_SEC && aliveness) | 984 | if (hhisr & IPC_HHIER_SEC && aliveness) { |
985 | ipc_isr = mei_txe_sec_reg_read_silent(hw, | 985 | ipc_isr = mei_txe_sec_reg_read_silent(hw, |
986 | SEC_IPC_HOST_INT_STATUS_REG); | 986 | SEC_IPC_HOST_INT_STATUS_REG); |
987 | else | 987 | } else { |
988 | ipc_isr = 0; | 988 | ipc_isr = 0; |
989 | hhisr &= ~IPC_HHIER_SEC; | ||
990 | } | ||
989 | 991 | ||
990 | generated = generated || | 992 | generated = generated || |
991 | (hisr & HISR_INT_STS_MSK) || | 993 | (hisr & HISR_INT_STS_MSK) || |
diff --git a/drivers/misc/vmw_vmci/vmci_doorbell.c b/drivers/misc/vmw_vmci/vmci_doorbell.c index a8cee33ae8d2..b3fa738ae005 100644 --- a/drivers/misc/vmw_vmci/vmci_doorbell.c +++ b/drivers/misc/vmw_vmci/vmci_doorbell.c | |||
@@ -431,6 +431,12 @@ int vmci_doorbell_create(struct vmci_handle *handle, | |||
431 | if (vmci_handle_is_invalid(*handle)) { | 431 | if (vmci_handle_is_invalid(*handle)) { |
432 | u32 context_id = vmci_get_context_id(); | 432 | u32 context_id = vmci_get_context_id(); |
433 | 433 | ||
434 | if (context_id == VMCI_INVALID_ID) { | ||
435 | pr_warn("Failed to get context ID\n"); | ||
436 | result = VMCI_ERROR_NO_RESOURCES; | ||
437 | goto free_mem; | ||
438 | } | ||
439 | |||
434 | /* Let resource code allocate a free ID for us */ | 440 | /* Let resource code allocate a free ID for us */ |
435 | new_handle = vmci_make_handle(context_id, VMCI_INVALID_ID); | 441 | new_handle = vmci_make_handle(context_id, VMCI_INVALID_ID); |
436 | } else { | 442 | } else { |
@@ -525,7 +531,7 @@ int vmci_doorbell_destroy(struct vmci_handle handle) | |||
525 | 531 | ||
526 | entry = container_of(resource, struct dbell_entry, resource); | 532 | entry = container_of(resource, struct dbell_entry, resource); |
527 | 533 | ||
528 | if (vmci_guest_code_active()) { | 534 | if (!hlist_unhashed(&entry->node)) { |
529 | int result; | 535 | int result; |
530 | 536 | ||
531 | dbell_index_table_remove(entry); | 537 | dbell_index_table_remove(entry); |
diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vmci_driver.c index 896be150e28f..d7eaf1eb11e7 100644 --- a/drivers/misc/vmw_vmci/vmci_driver.c +++ b/drivers/misc/vmw_vmci/vmci_driver.c | |||
@@ -113,5 +113,5 @@ module_exit(vmci_drv_exit); | |||
113 | 113 | ||
114 | MODULE_AUTHOR("VMware, Inc."); | 114 | MODULE_AUTHOR("VMware, Inc."); |
115 | MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface."); | 115 | MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface."); |
116 | MODULE_VERSION("1.1.4.0-k"); | 116 | MODULE_VERSION("1.1.5.0-k"); |
117 | MODULE_LICENSE("GPL v2"); | 117 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c index 15b64076bc26..bdbadaa47ef3 100644 --- a/drivers/vme/vme.c +++ b/drivers/vme/vme.c | |||
@@ -156,12 +156,16 @@ size_t vme_get_size(struct vme_resource *resource) | |||
156 | case VME_MASTER: | 156 | case VME_MASTER: |
157 | retval = vme_master_get(resource, &enabled, &base, &size, | 157 | retval = vme_master_get(resource, &enabled, &base, &size, |
158 | &aspace, &cycle, &dwidth); | 158 | &aspace, &cycle, &dwidth); |
159 | if (retval) | ||
160 | return 0; | ||
159 | 161 | ||
160 | return size; | 162 | return size; |
161 | break; | 163 | break; |
162 | case VME_SLAVE: | 164 | case VME_SLAVE: |
163 | retval = vme_slave_get(resource, &enabled, &base, &size, | 165 | retval = vme_slave_get(resource, &enabled, &base, &size, |
164 | &buf_base, &aspace, &cycle); | 166 | &buf_base, &aspace, &cycle); |
167 | if (retval) | ||
168 | return 0; | ||
165 | 169 | ||
166 | return size; | 170 | return size; |
167 | break; | 171 | break; |