Skip to content

Commit 13e9572

Browse files
author
Ben Skeggs
committed
drm/nouveau/fault/gp100: expose MaxwellFaultBufferA
This nvclass exposes the replayable fault buffer, which will be used by SVM to manage GPU page faults. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
1 parent ab2ee9f commit 13e9572

File tree

9 files changed

+142
-8
lines changed

9 files changed

+142
-8
lines changed

drivers/gpu/drm/nouveau/include/nvif/class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454

5555
#define VOLTA_USERMODE_A 0x0000c361
5656

57+
#define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069
58+
5759
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
5860
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
5961
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef __NVIF_CLB069_H__
2+
#define __NVIF_CLB069_H__
3+
struct nvif_clb069_v0 {
4+
__u8 version;
5+
__u8 pad01[3];
6+
__u32 entries;
7+
__u32 get;
8+
__u32 put;
9+
};
10+
11+
#define NVB069_V0_NTFY_FAULT 0x00
12+
#endif

drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ struct nvkm_fault {
1313
struct nvkm_event event;
1414

1515
struct nvkm_notify nrpfb;
16+
17+
struct nvkm_device_oclass user;
1618
};
1719

1820
struct nvkm_fault_data {

drivers/gpu/drm/nouveau/nvkm/engine/device/user.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -365,16 +365,15 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
365365
}
366366

367367
if (!sclass) {
368-
switch (index) {
369-
case 0: sclass = &nvkm_control_oclass; break;
370-
case 1:
371-
if (!device->mmu)
372-
return -EINVAL;
368+
if (index-- == 0)
369+
sclass = &nvkm_control_oclass;
370+
else if (device->mmu && index-- == 0)
373371
sclass = &device->mmu->user;
374-
break;
375-
default:
372+
else if (device->fault && index-- == 0)
373+
sclass = &device->fault->user;
374+
else
376375
return -EINVAL;
377-
}
376+
378377
oclass->base = sclass->base;
379378
}
380379

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
nvkm-y += nvkm/subdev/fault/base.o
2+
nvkm-y += nvkm/subdev/fault/user.o
23
nvkm-y += nvkm/subdev/fault/gp100.o
34
nvkm-y += nvkm/subdev/fault/gv100.o
45
nvkm-y += nvkm/subdev/fault/tu102.o

drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,7 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device,
176176
return -ENOMEM;
177177
nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev);
178178
fault->func = func;
179+
fault->user.ctor = nvkm_ufault_new;
180+
fault->user.base = func->user.base;
179181
return 0;
180182
}

drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
#include <subdev/mc.h>
2525

26+
#include <nvif/class.h>
27+
2628
static void
2729
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
2830
{
@@ -69,6 +71,7 @@ gp100_fault = {
6971
.buffer.init = gp100_fault_buffer_init,
7072
.buffer.fini = gp100_fault_buffer_fini,
7173
.buffer.intr = gp100_fault_buffer_intr,
74+
.user = { { 0, 0, MAXWELL_FAULT_BUFFER_A }, 0 },
7275
};
7376

7477
int

drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ struct nvkm_fault_func {
3434
void (*fini)(struct nvkm_fault_buffer *);
3535
void (*intr)(struct nvkm_fault_buffer *, bool enable);
3636
} buffer;
37+
struct {
38+
struct nvkm_sclass base;
39+
int rp;
40+
} user;
3741
};
3842

3943
int gv100_fault_oneinit(struct nvkm_fault *);
44+
45+
int nvkm_ufault_new(struct nvkm_device *, const struct nvkm_oclass *,
46+
void *, u32, struct nvkm_object **);
4047
#endif
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2018 Red Hat Inc.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+
* OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
#include "priv.h"
23+
24+
#include <core/memory.h>
25+
#include <subdev/mmu.h>
26+
27+
#include <nvif/clb069.h>
28+
#include <nvif/unpack.h>
29+
30+
static int
31+
nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
32+
enum nvkm_object_map *type, u64 *addr, u64 *size)
33+
{
34+
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
35+
struct nvkm_device *device = buffer->fault->subdev.device;
36+
*type = NVKM_OBJECT_MAP_IO;
37+
*addr = device->func->resource_addr(device, 3) + buffer->addr;
38+
*size = nvkm_memory_size(buffer->mem);
39+
return 0;
40+
}
41+
42+
static int
43+
nvkm_ufault_ntfy(struct nvkm_object *object, u32 type,
44+
struct nvkm_event **pevent)
45+
{
46+
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
47+
if (type == NVB069_V0_NTFY_FAULT) {
48+
*pevent = &buffer->fault->event;
49+
return 0;
50+
}
51+
return -EINVAL;
52+
}
53+
54+
static int
55+
nvkm_ufault_fini(struct nvkm_object *object, bool suspend)
56+
{
57+
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
58+
buffer->fault->func->buffer.fini(buffer);
59+
return 0;
60+
}
61+
62+
static int
63+
nvkm_ufault_init(struct nvkm_object *object)
64+
{
65+
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
66+
buffer->fault->func->buffer.init(buffer);
67+
return 0;
68+
}
69+
70+
static void *
71+
nvkm_ufault_dtor(struct nvkm_object *object)
72+
{
73+
return NULL;
74+
}
75+
76+
static const struct nvkm_object_func
77+
nvkm_ufault = {
78+
.dtor = nvkm_ufault_dtor,
79+
.init = nvkm_ufault_init,
80+
.fini = nvkm_ufault_fini,
81+
.ntfy = nvkm_ufault_ntfy,
82+
.map = nvkm_ufault_map,
83+
};
84+
85+
int
86+
nvkm_ufault_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
87+
void *argv, u32 argc, struct nvkm_object **pobject)
88+
{
89+
union {
90+
struct nvif_clb069_v0 v0;
91+
} *args = argv;
92+
struct nvkm_fault *fault = device->fault;
93+
struct nvkm_fault_buffer *buffer = fault->buffer[fault->func->user.rp];
94+
int ret = -ENOSYS;
95+
96+
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
97+
args->v0.entries = buffer->entries;
98+
args->v0.get = buffer->get;
99+
args->v0.put = buffer->put;
100+
} else
101+
return ret;
102+
103+
nvkm_object_ctor(&nvkm_ufault, oclass, &buffer->object);
104+
*pobject = &buffer->object;
105+
return 0;
106+
}

0 commit comments

Comments
 (0)