[SWDEV-462952] Options enabled for GPU passthrough scenarios

Added Dynamic Passthrough detection

Signed-off-by: Pham, Gabriel <Gabriel.Pham@amd.com>
Signed-off-by: Arif, Maisam <Maisam.Arif@amd.com>
Co-authored-by: Arif, Maisam <Maisam.Arif@amd.com>
This commit is contained in:
Pham, Gabriel
2025-01-30 19:12:03 -05:00
committed by GitHub
parent 5b2c271eff
commit 0f79efac78
6 changed files with 137 additions and 11 deletions
+20 -6
View File
@@ -57,6 +57,7 @@ class AMDSMIHelpers():
self._is_windows = False
self._count_of_sets_called = 0
# Check if the system is a virtual OS
if self.operating_system.startswith("Linux"):
self._is_linux = True
logging.debug(f"AMDSMIHelpers: Platform is linux:{self._is_linux}")
@@ -70,14 +71,27 @@ class AMDSMIHelpers():
self._is_baremetal = not self._is_virtual_os
# Check for passthrough system filtering by device id
if self._is_virtual_os:
#If hard coded passthrough device ids exist on Virtual OS,
# then it is a passthrough system
output = self.get_pci_device_ids()
passthrough_device_ids = ["7460", "73c8", "74a0", "74a1", "74a2"]
if any(('0x' + device_id) in output for device_id in passthrough_device_ids):
if self._is_virtual_os:
self._is_baremetal = True
self._is_virtual_os = False
self._is_passthrough = True
self._is_baremetal = True
self._is_virtual_os = False
self._is_passthrough = True
# Check for passthrough system dynamically via drm querying id_flags
if self.is_amdgpu_initialized() and not self._is_passthrough:
device_handles = amdsmi_interface.amdsmi_get_processor_handles()
for dev in device_handles:
passthrough_info = amdsmi_interface.amdsmi_get_gpu_passthrough_info(dev)
# isolate the relevant bits and then shift them over to get the correct values
ids_flags = (passthrough_info['ids_flags'] & amdsmi_interface.AmdSmiPassthroughInfoFlags.MASK) >> amdsmi_interface.AmdSmiPassthroughInfoFlags.SHIFT
if ids_flags & amdsmi_interface.AmdSmiPassthroughInfoFlags.PT == 0x2:
self._is_baremetal = True
self._is_virtual_os = False
self._is_passthrough = True
def increment_set_count(self):
self._count_of_sets_called += 1
@@ -693,7 +707,7 @@ class AMDSMIHelpers():
accelerator_partition_profiles['profile_indices'].append(str(profile['profiles'][p]['profile_index']))
accelerator_partition_profiles['profile_types'].append(profile['profiles'][p]['profile_type'])
accelerator_partition_profiles['memory_caps'].append(profile['profiles'][p]['memory_caps'])
break # Only need to get the profiles for one device
break # Only need to get the profiles for one device
except amdsmi_interface.AmdSmiLibraryException as e:
break
return accelerator_partition_profiles
+15
View File
@@ -1680,6 +1680,17 @@ typedef struct {
uint64_t reserved[15];
} amdsmi_topology_nearest_t;
/**
* @brief This structure contains information about passthrough mode in guest systems.
*/
typedef struct {
uint32_t device_id;
uint32_t rev_id;
uint32_t vendor_id;
uint64_t ids_flags;
} amdsmi_passthrough_info_t;
//! Place-holder "variant" for functions that have don't have any variants,
//! but do have monitors or sensors.
#define AMDSMI_DEFAULT_VARIANT 0xFFFFFFFFFFFFFFFF
@@ -5321,6 +5332,10 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle,
amdsmi_link_type_t link_type,
amdsmi_topology_nearest_t* topology_nearest_info);
amdsmi_status_t
amdsmi_get_gpu_passthrough_info(amdsmi_processor_handle processor_handle,
amdsmi_passthrough_info_t* info);
#ifdef ENABLE_ESMI_LIB
/*****************************************************************************/
/** @defgroup energyinfo Energy information (RAPL MSR)
+13 -1
View File
@@ -730,6 +730,18 @@ struct drm_amdgpu_cs_chunk_data {
*/
#define AMDGPU_IDS_FLAGS_FUSION 0x1
#define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
#define AMDGPU_IDS_FLAGS_TMZ 0x4
#define AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD 0x8
/*
* Query h/w info: Flag identifying VF/PF/PT mode
*
*/
#define AMDGPU_IDS_FLAGS_MODE_MASK 0x300
#define AMDGPU_IDS_FLAGS_MODE_SHIFT 0x8
#define AMDGPU_IDS_FLAGS_MODE_PF 0x0
#define AMDGPU_IDS_FLAGS_MODE_VF 0x1
#define AMDGPU_IDS_FLAGS_MODE_PT 0x2
/* indicate if acceleration can be working */
#define AMDGPU_INFO_ACCEL_WORKING 0x00
@@ -1059,7 +1071,7 @@ struct drm_amdgpu_info_device {
__u32 num_rb_pipes;
__u32 num_hw_gfx_contexts;
__u32 _pad;
__u64 ids_flags;
__u64 ids_flags; // Relevant info here REMOVE LATER
/** Starting virtual address for UMDs. */
__u64 virtual_address_offset;
/** The maximum virtual address */
+29
View File
@@ -438,6 +438,13 @@ class AmdSmiRegType(IntEnum):
USR1 = amdsmi_wrapper.AMDSMI_REG_USR1
class AmdSmiPassthroughInfoFlags(IntEnum):
MASK = 0x300
SHIFT = 0x8
PF = 0x0
VT = 0x1
PT = 0x2
class AmdSmiEventReader:
def __init__(
self, processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
@@ -4458,3 +4465,25 @@ def amdsmi_get_link_topology_nearest(
return {
'processor_list': device_list
}
def amdsmi_get_gpu_passthrough_info(
processor_handle: amdsmi_wrapper.amdsmi_processor_handle
) -> Dict[str, int]:
# make info struct here
info = amdsmi_wrapper.amdsmi_passthrough_info_t()
# call lib function here
_check_res(
amdsmi_wrapper.amdsmi_get_gpu_passthrough_info(
processor_handle,
ctypes.byref(info)
)
)
return {
"device_id": info.device_id,
"rev_id": info.rev_id,
"vendor_id": info.vendor_id,
"ids_flags": info.ids_flags
}
+24 -4
View File
@@ -1989,6 +1989,21 @@ struct_amdsmi_topology_nearest_t._fields_ = [
]
amdsmi_topology_nearest_t = struct_amdsmi_topology_nearest_t
class struct_amdsmi_passthrough_info_t(Structure):
pass
struct_amdsmi_passthrough_info_t._pack_ = 1 # source:False
struct_amdsmi_passthrough_info_t._fields_ = [
('device_id', ctypes.c_uint32),
('rev_id', ctypes.c_uint32),
('vendor_id', ctypes.c_uint32),
('PADDING_0', ctypes.c_ubyte * 4),
('ids_flags', ctypes.c_uint64),
]
amdsmi_passthrough_info_t = struct_amdsmi_passthrough_info_t
class struct_amdsmi_hsmp_driver_version_t(Structure):
pass
@@ -1999,6 +2014,7 @@ struct_amdsmi_hsmp_driver_version_t._fields_ = [
]
amdsmi_hsmp_driver_version_t = struct_amdsmi_hsmp_driver_version_t
class struct_amdsmi_smu_fw_version_t(Structure):
pass
@@ -2554,6 +2570,9 @@ amdsmi_get_gpu_total_ecc_count.argtypes = [amdsmi_processor_handle, ctypes.POINT
amdsmi_get_link_topology_nearest = _libraries['libamd_smi.so'].amdsmi_get_link_topology_nearest
amdsmi_get_link_topology_nearest.restype = amdsmi_status_t
amdsmi_get_link_topology_nearest.argtypes = [amdsmi_processor_handle, amdsmi_link_type_t, ctypes.POINTER(struct_amdsmi_topology_nearest_t)]
amdsmi_get_gpu_passthrough_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_passthrough_info
amdsmi_get_gpu_passthrough_info.restype = amdsmi_status_t
amdsmi_get_gpu_passthrough_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_passthrough_info_t)]
amdsmi_get_cpu_core_energy = _libraries['libamd_smi.so'].amdsmi_get_cpu_core_energy
amdsmi_get_cpu_core_energy.restype = amdsmi_status_t
amdsmi_get_cpu_core_energy.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint64)]
@@ -2976,7 +2995,7 @@ __all__ = \
'amdsmi_get_gpu_metrics_info',
'amdsmi_get_gpu_od_volt_curve_regions',
'amdsmi_get_gpu_od_volt_info', 'amdsmi_get_gpu_overdrive_level',
'amdsmi_get_gpu_pci_bandwidth',
'amdsmi_get_gpu_passthrough_info', 'amdsmi_get_gpu_pci_bandwidth',
'amdsmi_get_gpu_pci_replay_counter',
'amdsmi_get_gpu_pci_throughput', 'amdsmi_get_gpu_perf_level',
'amdsmi_get_gpu_pm_metrics_info',
@@ -3025,9 +3044,9 @@ __all__ = \
'amdsmi_mm_ip_t', 'amdsmi_name_value_t', 'amdsmi_nps_caps_t',
'amdsmi_od_vddc_point_t', 'amdsmi_od_volt_curve_t',
'amdsmi_od_volt_freq_data_t', 'amdsmi_p2p_capability_t',
'amdsmi_pcie_bandwidth_t', 'amdsmi_pcie_info_t',
'amdsmi_power_cap_info_t', 'amdsmi_power_info_t',
'amdsmi_power_profile_preset_masks_t',
'amdsmi_passthrough_info_t', 'amdsmi_pcie_bandwidth_t',
'amdsmi_pcie_info_t', 'amdsmi_power_cap_info_t',
'amdsmi_power_info_t', 'amdsmi_power_profile_preset_masks_t',
'amdsmi_power_profile_status_t', 'amdsmi_proc_info_t',
'amdsmi_process_handle_t', 'amdsmi_process_info_t',
'amdsmi_processor_handle', 'amdsmi_range_t',
@@ -3093,6 +3112,7 @@ __all__ = \
'struct_amdsmi_od_volt_curve_t',
'struct_amdsmi_od_volt_freq_data_t',
'struct_amdsmi_p2p_capability_t',
'struct_amdsmi_passthrough_info_t',
'struct_amdsmi_pcie_bandwidth_t', 'struct_amdsmi_pcie_info_t',
'struct_amdsmi_power_cap_info_t', 'struct_amdsmi_power_info_t',
'struct_amdsmi_power_profile_status_t',
+36
View File
@@ -3785,6 +3785,42 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle,
return status;
}
amdsmi_status_t
amdsmi_get_gpu_passthrough_info(amdsmi_processor_handle processor_handle, amdsmi_passthrough_info_t *info) {
AMDSMI_CHECK_INIT();
if (info == nullptr) {
return AMDSMI_STATUS_INVAL;
}
struct drm_amdgpu_info_device dev_info = {};
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (r != AMDSMI_STATUS_SUCCESS)
return r;
amdsmi_status_t status;
if (gpu_device->check_if_drm_is_supported()){
status = gpu_device->amdgpu_query_info(AMDGPU_INFO_DEV_INFO, sizeof(struct drm_amdgpu_info_device), &dev_info);
if (status != AMDSMI_STATUS_SUCCESS) return status;
SMIGPUDEVICE_MUTEX(gpu_device->get_mutex())
info->device_id = dev_info.device_id;
info->rev_id = dev_info.pci_rev;
info->vendor_id = gpu_device->get_vendor_id();
info->ids_flags = dev_info.ids_flags;
}
else {
return AMDSMI_STATUS_DRM_ERROR;
}
return AMDSMI_STATUS_SUCCESS;
}
#ifdef ENABLE_ESMI_LIB
static amdsmi_status_t amdsmi_errno_to_esmi_status(amdsmi_status_t status)
{