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;
