summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-11-30 14:05:14 -0500
committerDeepak Bhosale <dbhosale@nvidia.com>2017-12-05 13:25:37 -0500
commit1b125d8cbe05766c0cfb0ba9cac2bf46ffef7c3a (patch)
tree8566528813e08666431abea7a0063816a7b15156
parentfa2a3e2d3dd780d409e7673e7b47a34fd1cafb4f (diff)
gpu: nvgpu: fix indexing in locate pte function
The current code does not properly calculate the indexes within the PDE to access the proper entry, and it has a bug in assignement of the big page entries. This change fixes the issue by: (1) Passing a pointer to the level structure and dereferencing the index offset to the next level. (2) Changing the format of the address. (3) Ensuring big pages are only selected if their address is set. Bug 200364599 Change-Id: I46e32560ee341d8cfc08c077282dcb5549d2a140 Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1610562 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Deepak Bhosale <dbhosale@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/mm/gmmu.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gp10b/mm_gp10b.c23
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/gmmu.h1
5 files changed, 18 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/gmmu.c b/drivers/gpu/nvgpu/common/mm/gmmu.c
index 62c84e96..22f73083 100644
--- a/drivers/gpu/nvgpu/common/mm/gmmu.c
+++ b/drivers/gpu/nvgpu/common/mm/gmmu.c
@@ -838,7 +838,7 @@ static int __nvgpu_locate_pte(struct gk20a *g, struct vm_gk20a *vm,
838 if (!pd_next->mem) 838 if (!pd_next->mem)
839 return -EINVAL; 839 return -EINVAL;
840 840
841 attrs->pgsz = l->get_pgsz(g, pd, pd_idx); 841 attrs->pgsz = l->get_pgsz(g, l, pd, pd_idx);
842 842
843 if (attrs->pgsz >= gmmu_nr_page_sizes) 843 if (attrs->pgsz >= gmmu_nr_page_sizes)
844 return -EINVAL; 844 return -EINVAL;
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 3635bfc2..0b383a83 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -287,6 +287,7 @@ static void update_gmmu_pte_locked(struct vm_gk20a *vm,
287} 287}
288 288
289enum gmmu_pgsz_gk20a gk20a_get_pde_pgsz(struct gk20a *g, 289enum gmmu_pgsz_gk20a gk20a_get_pde_pgsz(struct gk20a *g,
290 const struct gk20a_mmu_level *l,
290 struct nvgpu_gmmu_pd *pd, u32 pd_idx) 291 struct nvgpu_gmmu_pd *pd, u32 pd_idx)
291{ 292{
292 /* 293 /*
@@ -296,6 +297,7 @@ enum gmmu_pgsz_gk20a gk20a_get_pde_pgsz(struct gk20a *g,
296} 297}
297 298
298enum gmmu_pgsz_gk20a gk20a_get_pte_pgsz(struct gk20a *g, 299enum gmmu_pgsz_gk20a gk20a_get_pte_pgsz(struct gk20a *g,
300 const struct gk20a_mmu_level *l,
299 struct nvgpu_gmmu_pd *pd, u32 pd_idx) 301 struct nvgpu_gmmu_pd *pd, u32 pd_idx)
300{ 302{
301 /* 303 /*
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index 2478ee1f..ee0c2a07 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -184,7 +184,9 @@ extern const struct gk20a_mmu_level gk20a_mm_levels_64k[];
184extern const struct gk20a_mmu_level gk20a_mm_levels_128k[]; 184extern const struct gk20a_mmu_level gk20a_mm_levels_128k[];
185 185
186enum gmmu_pgsz_gk20a gk20a_get_pde_pgsz(struct gk20a *g, 186enum gmmu_pgsz_gk20a gk20a_get_pde_pgsz(struct gk20a *g,
187 const struct gk20a_mmu_level *l,
187 struct nvgpu_gmmu_pd *pd, u32 pd_idx); 188 struct nvgpu_gmmu_pd *pd, u32 pd_idx);
188enum gmmu_pgsz_gk20a gk20a_get_pte_pgsz(struct gk20a *g, 189enum gmmu_pgsz_gk20a gk20a_get_pte_pgsz(struct gk20a *g,
190 const struct gk20a_mmu_level *l,
189 struct nvgpu_gmmu_pd *pd, u32 pd_idx); 191 struct nvgpu_gmmu_pd *pd, u32 pd_idx);
190#endif /* MM_GK20A_H */ 192#endif /* MM_GK20A_H */
diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
index bb52aeb0..8cefbd3e 100644
--- a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
@@ -328,9 +328,11 @@ static void update_gmmu_pte_locked(struct vm_gk20a *vm,
328 * big pages or small pages. 328 * big pages or small pages.
329 */ 329 */
330static enum gmmu_pgsz_gk20a gp10b_get_pde0_pgsz(struct gk20a *g, 330static enum gmmu_pgsz_gk20a gp10b_get_pde0_pgsz(struct gk20a *g,
331 const struct gk20a_mmu_level *l,
331 struct nvgpu_gmmu_pd *pd, u32 pd_idx) 332 struct nvgpu_gmmu_pd *pd, u32 pd_idx)
332{ 333{
333 u32 pde_base = pd->mem_offs / sizeof(u32); 334 u32 pde_base = pd->mem_offs / sizeof(u32);
335 u32 pde_offset = pde_base + pd_offset_from_index(l, pd_idx);
334 u32 pde_v[GP10B_PDE0_ENTRY_SIZE >> 2]; 336 u32 pde_v[GP10B_PDE0_ENTRY_SIZE >> 2];
335 u32 i; 337 u32 i;
336 enum gmmu_pgsz_gk20a pgsz = gmmu_nr_page_sizes; 338 enum gmmu_pgsz_gk20a pgsz = gmmu_nr_page_sizes;
@@ -340,18 +342,17 @@ static enum gmmu_pgsz_gk20a gp10b_get_pde0_pgsz(struct gk20a *g,
340 342
341 nvgpu_mem_begin(g, pd->mem); 343 nvgpu_mem_begin(g, pd->mem);
342 for (i = 0; i < GP10B_PDE0_ENTRY_SIZE >> 2; i++) 344 for (i = 0; i < GP10B_PDE0_ENTRY_SIZE >> 2; i++)
343 pde_v[i] = nvgpu_mem_rd32(g, pd->mem, pde_base + i); 345 pde_v[i] = nvgpu_mem_rd32(g, pd->mem, pde_offset + i);
344 nvgpu_mem_end(g, pd->mem); 346 nvgpu_mem_end(g, pd->mem);
345 347
346 /* 348 /*
347 * Check if the aperture AND address are set 349 * Check if the aperture AND address are set
348 */ 350 */
349 if (pde_v[2] & (gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f() || 351 if (pde_v[2] & (gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f() |
350 gmmu_new_dual_pde_aperture_small_video_memory_f())) { 352 gmmu_new_dual_pde_aperture_small_video_memory_f())) {
351 u64 addr = ((u64) (pde_v[2] & 353 u64 addr = (((u64) pde_v[3] << 32) | (u64) (pde_v[2] &
352 gmmu_new_dual_pde_address_small_sys_f(~0)) << 354 gmmu_new_dual_pde_address_small_sys_f(~0))) <<
353 gmmu_new_dual_pde_address_shift_v()) | 355 gmmu_new_dual_pde_address_shift_v();
354 ((u64) pde_v[3] << 32);
355 356
356 if (addr) 357 if (addr)
357 pgsz = gmmu_page_size_small; 358 pgsz = gmmu_page_size_small;
@@ -359,10 +360,10 @@ static enum gmmu_pgsz_gk20a gp10b_get_pde0_pgsz(struct gk20a *g,
359 360
360 if (pde_v[0] & (gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f() | 361 if (pde_v[0] & (gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f() |
361 gmmu_new_dual_pde_aperture_big_video_memory_f())) { 362 gmmu_new_dual_pde_aperture_big_video_memory_f())) {
362 u64 addr = ((u64) (pde_v[0] & 363 u64 addr = (((u64) pde_v[1] << 32) | (u64) (pde_v[0] &
363 gmmu_new_dual_pde_address_big_sys_f(~0)) << 364 gmmu_new_dual_pde_address_big_sys_f(~0))) <<
364 gmmu_new_dual_pde_address_big_shift_v()) | 365 gmmu_new_dual_pde_address_big_shift_v();
365 ((u64) pde_v[1] << 32); 366
366 if (addr) { 367 if (addr) {
367 /* 368 /*
368 * If small is set that means that somehow MM allowed 369 * If small is set that means that somehow MM allowed
@@ -374,8 +375,8 @@ static enum gmmu_pgsz_gk20a gp10b_get_pde0_pgsz(struct gk20a *g,
374 "both small and big apertures enabled"); 375 "both small and big apertures enabled");
375 return gmmu_nr_page_sizes; 376 return gmmu_nr_page_sizes;
376 } 377 }
378 pgsz = gmmu_page_size_big;
377 } 379 }
378 pgsz = gmmu_page_size_big;
379 } 380 }
380 381
381 return pgsz; 382 return pgsz;
diff --git a/drivers/gpu/nvgpu/include/nvgpu/gmmu.h b/drivers/gpu/nvgpu/include/nvgpu/gmmu.h
index ca07e359..ade94df9 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/gmmu.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/gmmu.h
@@ -204,6 +204,7 @@ struct gk20a_mmu_level {
204 * Get pde page size 204 * Get pde page size
205 */ 205 */
206 enum gmmu_pgsz_gk20a (*get_pgsz)(struct gk20a *g, 206 enum gmmu_pgsz_gk20a (*get_pgsz)(struct gk20a *g,
207 const struct gk20a_mmu_level *l,
207 struct nvgpu_gmmu_pd *pd, u32 pd_idx); 208 struct nvgpu_gmmu_pd *pd, u32 pd_idx);
208}; 209};
209 210