Commit 60460f65 authored by Dave Airlie's avatar Dave Airlie

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
parents 1d507b3a 9a991600
...@@ -135,11 +135,11 @@ int tegra_drm_submit(struct tegra_drm_context *context, ...@@ -135,11 +135,11 @@ int tegra_drm_submit(struct tegra_drm_context *context,
unsigned int num_relocs = args->num_relocs; unsigned int num_relocs = args->num_relocs;
unsigned int num_waitchks = args->num_waitchks; unsigned int num_waitchks = args->num_waitchks;
struct drm_tegra_cmdbuf __user *cmdbufs = struct drm_tegra_cmdbuf __user *cmdbufs =
(void * __user)(uintptr_t)args->cmdbufs; (void __user *)(uintptr_t)args->cmdbufs;
struct drm_tegra_reloc __user *relocs = struct drm_tegra_reloc __user *relocs =
(void * __user)(uintptr_t)args->relocs; (void __user *)(uintptr_t)args->relocs;
struct drm_tegra_waitchk __user *waitchks = struct drm_tegra_waitchk __user *waitchks =
(void * __user)(uintptr_t)args->waitchks; (void __user *)(uintptr_t)args->waitchks;
struct drm_tegra_syncpt syncpt; struct drm_tegra_syncpt syncpt;
struct host1x_job *job; struct host1x_job *job;
int err; int err;
...@@ -163,9 +163,10 @@ int tegra_drm_submit(struct tegra_drm_context *context, ...@@ -163,9 +163,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
struct drm_tegra_cmdbuf cmdbuf; struct drm_tegra_cmdbuf cmdbuf;
struct host1x_bo *bo; struct host1x_bo *bo;
err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf)); if (copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf))) {
if (err) err = -EFAULT;
goto fail; goto fail;
}
bo = host1x_bo_lookup(drm, file, cmdbuf.handle); bo = host1x_bo_lookup(drm, file, cmdbuf.handle);
if (!bo) { if (!bo) {
...@@ -178,10 +179,11 @@ int tegra_drm_submit(struct tegra_drm_context *context, ...@@ -178,10 +179,11 @@ int tegra_drm_submit(struct tegra_drm_context *context,
cmdbufs++; cmdbufs++;
} }
err = copy_from_user(job->relocarray, relocs, if (copy_from_user(job->relocarray, relocs,
sizeof(*relocs) * num_relocs); sizeof(*relocs) * num_relocs)) {
if (err) err = -EFAULT;
goto fail; goto fail;
}
while (num_relocs--) { while (num_relocs--) {
struct host1x_reloc *reloc = &job->relocarray[num_relocs]; struct host1x_reloc *reloc = &job->relocarray[num_relocs];
...@@ -199,15 +201,17 @@ int tegra_drm_submit(struct tegra_drm_context *context, ...@@ -199,15 +201,17 @@ int tegra_drm_submit(struct tegra_drm_context *context,
} }
} }
err = copy_from_user(job->waitchk, waitchks, if (copy_from_user(job->waitchk, waitchks,
sizeof(*waitchks) * num_waitchks); sizeof(*waitchks) * num_waitchks)) {
if (err) err = -EFAULT;
goto fail; goto fail;
}
err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts, if (copy_from_user(&syncpt, (void __user *)(uintptr_t)args->syncpts,
sizeof(syncpt)); sizeof(syncpt))) {
if (err) err = -EFAULT;
goto fail; goto fail;
}
job->is_addr_reg = context->client->ops->is_addr_reg; job->is_addr_reg = context->client->ops->is_addr_reg;
job->syncpt_incrs = syncpt.incrs; job->syncpt_incrs = syncpt.incrs;
...@@ -573,7 +577,7 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor) ...@@ -573,7 +577,7 @@ static void tegra_debugfs_cleanup(struct drm_minor *minor)
} }
#endif #endif
struct drm_driver tegra_drm_driver = { static struct drm_driver tegra_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM, .driver_features = DRIVER_MODESET | DRIVER_GEM,
.load = tegra_drm_load, .load = tegra_drm_load,
.unload = tegra_drm_unload, .unload = tegra_drm_unload,
......
...@@ -116,7 +116,7 @@ host1x_client_to_dc(struct host1x_client *client) ...@@ -116,7 +116,7 @@ host1x_client_to_dc(struct host1x_client *client)
static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) 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, 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, ...@@ -247,7 +247,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
info->var.yoffset * fb->pitches[0]; info->var.yoffset * fb->pitches[0];
drm->mode_config.fb_base = (resource_size_t)bo->paddr; 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->screen_size = size;
info->fix.smem_start = (unsigned long)(bo->paddr + offset); info->fix.smem_start = (unsigned long)(bo->paddr + offset);
info->fix.smem_len = size; info->fix.smem_len = size;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
struct tegra_rgb { struct tegra_rgb {
struct tegra_output output; struct tegra_output output;
struct tegra_dc *dc;
struct clk *clk_parent; struct clk *clk_parent;
struct clk *clk; struct clk *clk;
}; };
...@@ -84,18 +86,18 @@ static void tegra_dc_write_regs(struct tegra_dc *dc, ...@@ -84,18 +86,18 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
static int tegra_output_rgb_enable(struct tegra_output *output) 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; return 0;
} }
static int tegra_output_rgb_disable(struct tegra_output *output) 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; return 0;
} }
...@@ -146,6 +148,7 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc) ...@@ -146,6 +148,7 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
rgb->output.dev = dc->dev; rgb->output.dev = dc->dev;
rgb->output.of_node = np; rgb->output.of_node = np;
rgb->dc = dc;
err = tegra_output_probe(&rgb->output); err = tegra_output_probe(&rgb->output);
if (err < 0) if (err < 0)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "bus.h"
#include "dev.h" #include "dev.h"
static DEFINE_MUTEX(clients_lock); static DEFINE_MUTEX(clients_lock);
...@@ -257,7 +258,7 @@ static int host1x_unregister_client(struct host1x *host1x, ...@@ -257,7 +258,7 @@ static int host1x_unregister_client(struct host1x *host1x,
return -ENODEV; return -ENODEV;
} }
struct bus_type host1x_bus_type = { static struct bus_type host1x_bus_type = {
.name = "host1x", .name = "host1x",
}; };
...@@ -301,7 +302,7 @@ static int host1x_device_add(struct host1x *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.coherent_dma_mask = host1x->dev->coherent_dma_mask;
device->dev.dma_mask = &device->dev.coherent_dma_mask; device->dev.dma_mask = &device->dev.coherent_dma_mask;
device->dev.release = host1x_device_release; 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.bus = &host1x_bus_type;
device->dev.parent = host1x->dev; device->dev.parent = host1x->dev;
......
...@@ -54,8 +54,8 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr, ...@@ -54,8 +54,8 @@ static void cdma_timeout_cpu_incr(struct host1x_cdma *cdma, u32 getptr,
u32 *p = (u32 *)((u32)pb->mapped + getptr); u32 *p = (u32 *)((u32)pb->mapped + getptr);
*(p++) = HOST1X_OPCODE_NOP; *(p++) = HOST1X_OPCODE_NOP;
*(p++) = HOST1X_OPCODE_NOP; *(p++) = HOST1X_OPCODE_NOP;
dev_dbg(host1x->dev, "%s: NOP at 0x%x\n", __func__, dev_dbg(host1x->dev, "%s: NOP at %#llx\n", __func__,
pb->phys + getptr); (u64)pb->phys + getptr);
getptr = (getptr + 8) & (pb->size_bytes - 1); getptr = (getptr + 8) & (pb->size_bytes - 1);
} }
wmb(); wmb();
......
...@@ -163,8 +163,8 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) ...@@ -163,8 +163,8 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
continue; continue;
} }
host1x_debug_output(o, " GATHER at %08x+%04x, %d words\n", host1x_debug_output(o, " GATHER at %#llx+%04x, %d words\n",
g->base, g->offset, g->words); (u64)g->base, g->offset, g->words);
show_gather(o, g->base + g->offset, g->words, cdma, show_gather(o, g->base + g->offset, g->words, cdma,
g->base, mapped); g->base, mapped);
......
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