[libvirt] [PATCH v3 09/13] CPU selection infrastructure

Daniel P. Berrange berrange at redhat.com
Wed Dec 16 15:26:56 UTC 2009


On Wed, Dec 16, 2009 at 12:04:06AM +0100, Jiri Denemark wrote:
> diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
> new file mode 100644
> index 0000000..3bb0df3
> --- /dev/null
> +++ b/src/cpu/cpu_x86.c
> +#if HAVE_CPUID
> +static int
> +cpuidSet(uint32_t base, struct cpuX86cpuid **set)
> +{
> +    uint32_t max;
> +    uint32_t i;
> +
> +    asm("cpuid"
> +        : "=a" (max)
> +        : "a" (base));


I'm having trouble with this asm block causing a SEGV on i386

==10392== Invalid read of size 4
==10392==    at 0x404FC50: ??? (in /home/berrange/src/xen/libvirt/src/.libs/libvirt.so.0.7.4)
==10392==    by 0x409199D: x86NodeData (cpu_x86.c:1129)
==10392==    by 0x408F298: cpuNodeData (cpu.c:218)
==10392==    by 0x8093BA9: qemudCapsInitCPU (qemu_conf.c:987)
==10392==    by 0x8093D23: qemudCapsInit (qemu_conf.c:1031)
==10392==    by 0x807DEBC: qemudStartup (qemu_driver.c:1067)
==10392==    by 0x4096F8D: virStateInitialize (libvirt.c:830)
==10392==    by 0x805FB8B: main (libvirtd.c:3149)
==10392==  Address 0x756e666b is not stack'd, malloc'd or (recently) free'd
==10392== 
==10392== 
==10392== Process terminating with default action of signal 11 (SIGSEGV)
==10392==  Access not within mapped region at address 0x756E666B
==10392==    at 0x404FC50: ??? (in /home/berrange/src/xen/libvirt/src/.libs/libvirt.so.0.7.4)
==10392==    by 0x409199D: x86NodeData (cpu_x86.c:1129)
==10392==    by 0x408F298: cpuNodeData (cpu.c:218)
==10392==    by 0x8093BA9: qemudCapsInitCPU (qemu_conf.c:987)
==10392==    by 0x8093D23: qemudCapsInit (qemu_conf.c:1031)
==10392==    by 0x807DEBC: qemudStartup (qemu_driver.c:1067)
==10392==    by 0x4096F8D: virStateInitialize (libvirt.c:830)
==10392==    by 0x805FB8B: main (libvirtd.c:3149)


> +
> +    max -= base;
> +
> +    if (virAllocN(set, sizeof(**set), max + 1) < 0) {
> +        virReportOOMError(NULL);
> +        return -1;
> +    }
> +
> +    for (i = 0; i <= max; i++) {
> +        struct cpuX86cpuid *cpuid = (*set) + i;
> +
> +        cpuid->function = base | i;
> +
> +#if __x86_64__
> +        asm("cpuid"
> +            : "=a" (cpuid->eax),
> +              "=b" (cpuid->ebx),
> +              "=c" (cpuid->ecx),
> +              "=d" (cpuid->edx)
> +            : "a" (cpuid->function));
> +#else
> +        /* we need to avoid direct use of ebx for CPUID output as it is used
> +         * for global offset table on i386 with -fPIC
> +         */
> +        asm("push %%ebx;"
> +            "cpuid;"
> +            "mov %%ebx, %1;"
> +            "pop %%ebx;"
> +            : "=a" (cpuid->eax),
> +              "=r" (cpuid->ebx),
> +              "=c" (cpuid->ecx),
> +              "=d" (cpuid->edx)
> +            : "a" (cpuid->function)
> +            : "cc");
> +#endif
> +    }
> +
> +    return max + 1;
> +}
> +

Regards,
Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list