gpu: nvgpu: Implement NVGPU_AS_IOCTL_GET_VA_REGIONS

Implement NVGPU_AS_IOCTL_GET_VA_REGIONS which returns a list of GPU VA
regions for different page sizes. This is required for the userspace
for safe fixed-address address space allocation.

Bug 1551752

Change-Id: I63ddde30935db2471bec498dae0caa870e89c1a5
Signed-off-by: Sami Kiminki <skiminki@nvidia.com>
Reviewed-on: http://git-master/r/590814
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Sami Kiminki
2014-10-28 16:55:12 +02:00
committed by Dan Willemsen
parent f97e7036b1
commit cc6ccd2e3f
3 changed files with 82 additions and 1 deletions

View File

@@ -175,6 +175,52 @@ static int gk20a_as_ioctl_unmap_buffer(
return gk20a_vm_unmap_buffer(as_share, args->offset); return gk20a_vm_unmap_buffer(as_share, args->offset);
} }
static int gk20a_as_ioctl_get_va_regions(
struct gk20a_as_share *as_share,
struct nvgpu_as_get_va_regions_args *args)
{
unsigned int i;
unsigned int write_entries;
struct nvgpu_as_va_region __user *user_region_ptr;
struct vm_gk20a *vm = as_share->vm;
gk20a_dbg_fn("");
write_entries = args->buf_size / sizeof(struct nvgpu_as_va_region);
if (write_entries > gmmu_nr_page_sizes)
write_entries = gmmu_nr_page_sizes;
user_region_ptr =
(struct nvgpu_as_va_region __user *)(uintptr_t)args->buf_addr;
for (i = 0; i < write_entries; ++i) {
struct nvgpu_as_va_region region;
u32 base, limit;
memset(&region, 0, sizeof(struct nvgpu_as_va_region));
if (!vm->vma[i].constraint.enable) {
base = vm->vma[i].base;
limit = vm->vma[i].limit;
} else {
base = vm->vma[i].constraint.base;
limit = vm->vma[i].constraint.limit;
}
region.page_size = vm->gmmu_page_sizes[i];
region.offset = (u64)base * region.page_size;
region.pages = limit - base; /* NOTE: limit is exclusive */
if (copy_to_user(user_region_ptr + i, &region, sizeof(region)))
return -EFAULT;
}
args->buf_size =
gmmu_nr_page_sizes * sizeof(struct nvgpu_as_va_region);
return 0;
}
int gk20a_as_dev_open(struct inode *inode, struct file *filp) int gk20a_as_dev_open(struct inode *inode, struct file *filp)
{ {
struct gk20a_as_share *as_share; struct gk20a_as_share *as_share;
@@ -275,6 +321,11 @@ long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
err = gk20a_as_ioctl_unmap_buffer(as_share, err = gk20a_as_ioctl_unmap_buffer(as_share,
(struct nvgpu_as_unmap_buffer_args *)buf); (struct nvgpu_as_unmap_buffer_args *)buf);
break; break;
case NVGPU_AS_IOCTL_GET_VA_REGIONS:
trace_gk20a_as_ioctl_get_va_regions(dev_name(dev_from_gk20a(g)));
err = gk20a_as_ioctl_get_va_regions(as_share,
(struct nvgpu_as_get_va_regions_args *)buf);
break;
default: default:
dev_dbg(dev_from_gk20a(g), "unrecognized as ioctl: 0x%x", cmd); dev_dbg(dev_from_gk20a(g), "unrecognized as ioctl: 0x%x", cmd);
err = -ENOTTY; err = -ENOTTY;

View File

@@ -237,6 +237,18 @@ TRACE_EVENT(gk20a_as_ioctl_unmap_buffer,
TP_printk("name=%s ", __entry->name) TP_printk("name=%s ", __entry->name)
); );
TRACE_EVENT(gk20a_as_ioctl_get_va_regions,
TP_PROTO(const char *name),
TP_ARGS(name),
TP_STRUCT__entry(
__field(const char *, name)
),
TP_fast_assign(
__entry->name = name;
),
TP_printk("name=%s ", __entry->name)
);
TRACE_EVENT(gk20a_mmu_fault, TRACE_EVENT(gk20a_mmu_fault,
TP_PROTO(u32 fault_hi, u32 fault_lo, TP_PROTO(u32 fault_hi, u32 fault_lo,
u32 fault_info, u32 fault_info,

View File

@@ -793,6 +793,22 @@ struct nvgpu_as_unmap_buffer_args {
__u64 offset; /* in, byte address */ __u64 offset; /* in, byte address */
}; };
struct nvgpu_as_va_region {
__u64 offset;
__u32 page_size;
__u32 reserved;
__u64 pages;
};
struct nvgpu_as_get_va_regions_args {
__u64 buf_addr; /* Pointer to array of nvgpu_as_va_region:s.
* Ignored if buf_size is 0 */
__u32 buf_size; /* in: userspace buf size (in bytes)
out: kernel buf size (in bytes) */
__u32 reserved;
};
#define NVGPU_AS_IOCTL_BIND_CHANNEL \ #define NVGPU_AS_IOCTL_BIND_CHANNEL \
_IOWR(NVGPU_AS_IOCTL_MAGIC, 1, struct nvgpu_as_bind_channel_args) _IOWR(NVGPU_AS_IOCTL_MAGIC, 1, struct nvgpu_as_bind_channel_args)
#define NVGPU32_AS_IOCTL_ALLOC_SPACE \ #define NVGPU32_AS_IOCTL_ALLOC_SPACE \
@@ -807,9 +823,11 @@ struct nvgpu_as_unmap_buffer_args {
_IOWR(NVGPU_AS_IOCTL_MAGIC, 6, struct nvgpu_as_alloc_space_args) _IOWR(NVGPU_AS_IOCTL_MAGIC, 6, struct nvgpu_as_alloc_space_args)
#define NVGPU_AS_IOCTL_MAP_BUFFER_EX \ #define NVGPU_AS_IOCTL_MAP_BUFFER_EX \
_IOWR(NVGPU_AS_IOCTL_MAGIC, 7, struct nvgpu_as_map_buffer_ex_args) _IOWR(NVGPU_AS_IOCTL_MAGIC, 7, struct nvgpu_as_map_buffer_ex_args)
#define NVGPU_AS_IOCTL_GET_VA_REGIONS \
_IOWR(NVGPU_AS_IOCTL_MAGIC, 8, struct nvgpu_as_get_va_regions_args)
#define NVGPU_AS_IOCTL_LAST \ #define NVGPU_AS_IOCTL_LAST \
_IOC_NR(NVGPU_AS_IOCTL_MAP_BUFFER_EX) _IOC_NR(NVGPU_AS_IOCTL_GET_VA_REGIONS)
#define NVGPU_AS_IOCTL_MAX_ARG_SIZE \ #define NVGPU_AS_IOCTL_MAX_ARG_SIZE \
sizeof(struct nvgpu_as_map_buffer_ex_args) sizeof(struct nvgpu_as_map_buffer_ex_args)