aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-09 14:10:24 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-09 15:13:21 -0400
commit586491e6fc27f1783081955fd26d70789ddb3a07 (patch)
tree6a17f58b88e0c4e723f94f38225bf8b9252c38ba /drivers/gpu/drm/nouveau/core
parentaedf43d5fc0e6b0f5902e00603881869ef733d05 (diff)
drm/nouveau/device: audit and version NV_DEVICE class
The full object interfaces are about to be exposed to userspace, so we need to check for any security-related issues and version the structs to make it easier to handle any changes we may need in the future. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/base.c155
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/class.h30
4 files changed, 96 insertions, 93 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index 8d74a31635bf..c7e9794a3abc 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -195,66 +195,117 @@ nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
195 nv_wr32(object->engine, addr, data); 195 nv_wr32(object->engine, addr, data);
196} 196}
197 197
198static int
199nouveau_devobj_map(struct nouveau_object *object, u64 *addr, u32 *size)
200{
201 struct nouveau_device *device = nv_device(object);
202 *addr = nv_device_resource_start(device, 0);
203 *size = nv_device_resource_len(device, 0);
204 return 0;
205}
206
198static const u64 disable_map[] = { 207static const u64 disable_map[] = {
199 [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_DISABLE_VBIOS, 208 [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_V0_DISABLE_VBIOS,
200 [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_DISABLE_CORE, 209 [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_V0_DISABLE_CORE,
201 [NVDEV_SUBDEV_GPIO] = NV_DEVICE_DISABLE_CORE, 210 [NVDEV_SUBDEV_GPIO] = NV_DEVICE_V0_DISABLE_CORE,
202 [NVDEV_SUBDEV_I2C] = NV_DEVICE_DISABLE_CORE, 211 [NVDEV_SUBDEV_I2C] = NV_DEVICE_V0_DISABLE_CORE,
203 [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_DISABLE_CORE, 212 [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_V0_DISABLE_CORE,
204 [NVDEV_SUBDEV_MXM] = NV_DEVICE_DISABLE_CORE, 213 [NVDEV_SUBDEV_MXM] = NV_DEVICE_V0_DISABLE_CORE,
205 [NVDEV_SUBDEV_MC] = NV_DEVICE_DISABLE_CORE, 214 [NVDEV_SUBDEV_MC] = NV_DEVICE_V0_DISABLE_CORE,
206 [NVDEV_SUBDEV_BUS] = NV_DEVICE_DISABLE_CORE, 215 [NVDEV_SUBDEV_BUS] = NV_DEVICE_V0_DISABLE_CORE,
207 [NVDEV_SUBDEV_TIMER] = NV_DEVICE_DISABLE_CORE, 216 [NVDEV_SUBDEV_TIMER] = NV_DEVICE_V0_DISABLE_CORE,
208 [NVDEV_SUBDEV_FB] = NV_DEVICE_DISABLE_CORE, 217 [NVDEV_SUBDEV_FB] = NV_DEVICE_V0_DISABLE_CORE,
209 [NVDEV_SUBDEV_LTCG] = NV_DEVICE_DISABLE_CORE, 218 [NVDEV_SUBDEV_LTCG] = NV_DEVICE_V0_DISABLE_CORE,
210 [NVDEV_SUBDEV_IBUS] = NV_DEVICE_DISABLE_CORE, 219 [NVDEV_SUBDEV_IBUS] = NV_DEVICE_V0_DISABLE_CORE,
211 [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_DISABLE_CORE, 220 [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_V0_DISABLE_CORE,
212 [NVDEV_SUBDEV_VM] = NV_DEVICE_DISABLE_CORE, 221 [NVDEV_SUBDEV_VM] = NV_DEVICE_V0_DISABLE_CORE,
213 [NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE, 222 [NVDEV_SUBDEV_BAR] = NV_DEVICE_V0_DISABLE_CORE,
214 [NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE, 223 [NVDEV_SUBDEV_VOLT] = NV_DEVICE_V0_DISABLE_CORE,
215 [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE, 224 [NVDEV_SUBDEV_THERM] = NV_DEVICE_V0_DISABLE_CORE,
216 [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE, 225 [NVDEV_SUBDEV_PWR] = NV_DEVICE_V0_DISABLE_CORE,
217 [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE, 226 [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_V0_DISABLE_CORE,
218 [NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE, 227 [NVDEV_ENGINE_PERFMON] = NV_DEVICE_V0_DISABLE_CORE,
219 [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO, 228 [NVDEV_ENGINE_FIFO] = NV_DEVICE_V0_DISABLE_FIFO,
220 [NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO, 229 [NVDEV_ENGINE_SW] = NV_DEVICE_V0_DISABLE_FIFO,
221 [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH, 230 [NVDEV_ENGINE_GR] = NV_DEVICE_V0_DISABLE_GRAPH,
222 [NVDEV_ENGINE_MPEG] = NV_DEVICE_DISABLE_MPEG, 231 [NVDEV_ENGINE_MPEG] = NV_DEVICE_V0_DISABLE_MPEG,
223 [NVDEV_ENGINE_ME] = NV_DEVICE_DISABLE_ME, 232 [NVDEV_ENGINE_ME] = NV_DEVICE_V0_DISABLE_ME,
224 [NVDEV_ENGINE_VP] = NV_DEVICE_DISABLE_VP, 233 [NVDEV_ENGINE_VP] = NV_DEVICE_V0_DISABLE_VP,
225 [NVDEV_ENGINE_CRYPT] = NV_DEVICE_DISABLE_CRYPT, 234 [NVDEV_ENGINE_CRYPT] = NV_DEVICE_V0_DISABLE_CRYPT,
226 [NVDEV_ENGINE_BSP] = NV_DEVICE_DISABLE_BSP, 235 [NVDEV_ENGINE_BSP] = NV_DEVICE_V0_DISABLE_BSP,
227 [NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP, 236 [NVDEV_ENGINE_PPP] = NV_DEVICE_V0_DISABLE_PPP,
228 [NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0, 237 [NVDEV_ENGINE_COPY0] = NV_DEVICE_V0_DISABLE_COPY0,
229 [NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1, 238 [NVDEV_ENGINE_COPY1] = NV_DEVICE_V0_DISABLE_COPY1,
230 [NVDEV_ENGINE_VIC] = NV_DEVICE_DISABLE_VIC, 239 [NVDEV_ENGINE_VIC] = NV_DEVICE_V0_DISABLE_VIC,
231 [NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC, 240 [NVDEV_ENGINE_VENC] = NV_DEVICE_V0_DISABLE_VENC,
232 [NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP, 241 [NVDEV_ENGINE_DISP] = NV_DEVICE_V0_DISABLE_DISP,
233 [NVDEV_SUBDEV_NR] = 0, 242 [NVDEV_SUBDEV_NR] = 0,
234}; 243};
235 244
245static void
246nouveau_devobj_dtor(struct nouveau_object *object)
247{
248 struct nouveau_devobj *devobj = (void *)object;
249 int i;
250
251 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
252 nouveau_object_ref(NULL, &devobj->subdev[i]);
253
254 nouveau_parent_destroy(&devobj->base);
255}
256
257static struct nouveau_oclass
258nouveau_devobj_oclass_super = {
259 .handle = NV_DEVICE,
260 .ofuncs = &(struct nouveau_ofuncs) {
261 .dtor = nouveau_devobj_dtor,
262 .init = _nouveau_parent_init,
263 .fini = _nouveau_parent_fini,
264 .mthd = nouveau_devobj_mthd,
265 .map = nouveau_devobj_map,
266 .rd08 = nouveau_devobj_rd08,
267 .rd16 = nouveau_devobj_rd16,
268 .rd32 = nouveau_devobj_rd32,
269 .wr08 = nouveau_devobj_wr08,
270 .wr16 = nouveau_devobj_wr16,
271 .wr32 = nouveau_devobj_wr32,
272 }
273};
274
236static int 275static int
237nouveau_devobj_ctor(struct nouveau_object *parent, 276nouveau_devobj_ctor(struct nouveau_object *parent,
238 struct nouveau_object *engine, 277 struct nouveau_object *engine,
239 struct nouveau_oclass *oclass, void *data, u32 size, 278 struct nouveau_oclass *oclass, void *data, u32 size,
240 struct nouveau_object **pobject) 279 struct nouveau_object **pobject)
241{ 280{
281 union {
282 struct nv_device_v0 v0;
283 } *args = data;
242 struct nouveau_client *client = nv_client(parent); 284 struct nouveau_client *client = nv_client(parent);
243 struct nouveau_device *device; 285 struct nouveau_device *device;
244 struct nouveau_devobj *devobj; 286 struct nouveau_devobj *devobj;
245 struct nv_device_class *args = data;
246 u32 boot0, strap; 287 u32 boot0, strap;
247 u64 disable, mmio_base, mmio_size; 288 u64 disable, mmio_base, mmio_size;
248 void __iomem *map; 289 void __iomem *map;
249 int ret, i, c; 290 int ret, i, c;
250 291
251 if (size < sizeof(struct nv_device_class)) 292 nv_ioctl(parent, "create device size %d\n", size);
252 return -EINVAL; 293 if (nvif_unpack(args->v0, 0, 0, false)) {
294 nv_ioctl(parent, "create device v%d device %016llx "
295 "disable %016llx debug0 %016llx\n",
296 args->v0.version, args->v0.device,
297 args->v0.disable, args->v0.debug0);
298 } else
299 return ret;
300
301 /* give priviledged clients register access */
302 if (client->super)
303 oclass = &nouveau_devobj_oclass_super;
253 304
254 /* find the device subdev that matches what the client requested */ 305 /* find the device subdev that matches what the client requested */
255 device = nv_device(client->device); 306 device = nv_device(client->device);
256 if (args->device != ~0) { 307 if (args->v0.device != ~0) {
257 device = nouveau_device_find(args->device); 308 device = nouveau_device_find(args->v0.device);
258 if (!device) 309 if (!device)
259 return -ENODEV; 310 return -ENODEV;
260 } 311 }
@@ -273,14 +324,14 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
273 mmio_size = nv_device_resource_len(device, 0); 324 mmio_size = nv_device_resource_len(device, 0);
274 325
275 /* translate api disable mask into internal mapping */ 326 /* translate api disable mask into internal mapping */
276 disable = args->debug0; 327 disable = args->v0.debug0;
277 for (i = 0; i < NVDEV_SUBDEV_NR; i++) { 328 for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
278 if (args->disable & disable_map[i]) 329 if (args->v0.disable & disable_map[i])
279 disable |= (1ULL << i); 330 disable |= (1ULL << i);
280 } 331 }
281 332
282 /* identify the chipset, and determine classes of subdev/engines */ 333 /* identify the chipset, and determine classes of subdev/engines */
283 if (!(args->disable & NV_DEVICE_DISABLE_IDENTIFY) && 334 if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY) &&
284 !device->card_type) { 335 !device->card_type) {
285 map = ioremap(mmio_base, 0x102000); 336 map = ioremap(mmio_base, 0x102000);
286 if (map == NULL) 337 if (map == NULL)
@@ -379,7 +430,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
379 nv_debug(device, "crystal freq: %dKHz\n", device->crystal); 430 nv_debug(device, "crystal freq: %dKHz\n", device->crystal);
380 } 431 }
381 432
382 if (!(args->disable & NV_DEVICE_DISABLE_MMIO) && 433 if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) &&
383 !nv_subdev(device)->mmio) { 434 !nv_subdev(device)->mmio) {
384 nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size); 435 nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size);
385 if (!nv_subdev(device)->mmio) { 436 if (!nv_subdev(device)->mmio) {
@@ -435,18 +486,6 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
435 return 0; 486 return 0;
436} 487}
437 488
438static void
439nouveau_devobj_dtor(struct nouveau_object *object)
440{
441 struct nouveau_devobj *devobj = (void *)object;
442 int i;
443
444 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
445 nouveau_object_ref(NULL, &devobj->subdev[i]);
446
447 nouveau_parent_destroy(&devobj->base);
448}
449
450static struct nouveau_ofuncs 489static struct nouveau_ofuncs
451nouveau_devobj_ofuncs = { 490nouveau_devobj_ofuncs = {
452 .ctor = nouveau_devobj_ctor, 491 .ctor = nouveau_devobj_ctor,
@@ -454,12 +493,6 @@ nouveau_devobj_ofuncs = {
454 .init = _nouveau_parent_init, 493 .init = _nouveau_parent_init,
455 .fini = _nouveau_parent_fini, 494 .fini = _nouveau_parent_fini,
456 .mthd = nouveau_devobj_mthd, 495 .mthd = nouveau_devobj_mthd,
457 .rd08 = nouveau_devobj_rd08,
458 .rd16 = nouveau_devobj_rd16,
459 .rd32 = nouveau_devobj_rd32,
460 .wr08 = nouveau_devobj_wr08,
461 .wr16 = nouveau_devobj_wr16,
462 .wr32 = nouveau_devobj_wr32,
463}; 496};
464 497
465/****************************************************************************** 498/******************************************************************************
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 5311f0fcd291..ca8ce9cace7f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -990,7 +990,7 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
990 int ret = -EBUSY; 990 int ret = -EBUSY;
991 991
992 /* no context needed for channel objects... */ 992 /* no context needed for channel objects... */
993 if (nv_mclass(parent) != NV_DEVICE_CLASS) { 993 if (nv_mclass(parent) != NV_DEVICE) {
994 atomic_inc(&parent->refcount); 994 atomic_inc(&parent->refcount);
995 *pobject = parent; 995 *pobject = parent;
996 return 1; 996 return 1;
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
index 5103e88d1877..a11b83d50f9c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
@@ -88,7 +88,7 @@ nouveau_dmaobj_ctor(struct nouveau_object *parent,
88 dmaobj->conf0 = args->conf0; 88 dmaobj->conf0 = args->conf0;
89 89
90 switch (nv_mclass(parent)) { 90 switch (nv_mclass(parent)) {
91 case NV_DEVICE_CLASS: 91 case NV_DEVICE:
92 /* delayed, or no, binding */ 92 /* delayed, or no, binding */
93 break; 93 break;
94 default: 94 default:
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h
index 37d47cb44a7b..fa35f0041562 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/class.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/class.h
@@ -3,36 +3,6 @@
3 3
4#include <nvif/class.h> 4#include <nvif/class.h>
5 5
6/* Device class
7 *
8 * 0080: NV_DEVICE
9 */
10#define NV_DEVICE_CLASS 0x00000080
11
12#define NV_DEVICE_DISABLE_IDENTIFY 0x0000000000000001ULL
13#define NV_DEVICE_DISABLE_MMIO 0x0000000000000002ULL
14#define NV_DEVICE_DISABLE_VBIOS 0x0000000000000004ULL
15#define NV_DEVICE_DISABLE_CORE 0x0000000000000008ULL
16#define NV_DEVICE_DISABLE_DISP 0x0000000000010000ULL
17#define NV_DEVICE_DISABLE_FIFO 0x0000000000020000ULL
18#define NV_DEVICE_DISABLE_GRAPH 0x0000000100000000ULL
19#define NV_DEVICE_DISABLE_MPEG 0x0000000200000000ULL
20#define NV_DEVICE_DISABLE_ME 0x0000000400000000ULL
21#define NV_DEVICE_DISABLE_VP 0x0000000800000000ULL
22#define NV_DEVICE_DISABLE_CRYPT 0x0000001000000000ULL
23#define NV_DEVICE_DISABLE_BSP 0x0000002000000000ULL
24#define NV_DEVICE_DISABLE_PPP 0x0000004000000000ULL
25#define NV_DEVICE_DISABLE_COPY0 0x0000008000000000ULL
26#define NV_DEVICE_DISABLE_COPY1 0x0000010000000000ULL
27#define NV_DEVICE_DISABLE_VIC 0x0000020000000000ULL
28#define NV_DEVICE_DISABLE_VENC 0x0000040000000000ULL
29
30struct nv_device_class {
31 u64 device; /* device identifier, ~0 for client default */
32 u64 disable; /* disable particular subsystems */
33 u64 debug0; /* as above, but *internal* ids, and *NOT* ABI */
34};
35
36/* DMA object classes 6/* DMA object classes
37 * 7 *
38 * 0002: NV_DMA_FROM_MEMORY 8 * 0002: NV_DMA_FROM_MEMORY