mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-11 07:39:47 +00:00
Char/Misc driver fixes for 4.9-rc3
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iFYEABECABYFAlgUz3APHGdyZWdAa3JvYWguY29tAAoJEDFH1A3bLfspNGgAnibp VyUJZjQ7CDeIm2lD+Qgz/4a4AJ9xUaO6xmmmkov5QJ7LqscBmiw+jA== =1qM6 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
2a290036a1
@ -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)
|
|||||||
|
|
||||||
|
|
||||||
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,12 +1010,16 @@ 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,
|
|||||||
} 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
} 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
|
||||||
vmbus_recvpacket(channel, hbeat_txf_buf,
|
while (1) {
|
||||||
PAGE_SIZE, &recvlen, &requestid);
|
|
||||||
|
vmbus_recvpacket(channel, hbeat_txf_buf,
|
||||||
|
PAGE_SIZE, &recvlen, &requestid);
|
||||||
|
|
||||||
|
if (!recvlen)
|
||||||
|
break;
|
||||||
|
|
||||||
if (recvlen > 0) {
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
|
|
||||||
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);
|
|||||||
|
|
||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user