diff options
-rw-r--r-- | sys-utils/lscpu.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 36e36c9ef..9af09e90c 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -73,6 +73,7 @@ /* /sys paths */ #define _PATH_SYS_SYSTEM "/sys/devices/system" +#define _PATH_SYS_HYP_FEATURES "/sys/hypervisor/properties/features" #define _PATH_SYS_CPU _PATH_SYS_SYSTEM "/cpu" #define _PATH_SYS_NODE _PATH_SYS_SYSTEM "/node" #define _PATH_PROC_XEN "/proc/xen" @@ -86,6 +87,15 @@ #define _PATH_PROC_DEVICETREE "/proc/device-tree" #define _PATH_DEV_MEM "/dev/mem" +/* Xen Domain feature flag used for /sys/hypervisor/properties/features */ +#define XENFEAT_supervisor_mode_kernel 3 +#define XENFEAT_mmu_pt_update_preserve_ad 5 +#define XENFEAT_hvm_callback_vector 8 + +#define XEN_FEATURES_PV_MASK (1U << XENFEAT_mmu_pt_update_preserve_ad) +#define XEN_FEATURES_PVH_MASK ( (1U << XENFEAT_supervisor_mode_kernel) \ + | (1U << XENFEAT_hvm_callback_vector) ) + /* virtualization types */ enum { VIRT_NONE = 0, @@ -811,10 +821,28 @@ read_hypervisor(struct lscpu_desc *desc, struct lscpu_modifier *mod) desc->hyper = HYPER_VMWARE; } - if (desc->hyper) + if (desc->hyper) { desc->virtype = VIRT_FULL; - else if (read_hypervisor_powerpc(desc) > 0) {} + if (desc->hyper == HYPER_XEN && path_exist(_PATH_SYS_HYP_FEATURES)) { + uint32_t features; + + fd = path_fopen("r", 0, _PATH_SYS_HYP_FEATURES); + if (fd && fscanf(fd, "%x", &features) == 1) { + /* Xen PV domain */ + if (features & XEN_FEATURES_PV_MASK) + desc->virtype = VIRT_PARA; + /* Xen PVH domain */ + else if ((features & XEN_FEATURES_PVH_MASK) + == XEN_FEATURES_PVH_MASK) + desc->virtype = VIRT_PARA; + fclose(fd); + } else { + err(EXIT_FAILURE, _("failed to read from: %s"), + _PATH_SYS_HYP_FEATURES); + } + } + } else if (read_hypervisor_powerpc(desc) > 0) {} /* Xen para-virt or dom0 */ else if (path_exist(_PATH_PROC_XEN)) { |