From 8f40ee0734c82fa10b5fa62176211ed1c5f71886 Mon Sep 17 00:00:00 2001 From: Thomas Monjalon Date: Thu, 30 Nov 2017 22:27:01 +0100 Subject: [PATCH] eal/x86: get hypervisor name The CPUID instruction is caught by hypervisor which can return a flag indicating one is running, and its name. Suggested-by: Stephen Hemminger Signed-off-by: Thomas Monjalon Acked-by: Jerin Jacob --- lib/librte_eal/bsdapp/eal/Makefile | 2 + lib/librte_eal/common/Makefile | 2 +- .../common/arch/arm/rte_hypervisor.c | 11 +++++ .../common/arch/ppc_64/rte_hypervisor.c | 11 +++++ lib/librte_eal/common/arch/x86/rte_cpuflags.c | 11 +---- lib/librte_eal/common/arch/x86/rte_cpuid.h | 19 +++++++++ .../common/arch/x86/rte_hypervisor.c | 40 +++++++++++++++++++ lib/librte_eal/common/eal_common_hypervisor.c | 22 ++++++++++ .../common/include/arch/x86/rte_cpuflags.h | 1 + .../common/include/rte_hypervisor.h | 33 +++++++++++++++ lib/librte_eal/linuxapp/eal/Makefile | 2 + lib/librte_eal/rte_eal_version.map | 10 ++++- 12 files changed, 153 insertions(+), 11 deletions(-) create mode 100644 lib/librte_eal/common/arch/arm/rte_hypervisor.c create mode 100644 lib/librte_eal/common/arch/ppc_64/rte_hypervisor.c create mode 100644 lib/librte_eal/common/arch/x86/rte_cpuid.h create mode 100644 lib/librte_eal/common/arch/x86/rte_hypervisor.c create mode 100644 lib/librte_eal/common/eal_common_hypervisor.c create mode 100644 lib/librte_eal/common/include/rte_hypervisor.h diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile index 3c3407b783..c6940760f9 100644 --- a/lib/librte_eal/bsdapp/eal/Makefile +++ b/lib/librte_eal/bsdapp/eal/Makefile @@ -43,6 +43,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_cpuflags.c +SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_hypervisor.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_string_fns.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_hexdump.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_devargs.c @@ -59,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_service.c # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_cpuflags.c +SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_hypervisor.c SRCS-$(CONFIG_RTE_ARCH_X86) += rte_spinlock.c SRCS-y += rte_cycles.c diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index f37b9d866b..a0eaeed78d 100644 --- a/lib/librte_eal/common/Makefile +++ b/lib/librte_eal/common/Makefile @@ -15,7 +15,7 @@ INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h INC += rte_malloc.h rte_keepalive.h rte_time.h INC += rte_service.h rte_service_component.h -INC += rte_bitmap.h rte_vfio.h +INC += rte_bitmap.h rte_vfio.h rte_hypervisor.h GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h diff --git a/lib/librte_eal/common/arch/arm/rte_hypervisor.c b/lib/librte_eal/common/arch/arm/rte_hypervisor.c new file mode 100644 index 0000000000..3792fe2ce7 --- /dev/null +++ b/lib/librte_eal/common/arch/arm/rte_hypervisor.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 Mellanox Technologies, Ltd. + */ + +#include "rte_hypervisor.h" + +enum rte_hypervisor +rte_hypervisor_get(void) +{ + return RTE_HYPERVISOR_UNKNOWN; +} diff --git a/lib/librte_eal/common/arch/ppc_64/rte_hypervisor.c b/lib/librte_eal/common/arch/ppc_64/rte_hypervisor.c new file mode 100644 index 0000000000..3792fe2ce7 --- /dev/null +++ b/lib/librte_eal/common/arch/ppc_64/rte_hypervisor.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 Mellanox Technologies, Ltd. + */ + +#include "rte_hypervisor.h" + +enum rte_hypervisor +rte_hypervisor_get(void) +{ + return RTE_HYPERVISOR_UNKNOWN; +} diff --git a/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/lib/librte_eal/common/arch/x86/rte_cpuflags.c index 2df58a917d..053612d6f1 100644 --- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c +++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c @@ -7,16 +7,8 @@ #include #include #include -#include -enum cpu_register_t { - RTE_REG_EAX = 0, - RTE_REG_EBX, - RTE_REG_ECX, - RTE_REG_EDX, -}; - -typedef uint32_t cpuid_registers_t[4]; +#include "rte_cpuid.h" /** * Struct to hold a processor feature entry @@ -63,6 +55,7 @@ const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(AVX, 0x00000001, 0, RTE_REG_ECX, 28) FEAT_DEF(F16C, 0x00000001, 0, RTE_REG_ECX, 29) FEAT_DEF(RDRAND, 0x00000001, 0, RTE_REG_ECX, 30) + FEAT_DEF(HYPERVISOR, 0x00000001, 0, RTE_REG_ECX, 31) FEAT_DEF(FPU, 0x00000001, 0, RTE_REG_EDX, 0) FEAT_DEF(VME, 0x00000001, 0, RTE_REG_EDX, 1) diff --git a/lib/librte_eal/common/arch/x86/rte_cpuid.h b/lib/librte_eal/common/arch/x86/rte_cpuid.h new file mode 100644 index 0000000000..b773ad9312 --- /dev/null +++ b/lib/librte_eal/common/arch/x86/rte_cpuid.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation + */ + +#ifndef RTE_CPUID_H +#define RTE_CPUID_H + +#include + +enum cpu_register_t { + RTE_REG_EAX = 0, + RTE_REG_EBX, + RTE_REG_ECX, + RTE_REG_EDX, +}; + +typedef uint32_t cpuid_registers_t[4]; + +#endif /* RTE_CPUID_H */ diff --git a/lib/librte_eal/common/arch/x86/rte_hypervisor.c b/lib/librte_eal/common/arch/x86/rte_hypervisor.c new file mode 100644 index 0000000000..edf07be188 --- /dev/null +++ b/lib/librte_eal/common/arch/x86/rte_hypervisor.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 Mellanox Technologies, Ltd. + */ + +#include "rte_hypervisor.h" + +#include +#include + +#include "rte_cpuflags.h" +#include "rte_cpuid.h" + +/* See http://lwn.net/Articles/301888/ */ +#define HYPERVISOR_INFO_LEAF 0x40000000 + +enum rte_hypervisor +rte_hypervisor_get(void) +{ + cpuid_registers_t regs; + int reg; + char name[13]; + + if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_HYPERVISOR)) + return RTE_HYPERVISOR_NONE; + + __cpuid(HYPERVISOR_INFO_LEAF, + regs[RTE_REG_EAX], regs[RTE_REG_EBX], + regs[RTE_REG_ECX], regs[RTE_REG_EDX]); + for (reg = 1; reg < 4; reg++) + memcpy(name + (reg - 1) * 4, ®s[reg], 4); + name[12] = '\0'; + + if (strcmp("KVMKVMKVM", name) == 0) + return RTE_HYPERVISOR_KVM; + if (strcmp("Microsoft Hv", name) == 0) + return RTE_HYPERVISOR_HYPERV; + if (strcmp("VMwareVMware", name) == 0) + return RTE_HYPERVISOR_VMWARE; + return RTE_HYPERVISOR_UNKNOWN; +} diff --git a/lib/librte_eal/common/eal_common_hypervisor.c b/lib/librte_eal/common/eal_common_hypervisor.c new file mode 100644 index 0000000000..c3b4c621b9 --- /dev/null +++ b/lib/librte_eal/common/eal_common_hypervisor.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 Mellanox Technologies, Ltd. + */ + +#include "rte_hypervisor.h" + +const char * +rte_hypervisor_get_name(enum rte_hypervisor id) +{ + switch (id) { + case RTE_HYPERVISOR_NONE: + return "none"; + case RTE_HYPERVISOR_KVM: + return "KVM"; + case RTE_HYPERVISOR_HYPERV: + return "Hyper-V"; + case RTE_HYPERVISOR_VMWARE: + return "VMware"; + default: + return "unknown"; + } +} diff --git a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h index eb0bdf4800..8315f6b694 100644 --- a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h +++ b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h @@ -40,6 +40,7 @@ enum rte_cpu_flag_t { RTE_CPUFLAG_AVX, /**< AVX */ RTE_CPUFLAG_F16C, /**< F16C */ RTE_CPUFLAG_RDRAND, /**< RDRAND */ + RTE_CPUFLAG_HYPERVISOR, /**< Running in a VM */ /* (EAX 01h) EDX features */ RTE_CPUFLAG_FPU, /**< FPU */ diff --git a/lib/librte_eal/common/include/rte_hypervisor.h b/lib/librte_eal/common/include/rte_hypervisor.h new file mode 100644 index 0000000000..8d8aac7441 --- /dev/null +++ b/lib/librte_eal/common/include/rte_hypervisor.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 Mellanox Technologies, Ltd. + */ + +#ifndef RTE_HYPERVISOR_H +#define RTE_HYPERVISOR_H + +/** + * @file + * Hypervisor awareness. + */ + +enum rte_hypervisor { + RTE_HYPERVISOR_NONE, + RTE_HYPERVISOR_KVM, + RTE_HYPERVISOR_HYPERV, + RTE_HYPERVISOR_VMWARE, + RTE_HYPERVISOR_UNKNOWN +}; + +/** + * Get the id of hypervisor it is running on. + */ +enum rte_hypervisor +rte_hypervisor_get(void); + +/** + * Get the name of a given hypervisor id. + */ +const char * +rte_hypervisor_get_name(enum rte_hypervisor id); + +#endif /* RTE_HYPERVISOR_H */ diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile index 588c0bdfb0..7bf278f3bf 100644 --- a/lib/librte_eal/linuxapp/eal/Makefile +++ b/lib/librte_eal/linuxapp/eal/Makefile @@ -50,6 +50,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_cpuflags.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_hypervisor.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_string_fns.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_hexdump.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_devargs.c @@ -66,6 +67,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_service.c # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_cpuflags.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_hypervisor.c SRCS-$(CONFIG_RTE_ARCH_X86) += rte_spinlock.c SRCS-y += rte_cycles.c diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index f4f46c1be8..b3dc5a746a 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -200,6 +200,14 @@ DPDK_17.11 { } DPDK_17.08; +DPDK_18.02 { + global: + + rte_hypervisor_get; + rte_hypervisor_get_name; + +} DPDK_17.11; + EXPERIMENTAL { global: @@ -235,4 +243,4 @@ EXPERIMENTAL { rte_service_set_stats_enable; rte_service_start_with_defaults; -} DPDK_17.11; +} DPDK_18.02; -- 2.20.1