Commit 32c81f1b authored by Zhang Zekun's avatar Zhang Zekun Committed by Jian Zhang
Browse files

mm/sharepool: Use "tgid" instead of "pid" to find a task

ascend inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I612UG


CVE: NA

--------------------------------

To support container scenario, use tgid instead of pid to find a
specific task. In normal cases, "tgid" represent a process in init_pid_ns,
this patch should not introduce problems to existing code.

Rename the input parameter "int pid" to "int tgid" in following
exported interfaces:
1.mg_sp_group_id_by_pid()
2.mg_sp_group_add_task()
3.mg_sp_group_del_task()
4.mg_sp_make_share_k2u()
5.mg_sp_make_share_u2k()
6.mg_sp_config_dvpp_range()

Besides, rename these static function together:
1.__sp_find_spg_locked()
2.__sp_find_spg()

The following function use "current->pid" to find spg, change
"current->pid" to "current->tgid".
1.find_or_alloc_sp_group()
2.sp_alloc_prepare()
3.mg_sp_make_share_k2u()

Signed-off-by: default avatarZhang Zekun <zhangzekun11@huawei.com>
parent 66ae8ddd
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -249,9 +249,9 @@ static inline void sp_init_mm(struct mm_struct *mm)
/*
 * Those interfaces are exported for modules
 */
extern int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id);
extern int mg_sp_group_del_task(int pid, int spg_id);
extern int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num);
extern int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id);
extern int mg_sp_group_del_task(int tgid, int spg_id);
extern int mg_sp_group_id_by_pid(int tgid, int *spg_ids, int *num);
extern int proc_sp_group_state(struct seq_file *m, struct pid_namespace *ns,
			struct pid *pid, struct task_struct *task);

@@ -259,8 +259,8 @@ extern void *mg_sp_alloc(unsigned long size, unsigned long sp_flags, int spg_id)
extern int mg_sp_free(unsigned long addr, int id);

extern void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size,
			unsigned long sp_flags, int pid, int spg_id);
extern void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid);
			unsigned long sp_flags, int tgid, int spg_id);
extern void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int tgid);
extern int mg_sp_unshare(unsigned long va, unsigned long size, int spg_id);

extern int mg_sp_walk_page_range(unsigned long uva, unsigned long size,
@@ -271,7 +271,7 @@ extern void mg_sp_walk_page_free(struct sp_walk_data *sp_walk_data);
extern int sp_register_notifier(struct notifier_block *nb);
extern int sp_unregister_notifier(struct notifier_block *nb);

extern bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid);
extern bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int tgid);

extern bool mg_is_sharepool_addr(unsigned long addr);

@@ -321,12 +321,12 @@ static inline bool is_vmalloc_sharepool(unsigned long vm_flags)

#else /* CONFIG_ASCEND_SHARE_POOL */

static inline int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
static inline int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id)
{
	return -EPERM;
}

static inline int mg_sp_group_del_task(int pid, int spg_id)
static inline int mg_sp_group_del_task(int tgid, int spg_id)
{
	return -EPERM;
}
@@ -340,7 +340,7 @@ static inline void sp_group_post_exit(struct mm_struct *mm)
{
}

static inline int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num)
static inline int mg_sp_group_id_by_pid(int tgid, int *spg_ids, int *num)
{
	return -EPERM;
}
@@ -362,12 +362,12 @@ static inline int mg_sp_free(unsigned long addr, int id)
}

static inline void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size,
			unsigned long sp_flags, int pid, int spg_id)
			unsigned long sp_flags, int tgid, int spg_id)
{
	return NULL;
}

static inline void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid)
static inline void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int tgid)
{
	return NULL;
}
@@ -410,7 +410,7 @@ static inline int sp_unregister_notifier(struct notifier_block *nb)
	return -EPERM;
}

static inline bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid)
static inline bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int tgid)
{
	return false;
}
+33 −31
Original line number Diff line number Diff line
@@ -975,12 +975,14 @@ static void sp_group_drop(struct sp_group *spg)
}

