Commit 2a290036 authored by Linus Torvalds's avatar Linus Torvalds

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
parents c636e176 a7d5afe8
...@@ -5287,6 +5287,12 @@ M: Joe Perches <joe@perches.com> ...@@ -5287,6 +5287,12 @@ M: Joe Perches <joe@perches.com>
S: Maintained S: Maintained
F: scripts/get_maintainer.pl F: scripts/get_maintainer.pl
GENWQE (IBM Generic Workqueue Card)
M: Frank Haverkamp <haver@linux.vnet.ibm.com>
M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
S: Supported
F: drivers/misc/genwqe/
GFS2 FILE SYSTEM GFS2 FILE SYSTEM
M: Steven Whitehouse <swhiteho@redhat.com> M: Steven Whitehouse <swhiteho@redhat.com>
M: Bob Peterson <rpeterso@redhat.com> M: Bob Peterson <rpeterso@redhat.com>
......
...@@ -1002,7 +1002,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal) ...@@ -1002,7 +1002,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)
static struct binder_ref *binder_get_ref(struct binder_proc *proc, static struct binder_ref *binder_get_ref(struct binder_proc *proc,
uint32_t desc) u32 desc, bool need_strong_ref)
{ {
struct rb_node *n = proc->refs_by_desc.rb_node; struct rb_node *n = proc->refs_by_desc.rb_node;
struct binder_ref *ref; struct binder_ref *ref;
...@@ -1010,13 +1010,17 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc, ...@@ -1010,13 +1010,17 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc,
while (n) { while (n) {
ref = rb_entry(n, struct binder_ref, rb_node_desc); ref = rb_entry(n, struct binder_ref, rb_node_desc);
if (desc < ref->desc) if (desc < ref->desc) {
n = n->rb_left; n = n->rb_left;
else if (desc > ref->desc) } else if (desc > ref->desc) {
n = n->rb_right; n = n->rb_right;
else } else if (need_strong_ref && !ref->strong) {
binder_user_error("tried to use weak ref as strong ref\n");
return NULL;
} else {
return ref; return ref;
} }
}
return NULL; return NULL;
} }
...@@ -1285,7 +1289,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, ...@@ -1285,7 +1289,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
} break; } break;
case BINDER_TYPE_HANDLE: case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: { case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle); struct binder_ref *ref;
ref = binder_get_ref(proc, fp->handle,
fp->type == BINDER_TYPE_HANDLE);
if (ref == NULL) { if (ref == NULL) {
pr_err("transaction release %d bad handle %d\n", pr_err("transaction release %d bad handle %d\n",
...@@ -1380,7 +1387,7 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -1380,7 +1387,7 @@ static void binder_transaction(struct binder_proc *proc,
if (tr->target.handle) { if (tr->target.handle) {
struct binder_ref *ref; struct binder_ref *ref;
ref = binder_get_ref(proc, tr->target.handle); ref = binder_get_ref(proc, tr->target.handle, true);
if (ref == NULL) { if (ref == NULL) {
binder_user_error("%d:%d got transaction to invalid handle\n", binder_user_error("%d:%d got transaction to invalid handle\n",
proc->pid, thread->pid); proc->pid, thread->pid);
...@@ -1577,7 +1584,9 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -1577,7 +1584,9 @@ static void binder_transaction(struct binder_proc *proc,
fp->type = BINDER_TYPE_HANDLE; fp->type = BINDER_TYPE_HANDLE;
else else
fp->type = BINDER_TYPE_WEAK_HANDLE; fp->type = BINDER_TYPE_WEAK_HANDLE;
fp->binder = 0;
fp->handle = ref->desc; fp->handle = ref->desc;
fp->cookie = 0;
binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
&thread->todo); &thread->todo);
...@@ -1589,7 +1598,10 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -1589,7 +1598,10 @@ static void binder_transaction(struct binder_proc *proc,
} break; } break;
case BINDER_TYPE_HANDLE: case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: { case BINDER_TYPE_WEAK_HANDLE: {
struct binder_ref *ref = binder_get_ref(proc, fp->handle); struct binder_ref *ref;
ref = binder_get_ref(proc, fp->handle,
fp->type == BINDER_TYPE_HANDLE);
if (ref == NULL) { if (ref == NULL) {
binder_user_error("%d:%d got transaction with invalid handle, %d\n", 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,7 +1636,9 @@ static void binder_transaction(struct binder_proc *proc,
return_error = BR_FAILED_REPLY; return_error = BR_FAILED_REPLY;
goto err_binder_get_ref_for_node_failed; goto err_binder_get_ref_for_node_failed;
} }
fp->binder = 0;
fp->handle = new_ref->desc; fp->handle = new_ref->desc;
fp->cookie = 0;
binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
trace_binder_transaction_ref_to_ref(t, ref, trace_binder_transaction_ref_to_ref(t, ref,
new_ref); new_ref);
...@@ -1678,6 +1692,7 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -1678,6 +1692,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_debug(BINDER_DEBUG_TRANSACTION, binder_debug(BINDER_DEBUG_TRANSACTION,
" fd %d -> %d\n", fp->handle, target_fd); " fd %d -> %d\n", fp->handle, target_fd);
/* TODO: fput? */ /* TODO: fput? */
fp->binder = 0;
fp->handle = target_fd; fp->handle = target_fd;
} break; } break;
...@@ -1800,7 +1815,9 @@ static int binder_thread_write(struct binder_proc *proc, ...@@ -1800,7 +1815,9 @@ static int binder_thread_write(struct binder_proc *proc,
ref->desc); ref->desc);
} }
} else } else
ref = binder_get_ref(proc, target); ref = binder_get_ref(proc, target,
cmd == BC_ACQUIRE ||
cmd == BC_RELEASE);
if (ref == NULL) { if (ref == NULL) {
binder_user_error("%d:%d refcount change on invalid ref %d\n", binder_user_error("%d:%d refcount change on invalid ref %d\n",
proc->pid, thread->pid, target); proc->pid, thread->pid, target);
...@@ -1996,7 +2013,7 @@ static int binder_thread_write(struct binder_proc *proc, ...@@ -1996,7 +2013,7 @@ static int binder_thread_write(struct binder_proc *proc,
if (get_user(cookie, (binder_uintptr_t __user *)ptr)) if (get_user(cookie, (binder_uintptr_t __user *)ptr))
return -EFAULT; return -EFAULT;
ptr += sizeof(binder_uintptr_t); ptr += sizeof(binder_uintptr_t);
ref = binder_get_ref(proc, target); ref = binder_get_ref(proc, target, false);
if (ref == NULL) { if (ref == NULL) {
binder_user_error("%d:%d %s invalid ref %d\n", binder_user_error("%d:%d %s invalid ref %d\n",
proc->pid, thread->pid, proc->pid, thread->pid,
......
...@@ -51,7 +51,7 @@ static void qcom_usb_extcon_detect_cable(struct work_struct *work) ...@@ -51,7 +51,7 @@ static void qcom_usb_extcon_detect_cable(struct work_struct *work)
if (ret) if (ret)
return; return;
extcon_set_state(info->edev, EXTCON_USB_HOST, !id); extcon_set_state_sync(info->edev, EXTCON_USB_HOST, !id);
} }
static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id) static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id)
......
...@@ -314,10 +314,14 @@ static void heartbeat_onchannelcallback(void *context) ...@@ -314,10 +314,14 @@ static void heartbeat_onchannelcallback(void *context)
u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
struct icmsg_negotiate *negop = NULL; struct icmsg_negotiate *negop = NULL;
while (1) {
vmbus_recvpacket(channel, hbeat_txf_buf, vmbus_recvpacket(channel, hbeat_txf_buf,
PAGE_SIZE, &recvlen, &requestid); PAGE_SIZE, &recvlen, &requestid);
if (recvlen > 0) { if (!recvlen)
break;
icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
sizeof(struct vmbuspipe_hdr)]; sizeof(struct vmbuspipe_hdr)];
......
...@@ -352,17 +352,27 @@ int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, ...@@ -352,17 +352,27 @@ int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
if (copy_from_user(sgl->lpage, user_addr + user_size - if (copy_from_user(sgl->lpage, user_addr + user_size -
sgl->lpage_size, sgl->lpage_size)) { sgl->lpage_size, sgl->lpage_size)) {
rc = -EFAULT; rc = -EFAULT;
goto err_out1; goto err_out2;
} }
} }
return 0; return 0;
err_out2:
__genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
sgl->lpage_dma_addr);
sgl->lpage = NULL;
sgl->lpage_dma_addr = 0;
err_out1: err_out1:
__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage, __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
sgl->fpage_dma_addr); sgl->fpage_dma_addr);
sgl->fpage = NULL;
sgl->fpage_dma_addr = 0;
err_out: err_out:
__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl, __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
sgl->sgl_dma_addr); sgl->sgl_dma_addr);
sgl->sgl = NULL;
sgl->sgl_dma_addr = 0;
sgl->sgl_size = 0;
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -981,11 +981,13 @@ static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack) ...@@ -981,11 +981,13 @@ static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack)
hisr = mei_txe_br_reg_read(hw, HISR_REG); hisr = mei_txe_br_reg_read(hw, HISR_REG);
aliveness = mei_txe_aliveness_get(dev); aliveness = mei_txe_aliveness_get(dev);
if (hhisr & IPC_HHIER_SEC && aliveness) if (hhisr & IPC_HHIER_SEC && aliveness) {
ipc_isr = mei_txe_sec_reg_read_silent(hw, ipc_isr = mei_txe_sec_reg_read_silent(hw,
SEC_IPC_HOST_INT_STATUS_REG); SEC_IPC_HOST_INT_STATUS_REG);
else } else {
ipc_isr = 0; ipc_isr = 0;
hhisr &= ~IPC_HHIER_SEC;
}
generated = generated || generated = generated ||
(hisr & HISR_INT_STS_MSK) || (hisr & HISR_INT_STS_MSK) ||
......
...@@ -431,6 +431,12 @@ int vmci_doorbell_create(struct vmci_handle *handle, ...@@ -431,6 +431,12 @@ int vmci_doorbell_create(struct vmci_handle *handle,
if (vmci_handle_is_invalid(*handle)) { if (vmci_handle_is_invalid(*handle)) {
u32 context_id = vmci_get_context_id(); u32 context_id = vmci_get_context_id();
if (context_id == VMCI_INVALID_ID) {
pr_warn("Failed to get context ID\n");
result = VMCI_ERROR_NO_RESOURCES;
goto free_mem;
}
/* Let resource code allocate a free ID for us */ /* Let resource code allocate a free ID for us */
new_handle = vmci_make_handle(context_id, VMCI_INVALID_ID); new_handle = vmci_make_handle(context_id, VMCI_INVALID_ID);
} else { } else {
...@@ -525,7 +531,7 @@ int vmci_doorbell_destroy(struct vmci_handle handle) ...@@ -525,7 +531,7 @@ int vmci_doorbell_destroy(struct vmci_handle handle)
entry = container_of(resource, struct dbell_entry, resource); entry = container_of(resource, struct dbell_entry, resource);
if (vmci_guest_code_active()) { if (!hlist_unhashed(&entry->node)) {
int result; int result;
dbell_index_table_remove(entry); dbell_index_table_remove(entry);
......
...@@ -113,5 +113,5 @@ module_exit(vmci_drv_exit); ...@@ -113,5 +113,5 @@ module_exit(vmci_drv_exit);
MODULE_AUTHOR("VMware, Inc."); MODULE_AUTHOR("VMware, Inc.");
MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface."); MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface.");
MODULE_VERSION("1.1.4.0-k"); MODULE_VERSION("1.1.5.0-k");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -156,12 +156,16 @@ size_t vme_get_size(struct vme_resource *resource) ...@@ -156,12 +156,16 @@ size_t vme_get_size(struct vme_resource *resource)
case VME_MASTER: case VME_MASTER:
retval = vme_master_get(resource, &enabled, &base, &size, retval = vme_master_get(resource, &enabled, &base, &size,
&aspace, &cycle, &dwidth); &aspace, &cycle, &dwidth);
if (retval)
return 0;
return size; return size;
break; break;
case VME_SLAVE: case VME_SLAVE:
retval = vme_slave_get(resource, &enabled, &base, &size, retval = vme_slave_get(resource, &enabled, &base, &size,
&buf_base, &aspace, &cycle); &buf_base, &aspace, &cycle);
if (retval)
return 0;
return size; return size;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment