Unverified Commit 7272e67e authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!8969 Fix CVE-2024-36949

Merge Pull Request from: @ci-robot 
 
PR sync from: Zheng Zucheng <zhengzucheng@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/LQSUVTI4HA6HHITDY5SPRKAFJWA2NUHP/ 
Fix CVE-2024-36949

Mukul Joshi (1):
  drm/amdkfd: Rework kfd_locked handling

Zhigang Luo (1):
  amd/amdkfd: sync all devices to wait all processes being evicted


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/I9U8NU 
 
Link:https://gitee.com/openeuler/kernel/pulls/8969

 

Reviewed-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 8b903917 cf1bee5d
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -128,13 +128,6 @@ static int kfd_open(struct inode *inode, struct file *filep)
	if (IS_ERR(process))
		return PTR_ERR(process);

	if (kfd_is_locked()) {
		dev_dbg(kfd_device, "kfd is locked!\n"
				"process %d unreferenced", process->pasid);
		kfd_unref_process(process);
		return -EAGAIN;
	}

	/* filep now owns the reference returned by kfd_create_process */
	filep->private_data = process;

+14 −9
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@
 * once locked, kfd driver will stop any further GPU execution.
 * create process (open) will return -EAGAIN.
 */
static atomic_t kfd_locked = ATOMIC_INIT(0);
static int kfd_locked;

#ifdef CONFIG_DRM_AMDGPU_CIK
extern const struct kfd2kgd_calls gfx_v7_kfd2kgd;
@@ -842,8 +842,9 @@ int kgd2kfd_post_reset(struct kfd_dev *kfd)
	ret = kfd_resume(kfd);
	if (ret)
		return ret;
	atomic_dec(&kfd_locked);

	mutex_lock(&kfd_processes_mutex);
	--kfd_locked;
	mutex_unlock(&kfd_processes_mutex);
	atomic_set(&kfd->sram_ecc_flag, 0);

	kfd_smi_event_update_gpu_reset(kfd, true);
@@ -853,7 +854,8 @@ int kgd2kfd_post_reset(struct kfd_dev *kfd)

bool kfd_is_locked(void)
{
	return  (atomic_read(&kfd_locked) > 0);
	lockdep_assert_held(&kfd_processes_mutex);
	return  (kfd_locked > 0);
}

void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
@@ -863,9 +865,11 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)

	/* for runtime suspend, skip locking kfd */
	if (!run_pm) {
		mutex_lock(&kfd_processes_mutex);
		/* For first KFD device suspend all the KFD processes */
		if (atomic_inc_return(&kfd_locked) == 1)
		if (++kfd_locked == 1)
			kfd_suspend_all_processes();
		mutex_unlock(&kfd_processes_mutex);
	}

	kfd->dqm->ops.stop(kfd->dqm);
@@ -874,7 +878,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)

int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
{
	int ret, count;
	int ret;

	if (!kfd->init_complete)
		return 0;
@@ -885,10 +889,11 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)

	/* for runtime resume, skip unlocking kfd */
	if (!run_pm) {
		count = atomic_dec_return(&kfd_locked);
		WARN_ONCE(count < 0, "KFD suspend / resume ref. error");
		if (count == 0)
		mutex_lock(&kfd_processes_mutex);
		if (--kfd_locked == 0)
			ret = kfd_resume_all_processes();
		WARN_ONCE(kfd_locked < 0, "KFD suspend / resume ref. error");
		mutex_unlock(&kfd_processes_mutex);
	}

	return ret;
+2 −0
Original line number Diff line number Diff line
@@ -172,6 +172,8 @@ extern int queue_preemption_timeout_ms;
/* Enable eviction debug messages */
extern bool debug_evictions;

extern struct mutex kfd_processes_mutex;

enum cache_policy {
	cache_policy_coherent,
	cache_policy_noncoherent
+7 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ struct mm_struct;
 * Unique/indexed by mm_struct*
 */
DEFINE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE);
static DEFINE_MUTEX(kfd_processes_mutex);
DEFINE_MUTEX(kfd_processes_mutex);

DEFINE_SRCU(kfd_processes_srcu);

@@ -761,6 +761,12 @@ struct kfd_process *kfd_create_process(struct file *filep)
	 */
	mutex_lock(&kfd_processes_mutex);

	if (kfd_is_locked()) {
		mutex_unlock(&kfd_processes_mutex);
		pr_debug("KFD is locked! Cannot create process");
		return ERR_PTR(-EINVAL);
	}

	/* A prior open of /dev/kfd could have already created the process. */
	process = find_process(thread);
	if (process) {