/* use with put_task_struct(task) */
static int get_task(int pid, struct task_struct **task)
static int get_task(int tgid, struct task_struct **task)
{
	struct task_struct *tsk;
	struct pid *p;

	rcu_read_lock();
	tsk = find_task_by_vpid(pid);
	p = find_pid_ns(tgid, &init_pid_ns);
	tsk = pid_task(p, PIDTYPE_TGID);
	if (!tsk || (tsk->flags & PF_EXITING)) {
		rcu_read_unlock();
		return -ESRCH;
@@ -1010,14 +1012,14 @@ static bool is_process_in_group(struct sp_group *spg,
}

/* user must call sp_group_drop() after use */
static struct sp_group *__sp_find_spg_locked(int pid, int spg_id)
static struct sp_group *__sp_find_spg_locked(int tgid, int spg_id)
{
	struct sp_group *spg = NULL;
	struct task_struct *tsk = NULL;
	int ret = 0;

	if (spg_id == SPG_ID_DEFAULT) {
		ret = get_task(pid, &tsk);
		ret = get_task(tgid, &tsk);
		if (ret)
			return NULL;

@@ -1039,19 +1041,19 @@ static struct sp_group *__sp_find_spg_locked(int pid, int spg_id)
	return spg;
}

static struct sp_group *__sp_find_spg(int pid, int spg_id)
static struct sp_group *__sp_find_spg(int tgid, int spg_id)
{
	struct sp_group *spg;

	down_read(&sp_group_sem);
	spg = __sp_find_spg_locked(pid, spg_id);
	spg = __sp_find_spg_locked(tgid, spg_id);
	up_read(&sp_group_sem);
	return spg;
}

/**
 * mp_sp_group_id_by_pid() - Get the sp_group ID array of a process.
 * @pid: pid of target process.
 * @tgid: tgid of target process.
 * @spg_ids: point to an array to save the group ids the process belongs to
 * @num: input the spg_ids array size; output the spg number of the process
 *
@@ -1061,7 +1063,7 @@ static struct sp_group *__sp_find_spg(int pid, int spg_id)
 * -EINVAL	- spg_ids or num is NULL.
 * -E2BIG	- the num of groups process belongs to is larger than *num
 */
int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num)
int mg_sp_group_id_by_pid(int tgid, int *spg_ids, int *num)
{
	int ret = 0, real_count;
	struct sp_group_node *node;
@@ -1076,7 +1078,7 @@ int mg_sp_group_id_by_pid(int pid, int *spg_ids, int *num)
	if (!spg_ids || !num || *num <= 0)
		return -EINVAL;

	ret = get_task(pid, &tsk);
	ret = get_task(tgid, &tsk);
	if (ret)
		return ret;

@@ -1198,7 +1200,7 @@ static struct sp_group *find_or_alloc_sp_group(int spg_id, unsigned long flag)
{
	struct sp_group *spg;

	spg = __sp_find_spg_locked(current->pid, spg_id);
	spg = __sp_find_spg_locked(current->tgid, spg_id);

	if (!spg) {
		spg = create_spg(spg_id, flag);
@@ -1350,7 +1352,7 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg)

/**
 * mg_sp_group_add_task() - Add a process to an share group (sp_group).
 * @pid: the pid of the task to be added.
 * @tgid: the tgid of the task to be added.
 * @prot: the prot of task for this spg.
 * @spg_id: the ID of the sp_group.
 * @flag: to give some special message.
@@ -1364,7 +1366,7 @@ static int local_group_add_task(struct mm_struct *mm, struct sp_group *spg)
 * The automatically allocated ID is between [SPG_ID_AUTO_MIN, SPG_ID_AUTO_MAX].
 * When negative, the return value is -errno.
 */
int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id)
{
	unsigned long flag = 0;
	struct task_struct *tsk;
@@ -1393,7 +1395,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)
	}

	if (spg_id >= SPG_ID_AUTO_MIN && spg_id <= SPG_ID_AUTO_MAX) {
		spg = __sp_find_spg(pid, spg_id);
		spg = __sp_find_spg(tgid, spg_id);

		if (!spg) {
			pr_err_ratelimited("spg %d hasn't been created\n", spg_id);
@@ -1424,7 +1426,7 @@ int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id)

	down_write(&sp_group_sem);

	ret = get_task(pid, &tsk);
	ret = get_task(tgid, &tsk);
	if (ret) {
		up_write(&sp_group_sem);
		free_new_spg_id(id_newly_generated, spg_id);
@@ -1599,7 +1601,7 @@ EXPORT_SYMBOL_GPL(mg_sp_group_add_task);

/**
 * mg_sp_group_del_task() - delete a process from a sp group.
 * @pid: the pid of the task to be deleted
 * @tgid: the tgid of the task to be deleted
 * @spg_id: sharepool group id
 *
 * the group's spa list must be empty, or deletion will fail.
@@ -1607,9 +1609,9 @@ EXPORT_SYMBOL_GPL(mg_sp_group_add_task);
 * Return:
 * * if success, return 0.
 * * -EINVAL, spg_id invalid or spa_lsit not emtpy or spg dead
 * * -ESRCH, the task group of pid is not in group / process dead
 * * -ESRCH, the task group of tgid is not in group / process dead
 */
int mg_sp_group_del_task(int pid, int spg_id)
int mg_sp_group_del_task(int tgid, int spg_id)
{
	int ret = 0;
	struct sp_group *spg;
@@ -1626,7 +1628,7 @@ int mg_sp_group_del_task(int pid, int spg_id)
		return -EINVAL;
	}

	spg = __sp_find_spg(pid, spg_id);
	spg = __sp_find_spg(tgid, spg_id);
	if (!spg) {
		pr_err_ratelimited("spg not found or get task failed.");
		return -EINVAL;
@@ -1647,7 +1649,7 @@ int mg_sp_group_del_task(int pid, int spg_id)
		goto out;
	}

	ret = get_task(pid, &tsk);
	ret = get_task(tgid, &tsk);
	if (ret) {
		up_write(&sp_group_sem);
		pr_err_ratelimited("task is not found");
@@ -1759,7 +1761,7 @@ static void insert_sp_area(struct sp_mapping *spm, struct sp_area *spa)
 * @flags: how to allocate the memory.
 * @spg: the share group that the memory is allocated to.
 * @type: the type of the region.
 * @applier: the pid of the task which allocates the region.
 * @applier: the tgid of the task which allocates the region.
 *
 * Return: a valid pointer for success, NULL on failure.
 */
@@ -2318,7 +2320,7 @@ static int sp_alloc_prepare(unsigned long size, unsigned long sp_flags,
		sp_flags |= SP_HUGEPAGE;

	if (spg_id != SPG_ID_DEFAULT) {
		spg = __sp_find_spg(current->pid, spg_id);
		spg = __sp_find_spg(current->tgid, spg_id);
		if (!spg) {
			pr_err_ratelimited("allocation failed, can't find group\n");
			return -ENODEV;
@@ -2921,7 +2923,7 @@ static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc)
 * @kva: the VA of shared kernel memory.
 * @size: the size of shared kernel memory.
 * @sp_flags: how to allocate the memory. We only support SP_DVPP.
 * @pid:  the pid of the specified process (Not currently in use).
 * @tgid:  the tgid of the specified process (Not currently in use).
 * @spg_id: the share group that the memory is shared to.
 *
 * Return: the shared target user address to start at
@@ -2934,7 +2936,7 @@ static void *sp_k2u_finish(void *uva, struct sp_k2u_context *kc)
 * * if fail, return the pointer of -errno.
 */
void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size,
			unsigned long sp_flags, int pid, int spg_id)
			unsigned long sp_flags, int tgid, int spg_id)
{
	void *uva;
	int ret;
@@ -2954,7 +2956,7 @@ void *mg_sp_make_share_k2u(unsigned long kva, unsigned long size,
	} else {
		struct sp_group *spg;

		spg = __sp_find_spg(current->pid, kc.spg_id);
		spg = __sp_find_spg(current->tgid, kc.spg_id);
		if (spg) {
			ret = sp_check_caller_permission(spg, current->mm);
			if (ret < 0) {
@@ -3214,13 +3216,13 @@ static void __sp_walk_page_free(struct sp_walk_data *data)
 * mg_sp_make_share_u2k() - Share user memory of a specified process to kernel.
 * @uva: the VA of shared user memory
 * @size: the size of shared user memory
 * @pid: the pid of the specified process(Not currently in use)
 * @tgid: the tgid of the specified process(Not currently in use)
 *
 * Return:
 * * if success, return the starting kernel address of the shared memory.
 * * if failed, return the pointer of -errno.
 */
void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid)
void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int tgid)
{
	int ret = 0;
	struct mm_struct *mm = current->mm;
@@ -3282,7 +3284,7 @@ void *mg_sp_make_share_u2k(unsigned long uva, unsigned long size, int pid)
EXPORT_SYMBOL_GPL(mg_sp_make_share_u2k);

/*
 * Input parameters uva, pid and spg_id are now useless. spg_id will be useful
 * Input parameters uva, tgid and spg_id are now useless. spg_id will be useful
 * when supporting a process in multiple sp groups.
 *
 * Procedure of unshare uva must be compatible with:
@@ -3612,13 +3614,13 @@ static bool is_sp_dynamic_dvpp_addr(unsigned long addr);
 * @start: the value of share pool start
 * @size: the value of share pool
 * @device_id: the num of Da-vinci device
 * @pid: the pid of device process
 * @tgid: the tgid of device process
 *
 * Return true for success.
 * Return false if parameter invalid or has been set up.
 * This functuon has no concurrent problem.
 */
bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid)
bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int tgid)
{
	int ret;
	bool err = false;
@@ -3632,12 +3634,12 @@ bool mg_sp_config_dvpp_range(size_t start, size_t size, int device_id, int pid)
		return false;

	/* NOTE: check the start address */
	if (pid < 0 || size <= 0 || size > MMAP_SHARE_POOL_16G_SIZE ||
	if (tgid < 0 || size <= 0 || size > MMAP_SHARE_POOL_16G_SIZE ||
	    device_id < 0 || device_id >= MAX_DEVID || !is_online_node_id(device_id)
		|| !is_sp_dynamic_dvpp_addr(start) || !is_sp_dynamic_dvpp_addr(start + size - 1))
		return false;

	ret = get_task(pid, &tsk);
	ret = get_task(tgid, &tsk);
	if (ret)
		return false;