>>> On 9/30/2008 at 7:55 PM, in message <20080930235521.GG7835@xxxxxxxxxxx>, Karel Zak <kzak@xxxxxxxxxx> wrote: > On Mon, Sep 29, 2008 at 11:01:05PM +0200, Karel Zak wrote: >> On Mon, Sep 29, 2008 at 03:17:28PM +0200, Matthias Koenig wrote: >> > The tool has been written by Ky Srinivasan <ksrinivasan@xxxxxxxxxx>. >> >> Do we really need a new tool? IMHO the hypervisor Vendor ID should >> be exported by kernel in /sys or /proc -- or we can add this info to >> lscpu(1) or so. > > The (untested) patch below introduces a new fields "Hypervisor vendor > ID:" and "Para-Virtualized:" in lscpu(1). > > The "Hypervisor vendor ID:" field reports the raw ID, it means it works > for all hypervisors (the same logic like CPU "Vendor ID:"). > > I think this solution is a good compromise to avoid a new tool. > > (Note that lscpu(1) does not support XEN dom0 now. This problem will > be resolved ASAP.) > > Comments? Looks good. K. Y > > Karel > > From 5a8e8f8b28eb6ea4bdce27ed6629dfb4fb1665b5 Mon Sep 17 00:00:00 2001 > From: Karel Zak <kzak@xxxxxxxxxx> > Date: Wed, 1 Oct 2008 01:29:32 +0200 > Subject: [PATCH] lscpu: add Hypervisor vendor ID > > Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> > --- > sys-utils/lscpu.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 files changed, 101 insertions(+), 5 deletions(-) > > diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c > index d6bb8b9..5f39ced 100644 > --- a/sys-utils/lscpu.c > +++ b/sys-utils/lscpu.c > @@ -38,7 +38,8 @@ > /* /sys paths */ > #define _PATH_SYS_SYSTEM "sys/devices/system" > #define _PATH_SYS_CPU0 _PATH_SYS_SYSTEM "/cpu/cpu0" > -#define _PATH_PROC_XENCAP "proc/xen/capabilities" > +#define _PATH_PROC_XEN "proc/xen" > +#define _PATH_PROC_XENCAP _PATH_PROC_XEN "/capabilities" > #define _PATH_PROC_CPUINFO "proc/cpuinfo" > > int have_topology; > @@ -67,6 +68,9 @@ struct cpu_desc { > char *vendor; > char *family; > char *model; > + char *virtflag; /* virtualization flag (vmx, svm) */ > + char *hvid; /* hypervisor vendor ID */ > + int is_para; /* is paravirtualized ? */ > > /* caches */ > struct ca_desc cache[CACHE_MAX]; > @@ -246,9 +250,94 @@ read_basicinfo(struct cpu_desc *cpu) > else > continue; > } > + > + if (cpu->flags) { > + snprintf(buf, sizeof(buf), " %s ", cpu->flags); > + if (strstr(buf, " svm ")) > + cpu->virtflag = strdup("svm"); > + else if (strstr(buf, " vmx ")) > + cpu->virtflag = strdup("vmx"); > + } > + > fclose(fp); > } > > +#if defined(__x86_64__) || defined(__i386__) > + > +/* > + * This CPUID leaf returns the information about the hypervisor. > + * EAX : maximum input value for CPUID supported by the hypervisor. > + * EBX, ECX, EDX : Hypervisor vendor ID signature. E.g. VMwareVMware. > + */ > +#define HYPERVISOR_INFO_LEAF 0x40000000 > + > +static inline void > +cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, > + unsigned int *ecx, unsigned int *edx) > +{ > + __asm__("cpuid" > + : "=a" (*eax), > + "=b" (*ebx), > + "=c" (*ecx), > + "=d" (*edx) > + : "0" (op), "c"(0)); > +} > + > +static void > +read_hypervisor_cpuid(struct cpu_desc *cpu) > +{ > + unsigned int eax, ebx, ecx, edx; > + char hyper_vendor_id[13]; > + > + memset(hyper_vendor_id, 0, sizeof(hyper_vendor_id)); > + > + cpuid(HYPERVISOR_INFO_LEAF, &eax, &ebx, &ecx, &edx); > + memcpy(hyper_vendor_id + 0, &ebx, 4); > + memcpy(hyper_vendor_id + 4, &ecx, 4); > + memcpy(hyper_vendor_id + 8, &edx, 4); > + hyper_vendor_id[12] = '\0'; > + > + if (hyper_vendor_id[0]) > + cpu->hvid = strdup(hyper_vendor_id); > +} > + > +#else /* ! __x86_64__ */ > +static void > +read_hypervisor_cpuid(struct cpu_desc *cpu) > +{ > +} > +#endif > + > +static void > +read_hypervisor(struct cpu_desc *cpu) > +{ > + read_hypervisor_cpuid(cpu); > + > + if (!cpu->hvid) { > + /* fallback for non-x86 archs */ > + > + if (!access(_PATH_PROC_XEN, F_OK)) > + /* XEN dom0 or domU */ > + cpu->hvid = strdup("Xen"); > + } > + > + if (!cpu->virtflag && cpu->hvid && !strncmp(cpu->hvid, "Xen", 3)) { > + > + FILE *fd = fopen(_PATH_PROC_XENCAP, "r"); > + int dom0 = 0; > + > + if (fd) { > + char buf[256]; > + > + if (fscanf(fd, "%s", buf) == 1 && > + !strcmp(buf, "control_d")) > + dom0 = 1; > + fclose(fd); > + } > + cpu->is_para = !dom0; > + } > +} > + > static void > read_topology(struct cpu_desc *cpu) > { > @@ -344,6 +433,7 @@ check_system(void) > fd = fopen(_PATH_PROC_XENCAP, "r"); > if (fd) { > if (fscanf(fd, "%s", buf) == 1 && !strcmp(buf, "control_d")) > + /* !!!!!!!! TODO */ > errx(EXIT_FAILURE, > _("error: Dom0 Kernel is unsupported.")); > fclose(fd); > @@ -455,13 +545,17 @@ print_readable(struct cpu_desc *cpu) > print_s(_("Stepping:"), cpu->stepping); > if (cpu->mhz) > print_s(_("CPU MHz:"), cpu->mhz); > - if (cpu->flags) { > - snprintf(buf, sizeof(buf), " %s ", cpu->flags); > - if (strstr(buf, " svm ")) > + if (cpu->virtflag) { > + if (!strcmp(cpu->virtflag, "svm")) > print_s(_("Virtualization:"), "AMD-V"); > - else if (strstr(buf, " vmx ")) > + else if (!strcmp(cpu->virtflag, "vmx")) > print_s(_("Virtualization:"), "VT-x"); > } > + if (cpu->hvid) { > + print_s(_("Hypervisor vendor ID:"), cpu->hvid); > + print_s(_("Para-Virtualized:"), > + cpu->is_para ? _("Yes") : _("Not")); > + } > > if (have_cache) { > int i; > @@ -545,6 +639,8 @@ int main(int argc, char *argv[]) > if (have_node) > read_nodes(cpu); > > + read_hypervisor(cpu); > + > /* Show time! */ > if (parsable) > print_parsable(cpu); -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html