mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 11:23:43 +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 "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 */
|
||||
#define PAGE_SIZE TARGET_PAGE_SIZE
|
||||
|
||||
@ -72,6 +77,7 @@ struct KVMState
|
||||
int irqchip_in_kernel;
|
||||
int pit_in_kernel;
|
||||
int xsave, xcrs;
|
||||
int many_ioeventfds;
|
||||
};
|
||||
|
||||
static KVMState *kvm_state;
|
||||
@ -441,6 +447,39 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
|
||||
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,
|
||||
ram_addr_t size,
|
||||
ram_addr_t phys_offset)
|
||||
@ -717,6 +756,8 @@ int kvm_init(int smp_cpus)
|
||||
kvm_state = s;
|
||||
cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client);
|
||||
|
||||
s->many_ioeventfds = kvm_check_many_ioeventfds();
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@ -1046,6 +1087,14 @@ int kvm_has_xcrs(void)
|
||||
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)
|
||||
{
|
||||
if (!kvm_has_sync_mmu()) {
|
||||
|
@ -99,6 +99,11 @@ int kvm_has_robust_singlestep(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_has_many_ioeventfds(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvm_setup_guest_memory(void *start, size_t size)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user