Loading hw/vhost.c +14 −0 Original line number Diff line number Diff line Loading @@ -720,6 +720,18 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev, 0, virtio_queue_get_desc_size(vdev, idx)); } static void vhost_eventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } static void vhost_eventfd_del(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) { uint64_t features; Loading Loading @@ -751,6 +763,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) .log_sync = vhost_log_sync, .log_global_start = vhost_log_global_start, .log_global_stop = vhost_log_global_stop, .eventfd_add = vhost_eventfd_add, .eventfd_del = vhost_eventfd_del, .priority = 10 }; hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions)); Loading kvm-all.c +78 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include "kvm.h" #include "bswap.h" #include "memory.h" #include "exec-memory.h" /* This check must be after config-host.h is included */ #ifdef CONFIG_EVENTFD Loading Loading @@ -718,6 +719,81 @@ static void kvm_log_global_stop(struct MemoryListener *listener) assert(r >= 0); } static void kvm_mem_ioeventfd_add(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; assert(match_data && section->size == 4); r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space, data, true); if (r < 0) { abort(); } } static void kvm_mem_ioeventfd_del(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space, data, false); if (r < 0) { abort(); } } static void kvm_io_ioeventfd_add(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; assert(match_data && section->size == 2); r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, data, true); if (r < 0) { abort(); } } static void kvm_io_ioeventfd_del(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, data, false); if (r < 0) { abort(); } } static void kvm_eventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { if (section->address_space == get_system_memory()) { kvm_mem_ioeventfd_add(section, match_data, data, fd); } else { kvm_io_ioeventfd_add(section, match_data, data, fd); } } static void kvm_eventfd_del(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { if (section->address_space == get_system_memory()) { kvm_mem_ioeventfd_del(section, match_data, data, fd); } else { kvm_io_ioeventfd_del(section, match_data, data, fd); } } static MemoryListener kvm_memory_listener = { .region_add = kvm_region_add, .region_del = kvm_region_del, Loading @@ -726,6 +802,8 @@ static MemoryListener kvm_memory_listener = { .log_sync = kvm_log_sync, .log_global_start = kvm_log_global_start, .log_global_stop = kvm_log_global_stop, .eventfd_add = kvm_eventfd_add, .eventfd_del = kvm_eventfd_del, .priority = 10, }; Loading memory.c +18 −56 Original line number Diff line number Diff line Loading @@ -202,8 +202,6 @@ struct AddressSpaceOps { void (*range_del)(AddressSpace *as, FlatRange *fr); void (*log_start)(AddressSpace *as, FlatRange *fr); void (*log_stop)(AddressSpace *as, FlatRange *fr); void (*ioeventfd_add)(AddressSpace *as, MemoryRegionIoeventfd *fd); void (*ioeventfd_del)(AddressSpace *as, MemoryRegionIoeventfd *fd); }; #define FOR_EACH_FLAT_RANGE(var, view) \ Loading Loading @@ -369,37 +367,11 @@ static void as_memory_log_stop(AddressSpace *as, FlatRange *fr) { } static void as_memory_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; assert(fd->match_data && int128_get64(fd->addr.size) == 4); r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start), fd->data, true); if (r < 0) { abort(); } } static void as_memory_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start), fd->data, false); if (r < 0) { abort(); } } static const AddressSpaceOps address_space_ops_memory = { .range_add = as_memory_range_add, .range_del = as_memory_range_del, .log_start = as_memory_log_start, .log_stop = as_memory_log_stop, .ioeventfd_add = as_memory_ioeventfd_add, .ioeventfd_del = as_memory_ioeventfd_del, }; static AddressSpace address_space_memory = { Loading Loading @@ -493,35 +465,9 @@ static void as_io_range_del(AddressSpace *as, FlatRange *fr) int128_get64(fr->addr.size)); } static void as_io_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; assert(fd->match_data && int128_get64(fd->addr.size) == 2); r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start), fd->data, true); if (r < 0) { abort(); } } static void as_io_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start), fd->data, false); if (r < 0) { abort(); } } static const AddressSpaceOps address_space_ops_io = { .range_add = as_io_range_add, .range_del = as_io_range_del, .ioeventfd_add = as_io_ioeventfd_add, .ioeventfd_del = as_io_ioeventfd_del, }; static AddressSpace address_space_io = { Loading Loading @@ -653,6 +599,8 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, unsigned fds_old_nb) { unsigned iold, inew; MemoryRegionIoeventfd *fd; MemoryRegionSection section; /* Generate a symmetric difference of the old and new fd sets, adding * and deleting as necessary. Loading @@ -664,13 +612,27 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, && (inew == fds_new_nb || memory_region_ioeventfd_before(fds_old[iold], fds_new[inew]))) { as->ops->ioeventfd_del(as, &fds_old[iold]); fd = &fds_old[iold]; section = (MemoryRegionSection) { .address_space = as->root, .offset_within_address_space = int128_get64(fd->addr.start), .size = int128_get64(fd->addr.size), }; MEMORY_LISTENER_CALL(eventfd_del, Forward, §ion, fd->match_data, fd->data, fd->fd); ++iold; } else if (inew < fds_new_nb && (iold == fds_old_nb || memory_region_ioeventfd_before(fds_new[inew], fds_old[iold]))) { as->ops->ioeventfd_add(as, &fds_new[inew]); fd = &fds_new[inew]; section = (MemoryRegionSection) { .address_space = as->root, .offset_within_address_space = int128_get64(fd->addr.start), .size = int128_get64(fd->addr.size), }; MEMORY_LISTENER_CALL(eventfd_add, Reverse, §ion, fd->match_data, fd->data, fd->fd); ++inew; } else { ++iold; Loading memory.h +4 −0 Original line number Diff line number Diff line Loading @@ -185,6 +185,10 @@ struct MemoryListener { void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section); void (*log_global_start)(MemoryListener *listener); void (*log_global_stop)(MemoryListener *listener); void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd); void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd); /* Lower = earlier (during add), later (during del) */ unsigned priority; QTAILQ_ENTRY(MemoryListener) link; Loading xen-all.c +14 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,18 @@ static void xen_log_global_stop(MemoryListener *listener) { } static void xen_eventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } static void xen_eventfd_del(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } static MemoryListener xen_memory_listener = { .region_add = xen_region_add, .region_del = xen_region_del, Loading @@ -495,6 +507,8 @@ static MemoryListener xen_memory_listener = { .log_sync = xen_log_sync, .log_global_start = xen_log_global_start, .log_global_stop = xen_log_global_stop, .eventfd_add = xen_eventfd_add, .eventfd_del = xen_eventfd_del, .priority = 10, }; Loading Loading
hw/vhost.c +14 −0 Original line number Diff line number Diff line Loading @@ -720,6 +720,18 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev, 0, virtio_queue_get_desc_size(vdev, idx)); } static void vhost_eventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } static void vhost_eventfd_del(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) { uint64_t features; Loading Loading @@ -751,6 +763,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) .log_sync = vhost_log_sync, .log_global_start = vhost_log_global_start, .log_global_stop = vhost_log_global_stop, .eventfd_add = vhost_eventfd_add, .eventfd_del = vhost_eventfd_del, .priority = 10 }; hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions)); Loading
kvm-all.c +78 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include "kvm.h" #include "bswap.h" #include "memory.h" #include "exec-memory.h" /* This check must be after config-host.h is included */ #ifdef CONFIG_EVENTFD Loading Loading @@ -718,6 +719,81 @@ static void kvm_log_global_stop(struct MemoryListener *listener) assert(r >= 0); } static void kvm_mem_ioeventfd_add(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; assert(match_data && section->size == 4); r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space, data, true); if (r < 0) { abort(); } } static void kvm_mem_ioeventfd_del(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space, data, false); if (r < 0) { abort(); } } static void kvm_io_ioeventfd_add(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; assert(match_data && section->size == 2); r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, data, true); if (r < 0) { abort(); } } static void kvm_io_ioeventfd_del(MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { int r; r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, data, false); if (r < 0) { abort(); } } static void kvm_eventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { if (section->address_space == get_system_memory()) { kvm_mem_ioeventfd_add(section, match_data, data, fd); } else { kvm_io_ioeventfd_add(section, match_data, data, fd); } } static void kvm_eventfd_del(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { if (section->address_space == get_system_memory()) { kvm_mem_ioeventfd_del(section, match_data, data, fd); } else { kvm_io_ioeventfd_del(section, match_data, data, fd); } } static MemoryListener kvm_memory_listener = { .region_add = kvm_region_add, .region_del = kvm_region_del, Loading @@ -726,6 +802,8 @@ static MemoryListener kvm_memory_listener = { .log_sync = kvm_log_sync, .log_global_start = kvm_log_global_start, .log_global_stop = kvm_log_global_stop, .eventfd_add = kvm_eventfd_add, .eventfd_del = kvm_eventfd_del, .priority = 10, }; Loading
memory.c +18 −56 Original line number Diff line number Diff line Loading @@ -202,8 +202,6 @@ struct AddressSpaceOps { void (*range_del)(AddressSpace *as, FlatRange *fr); void (*log_start)(AddressSpace *as, FlatRange *fr); void (*log_stop)(AddressSpace *as, FlatRange *fr); void (*ioeventfd_add)(AddressSpace *as, MemoryRegionIoeventfd *fd); void (*ioeventfd_del)(AddressSpace *as, MemoryRegionIoeventfd *fd); }; #define FOR_EACH_FLAT_RANGE(var, view) \ Loading Loading @@ -369,37 +367,11 @@ static void as_memory_log_stop(AddressSpace *as, FlatRange *fr) { } static void as_memory_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; assert(fd->match_data && int128_get64(fd->addr.size) == 4); r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start), fd->data, true); if (r < 0) { abort(); } } static void as_memory_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; r = kvm_set_ioeventfd_mmio_long(fd->fd, int128_get64(fd->addr.start), fd->data, false); if (r < 0) { abort(); } } static const AddressSpaceOps address_space_ops_memory = { .range_add = as_memory_range_add, .range_del = as_memory_range_del, .log_start = as_memory_log_start, .log_stop = as_memory_log_stop, .ioeventfd_add = as_memory_ioeventfd_add, .ioeventfd_del = as_memory_ioeventfd_del, }; static AddressSpace address_space_memory = { Loading Loading @@ -493,35 +465,9 @@ static void as_io_range_del(AddressSpace *as, FlatRange *fr) int128_get64(fr->addr.size)); } static void as_io_ioeventfd_add(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; assert(fd->match_data && int128_get64(fd->addr.size) == 2); r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start), fd->data, true); if (r < 0) { abort(); } } static void as_io_ioeventfd_del(AddressSpace *as, MemoryRegionIoeventfd *fd) { int r; r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start), fd->data, false); if (r < 0) { abort(); } } static const AddressSpaceOps address_space_ops_io = { .range_add = as_io_range_add, .range_del = as_io_range_del, .ioeventfd_add = as_io_ioeventfd_add, .ioeventfd_del = as_io_ioeventfd_del, }; static AddressSpace address_space_io = { Loading Loading @@ -653,6 +599,8 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, unsigned fds_old_nb) { unsigned iold, inew; MemoryRegionIoeventfd *fd; MemoryRegionSection section; /* Generate a symmetric difference of the old and new fd sets, adding * and deleting as necessary. Loading @@ -664,13 +612,27 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, && (inew == fds_new_nb || memory_region_ioeventfd_before(fds_old[iold], fds_new[inew]))) { as->ops->ioeventfd_del(as, &fds_old[iold]); fd = &fds_old[iold]; section = (MemoryRegionSection) { .address_space = as->root, .offset_within_address_space = int128_get64(fd->addr.start), .size = int128_get64(fd->addr.size), }; MEMORY_LISTENER_CALL(eventfd_del, Forward, §ion, fd->match_data, fd->data, fd->fd); ++iold; } else if (inew < fds_new_nb && (iold == fds_old_nb || memory_region_ioeventfd_before(fds_new[inew], fds_old[iold]))) { as->ops->ioeventfd_add(as, &fds_new[inew]); fd = &fds_new[inew]; section = (MemoryRegionSection) { .address_space = as->root, .offset_within_address_space = int128_get64(fd->addr.start), .size = int128_get64(fd->addr.size), }; MEMORY_LISTENER_CALL(eventfd_add, Reverse, §ion, fd->match_data, fd->data, fd->fd); ++inew; } else { ++iold; Loading
memory.h +4 −0 Original line number Diff line number Diff line Loading @@ -185,6 +185,10 @@ struct MemoryListener { void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section); void (*log_global_start)(MemoryListener *listener); void (*log_global_stop)(MemoryListener *listener); void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd); void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd); /* Lower = earlier (during add), later (during del) */ unsigned priority; QTAILQ_ENTRY(MemoryListener) link; Loading
xen-all.c +14 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,18 @@ static void xen_log_global_stop(MemoryListener *listener) { } static void xen_eventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } static void xen_eventfd_del(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, int fd) { } static MemoryListener xen_memory_listener = { .region_add = xen_region_add, .region_del = xen_region_del, Loading @@ -495,6 +507,8 @@ static MemoryListener xen_memory_listener = { .log_sync = xen_log_sync, .log_global_start = xen_log_global_start, .log_global_stop = xen_log_global_stop, .eventfd_add = xen_eventfd_add, .eventfd_del = xen_eventfd_del, .priority = 10, }; Loading