diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index a00c21b6..aaadd186 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | |||
@@ -927,6 +927,7 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g, | |||
927 | 927 | ||
928 | u32 clk_domains = 0; | 928 | u32 clk_domains = 0; |
929 | u32 num_domains; | 929 | u32 num_domains; |
930 | u32 num_entries; | ||
930 | u32 i; | 931 | u32 i; |
931 | int bit; | 932 | int bit; |
932 | int err; | 933 | int err; |
@@ -936,10 +937,10 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g, | |||
936 | if (!session) | 937 | if (!session) |
937 | return -EINVAL; | 938 | return -EINVAL; |
938 | 939 | ||
939 | if (!args->flags) { | 940 | clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); |
940 | clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); | 941 | num_domains = hweight_long(clk_domains); |
941 | num_domains = hweight_long(clk_domains); | ||
942 | 942 | ||
943 | if (!args->flags) { | ||
943 | if (!args->num_entries) { | 944 | if (!args->num_entries) { |
944 | args->num_entries = num_domains; | 945 | args->num_entries = num_domains; |
945 | return 0; | 946 | return 0; |
@@ -949,18 +950,21 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g, | |||
949 | return -EINVAL; | 950 | return -EINVAL; |
950 | 951 | ||
951 | args->num_entries = 0; | 952 | args->num_entries = 0; |
953 | num_entries = num_domains; | ||
952 | 954 | ||
953 | } else { | 955 | } else { |
954 | if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) | 956 | if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) |
955 | return -EINVAL; | 957 | return -EINVAL; |
956 | 958 | ||
957 | num_domains = args->num_entries; | 959 | num_entries = args->num_entries; |
960 | if (num_entries > num_domains) | ||
961 | return -EINVAL; | ||
958 | } | 962 | } |
959 | 963 | ||
960 | entry = (struct nvgpu_gpu_clk_range __user *) | 964 | entry = (struct nvgpu_gpu_clk_range __user *) |
961 | (uintptr_t)args->clk_range_entries; | 965 | (uintptr_t)args->clk_range_entries; |
962 | 966 | ||
963 | for (i = 0; i < num_domains; i++, entry++) { | 967 | for (i = 0; i < num_entries; i++, entry++) { |
964 | 968 | ||
965 | if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { | 969 | if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { |
966 | if (copy_from_user(&clk_range, (void __user *)entry, | 970 | if (copy_from_user(&clk_range, (void __user *)entry, |
@@ -984,7 +988,7 @@ static int nvgpu_gpu_clk_get_range(struct gk20a *g, | |||
984 | return -EFAULT; | 988 | return -EFAULT; |
985 | } | 989 | } |
986 | 990 | ||
987 | args->num_entries = num_domains; | 991 | args->num_entries = num_entries; |
988 | 992 | ||
989 | return 0; | 993 | return 0; |
990 | } | 994 | } |
@@ -1051,6 +1055,7 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1051 | struct nvgpu_clk_session *session = priv->clk_session; | 1055 | struct nvgpu_clk_session *session = priv->clk_session; |
1052 | u32 clk_domains = 0; | 1056 | u32 clk_domains = 0; |
1053 | u32 num_domains; | 1057 | u32 num_domains; |
1058 | u32 num_entries; | ||
1054 | u32 i; | 1059 | u32 i; |
1055 | int err; | 1060 | int err; |
1056 | int bit; | 1061 | int bit; |
@@ -1060,10 +1065,10 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1060 | if (!session) | 1065 | if (!session) |
1061 | return -EINVAL; | 1066 | return -EINVAL; |
1062 | 1067 | ||
1063 | if (!args->flags) { | 1068 | clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); |
1064 | clk_domains = nvgpu_clk_arb_get_arbiter_clk_domains(g); | 1069 | num_domains = hweight_long(clk_domains); |
1065 | num_domains = hweight_long(clk_domains); | ||
1066 | 1070 | ||
1071 | if (!args->flags) { | ||
1067 | if (!args->num_entries) { | 1072 | if (!args->num_entries) { |
1068 | args->num_entries = num_domains; | 1073 | args->num_entries = num_domains; |
1069 | return 0; | 1074 | return 0; |
@@ -1073,18 +1078,21 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1073 | return -EINVAL; | 1078 | return -EINVAL; |
1074 | 1079 | ||
1075 | args->num_entries = 0; | 1080 | args->num_entries = 0; |
1081 | num_entries = num_domains; | ||
1076 | 1082 | ||
1077 | } else { | 1083 | } else { |
1078 | if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) | 1084 | if (args->flags != NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) |
1079 | return -EINVAL; | 1085 | return -EINVAL; |
1080 | 1086 | ||
1081 | num_domains = args->num_entries; | 1087 | num_entries = args->num_entries; |
1088 | if (num_entries > num_domains * 3) | ||
1089 | return -EINVAL; | ||
1082 | } | 1090 | } |
1083 | 1091 | ||
1084 | entry = (struct nvgpu_gpu_clk_info __user *) | 1092 | entry = (struct nvgpu_gpu_clk_info __user *) |
1085 | (uintptr_t)args->clk_info_entries; | 1093 | (uintptr_t)args->clk_info_entries; |
1086 | 1094 | ||
1087 | for (i = 0; i < num_domains; i++, entry++) { | 1095 | for (i = 0; i < num_entries; i++, entry++) { |
1088 | 1096 | ||
1089 | if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { | 1097 | if (args->flags == NVGPU_GPU_CLK_FLAG_SPECIFIC_DOMAINS) { |
1090 | if (copy_from_user(&clk_info, (void __user *)entry, | 1098 | if (copy_from_user(&clk_info, (void __user *)entry, |
@@ -1125,7 +1133,7 @@ static int nvgpu_gpu_clk_get_info(struct gk20a *g, | |||
1125 | return -EFAULT; | 1133 | return -EFAULT; |
1126 | } | 1134 | } |
1127 | 1135 | ||
1128 | args->num_entries = num_domains; | 1136 | args->num_entries = num_entries; |
1129 | 1137 | ||
1130 | return 0; | 1138 | return 0; |
1131 | } | 1139 | } |