Skip to content

Commit

Permalink
kvm: use separate MemoryListeners for memory and I/O
Browse files Browse the repository at this point in the history
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 <avi@redhat.com>
  • Loading branch information
avikivity committed Oct 15, 2012
1 parent 0fada67 commit d22b096
Showing 1 changed file with 44 additions and 39 deletions.
83 changes: 44 additions & 39 deletions kvm-all.c
Expand Up @@ -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);
Expand All @@ -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,
Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -847,8 +835,24 @@ 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,
.eventfd_add = kvm_mem_ioeventfd_add,
.eventfd_del = kvm_mem_ioeventfd_del,
.priority = 10,
};

static MemoryListener kvm_io_listener = {
.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,
};

Expand Down Expand Up @@ -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();

Expand Down

0 comments on commit d22b096

Please sign in to comment.