Revision 94a8d39a
b/configure | ||
---|---|---|
1662 | 1662 |
#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12 |
1663 | 1663 |
#error Invalid KVM version |
1664 | 1664 |
#endif |
1665 |
#if !defined(KVM_CAP_USER_MEMORY) |
|
1666 |
#error Missing KVM capability KVM_CAP_USER_MEMORY |
|
1667 |
#endif |
|
1668 |
#if !defined(KVM_CAP_SET_TSS_ADDR) |
|
1669 |
#error Missing KVM capability KVM_CAP_SET_TSS_ADDR |
|
1670 |
#endif |
|
1671 |
#if !defined(KVM_CAP_DESTROY_MEMORY_REGION_WORKS) |
|
1672 |
#error Missing KVM capability KVM_CAP_DESTROY_MEMORY_REGION_WORKS |
|
1673 |
#endif |
|
1674 |
#if !defined(KVM_CAP_USER_NMI) |
|
1675 |
#error Missing KVM capability KVM_CAP_USER_NMI |
|
1665 |
EOF |
|
1666 |
must_have_caps="KVM_CAP_USER_MEMORY \ |
|
1667 |
KVM_CAP_DESTROY_MEMORY_REGION_WORKS \ |
|
1668 |
KVM_CAP_COALESCED_MMIO \ |
|
1669 |
KVM_CAP_SYNC_MMU \ |
|
1670 |
" |
|
1671 |
if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) ; then |
|
1672 |
must_have_caps="$caps \ |
|
1673 |
KVM_CAP_SET_TSS_ADDR \ |
|
1674 |
KVM_CAP_EXT_CPUID \ |
|
1675 |
KVM_CAP_CLOCKSOURCE \ |
|
1676 |
KVM_CAP_NOP_IO_DELAY \ |
|
1677 |
KVM_CAP_PV_MMU \ |
|
1678 |
KVM_CAP_MP_STATE \ |
|
1679 |
KVM_CAP_USER_NMI \ |
|
1680 |
" |
|
1681 |
fi |
|
1682 |
for c in $must_have_caps ; do |
|
1683 |
cat >> $TMPC <<EOF |
|
1684 |
#if !defined($c) |
|
1685 |
#error Missing KVM capability $c |
|
1676 | 1686 |
#endif |
1687 |
EOF |
|
1688 |
done |
|
1689 |
cat >> $TMPC <<EOF |
|
1677 | 1690 |
int main(void) { return 0; } |
1678 | 1691 |
EOF |
1679 | 1692 |
if test "$kerneldir" != "" ; then |
... | ... | |
1708 | 1721 |
| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'` |
1709 | 1722 |
if test "$kvmerr" != "" ; then |
1710 | 1723 |
echo -e "${kvmerr}\n\ |
1711 |
NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
|
|
1712 |
recent kvm-kmod from http://sourceforge.net/projects/kvm."
|
|
1724 |
NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \ |
|
1725 |
recent kvm-kmod from http://sourceforge.net/projects/kvm." |
|
1713 | 1726 |
fi |
1714 | 1727 |
fi |
1715 | 1728 |
feature_not_found "kvm" |
b/kvm-all.c | ||
---|---|---|
63 | 63 |
int fd; |
64 | 64 |
int vmfd; |
65 | 65 |
int coalesced_mmio; |
66 |
#ifdef KVM_CAP_COALESCED_MMIO |
|
67 | 66 |
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; |
68 |
#endif |
|
69 | 67 |
int broken_set_mem_region; |
70 | 68 |
int migration_log; |
71 | 69 |
int vcpu_events; |
... | ... | |
82 | 80 |
|
83 | 81 |
static KVMState *kvm_state; |
84 | 82 |
|
83 |
static const KVMCapabilityInfo kvm_required_capabilites[] = { |
|
84 |
KVM_CAP_INFO(USER_MEMORY), |
|
85 |
KVM_CAP_INFO(DESTROY_MEMORY_REGION_WORKS), |
|
86 |
KVM_CAP_LAST_INFO |
|
87 |
}; |
|
88 |
|
|
85 | 89 |
static KVMSlot *kvm_alloc_slot(KVMState *s) |
86 | 90 |
{ |
87 | 91 |
int i; |
... | ... | |
227 | 231 |
goto err; |
228 | 232 |
} |
229 | 233 |
|
230 |
#ifdef KVM_CAP_COALESCED_MMIO |
|
231 | 234 |
if (s->coalesced_mmio && !s->coalesced_mmio_ring) { |
232 | 235 |
s->coalesced_mmio_ring = |
233 | 236 |
(void *)env->kvm_run + s->coalesced_mmio * PAGE_SIZE; |
234 | 237 |
} |
235 |
#endif |
|
236 | 238 |
|
237 | 239 |
ret = kvm_arch_init_vcpu(env); |
238 | 240 |
if (ret == 0) { |
... | ... | |
401 | 403 |
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) |
402 | 404 |
{ |
403 | 405 |
int ret = -ENOSYS; |
404 |
#ifdef KVM_CAP_COALESCED_MMIO |
|
405 | 406 |
KVMState *s = kvm_state; |
406 | 407 |
|
407 | 408 |
if (s->coalesced_mmio) { |
... | ... | |
412 | 413 |
|
413 | 414 |
ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone); |
414 | 415 |
} |
415 |
#endif |
|
416 | 416 |
|
417 | 417 |
return ret; |
418 | 418 |
} |
... | ... | |
420 | 420 |
int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) |
421 | 421 |
{ |
422 | 422 |
int ret = -ENOSYS; |
423 |
#ifdef KVM_CAP_COALESCED_MMIO |
|
424 | 423 |
KVMState *s = kvm_state; |
425 | 424 |
|
426 | 425 |
if (s->coalesced_mmio) { |
... | ... | |
431 | 430 |
|
432 | 431 |
ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone); |
433 | 432 |
} |
434 |
#endif |
|
435 | 433 |
|
436 | 434 |
return ret; |
437 | 435 |
} |
... | ... | |
481 | 479 |
#endif |
482 | 480 |
} |
483 | 481 |
|
482 |
static const KVMCapabilityInfo * |
|
483 |
kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list) |
|
484 |
{ |
|
485 |
while (list->name) { |
|
486 |
if (!kvm_check_extension(s, list->value)) { |
|
487 |
return list; |
|
488 |
} |
|
489 |
list++; |
|
490 |
} |
|
491 |
return NULL; |
|
492 |
} |
|
493 |
|
|
484 | 494 |
static void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size, |
485 | 495 |
ram_addr_t phys_offset) |
486 | 496 |
{ |
... | ... | |
642 | 652 |
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n" |
643 | 653 |
"(see http://sourceforge.net/projects/kvm).\n"; |
644 | 654 |
KVMState *s; |
655 |
const KVMCapabilityInfo *missing_cap; |
|
645 | 656 |
int ret; |
646 | 657 |
int i; |
647 | 658 |
|
... | ... | |
685 | 696 |
goto err; |
686 | 697 |
} |
687 | 698 |
|
688 |
/* initially, KVM allocated its own memory and we had to jump through |
|
689 |
* hooks to make phys_ram_base point to this. Modern versions of KVM |
|
690 |
* just use a user allocated buffer so we can use regular pages |
|
691 |
* unmodified. Make sure we have a sufficiently modern version of KVM. |
|
692 |
*/ |
|
693 |
if (!kvm_check_extension(s, KVM_CAP_USER_MEMORY)) { |
|
694 |
ret = -EINVAL; |
|
695 |
fprintf(stderr, "kvm does not support KVM_CAP_USER_MEMORY\n%s", |
|
696 |
upgrade_note); |
|
697 |
goto err; |
|
699 |
missing_cap = kvm_check_extension_list(s, kvm_required_capabilites); |
|
700 |
if (!missing_cap) { |
|
701 |
missing_cap = |
|
702 |
kvm_check_extension_list(s, kvm_arch_required_capabilities); |
|
698 | 703 |
} |
699 |
|
|
700 |
/* There was a nasty bug in < kvm-80 that prevents memory slots from being |
|
701 |
* destroyed properly. Since we rely on this capability, refuse to work |
|
702 |
* with any kernel without this capability. */ |
|
703 |
if (!kvm_check_extension(s, KVM_CAP_DESTROY_MEMORY_REGION_WORKS)) { |
|
704 |
if (missing_cap) { |
|
704 | 705 |
ret = -EINVAL; |
705 |
|
|
706 |
fprintf(stderr, |
|
707 |
"KVM kernel module broken (DESTROY_MEMORY_REGION).\n%s", |
|
708 |
upgrade_note); |
|
706 |
fprintf(stderr, "kvm does not support %s\n%s", |
|
707 |
missing_cap->name, upgrade_note); |
|
709 | 708 |
goto err; |
710 | 709 |
} |
711 | 710 |
|
712 |
s->coalesced_mmio = 0; |
|
713 |
#ifdef KVM_CAP_COALESCED_MMIO |
|
714 | 711 |
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); |
715 |
s->coalesced_mmio_ring = NULL; |
|
716 |
#endif |
|
717 | 712 |
|
718 | 713 |
s->broken_set_mem_region = 1; |
719 | 714 |
#ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS |
... | ... | |
845 | 840 |
|
846 | 841 |
void kvm_flush_coalesced_mmio_buffer(void) |
847 | 842 |
{ |
848 |
#ifdef KVM_CAP_COALESCED_MMIO |
|
849 | 843 |
KVMState *s = kvm_state; |
850 | 844 |
if (s->coalesced_mmio_ring) { |
851 | 845 |
struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring; |
... | ... | |
859 | 853 |
ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX; |
860 | 854 |
} |
861 | 855 |
} |
862 |
#endif |
|
863 | 856 |
} |
864 | 857 |
|
865 | 858 |
static void do_kvm_cpu_synchronize_state(void *_env) |
... | ... | |
1059 | 1052 |
|
1060 | 1053 |
int kvm_has_sync_mmu(void) |
1061 | 1054 |
{ |
1062 |
#ifdef KVM_CAP_SYNC_MMU |
|
1063 |
KVMState *s = kvm_state; |
|
1064 |
|
|
1065 |
return kvm_check_extension(s, KVM_CAP_SYNC_MMU); |
|
1066 |
#else |
|
1067 |
return 0; |
|
1068 |
#endif |
|
1055 |
return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); |
|
1069 | 1056 |
} |
1070 | 1057 |
|
1071 | 1058 |
int kvm_has_vcpu_events(void) |
b/kvm.h | ||
---|---|---|
32 | 32 |
|
33 | 33 |
struct kvm_run; |
34 | 34 |
|
35 |
typedef struct KVMCapabilityInfo { |
|
36 |
const char *name; |
|
37 |
int value; |
|
38 |
} KVMCapabilityInfo; |
|
39 |
|
|
40 |
#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP } |
|
41 |
#define KVM_CAP_LAST_INFO { NULL, 0 } |
|
42 |
|
|
35 | 43 |
/* external API */ |
36 | 44 |
|
37 | 45 |
int kvm_init(void); |
... | ... | |
86 | 94 |
|
87 | 95 |
/* Arch specific hooks */ |
88 | 96 |
|
97 |
extern const KVMCapabilityInfo kvm_arch_required_capabilities[]; |
|
98 |
|
|
89 | 99 |
int kvm_arch_post_run(CPUState *env, struct kvm_run *run); |
90 | 100 |
|
91 | 101 |
int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run); |
b/target-i386/kvm.c | ||
---|---|---|
54 | 54 |
#define BUS_MCEERR_AO 5 |
55 | 55 |
#endif |
56 | 56 |
|
57 |
const KVMCapabilityInfo kvm_arch_required_capabilities[] = { |
|
58 |
KVM_CAP_INFO(SET_TSS_ADDR), |
|
59 |
KVM_CAP_INFO(EXT_CPUID), |
|
60 |
KVM_CAP_INFO(MP_STATE), |
|
61 |
KVM_CAP_LAST_INFO |
|
62 |
}; |
|
63 |
|
|
57 | 64 |
static bool has_msr_star; |
58 | 65 |
static bool has_msr_hsave_pa; |
59 | 66 |
static int lm_capable_kernel; |
60 | 67 |
|
61 |
#ifdef KVM_CAP_EXT_CPUID |
|
62 |
|
|
63 | 68 |
static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) |
64 | 69 |
{ |
65 | 70 |
struct kvm_cpuid2 *cpuid; |
... | ... | |
93 | 98 |
uint32_t ret = 0; |
94 | 99 |
uint32_t cpuid_1_edx; |
95 | 100 |
|
96 |
if (!kvm_check_extension(env->kvm_state, KVM_CAP_EXT_CPUID)) { |
|
97 |
return -1U; |
|
98 |
} |
|
99 |
|
|
100 | 101 |
max = 1; |
101 | 102 |
while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) { |
102 | 103 |
max *= 2; |
... | ... | |
140 | 141 |
return ret; |
141 | 142 |
} |
142 | 143 |
|
143 |
#else |
|
144 |
|
|
145 |
uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, |
|
146 |
uint32_t index, int reg) |
|
147 |
{ |
|
148 |
return -1U; |
|
149 |
} |
|
150 |
|
|
151 |
#endif |
|
152 |
|
|
153 | 144 |
#ifdef CONFIG_KVM_PARA |
154 | 145 |
struct kvm_para_features { |
155 | 146 |
int cap; |
156 | 147 |
int feature; |
157 | 148 |
} para_features[] = { |
158 |
#ifdef KVM_CAP_CLOCKSOURCE |
|
159 | 149 |
{ KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE }, |
160 |
#endif |
|
161 |
#ifdef KVM_CAP_NOP_IO_DELAY |
|
162 | 150 |
{ KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY }, |
163 |
#endif |
|
164 |
#ifdef KVM_CAP_PV_MMU |
|
165 | 151 |
{ KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, |
166 |
#endif |
|
167 | 152 |
#ifdef KVM_CAP_ASYNC_PF |
168 | 153 |
{ KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, |
169 | 154 |
#endif |
... | ... | |
542 | 527 |
|
543 | 528 |
/* create vm86 tss. KVM uses vm86 mode to emulate 16-bit code |
544 | 529 |
* directly. In order to use vm86 mode, a TSS is needed. Since this |
545 |
* must be part of guest physical memory, we need to allocate it. Older |
|
546 |
* versions of KVM just assumed that it would be at the end of physical |
|
547 |
* memory but that doesn't work with more than 4GB of memory. We simply |
|
548 |
* refuse to work with those older versions of KVM. */ |
|
549 |
ret = kvm_check_extension(s, KVM_CAP_SET_TSS_ADDR); |
|
550 |
if (ret <= 0) { |
|
551 |
fprintf(stderr, "kvm does not support KVM_CAP_SET_TSS_ADDR\n"); |
|
552 |
return ret; |
|
553 |
} |
|
530 |
* must be part of guest physical memory, we need to allocate it. */ |
|
554 | 531 |
|
555 | 532 |
/* this address is 3 pages before the bios, and the bios should present |
556 | 533 |
* as unavaible memory. FIXME, need to ensure the e820 map deals with |
b/target-ppc/kvm.c | ||
---|---|---|
37 | 37 |
do { } while (0) |
38 | 38 |
#endif |
39 | 39 |
|
40 |
const KVMCapabilityInfo kvm_arch_required_capabilities[] = { |
|
41 |
KVM_CAP_LAST_INFO |
|
42 |
}; |
|
43 |
|
|
40 | 44 |
static int cap_interrupt_unset = false; |
41 | 45 |
static int cap_interrupt_level = false; |
42 | 46 |
|
b/target-s390x/kvm.c | ||
---|---|---|
70 | 70 |
#define SCLP_CMDW_READ_SCP_INFO 0x00020001 |
71 | 71 |
#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 |
72 | 72 |
|
73 |
const KVMCapabilityInfo kvm_arch_required_capabilities[] = { |
|
74 |
KVM_CAP_LAST_INFO |
|
75 |
}; |
|
76 |
|
|
73 | 77 |
int kvm_arch_init(KVMState *s) |
74 | 78 |
{ |
75 | 79 |
return 0; |
Also available in: Unified diff