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; |
