Loading drivers/soc/qcom/secure_buffer.c +18 −14 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #define CREATE_TRACE_POINTS #include "trace_secure_buffer.h" DEFINE_MUTEX(secure_buffer_mutex); struct cp2_mem_chunks { Loading @@ -28,24 +31,12 @@ struct cp2_lock_req { u32 lock; } __attribute__ ((__packed__)); struct mem_prot_info { phys_addr_t addr; u64 size; }; #define MEM_PROT_ASSIGN_ID 0x16 #define MEM_PROTECT_LOCK_ID2 0x0A #define MEM_PROTECT_LOCK_ID2_FLAT 0x11 #define V2_CHUNK_SIZE SZ_1M #define FEATURE_ID_CP 12 struct dest_vm_and_perm_info { u32 vm; u32 perm; u64 ctx; u32 ctx_size; }; #define BATCH_MAX_SIZE SZ_2M #define BATCH_MAX_SECTIONS 32 Loading Loading @@ -228,9 +219,13 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) unsigned int entries_size; unsigned int batch_start = 0; unsigned int batches_processed; unsigned int i = 0; u64 total_delta; struct scatterlist *curr_sgl = table->sgl; struct scatterlist *next_sgl; int ret = 0; ktime_t batch_assign_start_ts; ktime_t first_assign_ts; struct mem_prot_info *sg_table_copy = kcalloc(BATCH_MAX_SECTIONS, sizeof(*sg_table_copy), GFP_KERNEL); Loading @@ -238,6 +233,7 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) if (!sg_table_copy) return -ENOMEM; first_assign_ts = ktime_get(); while (batch_start < table->nents) { batches_processed = get_batches_from_sgl(sg_table_copy, curr_sgl, &next_sgl); Loading @@ -248,8 +244,13 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) desc->args[0] = virt_to_phys(sg_table_copy); desc->args[1] = entries_size; trace_hyp_assign_batch_start(sg_table_copy, batches_processed); batch_assign_start_ts = ktime_get(); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, MEM_PROT_ASSIGN_ID), desc); trace_hyp_assign_batch_end(ret, ktime_us_delta(ktime_get(), batch_assign_start_ts)); i++; if (ret) { pr_info("%s: Failed to assign memory protection, ret = %d\n", __func__, ret); Loading @@ -263,7 +264,8 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) batch_start += batches_processed; } total_delta = ktime_us_delta(ktime_get(), first_assign_ts); trace_hyp_assign_end(total_delta, total_delta / i); kfree(sg_table_copy); return ret; } Loading @@ -288,7 +290,7 @@ static int __hyp_assign_table(struct sg_table *table, size_t dest_vm_copy_size; if (!table || !table->sgl || !source_vm_list || !source_nelems || !dest_vmids || !dest_perms || !dest_nelems) !dest_vmids || !dest_perms || !dest_nelems || !table->nents) return -EINVAL; /* Loading Loading @@ -333,6 +335,8 @@ static int __hyp_assign_table(struct sg_table *table, dmac_flush_range(dest_vm_copy, (void *)dest_vm_copy + dest_vm_copy_size); trace_hyp_assign_info(source_vm_list, source_nelems, dest_vmids, dest_perms, dest_nelems); ret = batched_hyp_assign(table, &desc); mutex_unlock(&secure_buffer_mutex); Loading drivers/soc/qcom/trace_secure_buffer.h 0 → 100644 +140 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019 The Linux Foundation. All rights reserved. */ #undef TRACE_SYSTEM #define TRACE_SYSTEM secure_buffer #if !defined(_TRACE_SECURE_BUFFER_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_SECURE_BUFFER_H #include <linux/types.h> #include <linux/tracepoint.h> #include <soc/qcom/secure_buffer.h> TRACE_EVENT(hyp_assign_info, TP_PROTO(u32 *source_vm_list, int source_nelems, int *dest_vmids, int *dest_perms, int dest_nelems), TP_ARGS(source_vm_list, source_nelems, dest_vmids, dest_perms, dest_nelems), TP_STRUCT__entry( __field(int, source_nelems) __field(int, dest_nelems) __dynamic_array(u32, source_vm_list, source_nelems) __dynamic_array(int, dest_vmids, dest_nelems) __dynamic_array(int, dest_perms, dest_nelems) ), TP_fast_assign( __entry->source_nelems = source_nelems; __entry->dest_nelems = dest_nelems; memcpy(__get_dynamic_array(source_vm_list), source_vm_list, source_nelems * sizeof(*source_vm_list)); memcpy(__get_dynamic_array(dest_vmids), dest_vmids, dest_nelems * sizeof(*dest_vmids)); memcpy(__get_dynamic_array(dest_perms), dest_perms, dest_nelems * sizeof(*dest_perms)); ), TP_printk("srcVMIDs: %s dstVMIDs: %s dstPerms: %s", __print_array(__get_dynamic_array(source_vm_list), __entry->source_nelems, sizeof(u32)), __print_array(__get_dynamic_array(dest_vmids), __entry->dest_nelems, sizeof(int)), __print_array(__get_dynamic_array(dest_perms), __entry->dest_nelems, sizeof(int)) ) ); TRACE_EVENT(hyp_assign_batch_start, TP_PROTO(struct mem_prot_info *info, int info_nelems), TP_ARGS(info, info_nelems), TP_STRUCT__entry( __field(int, info_nelems) __field(u64, batch_size) __dynamic_array(phys_addr_t, addrs, info_nelems) __dynamic_array(u64, sizes, info_nelems) ), TP_fast_assign( unsigned int i; phys_addr_t *addr_arr_ptr = __get_dynamic_array(addrs); u64 *sizes_arr_ptr = __get_dynamic_array(sizes); __entry->info_nelems = info_nelems; __entry->batch_size = 0; for (i = 0; i < info_nelems; i++) { addr_arr_ptr[i] = info[i].addr; sizes_arr_ptr[i] = info[i].size; __entry->batch_size += info[i].size; } ), TP_printk("num entries: %d batch size: %llu phys addrs: %s sizes: %s", __entry->info_nelems, __entry->batch_size, __print_array(__get_dynamic_array(addrs), __entry->info_nelems, sizeof(phys_addr_t)), __print_array(__get_dynamic_array(sizes), __entry->info_nelems, sizeof(u64)) ) ); TRACE_EVENT(hyp_assign_batch_end, TP_PROTO(int ret, u64 delta), TP_ARGS(ret, delta), TP_STRUCT__entry( __field(int, ret) __field(u64, delta) ), TP_fast_assign( __entry->ret = ret; __entry->delta = delta; ), TP_printk("ret: %d time delta: %lld us", __entry->ret, __entry->delta ) ); TRACE_EVENT(hyp_assign_end, TP_PROTO(u64 tot_delta, u64 avg_delta), TP_ARGS(tot_delta, avg_delta), TP_STRUCT__entry( __field(u64, tot_delta) __field(u64, avg_delta) ), TP_fast_assign( __entry->tot_delta = tot_delta; __entry->avg_delta = avg_delta; ), TP_printk("total time delta: %lld us avg batch delta: %lld us", __entry->tot_delta, __entry->avg_delta ) ); #endif /* _TRACE_SECURE_BUFFER_H */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH ../../drivers/soc/qcom/ #undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE trace_secure_buffer /* This part must be outside protection */ #include <trace/define_trace.h> include/soc/qcom/secure_buffer.h +12 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,18 @@ enum vmid { #define PERM_WRITE 0x2 #define PERM_EXEC 0x1 struct dest_vm_and_perm_info { u32 vm; u32 perm; u64 ctx; u32 ctx_size; }; struct mem_prot_info { phys_addr_t addr; u64 size; }; #ifdef CONFIG_QCOM_SECURE_BUFFER int msm_secure_table(struct sg_table *table); int msm_unsecure_table(struct sg_table *table); Loading Loading
drivers/soc/qcom/secure_buffer.c +18 −14 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #define CREATE_TRACE_POINTS #include "trace_secure_buffer.h" DEFINE_MUTEX(secure_buffer_mutex); struct cp2_mem_chunks { Loading @@ -28,24 +31,12 @@ struct cp2_lock_req { u32 lock; } __attribute__ ((__packed__)); struct mem_prot_info { phys_addr_t addr; u64 size; }; #define MEM_PROT_ASSIGN_ID 0x16 #define MEM_PROTECT_LOCK_ID2 0x0A #define MEM_PROTECT_LOCK_ID2_FLAT 0x11 #define V2_CHUNK_SIZE SZ_1M #define FEATURE_ID_CP 12 struct dest_vm_and_perm_info { u32 vm; u32 perm; u64 ctx; u32 ctx_size; }; #define BATCH_MAX_SIZE SZ_2M #define BATCH_MAX_SECTIONS 32 Loading Loading @@ -228,9 +219,13 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) unsigned int entries_size; unsigned int batch_start = 0; unsigned int batches_processed; unsigned int i = 0; u64 total_delta; struct scatterlist *curr_sgl = table->sgl; struct scatterlist *next_sgl; int ret = 0; ktime_t batch_assign_start_ts; ktime_t first_assign_ts; struct mem_prot_info *sg_table_copy = kcalloc(BATCH_MAX_SECTIONS, sizeof(*sg_table_copy), GFP_KERNEL); Loading @@ -238,6 +233,7 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) if (!sg_table_copy) return -ENOMEM; first_assign_ts = ktime_get(); while (batch_start < table->nents) { batches_processed = get_batches_from_sgl(sg_table_copy, curr_sgl, &next_sgl); Loading @@ -248,8 +244,13 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) desc->args[0] = virt_to_phys(sg_table_copy); desc->args[1] = entries_size; trace_hyp_assign_batch_start(sg_table_copy, batches_processed); batch_assign_start_ts = ktime_get(); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, MEM_PROT_ASSIGN_ID), desc); trace_hyp_assign_batch_end(ret, ktime_us_delta(ktime_get(), batch_assign_start_ts)); i++; if (ret) { pr_info("%s: Failed to assign memory protection, ret = %d\n", __func__, ret); Loading @@ -263,7 +264,8 @@ static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc) batch_start += batches_processed; } total_delta = ktime_us_delta(ktime_get(), first_assign_ts); trace_hyp_assign_end(total_delta, total_delta / i); kfree(sg_table_copy); return ret; } Loading @@ -288,7 +290,7 @@ static int __hyp_assign_table(struct sg_table *table, size_t dest_vm_copy_size; if (!table || !table->sgl || !source_vm_list || !source_nelems || !dest_vmids || !dest_perms || !dest_nelems) !dest_vmids || !dest_perms || !dest_nelems || !table->nents) return -EINVAL; /* Loading Loading @@ -333,6 +335,8 @@ static int __hyp_assign_table(struct sg_table *table, dmac_flush_range(dest_vm_copy, (void *)dest_vm_copy + dest_vm_copy_size); trace_hyp_assign_info(source_vm_list, source_nelems, dest_vmids, dest_perms, dest_nelems); ret = batched_hyp_assign(table, &desc); mutex_unlock(&secure_buffer_mutex); Loading
drivers/soc/qcom/trace_secure_buffer.h 0 → 100644 +140 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019 The Linux Foundation. All rights reserved. */ #undef TRACE_SYSTEM #define TRACE_SYSTEM secure_buffer #if !defined(_TRACE_SECURE_BUFFER_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_SECURE_BUFFER_H #include <linux/types.h> #include <linux/tracepoint.h> #include <soc/qcom/secure_buffer.h> TRACE_EVENT(hyp_assign_info, TP_PROTO(u32 *source_vm_list, int source_nelems, int *dest_vmids, int *dest_perms, int dest_nelems), TP_ARGS(source_vm_list, source_nelems, dest_vmids, dest_perms, dest_nelems), TP_STRUCT__entry( __field(int, source_nelems) __field(int, dest_nelems) __dynamic_array(u32, source_vm_list, source_nelems) __dynamic_array(int, dest_vmids, dest_nelems) __dynamic_array(int, dest_perms, dest_nelems) ), TP_fast_assign( __entry->source_nelems = source_nelems; __entry->dest_nelems = dest_nelems; memcpy(__get_dynamic_array(source_vm_list), source_vm_list, source_nelems * sizeof(*source_vm_list)); memcpy(__get_dynamic_array(dest_vmids), dest_vmids, dest_nelems * sizeof(*dest_vmids)); memcpy(__get_dynamic_array(dest_perms), dest_perms, dest_nelems * sizeof(*dest_perms)); ), TP_printk("srcVMIDs: %s dstVMIDs: %s dstPerms: %s", __print_array(__get_dynamic_array(source_vm_list), __entry->source_nelems, sizeof(u32)), __print_array(__get_dynamic_array(dest_vmids), __entry->dest_nelems, sizeof(int)), __print_array(__get_dynamic_array(dest_perms), __entry->dest_nelems, sizeof(int)) ) ); TRACE_EVENT(hyp_assign_batch_start, TP_PROTO(struct mem_prot_info *info, int info_nelems), TP_ARGS(info, info_nelems), TP_STRUCT__entry( __field(int, info_nelems) __field(u64, batch_size) __dynamic_array(phys_addr_t, addrs, info_nelems) __dynamic_array(u64, sizes, info_nelems) ), TP_fast_assign( unsigned int i; phys_addr_t *addr_arr_ptr = __get_dynamic_array(addrs); u64 *sizes_arr_ptr = __get_dynamic_array(sizes); __entry->info_nelems = info_nelems; __entry->batch_size = 0; for (i = 0; i < info_nelems; i++) { addr_arr_ptr[i] = info[i].addr; sizes_arr_ptr[i] = info[i].size; __entry->batch_size += info[i].size; } ), TP_printk("num entries: %d batch size: %llu phys addrs: %s sizes: %s", __entry->info_nelems, __entry->batch_size, __print_array(__get_dynamic_array(addrs), __entry->info_nelems, sizeof(phys_addr_t)), __print_array(__get_dynamic_array(sizes), __entry->info_nelems, sizeof(u64)) ) ); TRACE_EVENT(hyp_assign_batch_end, TP_PROTO(int ret, u64 delta), TP_ARGS(ret, delta), TP_STRUCT__entry( __field(int, ret) __field(u64, delta) ), TP_fast_assign( __entry->ret = ret; __entry->delta = delta; ), TP_printk("ret: %d time delta: %lld us", __entry->ret, __entry->delta ) ); TRACE_EVENT(hyp_assign_end, TP_PROTO(u64 tot_delta, u64 avg_delta), TP_ARGS(tot_delta, avg_delta), TP_STRUCT__entry( __field(u64, tot_delta) __field(u64, avg_delta) ), TP_fast_assign( __entry->tot_delta = tot_delta; __entry->avg_delta = avg_delta; ), TP_printk("total time delta: %lld us avg batch delta: %lld us", __entry->tot_delta, __entry->avg_delta ) ); #endif /* _TRACE_SECURE_BUFFER_H */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH ../../drivers/soc/qcom/ #undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE trace_secure_buffer /* This part must be outside protection */ #include <trace/define_trace.h>
include/soc/qcom/secure_buffer.h +12 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,18 @@ enum vmid { #define PERM_WRITE 0x2 #define PERM_EXEC 0x1 struct dest_vm_and_perm_info { u32 vm; u32 perm; u64 ctx; u32 ctx_size; }; struct mem_prot_info { phys_addr_t addr; u64 size; }; #ifdef CONFIG_QCOM_SECURE_BUFFER int msm_secure_table(struct sg_table *table); int msm_unsecure_table(struct sg_table *table); Loading