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).
User contributions licensed under CC BY-SA 3.0