drm/tegra: Fixes for v3.13-rc3
This assortment of patches fix a few build and sparse warnings and make sure to always return -EFAULT on copy_from_user() failures. Finally the upcasting from struct drm_crtc to struct tegra_dc is made safer to prevent potential segmentation faults. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJSnaLrAAoJEN0jrNd/PrOhm+YP/jXPCBWuyMzbw6Sld0U9gs7c xjxBuH7CwU5CCEA1OzBoQOf5ANrlbZ7rnbNoJzqPktss1TWADhBs8Yvn/SsOClwe L+5yiVZ21pKXPOXpX2e4NlIrNqyq+USb+Ve3SfhNoWIcZyIjKosy66sQJBijo5ap Kz+EpFcGjYePt3zhyIR4JOEtfjJd0gk2e72MBPFUtnteS9ecNt+ZGZaTse27xVn3 ogyvef7Vp2r097OO5QS9PnohPQffJMmU36dzfzzKIcvn7vg+3xuO7sZdzdEvErHh eNXXJoFIpUA1xbrmrNLl0HcnCkwun+nrpEd29ceszqd0Pspz6TUdTj6Og5vjbCrZ LhVBZQydTpQQoMmI9l12GmePvEhjgWDc68bRCjhuIlRa84+nXWglJ29cgrvEdBJA /V1dRE1WAL+TkBK83LcjiwihrM/KKqILjgl8ta6D6Jyi0JGEjUQBY2JEYedt2/T6 y9nhZ8pwI/rbROS71AXWgMjHoKhS/D939jwCMo+3bLjn2Vi4QyyDJeahbVsiGNze kUCcKVvWh3eJNSZYEnpWPNFQaFDxZhFPtr+kPCG9AB1w3yji/dluEOe8r/pUvHnn KK87Jfcu8UaiusILW/k6h9skZAPbC/t8I9S50JgSeO1jDVMN8lqlv1IP32cGFVXm j9ZbTEyeJN8VFVMs5r2E =Du68 -----END PGP SIGNATURE----- Merge tag 'drm/for-3.13-rc3' of git://anongit.freedesktop.org/tegra/linux into drm-fixes drm/tegra: Fixes for v3.13-rc3 This assortment of patches fix a few build and sparse warnings and make sure to always return -EFAULT on copy_from_user() failures. Finally the upcasting from struct drm_crtc to struct tegra_dc is made safer to prevent potential segmentation faults. * tag 'drm/for-3.13-rc3' of git://anongit.freedesktop.org/tegra/linux: drm/tegra: return -EFAULT if copy_from_user() fails gpu: host1x: Fix a few sparse warnings drm/tegra: Force cast to __iomem to make sparse happy drm/tegra: Make tegra_drm_driver static drm/tegra: Fix address space mismatches drm/tegra: Tightly bind RGB output to DC drm/tegra: Make CRTC upcasting safer gpu: host1x: Silence a few warnings with LPAE=y
This commit is contained in:
Коммит
60460f6551
|
@ -135,11 +135,11 @@ int tegra_drm_submit(struct tegra_drm_context *context,
|
|||
unsigned int num_relocs = args->num_relocs;
|
||||
unsigned int num_waitchks = args->num_waitchks;
|
||||
struct drm_tegra_cmdbuf __user *cmdbufs =
|
||||
(void * __user)(uintptr_t)args->cmdbufs;
|
||||
(void __user *)(uintptr_t)args->cmdbufs;
|
||||
struct drm_tegra_reloc __user *relocs =
|
||||
(void * __user)(uintptr_t)args->relocs;
|
||||
(void __user *)(uintptr_t)args->relocs;
|
||||
struct drm_tegra_waitchk __user *waitchks =
|
||||
(void * __user)(uintptr_t)args->waitchks;
|
||||
(void __user *)(uintptr_t)args->waitchks;
|
||||
struct drm_tegra_syncpt syncpt;
|
||||
struct host1x_job *job;
|
||||
int err;
|
||||
|
@ -163,9 +163,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
|
|||
struct drm_tegra_cmdbuf cmdbuf;
|
||||
struct host1x_bo *bo;
|
||||
|
||||
err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf));
|
||||
if (err)
|
||||
if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) {
|
||||
err = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bo = host1x_bo_lookup(drm, file, cmdbuf.handle);
|
||||
if (!bo) {
|
||||
|
@ -178,10 +179,11 @@ int tegra_drm_submit(struct tegra_drm_context *context,
|
|||
cmdbufs++;
|
||||
}
|
||||
|
||||
err = copy_from_user(job->relocarray, relocs,
|
||||
sizeof(*relocs) * num_relocs);
|
||||
if (err)
|
||||
if (copy_from_user(job->relocarray, relocs,
|
||||
sizeof(*relocs) * num_relocs)) {
|
||||
err = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (num_relocs--) {
|
||||
struct host1x_reloc *reloc = &job->relocarray[num_relocs];
|
||||
|
@ -199,15 +201,17 @@ int tegra_drm_submit(struct tegra_drm_context *context,
|
|||
}
|
||||
}
|
||||
|
||||
err = copy_from_user(job->waitchk, waitchks,
|
||||
sizeof(*waitchks) * num_waitchks);
|
||||
if (err)
|
||||
if (copy_from_user(job->waitchk, waitchks,
|
||||
sizeof(*waitchks) * num_waitchks)) {
|
||||
err = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts,
|
||||
sizeof(syncpt));
|
||||
if (err)
|
||||
if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts,
|
||||
sizeof(syncpt))) {
|
||||
err = -EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
job->is_addr_reg = context->client->ops->is_addr_reg;
|
||||
job->syncpt_incrs = syncpt.incrs;
|
||||
|
@ -573,7 +577,7 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor)
|
|||
}
|
||||
#endif
|
||||
|
||||
struct drm_driver tegra_drm_driver = {
|
||||
static struct drm_driver tegra_drm_driver = {
|
||||
.driver_features = DRIVER_MODESET | DRIVER_GEM,
|
||||
.load = tegra_drm_load,
|
||||
.unload = tegra_drm_unload,
|
||||
|
|
|
@ -116,7 +116,7 @@ host1x_client_to_dc(struct host1x_client *client)
|
|||
|
||||
static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
|
||||
{
|
||||
return container_of(crtc, struct tegra_dc, base);
|
||||
return crtc ? container_of(crtc, struct tegra_dc, base) : NULL;
|
||||
}
|
||||
|
||||
static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value,
|
||||
|
|
|
@ -247,7 +247,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
|
|||
info->var.yoffset * fb->pitches[0];
|
||||
|
||||
drm->mode_config.fb_base = (resource_size_t)bo->paddr;
|
||||
info->screen_base = bo->vaddr + offset;
|
||||
info->screen_base = (void __iomem *)bo->vaddr + offset;
|
||||
info->screen_size = size;
|
||||
info->fix.smem_start = (unsigned long)(bo->paddr + offset);
|
||||
info->fix.smem_len = size;
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
struct tegra_rgb {
|
||||
struct tegra_output output;
|
||||
struct tegra_dc *dc;
|
||||
|
||||
struct clk *clk_parent;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
@ -84,18 +86,18 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
|
|||
|
||||
static int tegra_output_rgb_enable(struct tegra_output *output)
|
||||
{
|
||||
struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
|
||||
struct tegra_rgb *rgb = to_rgb(output);
|
||||
|
||||
tegra_dc_write_regs(dc, rgb_enable, ARRAY_SIZE(rgb_enable));
|
||||
tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_output_rgb_disable(struct tegra_output *output)
|
||||
{
|
||||
struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
|
||||
struct tegra_rgb *rgb = to_rgb(output);
|
||||
|
||||
tegra_dc_write_regs(dc, rgb_disable, ARRAY_SIZE(rgb_disable));
|
||||
tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -146,6 +148,7 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
|
|||
|
||||
rgb->output.dev = dc->dev;
|
||||
rgb->output.of_node = np;
|
||||
rgb->dc = dc;
|
||||
|
||||
err = tegra_output_probe(&rgb->output);
|
||||
if (err < 0)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "bus.h"
|
||||
#include "dev.h"
|
||||
|
||||
static DEFINE_MUTEX(clients_lock);
|
||||
|
@ -257,7 +258,7 @@ static int host1x_unregister_client(struct host1x *host1x,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct bus_type host1x_bus_type = {
|
||||
static struct bus_type host1x_bus_type = {
|
||||
.name = "host1x",
|
||||
};
|
||||
|
||||
|
@ -301,7 +302,7 @@ static int host1x_device_add(struct host1x *host1x,
|
|||
device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
|
||||
device->dev.dma_mask = &device->dev.coherent_dma_mask;
|
||||
device->dev.release = host1x_device_release;
|
||||
dev_set_name(&device->dev, driver->name);
|
||||
dev_set_name(&device->dev, "%s", driver->name);
|
||||
device->dev.bus = &host1x_bus_type;
|
||||
device->dev.parent = host1x->dev;
|
||||
|
||||
|
|
|
@ -54,8 +54,8 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
|
|||
u32 *p = (u32 *)((u32)pb->mapped + getptr);
|
||||
*(p++) = HOST1X_OPCODE_NOP;
|
||||
*(p++) = HOST1X_OPCODE_NOP;
|
||||
dev_dbg(host1x->dev, "%s: NOP at 0x%x\n", __func__,
|
||||
pb->phys + getptr);
|
||||
dev_dbg(host1x->dev, "%s: NOP at %#llx\n", __func__,
|
||||
(u64)pb->phys + getptr);
|
||||
getptr = (getptr + 8) & (pb->size_bytes - 1);
|
||||
}
|
||||
wmb();
|
||||
|
|
|
@ -163,8 +163,8 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
|
|||
continue;
|
||||
}
|
||||
|
||||
host1x_debug_output(o, " GATHER at %08x+%04x, %d words\n",
|
||||
g->base, g->offset, g->words);
|
||||
host1x_debug_output(o, " GATHER at %#llx+%04x, %d words\n",
|
||||
(u64)g->base, g->offset, g->words);
|
||||
|
||||
show_gather(o, g->base + g->offset, g->words, cdma,
|
||||
g->base, mapped);
|
||||
|
|
Загрузка…
Ссылка в новой задаче