diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/as_gk20a.c | 51 |
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 | ||
178 | static 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(®ion, 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, ®ion, 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 | |||
178 | int gk20a_as_dev_open(struct inode *inode, struct file *filp) | 224 | int 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; |