From cc5e719e2c8086c61bdd9114f42095f8d5b1b0db Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Oct 2023 13:24:33 +0200 Subject: kvm: require KVM_CAP_SIGNAL_MSI This was introduced in KVM in Linux 3.5, we can require it unconditionally in kvm_irqchip_send_msi(). However, not all architectures have to implement it so check it only in x86, the only architecture that ever had MSI injection but not KVM_CAP_SIGNAL_MSI. ARM uses it to detect the presence of the ITS emulation in the kernel, introduced in Linux 4.8. Assume that it's there and possibly fail when realizing the arm-its-kvm device. Signed-off-by: Paolo Bonzini --- hw/intc/arm_gicv3_its_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c index abaf77057e..fddd6d490c 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -163,8 +163,7 @@ type_init(gicv3_its_common_register_types) const char *its_class_name(void) { if (kvm_irqchip_in_kernel()) { - /* KVM implementation requires this capability */ - return kvm_direct_msi_enabled() ? "arm-its-kvm" : NULL; + return "arm-its-kvm"; } else { /* Software emulation based model */ return "arm-gicv3-its"; -- cgit v1.2.3-70-g09d2 From a788260b2000f1fe826885c06f2a34df1c5b335c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Oct 2023 13:34:50 +0200 Subject: kvm: require KVM_IRQFD for kernel irqchip KVM_IRQFD was introduced in Linux 2.6.32, and since then it has always been available on architectures that support an in-kernel interrupt controller. We can require it unconditionally. Reviewed-by: Manos Pitsidianakis Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-all.c | 13 +++++-------- accel/stubs/kvm-stub.c | 1 - hw/intc/arm_gicv3_its_kvm.c | 2 +- include/sysemu/kvm.h | 6 +++--- target/riscv/kvm/kvm-cpu.c | 2 +- 5 files changed, 10 insertions(+), 14 deletions(-) (limited to 'hw') diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 0c7b0569da..be50d47f7b 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -91,7 +91,6 @@ bool kvm_split_irqchip; bool kvm_async_interrupts_allowed; bool kvm_halt_in_kernel_allowed; bool kvm_eventfds_allowed; -bool kvm_irqfds_allowed; bool kvm_resamplefds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; @@ -2128,10 +2127,6 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, EventNotifier *event, } } - if (!kvm_irqfds_enabled()) { - return -ENOSYS; - } - return kvm_vm_ioctl(s, KVM_IRQFD, &irqfd); } @@ -2292,6 +2287,11 @@ static void kvm_irqchip_create(KVMState *s) return; } + if (kvm_check_extension(s, KVM_CAP_IRQFD) <= 0) { + fprintf(stderr, "kvm: irqfd not implemented\n"); + exit(1); + } + /* First probe and see if there's a arch-specific hook to create the * in-kernel irqchip for us */ ret = kvm_arch_irqchip_create(s); @@ -2589,9 +2589,6 @@ static int kvm_init(MachineState *ms) kvm_eventfds_allowed = (kvm_check_extension(s, KVM_CAP_IOEVENTFD) > 0); - kvm_irqfds_allowed = - (kvm_check_extension(s, KVM_CAP_IRQFD) > 0); - kvm_resamplefds_allowed = (kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0); diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index bce005adad..19d58f2778 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -18,7 +18,6 @@ KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; bool kvm_eventfds_allowed; -bool kvm_irqfds_allowed; bool kvm_resamplefds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c index 61c1cc7bdb..f7df602cff 100644 --- a/hw/intc/arm_gicv3_its_kvm.c +++ b/hw/intc/arm_gicv3_its_kvm.c @@ -123,7 +123,7 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp) kvm_msi_use_devid = true; kvm_gsi_direct_mapping = false; - kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); + kvm_msi_via_irqfd_allowed = true; } /** diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 93dccf5dd9..575dee53b3 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -37,7 +37,6 @@ extern bool kvm_split_irqchip; extern bool kvm_async_interrupts_allowed; extern bool kvm_halt_in_kernel_allowed; extern bool kvm_eventfds_allowed; -extern bool kvm_irqfds_allowed; extern bool kvm_resamplefds_allowed; extern bool kvm_msi_via_irqfd_allowed; extern bool kvm_gsi_routing_allowed; @@ -102,8 +101,10 @@ extern bool kvm_msi_use_devid; * Returns: true if we can use irqfds to inject interrupts into * a KVM CPU (ie the kernel supports irqfds and we are running * with a configuration where it is meaningful to use them). + * + * Always available if running with in-kernel irqchip. */ -#define kvm_irqfds_enabled() (kvm_irqfds_allowed) +#define kvm_irqfds_enabled() kvm_irqchip_in_kernel() /** * kvm_resamplefds_enabled: @@ -167,7 +168,6 @@ extern bool kvm_msi_use_devid; #define kvm_async_interrupts_enabled() (false) #define kvm_halt_in_kernel() (false) #define kvm_eventfds_enabled() (false) -#define kvm_irqfds_enabled() (false) #define kvm_resamplefds_enabled() (false) #define kvm_msi_via_irqfd_enabled() (false) #define kvm_gsi_routing_allowed() (false) diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index 090d617627..26e68c7ab4 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -1420,7 +1420,7 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, exit(1); } - kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); + kvm_msi_via_irqfd_allowed = true; } static void kvm_cpu_instance_init(CPUState *cs) -- cgit v1.2.3-70-g09d2 From 5d9ec1f4c78ed25720b4fd01ddcddb00db50fa6c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Oct 2023 14:08:22 +0200 Subject: kvm: assume that many ioeventfds can be created NR_IOBUS_DEVS was increased to 200 in Linux 2.6.34. By Linux 3.5 it had increased to 1000 and later ioeventfds were changed to not count against the limit. But the earlier limit of 200 would already be enough for kvm_check_many_ioeventfds() to be true, so remove the check. Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-all.c | 47 ----------------------------------------------- accel/stubs/kvm-stub.c | 5 ----- hw/virtio/virtio-pci.c | 4 ---- include/sysemu/kvm.h | 1 - include/sysemu/kvm_int.h | 1 - 5 files changed, 58 deletions(-) (limited to 'hw') diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 50717a0d63..05be687be1 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -1253,43 +1253,6 @@ static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val, } -static int kvm_check_many_ioeventfds(void) -{ - /* Userspace can use ioeventfd for io notification. This requires a host - * that supports eventfd(2) and an I/O thread; since eventfd does not - * support SIGIO it cannot interrupt the vcpu. - * - * Older kernels have a 6 device limit on the KVM io bus. Find out so we - * can avoid creating too many ioeventfds. - */ -#if defined(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(ioeventfds[i], 0, i, true, 2, 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(ioeventfds[i], 0, i, false, 2, true); - close(ioeventfds[i]); - } - return ret; -#else - return 0; -#endif -} - static const KVMCapabilityInfo * kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list) { @@ -2648,8 +2611,6 @@ static int kvm_init(MachineState *ms) memory_listener_register(&kvm_coalesced_pio_listener, &address_space_io); - s->many_ioeventfds = kvm_check_many_ioeventfds(); - s->sync_mmu = !!kvm_vm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); if (!s->sync_mmu) { ret = ram_block_discard_disable(true); @@ -3218,14 +3179,6 @@ int kvm_max_nested_state_length(void) return kvm_state->max_nested_state_len; } -int kvm_has_many_ioeventfds(void) -{ - if (!kvm_enabled()) { - return 0; - } - return kvm_state->many_ioeventfds; -} - int kvm_has_gsi_routing(void) { #ifdef KVM_CAP_IRQ_ROUTING diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 19d58f2778..b2d8885853 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -40,11 +40,6 @@ bool kvm_has_sync_mmu(void) return false; } -int kvm_has_many_ioeventfds(void) -{ - return 0; -} - int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr) { return 1; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index af1f4bc187..5f614334ec 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -2114,10 +2114,6 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) bool pcie_port = pci_bus_is_express(pci_get_bus(pci_dev)) && !pci_bus_is_root(pci_get_bus(pci_dev)); - if (kvm_enabled() && !kvm_has_many_ioeventfds()) { - proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; - } - /* fd-based ioevents can't be synchronized in record/replay */ if (replay_mode != REPLAY_MODE_NONE) { proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index bcc9bd96a9..8c5867ba8a 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -214,7 +214,6 @@ int kvm_has_vcpu_events(void); int kvm_has_robust_singlestep(void); int kvm_has_debugregs(void); int kvm_max_nested_state_length(void); -int kvm_has_many_ioeventfds(void); int kvm_has_gsi_routing(void); /** diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index 817238b958..840b905a2e 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -84,7 +84,6 @@ struct KVMState QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints; #endif int max_nested_state_len; - int many_ioeventfds; int kvm_shadow_mem; bool kernel_irqchip_allowed; bool kernel_irqchip_required; -- cgit v1.2.3-70-g09d2 From 126e7f780367b0263d9a112729736d6a0bd6d441 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Oct 2023 14:13:04 +0200 Subject: kvm: require KVM_CAP_IOEVENTFD and KVM_CAP_IOEVENTFD_ANY_LENGTH KVM_CAP_IOEVENTFD_ANY_LENGTH was added in Linux 4.4, released in 2016. Assume that it is present. Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-all.c | 22 ++++++---------------- accel/stubs/kvm-stub.c | 2 -- hw/misc/pci-testdev.c | 3 +-- hw/s390x/virtio-ccw.c | 4 ---- hw/virtio/vhost-user.c | 7 +------ hw/virtio/virtio-mmio.c | 4 ---- hw/virtio/virtio-pci.c | 19 ++++--------------- include/sysemu/kvm.h | 19 ------------------- system/memory.c | 16 ++++++---------- 9 files changed, 18 insertions(+), 78 deletions(-) (limited to 'hw') diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 05be687be1..120051da64 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -90,7 +90,6 @@ bool kvm_kernel_irqchip; bool kvm_split_irqchip; bool kvm_async_interrupts_allowed; bool kvm_halt_in_kernel_allowed; -bool kvm_eventfds_allowed; bool kvm_resamplefds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; @@ -98,7 +97,6 @@ bool kvm_gsi_direct_mapping; bool kvm_allowed; bool kvm_readonly_mem_allowed; bool kvm_vm_attributes_allowed; -bool kvm_ioeventfd_any_length_allowed; bool kvm_msi_use_devid; bool kvm_has_guest_debug; static int kvm_sstep_flags; @@ -110,6 +108,8 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_INFO(DESTROY_MEMORY_REGION_WORKS), KVM_CAP_INFO(JOIN_MEMORY_REGIONS_WORKS), KVM_CAP_INFO(INTERNAL_ERROR_DATA), + KVM_CAP_INFO(IOEVENTFD), + KVM_CAP_INFO(IOEVENTFD_ANY_LENGTH), KVM_CAP_LAST_INFO }; @@ -2547,18 +2547,12 @@ static int kvm_init(MachineState *ms) kvm_readonly_mem_allowed = (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0); - kvm_eventfds_allowed = - (kvm_check_extension(s, KVM_CAP_IOEVENTFD) > 0); - kvm_resamplefds_allowed = (kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0); kvm_vm_attributes_allowed = (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) > 0); - kvm_ioeventfd_any_length_allowed = - (kvm_check_extension(s, KVM_CAP_IOEVENTFD_ANY_LENGTH) > 0); - #ifdef KVM_CAP_SET_GUEST_DEBUG kvm_has_guest_debug = (kvm_check_extension(s, KVM_CAP_SET_GUEST_DEBUG) > 0); @@ -2595,19 +2589,15 @@ static int kvm_init(MachineState *ms) kvm_irqchip_create(s); } - if (kvm_eventfds_allowed) { - s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add; - s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del; - } + s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add; + s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del; s->memory_listener.listener.coalesced_io_add = kvm_coalesce_mmio_region; s->memory_listener.listener.coalesced_io_del = kvm_uncoalesce_mmio_region; kvm_memory_listener_register(s, &s->memory_listener, &address_space_memory, 0, "kvm-memory"); - if (kvm_eventfds_allowed) { - memory_listener_register(&kvm_io_listener, - &address_space_io); - } + memory_listener_register(&kvm_io_listener, + &address_space_io); memory_listener_register(&kvm_coalesced_pio_listener, &address_space_io); diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index b2d8885853..1b37d9a302 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -17,14 +17,12 @@ KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; -bool kvm_eventfds_allowed; bool kvm_resamplefds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; bool kvm_gsi_direct_mapping; bool kvm_allowed; bool kvm_readonly_mem_allowed; -bool kvm_ioeventfd_any_length_allowed; bool kvm_msi_use_devid; void kvm_flush_coalesced_mmio_buffer(void) diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c index 49303134e4..acedd0f82b 100644 --- a/hw/misc/pci-testdev.c +++ b/hw/misc/pci-testdev.c @@ -245,7 +245,6 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp) uint8_t *pci_conf; char *name; int r, i; - bool fastmmio = kvm_ioeventfd_any_length_enabled(); pci_conf = pci_dev->config; @@ -279,7 +278,7 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp) g_free(name); test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH); test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd"); - if (fastmmio && IOTEST_IS_MEM(i) && !test->match_data) { + if (IOTEST_IS_MEM(i) && !test->match_data) { test->size = 0; } else { test->size = IOTEST_ACCESS_WIDTH; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 17c548b84f..80453718a3 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -768,10 +768,6 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) sch->cssid, sch->ssid, sch->schid, sch->devno, ccw_dev->devno.valid ? "user-configured" : "auto-configured"); - if (kvm_enabled() && !kvm_eventfds_enabled()) { - dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD; - } - /* fd-based ioevents can't be synchronized in record/replay */ if (replay_mode != REPLAY_MODE_NONE) { dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD; diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index b8a7b5542d..7b42ae8aae 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -264,11 +264,6 @@ struct scrub_regions { int fd_idx; }; -static bool ioeventfd_enabled(void) -{ - return !kvm_enabled() || kvm_eventfds_enabled(); -} - static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg) { struct vhost_user *u = dev->opaque; @@ -1318,7 +1313,7 @@ static int vhost_set_vring_file(struct vhost_dev *dev, .hdr.size = sizeof(msg.payload.u64), }; - if (ioeventfd_enabled() && file->fd > 0) { + if (file->fd > 0) { fds[fd_num++] = file->fd; } else { msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK; diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index c2c6d85475..22f15e1e02 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -761,10 +761,6 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp) qbus_init(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS, d, NULL); sysbus_init_irq(sbd, &proxy->irq); - if (!kvm_eventfds_enabled()) { - proxy->flags &= ~VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD; - } - /* fd-based ioevents can't be synchronized in record/replay */ if (replay_mode != REPLAY_MODE_NONE) { proxy->flags &= ~VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 5f614334ec..205dbf24fb 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -332,7 +332,6 @@ static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier, VirtQueue *vq = virtio_get_queue(vdev, n); bool legacy = virtio_pci_legacy(proxy); bool modern = virtio_pci_modern(proxy); - bool fast_mmio = kvm_ioeventfd_any_length_enabled(); bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY; MemoryRegion *modern_mr = &proxy->notify.mr; MemoryRegion *modern_notify_mr = &proxy->notify_pio.mr; @@ -343,13 +342,8 @@ static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier, if (assign) { if (modern) { - if (fast_mmio) { - memory_region_add_eventfd(modern_mr, modern_addr, 0, - false, n, notifier); - } else { - memory_region_add_eventfd(modern_mr, modern_addr, 2, - false, n, notifier); - } + memory_region_add_eventfd(modern_mr, modern_addr, 0, + false, n, notifier); if (modern_pio) { memory_region_add_eventfd(modern_notify_mr, 0, 2, true, n, notifier); @@ -361,13 +355,8 @@ static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier, } } else { if (modern) { - if (fast_mmio) { - memory_region_del_eventfd(modern_mr, modern_addr, 0, - false, n, notifier); - } else { - memory_region_del_eventfd(modern_mr, modern_addr, 2, - false, n, notifier); - } + memory_region_del_eventfd(modern_mr, modern_addr, 0, + false, n, notifier); if (modern_pio) { memory_region_del_eventfd(modern_notify_mr, 0, 2, true, n, notifier); diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 8c5867ba8a..31c03cc193 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -36,13 +36,11 @@ extern bool kvm_kernel_irqchip; extern bool kvm_split_irqchip; extern bool kvm_async_interrupts_allowed; extern bool kvm_halt_in_kernel_allowed; -extern bool kvm_eventfds_allowed; extern bool kvm_resamplefds_allowed; extern bool kvm_msi_via_irqfd_allowed; extern bool kvm_gsi_routing_allowed; extern bool kvm_gsi_direct_mapping; extern bool kvm_readonly_mem_allowed; -extern bool kvm_ioeventfd_any_length_allowed; extern bool kvm_msi_use_devid; #define kvm_enabled() (kvm_allowed) @@ -86,15 +84,6 @@ extern bool kvm_msi_use_devid; */ #define kvm_halt_in_kernel() (kvm_halt_in_kernel_allowed) -/** - * kvm_eventfds_enabled: - * - * Returns: true if we can use eventfds to receive notifications - * from a KVM CPU (ie the kernel supports eventds and we are running - * with a configuration where it is meaningful to use them). - */ -#define kvm_eventfds_enabled() (kvm_eventfds_allowed) - /** * kvm_irqfds_enabled: * @@ -147,12 +136,6 @@ extern bool kvm_msi_use_devid; */ #define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed) -/** - * kvm_ioeventfd_any_length_enabled: - * Returns: true if KVM allows any length io eventfd. - */ -#define kvm_ioeventfd_any_length_enabled() (kvm_ioeventfd_any_length_allowed) - /** * kvm_msi_devid_required: * Returns: true if KVM requires a device id to be provided while @@ -168,13 +151,11 @@ extern bool kvm_msi_use_devid; #define kvm_async_interrupts_enabled() (false) #define kvm_halt_in_kernel() (false) #define kvm_irqfds_enabled() (false) -#define kvm_eventfds_enabled() (false) #define kvm_resamplefds_enabled() (false) #define kvm_msi_via_irqfd_enabled() (false) #define kvm_gsi_routing_allowed() (false) #define kvm_gsi_direct_mapping() (false) #define kvm_readonly_mem_enabled() (false) -#define kvm_ioeventfd_any_length_enabled() (false) #define kvm_msi_devid_required() (false) #endif /* CONFIG_KVM_IS_POSSIBLE */ diff --git a/system/memory.c b/system/memory.c index a800fbc9e5..4928f2525d 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1535,7 +1535,12 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, adjust_endianness(mr, &data, op); - if ((!kvm_eventfds_enabled()) && + /* + * FIXME: it's not clear why under KVM the write would be processed + * directly, instead of going through eventfd. This probably should + * test "tcg_enabled() || qtest_enabled()", or should just go away. + */ + if (!kvm_enabled() && memory_region_dispatch_write_eventfds(mr, addr, data, size, attrs)) { return MEMTX_OK; } @@ -2550,8 +2555,6 @@ void memory_region_clear_flush_coalesced(MemoryRegion *mr) } } -static bool userspace_eventfd_warning; - void memory_region_add_eventfd(MemoryRegion *mr, hwaddr addr, unsigned size, @@ -2568,13 +2571,6 @@ void memory_region_add_eventfd(MemoryRegion *mr, }; unsigned i; - if (kvm_enabled() && (!(kvm_eventfds_enabled() || - userspace_eventfd_warning))) { - userspace_eventfd_warning = true; - error_report("Using eventfd without MMIO binding in KVM. " - "Suboptimal performance expected"); - } - if (size) { adjust_endianness(mr, &mrfd.data, size_memop(size) | MO_TE); } -- cgit v1.2.3-70-g09d2 From 700766ba602330a4fc907254a2f45773a6c694fa Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Oct 2023 14:30:44 +0200 Subject: kvm: i386: require KVM_CAP_ADJUST_CLOCK This was introduced in KVM in Linux 2.6.33, we can require it unconditionally. KVM_CLOCK_TSC_STABLE was only added in Linux 4.9, for now do not require it (though it would allow the removal of some pretty yucky code). Signed-off-by: Paolo Bonzini --- hw/i386/kvm/clock.c | 4 ---- target/i386/kvm/kvm.c | 6 +----- target/i386/kvm/kvm_i386.h | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index f25977d3f6..e756b0aa43 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -333,10 +333,6 @@ void kvmclock_create(bool create_always) X86CPU *cpu = X86_CPU(first_cpu); assert(kvm_enabled()); - if (!kvm_has_adjust_clock()) { - return; - } - if (create_always || cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 42574c2df8..d4bf327fa6 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -98,6 +98,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_INFO(VCPU_EVENTS), KVM_CAP_INFO(X86_ROBUST_SINGLESTEP), KVM_CAP_INFO(MCE), + KVM_CAP_INFO(ADJUST_CLOCK), KVM_CAP_LAST_INFO }; @@ -177,11 +178,6 @@ bool kvm_has_adjust_clock_stable(void) return (ret & KVM_CLOCK_TSC_STABLE); } -bool kvm_has_adjust_clock(void) -{ - return kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK); -} - bool kvm_has_exception_payload(void) { return has_exception_payload; diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index 55d4e68c34..7e60ea4f23 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -50,7 +50,6 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); #ifdef CONFIG_KVM -bool kvm_has_adjust_clock(void); bool kvm_has_adjust_clock_stable(void); bool kvm_has_exception_payload(void); void kvm_synchronize_all_tsc(void); -- cgit v1.2.3-70-g09d2 From 39dd3e1f55a70f568cc9d280f67467aa4e8a63bd Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Oct 2023 14:29:03 +0200 Subject: kvm: i8254: require KVM_CAP_PIT2 and KVM_CAP_PIT_STATE2 Signed-off-by: Paolo Bonzini --- hw/i386/kvm/i8254.c | 38 ++++++++++++-------------------------- hw/i386/pc.c | 6 +----- target/i386/kvm/kvm.c | 7 ------- target/i386/kvm/kvm_i386.h | 1 - 4 files changed, 13 insertions(+), 39 deletions(-) (limited to 'hw') diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c index a649b2b7ca..e49b9c4b56 100644 --- a/hw/i386/kvm/i8254.c +++ b/hw/i386/kvm/i8254.c @@ -97,24 +97,12 @@ static void kvm_pit_get(PITCommonState *pit) return; } - if (kvm_has_pit_state2()) { - ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit); - if (ret < 0) { - fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(-ret)); - abort(); - } - pit->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY; - } else { - /* - * kvm_pit_state2 is superset of kvm_pit_state struct, - * so we can use it for KVM_GET_PIT as well. - */ - ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT, &kpit); - if (ret < 0) { - fprintf(stderr, "KVM_GET_PIT failed: %s\n", strerror(-ret)); - abort(); - } + ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit); + if (ret < 0) { + fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(-ret)); + abort(); } + pit->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY; for (i = 0; i < 3; i++) { kchan = &kpit.channels[i]; sc = &pit->channels[i]; @@ -170,12 +158,9 @@ static void kvm_pit_put(PITCommonState *pit) kchan->count_load_time = sc->count_load_time - s->kernel_clock_offset; } - ret = kvm_vm_ioctl(kvm_state, - kvm_has_pit_state2() ? KVM_SET_PIT2 : KVM_SET_PIT, - &kpit); + ret = kvm_vm_ioctl(kvm_state, KVM_SET_PIT2, &kpit); if (ret < 0) { - fprintf(stderr, "%s failed: %s\n", - kvm_has_pit_state2() ? "KVM_SET_PIT2" : "KVM_SET_PIT", + fprintf(stderr, "KVM_SET_PIT2 failed: %s\n", strerror(-ret)); abort(); } @@ -261,11 +246,12 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp) }; int ret; - if (kvm_check_extension(kvm_state, KVM_CAP_PIT2)) { - ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT2, &config); - } else { - ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT); + if (!kvm_check_extension(kvm_state, KVM_CAP_PIT_STATE2) || + !kvm_check_extension(kvm_state, KVM_CAP_PIT2)) { + error_setg(errp, "In-kernel PIT not available"); } + + ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT2, &config); if (ret < 0) { error_setg(errp, "Create kernel PIC irqchip failed: %s", strerror(-ret)); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 11fed78d17..6031234a73 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1214,12 +1214,8 @@ void pc_basic_device_init(struct PCMachineState *pcms, /* * Check if an HPET shall be created. - * - * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT - * when the HPET wants to take over. Thus we have to disable the latter. */ - if (pcms->hpet_enabled && (!kvm_irqchip_in_kernel() || - kvm_has_pit_state2())) { + if (pcms->hpet_enabled) { qemu_irq rtc_irq; hpet = qdev_try_new(TYPE_HPET); diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index e364b842e6..770e81d56e 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -145,7 +145,6 @@ static uint32_t num_architectural_pmu_fixed_counters; static int has_xsave2; static int has_xcrs; -static int has_pit_state2; static int has_sregs2; static int has_exception_payload; static int has_triple_fault_event; @@ -162,11 +161,6 @@ static KVMMSRHandlers msr_handlers[KVM_MSR_FILTER_MAX_RANGES]; static RateLimit bus_lock_ratelimit_ctrl; static int kvm_get_one_msr(X86CPU *cpu, int index, uint64_t *value); -bool kvm_has_pit_state2(void) -{ - return !!has_pit_state2; -} - bool kvm_has_smm(void) { return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM); @@ -2543,7 +2537,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } has_xcrs = kvm_check_extension(s, KVM_CAP_XCRS); - has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); has_sregs2 = kvm_check_extension(s, KVM_CAP_SREGS2) > 0; hv_vpindex_settable = kvm_check_extension(s, KVM_CAP_HYPERV_VP_INDEX); diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index 7e60ea4f23..30fedcffea 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -33,7 +33,6 @@ bool kvm_has_smm(void); bool kvm_enable_x2apic(void); bool kvm_hv_vpindex_settable(void); -bool kvm_has_pit_state2(void); bool kvm_enable_sgx_provisioning(KVMState *s); bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp); -- cgit v1.2.3-70-g09d2