mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: fix REMAP to support small/big pages
Initially, REMAP only worked with big pages but in some cases only small pages are supported where REMAP functionality is also needed. This cleans up some page size assumptions. In particular, on a remap request, the nvgpu_vm_area is found from the passed in VA, but can only be done from virt_offset_in_pages if we're also told the page size. This now occurs from _PAGESIZE_ flags which are required by both map and unmap operations. Jira NVGPU-6804 Change-Id: I311980a1b5e0e5e1840bdc1123479350a5c9d469 Signed-off-by: Chris Johnson <cwj@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2566087 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
359e83b45a
commit
14ed75e857
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2017-2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -157,23 +157,50 @@ void nvgpu_vm_remap_os_buf_put(struct vm_gk20a *vm,
|
||||
static int nvgpu_vm_remap_validate_map_op(struct nvgpu_as_remap_op *op)
|
||||
{
|
||||
int err = 0;
|
||||
u32 valid_flags = (NVGPU_AS_REMAP_OP_FLAGS_CACHEABLE |
|
||||
const u32 pagesize_flags = (NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_4K |
|
||||
NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_64K |
|
||||
NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_128K);
|
||||
const u32 valid_flags = (pagesize_flags |
|
||||
NVGPU_AS_REMAP_OP_FLAGS_CACHEABLE |
|
||||
NVGPU_AS_REMAP_OP_FLAGS_ACCESS_NO_WRITE);
|
||||
const u32 pagesize = op->flags & pagesize_flags;
|
||||
|
||||
if ((op->flags & ~valid_flags) != 0) {
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
/* must be set and to a single pagesize */
|
||||
if ((pagesize != NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_4K) &&
|
||||
(pagesize != NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_64K) &&
|
||||
(pagesize != NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_128K)) {
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nvgpu_vm_remap_validate_unmap_op(struct nvgpu_as_remap_op *op)
|
||||
{
|
||||
int err = 0;
|
||||
const u32 pagesize_flags = (NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_4K |
|
||||
NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_64K |
|
||||
NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_128K);
|
||||
const u32 valid_flags = pagesize_flags;
|
||||
const u32 pagesize = op->flags & pagesize_flags;
|
||||
|
||||
if ((op->flags & ~valid_flags) != 0) {
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
/* must be set and to a single pagesize */
|
||||
if ((pagesize != NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_4K) &&
|
||||
(pagesize != NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_64K) &&
|
||||
(pagesize != NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_128K)) {
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
if ((op->compr_kind != NVGPU_KIND_INVALID) ||
|
||||
(op->incompr_kind != NVGPU_KIND_INVALID) ||
|
||||
(op->flags != 0) ||
|
||||
(op->mem_offset_in_pages != 0)) {
|
||||
err = -EINVAL;
|
||||
}
|
||||
@@ -191,7 +218,15 @@ static u32 nvgpu_vm_remap_translate_as_flags(u32 flags)
|
||||
if ((flags & NVGPU_AS_REMAP_OP_FLAGS_ACCESS_NO_WRITE) != 0) {
|
||||
core_flags |= NVGPU_VM_REMAP_OP_FLAGS_ACCESS_NO_WRITE;
|
||||
}
|
||||
|
||||
if ((flags & NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_4K) != 0) {
|
||||
core_flags |= NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_4K;
|
||||
}
|
||||
if ((flags & NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_64K) != 0) {
|
||||
core_flags |= NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_64K;
|
||||
}
|
||||
if ((flags & NVGPU_AS_REMAP_OP_FLAGS_PAGESIZE_128K) != 0) {
|
||||
core_flags |= NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_128K;
|
||||
}
|
||||
return core_flags;
|
||||
}
|
||||
|
||||
@@ -201,7 +236,6 @@ int nvgpu_vm_remap_translate_as_op(struct vm_gk20a *vm,
|
||||
{
|
||||
int err = 0;
|
||||
u64 page_size;
|
||||
u64 max_num_pages;
|
||||
|
||||
if (as_op->mem_handle == 0) {
|
||||
err = nvgpu_vm_remap_validate_unmap_op(as_op);
|
||||
@@ -212,18 +246,17 @@ int nvgpu_vm_remap_translate_as_op(struct vm_gk20a *vm,
|
||||
if (err != 0)
|
||||
goto clean_up;
|
||||
|
||||
page_size = vm->gmmu_page_sizes[GMMU_PAGE_SIZE_BIG];
|
||||
max_num_pages = (ULONG_MAX / page_size);
|
||||
vm_op->flags = nvgpu_vm_remap_translate_as_flags(as_op->flags);
|
||||
page_size = nvgpu_vm_remap_page_size(vm_op);
|
||||
|
||||
if ((as_op->num_pages == 0) ||
|
||||
(as_op->num_pages > max_num_pages) ||
|
||||
(as_op->mem_offset_in_pages > max_num_pages) ||
|
||||
(as_op->virt_offset_in_pages > max_num_pages)) {
|
||||
if ((as_op->num_pages == 0) || (page_size == 0) ||
|
||||
(as_op->num_pages > (vm->va_limit / page_size)) ||
|
||||
(as_op->mem_offset_in_pages > (vm->va_limit / page_size)) ||
|
||||
(as_op->virt_offset_in_pages > (vm->va_limit / page_size))) {
|
||||
err = -EINVAL;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
vm_op->flags = nvgpu_vm_remap_translate_as_flags(as_op->flags);
|
||||
vm_op->compr_kind = as_op->compr_kind;
|
||||
vm_op->incompr_kind = as_op->incompr_kind;
|
||||
vm_op->mem_handle = as_op->mem_handle;
|
||||
|
||||
Reference in New Issue
Block a user