@@ -862,6 +862,76 @@ static int aie2_query_resource_info(struct amdxdna_client *client,
862862 return 0 ;
863863}
864864
865+ static int aie2_fill_hwctx_map (struct amdxdna_hwctx * hwctx , void * arg )
866+ {
867+ struct amdxdna_dev * xdna = hwctx -> client -> xdna ;
868+ u32 * map = arg ;
869+
870+ if (hwctx -> fw_ctx_id >= xdna -> dev_handle -> priv -> hwctx_limit ) {
871+ XDNA_ERR (xdna , "Invalid fw ctx id %d/%d " , hwctx -> fw_ctx_id ,
872+ xdna -> dev_handle -> priv -> hwctx_limit );
873+ return - EINVAL ;
874+ }
875+
876+ map [hwctx -> fw_ctx_id ] = hwctx -> id ;
877+ return 0 ;
878+ }
879+
880+ static int aie2_get_telemetry (struct amdxdna_client * client ,
881+ struct amdxdna_drm_get_info * args )
882+ {
883+ struct amdxdna_drm_query_telemetry_header * header __free (kfree ) = NULL ;
884+ u32 telemetry_data_sz , header_sz , elem_num ;
885+ struct amdxdna_dev * xdna = client -> xdna ;
886+ struct amdxdna_client * tmp_client ;
887+ int ret ;
888+
889+ elem_num = xdna -> dev_handle -> priv -> hwctx_limit ;
890+ header_sz = struct_size (header , map , elem_num );
891+ if (args -> buffer_size <= header_sz ) {
892+ XDNA_ERR (xdna , "Invalid buffer size" );
893+ return - EINVAL ;
894+ }
895+
896+ telemetry_data_sz = args -> buffer_size - header_sz ;
897+ if (telemetry_data_sz > SZ_4M ) {
898+ XDNA_ERR (xdna , "Buffer size is too big, %d" , telemetry_data_sz );
899+ return - EINVAL ;
900+ }
901+
902+ header = kzalloc (header_sz , GFP_KERNEL );
903+ if (!header )
904+ return - ENOMEM ;
905+
906+ if (copy_from_user (header , u64_to_user_ptr (args -> buffer ), sizeof (* header ))) {
907+ XDNA_ERR (xdna , "Failed to copy telemetry header from user" );
908+ return - EFAULT ;
909+ }
910+
911+ header -> map_num_elements = elem_num ;
912+ list_for_each_entry (tmp_client , & xdna -> client_list , node ) {
913+ ret = amdxdna_hwctx_walk (tmp_client , & header -> map ,
914+ aie2_fill_hwctx_map );
915+ if (ret )
916+ return ret ;
917+ }
918+
919+ ret = aie2_query_telemetry (xdna -> dev_handle ,
920+ u64_to_user_ptr (args -> buffer + header_sz ),
921+ telemetry_data_sz , header );
922+ if (ret ) {
923+ XDNA_ERR (xdna , "Query telemetry failed ret %d" , ret );
924+ return ret ;
925+ }
926+
927+ if (copy_to_user (u64_to_user_ptr (args -> buffer ), header , header_sz )) {
928+ XDNA_ERR (xdna , "Copy header failed" );
929+ return - EFAULT ;
930+ }
931+
932+ return 0 ;
933+ }
934+
865935static int aie2_get_info (struct amdxdna_client * client , struct amdxdna_drm_get_info * args )
866936{
867937 struct amdxdna_dev * xdna = client -> xdna ;
@@ -896,6 +966,9 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i
896966 case DRM_AMDXDNA_GET_POWER_MODE :
897967 ret = aie2_get_power_mode (client , args );
898968 break ;
969+ case DRM_AMDXDNA_QUERY_TELEMETRY :
970+ ret = aie2_get_telemetry (client , args );
971+ break ;
899972 case DRM_AMDXDNA_QUERY_RESOURCE_INFO :
900973 ret = aie2_query_resource_info (client , args );
901974 break ;
0 commit comments