KVM CPUID missing "Extended Processor Info and Feature Bits" features

0

I am trying to use KVM with QEMU. I am missing a lot of features in the QEMU (those features present in the HOST). I checked the code in the QEMU and it check the features exposed by the KVM. I wrote simple .c code that checks if KVM expose available features :

#include <stdio.h>
#include <fcntl.h>
#include <linux/kvm.h>
#include <stdint.h>

static struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid,
                                             uint32_t function,
                                             uint32_t index);
void main(){
    int status, fd, max=64;
    uint32_t ret = 0;
    fd = open("/dev/kvm", O_RDWR | O_CLOEXEC);
    if (fd == -1)
        errx("cannot open /dev/kvm");

    status = ioctl(fd, KVM_GET_API_VERSION,0);
    printf("kvm api=%d\n", status);

    struct kvm_cpuid2 *cpuid;
    int r, size;

    size = sizeof(*cpuid) + max * sizeof(*cpuid->entries);
    cpuid = malloc(size);
    cpuid->nent = max;
    r = ioctl(fd , KVM_GET_SUPPORTED_CPUID, cpuid);
    if (r == 0 && cpuid->nent >= max) {
        errx("2 big\n");
    }
    if (r < 0){
        errx("problem\n");
    }

    struct kvm_cpuid_entry2 *entry = cpuid_find_entry(cpuid, 0x80000001, 0);
    if (entry) {
        ret = entry->edx;
    }
    printf("edx = %x\n", ret);
    if (ret & (1U << 0)) printf(" fpu");
    if (ret & (1U << 1)) printf(" vme");
    if (ret & (1U << 2)) printf(" de");
    if (ret & (1U << 3)) printf(" pse");
    if (ret & (1U << 4)) printf(" tsc");
    if (ret & (1U << 5)) printf(" msr");
    if (ret & (1U << 6)) printf(" pae");
    if (ret & (1U << 7)) printf(" mce");
    if (ret & (1U << 8)) printf(" cx8");
    if (ret & (1U << 9)) printf(" apic");
    if (ret & (1U << 11)) printf(" syscall");
    if (ret & (1U << 12)) printf(" mtrr");
    if (ret & (1U << 13)) printf(" pge");
    if (ret & (1U << 14)) printf(" mca");
    if (ret & (1U << 15)) printf(" cmov");
    if (ret & (1U << 16)) printf(" pat");
    if (ret & (1U << 17)) printf(" pse36");
    if (ret & (1U << 18)) printf(" mp");
    if (ret & (1U << 20)) printf(" nx");
    if (ret & (1U << 22)) printf(" mmxext");
    if (ret & (1U << 23)) printf(" mmx");
    if (ret & (1U << 24)) printf(" fxsr");
    if (ret & (1U << 25)) printf(" fxsr_opt");
    if (ret & (1U << 26)) printf(" pdpe1gb");
    if (ret & (1U << 27)) printf(" rdtscp");
    if (ret & (1U << 29)) printf(" lm");
    if (ret & (1U << 30)) printf(" 3dnowext");
    if (ret & (1U << 31)) printf(" 3dnow");
    printf("\n");
}

static struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid,
                                                 uint32_t function,
                                                 uint32_t index)
{
    int i;
    for (i = 0; i < cpuid->nent; ++i) {
        if (cpuid->entries[i].function == function &&
            cpuid->entries[i].index == index) {
            return &cpuid->entries[i];
        }
    }
    /* not found: */
    return NULL;
}

the above code prints :

kvm api=12
edx = 28100800
 syscall nx rdtscp lm

If I check in the command line I get:

> cat /proc/cpuinfo | grep flags | uniq
flags           : fpu vme de pse tsc msr pae mce 
cx8 apic sep mtrr pge mca cmov pat pse36 clflush 
mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp 
lm constant_tsc arch_perfmon nopl xtopology 
tsc_reliable nonstop_tsc cpuid pni pclmulqdq 
vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe 
popcnt tsc_deadline_timer aes xsave avx f16c 
rdrand hypervisor lahf_lm abm 3dnowprefetch 
cpuid_fault invpcid_single pti ssbd ibrs ibpb 
stibp tpr_shadow vnmi ept vpid ept_ad fsgsbase 
tsc_adjust bmi1 hle avx2 smep bmi2 invpcid rtm mpx 
avx512f avx512dq rdseed adx smap clflushopt clwb 
avx512cd avx512bw avx512vl xsaveopt xsavec xsaves 
arat pku ospke flush_l1d arch_capabilities

Clearly - a lot of feature of the "EAX=80000001h: Extended Processor Info and Feature Bits" are missing (Specifically I am looking for pdpe1gb).I read the kvm api and it doesn't mentioned something about it.

using:

vendor_id : GenuineIntel cpu family : 6 model : 85 model name : Intel(R) Xeon(R) Gold 6130 CPU @ 2.10GHz

using kvm api 12.

using ubutnu 18 with kernel 5.4.0-70-generic

I configured nested=Y (my HOST is a VM as well).

  1. Where can I find the doc the describes what is supported by KVM and what's not ? maybe it doesn't support ?
  2. The 26 bit I am checking was by looking into QEMU code. Where can I find docs about the bits of intel ?
  3. Why I am not getting the pdpe1gb bit exposed in my example?
linux-kernel
kvm
asked on Stack Overflow Mar 31, 2021 by yehudahs • edited Apr 1, 2021 by yehudahs

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0