aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-29 14:19:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-29 14:19:02 -0400
commit2a290036a1e4c813ee913154cd0334bd07330582 (patch)
tree8ec1300dfd7a3e38a62046960b5ff8fc84efda55
parentc636e176d8e5afe2f3b3e3f1de33ec13f1cee308 (diff)
parenta7d5afe82d4931289250d6e807e35db3885b3b12 (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--MAINTAINERS6
-rw-r--r--drivers/android/binder.c35
-rw-r--r--drivers/extcon/extcon-qcom-spmi-misc.c2
-rw-r--r--drivers/hv/hv_util.c10
-rw-r--r--drivers/misc/genwqe/card_utils.c12
-rw-r--r--drivers/misc/mei/hw-txe.c6
-rw-r--r--drivers/misc/vmw_vmci/vmci_doorbell.c8
-rw-r--r--drivers/misc/vmw_vmci/vmci_driver.c2
-rw-r--r--drivers/vme/vme.c4
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>
5287S: Maintained 5287S: Maintained
5288F: scripts/get_maintainer.pl 5288F: scripts/get_maintainer.pl
5289 5289
5290GENWQE (IBM Generic Workqueue Card)
5291M: Frank Haverkamp <haver@linux.vnet.ibm.com>
5292M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
5293S: Supported
5294F: drivers/misc/genwqe/
5295
5290GFS2 FILE SYSTEM 5296GFS2 FILE SYSTEM
5291M: Steven Whitehouse <swhiteho@redhat.com> 5297M: Steven Whitehouse <swhiteho@redhat.com>
5292M: Bob Peterson <rpeterso@redhat.com> 5298M: 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
1004static struct binder_ref *binder_get_ref(struct binder_proc *proc, 1004static 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
57static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id) 57static 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
114MODULE_AUTHOR("VMware, Inc."); 114MODULE_AUTHOR("VMware, Inc.");
115MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface."); 115MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface.");
116MODULE_VERSION("1.1.4.0-k"); 116MODULE_VERSION("1.1.5.0-k");
117MODULE_LICENSE("GPL v2"); 117MODULE_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;