summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-06-21 15:37:37 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2018-06-21 15:37:37 +0200
commite86ab6530fd4e461ae622b6c1ff72359952a7189 (patch)
treefb387e644216e47c13da26c5dbecab6822714393 /drivers
parente81dd8a3500fea94ce8786554cbc29bc6b2a9207 (diff)
parente78bb38b883c42edf81766a1d557aed74458e08f (diff)
Merge tag 'tegra-l4t-r21.7' into toradex_tk1_l4t_r21.7-next
Merge NVIDIA's latest Linux for Tegra aka L4T R21.7 Linux kernel changes from git://nv-tegra.nvidia.com/linux-3.10.git commit: e78bb38b883c42edf81766a1d557aed74458e08f Conflicts involved missing 24-bit LVDS support and a single whitespace aka tab difference in drivers/video/tegra/dc/sor.c. Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c19
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c31
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c7
-rw-r--r--drivers/hid/hid-core.c3
-rw-r--r--drivers/media/i2c/ad9389b.c4
-rw-r--r--drivers/media/i2c/adv7604.c4
-rw-r--r--drivers/media/i2c/ov7670.c4
-rw-r--r--drivers/media/i2c/ov9650.c3
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c7
-rw-r--r--drivers/media/i2c/s5k6aa.c3
-rw-r--r--drivers/media/tuners/tuner-xc2028.c3
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c3
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c3
-rw-r--r--drivers/misc/tegra-cryptodev.c70
-rw-r--r--drivers/pci/host/pci-tegra.c21
-rw-r--r--drivers/scsi/sg.c8
-rw-r--r--drivers/staging/android/ion/ion_heap.c12
-rw-r--r--drivers/thermal/thermal_core.c11
-rw-r--r--drivers/tty/tty_ldisc.c7
-rw-r--r--drivers/video/tegra/dc/sor.c4
-rw-r--r--drivers/video/tegra/dc/sor_regs.h2
-rw-r--r--drivers/video/tegra/host/host1x/host1x.c5
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.c9
25 files changed, 220 insertions, 31 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 3065e8403559..0a48f6a551ae 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -3,7 +3,7 @@
*
* GK20A Graphics channel
*
- * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -669,7 +669,7 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
memset(&ch->ramfc, 0, sizeof(struct mem_desc_sub));
/* free gpfifo */
- if (ch->gpfifo.gpu_va)
+ if (ch->vm && ch->gpfifo.gpu_va)
gk20a_gmmu_unmap(ch_vm, ch->gpfifo.gpu_va,
ch->gpfifo.size, gk20a_mem_flag_none);
if (ch->gpfifo.cpu_va)
@@ -698,8 +698,9 @@ unbind:
channel_gk20a_unbind(ch);
channel_gk20a_free_inst(g, ch);
- ch->vpr = false;
+ gk20a_vm_put(ch->vm); /* Don't use VM after this. */
ch->vm = NULL;
+ ch->vpr = false;
WARN_ON(ch->sync);
/* unlink all debug sessions */
@@ -2066,6 +2067,18 @@ long gk20a_channel_ioctl(struct file *filp,
(struct nvhost_alloc_obj_ctx_args *)buf);
gk20a_idle(dev);
break;
+ case NVHOST_IOCTL_CHANNEL_FREE_OBJ_CTX:
+ err = gk20a_busy(dev);
+ if (err) {
+ dev_err(&dev->dev,
+ "%s: failed to host gk20a for ioctl cmd: 0x%x",
+ __func__, cmd);
+ return err;
+ }
+ err = gk20a_free_obj_ctx(ch,
+ (struct nvhost_free_obj_ctx_args *)buf);
+ gk20a_idle(dev);
+ break;
case NVHOST_IOCTL_CHANNEL_ALLOC_GPFIFO:
err = gk20a_busy(dev);
if (err) {
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 831db0f4986a..547bb064fd63 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -3,7 +3,7 @@
*
* GK20A graphics channel
*
- * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -98,6 +98,7 @@ struct channel_gk20a {
u64 userd_iova;
u64 userd_gpu_va;
+ s32 num_objects;
u32 obj_class; /* we support only one obj per channel */
struct priv_cmd_queue priv_cmd_q;
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index d5a3bbd34a78..db34cc0e85e9 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -1,7 +1,7 @@
/*
* GK20A Graphics
*
- * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,6 +26,7 @@
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/nvhost.h>
+#include <asm/barrier.h>
#include "gk20a.h"
#include "kind_gk20a.h"
@@ -2697,6 +2698,7 @@ void gk20a_free_channel_ctx(struct channel_gk20a *c)
memset(&c->ch_ctx, 0, sizeof(struct channel_ctx_gk20a));
+ c->num_objects = 0;
c->first_init = false;
}
@@ -2847,6 +2849,8 @@ int gk20a_alloc_obj_ctx(struct channel_gk20a *c,
c->first_init = true;
}
+ c->num_objects++;
+
gk20a_dbg_fn("done");
return 0;
out:
@@ -2858,6 +2862,29 @@ out:
return err;
}
+int gk20a_free_obj_ctx(struct channel_gk20a *c,
+ struct nvhost_free_obj_ctx_args *args)
+{
+ unsigned long timeout = gk20a_get_gr_idle_timeout(c->g);
+
+ gk20a_dbg_fn("");
+
+ if (c->num_objects == 0)
+ return 0;
+
+ c->num_objects--;
+
+ if (c->num_objects == 0) {
+ c->first_init = false;
+ gk20a_disable_channel(c,
+ !c->has_timedout,
+ timeout);
+ gr_gk20a_unmap_channel_patch_ctx(c);
+ }
+
+ return 0;
+}
+
static void gk20a_remove_gr_support(struct gr_gk20a *gr)
{
struct gk20a *g = gr->g;
@@ -3568,6 +3595,7 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr,
mutex_lock(&gr->zbc_lock);
switch (zbc_val->type) {
case GK20A_ZBC_TYPE_COLOR:
+ speculation_barrier();
/* search existing tables */
for (i = 0; i < gr->max_used_color_index; i++) {
@@ -3606,6 +3634,7 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr,
}
break;
case GK20A_ZBC_TYPE_DEPTH:
+ speculation_barrier();
/* search existing tables */
for (i = 0; i < gr->max_used_depth_index; i++) {
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
index 526eefb46b6f..2a31aa0b830f 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
@@ -1,7 +1,7 @@
/*
* GK20A Graphics Engine
*
- * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -324,9 +324,12 @@ int gk20a_init_gr_channel(struct channel_gk20a *ch_gk20a);
int gr_gk20a_init_ctx_vars(struct gk20a *g, struct gr_gk20a *gr);
struct nvhost_alloc_obj_ctx_args;
+struct nvhost_free_obj_ctx_args;
int gk20a_alloc_obj_ctx(struct channel_gk20a *c,
struct nvhost_alloc_obj_ctx_args *args);
+int gk20a_free_obj_ctx(struct channel_gk20a *c,
+ struct nvhost_free_obj_ctx_args *args);
void gk20a_free_channel_ctx(struct channel_gk20a *c);
int gk20a_gr_isr(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 2bbd973ad0b1..c5a5791f9489 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -1329,6 +1329,12 @@ u64 gk20a_vm_map(struct vm_gk20a *vm,
bfr.pgsz_idx = -1;
mapping_size = mapping_size ? mapping_size : bfr.size;
+ if ((mapping_size > bfr.size) ||
+ (buffer_offset > (bfr.size - mapping_size))) {
+ err = -EINVAL;
+ goto clean_up;
+ }
+
/* If FIX_OFFSET is set, pgsz is determined. Otherwise, select
* page size according to memory alignment */
if (flags & NVHOST_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) {
@@ -2420,6 +2426,7 @@ int gk20a_vm_bind_channel(struct gk20a_as_share *as_share,
gk20a_dbg_fn("");
+ gk20a_vm_get(vm);
ch->vm = vm;
err = channel_gk20a_commit_va(ch);
if (err)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 46b7b12376f9..dcea21ed9cd6 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1138,6 +1138,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
/* Ignore report if ErrorRollOver */
if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
value[n] >= min && value[n] <= max &&
+ value[n] - min < field->maxusage &&
field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
goto exit;
}
@@ -1150,11 +1151,13 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
}
if (field->value[n] >= min && field->value[n] <= max
+ && field->value[n] - min < field->maxusage
&& field->usage[field->value[n] - min].hid
&& search(value, field->value[n], count))
hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
if (value[n] >= min && value[n] <= max
+ && value[n] - min < field->maxusage
&& field->usage[value[n] - min].hid
&& search(field->value, value[n], count))
hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 58344b6c3a55..436b9fd4775e 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -36,6 +36,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/ad9389b.h>
+#include <asm/barrier.h>
static int debug;
module_param(debug, int, 0644);
@@ -627,6 +628,9 @@ static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi
}
if (edid->start_block >= state->edid.segments * 2)
return -E2BIG;
+
+ speculation_barrier();
+
if (edid->blocks + edid->start_block >= state->edid.segments * 2)
edid->blocks = state->edid.segments * 2 - edid->start_block;
memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 31a63c9324fe..84202010d7d8 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -40,6 +40,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-chip-ident.h>
#include <media/adv7604.h>
+#include <asm/barrier.h>
static int debug;
module_param(debug, int, 0644);
@@ -1593,6 +1594,9 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi
return -EINVAL;
if (edid->start_block >= state->edid_blocks)
return -EINVAL;
+
+ speculation_barrier();
+
if (edid->start_block + edid->blocks > state->edid_blocks)
edid->blocks = state->edid_blocks - edid->start_block;
if (!edid->edid)
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 617ad3fff4aa..7124145a210b 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -21,6 +21,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-mediabus.h>
#include <media/ov7670.h>
+#include <asm/barrier.h>
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
@@ -1087,6 +1088,9 @@ static int ov7670_enum_frameintervals(struct v4l2_subdev *sd,
{
if (interval->index >= ARRAY_SIZE(ov7670_frame_rates))
return -EINVAL;
+
+ speculation_barrier();
+
interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
interval->discrete.numerator = 1;
interval->discrete.denominator = ov7670_frame_rates[interval->index];
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 1dbb8118a285..47902efae8d4 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -30,6 +30,7 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/ov9650.h>
+#include <asm/barrier.h>
static int debug;
module_param(debug, int, 0644);
@@ -1086,6 +1087,8 @@ static int ov965x_enum_frame_sizes(struct v4l2_subdev *sd,
if (fse->index > ARRAY_SIZE(ov965x_framesizes))
return -EINVAL;
+ speculation_barrier();
+
while (--i)
if (fse->code == ov965x_formats[i].code)
break;
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 9eac5310942f..a7078441e1e1 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -33,6 +33,7 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/s5c73m3.h>
+#include <asm/barrier.h>
#include "s5c73m3.h"
@@ -959,6 +960,8 @@ static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd,
if (fie->index >= ARRAY_SIZE(s5c73m3_intervals))
return -EINVAL;
+ speculation_barrier();
+
mutex_lock(&state->lock);
fi = &s5c73m3_intervals[fie->index];
if (fie->width > fi->size.width || fie->height > fi->size.height)
@@ -1228,6 +1231,8 @@ static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd,
if (fse->index >= s5c73m3_resolutions_len[idx])
return -EINVAL;
+ speculation_barrier();
+
fse->min_width = s5c73m3_resolutions[idx][fse->index].width;
fse->max_width = fse->min_width;
fse->max_height = s5c73m3_resolutions[idx][fse->index].height;
@@ -1272,6 +1277,8 @@ static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd,
if (fse->index >= s5c73m3_resolutions_len[idx])
return -EINVAL;
+ speculation_barrier();
+
fse->min_width = s5c73m3_resolutions[idx][fse->index].width;
fse->max_width = fse->min_width;
fse->max_height = s5c73m3_resolutions[idx][fse->index].height;
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index bdf5e3db31d1..aff91c3bcfde 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -29,6 +29,7 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/s5k6aa.h>
+#include <asm/barrier.h>
static int debug;
module_param(debug, int, 0644);
@@ -1006,6 +1007,8 @@ static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
if (fie->index > ARRAY_SIZE(s5k6aa_intervals))
return -EINVAL;
+ speculation_barrier();
+
v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
S5K6AA_WIN_WIDTH_MAX, 1,
&fie->height, S5K6AA_WIN_HEIGHT_MIN,
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index 9771cd83c06e..38afc54ef349 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -1385,11 +1385,12 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
* in order to avoid troubles during device release.
*/
kfree(priv->ctrl.fname);
+ priv->ctrl.fname = NULL;
memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
if (p->fname) {
priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
if (priv->ctrl.fname == NULL)
- rc = -ENOMEM;
+ return -ENOMEM;
}
/*
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 6f52e699178b..99b3162ab5b4 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -28,6 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/videobuf2-core.h>
+#include <asm/barrier.h>
/* Zero out the end of the struct pointed to by p. Everything after, but
* not including, the specified field is cleared. */
@@ -2121,6 +2122,7 @@ bool v4l2_is_known_ioctl(unsigned int cmd)
{
if (_IOC_NR(cmd) >= V4L2_IOCTLS)
return false;
+ speculation_barrier();
return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
}
@@ -2130,6 +2132,7 @@ struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd)
return vdev->lock;
if (test_bit(_IOC_NR(cmd), vdev->disable_locking))
return NULL;
+ speculation_barrier();
if (vdev->queue && vdev->queue->lock &&
(v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
return vdev->queue->lock;
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index e3bdc3be91e1..60ba606afc56 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -23,6 +23,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-core.h>
+#include <asm/barrier.h>
static int debug;
module_param(debug, int, 0644);
@@ -1800,6 +1801,8 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
return -EINVAL;
}
+ speculation_barrier();
+
vb = q->bufs[eb->index];
if (eb->plane >= vb->num_planes) {
diff --git a/drivers/misc/tegra-cryptodev.c b/drivers/misc/tegra-cryptodev.c
index 88c9cb217880..2c0d3918100d 100644
--- a/drivers/misc/tegra-cryptodev.c
+++ b/drivers/misc/tegra-cryptodev.c
@@ -33,6 +33,7 @@
#include <linux/tegra-soc.h>
#include <crypto/rng.h>
#include <crypto/hash.h>
+#include <asm/barrier.h>
#include "tegra-cryptodev.h"
@@ -282,6 +283,8 @@ static int process_crypt_req(struct tegra_crypto_ctx *ctx, struct tegra_crypt_re
const u8 *key = NULL;
struct tegra_crypto_completion tcrypt_complete;
+ speculation_barrier();
+
if (crypt_req->op & TEGRA_CRYPTO_ECB) {
req = ablkcipher_request_alloc(ctx->ecb_tfm, GFP_KERNEL);
tfm = ctx->ecb_tfm;
@@ -425,6 +428,33 @@ static int tegra_crypt_rsa(struct tegra_crypto_ctx *ctx,
int ret = 0;
unsigned long *xbuf[XBUFSIZE];
struct tegra_crypto_completion rsa_complete;
+ unsigned int total_key_len;
+ char *key_mem;
+
+ if ((((rsa_req->keylen >> 16) & 0xFFFF) >
+ MAX_RSA_MSG_LEN) ||
+ ((rsa_req->keylen & 0xFFFF) >
+ MAX_RSA_MSG_LEN)) {
+ pr_err("Invalid rsa key length\n");
+ return -EINVAL;
+ }
+
+ total_key_len = (((rsa_req->keylen >> 16) & 0xFFFF) +
+ (rsa_req->keylen & 0xFFFF));
+
+ key_mem = kzalloc(total_key_len, GFP_KERNEL);
+ if (!key_mem)
+ return -ENOMEM;
+
+ ret = copy_from_user(key_mem, (void __user *)rsa_req->key,
+ total_key_len);
+ if (ret) {
+ pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
+ kfree(key_mem);
+ return -EINVAL;
+ }
+
+ rsa_req->key = key_mem;
switch (rsa_req->algo) {
case TEGRA_RSA512:
@@ -475,10 +505,8 @@ static int tegra_crypt_rsa(struct tegra_crypto_ctx *ctx,
init_completion(&rsa_complete.restart);
result = kzalloc(rsa_req->keylen >> 16, GFP_KERNEL);
- if (!result) {
- pr_err("\nresult alloc fail\n");
+ if (!result)
goto result_fail;
- }
hash_buff = xbuf[0];
@@ -528,6 +556,7 @@ result_fail:
buf_fail:
ahash_request_free(req);
req_fail:
+ kfree(key_mem);
return ret;
}
@@ -537,6 +566,7 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
struct crypto_ahash *tfm;
struct scatterlist sg[1];
char result[64];
+ char algo[64];
struct ahash_request *req;
struct tegra_crypto_completion sha_complete;
void *hash_buff;
@@ -548,17 +578,23 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
return -EINVAL;
}
- tfm = crypto_alloc_ahash(sha_req->algo, 0, 0);
+ if (strncpy_from_user(algo, sha_req->algo, sizeof(algo)) < 0) {
+ ret = -EFAULT;
+ goto out_alloc;
+ }
+ algo[sizeof(algo) - 1] = '\0';
+
+ tfm = crypto_alloc_ahash(algo, 0, 0);
if (IS_ERR(tfm)) {
pr_err("alg:hash:Failed to load transform for %s:%ld\n",
- sha_req->algo, PTR_ERR(tfm));
+ algo, PTR_ERR(tfm));
goto out_alloc;
}
req = ahash_request_alloc(tfm, GFP_KERNEL);
if (!req) {
pr_err("alg:hash:Failed to allocate request for %s\n",
- sha_req->algo);
+ algo);
goto out_noreq;
}
@@ -574,7 +610,14 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
hash_buff = xbuf[0];
- memcpy(hash_buff, sha_req->plaintext, sha_req->plaintext_sz);
+ ret = copy_from_user((void *)hash_buff,
+ (void __user *)sha_req->plaintext,
+ sha_req->plaintext_sz);
+ if (ret) {
+ ret = -EFAULT;
+ pr_err("%s: copy_from_user failed (%d)\n", __func__, ret);
+ goto out;
+ }
sg_init_one(&sg[0], hash_buff, sha_req->plaintext_sz);
if (sha_req->keylen) {
@@ -583,7 +626,7 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
sha_req->keylen);
if (ret) {
pr_err("alg:hash:setkey failed on %s:ret=%d\n",
- sha_req->algo, ret);
+ algo, ret);
goto out;
}
@@ -594,21 +637,21 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_init(req));
if (ret) {
pr_err("alg: hash: init failed for %s: ret=%d\n",
- sha_req->algo, ret);
+ algo, ret);
goto out;
}
ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_update(req));
if (ret) {
pr_err("alg: hash: update failed for %s: ret=%d\n",
- sha_req->algo, ret);
+ algo, ret);
goto out;
}
ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_final(req));
if (ret) {
pr_err("alg: hash: final failed for %s: ret=%d\n",
- sha_req->algo, ret);
+ algo, ret);
goto out;
}
@@ -617,7 +660,7 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
if (ret) {
ret = -EFAULT;
pr_err("alg: hash: copy_to_user failed (%d) for %s\n",
- ret, sha_req->algo);
+ ret, algo);
}
out:
@@ -890,6 +933,9 @@ rng_out:
rsa_req.algo);
return -EINVAL;
}
+
+ speculation_barrier();
+
ret = tegra_crypt_rsa(ctx, &rsa_req);
break;
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index bd521b77bc5b..7d7d9feae144 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -182,6 +182,7 @@
#define RP_VEND_XP 0x00000F00
#define RP_VEND_XP_DL_UP (1 << 30)
+#define RP_VEND_XP_UPDATE_FC_THRESHOLD (0xFF << 18)
#define RP_LINK_CONTROL_STATUS 0x00000090
@@ -195,6 +196,13 @@
#define NV_PCIE2_RP_INTR_BCR 0x0000003C
#define NV_PCIE2_RP_INTR_BCR_INTR_LINE (0xFF << 0)
+#define NV_PCIE2_RP_PRIV_XP_DL 0x00000494
+#define PCIE2_RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1FF << 1)
+
+#define NV_PCIE2_RP_RX_HDR_LIMIT 0x00000E00
+#define PCIE2_RP_RX_HDR_LIMIT_PW_MASK (0xFF00)
+#define PCIE2_RP_RX_HDR_LIMIT_PW (0x0E << 8)
+
#define NV_PCIE2_RP_PRIV_MISC 0x00000FE0
#define PCIE2_RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0)
#define PCIE2_RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0)
@@ -1609,6 +1617,19 @@ static void tegra_pcie_apply_sw_war(int index, bool enum_done)
data = rp_readl(NV_PCIE2_RP_INTR_BCR, index);
data |= NV_PCIE2_RP_INTR_BCR_INTR_LINE;
rp_writel(data, NV_PCIE2_RP_INTR_BCR, index);
+ /* WAR for RAW violation on T124/T132 platforms */
+ data = rp_readl(NV_PCIE2_RP_RX_HDR_LIMIT, index);
+ data &= ~PCIE2_RP_RX_HDR_LIMIT_PW_MASK;
+ data |= PCIE2_RP_RX_HDR_LIMIT_PW;
+ rp_writel(data, NV_PCIE2_RP_RX_HDR_LIMIT, index);
+
+ data = rp_readl(NV_PCIE2_RP_PRIV_XP_DL, index);
+ data |= PCIE2_RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD;
+ rp_writel(data, NV_PCIE2_RP_PRIV_XP_DL, index);
+
+ data = rp_readl(RP_VEND_XP, index);
+ data |= RP_VEND_XP_UPDATE_FC_THRESHOLD;
+ rp_writel(data, RP_VEND_XP, index);
}
}
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index df5e961484e1..47eafb87e038 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -765,8 +765,14 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
return k; /* probably out of space --> ENOMEM */
}
if (sdp->detached) {
- if (srp->bio)
+ if (srp->bio) {
+ if (srp->rq->cmd != srp->rq->__cmd)
+ kfree(srp->rq->cmd);
+
blk_end_request_all(srp->rq, -EIO);
+ srp->rq = NULL;
+ }
+
sg_finish_rem_req(srp);
return -ENODEV;
}
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index 551fe2e0bc2d..ec1fb7913f4c 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -269,6 +269,8 @@ static int ion_heap_shrink(struct shrinker *shrinker, struct shrink_control *sc)
{
struct ion_heap *heap = container_of(shrinker, struct ion_heap,
shrinker);
+ if (IS_ERR_OR_NULL(heap))
+ return -EINVAL;
int total = 0;
int freed = 0;
int to_scan = sc->nr_to_scan;
@@ -309,8 +311,9 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
switch (heap_data->type) {
case ION_HEAP_TYPE_SYSTEM_CONTIG:
- heap = ion_system_contig_heap_create(heap_data);
- break;
+ pr_err("%s: Heap type is disabled: %d\n", __func__,
+ heap_data->type);
+ return ERR_PTR(-EINVAL);
case ION_HEAP_TYPE_SYSTEM:
heap = ion_system_heap_create(heap_data);
break;
@@ -343,12 +346,13 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
void ion_heap_destroy(struct ion_heap *heap)
{
- if (!heap)
+ if (IS_ERR_OR_NULL(heap))
return;
switch (heap->type) {
case ION_HEAP_TYPE_SYSTEM_CONTIG:
- ion_system_contig_heap_destroy(heap);
+ pr_err("%s: Heap type is disabled: %d\n", __func__,
+ heap->type);
break;
case ION_HEAP_TYPE_SYSTEM:
ion_system_heap_destroy(heap);
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index ffb4b9c41a40..68e6e09fdb37 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -944,8 +944,8 @@ thermal_cooling_device_cur_state_store(struct device *dev,
const char *buf, size_t count)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
- unsigned long state;
- int result;
+ unsigned long state, max_state;
+ int result, ret;
if (!sscanf(buf, "%ld\n", &state))
return -EINVAL;
@@ -953,6 +953,13 @@ thermal_cooling_device_cur_state_store(struct device *dev,
if ((long)state < 0)
return -EINVAL;
+ ret = cdev->ops->get_max_state(cdev, &max_state);
+ if (ret)
+ return ret;
+
+ if (state > max_state)
+ return -EINVAL;
+
result = cdev->ops->set_cur_state(cdev, state);
if (result)
return result;
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 1afe192bef6a..b5cbe12e2815 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -400,6 +400,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);
* they are not on hot paths so a little discipline won't do
* any harm.
*
+ * The line discipline-related tty_struct fields are reset to
+ * prevent the ldisc driver from re-using stale information for
+ * the new ldisc instance.
+ *
* Locking: takes termios_mutex
*/
@@ -408,6 +412,9 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
mutex_lock(&tty->termios_mutex);
tty->termios.c_line = num;
mutex_unlock(&tty->termios_mutex);
+
+ tty->disc_data = NULL;
+ tty->receive_room = 0;
}
/**
diff --git a/drivers/video/tegra/dc/sor.c b/drivers/video/tegra/dc/sor.c
index 1326155cd183..5fee008d122a 100644
--- a/drivers/video/tegra/dc/sor.c
+++ b/drivers/video/tegra/dc/sor.c
@@ -1,7 +1,7 @@
/*
* drivers/video/tegra/dc/sor.c
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -1287,7 +1287,7 @@ void tegra_dc_sor_enable_lvds(struct tegra_dc_sor_data *sor,
6 << NV_SOR_LVDS_ROTDAT_SHIFT:
0 << NV_SOR_LVDS_ROTDAT_SHIFT);
tegra_sor_writel(sor, NV_SOR_LANE4_DRIVE_CURRENT(sor->portnum),
- 0x40);
+ 0x40);
}
#if 0
diff --git a/drivers/video/tegra/dc/sor_regs.h b/drivers/video/tegra/dc/sor_regs.h
index 8e1cc1c3231c..8080e2925d82 100644
--- a/drivers/video/tegra/dc/sor_regs.h
+++ b/drivers/video/tegra/dc/sor_regs.h
@@ -1,7 +1,7 @@
/*
* drivers/video/tegra/dc/sor_regs.h
*
- * Copyright (c) 2011-2013, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
diff --git a/drivers/video/tegra/host/host1x/host1x.c b/drivers/video/tegra/host/host1x/host1x.c
index 522219484286..6af16bab059c 100644
--- a/drivers/video/tegra/host/host1x/host1x.c
+++ b/drivers/video/tegra/host/host1x/host1x.c
@@ -33,6 +33,8 @@
#include <linux/tegra-soc.h>
#include <linux/tegra_pm_domains.h>
+#include <linux/version.h>
+#include <asm/barrier.h>
#include "dev.h"
#include <trace/events/nvhost.h>
@@ -267,6 +269,8 @@ static int nvhost_ioctl_ctrl_module_mutex(struct nvhost_ctrl_userctx *ctx,
args->lock > 1)
return -EINVAL;
+ speculation_barrier();
+
trace_nvhost_ioctl_ctrl_module_mutex(args->lock, args->id);
if (args->lock && !ctx->mod_locks[args->id]) {
if (args->id == 0)
@@ -379,6 +383,7 @@ static int nvhost_ioctl_ctrl_syncpt_read_max(struct nvhost_ctrl_userctx *ctx,
{
if (args->id >= nvhost_syncpt_nb_pts(&ctx->dev->syncpt))
return -EINVAL;
+ speculation_barrier();
args->value = nvhost_syncpt_read_max(&ctx->dev->syncpt, args->id);
return 0;
}
diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c
index b0af8a143bd2..4d431cc14890 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.c
+++ b/drivers/video/tegra/host/nvhost_syncpt.c
@@ -3,7 +3,7 @@
*
* Tegra Graphics Host Syncpoints
*
- * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2010-2018, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -650,13 +650,18 @@ static ssize_t syncpt_name_show(struct kobject *kobj,
{
struct nvhost_syncpt_attr *syncpt_attr =
container_of(attr, struct nvhost_syncpt_attr, attr);
+ ssize_t count = 0;
if (syncpt_attr->id < 0)
return snprintf(buf, PAGE_SIZE, "\n");
- return snprintf(buf, PAGE_SIZE, "%s\n",
+ mutex_lock(&syncpt_attr->host->syncpt.syncpt_mutex);
+ count = snprintf(buf, PAGE_SIZE, "%s\n",
nvhost_syncpt_get_name(syncpt_attr->host->dev,
syncpt_attr->id));
+ mutex_unlock(&syncpt_attr->host->syncpt.syncpt_mutex);
+
+ return count;
}
static ssize_t syncpt_min_show(struct kobject *kobj,