From 10e97dccc54d4bd271c2de82dfce26b2c161bf94 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 31 Mar 2015 13:15:58 -0700 Subject: gpu: nvgpu: Check alignment of fixed allocs When mapping buffer on a fixed address, ensure that the alignment of buffer and the address are compabile. When freeing, retrieve page size from the VA instead of choosing it again. Bug 1605769 Change-Id: I4f73453996cd53a912b6a414caa41563cde28da7 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/725764 --- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index d8dacad8..43758712 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -1312,16 +1312,25 @@ u64 gk20a_vm_map(struct vm_gk20a *vm, bfr.pgsz_idx = -1; mapping_size = mapping_size ? mapping_size : bfr.size; - /* If FIX_OFFSET is set, pgsz is determined. Otherwise, select - * page size according to memory alignment */ + if (vm->big_pages) + gmmu_select_page_size(vm, &bfr); + else + bfr.pgsz_idx = gmmu_page_size_small; + + /* If FIX_OFFSET is set, pgsz is determined at address allocation + * time. The alignment at address alloc time must be the same as + * the alignment determined by gmmu_select_page_size(). + */ if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) { - bfr.pgsz_idx = NV_GMMU_VA_IS_UPPER(offset_align) ? + int pgsz_idx = NV_GMMU_VA_IS_UPPER(offset_align) ? gmmu_page_size_big : gmmu_page_size_small; - } else { - if (vm->big_pages) - gmmu_select_page_size(vm, &bfr); - else - bfr.pgsz_idx = gmmu_page_size_small; + if (pgsz_idx > bfr.pgsz_idx) { + gk20a_err(d, "%llx buffer pgsz %d, VA pgsz %d", + offset_align, bfr.pgsz_idx, pgsz_idx); + err = -EINVAL; + goto clean_up; + } + bfr.pgsz_idx = min(bfr.pgsz_idx, pgsz_idx); } /* validate/adjust bfr attributes */ @@ -2495,17 +2504,8 @@ int gk20a_vm_free_space(struct gk20a_as_share *as_share, args->pages, args->offset); /* determine pagesz idx */ - for (pgsz_idx = gmmu_page_size_small; - pgsz_idx < gmmu_nr_page_sizes; - pgsz_idx++) { - if (vm->gmmu_page_sizes[pgsz_idx] == args->page_size) - break; - } - - if (pgsz_idx >= gmmu_nr_page_sizes) { - err = -EINVAL; - goto clean_up; - } + pgsz_idx = NV_GMMU_VA_IS_UPPER(args->offset) ? + gmmu_page_size_big : gmmu_page_size_small; start_page_nr = (u32)(args->offset >> ilog2(vm->gmmu_page_sizes[pgsz_idx])); -- cgit v1.2.2