Skip to content

Commit 71871aa

Browse files
author
Ben Skeggs
committed
drm/nouveau/mmu/gp100-: add privileged methods for fault replay/cancel
Host methods exist to do at least some of what we need, but we are not currently pushing replay/cancels through a channel like UVM does as it's not clear whether it's necessary in our case (UVM also updates PTEs with the GPU). UVM also pushes a software method for fault cancels on Pascal, seemingly because the host methods don't appear to be sufficient. If/when we want to push the replay/cancel on the GPU, we can re-purpose the cancellation code here to implement that swmthd. Keep it simple for now, until we figure out exactly what we need here. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
1 parent a5ff307 commit 71871aa

File tree

8 files changed

+101
-0
lines changed

8 files changed

+101
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct nvif_vmm_v0 {
1717
#define NVIF_VMM_V0_UNMAP 0x04
1818
#define NVIF_VMM_V0_PFNMAP 0x05
1919
#define NVIF_VMM_V0_PFNCLR 0x06
20+
#define NVIF_VMM_V0_MTHD(i) ((i) + 0x80)
2021

2122
struct nvif_vmm_page_v0 {
2223
__u8 version;

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,19 @@ struct gp100_vmm_map_v0 {
1818
__u8 priv;
1919
__u8 kind;
2020
};
21+
22+
#define GP100_VMM_VN_FAULT_REPLAY NVIF_VMM_V0_MTHD(0x00)
23+
#define GP100_VMM_VN_FAULT_CANCEL NVIF_VMM_V0_MTHD(0x01)
24+
25+
struct gp100_vmm_fault_replay_vn {
26+
};
27+
28+
struct gp100_vmm_fault_cancel_v0 {
29+
__u8 version;
30+
__u8 hub;
31+
__u8 gpc;
32+
__u8 client;
33+
__u8 pad04[4];
34+
__u64 inst;
35+
};
2136
#endif

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,13 @@ nvkm_uvmm_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
341341
case NVIF_VMM_V0_UNMAP : return nvkm_uvmm_mthd_unmap (uvmm, argv, argc);
342342
case NVIF_VMM_V0_PFNMAP: return nvkm_uvmm_mthd_pfnmap(uvmm, argv, argc);
343343
case NVIF_VMM_V0_PFNCLR: return nvkm_uvmm_mthd_pfnclr(uvmm, argv, argc);
344+
case NVIF_VMM_V0_MTHD(0x00) ... NVIF_VMM_V0_MTHD(0x7f):
345+
if (uvmm->vmm->func->mthd) {
346+
return uvmm->vmm->func->mthd(uvmm->vmm,
347+
uvmm->object.client,
348+
mthd, argv, argc);
349+
}
350+
break;
344351
default:
345352
break;
346353
}

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ struct nvkm_vmm_func {
145145
struct nvkm_vmm_map *);
146146
void (*flush)(struct nvkm_vmm *, int depth);
147147

148+
int (*mthd)(struct nvkm_vmm *, struct nvkm_client *,
149+
u32 mthd, void *argv, u32 argc);
150+
148151
void (*invalidate_pdb)(struct nvkm_vmm *, u64 addr);
149152

150153
u64 page_block;
@@ -220,6 +223,7 @@ int gm200_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
220223
int gp100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
221224
int gp100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *);
222225
void gp100_vmm_flush(struct nvkm_vmm *, int);
226+
int gp100_vmm_mthd(struct nvkm_vmm *, struct nvkm_client *, u32, void *, u32);
223227
void gp100_vmm_invalidate_pdb(struct nvkm_vmm *, u64 addr);
224228

225229
int gv100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
*/
2222
#include "vmm.h"
2323

24+
#include <core/client.h>
2425
#include <subdev/fb.h>
2526
#include <subdev/ltc.h>
27+
#include <subdev/timer.h>
28+
#include <engine/gr.h>
2629

2730
#include <nvif/ifc00d.h>
2831
#include <nvif/unpack.h>
@@ -384,6 +387,73 @@ gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
384387
return 0;
385388
}
386389

