Commit b57c4ec9 authored by Lijo Lazar's avatar Lijo Lazar Committed by Alex Deucher
Browse files

drm/amdgpu: Fix error handling in slot reset



If the device has not recovered after slot reset is called, it goes to
out label for error handling. There it could make decision based on
uninitialized hive pointer and could result in accessing an uninitialized
list.

Initialize the list and hive properly so that it handles the error
situation and also releases the reset domain lock which is acquired
during error_detected callback.

Fixes: 732c6cef ("drm/amdgpu: Replace tmp_adev with hive in amdgpu_pci_slot_reset")
Signed-off-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Reviewed-by: default avatarCe Sun <cesun102@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
(cherry picked from commit bb713621)
parent a5fe1a54
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -7059,6 +7059,15 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
	dev_info(adev->dev, "PCI error: slot reset callback!!\n");

	memset(&reset_context, 0, sizeof(reset_context));
	INIT_LIST_HEAD(&device_list);
	hive = amdgpu_get_xgmi_hive(adev);
	if (hive) {
		mutex_lock(&hive->hive_lock);
		list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
			list_add_tail(&tmp_adev->reset_list, &device_list);
	} else {
		list_add_tail(&adev->reset_list, &device_list);
	}

	if (adev->pcie_reset_ctx.swus)
		link_dev = adev->pcie_reset_ctx.swus;
@@ -7099,19 +7108,13 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
	reset_context.reset_req_dev = adev;
	set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
	set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
	INIT_LIST_HEAD(&device_list);

	hive = amdgpu_get_xgmi_hive(adev);
	if (hive) {
		mutex_lock(&hive->hive_lock);
		reset_context.hive = hive;
		list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
		list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
			tmp_adev->pcie_reset_ctx.in_link_reset = true;
			list_add_tail(&tmp_adev->reset_list, &device_list);
		}
	} else {
		set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
		list_add_tail(&adev->reset_list, &device_list);
	}

	r = amdgpu_device_asic_reset(adev, &device_list, &reset_context);