#linux-kernel #kvm
#linux-ядро #kvm
Вопрос:
Я пытаюсь использовать KVM с QEMU. Мне не хватает многих функций в QEMU (те функции, которые присутствуют в хосте). Я проверил код в QEMU, и он проверяет функции, предоставляемые KVM. Я написал простой код на языке .c, который проверяет, предоставляет ли KVM доступные функции :
#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=%dn", 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 amp;amp; cpuid->nent >= max) {
errx("2 bign");
}
if (r < 0){
errx("problemn");
}
struct kvm_cpuid_entry2 *entry = cpuid_find_entry(cpuid, 0x80000001, 0);
if (entry) {
ret = entry->edx;
}
printf("edx = %xn", ret);
if (ret amp; (1U << 0)) printf(" fpu");
if (ret amp; (1U << 1)) printf(" vme");
if (ret amp; (1U << 2)) printf(" de");
if (ret amp; (1U << 3)) printf(" pse");
if (ret amp; (1U << 4)) printf(" tsc");
if (ret amp; (1U << 5)) printf(" msr");
if (ret amp; (1U << 6)) printf(" pae");
if (ret amp; (1U << 7)) printf(" mce");
if (ret amp; (1U << 8)) printf(" cx8");
if (ret amp; (1U << 9)) printf(" apic");
if (ret amp; (1U << 11)) printf(" syscall");
if (ret amp; (1U << 12)) printf(" mtrr");
if (ret amp; (1U << 13)) printf(" pge");
if (ret amp; (1U << 14)) printf(" mca");
if (ret amp; (1U << 15)) printf(" cmov");
if (ret amp; (1U << 16)) printf(" pat");
if (ret amp; (1U << 17)) printf(" pse36");
if (ret amp; (1U << 18)) printf(" mp");
if (ret amp; (1U << 20)) printf(" nx");
if (ret amp; (1U << 22)) printf(" mmxext");
if (ret amp; (1U << 23)) printf(" mmx");
if (ret amp; (1U << 24)) printf(" fxsr");
if (ret amp; (1U << 25)) printf(" fxsr_opt");
if (ret amp; (1U << 26)) printf(" pdpe1gb");
if (ret amp; (1U << 27)) printf(" rdtscp");
if (ret amp; (1U << 29)) printf(" lm");
if (ret amp; (1U << 30)) printf(" 3dnowext");
if (ret amp; (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 amp;amp;
cpuid->entries[i].index == index) {
return amp;cpuid->entries[i];
}
}
/* not found: */
return NULL;
}
приведенный выше код выводит :
kvm api=12
edx = 28100800
syscall nx rdtscp lm
Если я проверю в командной строке, я получу:
> 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
Очевидно, что многие функции «EAX = 8000000001h: расширенная информация о процессоре и биты функций» отсутствуют (в частности, я ищу pdpe1gb).Я прочитал kvm api, и в нем ничего не упоминается об этом.
использование:
vendor_id: GenuineIntel Семейство процессоров : 6 модель : 85 название модели : Intel (R) Xeon (R) Gold 6130 CPU @ 2.10GHz
использование kvm api 12.
использование ubutnu 18 с ядром 5.4.0-70-generic
Я настроил nested=Y (мой хост также является виртуальной машиной).
- Где я могу найти документ, в котором описывается, что поддерживается KVM, а что нет? может быть, он не поддерживает?
- 26 бит, который я проверяю, был путем изучения кода QEMU. Где я могу найти документы о битах Intel?
- Почему я не получаю бит pdpe1gb, отображаемый в моем примере?
Комментарии:
1. Пожалуйста, добавьте свою версию ядра.
2. На сайте Intel есть большие PDF-файлы для каждого процессора, которые описывают CPUID и другие общедоступные функции.
3. @stark — я не нашел PDF-файл от intel, но я нахожу wiki по адресу en.wikipedia.org/wiki/CPUID