Skip to content

Commit a5ff307

Browse files
author
Ben Skeggs
committed
drm/nouveau/mmu: add a privileged method to directly manage PTEs
This provides a somewhat more direct method of manipulating the GPU page tables, which will be required to support SVM. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
1 parent 8e68271 commit a5ff307

File tree

6 files changed

+451
-34
lines changed

6 files changed

+451
-34
lines changed

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ struct nvif_vmm_v0 {
1515
#define NVIF_VMM_V0_PUT 0x02
1616
#define NVIF_VMM_V0_MAP 0x03
1717
#define NVIF_VMM_V0_UNMAP 0x04
18+
#define NVIF_VMM_V0_PFNMAP 0x05
19+
#define NVIF_VMM_V0_PFNCLR 0x06
1820

1921
struct nvif_vmm_page_v0 {
2022
__u8 version;
@@ -62,4 +64,28 @@ struct nvif_vmm_unmap_v0 {
6264
__u8 pad01[7];
6365
__u64 addr;
6466
};
67+
68+
struct nvif_vmm_pfnmap_v0 {
69+
__u8 version;
70+
__u8 page;
71+
__u8 pad02[6];
72+
__u64 addr;
73+
__u64 size;
74+
#define NVIF_VMM_PFNMAP_V0_ADDR 0xfffffffffffff000ULL
75+
#define NVIF_VMM_PFNMAP_V0_ADDR_SHIFT 12
76+
#define NVIF_VMM_PFNMAP_V0_APER 0x00000000000000f0ULL
77+
#define NVIF_VMM_PFNMAP_V0_HOST 0x0000000000000000ULL
78+
#define NVIF_VMM_PFNMAP_V0_VRAM 0x0000000000000010ULL
79+
#define NVIF_VMM_PFNMAP_V0_W 0x0000000000000002ULL
80+
#define NVIF_VMM_PFNMAP_V0_V 0x0000000000000001ULL
81+
#define NVIF_VMM_PFNMAP_V0_NONE 0x0000000000000000ULL
82+
__u64 phys[];
83+
};
84+
85+
struct nvif_vmm_pfnclr_v0 {
86+
__u8 version;
87+
__u8 pad01[7];
88+
__u64 addr;
89+
__u64 size;
90+
};
6591
#endif

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct nvkm_vmm_map {
6464
struct nvkm_mm_node *mem;
6565
struct scatterlist *sgl;
6666
dma_addr_t *dma;
67+
u64 *pfn;
6768
u64 off;
6869

6970
const struct nvkm_vmm_page *page;

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

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,69 @@ nvkm_uvmm_search(struct nvkm_client *client, u64 handle)
4242
return nvkm_uvmm(object)->vmm;
4343
}
4444

45+
static int
46+
nvkm_uvmm_mthd_pfnclr(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
47+
{
48+
struct nvkm_client *client = uvmm->object.client;
49+
union {
50+
struct nvif_vmm_pfnclr_v0 v0;
51+
} *args = argv;
52+
struct nvkm_vmm *vmm = uvmm->vmm;
53+
int ret = -ENOSYS;
54+
u64 addr, size;
55+
56+
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
57+
addr = args->v0.addr;
58+
size = args->v0.size;
59+
} else
60+
return ret;
61+
62+
if (!client->super)
63+
return -ENOENT;
64+
65+
if (size) {
66+
mutex_lock(&vmm->mutex);
67+
ret = nvkm_vmm_pfn_unmap(vmm, addr, size);
68+
mutex_unlock(&vmm->mutex);
69+
}
70+
71+
return ret;
72+
}
73+
74+
static int
75+
nvkm_uvmm_mthd_pfnmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
76+
{
77+
struct nvkm_client *client = uvmm->object.client;
78+
union {
79+
struct nvif_vmm_pfnmap_v0 v0;
80+
} *args = argv;
81+
struct nvkm_vmm *vmm = uvmm->vmm;
82+
int ret = -ENOSYS;
83+
u64 addr, size, *phys;
84+
u8 page;
85+
86+
if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, true))) {
87+
page = args->v0.page;
88+
addr = args->v0.addr;
89+
size = args->v0.size;
90+
phys = args->v0.phys;
91+
if (argc != (size >> page) * sizeof(args->v0.phys[0]))
92+
return -EINVAL;
93+
} else
94+
return ret;
95+
96+
if (!client->super)
97+
return -ENOENT;
98+
99+
if (size) {
100+
mutex_lock(&vmm->mutex);
101+
ret = nvkm_vmm_pfn_map(vmm, page, addr, size, phys);
102+
mutex_unlock(&vmm->mutex);
103+
}
104+
105+
return ret;
106+
}
107+
45108
static int
46109
nvkm_uvmm_mthd_unmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
47110
{
@@ -78,7 +141,7 @@ nvkm_uvmm_mthd_unmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
78141
goto done;
79142
}
80143

81-
nvkm_vmm_unmap_locked(vmm, vma);
144+
nvkm_vmm_unmap_locked(vmm, vma, false);
82145
ret = 0;
83146
done:
84147
mutex_unlock(&vmm->mutex);
@@ -124,6 +187,11 @@ nvkm_uvmm_mthd_map(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
124187
goto fail;
125188
}
126189

190+
if (ret = -EINVAL, vma->mapped && !vma->memory) {
191+
VMM_DEBUG(vmm, "pfnmap %016llx", addr);
192+
goto fail;
193+
}
194+
127195
if (ret = -EINVAL, vma->addr != addr || vma->size != size) {
128196
if (addr + size > vma->addr + vma->size || vma->memory ||
129197
(vma->refd == NVKM_VMA_PAGE_NONE && !vma->mapref)) {
@@ -271,6 +339,8 @@ nvkm_uvmm_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
271339
case NVIF_VMM_V0_PUT : return nvkm_uvmm_mthd_put (uvmm, argv, argc);
272340
case NVIF_VMM_V0_MAP : return nvkm_uvmm_mthd_map (uvmm, argv, argc);
273341
case NVIF_VMM_V0_UNMAP : return nvkm_uvmm_mthd_unmap (uvmm, argv, argc);
342+
case NVIF_VMM_V0_PFNMAP: return nvkm_uvmm_mthd_pfnmap(uvmm, argv, argc);
343+
case NVIF_VMM_V0_PFNCLR: return nvkm_uvmm_mthd_pfnclr(uvmm, argv, argc);
274344
default:
275345
break;
276346
}

0 commit comments

Comments
 (0)