diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-06-23 18:28:00 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-07-03 20:59:12 -0400 |
commit | 63714e7cc158d0574947c2171a81988ffece2a2a (patch) | |
tree | 982f88d7ab69376552506c70651a5e1975161ad3 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |
parent | 4cc1457703462f3743c05a866690d1748e7bd8e8 (diff) |
gpu: nvgpu: Implement priv pages
Implement support for privileged pages. Use them for kernel allocated buffers.
Change-Id: I720fc441008077b8e2ed218a7a685b8aab2258f0
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/761919
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index f3512f90..112e218a 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -101,7 +101,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
101 | u8 kind_v, u32 ctag_offset, bool cacheable, | 101 | u8 kind_v, u32 ctag_offset, bool cacheable, |
102 | bool umapped_pte, int rw_flag, | 102 | bool umapped_pte, int rw_flag, |
103 | bool sparse, | 103 | bool sparse, |
104 | u32 flags); | 104 | bool priv); |
105 | static int __must_check gk20a_init_system_vm(struct mm_gk20a *mm); | 105 | static int __must_check gk20a_init_system_vm(struct mm_gk20a *mm); |
106 | static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); | 106 | static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); |
107 | static int __must_check gk20a_init_hwpm(struct mm_gk20a *mm); | 107 | static int __must_check gk20a_init_hwpm(struct mm_gk20a *mm); |
@@ -1168,6 +1168,7 @@ u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm, | |||
1168 | int rw_flag, | 1168 | int rw_flag, |
1169 | bool clear_ctags, | 1169 | bool clear_ctags, |
1170 | bool sparse, | 1170 | bool sparse, |
1171 | bool priv, | ||
1171 | struct vm_gk20a_mapping_batch *batch) | 1172 | struct vm_gk20a_mapping_batch *batch) |
1172 | { | 1173 | { |
1173 | int err = 0; | 1174 | int err = 0; |
@@ -1208,7 +1209,7 @@ u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm, | |||
1208 | NVGPU_AS_MAP_BUFFER_FLAGS_UNMAPPED_PTE, | 1209 | NVGPU_AS_MAP_BUFFER_FLAGS_UNMAPPED_PTE, |
1209 | rw_flag, | 1210 | rw_flag, |
1210 | sparse, | 1211 | sparse, |
1211 | flags); | 1212 | priv); |
1212 | if (err) { | 1213 | if (err) { |
1213 | gk20a_err(d, "failed to update ptes on map"); | 1214 | gk20a_err(d, "failed to update ptes on map"); |
1214 | goto fail_validate; | 1215 | goto fail_validate; |
@@ -1559,6 +1560,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm, | |||
1559 | flags, rw_flag, | 1560 | flags, rw_flag, |
1560 | clear_ctags, | 1561 | clear_ctags, |
1561 | false, | 1562 | false, |
1563 | false, | ||
1562 | batch); | 1564 | batch); |
1563 | if (!map_offset) | 1565 | if (!map_offset) |
1564 | goto clean_up; | 1566 | goto clean_up; |
@@ -1779,6 +1781,7 @@ int gk20a_vm_map_compbits(struct vm_gk20a *vm, | |||
1779 | gk20a_mem_flag_read_only, | 1781 | gk20a_mem_flag_read_only, |
1780 | false, /* clear_ctags */ | 1782 | false, /* clear_ctags */ |
1781 | false, /* sparse */ | 1783 | false, /* sparse */ |
1784 | false, /* priv */ | ||
1782 | NULL); /* mapping_batch handle */ | 1785 | NULL); /* mapping_batch handle */ |
1783 | 1786 | ||
1784 | if (!mapped_buffer->ctag_map_win_addr) { | 1787 | if (!mapped_buffer->ctag_map_win_addr) { |
@@ -1802,7 +1805,8 @@ u64 gk20a_gmmu_map(struct vm_gk20a *vm, | |||
1802 | struct sg_table **sgt, | 1805 | struct sg_table **sgt, |
1803 | u64 size, | 1806 | u64 size, |
1804 | u32 flags, | 1807 | u32 flags, |
1805 | int rw_flag) | 1808 | int rw_flag, |
1809 | bool priv) | ||
1806 | { | 1810 | { |
1807 | struct gk20a *g = gk20a_from_vm(vm); | 1811 | struct gk20a *g = gk20a_from_vm(vm); |
1808 | u64 vaddr; | 1812 | u64 vaddr; |
@@ -1818,6 +1822,7 @@ u64 gk20a_gmmu_map(struct vm_gk20a *vm, | |||
1818 | flags, rw_flag, | 1822 | flags, rw_flag, |
1819 | false, /* clear_ctags */ | 1823 | false, /* clear_ctags */ |
1820 | false, /* sparse */ | 1824 | false, /* sparse */ |
1825 | priv, /* priv */ | ||
1821 | NULL); /* mapping_batch handle */ | 1826 | NULL); /* mapping_batch handle */ |
1822 | mutex_unlock(&vm->update_gmmu_lock); | 1827 | mutex_unlock(&vm->update_gmmu_lock); |
1823 | if (!vaddr) { | 1828 | if (!vaddr) { |
@@ -1932,7 +1937,8 @@ int gk20a_gmmu_alloc_map_attr(struct vm_gk20a *vm, | |||
1932 | if (err) | 1937 | if (err) |
1933 | return err; | 1938 | return err; |
1934 | 1939 | ||
1935 | mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0, gk20a_mem_flag_none); | 1940 | mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0, |
1941 | gk20a_mem_flag_none, false); | ||
1936 | if (!mem->gpu_va) { | 1942 | if (!mem->gpu_va) { |
1937 | err = -ENOMEM; | 1943 | err = -ENOMEM; |
1938 | goto fail_free; | 1944 | goto fail_free; |
@@ -2126,7 +2132,7 @@ static int update_gmmu_pde_locked(struct vm_gk20a *vm, | |||
2126 | u64 *iova, | 2132 | u64 *iova, |
2127 | u32 kind_v, u32 *ctag, | 2133 | u32 kind_v, u32 *ctag, |
2128 | bool cacheable, bool unammped_pte, | 2134 | bool cacheable, bool unammped_pte, |
2129 | int rw_flag, bool sparse, u32 flags) | 2135 | int rw_flag, bool sparse, bool priv) |
2130 | { | 2136 | { |
2131 | struct gk20a *g = gk20a_from_vm(vm); | 2137 | struct gk20a *g = gk20a_from_vm(vm); |
2132 | bool small_valid, big_valid; | 2138 | bool small_valid, big_valid; |
@@ -2176,7 +2182,7 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
2176 | u64 *iova, | 2182 | u64 *iova, |
2177 | u32 kind_v, u32 *ctag, | 2183 | u32 kind_v, u32 *ctag, |
2178 | bool cacheable, bool unmapped_pte, | 2184 | bool cacheable, bool unmapped_pte, |
2179 | int rw_flag, bool sparse, u32 flags) | 2185 | int rw_flag, bool sparse, bool priv) |
2180 | { | 2186 | { |
2181 | struct gk20a *g = gk20a_from_vm(vm); | 2187 | struct gk20a *g = gk20a_from_vm(vm); |
2182 | u32 ctag_granularity = g->ops.fb.compression_page_size(g); | 2188 | u32 ctag_granularity = g->ops.fb.compression_page_size(g); |
@@ -2193,6 +2199,9 @@ static int update_gmmu_pte_locked(struct vm_gk20a *vm, | |||
2193 | gmmu_pte_address_sys_f(*iova | 2199 | gmmu_pte_address_sys_f(*iova |
2194 | >> gmmu_pte_address_shift_v()); | 2200 | >> gmmu_pte_address_shift_v()); |
2195 | 2201 | ||
2202 | if (priv) | ||
2203 | pte_w[0] |= gmmu_pte_privilege_true_f(); | ||
2204 | |||
2196 | pte_w[1] = gmmu_pte_aperture_video_memory_f() | | 2205 | pte_w[1] = gmmu_pte_aperture_video_memory_f() | |
2197 | gmmu_pte_kind_f(kind_v) | | 2206 | gmmu_pte_kind_f(kind_v) | |
2198 | gmmu_pte_comptagline_f(*ctag / ctag_granularity); | 2207 | gmmu_pte_comptagline_f(*ctag / ctag_granularity); |
@@ -2270,7 +2279,7 @@ static int update_gmmu_level_locked(struct vm_gk20a *vm, | |||
2270 | int rw_flag, | 2279 | int rw_flag, |
2271 | bool sparse, | 2280 | bool sparse, |
2272 | int lvl, | 2281 | int lvl, |
2273 | u32 flags) | 2282 | bool priv) |
2274 | { | 2283 | { |
2275 | const struct gk20a_mmu_level *l = &vm->mmu_levels[lvl]; | 2284 | const struct gk20a_mmu_level *l = &vm->mmu_levels[lvl]; |
2276 | const struct gk20a_mmu_level *next_l = &vm->mmu_levels[lvl+1]; | 2285 | const struct gk20a_mmu_level *next_l = &vm->mmu_levels[lvl+1]; |
@@ -2318,7 +2327,7 @@ static int update_gmmu_level_locked(struct vm_gk20a *vm, | |||
2318 | err = l->update_entry(vm, pte, pde_i, pgsz_idx, | 2327 | err = l->update_entry(vm, pte, pde_i, pgsz_idx, |
2319 | sgl, offset, iova, | 2328 | sgl, offset, iova, |
2320 | kind_v, ctag, cacheable, unmapped_pte, | 2329 | kind_v, ctag, cacheable, unmapped_pte, |
2321 | rw_flag, sparse, flags); | 2330 | rw_flag, sparse, priv); |
2322 | if (err) | 2331 | if (err) |
2323 | return err; | 2332 | return err; |
2324 | 2333 | ||
@@ -2339,7 +2348,7 @@ static int update_gmmu_level_locked(struct vm_gk20a *vm, | |||
2339 | gpu_va, | 2348 | gpu_va, |
2340 | next, | 2349 | next, |
2341 | kind_v, ctag, cacheable, unmapped_pte, | 2350 | kind_v, ctag, cacheable, unmapped_pte, |
2342 | rw_flag, sparse, lvl+1, flags); | 2351 | rw_flag, sparse, lvl+1, priv); |
2343 | unmap_gmmu_pages(next_pte); | 2352 | unmap_gmmu_pages(next_pte); |
2344 | 2353 | ||
2345 | if (err) | 2354 | if (err) |
@@ -2364,7 +2373,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
2364 | bool cacheable, bool unmapped_pte, | 2373 | bool cacheable, bool unmapped_pte, |
2365 | int rw_flag, | 2374 | int rw_flag, |
2366 | bool sparse, | 2375 | bool sparse, |
2367 | u32 flags) | 2376 | bool priv) |
2368 | { | 2377 | { |
2369 | struct gk20a *g = gk20a_from_vm(vm); | 2378 | struct gk20a *g = gk20a_from_vm(vm); |
2370 | int ctag_granularity = g->ops.fb.compression_page_size(g); | 2379 | int ctag_granularity = g->ops.fb.compression_page_size(g); |
@@ -2377,7 +2386,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
2377 | 2386 | ||
2378 | gk20a_dbg(gpu_dbg_pte, "size_idx=%d, iova=%llx, buffer offset %lld, nents %d", | 2387 | gk20a_dbg(gpu_dbg_pte, "size_idx=%d, iova=%llx, buffer offset %lld, nents %d", |
2379 | pgsz_idx, | 2388 | pgsz_idx, |
2380 | sgt ? g->ops.mm.get_iova_addr(vm->mm->g, sgt->sgl, flags) | 2389 | sgt ? g->ops.mm.get_iova_addr(vm->mm->g, sgt->sgl, 0) |
2381 | : 0ULL, | 2390 | : 0ULL, |
2382 | buffer_offset, | 2391 | buffer_offset, |
2383 | sgt ? sgt->nents : 0); | 2392 | sgt ? sgt->nents : 0); |
@@ -2386,7 +2395,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
2386 | return -EINVAL; | 2395 | return -EINVAL; |
2387 | 2396 | ||
2388 | if (sgt) { | 2397 | if (sgt) { |
2389 | iova = g->ops.mm.get_iova_addr(vm->mm->g, sgt->sgl, flags); | 2398 | iova = g->ops.mm.get_iova_addr(vm->mm->g, sgt->sgl, 0); |
2390 | if (!vm->mm->bypass_smmu && iova) { | 2399 | if (!vm->mm->bypass_smmu && iova) { |
2391 | iova += space_to_skip; | 2400 | iova += space_to_skip; |
2392 | } else { | 2401 | } else { |
@@ -2422,7 +2431,7 @@ static int update_gmmu_ptes_locked(struct vm_gk20a *vm, | |||
2422 | &iova, | 2431 | &iova, |
2423 | gpu_va, gpu_end, | 2432 | gpu_va, gpu_end, |
2424 | kind_v, &ctag, | 2433 | kind_v, &ctag, |
2425 | cacheable, unmapped_pte, rw_flag, sparse, 0, flags); | 2434 | cacheable, unmapped_pte, rw_flag, sparse, 0, priv); |
2426 | unmap_gmmu_pages(&vm->pdb); | 2435 | unmap_gmmu_pages(&vm->pdb); |
2427 | 2436 | ||
2428 | smp_mb(); | 2437 | smp_mb(); |
@@ -2835,6 +2844,7 @@ int gk20a_vm_alloc_space(struct gk20a_as_share *as_share, | |||
2835 | gk20a_mem_flag_none, | 2844 | gk20a_mem_flag_none, |
2836 | false, | 2845 | false, |
2837 | true, | 2846 | true, |
2847 | false, | ||
2838 | NULL); | 2848 | NULL); |
2839 | if (!map_offset) { | 2849 | if (!map_offset) { |
2840 | mutex_unlock(&vm->update_gmmu_lock); | 2850 | mutex_unlock(&vm->update_gmmu_lock); |