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>
This commit is contained in:
@@ -54,6 +54,8 @@
|
|||||||
|
|
||||||
#define VOLTA_USERMODE_A 0x0000c361
|
#define VOLTA_USERMODE_A 0x0000c361
|
||||||
|
|
||||||
|
#define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069
|
||||||
|
|
||||||
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
|
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
|
||||||
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
|
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
|
||||||
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
|
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
|
||||||
|
12
drivers/gpu/drm/nouveau/include/nvif/clb069.h
Normal file
12
drivers/gpu/drm/nouveau/include/nvif/clb069.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef __NVIF_CLB069_H__
|
||||||
|
#define __NVIF_CLB069_H__
|
||||||
|
struct nvif_clb069_v0 {
|
||||||
|
__u8 version;
|
||||||
|
__u8 pad01[3];
|
||||||
|
__u32 entries;
|
||||||
|
__u32 get;
|
||||||
|
__u32 put;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NVB069_V0_NTFY_FAULT 0x00
|
||||||
|
#endif
|
@@ -13,6 +13,8 @@ struct nvkm_fault {
|
|||||||
struct nvkm_event event;
|
struct nvkm_event event;
|
||||||
|
|
||||||
struct nvkm_notify nrpfb;
|
struct nvkm_notify nrpfb;
|
||||||
|
|
||||||
|
struct nvkm_device_oclass user;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nvkm_fault_data {
|
struct nvkm_fault_data {
|
||||||
|
@@ -365,16 +365,15 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sclass) {
|
if (!sclass) {
|
||||||
switch (index) {
|
if (index-- == 0)
|
||||||
case 0: sclass = &nvkm_control_oclass; break;
|
sclass = &nvkm_control_oclass;
|
||||||
case 1:
|
else if (device->mmu && index-- == 0)
|
||||||
if (!device->mmu)
|
|
||||||
return -EINVAL;
|
|
||||||
sclass = &device->mmu->user;
|
sclass = &device->mmu->user;
|
||||||
break;
|
else if (device->fault && index-- == 0)
|
||||||
default:
|
sclass = &device->fault->user;
|
||||||
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
oclass->base = sclass->base;
|
oclass->base = sclass->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
nvkm-y += nvkm/subdev/fault/base.o
|
nvkm-y += nvkm/subdev/fault/base.o
|
||||||
|
nvkm-y += nvkm/subdev/fault/user.o
|
||||||
nvkm-y += nvkm/subdev/fault/gp100.o
|
nvkm-y += nvkm/subdev/fault/gp100.o
|
||||||
nvkm-y += nvkm/subdev/fault/gv100.o
|
nvkm-y += nvkm/subdev/fault/gv100.o
|
||||||
nvkm-y += nvkm/subdev/fault/tu102.o
|
nvkm-y += nvkm/subdev/fault/tu102.o
|
||||||
|
@@ -176,5 +176,7 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev);
|
nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev);
|
||||||
fault->func = func;
|
fault->func = func;
|
||||||
|
fault->user.ctor = nvkm_ufault_new;
|
||||||
|
fault->user.base = func->user.base;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include <subdev/mc.h>
|
#include <subdev/mc.h>
|
||||||
|
|
||||||
|
#include <nvif/class.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
|
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
|
||||||
{
|
{
|
||||||
@@ -69,6 +71,7 @@ gp100_fault = {
|
|||||||
.buffer.init = gp100_fault_buffer_init,
|
.buffer.init = gp100_fault_buffer_init,
|
||||||
.buffer.fini = gp100_fault_buffer_fini,
|
.buffer.fini = gp100_fault_buffer_fini,
|
||||||
.buffer.intr = gp100_fault_buffer_intr,
|
.buffer.intr = gp100_fault_buffer_intr,
|
||||||
|
.user = { { 0, 0, MAXWELL_FAULT_BUFFER_A }, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@@ -34,7 +34,14 @@ struct nvkm_fault_func {
|
|||||||
void (*fini)(struct nvkm_fault_buffer *);
|
void (*fini)(struct nvkm_fault_buffer *);
|
||||||
void (*intr)(struct nvkm_fault_buffer *, bool enable);
|
void (*intr)(struct nvkm_fault_buffer *, bool enable);
|
||||||
} buffer;
|
} buffer;
|
||||||
|
struct {
|
||||||
|
struct nvkm_sclass base;
|
||||||
|
int rp;
|
||||||
|
} user;
|
||||||
};
|
};
|
||||||
|
|
||||||
int gv100_fault_oneinit(struct nvkm_fault *);
|
int gv100_fault_oneinit(struct nvkm_fault *);
|
||||||
|
|
||||||
|
int nvkm_ufault_new(struct nvkm_device *, const struct nvkm_oclass *,
|
||||||
|
void *, u32, struct nvkm_object **);
|
||||||
#endif
|
#endif
|
||||||
|
106
drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
Normal file
106
drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
#include <core/memory.h>
|
||||||
|
#include <subdev/mmu.h>
|
||||||
|
|
||||||
|
#include <nvif/clb069.h>
|
||||||
|
#include <nvif/unpack.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
|
||||||
|
enum nvkm_object_map *type, u64 *addr, u64 *size)
|
||||||
|
{
|
||||||
|
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||||
|
struct nvkm_device *device = buffer->fault->subdev.device;
|
||||||
|
*type = NVKM_OBJECT_MAP_IO;
|
||||||
|
*addr = device->func->resource_addr(device, 3) + buffer->addr;
|
||||||
|
*size = nvkm_memory_size(buffer->mem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_ufault_ntfy(struct nvkm_object *object, u32 type,
|
||||||
|
struct nvkm_event **pevent)
|
||||||
|
{
|
||||||
|
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||||
|
if (type == NVB069_V0_NTFY_FAULT) {
|
||||||
|
*pevent = &buffer->fault->event;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_ufault_fini(struct nvkm_object *object, bool suspend)
|
||||||
|
{
|
||||||
|
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||||
|
buffer->fault->func->buffer.fini(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nvkm_ufault_init(struct nvkm_object *object)
|
||||||
|
{
|
||||||
|
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
|
||||||
|
buffer->fault->func->buffer.init(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
nvkm_ufault_dtor(struct nvkm_object *object)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct nvkm_object_func
|
||||||
|
nvkm_ufault = {
|
||||||
|
.dtor = nvkm_ufault_dtor,
|
||||||
|
.init = nvkm_ufault_init,
|
||||||
|
.fini = nvkm_ufault_fini,
|
||||||
|
.ntfy = nvkm_ufault_ntfy,
|
||||||
|
.map = nvkm_ufault_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
nvkm_ufault_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
|
||||||
|
void *argv, u32 argc, struct nvkm_object **pobject)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct nvif_clb069_v0 v0;
|
||||||
|
} *args = argv;
|
||||||
|
struct nvkm_fault *fault = device->fault;
|
||||||
|
struct nvkm_fault_buffer *buffer = fault->buffer[fault->func->user.rp];
|
||||||
|
int ret = -ENOSYS;
|
||||||
|
|
||||||
|
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
|
||||||
|
args->v0.entries = buffer->entries;
|
||||||
|
args->v0.get = buffer->get;
|
||||||
|
args->v0.put = buffer->put;
|
||||||
|
} else
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
nvkm_object_ctor(&nvkm_ufault, oclass, &buffer->object);
|
||||||
|
*pobject = &buffer->object;
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user