aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadhri Jagan Sridharan <badhri@google.com>2018-05-10 13:46:57 -0700
committerBadhri Jagan Sridharan <badhri@google.com>2018-05-10 20:55:55 +0000
commit5a2a297d83399ba9f45b36a4cf7977678865590a (patch)
tree246e05372d9348c70ff6ce1dfebf802c444eb5d6
parent56d0150e64b29eccbd0184107ed6b991296c1e19 (diff)
parent10d9656e3640c1add0de7cbc65f687ede281f871 (diff)
Merge branch 'android-msm-angler-3.10-security-next' into android-msm-angler-3.10android-8.1.0_r0.80
July 2018.1 Bug: 79366047 Change-Id: I13f70caa78d9794fe5bd5f53d1596ee981897598 Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com>
-rw-r--r--drivers/char/adsprpc.c92
-rw-r--r--drivers/char/adsprpc_compat.c14
-rw-r--r--drivers/char/adsprpc_shared.h25
-rw-r--r--drivers/cpuidle/lpm-levels-of.c10
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c4
-rw-r--r--drivers/scsi/sg.c5
-rw-r--r--drivers/soc/qcom/qdsp6v2/apr.c25
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_rotator.c9
-rw-r--r--kernel/futex.c103
-rw-r--r--net/ipv4/ip_output.c7
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv6/ip6_output.c7
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c10
13 files changed, 209 insertions, 104 deletions
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 865c85671610..e878a84cc109 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -80,7 +80,7 @@ static inline uintptr_t buf_page_offset(void *buf)
return offset;
}
-static inline int buf_num_pages(void *buf, ssize_t len)
+static inline int buf_num_pages(void *buf, size_t len)
{
uintptr_t start = buf_page_start(buf) >> PAGE_SHIFT;
uintptr_t end = (((uintptr_t) buf + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
@@ -152,7 +152,7 @@ struct fastrpc_buf {
struct ion_handle *handle;
void *virt;
ion_phys_addr_t phys;
- ssize_t size;
+ size_t size;
int used;
};
@@ -239,7 +239,7 @@ struct fastrpc_mmap {
ion_phys_addr_t phys;
uintptr_t *vaddrin;
uintptr_t vaddrout;
- ssize_t size;
+ size_t size;
int refs;
};
@@ -287,7 +287,7 @@ static int map_iommu_mem(struct ion_handle *handle, struct file_data *fdata,
ion_phys_addr_t *iova, unsigned long size)
{
struct fastrpc_apps *me = &gfa;
- struct fastrpc_mmap *map = 0, *mapmatch = 0;
+ struct fastrpc_mmap *map = NULL, *mapmatch = NULL;
struct hlist_node *n;
unsigned long len = size;
int cid = fdata->cid;
@@ -321,7 +321,7 @@ static void unmap_iommu_mem(struct ion_handle *handle, struct file_data *fdata,
int cached)
{
struct fastrpc_apps *me = &gfa;
- struct fastrpc_mmap *map = 0, *mapmatch = 0;
+ struct fastrpc_mmap *map = NULL, *mapmatch = NULL;
struct hlist_node *n;
int cid = fdata->cid;
@@ -356,10 +356,10 @@ static void free_mem(struct fastrpc_buf *buf, struct file_data *fd)
}
if (!IS_ERR_OR_NULL(buf->virt)) {
ion_unmap_kernel(me->iclient, buf->handle);
- buf->virt = 0;
+ buf->virt = NULL;
}
ion_free(me->iclient, buf->handle);
- buf->handle = 0;
+ buf->handle = NULL;
}
}
@@ -375,11 +375,11 @@ static void free_map(struct fastrpc_mmap *map, struct file_data *fdata)
}
if (!IS_ERR_OR_NULL(map->virt)) {
ion_unmap_kernel(me->iclient, map->handle);
- map->virt = 0;
+ map->virt = NULL;
}
ion_free(me->iclient, map->handle);
}
- map->handle = 0;
+ map->handle = NULL;
}
static int alloc_mem(struct fastrpc_buf *buf, struct file_data *fdata)
@@ -390,8 +390,8 @@ static int alloc_mem(struct fastrpc_buf *buf, struct file_data *fdata)
int err = 0;
int cid = fdata->cid;
unsigned int heap;
- buf->handle = 0;
- buf->virt = 0;
+ buf->handle = NULL;
+ buf->virt = NULL;
buf->phys = 0;
heap = me->channel[cid].smmu.enabled ? ION_HEAP(ION_IOMMU_HEAP_ID) :
ION_HEAP(ION_ADSP_HEAP_ID);
@@ -426,7 +426,7 @@ static int context_restore_interrupted(struct fastrpc_apps *me,
struct smq_invoke_ctx **po)
{
int err = 0;
- struct smq_invoke_ctx *ctx = 0, *ictx = 0;
+ struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
struct hlist_node *n;
struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
spin_lock(&me->clst.hlock);
@@ -522,7 +522,7 @@ static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
struct smq_invoke_ctx **po)
{
int err = 0, bufs, ii, size = 0;
- struct smq_invoke_ctx *ctx = 0;
+ struct smq_invoke_ctx *ctx = NULL;
struct smq_context_list *clst = &me->clst;
struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
@@ -536,7 +536,7 @@ static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
bufs * sizeof(*ctx->handles);
}
- VERIFY(err, 0 != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
+ VERIFY(err, NULL != (ctx = kzalloc(sizeof(*ctx) + size, GFP_KERNEL)));
if (err)
goto bail;
@@ -544,8 +544,8 @@ static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
ctx->apps = me;
ctx->fdata = fdata;
ctx->pra = (remote_arg_t *)(&ctx[1]);
- ctx->fds = invokefd->fds == 0 ? 0 : (int *)(&ctx->pra[bufs]);
- ctx->handles = invokefd->fds == 0 ? 0 :
+ ctx->fds = invokefd->fds == NULL ? NULL : (int *)(&ctx->pra[bufs]);
+ ctx->handles = invokefd->fds == NULL ? NULL :
(struct ion_handle **)(&ctx->fds[bufs]);
if (!kernel) {
VERIFY(err, 0 == copy_from_user(ctx->pra, invoke->pra,
@@ -680,7 +680,7 @@ static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
static void context_notify_all_users(struct smq_context_list *me, int cid)
{
- struct smq_invoke_ctx *ictx = 0;
+ struct smq_invoke_ctx *ictx = NULL;
struct hlist_node *n;
spin_lock(&me->hlock);
hlist_for_each_entry_safe(ictx, n, &me->pending, hn) {
@@ -705,10 +705,10 @@ static void context_list_ctor(struct smq_context_list *me)
static void context_list_dtor(struct fastrpc_apps *me,
struct smq_context_list *clst)
{
- struct smq_invoke_ctx *ictx = 0, *ctxfree;
+ struct smq_invoke_ctx *ictx = NULL, *ctxfree;
struct hlist_node *n;
do {
- ctxfree = 0;
+ ctxfree = NULL;
spin_lock(&clst->hlock);
hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
hlist_del(&ictx->hn);
@@ -741,7 +741,7 @@ static int get_page_list(uint32_t kernel, struct smq_invoke_ctx *ctx)
struct fastrpc_buf *ibuf = &ctx->dev->buf;
struct fastrpc_buf *obuf = &ctx->obuf;
remote_arg_t *pra = ctx->pra;
- ssize_t rlen;
+ size_t rlen;
uint32_t sc = ctx->sc;
int cid = ctx->fdata->cid;
int i, err = 0;
@@ -768,7 +768,7 @@ static int get_page_list(uint32_t kernel, struct smq_invoke_ctx *ctx)
for (i = 0; i < inbufs + outbufs; ++i) {
void *buf;
int num;
- ssize_t len;
+ size_t len;
list[i].num = 0;
list[i].pgidx = 0;
@@ -875,14 +875,14 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
{
struct fastrpc_apps *me = &gfa;
struct smq_invoke_buf *list;
- struct fastrpc_buf *pbuf = &ctx->obuf, *obufs = 0;
+ struct fastrpc_buf *pbuf = &ctx->obuf, *obufs = NULL;
struct smq_phy_page *pages;
struct vm_area_struct *vma;
struct ion_handle **handles = ctx->handles;
void *args;
remote_arg_t *pra = ctx->pra;
remote_arg_t *rpra = ctx->rpra;
- ssize_t rlen, used, size, copylen = 0;
+ size_t rlen, used, size, copylen = 0;
uint32_t sc = ctx->sc, start;
int i, inh, bufs = 0, err = 0, oix;
int inbufs = REMOTE_SCALARS_INBUFS(sc);
@@ -975,7 +975,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
/* copy non ion buffers */
for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
- ssize_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
+ size_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
if (!pra[i].buf.len)
continue;
if (list[i].num)
@@ -1270,7 +1270,7 @@ static void free_dev(struct fastrpc_device *dev, struct file_data *fdata)
static int alloc_dev(struct fastrpc_device **dev, struct file_data *fdata)
{
int err = 0;
- struct fastrpc_device *fd = 0;
+ struct fastrpc_device *fd = NULL;
VERIFY(err, 0 != try_module_get(THIS_MODULE));
if (err)
@@ -1298,7 +1298,7 @@ static int get_dev(struct fastrpc_apps *me, struct file_data *fdata,
struct fastrpc_device **rdev)
{
struct hlist_head *head;
- struct fastrpc_device *dev = 0, *devfree = 0;
+ struct fastrpc_device *dev = NULL, *devfree = NULL;
struct hlist_node *n;
uint32_t h = hash_32(current->tgid, RPC_HASH_BITS);
int err = 0;
@@ -1344,7 +1344,7 @@ static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t mode,
struct fastrpc_ioctl_invoke_fd *invokefd,
struct file_data *fdata)
{
- struct smq_invoke_ctx *ctx = 0;
+ struct smq_invoke_ctx *ctx = NULL;
struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
int cid = fdata->cid;
int interrupted = 0;
@@ -1433,8 +1433,8 @@ static int fastrpc_init_process(struct file_data *fdata,
{
int err = 0;
struct fastrpc_ioctl_invoke_fd ioctl;
- struct smq_phy_page *pages = 0;
- struct fastrpc_mmap *map = 0;
+ struct smq_phy_page *pages = NULL;
+ struct fastrpc_mmap *map = NULL;
int npages = 0;
struct fastrpc_apps *me = &gfa;
if (init->flags == FASTRPC_INIT_ATTACH) {
@@ -1589,7 +1589,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_apps *me,
struct {
int pid;
uintptr_t vaddrout;
- ssize_t size;
+ size_t size;
} inargs;
inargs.pid = current->tgid;
@@ -1643,9 +1643,9 @@ static int map_buffer(struct fastrpc_apps *me, struct file_data *fdata,
struct smq_phy_page **ppages, int *pnpages)
{
struct ion_client *clnt = gfa.iclient;
- struct ion_handle *handle = 0;
- struct fastrpc_mmap *map = 0, *mapmatch = 0;
- struct smq_phy_page *pages = 0;
+ struct ion_handle *handle = NULL;
+ struct fastrpc_mmap *map = NULL, *mapmatch = NULL;
+ struct smq_phy_page *pages = NULL;
struct hlist_node *n;
uintptr_t vaddrout = 0;
int num;
@@ -1722,8 +1722,8 @@ static int fastrpc_internal_mmap(struct fastrpc_apps *me,
struct fastrpc_ioctl_mmap *mmap)
{
- struct fastrpc_mmap *map = 0;
- struct smq_phy_page *pages = 0;
+ struct fastrpc_mmap *map = NULL;
+ struct smq_phy_page *pages = NULL;
int num = 0;
int err = 0;
VERIFY(err, 0 == map_buffer(me, fdata, mmap->fd, (char *)mmap->vaddrin,
@@ -1753,7 +1753,7 @@ static void cleanup_current_dev(struct file_data *fdata)
struct fastrpc_device *dev, *devfree;
rnext:
- devfree = dev = 0;
+ devfree = dev = NULL;
spin_lock(&me->hlock);
head = &me->htbl[h];
hlist_for_each_entry_safe(dev, n, head, hn) {
@@ -1791,9 +1791,9 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
struct file_data *fdata = (struct file_data *)file->private_data;
struct fastrpc_apps *me = &gfa;
struct smq_context_list *clst = &me->clst;
- struct smq_invoke_ctx *ictx = 0, *ctxfree;
+ struct smq_invoke_ctx *ictx = NULL, *ctxfree;
struct hlist_node *n;
- struct fastrpc_mmap *map = 0;
+ struct fastrpc_mmap *map = NULL;
int cid = MINOR(inode->i_rdev);
if (!fdata)
@@ -1801,7 +1801,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
(void)fastrpc_release_current_dsp_process(fdata);
do {
- ctxfree = 0;
+ ctxfree = NULL;
spin_lock(&clst->hlock);
hlist_for_each_entry_safe(ictx, n, &clst->interrupted, hn) {
if ((ictx->tgid == current->tgid) &&
@@ -1839,7 +1839,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
mutex_lock(&me->smd_mutex);
ssrcount = me->channel[cid].ssrcount;
if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
- (me->channel[cid].chan == 0)) {
+ (me->channel[cid].chan == NULL)) {
VERIFY(err, 0 == smd_named_open_on_edge(
FASTRPC_SMD_GUID,
gcinfo[cid].channel,
@@ -1859,9 +1859,9 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
}
mutex_unlock(&me->smd_mutex);
- filp->private_data = 0;
+ filp->private_data = NULL;
if (0 != try_module_get(THIS_MODULE)) {
- struct file_data *fdata = 0;
+ struct file_data *fdata = NULL;
/* This call will cause a dev to be created
* which will addref this module
*/
@@ -1891,7 +1891,7 @@ bail:
completion_bail:
smd_close(me->channel[cid].chan);
- me->channel[cid].chan = 0;
+ me->channel[cid].chan = NULL;
smd_bail:
mutex_unlock(&me->smd_mutex);
return err;
@@ -1913,7 +1913,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
switch (ioctl_num) {
case FASTRPC_IOCTL_INVOKE_FD:
case FASTRPC_IOCTL_INVOKE:
- invokefd.fds = 0;
+ invokefd.fds = NULL;
size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
sizeof(invokefd.inv) : sizeof(invokefd);
VERIFY(err, 0 == copy_from_user(&invokefd, param, size));
@@ -1994,7 +1994,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb,
ctx->ssrcount++;
if (ctx->chan) {
smd_close(ctx->chan);
- ctx->chan = 0;
+ ctx->chan = NULL;
pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
MAJOR(me->dev_no), cid);
}
diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c
index ee324dcf91f0..160ad1851c9a 100644
--- a/drivers/char/adsprpc_compat.c
+++ b/drivers/char/adsprpc_compat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,7 +33,7 @@
struct compat_remote_buf {
compat_uptr_t pv; /* buffer pointer */
- compat_ssize_t len; /* length of buffer */
+ compat_size_t len; /* length of buffer */
};
union compat_remote_arg {
@@ -56,13 +56,13 @@ struct compat_fastrpc_ioctl_mmap {
compat_int_t fd; /* ion fd */
compat_uint_t flags; /* flags for dsp to map with */
compat_uptr_t vaddrin; /* optional virtual address */
- compat_ssize_t size; /* size */
+ compat_size_t size; /* size */
compat_uptr_t vaddrout; /* dsps virtual address */
};
struct compat_fastrpc_ioctl_munmap {
compat_uptr_t vaddrout; /* address to unmap */
- compat_ssize_t size; /* size */
+ compat_size_t size; /* size */
};
struct compat_fastrpc_ioctl_init {
@@ -81,7 +81,7 @@ static int compat_get_fastrpc_ioctl_invoke(
unsigned int cmd)
{
compat_uint_t u, sc;
- compat_ssize_t s;
+ compat_size_t s;
compat_uptr_t p;
struct fastrpc_ioctl_invoke_fd *inv;
union compat_remote_arg *pra32;
@@ -164,7 +164,7 @@ static int compat_get_fastrpc_ioctl_mmap(
{
compat_uint_t u;
compat_int_t i;
- compat_ssize_t s;
+ compat_size_t s;
compat_uptr_t p;
int err;
@@ -198,7 +198,7 @@ static int compat_get_fastrpc_ioctl_munmap(
struct fastrpc_ioctl_munmap __user *unmap)
{
compat_uptr_t p;
- compat_ssize_t s;
+ compat_size_t s;
int err;
err = get_user(p, &unmap32->vaddrout);
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index c8e31369cef1..b8e5f23a56c0 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014,2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -93,7 +93,7 @@ do {\
struct remote_buf {
void *pv; /* buffer pointer */
- ssize_t len; /* length of buffer */
+ size_t len; /* length of buffer */
};
union remote_arg {
@@ -114,25 +114,25 @@ struct fastrpc_ioctl_invoke_fd {
struct fastrpc_ioctl_init {
uint32_t flags; /* one of FASTRPC_INIT_* macros */
- uintptr_t __user file; /* pointer to elf file */
- int32_t filelen; /* elf file length */
+ uintptr_t file; /* pointer to elf file */
+ uint32_t filelen; /* elf file length */
int32_t filefd; /* ION fd for the file */
- uintptr_t __user mem; /* mem for the PD */
- int32_t memlen; /* mem length */
+ uintptr_t mem; /* mem for the PD */
+ uint32_t memlen; /* mem length */
int32_t memfd; /* ION fd for the mem */
};
struct fastrpc_ioctl_munmap {
uintptr_t vaddrout; /* address to unmap */
- ssize_t size; /* size */
+ size_t size; /* size */
};
struct fastrpc_ioctl_mmap {
int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
- uintptr_t __user *vaddrin; /* optional virtual address */
- ssize_t size; /* size */
+ uintptr_t vaddrin; /* optional virtual address */
+ size_t size; /* size */
uintptr_t vaddrout; /* dsps virtual address */
};
@@ -144,7 +144,7 @@ struct smq_null_invoke {
struct smq_phy_page {
unsigned long addr; /* physical address */
- ssize_t size; /* size of contiguous region */
+ size_t size; /* size of contiguous region */
};
struct smq_invoke_buf {
@@ -171,14 +171,15 @@ struct smq_invoke_rsp {
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg_t *pra,
uint32_t sc)
{
- int len = REMOTE_SCALARS_LENGTH(sc);
+ unsigned int len = REMOTE_SCALARS_LENGTH(sc);
+
return (struct smq_invoke_buf *)(&pra[len]);
}
static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
struct smq_invoke_buf *buf)
{
- int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
+ uint32_t nTotal = REMOTE_SCALARS_INBUFS(sc)+REMOTE_SCALARS_OUTBUFS(sc);
return (struct smq_phy_page *)(&buf[nTotal]);
}
diff --git a/drivers/cpuidle/lpm-levels-of.c b/drivers/cpuidle/lpm-levels-of.c
index f136a86036eb..d2202b43e907 100644
--- a/drivers/cpuidle/lpm-levels-of.c
+++ b/drivers/cpuidle/lpm-levels-of.c
@@ -576,14 +576,12 @@ failed:
void free_cluster_node(struct lpm_cluster *cluster)
{
- struct list_head *list;
int i;
+ struct lpm_cluster *cl, *m;
- list_for_each(list, &cluster->child) {
- struct lpm_cluster *n;
- n = list_entry(list, typeof(*n), list);
- list_del(list);
- free_cluster_node(n);
+ list_for_each_entry_safe(cl, m, &cluster->child, list) {
+ list_del(&cl->list);
+ free_cluster_node(cl);
};
if (cluster->cpu) {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
index b96d7be1e18d..c82b4f5cc9db 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
@@ -603,6 +603,10 @@ static long msm_ois_subdev_do_ioctl(
parg = &ois_data;
break;
}
+ break;
+ case VIDIOC_MSM_OIS_CFG:
+ pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
+ return -EINVAL;
}
rc = msm_ois_subdev_ioctl(sd, cmd, parg);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index f40dbef23c31..d0074071f662 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1985,11 +1985,12 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
if ((1 == resp->done) && (!resp->sg_io_owned) &&
((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
resp->done = 2; /* guard against other readers */
- break;
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+ return resp;
}
}
write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
- return resp;
+ return NULL;
}
/* always adds to end of list */
diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c
index 5f25054e9f02..eeb07916a6e6 100644
--- a/drivers/soc/qcom/qdsp6v2/apr.c
+++ b/drivers/soc/qcom/qdsp6v2/apr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015, 2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -404,19 +404,19 @@ struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn,
mutex_unlock(&svc->m_lock);
return NULL;
}
- if (!svc->port_cnt && !svc->svc_cnt)
+ if (!svc->svc_cnt)
clnt->svc_cnt++;
svc->port_cnt++;
svc->port_fn[temp_port] = svc_fn;
svc->port_priv[temp_port] = priv;
+ svc->svc_cnt++;
} else {
if (!svc->fn) {
- if (!svc->port_cnt && !svc->svc_cnt)
+ if (!svc->svc_cnt)
clnt->svc_cnt++;
svc->fn = svc_fn;
- if (svc->port_cnt)
- svc->svc_cnt++;
svc->priv = priv;
+ svc->svc_cnt++;
}
}
@@ -622,24 +622,17 @@ int apr_deregister(void *handle)
client_id = svc->client_id;
clnt = &client[dest_id][client_id];
- if (svc->port_cnt > 0 || svc->svc_cnt > 0) {
+ if (svc->svc_cnt > 0) {
if (svc->port_cnt)
svc->port_cnt--;
- else if (svc->svc_cnt)
- svc->svc_cnt--;
- if (!svc->port_cnt && !svc->svc_cnt) {
+ svc->svc_cnt--;
+ if (!svc->svc_cnt) {
client[dest_id][client_id].svc_cnt--;
- svc->need_reset = 0x0;
- }
- } else if (client[dest_id][client_id].svc_cnt > 0) {
- client[dest_id][client_id].svc_cnt--;
- if (!client[dest_id][client_id].svc_cnt) {
- svc->need_reset = 0x0;
pr_debug("%s: service is reset %pK\n", __func__, svc);
}
}
- if (!svc->port_cnt && !svc->svc_cnt) {
+ if (!svc->svc_cnt) {
svc->priv = NULL;
svc->id = 0;
svc->fn = NULL;
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index 737ef9df3ddc..7301ea087b16 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -43,6 +43,7 @@ struct mdss_mdp_rot_pipe {
struct mdss_mdp_rot_session_mgr {
struct list_head queue;
struct mutex session_lock;
+ struct mutex req_lock;
int session_id;
int session_count;
@@ -77,6 +78,7 @@ int mdss_mdp_rot_mgr_init(void)
mutex_init(&rot_mgr->session_lock);
mutex_init(&rot_mgr->pipe_lock);
+ mutex_init(&rot_mgr->req_lock);
INIT_LIST_HEAD(&rot_mgr->queue);
rot_mgr->rot_work_queue = alloc_workqueue("rot_commit_workq",
WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM,
@@ -1019,9 +1021,11 @@ int mdss_mdp_rotator_play(struct msm_fb_data_type *mfd,
u32 flgs;
struct mdss_mdp_data src_buf;
+ mutex_lock(&rot_mgr->req_lock);
rot = mdss_mdp_rot_mgr_get_session(req->id);
if (!rot) {
pr_err("invalid session id=%x\n", req->id);
+ mutex_unlock(&rot_mgr->req_lock);
return -ENOENT;
}
@@ -1072,6 +1076,7 @@ int mdss_mdp_rotator_play(struct msm_fb_data_type *mfd,
dst_buf_fail:
mutex_unlock(&rot->lock);
+ mutex_unlock(&rot_mgr->req_lock);
mdss_iommu_ctrl(0);
return ret;
}
@@ -1081,9 +1086,11 @@ int mdss_mdp_rotator_unset(int ndx)
struct mdss_mdp_rotator_session *rot;
int ret = 0;
+ mutex_lock(&rot_mgr->req_lock);
rot = mdss_mdp_rot_mgr_get_session(ndx);
if (rot)
ret = mdss_mdp_rotator_release(rot);
+ mutex_unlock(&rot_mgr->req_lock);
return ret;
}
diff --git a/kernel/futex.c b/kernel/futex.c
index 8034766c370b..8f0012ec7739 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -243,6 +243,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
unsigned long address = (unsigned long)uaddr;
struct mm_struct *mm = current->mm;
struct page *page, *page_head;
+ struct address_space *mapping;
int err, ro = 0;
/*
@@ -320,7 +321,19 @@ again:
}
#endif
- lock_page(page_head);
+ /*
+ * The treatment of mapping from this point on is critical. The page
+ * lock protects many things but in this context the page lock
+ * stabilizes mapping, prevents inode freeing in the shared
+ * file-backed region case and guards against movement to swap cache.
+ *
+ * Strictly speaking the page lock is not needed in all cases being
+ * considered here and page lock forces unnecessarily serialization
+ * From this point on, mapping will be re-verified if necessary and
+ * page lock will be acquired only if it is unavoidable
+ */
+
+ mapping = READ_ONCE(page_head->mapping);
/*
* If page_head->mapping is NULL, then it cannot be a PageAnon
@@ -337,18 +350,31 @@ again:
* shmem_writepage move it from filecache to swapcache beneath us:
* an unlikely race, but we do need to retry for page_head->mapping.
*/
- if (!page_head->mapping) {
- int shmem_swizzled = PageSwapCache(page_head);
+ if (unlikely(!mapping)) {
+ int shmem_swizzled;
+
+ /*
+ * Page lock is required to identify which special case above
+ * applies. If this is really a shmem page then the page lock
+ * will prevent unexpected transitions.
+ */
+ lock_page(page);
+ shmem_swizzled = PageSwapCache(page) || page->mapping;
unlock_page(page_head);
put_page(page_head);
+
if (shmem_swizzled)
goto again;
+
return -EFAULT;
}
/*
* Private mappings are handled in a simple way.
*
+ * If the futex key is stored on an anonymous page, then the associated
+ * object is the mm which is implicitly pinned by the calling process.
+ *
* NOTE: When userspace waits on a MAP_SHARED mapping, even if
* it's a read-only handle, it's expected that futexes attach to
* the object not the particular process.
@@ -366,16 +392,74 @@ again:
key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */
key->private.mm = mm;
key->private.address = address;
+
+ get_futex_key_refs(key); /* implies smp_mb(); (B) */
+
} else {
+ struct inode *inode;
+
+ /*
+ * The associated futex object in this case is the inode and
+ * the page->mapping must be traversed. Ordinarily this should
+ * be stabilised under page lock but it's not strictly
+ * necessary in this case as we just want to pin the inode, not
+ * update the radix tree or anything like that.
+ *
+ * The RCU read lock is taken as the inode is finally freed
+ * under RCU. If the mapping still matches expectations then the
+ * mapping->host can be safely accessed as being a valid inode.
+ */
+ rcu_read_lock();
+
+ if (READ_ONCE(page_head->mapping) != mapping) {
+ rcu_read_unlock();
+ put_page(page_head);
+
+ goto again;
+ }
+
+ inode = READ_ONCE(mapping->host);
+ if (!inode) {
+ rcu_read_unlock();
+ put_page(page_head);
+
+ goto again;
+ }
+
+ /*
+ * Take a reference unless it is about to be freed. Previously
+ * this reference was taken by ihold under the page lock
+ * pinning the inode in place so i_lock was unnecessary. The
+ * only way for this check to fail is if the inode was
+ * truncated in parallel so warn for now if this happens.
+ *
+ * We are not calling into get_futex_key_refs() in file-backed
+ * cases, therefore a successful atomic_inc return below will
+ * guarantee that get_futex_key() will still imply smp_mb(); (B).
+ */
+ if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) {
+ rcu_read_unlock();
+ put_page(page_head);
+
+ goto again;
+ }
+
+ /* Should be impossible but lets be paranoid for now */
+ if (WARN_ON_ONCE(inode->i_mapping != mapping)) {
+ err = -EFAULT;
+ rcu_read_unlock();
+ iput(inode);
+
+ goto out;
+ }
+
key->both.offset |= FUT_OFF_INODE; /* inode-based key */
- key->shared.inode = page_head->mapping->host;
- key->shared.pgoff = basepage_index(page);
+ key->shared.inode = inode;
+ key->shared.pgoff = page_head->index;
+ rcu_read_unlock();
}
- get_futex_key_refs(key);
-
out:
- unlock_page(page_head);
put_page(page_head);
return err;
}
@@ -1375,6 +1459,9 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
struct plist_head *head1;
struct futex_q *this, *next;
+ if (nr_wake < 0 || nr_requeue < 0)
+ return -EINVAL;
+
if (requeue_pi) {
/*
* Requeue PI only works on two distinct uaddrs. This
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 47d236156f0f..b3458e0cd84f 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -843,10 +843,12 @@ static int __ip_append_data(struct sock *sk,
csummode = CHECKSUM_PARTIAL;
cork->length += length;
- if (((length > mtu) || (skb && skb_has_frags(skb))) &&
+ if ((skb && skb_has_frags(skb)) ||
+ ((length > mtu) &&
+ (skb_queue_len(queue) <= 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
- (sk->sk_type == SOCK_DGRAM)) {
+ (sk->sk_type == SOCK_DGRAM))) {
err = ip_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, transhdrlen,
maxfraglen, flags);
@@ -1157,6 +1159,7 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
cork->length += size;
if ((size + skb->len > mtu) &&
+ (skb_queue_len(&sk->sk_write_queue) == 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO)) {
skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 333dcb2f5e6d..657b0e6531f2 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -769,7 +769,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
if (is_udplite) /* UDP-Lite */
csum = udplite_csum(skb);
- else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */
+ else if (sk->sk_no_check == UDP_CSUM_NOXMIT && !skb_has_frags(skb)) { /* UDP csum off */
skb->ip_summed = CHECKSUM_NONE;
goto send;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 1d165d5cb6b7..40f766e6f5c3 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1286,11 +1286,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
skb = skb_peek_tail(&sk->sk_write_queue);
cork->length += length;
- if (((length > mtu) ||
- (skb && skb_has_frags(skb))) &&
+ if ((skb && skb_has_frags(skb)) ||
+ (((length + fragheaderlen) > mtu) &&
+ (skb_queue_len(&sk->sk_write_queue) <= 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) &&
- (sk->sk_type == SOCK_DGRAM)) {
+ (sk->sk_type == SOCK_DGRAM))) {
err = ip6_ufo_append_data(sk, getfrag, from, length,
hh_len, fragheaderlen,
transhdrlen, mtu, flags, rt);
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 2f46e43d4739..737cb0cbb4c3 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -135,6 +135,11 @@ static ssize_t audio_output_latency_dbgfs_read(struct file *file,
pr_err("%s: out_buffer is null\n", __func__);
return 0;
}
+ if (count < OUT_BUFFER_SIZE) {
+ pr_err("%s: read size %d exceeds buf size %zd\n", __func__,
+ OUT_BUFFER_SIZE, count);
+ return 0;
+ }
snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\
out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\
out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
@@ -188,6 +193,11 @@ static ssize_t audio_input_latency_dbgfs_read(struct file *file,
pr_err("%s: in_buffer is null\n", __func__);
return 0;
}
+ if (count < IN_BUFFER_SIZE) {
+ pr_err("%s: read size %d exceeds buf size %zd\n", __func__,
+ IN_BUFFER_SIZE, count);
+ return 0;
+ }
snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\
in_cont_tv.tv_sec, in_cont_tv.tv_usec);
return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,