From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Manisha Chinthapally Date: Fri, 25 Jan 2019 15:24:05 -0800 Subject: [PATCH] Get vcpu pcpu mapping In virtualization platforms, SEP collects samples from multiple guest OSes, But to associate a sample to the guest we need VCPU-PCPU-OSID mapping info. So, added an IOCTL that allows to get VCPU PCPU mapping information on all the guest OSes Tracked-On: PKT-1717 Signed-off-by: Manisha Chinthapally --- drivers/platform/x86/sepdk/inc/lwpmudrv.h | 6 +- .../x86/sepdk/include/lwpmudrv_ioctl.h | 3 + .../x86/sepdk/include/lwpmudrv_struct.h | 36 +++- drivers/platform/x86/sepdk/sep/lwpmudrv.c | 162 +++++++++++++++++- 4 files changed, 195 insertions(+), 12 deletions(-) diff --git a/drivers/platform/x86/sepdk/inc/lwpmudrv.h b/drivers/platform/x86/sepdk/inc/lwpmudrv.h index 994121d28ef2..ae8a3aee26a1 100644 --- a/drivers/platform/x86/sepdk/inc/lwpmudrv.h +++ b/drivers/platform/x86/sepdk/inc/lwpmudrv.h @@ -454,8 +454,8 @@ int sbuf_share_setup(uint32_t pcpu_id, uint32_t sbuf_id, shared_buf_t *sbuf); extern shared_buf_t **samp_buf_per_cpu; -#define MAX_NR_VCPUS 8 -#define MAX_NR_VMS 4 +#define MAX_NR_VCPUS 4 +#define MAX_NR_VMS 4 #define MAX_MSR_LIST_NUM 15 #define MAX_GROUP_NUM 1 @@ -504,7 +504,7 @@ struct profiling_vm_info { struct profiling_vm_info_list { uint16_t num_vms; - struct profiling_vm_info vm_list[MAX_NR_VMS]; + struct profiling_vm_info vm_list[MAX_NR_VMS+1]; }; struct profiling_version_info { diff --git a/drivers/platform/x86/sepdk/include/lwpmudrv_ioctl.h b/drivers/platform/x86/sepdk/include/lwpmudrv_ioctl.h index 3b60274826c6..9713b19c0e5c 100644 --- a/drivers/platform/x86/sepdk/include/lwpmudrv_ioctl.h +++ b/drivers/platform/x86/sepdk/include/lwpmudrv_ioctl.h @@ -112,6 +112,9 @@ extern "C" { #define DRV_OPERATION_GET_AGENT_MODE 93 #define DRV_OPERATION_INIT_DRIVER 94 #define DRV_OPERATION_SET_EMON_BUFFER_DRIVER_HELPER 95 +#define DRV_OPERATION_GET_NUM_VM 96 +#define DRV_OPERATION_GET_VCPU_MAP 97 + // Only used by MAC OS #define DRV_OPERATION_GET_ASLR_OFFSET 997 // this may not need #define DRV_OPERATION_SET_OSX_VERSION 998 diff --git a/drivers/platform/x86/sepdk/include/lwpmudrv_struct.h b/drivers/platform/x86/sepdk/include/lwpmudrv_struct.h index 3af04d4ed829..629750152fdb 100644 --- a/drivers/platform/x86/sepdk/include/lwpmudrv_struct.h +++ b/drivers/platform/x86/sepdk/include/lwpmudrv_struct.h @@ -1646,14 +1646,14 @@ typedef CPU_MAP_TRACE_NODE * CPU_MAP_TRACE; struct CPU_MAP_TRACE_NODE_S { U64 tsc; U32 os_id; - U16 vcpu_id; - U16 pcpu_id; + U32 vcpu_id; + U32 pcpu_id; U8 is_static : 1; U8 initial : 1; U8 reserved1 : 6; U8 reserved2; U16 reserved3; - U32 reserved4; + U64 tsc_offset; }; #define CPU_MAP_TRACE_tsc(x) ((x)->tsc) @@ -1663,6 +1663,28 @@ struct CPU_MAP_TRACE_NODE_S { #define CPU_MAP_TRACE_is_static(x) ((x)->is_static) #define CPU_MAP_TRACE_initial(x) ((x)->initial) +#define MAX_NUM_VCPU 64 +#define MAX_NUM_VM 16 + +typedef struct CPU_MAP_TRACE_LIST_NODE_S CPU_MAP_TRACE_LIST_NODE; +typedef CPU_MAP_TRACE_LIST_NODE * CPU_MAP_TRACE_LIST; + +struct CPU_MAP_TRACE_LIST_NODE_S { + U32 osid; + U8 num_entries; + U8 reserved1; + U16 reserved2; + CPU_MAP_TRACE_NODE entries[MAX_NUM_VCPU]; +}; + +typedef struct VM_OSID_MAP_NODE_S VM_OSID_MAP_NODE; +typedef VM_OSID_MAP_NODE * VM_OSID_MAP; +struct VM_OSID_MAP_NODE_S { + U32 num_vms; + U32 reserved1; + U32 osid[MAX_NUM_VM]; +}; + typedef struct VM_SWITCH_TRACE_NODE_S VM_SWITCH_TRACE_NODE; typedef VM_SWITCH_TRACE_NODE * VM_SWITCH_TRACE; @@ -1675,10 +1697,10 @@ struct VM_SWITCH_TRACE_NODE_S { U64 reserved2; }; -#define VM_SWITCH_TRACE_tsc(x) ((x)->tsc) -#define VM_SWITCH_TRACE_from_os_id(x) ((x)->from_os_id) -#define VM_SWITCH_TRACE_to_os_id(x) ((x)->to_os_id) -#define VM_SWITCH_TRACE_reason(x) ((x)->reason) +#define VM_SWITCH_TRACE_tsc(x) ((x)->tsc) +#define VM_SWITCH_TRACE_from_os_id(x) ((x)->from_os_id) +#define VM_SWITCH_TRACE_to_os_id(x) ((x)->to_os_id) +#define VM_SWITCH_TRACE_reason(x) ((x)->reason) typedef struct EMON_BUFFER_DRIVER_HELPER_NODE_S EMON_BUFFER_DRIVER_HELPER_NODE; typedef EMON_BUFFER_DRIVER_HELPER_NODE * EMON_BUFFER_DRIVER_HELPER; diff --git a/drivers/platform/x86/sepdk/sep/lwpmudrv.c b/drivers/platform/x86/sepdk/sep/lwpmudrv.c index bb53962d2695..ccc78629b028 100755 --- a/drivers/platform/x86/sepdk/sep/lwpmudrv.c +++ b/drivers/platform/x86/sepdk/sep/lwpmudrv.c @@ -1675,7 +1675,7 @@ static OS_STATUS lwpmudrv_Pause(void) #if !defined(DRV_SEP_ACRN_ON) CONTROL_Invoke_Parallel(lwpmudrv_Pause_Op, NULL); #endif - /* + /* * This means that the PAUSE state has been reached. */ CHANGE_DRIVER_STATE(STATE_BIT_PAUSING, DRV_STATE_PAUSED); @@ -6237,6 +6237,154 @@ static OS_STATUS lwpmudrv_Get_Agent_Mode(IOCTL_ARGS args) return status; } +/* ------------------------------------------------------------------------- */ +/*! + * @fn static OS_STATUS lwpmudrv_Get_Num_Of_Vms(IOCTL_ARGS arg) + * + * @param arg - pointer to the IOCTL_ARGS structure + * + * @return OS_STATUS + * + * @brief Local function to get number of VMS available + * @brief Returns status. + * + * Special Notes + */ +static OS_STATUS lwpmudrv_Get_Num_Of_Vms(IOCTL_ARGS args) + +{ + VM_OSID_MAP_NODE vm_map; +#if defined(DRV_SEP_ACRN_ON) + U32 i; +#endif + if (args->buf_drv_to_usr == NULL) { + SEP_PRINT_ERROR("Invalid arguments (buf_drv_to_usr is NULL)!"); + return OS_INVALID; + } + + if (args->len_drv_to_usr != sizeof(VM_OSID_MAP_NODE)) { + SEP_PRINT_ERROR( + "Invalid arguments (unexpected len_drv_to_usr value)!"); + return OS_INVALID; + } + + memset(&vm_map, 0, sizeof(VM_OSID_MAP_NODE)); + +#if defined(DRV_SEP_ACRN_ON) + if (vm_info_list == NULL) { + vm_info_list = + CONTROL_Allocate_Memory(sizeof(struct profiling_vm_info_list)); + } + memset(vm_info_list, 0, sizeof(struct profiling_vm_info_list)); + + BUG_ON(!virt_addr_valid(vm_info_list)); + + acrn_hypercall2(HC_PROFILING_OPS, PROFILING_GET_VMINFO, + virt_to_phys(vm_info_list)); + + vm_map.num_vms = 0; + for (i = 0; i < vm_info_list->num_vms; i++) { + if (vm_info_list->vm_list[i].num_vcpus != 0) { + vm_map.osid[i] = (U32)vm_info_list->vm_list[i].vm_id; + vm_map.num_vms++; + } + } + +#endif + if (copy_to_user((void __user *)args->buf_drv_to_usr, + &vm_map, args->len_drv_to_usr)) { + SEP_DRV_LOG_ERROR_FLOW_OUT("Memory copy failure!"); + return OS_FAULT; + } + + return OS_SUCCESS; + +} +/* ------------------------------------------------------------------------- */ +/*! + * @fn static OS_STATUS lwpmudrv_Get_Cpu_Map_Info(IOCTL_ARGS arg) + * + * @param arg - pointer to the IOCTL_ARGS structure + * + * @return OS_STATUS + * + * @brief Local function to get pcpu-vcpu mapping info + * @brief Returns status. + * + * Special Notes + */ +static OS_STATUS lwpmudrv_Get_Cpu_Map_Info(IOCTL_ARGS args) +{ + CPU_MAP_TRACE_LIST cpumap; + DRV_STATUS status = OS_SUCCESS; +#if defined(DRV_SEP_ACRN_ON) + U32 i, j; +#endif + + if ((args->buf_drv_to_usr == NULL) || + (args->len_drv_to_usr != sizeof(CPU_MAP_TRACE_LIST_NODE))) { + SEP_PRINT_ERROR("Invalid drv_to_usr arguments!"); + return OS_INVALID; + } + + if ((args->buf_usr_to_drv == NULL) || + (args->len_usr_to_drv != sizeof(CPU_MAP_TRACE_LIST_NODE))) { + SEP_PRINT_ERROR("Invalid usr_to_drv arguments!"); + return OS_INVALID; + } + + cpumap = (CPU_MAP_TRACE_LIST) + CONTROL_Allocate_Memory(sizeof(CPU_MAP_TRACE_LIST_NODE)); + if (cpumap == NULL) { + SEP_DRV_LOG_ERROR_FLOW_OUT("Memory allocation failure"); + return OS_NO_MEM; + } + + if (copy_from_user(cpumap, (void __user *)args->buf_usr_to_drv, + sizeof(CPU_MAP_TRACE_LIST_NODE))) { + SEP_DRV_LOG_ERROR_FLOW_OUT("Memory copy failure"); + status = OS_FAULT; + goto cleanup; + } + +#if defined(DRV_SEP_ACRN_ON) + if (vm_info_list == NULL) { + SEP_DRV_LOG_ERROR_FLOW_OUT("vm_info_list is NULL!"); + status = OS_INVALID; + goto cleanup; + } + + SEP_DRV_LOG_TRACE("CPU mapping for osid %d ", cpumap->osid); + for (i = 0; i < vm_info_list->num_vms; i++) { + if (vm_info_list->vm_list[i].vm_id == cpumap->osid) { + for (j = 0; + j < vm_info_list->vm_list[i].num_vcpus; j++) { + UTILITY_Read_TSC(&(cpumap->entries[j].tsc)); + cpumap->entries[j].is_static = 1; + cpumap->entries[j].vcpu_id = + vm_info_list->vm_list[i].cpu_map[j].vcpu_id; + cpumap->entries[j].pcpu_id = + vm_info_list->vm_list[i].cpu_map[j].pcpu_id; + cpumap->entries[j].os_id = + vm_info_list->vm_list[i].vm_id; + cpumap->num_entries++; + } + } + } +#endif + if (copy_to_user((void __user *)args->buf_drv_to_usr, + cpumap, args->len_drv_to_usr)) { + SEP_DRV_LOG_ERROR_FLOW_OUT("Memory copy failure!"); + status = OS_FAULT; + goto cleanup; + } + +cleanup: + cpumap = CONTROL_Free_Memory(cpumap); + return status; +} + + /******************************************************************************* * External Driver functions - Open * This function is common to all drivers @@ -6358,7 +6506,7 @@ static IOCTL_OP_TYPE lwpmu_Service_IOCTL(IOCTL_USE_INODE struct file *filp, UTILITY_Driver_Set_Active_Ioctl(cmd); switch (cmd) { - /* + /* * Common IOCTL commands */ @@ -6529,6 +6677,16 @@ static IOCTL_OP_TYPE lwpmu_Service_IOCTL(IOCTL_USE_INODE struct file *filp, status = lwpmudrv_Get_Agent_Mode(&local_args); break; + case DRV_OPERATION_GET_VCPU_MAP: + SEP_DRV_LOG_TRACE("DRV_OPERATION_GET_CPU_MAP\n"); + status = lwpmudrv_Get_Cpu_Map_Info(&local_args); + break; + + case DRV_OPERATION_GET_NUM_VM: + SEP_DRV_LOG_TRACE("DRV_OPERATION_GET_NUM_VM\n"); + status = lwpmudrv_Get_Num_Of_Vms(&local_args); + break; + /* * EMON-specific IOCTL commands */ -- https://clearlinux.org