count0, count1, pcie_get_mps(adev->pdev));
 }
 
+/**
+ * DOC: unique_id
+ *
+ * The amdgpu driver provides a sysfs API for providing a unique ID for the GPU
+ * The file unique_id is used for this.
+ * This will provide a Unique ID that will persist from machine to machine
+ *
+ * NOTE: This will only work for GFX9 and newer. This file will be absent
+ * on unsupported ASICs (GFX8 and older)
+ */
+static ssize_t amdgpu_get_unique_id(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+       struct amdgpu_device *adev = ddev->dev_private;
+
+       if (adev->unique_id)
+               return snprintf(buf, PAGE_SIZE, "%016llx\n", adev->unique_id);
+
+       return 0;
+}
+
 static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state);
 static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
                   amdgpu_get_dpm_forced_performance_level,
 static DEVICE_ATTR(ppfeatures, S_IRUGO | S_IWUSR,
                amdgpu_get_ppfeature_status,
                amdgpu_set_ppfeature_status);
+static DEVICE_ATTR(unique_id, S_IRUGO, amdgpu_get_unique_id, NULL);
 
 static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
                                      struct device_attribute *attr,
                        return ret;
                }
        }
+       if (adev->unique_id)
+               ret = device_create_file(adev->dev, &dev_attr_unique_id);
+       if (ret) {
+               DRM_ERROR("failed to create device file unique_id\n");
+               return ret;
+       }
        ret = amdgpu_debugfs_pm_init(adev);
        if (ret) {
                DRM_ERROR("Failed to register debugfs file for dpm!\n");
                device_remove_file(adev->dev, &dev_attr_mem_busy_percent);
        if (!(adev->flags & AMD_IS_APU))
                device_remove_file(adev->dev, &dev_attr_pcie_bw);
+       if (adev->unique_id)
+               device_remove_file(adev->dev, &dev_attr_unique_id);
        if ((adev->asic_type >= CHIP_VEGA10) &&
            !(adev->flags & AMD_IS_APU))
                device_remove_file(adev->dev, &dev_attr_ppfeatures);
 
        struct vega10_hwmgr *data = hwmgr->backend;
        int i;
        uint32_t sub_vendor_id, hw_revision;
+       uint32_t top32, bottom32;
        struct amdgpu_device *adev = hwmgr->adev;
 
        vega10_initialize_power_tune_defaults(hwmgr);
                (hw_revision == 0) &&
                (sub_vendor_id != 0x1002))
                data->smu_features[GNLD_PCC_LIMIT].supported = true;
+
+       /* Get the SN to turn into a Unique ID */
+       smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
+       top32 = smum_get_argument(hwmgr);
+       smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
+       bottom32 = smum_get_argument(hwmgr);
+
+       adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
 }
 
 #ifdef PPLIB_VEGA10_EVV_SUPPORT
 
 static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 {
        struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
+       struct amdgpu_device *adev = hwmgr->adev;
+       uint32_t top32, bottom32;
        int i;
 
        data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
                        ((data->registry_data.disallowed_features >> i) & 1) ?
                        false : true;
        }
+
+       /* Get the SN to turn into a Unique ID */
+       smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
+       top32 = smum_get_argument(hwmgr);
+       smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
+       bottom32 = smum_get_argument(hwmgr);
+
+       adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
 }
 
 static int vega12_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
 
 static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
 {
        struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
+       struct amdgpu_device *adev = hwmgr->adev;
+       uint32_t top32, bottom32;
        int i;
 
        data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
                        ((data->registry_data.disallowed_features >> i) & 1) ?
                        false : true;
        }
+
+       /* Get the SN to turn into a Unique ID */
+       smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
+       top32 = smum_get_argument(hwmgr);
+       smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
+       bottom32 = smum_get_argument(hwmgr);
+
+       adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
 }
 
 static int vega20_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)