@@ -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+
45108static int
46109nvkm_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 ;
83146done :
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