From d73ad6c07da23636c00c60effeeb53ea35847ee8 Mon Sep 17 00:00:00 2001 From: Sami Kiminki Date: Tue, 28 Nov 2017 18:12:12 +0200 Subject: gpu: nvgpu: Alignment check for compressible fixed-address mappings Add an alignment check for compressible-kind fixed-address mappings. If we're using page size smaller than the comptag line coverage window, the GPU VA and the physical buffer offset must be aligned in respect to that window. Bug 1995897 Bug 2011640 Bug 2011668 Change-Id: If68043ee2828d54b9398d77553d10d35cc319236 Signed-off-by: Sami Kiminki Reviewed-on: https://git-master.nvidia.com/r/1606439 Reviewed-by: mobile promotions Tested-by: mobile promotions --- .../nvgpu/common/linux/vgpu/gm20b/vgpu_hal_gm20b.c | 1 + .../nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c | 1 + .../nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c | 1 + drivers/gpu/nvgpu/common/mm/vm.c | 23 ++++++++++++++++++++++ drivers/gpu/nvgpu/gk20a/gk20a.h | 17 ++++++++++++++++ drivers/gpu/nvgpu/gm20b/fb_gm20b.c | 5 +++++ drivers/gpu/nvgpu/gm20b/fb_gm20b.h | 1 + drivers/gpu/nvgpu/gm20b/hal_gm20b.c | 1 + drivers/gpu/nvgpu/gp106/hal_gp106.c | 1 + drivers/gpu/nvgpu/gp10b/hal_gp10b.c | 1 + drivers/gpu/nvgpu/gv100/hal_gv100.c | 1 + drivers/gpu/nvgpu/gv11b/hal_gv11b.c | 1 + 12 files changed, 54 insertions(+) diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gm20b/vgpu_hal_gm20b.c b/drivers/gpu/nvgpu/common/linux/vgpu/gm20b/vgpu_hal_gm20b.c index 0e560981..6f50dbb8 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/gm20b/vgpu_hal_gm20b.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/gm20b/vgpu_hal_gm20b.c @@ -195,6 +195,7 @@ static const struct gpu_ops vgpu_gm20b_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gm20b_fb_compression_page_size, .compressible_page_size = gm20b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c b/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c index acd0ad5d..7c376396 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c @@ -223,6 +223,7 @@ static const struct gpu_ops vgpu_gp10b_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gp10b_fb_compression_page_size, .compressible_page_size = gp10b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c index a470377c..7d60bfb2 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c @@ -263,6 +263,7 @@ static const struct gpu_ops vgpu_gv11b_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gp10b_fb_compression_page_size, .compressible_page_size = gp10b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index 637632e0..f85089d5 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c @@ -847,6 +847,29 @@ struct nvgpu_mapped_buf *nvgpu_vm_map(struct vm_gk20a *vm, goto clean_up; } + if ((binfo.compr_kind != NVGPU_KIND_INVALID) && + (flags & NVGPU_VM_MAP_FIXED_OFFSET)) { + /* + * Fixed-address compressible mapping is + * requested. Make sure we're respecting the alignment + * requirement for virtual addresses and buffer + * offsets. + * + * This check must be done before we may fall back to + * the incompressible kind. + */ + + const u64 offset_mask = g->ops.fb.compression_align_mask(g); + + if ((map_addr & offset_mask) != (phys_offset & offset_mask)) { + nvgpu_log(g, gpu_dbg_map, + "Misaligned compressible-kind fixed-address " + "mapping"); + err = -EINVAL; + goto clean_up; + } + } + if (binfo.compr_kind != NVGPU_KIND_INVALID) { struct gk20a_comptags comptags = { 0 }; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index a361648f..c6bc129f 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -446,8 +446,25 @@ struct gpu_ops { void (*init_kind_attr)(struct gk20a *g); void (*set_mmu_page_size)(struct gk20a *g); bool (*set_use_full_comp_tag_line)(struct gk20a *g); + + /* + * Compression tag line coverage. When mapping a compressible + * buffer, ctagline is increased when the virtual address + * crosses over the compression page boundary. + */ unsigned int (*compression_page_size)(struct gk20a *g); + + /* + * Minimum page size that can be used for compressible kinds. + */ unsigned int (*compressible_page_size)(struct gk20a *g); + + /* + * Compressible kind mappings: Mask for the virtual and physical + * address bits that must match. + */ + u32 (*compression_align_mask)(struct gk20a *g); + void (*dump_vpr_wpr_info)(struct gk20a *g); int (*vpr_info_fetch)(struct gk20a *g); void (*read_wpr_info)(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/gm20b/fb_gm20b.c b/drivers/gpu/nvgpu/gm20b/fb_gm20b.c index 1f8cc326..0157aa7a 100644 --- a/drivers/gpu/nvgpu/gm20b/fb_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/fb_gm20b.c @@ -70,6 +70,11 @@ unsigned int gm20b_fb_compressible_page_size(struct gk20a *g) return SZ_64K; } +u32 gm20b_fb_compression_align_mask(struct gk20a *g) +{ + return SZ_64K - 1; +} + void gm20b_fb_dump_vpr_wpr_info(struct gk20a *g) { u32 val; diff --git a/drivers/gpu/nvgpu/gm20b/fb_gm20b.h b/drivers/gpu/nvgpu/gm20b/fb_gm20b.h index 32d36f57..1d1d5899 100644 --- a/drivers/gpu/nvgpu/gm20b/fb_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/fb_gm20b.h @@ -31,6 +31,7 @@ void gm20b_fb_set_mmu_page_size(struct gk20a *g); bool gm20b_fb_set_use_full_comp_tag_line(struct gk20a *g); unsigned int gm20b_fb_compression_page_size(struct gk20a *g); unsigned int gm20b_fb_compressible_page_size(struct gk20a *g); +u32 gm20b_fb_compression_align_mask(struct gk20a *g); void gm20b_fb_dump_vpr_wpr_info(struct gk20a *g); void gm20b_fb_read_wpr_info(struct gk20a *g, struct wpr_carveout_info *inf); int gm20b_fb_vpr_info_fetch(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index 920a3e9b..3ef11d11 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c @@ -321,6 +321,7 @@ static const struct gpu_ops gm20b_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gm20b_fb_compression_page_size, .compressible_page_size = gm20b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index d63398c7..a3a58903 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c @@ -378,6 +378,7 @@ static const struct gpu_ops gp106_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gp10b_fb_compression_page_size, .compressible_page_size = gp10b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c index 5ae6b638..0186ba00 100644 --- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c @@ -346,6 +346,7 @@ static const struct gpu_ops gp10b_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gp10b_fb_compression_page_size, .compressible_page_size = gp10b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c index 4044c4b5..36ac029b 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c @@ -430,6 +430,7 @@ static const struct gpu_ops gv100_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gp10b_fb_compression_page_size, .compressible_page_size = gp10b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, diff --git a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c index e6cf0e62..db24a68e 100644 --- a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c @@ -403,6 +403,7 @@ static const struct gpu_ops gv11b_ops = { gm20b_fb_set_use_full_comp_tag_line, .compression_page_size = gp10b_fb_compression_page_size, .compressible_page_size = gp10b_fb_compressible_page_size, + .compression_align_mask = gm20b_fb_compression_align_mask, .vpr_info_fetch = gm20b_fb_vpr_info_fetch, .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info, .read_wpr_info = gm20b_fb_read_wpr_info, -- cgit v1.2.2