• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * drivers/auth_ctl/auth_ctrl.c
4  *
5  * Copyright (c) 2022 Huawei Device Co., Ltd.
6  *
7  */
8 #include <linux/sched.h>
9 #include <linux/list.h>
10 #include <linux/mutex.h>
11 #include <linux/stop_machine.h>
12 #include <linux/sched/auth_ctrl.h>
13 #include <linux/sched/rtg_auth.h>
14 #include <linux/sched/qos_ctrl.h>
15 #include <linux/sched/qos_auth.h>
16 #include <uapi/linux/sched/types.h>
17 
18 #include "auth_ctrl.h"
19 #include "qos_ctrl.h"
20 
21 typedef long (*qos_ctrl_func)(int abi, void __user *uarg);
22 
23 static long ctrl_qos_operation(int abi, void __user *uarg);
24 static long ctrl_qos_policy(int abi, void __user *uarg);
25 
26 #define QOS_LEVEL_SET_MAX 5
27 
28 static qos_ctrl_func g_func_array[QOS_CTRL_MAX_NR] = {
29 	NULL, /* reserved */
30 	ctrl_qos_operation,
31 	ctrl_qos_policy,
32 };
33 
34 static struct qos_policy_map qos_policy_array[QOS_POLICY_MAX_NR];
35 
remove_qos_tasks(struct auth_struct * auth)36 void remove_qos_tasks(struct auth_struct *auth)
37 {
38 	int i;
39 	struct qos_task_struct *tmp, *next;
40 	struct task_struct *p;
41 
42 	mutex_lock(&auth->mutex);
43 	for (i = QOS_POLICY_MIN_LEVEL; i < NR_QOS; ++i) {
44 		list_for_each_entry_safe(tmp, next, &auth->tasks[i], qos_list) {
45 			p = container_of(tmp, struct task_struct, qts);
46 			if (!list_empty(&tmp->qos_list)) {
47 				list_del_init(&tmp->qos_list);
48 				tmp->in_qos = NO_QOS;
49 				put_task_struct(p);
50 			}
51 		}
52 	}
53 	mutex_unlock(&auth->mutex);
54 }
55 
init_sched_attr(struct sched_attr * attr)56 static void init_sched_attr(struct sched_attr *attr)
57 {
58 	memset(attr, 0, sizeof(struct sched_attr));
59 }
60 
is_system(unsigned int uid)61 static inline bool is_system(unsigned int uid)
62 {
63 	return uid == SYSTEM_UID;
64 }
65 
66 /* This function must be called when p is valid. That means the p's refcount must exist */
sched_set_task_qos_attr(struct task_struct * p,int level,int status)67 static int sched_set_task_qos_attr(struct task_struct *p, int level, int status)
68 {
69 	struct qos_policy_item *item;
70 	struct qos_policy_map *policy_map;
71 	struct sched_attr attr;
72 
73 	read_lock(&qos_policy_array[status].lock);
74 	if (!qos_policy_array[status].initialized) {
75 		pr_err("[QOS_CTRL] dirty qos policy, pid=%d, uid=%d, status=%d\n",
76 		       p->pid, p->cred->uid.val, status);
77 		read_unlock(&qos_policy_array[status].lock);
78 		return -DIRTY_QOS_POLICY;
79 	}
80 
81 	policy_map = &qos_policy_array[status];
82 	item = &policy_map->levels[level];
83 
84 	init_sched_attr(&attr);
85 	attr.size			= sizeof(struct sched_attr);
86 	attr.sched_policy		= SCHED_NORMAL;
87 
88 	if (policy_map->policy_flag & QOS_FLAG_NICE)
89 		attr.sched_nice = item->nice;
90 
91 	if (policy_map->policy_flag & QOS_FLAG_LATENCY_NICE) {
92 		attr.sched_flags |= SCHED_FLAG_LATENCY_NICE;
93 		attr.sched_latency_nice = item->latency_nice;
94 	}
95 
96 	if ((policy_map->policy_flag & QOS_FLAG_RT) && item->rt_sched_priority) {
97 		attr.sched_policy = SCHED_FIFO;
98 		attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
99 		attr.sched_priority = item->rt_sched_priority;
100 	}
101 
102 	read_unlock(&qos_policy_array[status].lock);
103 
104 	if (unlikely(p->flags & PF_EXITING)) {
105 		pr_info("[QOS_CTRL] dying task, no need to set qos\n");
106 		return -THREAD_EXITING;
107 	}
108 
109 	return sched_setattr_nocheck(p, &attr);
110 }
111 
112 /*
113  * Switch qos mode when status changed.
114  * Lock auth before calling this function
115  */
qos_switch(struct auth_struct * auth,int target_status)116 void qos_switch(struct auth_struct *auth, int target_status)
117 {
118 	int i;
119 	int ret;
120 	struct task_struct *task;
121 	struct qos_task_struct *qts;
122 
123 	if (!auth) {
124 		pr_err("[QOS_CTRL] auth no exist, qos switch failed\n");
125 		return;
126 	}
127 
128 	lockdep_assert_held(&auth->mutex);
129 
130 	if (auth->status == target_status) {
131 		pr_info("[QOS_CTRL] same status, no need to switch qos\n");
132 		return;
133 	}
134 
135 	for (i = QOS_POLICY_MIN_LEVEL; i < NR_QOS; ++i) {
136 		list_for_each_entry(qts, &auth->tasks[i], qos_list) {
137 			task = container_of(qts, struct task_struct, qts);
138 			ret = sched_set_task_qos_attr(task, i, target_status);
139 			if (ret)
140 				pr_err("[QOS_CTRL] set qos attr failed, qos switch failed\n");
141 		}
142 	}
143 }
144 
qos_insert_task(struct task_struct * p,struct list_head * head,unsigned int level)145 static int qos_insert_task(struct task_struct *p, struct list_head *head, unsigned int level)
146 {
147 	struct qos_task_struct *qts = &p->qts;
148 
149 	if (qts->in_qos > NO_QOS) {
150 		pr_err("[QOS_CTRL] qos apply still active, no duplicate add\n");
151 		return -PID_DUPLICATE;
152 	}
153 
154 	if (likely(list_empty(&qts->qos_list))) {
155 		get_task_struct(p);
156 		list_add(&qts->qos_list, head);
157 		qts->in_qos = level;
158 	}
159 
160 	return 0;
161 }
162 
qos_remove_task(struct task_struct * p)163 static int qos_remove_task(struct task_struct *p)
164 {
165 	struct qos_task_struct *qts = (struct qos_task_struct *) &p->qts;
166 
167 	if (qts->in_qos == NO_QOS) {
168 		pr_err("[QOS_CTRL] task not in qos, no need to remove\n");
169 		return -PID_NOT_EXIST;
170 	}
171 
172 	if (likely(!list_empty(&qts->qos_list))) {
173 		list_del_init(&qts->qos_list);
174 		qts->in_qos = NO_QOS;
175 		put_task_struct(p);
176 	}
177 
178 	return 0;
179 }
180 
super_user(struct task_struct * p)181 static inline bool super_user(struct task_struct *p)
182 {
183 	return super_uid(task_uid(p).val);
184 }
185 
186 /*
187  * judge permission for changing tasks' qos
188  */
can_change_qos(struct task_struct * p,unsigned int qos_level)189 static bool can_change_qos(struct task_struct *p, unsigned int qos_level)
190 {
191 	struct auth_struct *auth;
192 	auth = get_authority(p);
193 	/* just system & root user can set(be setted) high qos level */
194 	if (!auth || (auth && !super_user(p) && qos_level > QOS_LEVEL_SET_MAX)) {
195 		pr_err("[QOS_CTRL] %d have no permission to change qos\n", p->pid);
196 		return false;
197 	}
198 
199 	return true;
200 }
201 
qos_apply(struct qos_ctrl_data * data)202 int qos_apply(struct qos_ctrl_data *data)
203 {
204 	unsigned int level = data->level;
205 	struct auth_struct *auth;
206 	struct task_struct *p;
207 	struct qos_task_struct *qts;
208 	int pid = data->pid;
209 	int ret;
210 
211 	if (level >= NR_QOS || level == NO_QOS) {
212 		pr_err("[QOS_CTRL] no this qos level, qos apply failed\n");
213 		ret = -ARG_INVALID;
214 		goto out;
215 	}
216 
217 	p = find_get_task_by_vpid((pid_t)pid);
218 	if (unlikely(!p)) {
219 		pr_err("[QOS_CTRL] no matching task for this pid, qos apply failed\n");
220 		ret = -ESRCH;
221 		goto out;
222 	}
223 
224 	if (unlikely(p->flags & PF_EXITING)) {
225 		pr_info("[QOS_CTRL] dying task, no need to set qos\n");
226 		ret = -THREAD_EXITING;
227 		goto out_put_task;
228 	}
229 
230 	if (!can_change_qos(current, level)) {
231 		pr_err("[QOS_CTRL] QOS apply not permit\n");
232 		ret = -ARG_INVALID;
233 		goto out_put_task;
234 	}
235 
236 	auth = get_authority(p);
237 	if (!auth) {
238 		pr_err("[QOS_CTRL] no auth data for pid=%d(%s), qos apply failed\n",
239 		       p->tgid, p->comm);
240 		ret = -PID_NOT_FOUND;
241 		goto out_put_task;
242 	}
243 
244 	mutex_lock(&auth->mutex);
245 	if (auth->status == AUTH_STATUS_DEAD) {
246 		pr_err("[QOS_CTRL] this auth data has been deleted\n");
247 		ret = -INVALID_AUTH;
248 		goto out_unlock;
249 	}
250 
251 	if (auth->num[level] >= QOS_NUM_MAX) {
252 		pr_err("[QOS_CTRL] qos num exceeds limit, cached only\n");
253 		ret = -QOS_THREAD_NUM_EXCEED_LIMIT;
254 		goto out_unlock;
255 	}
256 
257 	qts = (struct qos_task_struct *) &p->qts;
258 
259 	if (rt_task(p) && qts->in_qos == NO_QOS) {
260 		pr_err("[QOS_CTRL] can not apply qos for native rt task\n");
261 		ret = -ALREADY_RT_TASK;
262 		goto out_unlock;
263 	}
264 
265 	/* effective qos must in range [NO_QOS, NR_QOS) */
266 	if (qts->in_qos != NO_QOS) {
267 		if (qts->in_qos == level) {
268 			ret = 0;
269 			goto out_unlock;
270 		}
271 
272 		--auth->num[qts->in_qos];
273 		qos_remove_task(p);
274 	}
275 
276 	ret = qos_insert_task(p, &auth->tasks[level], level);
277 	if (ret < 0) {
278 		pr_err("[QOS_CTRL] insert task to qos list %d failed\n", level);
279 		goto out_unlock;
280 	}
281 
282 	++auth->num[level];
283 
284 	ret = sched_set_task_qos_attr(p, level, auth->status);
285 	if (ret) {
286 		pr_err("[QOS_CTRL] set qos_level %d for thread %d on status %d failed\n",
287 		       level, p->pid, auth->status);
288 		--auth->num[level];
289 		qos_remove_task(p);
290 	}
291 
292 out_unlock:
293 	mutex_unlock(&auth->mutex);
294 	put_auth_struct(auth);
295 out_put_task:
296 	put_task_struct(p);
297 out:
298 	return ret;
299 }
300 
qos_leave(struct qos_ctrl_data * data)301 int qos_leave(struct qos_ctrl_data *data)
302 {
303 	unsigned int level;
304 	struct auth_struct *auth;
305 	struct task_struct *p;
306 	struct qos_task_struct *qts;
307 	int pid = data->pid;
308 	int ret;
309 
310 	p = find_get_task_by_vpid((pid_t)pid);
311 	if (!p) {
312 		pr_err("[QOS_CTRL] no matching task for this pid, qos apply failed\n");
313 		ret = -ESRCH;
314 		goto out;
315 	}
316 
317 	if (unlikely(p->flags & PF_EXITING)) {
318 		pr_info("[QOS_CTRL] dying task, no need to set qos\n");
319 		ret = -THREAD_EXITING;
320 		goto out_put_task;
321 	}
322 
323 	auth = get_authority(p);
324 	if (!auth) {
325 		pr_err("[QOS_CTRL] no auth data for pid=%d(%s), qos stop failed\n",
326 		       p->tgid, p->comm);
327 		ret = -PID_NOT_FOUND;
328 		goto out_put_task;
329 	}
330 
331 	mutex_lock(&auth->mutex);
332 
333 	qts = (struct qos_task_struct *) &p->qts;
334 
335 	level = qts->in_qos;
336 	if (level == NO_QOS) {
337 		pr_err("[QOS_CTRL] task not in qos list, qos stop failed\n");
338 		ret = -ARG_INVALID;
339 		goto out_unlock;
340 	}
341 
342 	if (!can_change_qos(current, 0)) {
343 		pr_err("[QOS_CTRL] apply for others not permit\n");
344 		ret = -ARG_INVALID;
345 		goto out_unlock;
346 	}
347 
348 	if (auth->status == AUTH_STATUS_DEAD) {
349 		pr_err("[QOS_CTRL] this auth data has been deleted\n");
350 		ret = -INVALID_AUTH;
351 		goto out_unlock;
352 	}
353 
354 	ret = qos_remove_task(p);
355 	if (ret < 0) {
356 		pr_err("[QOS_CTRL] remove task from qos list %d failed\n", level);
357 		goto out_unlock;
358 	}
359 
360 	--auth->num[level];
361 
362 	/*
363 	 * NO NEED to judge whether current status is AUTH_STATUS_DISABLE.
364 	 * In the auth destoring context, the removing of thread's sched attr was protected by
365 	 * auth->mutex, AUTH_STATUS_DISABLED will never appear here.
366 	 *
367 	 * The second param 3 means nothing, actually you can use any valid level here, cause the
368 	 * policy matching AUTH_STATUS_DISABLED has default parameters for all qos level, which can
369 	 * keep a powerful thread to behave like a ordinary thread.
370 	 */
371 	ret = sched_set_task_qos_attr(p, 3, AUTH_STATUS_DISABLED);
372 	if (ret)
373 		pr_err("[QOS_CTRL] set qos_level %d for thread %d on status %d to default failed\n",
374 		       level, p->pid, auth->status);
375 
376 out_unlock:
377 	mutex_unlock(&auth->mutex);
378 	put_auth_struct(auth);
379 out_put_task:
380 	put_task_struct(p);
381 out:
382 	return ret;
383 }
384 
qos_get(struct qos_ctrl_data * data)385 int qos_get(struct qos_ctrl_data *data)
386 {
387 	struct task_struct *p;
388 	struct qos_task_struct *qts;
389 	int pid = data->pid;
390 	int ret = 0;
391 
392 	p = find_get_task_by_vpid((pid_t)pid);
393 	if (unlikely(!p)) {
394 		pr_err("[QOS_CTRL] no matching task for this pid, qos get failed\n");
395 		ret = -ESRCH;
396 		goto out;
397 	}
398 
399 	if (unlikely(p->flags & PF_EXITING)) {
400 		pr_info("[QOS_CTRL] dying task, no need to set qos\n");
401 		ret = -THREAD_EXITING;
402 		goto out_put_task;
403 	}
404 
405 	qts = (struct qos_task_struct *) &p->qts;
406 	data->qos = qts->in_qos;
407 
408 out_put_task:
409 	put_task_struct(p);
410 out:
411 	return ret;
412 }
413 
init_task_qos(struct task_struct * p)414 void init_task_qos(struct task_struct *p)
415 {
416 	struct qos_task_struct *qts = (struct qos_task_struct *) &p->qts;
417 
418 	INIT_LIST_HEAD(&qts->qos_list);
419 	qts->in_qos = NO_QOS;
420 }
421 
422 /*
423  * Remove statistic info in auth when task exit
424  */
sched_exit_qos_list(struct task_struct * p)425 void sched_exit_qos_list(struct task_struct *p)
426 {
427 	struct auth_struct *auth;
428 	struct qos_task_struct *qts = (struct qos_task_struct *) &p->qts;
429 
430 	/*
431 	 * For common tasks(the vast majority):
432 	 * skip get authority, fast return here.
433 	 *
434 	 * For qos tasks:
435 	 * If contend with auth_delete() happens,
436 	 * 1. function return here, auth_delete() will do the clean up
437 	 * 2. function go on, either no auth return, either do clean up here
438 	 * Both cases guarantee data synchronization
439 	 */
440 	if (likely(qts->in_qos == NO_QOS))
441 		return;
442 
443 	auth = get_authority(p);
444 	if (!auth)
445 		goto out;
446 
447 	mutex_lock(&auth->mutex);
448 	if (qts->in_qos == NO_QOS) {
449 		mutex_unlock(&auth->mutex);
450 		goto out_put_auth;
451 	}
452 	--auth->num[qts->in_qos];
453 	list_del_init(&qts->qos_list);
454 	qts->in_qos = NO_QOS;
455 	put_task_struct(p);
456 	mutex_unlock(&auth->mutex);
457 
458 out_put_auth:
459 	put_auth_struct(auth);
460 out:
461 	return;
462 }
463 
464 typedef int (*qos_manipulate_func)(struct qos_ctrl_data *data);
465 
466 static qos_manipulate_func qos_func_array[QOS_OPERATION_CMD_MAX_NR] = {
467 	NULL,
468 	qos_apply,  //1
469 	qos_leave,
470 	qos_get,
471 };
472 
do_qos_manipulate(struct qos_ctrl_data * data)473 static long do_qos_manipulate(struct qos_ctrl_data *data)
474 {
475 	long ret = 0;
476 	unsigned int type = data->type;
477 
478 	if (type <= 0 || type >= QOS_OPERATION_CMD_MAX_NR) {
479 		pr_err("[QOS_CTRL] CMD_ID_QOS_MANIPULATE type not valid\n");
480 		return -ARG_INVALID;
481 	}
482 
483 	if (qos_func_array[type])
484 		ret = (long)(*qos_func_array[type])(data);
485 
486 	return ret;
487 }
488 
ctrl_qos_operation(int abi,void __user * uarg)489 static long ctrl_qos_operation(int abi, void __user *uarg)
490 {
491 	struct qos_ctrl_data qos_data;
492 	int ret = -1;
493 
494 #pragma GCC diagnostic push
495 #pragma GCC diagonstic ignored "-Wpointer-to-int-cast"
496 
497 	switch (abi) {
498 	case QOS_IOCTL_ABI_ARM32:
499 		ret = copy_from_user(&qos_data,
500 				(void __user *)compat_ptr((compat_uptr_t)uarg),
501 				sizeof(struct qos_ctrl_data));
502 		break;
503 	case QOS_IOCTL_ABI_AARCH64:
504 		ret = copy_from_user(&qos_data, uarg, sizeof(struct qos_ctrl_data));
505 		break;
506 	default:
507 		pr_err("[QOS_CTRL] abi format error\n");
508 		break;
509 	}
510 
511 #pragma GCC diagnostic pop
512 
513 	if (ret) {
514 		pr_err("[QOS_CTRL] %s copy user data failed\n", __func__);
515 		return ret;
516 	}
517 
518 	ret = do_qos_manipulate(&qos_data);
519 	if (ret < 0) {
520 		pr_err("[QOS_CTRL] CMD_ID_QOS_MANIPULATE failed\n");
521 		return ret;
522 	}
523 
524 #pragma GCC diagnostic push
525 #pragma GCC diagonstic ignored "-Wpointer-to-int-cast"
526 
527 	switch (abi) {
528 	case QOS_IOCTL_ABI_ARM32:
529 		ret = copy_to_user((void __user *)compat_ptr((compat_uptr_t)uarg),
530 				&qos_data, sizeof(struct qos_ctrl_data));
531 		break;
532 	case QOS_IOCTL_ABI_AARCH64:
533 		ret = copy_to_user(uarg, &qos_data, sizeof(struct qos_ctrl_data));
534 		break;
535 	default:
536 		pr_err("[QOS_CTRL] abi format error\n");
537 		break;
538 	}
539 
540 #pragma GCC diagnostic pop
541 
542 	if (ret) {
543 		pr_err("[QOS_CTRL] %s copy to user failed\n", __func__);
544 		return ret;
545 	}
546 	return 0;
547 }
548 
549 #define MAX_LATENCY_NICE	19
550 #define MIN_LATENCY_NICE	-20
551 
valid_nice(int nice)552 static inline bool valid_nice(int nice)
553 {
554 	return nice >= MIN_NICE && nice <= MAX_NICE;
555 }
556 
valid_latency_nice(int latency_nice)557 static inline bool valid_latency_nice(int latency_nice)
558 {
559 	return latency_nice >= MIN_LATENCY_NICE && latency_nice <= MAX_LATENCY_NICE;
560 }
561 
valid_uclamp(int uclamp_min,int uclamp_max)562 static inline bool valid_uclamp(int uclamp_min, int uclamp_max)
563 {
564 	if (uclamp_min > uclamp_max)
565 		return false;
566 	if (uclamp_max > SCHED_CAPACITY_SCALE)
567 		return false;
568 
569 	return true;
570 }
571 
valid_rt(int sched_priority)572 static inline bool valid_rt(int sched_priority)
573 {
574 	if (sched_priority > MAX_USER_RT_PRIO - 1 || sched_priority < 0)
575 		return false;
576 
577 	return true;
578 }
579 
valid_qos_flag(unsigned int qos_flag)580 static bool valid_qos_flag(unsigned int qos_flag)
581 {
582 	if (qos_flag & ~QOS_FLAG_ALL)
583 		return false;
584 
585 	return true;
586 }
587 
valid_qos_item(struct qos_policy_datas * datas)588 static inline bool valid_qos_item(struct qos_policy_datas *datas)
589 {
590 	int i;
591 	int type = datas->policy_type;
592 	struct qos_policy_data *data;
593 
594 	if (type <= 0 || type >= QOS_POLICY_MAX_NR) {
595 		pr_err("[QOS_CTRL] not valid qos policy type, policy change failed\n");
596 		goto out_failed;
597 	}
598 
599 	if (!valid_qos_flag(datas->policy_flag)) {
600 		pr_err("[QOS_CTRL] not valid qos flag, policy change failed\n");
601 		goto out_failed;
602 	}
603 
604 	/* check user space qos polcicy data, level 0 reserved */
605 	for (i = 0; i < NR_QOS; ++i) {
606 		data = &datas->policys[i];
607 
608 		if (!valid_nice(data->nice)) {
609 			pr_err("[QOS_CTRL] invalid nice, policy change failed\n");
610 			goto out_failed;
611 		}
612 
613 		if (!valid_latency_nice(data->latency_nice)) {
614 			pr_err("[QOS_CTRL] invalid latency_nice, policy change failed\n");
615 			goto out_failed;
616 		}
617 
618 		if (!valid_uclamp(data->uclamp_min, data->uclamp_max)) {
619 			pr_err("[QOS_CTRL] invalid uclamp, policy change failed\n");
620 			goto out_failed;
621 		}
622 
623 		if (!valid_rt(data->rt_sched_priority)) {
624 			pr_err("[QOS_CTRL] invalid rt, policy change failed\n");
625 			goto out_failed;
626 		}
627 	}
628 
629 	return true;
630 
631 out_failed:
632 	pr_err("[QOS_CTRL] not valid qos policy params\n");
633 	return false;
634 }
635 
do_qos_policy_change(struct qos_policy_datas * datas)636 static long do_qos_policy_change(struct qos_policy_datas *datas)
637 {
638 	long ret = 0;
639 	int i;
640 	struct qos_policy_item *item;
641 	struct qos_policy_data *data;
642 	int type = datas->policy_type;
643 
644 	if (type >= QOS_POLICY_MAX_NR) {
645 		pr_err("[QOS_CTRL] not valid policy type\n");
646 		goto out_failed;
647 	}
648 
649 	if (!valid_qos_item(datas))
650 		goto out_failed;
651 
652 	write_lock(&qos_policy_array[type].lock);
653 	for (i = QOS_POLICY_MIN_LEVEL; i < NR_QOS; ++i) {
654 		item = &qos_policy_array[type].levels[i];
655 
656 		/* user space policy params */
657 		data = &datas->policys[i];
658 
659 		item->nice = data->nice;
660 		item->latency_nice = data->latency_nice;
661 		item->uclamp_min = data->uclamp_min;
662 		item->uclamp_max = data->uclamp_max;
663 		/* only specific qos level could use SCHED_FIFO */
664 		item->rt_sched_priority = (i < MIN_RT_QOS_LEVEL) ? 0 :
665 					  data->rt_sched_priority;
666 	}
667 	qos_policy_array[type].policy_flag = datas->policy_flag;
668 	qos_policy_array[type].initialized = true;
669 	write_unlock(&qos_policy_array[type].lock);
670 
671 	return ret;
672 
673 out_failed:
674 	return -ARG_INVALID;
675 }
676 
ctrl_qos_policy(int abi,void __user * uarg)677 static long ctrl_qos_policy(int abi, void __user *uarg)
678 {
679 	struct qos_policy_datas policy_datas;
680 	long ret = -1;
681 
682 #pragma GCC diagnostic push
683 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
684 
685 	switch (abi) {
686 	case QOS_IOCTL_ABI_ARM32:
687 		ret = copy_from_user(&policy_datas,
688 				(void __user *)compat_ptr((compat_uptr_t)uarg),
689 				sizeof(struct qos_policy_datas));
690 		break;
691 	case QOS_IOCTL_ABI_AARCH64:
692 		ret = copy_from_user(&policy_datas, uarg, sizeof(struct qos_policy_datas));
693 		break;
694 	default:
695 		pr_err("[QOS_CTRL] abi format error\n");
696 		break;
697 	}
698 
699 #pragma GCC diagnostic pop
700 
701 	if (ret) {
702 		pr_err("[QOS_RTG] %s copy user data failed\n", __func__);
703 		return ret;
704 	}
705 
706 	return do_qos_policy_change(&policy_datas);
707 }
708 
do_qos_ctrl_ioctl(int abi,struct file * file,unsigned int cmd,unsigned long arg)709 long do_qos_ctrl_ioctl(int abi, struct file *file, unsigned int cmd, unsigned long arg)
710 {
711 	void __user *uarg = (void __user *)arg;
712 	unsigned int func_cmd = _IOC_NR(cmd);
713 
714 	if (uarg == NULL) {
715 		pr_err("%s: invalid user uarg\n", __func__);
716 		return -EINVAL;
717 	}
718 
719 	if (_IOC_TYPE(cmd) != QOS_CTRL_IPC_MAGIG) {
720 		pr_err("%s: qos ctrl magic fail, TYPE=%d\n",
721 		       __func__, _IOC_TYPE(cmd));
722 		return -EINVAL;
723 	}
724 
725 	if (func_cmd >= QOS_CTRL_MAX_NR) {
726 		pr_err("%s: qos ctrl cmd error, cmd:%d\n",
727 		       __func__, _IOC_TYPE(cmd));
728 		return -EINVAL;
729 	}
730 
731 #ifdef CONFIG_QOS_AUTHORITY
732 	if (!check_authorized(func_cmd, QOS_AUTH_FLAG)) {
733 		pr_err("[QOS_CTRL] %s: pid not authorized\n", __func__);
734 		return -PID_NOT_AUTHORIZED;
735 	}
736 #endif
737 
738 	if (g_func_array[func_cmd])
739 		return (*g_func_array[func_cmd])(abi, uarg);
740 
741 	return -EINVAL;
742 }
743 
init_qos_policy_array(void)744 static void init_qos_policy_array(void)
745 {
746 	int i;
747 
748 	/* index 0 reserved */
749 	for (i = 1; i < QOS_POLICY_MAX_NR; ++i)
750 		rwlock_init(&qos_policy_array[i].lock);
751 
752 	pr_info("[QOS_CTRL] lock in qos policy initialized\n");
753 }
754 
init_qos_ctrl(void)755 int __init init_qos_ctrl(void)
756 {
757 	init_qos_policy_array();
758 
759 	return 0;
760 }
761 
762