The CPUID instruction is catched by hypervisor which can return
a flag indicating one is running, and its name.

Suggested-by: Stephen Hemminger <sthem...@microsoft.com>
Signed-off-by: Thomas Monjalon <tho...@monjalon.net>
---
warning: to be tested
---
 lib/librte_eal/common/arch/arm/rte_cpuflags.c      |  6 +++++
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   |  6 +++++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c      | 30 ++++++++++++++++++++++
 .../common/include/arch/x86/rte_cpuflags.h         |  1 +
 .../common/include/generic/rte_cpuflags.h          | 14 ++++++++++
 lib/librte_eal/rte_eal_version.map                 |  9 ++++++-
 6 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c 
b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
index 88f1cbe37..f1f0cb51d 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -178,3 +178,9 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
                return NULL;
        return rte_cpu_feature_table[feature].name;
 }
+
+enum rte_hypervisor
+rte_hypervisor_get_name(void)
+{
+       return RTE_HYPERVISOR_UNKNOWN;
+}
diff --git a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c 
b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
index 970a61c5e..b905cbd2c 100644
--- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
@@ -146,3 +146,9 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
                return NULL;
        return rte_cpu_feature_table[feature].name;
 }
+
+enum rte_hypervisor
+rte_hypervisor_get_name(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 7d4a0fefb..76893b8f1 100644
--- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
@@ -34,6 +34,7 @@
 #include "rte_cpuflags.h"
 
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 #include <stdint.h>
 #include <cpuid.h>
@@ -92,6 +93,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)
@@ -194,3 +196,31 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
                return NULL;
        return rte_cpu_feature_table[feature].name;
 }
+
+/* See http://lwn.net/Articles/301888/ */
+#define HYPERVISOR_INFO_LEAF 0x40000000
+
+enum rte_hypervisor
+rte_hypervisor_get_name(void)
+{
+       cpuid_registers_t regs;
+       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 (int reg = 1; reg < 4; reg++)
+               memcpy(name + (reg - 1) * 4, &regs[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/include/arch/x86/rte_cpuflags.h 
b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
index 26204fabb..686ac07f3 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h
@@ -69,6 +69,7 @@ enum rte_cpu_flag_t {
        RTE_CPUFLAG_AVX,                    /**< AVX */
        RTE_CPUFLAG_F16C,                   /**< F16C */
        RTE_CPUFLAG_RDRAND,                 /**< RDRAND */
+       RTE_CPUFLAG_HYPERVISOR,             /**< Running on a hypervisor */
 
        /* (EAX 01h) EDX features */
        RTE_CPUFLAG_FPU,                    /**< FPU */
diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h 
b/lib/librte_eal/common/include/generic/rte_cpuflags.h
index c1c5551fc..3832fb851 100644
--- a/lib/librte_eal/common/include/generic/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h
@@ -93,4 +93,18 @@ rte_cpu_check_supported(void);
 int
 rte_cpu_is_supported(void);
 
+enum rte_hypervisor {
+       RTE_HYPERVISOR_NONE,
+       RTE_HYPERVISOR_KVM,
+       RTE_HYPERVISOR_HYPERV,
+       RTE_HYPERVISOR_VMWARE,
+       RTE_HYPERVISOR_UNKNOWN
+};
+
+/**
+ * Get the type of hypervisor it is running on.
+ */
+enum rte_hypervisor
+rte_hypervisor_get_name(void);
+
 #endif /* _RTE_CPUFLAGS_H_ */
diff --git a/lib/librte_eal/rte_eal_version.map 
b/lib/librte_eal/rte_eal_version.map
index f4f46c1be..3f8d81577 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -200,6 +200,13 @@ DPDK_17.11 {
 
 } DPDK_17.08;
 
+DPDK_18.02 {
+       global:
+
+       rte_hypervisor_get_name;
+
+} DPDK_17.11;
+
 EXPERIMENTAL {
        global:
 
@@ -235,4 +242,4 @@ EXPERIMENTAL {
        rte_service_set_stats_enable;
        rte_service_start_with_defaults;
 
-} DPDK_17.11;
+} DPDK_18.02;
-- 
2.15.0

Reply via email to