summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/as_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/as_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/as_gk20a.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/as_gk20a.c b/drivers/gpu/nvgpu/gk20a/as_gk20a.c
index 0f587a30..34423d21 100644
--- a/drivers/gpu/nvgpu/gk20a/as_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/as_gk20a.c
@@ -175,6 +175,52 @@ static int gk20a_as_ioctl_unmap_buffer(
175 return gk20a_vm_unmap_buffer(as_share, args->offset); 175 return gk20a_vm_unmap_buffer(as_share, args->offset);
176} 176}
177 177
178static int gk20a_as_ioctl_get_va_regions(
179 struct gk20a_as_share *as_share,
180 struct nvgpu_as_get_va_regions_args *args)
181{
182 unsigned int i;
183 unsigned int write_entries;
184 struct nvgpu_as_va_region __user *user_region_ptr;
185 struct vm_gk20a *vm = as_share->vm;
186
187 gk20a_dbg_fn("");
188
189 write_entries = args->buf_size / sizeof(struct nvgpu_as_va_region);
190 if (write_entries > gmmu_nr_page_sizes)
191 write_entries = gmmu_nr_page_sizes;
192
193 user_region_ptr =
194 (struct nvgpu_as_va_region __user *)(uintptr_t)args->buf_addr;
195
196 for (i = 0; i < write_entries; ++i) {
197 struct nvgpu_as_va_region region;
198 u32 base, limit;
199
200 memset(&region, 0, sizeof(struct nvgpu_as_va_region));
201
202 if (!vm->vma[i].constraint.enable) {
203 base = vm->vma[i].base;
204 limit = vm->vma[i].limit;
205 } else {
206 base = vm->vma[i].constraint.base;
207 limit = vm->vma[i].constraint.limit;
208 }
209
210 region.page_size = vm->gmmu_page_sizes[i];
211 region.offset = (u64)base * region.page_size;
212 region.pages = limit - base; /* NOTE: limit is exclusive */
213
214 if (copy_to_user(user_region_ptr + i, &region, sizeof(region)))
215 return -EFAULT;
216 }
217
218 args->buf_size =
219 gmmu_nr_page_sizes * sizeof(struct nvgpu_as_va_region);
220
221 return 0;
222}
223
178int gk20a_as_dev_open(struct inode *inode, struct file *filp) 224int gk20a_as_dev_open(struct inode *inode, struct file *filp)
179{ 225{
180 struct gk20a_as_share *as_share; 226 struct gk20a_as_share *as_share;
@@ -275,6 +321,11 @@ long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
275 err = gk20a_as_ioctl_unmap_buffer(as_share, 321 err = gk20a_as_ioctl_unmap_buffer(as_share,
276 (struct nvgpu_as_unmap_buffer_args *)buf); 322 (struct nvgpu_as_unmap_buffer_args *)buf);
277 break; 323 break;
324 case NVGPU_AS_IOCTL_GET_VA_REGIONS:
325 trace_gk20a_as_ioctl_get_va_regions(dev_name(dev_from_gk20a(g)));
326 err = gk20a_as_ioctl_get_va_regions(as_share,
327 (struct nvgpu_as_get_va_regions_args *)buf);
328 break;
278 default: 329 default:
279 dev_dbg(dev_from_gk20a(g), "unrecognized as ioctl: 0x%x", cmd); 330 dev_dbg(dev_from_gk20a(g), "unrecognized as ioctl: 0x%x", cmd);
280 err = -ENOTTY; 331 err = -ENOTTY;