clear-pkgs-linux-iot-lts2018/0976-Get-vcpu-pcpu-mapping....

321 lines
9.6 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Manisha Chinthapally <manisha.chinthapally@intel.com>
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 <manisha.chinthapally@intel.com>
---
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.
+ *
+ * <I>Special Notes</I>
+ */
+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.
+ *
+ * <I>Special Notes</I>
+ */
+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