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>
This commit is contained in:
parent
a5ff307fe1
commit
71871aa6df
@ -17,6 +17,7 @@ struct nvif_vmm_v0 {
|
|||||||
#define NVIF_VMM_V0_UNMAP 0x04
|
#define NVIF_VMM_V0_UNMAP 0x04
|
||||||
#define NVIF_VMM_V0_PFNMAP 0x05
|
#define NVIF_VMM_V0_PFNMAP 0x05
|
||||||
#define NVIF_VMM_V0_PFNCLR 0x06
|
#define NVIF_VMM_V0_PFNCLR 0x06
|
||||||
|
#define NVIF_VMM_V0_MTHD(i) ((i) + 0x80)
|
||||||
|
|
||||||
struct nvif_vmm_page_v0 {
|
struct nvif_vmm_page_v0 {
|
||||||
__u8 version;
|
__u8 version;
|
||||||
|
@ -18,4 +18,19 @@ struct gp100_vmm_map_v0 {
|
|||||||
__u8 priv;
|
__u8 priv;
|
||||||
__u8 kind;
|
__u8 kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GP100_VMM_VN_FAULT_REPLAY NVIF_VMM_V0_MTHD(0x00)
|
||||||
|
#define GP100_VMM_VN_FAULT_CANCEL NVIF_VMM_V0_MTHD(0x01)
|
||||||
|
|
||||||
|
struct gp100_vmm_fault_replay_vn {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gp100_vmm_fault_cancel_v0 {
|
||||||
|
__u8 version;
|
||||||
|
__u8 hub;
|
||||||
|
__u8 gpc;
|
||||||
|
__u8 client;
|
||||||
|
__u8 pad04[4];
|
||||||
|
__u64 inst;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -341,6 +341,13 @@ nvkm_uvmm_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
|
|||||||
case NVIF_VMM_V0_UNMAP : return nvkm_uvmm_mthd_unmap (uvmm, argv, argc);
|
case NVIF_VMM_V0_UNMAP : return nvkm_uvmm_mthd_unmap (uvmm, argv, argc);
|
||||||
case NVIF_VMM_V0_PFNMAP: return nvkm_uvmm_mthd_pfnmap(uvmm, argv, argc);
|
case NVIF_VMM_V0_PFNMAP: return nvkm_uvmm_mthd_pfnmap(uvmm, argv, argc);
|
||||||
case NVIF_VMM_V0_PFNCLR: return nvkm_uvmm_mthd_pfnclr(uvmm, argv, argc);
|
case NVIF_VMM_V0_PFNCLR: return nvkm_uvmm_mthd_pfnclr(uvmm, argv, argc);
|
||||||
|
case NVIF_VMM_V0_MTHD(0x00) ... NVIF_VMM_V0_MTHD(0x7f):
|
||||||
|
if (uvmm->vmm->func->mthd) {
|
||||||
|
return uvmm->vmm->func->mthd(uvmm->vmm,
|
||||||
|
uvmm->object.client,
|
||||||
|
mthd, argv, argc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,9 @@ struct nvkm_vmm_func {
|
|||||||
struct nvkm_vmm_map *);
|
struct nvkm_vmm_map *);
|
||||||
void (*flush)(struct nvkm_vmm *, int depth);
|
void (*flush)(struct nvkm_vmm *, int depth);
|
||||||
|
|
||||||
|
int (*mthd)(struct nvkm_vmm *, struct nvkm_client *,
|
||||||
|
u32 mthd, void *argv, u32 argc);
|
||||||
|
|
||||||
void (*invalidate_pdb)(struct nvkm_vmm *, u64 addr);
|
void (*invalidate_pdb)(struct nvkm_vmm *, u64 addr);
|
||||||
|
|
||||||
u64 page_block;
|
u64 page_block;
|
||||||
@ -220,6 +223,7 @@ int gm200_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
|
|||||||
int gp100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
|
int gp100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
|
||||||
int gp100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *);
|
int gp100_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *);
|
||||||
void gp100_vmm_flush(struct nvkm_vmm *, int);
|
void gp100_vmm_flush(struct nvkm_vmm *, int);
|
||||||
|
int gp100_vmm_mthd(struct nvkm_vmm *, struct nvkm_client *, u32, void *, u32);
|
||||||
void gp100_vmm_invalidate_pdb(struct nvkm_vmm *, u64 addr);
|
void gp100_vmm_invalidate_pdb(struct nvkm_vmm *, u64 addr);
|
||||||
|
|
||||||
int gv100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
|
int gv100_vmm_join(struct nvkm_vmm *, struct nvkm_memory *);
|
||||||
|
@ -21,8 +21,11 @@
|
|||||||
*/
|
*/
|
||||||
#include "vmm.h"
|
#include "vmm.h"
|
||||||
|
|
||||||
|
#include <core/client.h>
|
||||||
#include <subdev/fb.h>
|
#include <subdev/fb.h>
|
||||||
#include <subdev/ltc.h>
|
#include <subdev/ltc.h>
|
||||||
|
#include <subdev/timer.h>
|
||||||
|
#include <engine/gr.h>
|
||||||
|
|
||||||
#include <nvif/ifc00d.h>
|
#include <nvif/ifc00d.h>
|
||||||
#include <nvif/unpack.h>
|
#include <nvif/unpack.h>
|
||||||
@ -384,6 +387,73 @@ gp100_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gp100_vmm_fault_cancel(struct nvkm_vmm *vmm, void *argv, u32 argc)
|
||||||
|
{
|
||||||
|
struct nvkm_device *device = vmm->mmu->subdev.device;
|
||||||
|
union {
|
||||||
|
struct gp100_vmm_fault_cancel_v0 v0;
|
||||||
|
} *args = argv;
|
||||||
|
int ret = -ENOSYS;
|
||||||
|
u32 inst, aper;
|
||||||
|
|
||||||
|
if ((ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Translate MaxwellFaultBufferA instance pointer to the same
|
||||||
|
* format as the NV_GR_FECS_CURRENT_CTX register.
|
||||||
|
*/
|
||||||
|
aper = (args->v0.inst >> 8) & 3;
|
||||||
|
args->v0.inst >>= 12;
|
||||||
|
args->v0.inst |= aper << 28;
|
||||||
|
args->v0.inst |= 0x80000000;
|
||||||
|
|
||||||
|
if (!WARN_ON(nvkm_gr_ctxsw_pause(device))) {
|
||||||
|
if ((inst = nvkm_gr_ctxsw_inst(device)) == args->v0.inst) {
|
||||||
|
gf100_vmm_invalidate(vmm, 0x0000001b
|
||||||
|
/* CANCEL_TARGETED. */ |
|
||||||
|
(args->v0.hub << 20) |
|
||||||
|
(args->v0.gpc << 15) |
|
||||||
|
(args->v0.client << 9));
|
||||||
|
}
|
||||||
|
WARN_ON(nvkm_gr_ctxsw_resume(device));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gp100_vmm_fault_replay(struct nvkm_vmm *vmm, void *argv, u32 argc)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct gp100_vmm_fault_replay_vn vn;
|
||||||
|
} *args = argv;
|
||||||
|
int ret = -ENOSYS;
|
||||||
|
|
||||||
|
if (!(ret = nvif_unvers(ret, &argv, &argc, args->vn))) {
|
||||||
|
gf100_vmm_invalidate(vmm, 0x0000000b); /* REPLAY_GLOBAL. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gp100_vmm_mthd(struct nvkm_vmm *vmm,
|
||||||
|
struct nvkm_client *client, u32 mthd, void *argv, u32 argc)
|
||||||
|
{
|
||||||
|
if (client->super) {
|
||||||
|
switch (mthd) {
|
||||||
|
case GP100_VMM_VN_FAULT_REPLAY:
|
||||||
|
return gp100_vmm_fault_replay(vmm, argv, argc);
|
||||||
|
case GP100_VMM_VN_FAULT_CANCEL:
|
||||||
|
return gp100_vmm_fault_cancel(vmm, argv, argc);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gp100_vmm_invalidate_pdb(struct nvkm_vmm *vmm, u64 addr)
|
gp100_vmm_invalidate_pdb(struct nvkm_vmm *vmm, u64 addr)
|
||||||
{
|
{
|
||||||
@ -417,6 +487,7 @@ gp100_vmm = {
|
|||||||
.aper = gf100_vmm_aper,
|
.aper = gf100_vmm_aper,
|
||||||
.valid = gp100_vmm_valid,
|
.valid = gp100_vmm_valid,
|
||||||
.flush = gp100_vmm_flush,
|
.flush = gp100_vmm_flush,
|
||||||
|
.mthd = gp100_vmm_mthd,
|
||||||
.invalidate_pdb = gp100_vmm_invalidate_pdb,
|
.invalidate_pdb = gp100_vmm_invalidate_pdb,
|
||||||
.page = {
|
.page = {
|
||||||
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
||||||
|
@ -28,6 +28,7 @@ gp10b_vmm = {
|
|||||||
.aper = gk20a_vmm_aper,
|
.aper = gk20a_vmm_aper,
|
||||||
.valid = gp100_vmm_valid,
|
.valid = gp100_vmm_valid,
|
||||||
.flush = gp100_vmm_flush,
|
.flush = gp100_vmm_flush,
|
||||||
|
.mthd = gp100_vmm_mthd,
|
||||||
.invalidate_pdb = gp100_vmm_invalidate_pdb,
|
.invalidate_pdb = gp100_vmm_invalidate_pdb,
|
||||||
.page = {
|
.page = {
|
||||||
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
||||||
|
@ -66,6 +66,7 @@ gv100_vmm = {
|
|||||||
.aper = gf100_vmm_aper,
|
.aper = gf100_vmm_aper,
|
||||||
.valid = gp100_vmm_valid,
|
.valid = gp100_vmm_valid,
|
||||||
.flush = gp100_vmm_flush,
|
.flush = gp100_vmm_flush,
|
||||||
|
.mthd = gp100_vmm_mthd,
|
||||||
.invalidate_pdb = gp100_vmm_invalidate_pdb,
|
.invalidate_pdb = gp100_vmm_invalidate_pdb,
|
||||||
.page = {
|
.page = {
|
||||||
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
||||||
|
@ -56,6 +56,7 @@ tu102_vmm = {
|
|||||||
.aper = gf100_vmm_aper,
|
.aper = gf100_vmm_aper,
|
||||||
.valid = gp100_vmm_valid,
|
.valid = gp100_vmm_valid,
|
||||||
.flush = tu102_vmm_flush,
|
.flush = tu102_vmm_flush,
|
||||||
|
.mthd = gp100_vmm_mthd,
|
||||||
.page = {
|
.page = {
|
||||||
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
{ 47, &gp100_vmm_desc_16[4], NVKM_VMM_PAGE_Sxxx },
|
||||||
{ 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx },
|
{ 38, &gp100_vmm_desc_16[3], NVKM_VMM_PAGE_Sxxx },
|
||||||
|
Loading…
Reference in New Issue
Block a user