mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 19:33:39 +08:00
kvm: test for ioeventfd support on old kernels
There used to be a limit of 6 KVM io bus devices in the kernel. On such a kernel, we can't use many ioeventfds for host notification since the limit is reached too easily. Add an API to test for this condition. Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
85cf2a8d74
commit
d2f2b8a740
49
kvm-all.c
49
kvm-all.c
@ -28,6 +28,11 @@
|
|||||||
#include "kvm.h"
|
#include "kvm.h"
|
||||||
#include "bswap.h"
|
#include "bswap.h"
|
||||||
|
|
||||||
|
/* This check must be after config-host.h is included */
|
||||||
|
#ifdef CONFIG_EVENTFD
|
||||||
|
#include <sys/eventfd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* KVM uses PAGE_SIZE in it's definition of COALESCED_MMIO_MAX */
|
/* KVM uses PAGE_SIZE in it's definition of COALESCED_MMIO_MAX */
|
||||||
#define PAGE_SIZE TARGET_PAGE_SIZE
|
#define PAGE_SIZE TARGET_PAGE_SIZE
|
||||||
|
|
||||||
@ -72,6 +77,7 @@ struct KVMState
|
|||||||
int irqchip_in_kernel;
|
int irqchip_in_kernel;
|
||||||
int pit_in_kernel;
|
int pit_in_kernel;
|
||||||
int xsave, xcrs;
|
int xsave, xcrs;
|
||||||
|
int many_ioeventfds;
|
||||||
};
|
};
|
||||||
|
|
||||||
static KVMState *kvm_state;
|
static KVMState *kvm_state;
|
||||||
@ -441,6 +447,39 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kvm_check_many_ioeventfds(void)
|
||||||
|
{
|
||||||
|
/* Older kernels have a 6 device limit on the KVM io bus. Find out so we
|
||||||
|
* can avoid creating too many ioeventfds.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_EVENTFD
|
||||||
|
int ioeventfds[7];
|
||||||
|
int i, ret = 0;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ioeventfds); i++) {
|
||||||
|
ioeventfds[i] = eventfd(0, EFD_CLOEXEC);
|
||||||
|
if (ioeventfds[i] < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true);
|
||||||
|
if (ret < 0) {
|
||||||
|
close(ioeventfds[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decide whether many devices are supported or not */
|
||||||
|
ret = i == ARRAY_SIZE(ioeventfds);
|
||||||
|
|
||||||
|
while (i-- > 0) {
|
||||||
|
kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false);
|
||||||
|
close(ioeventfds[i]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void kvm_set_phys_mem(target_phys_addr_t start_addr,
|
static void kvm_set_phys_mem(target_phys_addr_t start_addr,
|
||||||
ram_addr_t size,
|
ram_addr_t size,
|
||||||
ram_addr_t phys_offset)
|
ram_addr_t phys_offset)
|
||||||
@ -717,6 +756,8 @@ int kvm_init(int smp_cpus)
|
|||||||
kvm_state = s;
|
kvm_state = s;
|
||||||
cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client);
|
cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client);
|
||||||
|
|
||||||
|
s->many_ioeventfds = kvm_check_many_ioeventfds();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -1046,6 +1087,14 @@ int kvm_has_xcrs(void)
|
|||||||
return kvm_state->xcrs;
|
return kvm_state->xcrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_has_many_ioeventfds(void)
|
||||||
|
{
|
||||||
|
if (!kvm_enabled()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return kvm_state->many_ioeventfds;
|
||||||
|
}
|
||||||
|
|
||||||
void kvm_setup_guest_memory(void *start, size_t size)
|
void kvm_setup_guest_memory(void *start, size_t size)
|
||||||
{
|
{
|
||||||
if (!kvm_has_sync_mmu()) {
|
if (!kvm_has_sync_mmu()) {
|
||||||
|
@ -99,6 +99,11 @@ int kvm_has_robust_singlestep(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_has_many_ioeventfds(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void kvm_setup_guest_memory(void *start, size_t size)
|
void kvm_setup_guest_memory(void *start, size_t size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
1
kvm.h
1
kvm.h
@ -42,6 +42,7 @@ int kvm_has_robust_singlestep(void);
|
|||||||
int kvm_has_debugregs(void);
|
int kvm_has_debugregs(void);
|
||||||
int kvm_has_xsave(void);
|
int kvm_has_xsave(void);
|
||||||
int kvm_has_xcrs(void);
|
int kvm_has_xcrs(void);
|
||||||
|
int kvm_has_many_ioeventfds(void);
|
||||||
|
|
||||||
#ifdef NEED_CPU_H
|
#ifdef NEED_CPU_H
|
||||||
int kvm_init_vcpu(CPUState *env);
|
int kvm_init_vcpu(CPUState *env);
|
||||||
|
Loading…
Reference in New Issue
Block a user