390+
static int
391+
gp100_vmm_fault_cancel(struct nvkm_vmm *vmm, void *argv, u32 argc)
392+
{
393+
struct nvkm_device *device = vmm->mmu->subdev.device;
394+
union {
395+
struct gp100_vmm_fault_cancel_v0 v0;
396+
} *args = argv;
397+
int ret = -ENOSYS;
398+
u32 inst, aper;
399+
400+
if ((ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false)))
401+
return ret;
402+
403+
/* Translate MaxwellFaultBufferA instance pointer to the same
404+
* format as the NV_GR_FECS_CURRENT_CTX register.
405+
*/
406+
aper = (args->v0.inst >> 8) & 3;
407+
args->v0.inst >>= 12;
408+
args->v0.inst |= aper << 28;
409+
args->v0.inst |= 0x80000000;
410+
411+
if (!WARN_ON(nvkm_gr_ctxsw_pause(device))) {
412+
if ((inst = nvkm_gr_ctxsw_inst(device)) == args->v0.inst) {
413+
gf100_vmm_invalidate(vmm, 0x0000001b
414+
/* CANCEL_TARGETED. */ |
415+
(args->v0.hub << 20) |
416+
(args->v0.gpc << 15) |
417+
(args->v0.client << 9));
418+
}
419+
WARN_ON(nvkm_gr_ctxsw_resume(device));
420+
}
421+
422+
return 0;
423+
}
424+
425+
static int
426+
gp100_vmm_fault_replay(struct nvkm_vmm *vmm, void *argv, u32 argc)
427+
{
428+
union {
429+
struct gp100_vmm_fault_replay_vn vn;
430+
} *args = argv;
431+
int ret = -ENOSYS;
432+
433+
if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) {
434+
gf100_vmm_invalidate(vmm, 0x0000000b); /* REPLAY_GLOBAL. */
435+
}
436+
437+
return ret;
438+
}
439+
440+
int
441+
gp100_vmm_mthd(struct nvkm_vmm *vmm,
442+
struct nvkm_client *client, u32 mthd, void *argv, u32 argc)
443+
{
444+
if (client->super) {
445+
switch (mthd) {
446+
case GP100_VMM_VN_FAULT_REPLAY:
447+
return gp100_vmm_fault_replay(vmm, argv, argc);
448+
case GP100_VMM_VN_FAULT_CANCEL:
449+
return gp100_vmm_fault_cancel(vmm, argv, argc);
450+
default:
451+
break;
452+
}
453+
}
454+
return -EINVAL;
455+
}
456+
387457
void
388458
gp100_vmm_invalidate_pdb(struct nvkm_vmm *vmm, u64 addr)
389459
{
@@ -417,6 +487,7 @@ gp100_vmm = {
417487
.aper = gf100_vmm_aper,
418488
.valid = gp100_vmm_valid,
419489
.flush = gp100_vmm_flush,
490+
.mthd = gp100_vmm_mthd,
420491
.invalidate_pdb = gp100_vmm_invalidate_pdb,
421492
.page = {
422493
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ gp10b_vmm = {
2828
.aper = gk20a_vmm_aper,
2929
.valid = gp100_vmm_valid,
3030
.flush = gp100_vmm_flush,
31+
.mthd = gp100_vmm_mthd,
3132
.invalidate_pdb = gp100_vmm_invalidate_pdb,
3233
.page = {
3334
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgv100.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ gv100_vmm = {
6666
.aper = gf100_vmm_aper,
6767
.valid = gp100_vmm_valid,
6868
.flush = gp100_vmm_flush,
69+
.mthd = gp100_vmm_mthd,
6970
.invalidate_pdb = gp100_vmm_invalidate_pdb,
7071
.page = {
7172
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },

drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ tu102_vmm = {
5656
.aper = gf100_vmm_aper,
5757
.valid = gp100_vmm_valid,
5858
.flush = tu102_vmm_flush,
59+
.mthd = gp100_vmm_mthd,
5960
.page = {
6061
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
6162
{ 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx },

0 commit comments

Comments
 (0)