On Wed, Oct 3, 2012 at 4:03 PM, Avi Kivity <a...@redhat.com> wrote: > The construct > > if (address_space == get_system_memory()) { > // memory thing > } else { > // io thing > } > > fails if we have more than two address spaces. Use a separate listener > for memory and I/O, and utilize MemoryListener's address space filtering to > fix this. > > Signed-off-by: Avi Kivity <a...@redhat.com> > --- > kvm-all.c | 83 > +++++++++++++++++++++++++++++++++------------------------------ > 1 file changed, 44 insertions(+), 39 deletions(-) > > diff --git a/kvm-all.c b/kvm-all.c > index 92a7137..c69e012 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -755,9 +755,16 @@ 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) > +static void kvm_log_nop(struct MemoryListener *listener) > { > +} > + > +static void kvm_mem_ioeventfd_add(MemoryListener *listener, > + MemoryRegionSection *section, > + bool match_data, uint64_t data, > + EventNotifier *e) > +{ > + int fd = event_notifier_get_fd(e); > int r; > > assert(match_data && section->size <= 8); > @@ -769,9 +776,12 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection > *section, > } > } > > -static void kvm_mem_ioeventfd_del(MemoryRegionSection *section, > - bool match_data, uint64_t data, int fd) > +static void kvm_mem_ioeventfd_del(MemoryListener *listener, > + MemoryRegionSection *section, > + bool match_data, uint64_t data, > + EventNotifier *e) > { > + int fd = event_notifier_get_fd(e); > int r; > > r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space, > @@ -781,9 +791,12 @@ static void kvm_mem_ioeventfd_del(MemoryRegionSection > *section, > } > } > > -static void kvm_io_ioeventfd_add(MemoryRegionSection *section, > - bool match_data, uint64_t data, int fd) > +static void kvm_io_ioeventfd_add(MemoryListener *listener, > + MemoryRegionSection *section, > + bool match_data, uint64_t data, > + EventNotifier *e) > { > + int fd = event_notifier_get_fd(e); > int r; > > assert(match_data && section->size == 2); > @@ -795,10 +808,13 @@ static void kvm_io_ioeventfd_add(MemoryRegionSection > *section, > } > } > > -static void kvm_io_ioeventfd_del(MemoryRegionSection *section, > - bool match_data, uint64_t data, int fd) > +static void kvm_io_ioeventfd_del(MemoryListener *listener, > + MemoryRegionSection *section, > + bool match_data, uint64_t data, > + EventNotifier *e) > > { > + int fd = event_notifier_get_fd(e); > int r; > > r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space, > @@ -808,34 +824,6 @@ static void kvm_io_ioeventfd_del(MemoryRegionSection > *section, > } > } > > -static void kvm_eventfd_add(MemoryListener *listener, > - MemoryRegionSection *section, > - bool match_data, uint64_t data, > - EventNotifier *e) > -{ > - if (section->address_space == get_system_memory()) { > - kvm_mem_ioeventfd_add(section, match_data, data, > - event_notifier_get_fd(e)); > - } else { > - kvm_io_ioeventfd_add(section, match_data, data, > - event_notifier_get_fd(e)); > - } > -} > - > -static void kvm_eventfd_del(MemoryListener *listener, > - MemoryRegionSection *section, > - bool match_data, uint64_t data, > - EventNotifier *e) > -{ > - if (section->address_space == get_system_memory()) { > - kvm_mem_ioeventfd_del(section, match_data, data, > - event_notifier_get_fd(e)); > - } else { > - kvm_io_ioeventfd_del(section, match_data, data, > - event_notifier_get_fd(e)); > - } > -} > - > static MemoryListener kvm_memory_listener = { > .begin = kvm_begin, > .commit = kvm_commit, > @@ -847,8 +835,24 @@ static void kvm_eventfd_del(MemoryListener *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, > + .eventfd_add = kvm_mem_ioeventfd_add, > + .eventfd_del = kvm_mem_ioeventfd_del, > + .priority = 10, > +}; > + > +static MemoryListener kvm_io_listener = {
const > + .begin = kvm_begin, > + .commit = kvm_commit, > + .region_add = kvm_region_nop, > + .region_del = kvm_region_nop, > + .region_nop = kvm_region_nop, > + .log_start = kvm_region_nop, > + .log_stop = kvm_region_nop, > + .log_sync = kvm_region_nop, > + .log_global_start = kvm_log_nop, > + .log_global_stop = kvm_log_nop, > + .eventfd_add = kvm_io_ioeventfd_add, > + .eventfd_del = kvm_io_ioeventfd_del, > .priority = 10, > }; > > @@ -1401,7 +1405,8 @@ int kvm_init(void) > } > > kvm_state = s; > - memory_listener_register(&kvm_memory_listener, NULL); > + memory_listener_register(&kvm_memory_listener, get_system_memory()); > + memory_listener_register(&kvm_io_listener, get_system_io()); > > s->many_ioeventfds = kvm_check_many_ioeventfds(); > > -- > 1.7.12 >