Loading drivers/gpu/msm/kgsl_sharedmem.c +32 −8 Original line number Original line Diff line number Diff line Loading @@ -482,7 +482,7 @@ static void kgsl_page_alloc_unmap_kernel(struct kgsl_memdesc *memdesc) mutex_unlock(&kernel_map_global_lock); mutex_unlock(&kernel_map_global_lock); } } static int kgsl_lock_sgt(struct sg_table *sgt) static int kgsl_lock_sgt(struct sg_table *sgt, uint64_t size) { { struct scatterlist *sg; struct scatterlist *sg; int dest_perms = PERM_READ | PERM_WRITE; int dest_perms = PERM_READ | PERM_WRITE; Loading @@ -492,12 +492,26 @@ static int kgsl_lock_sgt(struct sg_table *sgt) int i; int i; ret = hyp_assign_table(sgt, &source_vm, 1, &dest_vm, &dest_perms, 1); ret = hyp_assign_table(sgt, &source_vm, 1, &dest_vm, &dest_perms, 1); if (!ret) { if (ret) { /* * If returned error code is EADDRNOTAVAIL, then this * memory may no longer be in a usable state as security * state of the pages is unknown after this failure. This * memory can neither be added back to the pool nor buddy * system. */ if (ret == -EADDRNOTAVAIL) pr_err("Failure to lock secure GPU memory 0x%llx bytes will not be recoverable\n", size); return ret; } /* Set private bit for each sg to indicate that its secured */ /* Set private bit for each sg to indicate that its secured */ for_each_sg(sgt->sgl, sg, sgt->nents, i) for_each_sg(sgt->sgl, sg, sgt->nents, i) SetPagePrivate(sg_page(sg)); SetPagePrivate(sg_page(sg)); } return ret; return 0; } } static int kgsl_unlock_sgt(struct sg_table *sgt) static int kgsl_unlock_sgt(struct sg_table *sgt) Loading Loading @@ -961,11 +975,18 @@ kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc, goto done; goto done; } } ret = kgsl_lock_sgt(memdesc->sgt); ret = kgsl_lock_sgt(memdesc->sgt, memdesc->size); if (ret) { if (ret) { sg_free_table(memdesc->sgt); sg_free_table(memdesc->sgt); kfree(memdesc->sgt); kfree(memdesc->sgt); memdesc->sgt = NULL; memdesc->sgt = NULL; if (ret == -EADDRNOTAVAIL) { kgsl_free(memdesc->pages); memset(memdesc, 0, sizeof(*memdesc)); return ret; } goto done; goto done; } } Loading Loading @@ -1068,8 +1089,11 @@ struct page *kgsl_alloc_secure_page(void) sg_init_table(&sgl, 1); sg_init_table(&sgl, 1); sg_set_page(&sgl, page, PAGE_SIZE, 0); sg_set_page(&sgl, page, PAGE_SIZE, 0); status = kgsl_lock_sgt(&sgt); status = kgsl_lock_sgt(&sgt, PAGE_SIZE); if (status) { if (status) { if (status == -EADDRNOTAVAIL) return NULL; __free_page(page); __free_page(page); return NULL; return NULL; } } Loading Loading
drivers/gpu/msm/kgsl_sharedmem.c +32 −8 Original line number Original line Diff line number Diff line Loading @@ -482,7 +482,7 @@ static void kgsl_page_alloc_unmap_kernel(struct kgsl_memdesc *memdesc) mutex_unlock(&kernel_map_global_lock); mutex_unlock(&kernel_map_global_lock); } } static int kgsl_lock_sgt(struct sg_table *sgt) static int kgsl_lock_sgt(struct sg_table *sgt, uint64_t size) { { struct scatterlist *sg; struct scatterlist *sg; int dest_perms = PERM_READ | PERM_WRITE; int dest_perms = PERM_READ | PERM_WRITE; Loading @@ -492,12 +492,26 @@ static int kgsl_lock_sgt(struct sg_table *sgt) int i; int i; ret = hyp_assign_table(sgt, &source_vm, 1, &dest_vm, &dest_perms, 1); ret = hyp_assign_table(sgt, &source_vm, 1, &dest_vm, &dest_perms, 1); if (!ret) { if (ret) { /* * If returned error code is EADDRNOTAVAIL, then this * memory may no longer be in a usable state as security * state of the pages is unknown after this failure. This * memory can neither be added back to the pool nor buddy * system. */ if (ret == -EADDRNOTAVAIL) pr_err("Failure to lock secure GPU memory 0x%llx bytes will not be recoverable\n", size); return ret; } /* Set private bit for each sg to indicate that its secured */ /* Set private bit for each sg to indicate that its secured */ for_each_sg(sgt->sgl, sg, sgt->nents, i) for_each_sg(sgt->sgl, sg, sgt->nents, i) SetPagePrivate(sg_page(sg)); SetPagePrivate(sg_page(sg)); } return ret; return 0; } } static int kgsl_unlock_sgt(struct sg_table *sgt) static int kgsl_unlock_sgt(struct sg_table *sgt) Loading Loading @@ -961,11 +975,18 @@ kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc, goto done; goto done; } } ret = kgsl_lock_sgt(memdesc->sgt); ret = kgsl_lock_sgt(memdesc->sgt, memdesc->size); if (ret) { if (ret) { sg_free_table(memdesc->sgt); sg_free_table(memdesc->sgt); kfree(memdesc->sgt); kfree(memdesc->sgt); memdesc->sgt = NULL; memdesc->sgt = NULL; if (ret == -EADDRNOTAVAIL) { kgsl_free(memdesc->pages); memset(memdesc, 0, sizeof(*memdesc)); return ret; } goto done; goto done; } } Loading Loading @@ -1068,8 +1089,11 @@ struct page *kgsl_alloc_secure_page(void) sg_init_table(&sgl, 1); sg_init_table(&sgl, 1); sg_set_page(&sgl, page, PAGE_SIZE, 0); sg_set_page(&sgl, page, PAGE_SIZE, 0); status = kgsl_lock_sgt(&sgt); status = kgsl_lock_sgt(&sgt, PAGE_SIZE); if (status) { if (status) { if (status == -EADDRNOTAVAIL) return NULL; __free_page(page); __free_page(page); return NULL; return NULL; } } Loading