From d7bf3a1c0492220ee97da0889d4973594e8f7aad Mon Sep 17 00:00:00 2001 From: PolloLoco Date: Wed, 28 Feb 2024 22:18:14 +0100 Subject: [PATCH] WIP: Add support for 17.0 host driver while keeping backwards compat with 16.x --- src/lib.rs | 34 +++++++++++++++++++--------------- src/nvidia/ctrla081.rs | 14 +++++++++++--- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fce3b37..b055bf5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,7 +121,7 @@ trait VgpuConfigLike { fn adapter_name_unicode(&mut self) -> &mut [u16; 64]; fn short_gpu_name_string(&mut self) -> &mut [u8; 64]; fn licensed_product_name(&mut self) -> &mut [u8; 128]; - fn vgpu_extra_params(&mut self) -> &mut [u8; 1024]; + fn vgpu_extra_params(&mut self) -> &mut [u8]; } macro_rules! impl_trait_fn { @@ -177,7 +177,7 @@ impl VgpuConfigLike for NvA082CtrlCmdHostVgpuDeviceGetVgpuTypeInfoParams { impl_trait_fn!(adapter_name_unicode, [u16; 64]); impl_trait_fn!(short_gpu_name_string, [u8; 64]); impl_trait_fn!(licensed_product_name, [u8; 128]); - impl_trait_fn!(vgpu_extra_params, [u8; 1024]); + impl_trait_fn!(vgpu_extra_params, [u8]); } impl VgpuConfigLike for NvA081CtrlVgpuInfo { @@ -213,7 +213,7 @@ impl VgpuConfigLike for NvA081CtrlVgpuInfo { impl_trait_fn!(adapter_name_unicode, [u16; 64]); impl_trait_fn!(short_gpu_name_string, [u8; 64]); impl_trait_fn!(licensed_product_name, [u8; 128]); - impl_trait_fn!(vgpu_extra_params, [u8; 1024]); + impl_trait_fn!(vgpu_extra_params, [u8]); } #[derive(Deserialize)] @@ -426,19 +426,23 @@ pub unsafe extern "C" fn ioctl(fd: RawFd, request: c_ulong, argp: *mut c_void) - *LAST_MDEV_UUID.lock() = Some(config.mdev_uuid); } - NVA081_CTRL_CMD_VGPU_CONFIG_GET_VGPU_TYPE_INFO - if check_size!( - NVA081_CTRL_CMD_VGPU_CONFIG_GET_VGPU_TYPE_INFO, - NvA081CtrlVgpuConfigGetVgpuTypeInfoParams - ) => - { - let params: &mut NvA081CtrlVgpuConfigGetVgpuTypeInfoParams = - &mut *io_data.params.cast(); - info!("{:#?}", params); + NVA081_CTRL_CMD_VGPU_CONFIG_GET_VGPU_TYPE_INFO => { + // 17.0 driver sends larger struct with size 5096 bytes. Only extra members added at the end, + // nothing in between or changed, so accessing the larger struct is "safe" + if io_data.params_size == 5096 + || check_size!( + NVA081_CTRL_CMD_VGPU_CONFIG_GET_VGPU_TYPE_INFO, + NvA081CtrlVgpuConfigGetVgpuTypeInfoParams + ) + { + let params: &mut NvA081CtrlVgpuConfigGetVgpuTypeInfoParams = + &mut *io_data.params.cast(); + info!("{:#?}", params); - if !handle_profile_override(&mut params.vgpu_type_info) { - error!("Failed to apply profile override"); - return -1; + if !handle_profile_override(&mut params.vgpu_type_info) { + error!("Failed to apply profile override"); + return -1; + } } } NVA082_CTRL_CMD_HOST_VGPU_DEVICE_GET_VGPU_TYPE_INFO diff --git a/src/nvidia/ctrla081.rs b/src/nvidia/ctrla081.rs index 972f960..8eeb07b 100644 --- a/src/nvidia/ctrla081.rs +++ b/src/nvidia/ctrla081.rs @@ -1,5 +1,6 @@ ///! Sourced from https://github.com/NVIDIA/open-gpu-kernel-modules/blob/758b4ee8189c5198504cb1c3c5bc29027a9118a3/src/common/sdk/nvidia/inc/ctrl/ctrla081.h use std::fmt; +use std::mem::size_of; use super::ctrl2080gpu::{NV2080_GPU_MAX_NAME_STRING_LENGTH, NV_GRID_LICENSE_INFO_MAX_LENGTH}; use crate::format::{CStrFormat, HexFormat, HexFormatSlice, WideCharFormat}; @@ -10,6 +11,8 @@ pub const NVA081_VGPU_SIGNATURE_SIZE: usize = 128; pub const NVA081_EXTRA_PARAMETERS_SIZE: usize = 1024; +// pub const NVA081_MAX_VGPU_PER_PGPU: usize = 32; + /// See `NVA081_CTRL_VGPU_CONFIG_INFO` // Set `align(8)` for `NVA081_CTRL_VGPU_CONFIG_GET_VGPU_TYPE_INFO_PARAMS` #[repr(C, align(8))] @@ -43,7 +46,8 @@ pub struct NvA081CtrlVgpuInfo { pub adapter_name_unicode: [u16; NV2080_GPU_MAX_NAME_STRING_LENGTH], pub short_gpu_name_string: [u8; NV2080_GPU_MAX_NAME_STRING_LENGTH], pub licensed_product_name: [u8; NV_GRID_LICENSE_INFO_MAX_LENGTH], - pub vgpu_extra_params: [u8; NVA081_EXTRA_PARAMETERS_SIZE], + // this is an array of NvU32 but having it as u8 makes it easier :) + pub vgpu_extra_params: [u8; NVA081_EXTRA_PARAMETERS_SIZE * size_of::()], pub ftrace_enable: u32, pub gpu_direct_supported: u32, pub nvlink_p2p_supported: u32, @@ -51,6 +55,11 @@ pub struct NvA081CtrlVgpuInfo { pub exclusive_type: u32, pub exclusive_size: u32, pub gpu_instance_profile_id: u32, + // R550 adds additional fields, leave them out for now for backwards compat with 16.x + // https://github.com/NVIDIA/open-gpu-kernel-modules/blob/550/src/common/sdk/nvidia/inc/ctrl/ctrla081.h#L122-L124 + // pub placement_size: u32, + // pub placement_count: u32, + // pub placement_ids: [u32; NVA081_MAX_VGPU_PER_PGPU], } pub const NVA081_CTRL_CMD_VGPU_CONFIG_GET_VGPU_TYPE_INFO: u32 = 0xa0810103; @@ -62,7 +71,6 @@ pub const NVA081_CTRL_CMD_VGPU_CONFIG_GET_VGPU_TYPE_INFO: u32 = 0xa0810103; pub struct NvA081CtrlVgpuConfigGetVgpuTypeInfoParams { pub vgpu_type: u32, pub vgpu_type_info: NvA081CtrlVgpuInfo, - unknown_end: [u8; 0xc00], } pub const NVA081_CTRL_CMD_VGPU_CONFIG_GET_MIGRATION_CAP: u32 = 0xa0810112; @@ -154,7 +162,7 @@ mod test { #[test] fn verify_sizes() { - assert_eq!(mem::size_of::(), 0x758); + assert_eq!(mem::size_of::(), 0x1358); assert_eq!( mem::size_of::(), 0x1360