Message ID | b7c4e2af5c7a7091d99cd8e0d838fb09daa376e5.1345637459.git.julien.grall@citrix.com |
---|---|
State | New |
Headers | show |
On Wed, 22 Aug 2012, Julien Grall wrote: > Add Memory listener on IO and modify the one on memory. > Becareful, the first listener is not called is the range is still register with > register_ioport*. So Xen will never know that this QEMU is handle the range. I don't understand what you mean here. Could you please elaborate? > IO request works as before, the only thing is QEMU will never receive IO request > that it can't handle. > > y Changes to be committed: Just remove this line from the commit message. > Signed-off-by: Julien Grall <julien.grall@citrix.com> > --- > xen-all.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 113 insertions(+), 0 deletions(-) > > diff --git a/xen-all.c b/xen-all.c > index 5f05838..14e5d3d 100644 > --- a/xen-all.c > +++ b/xen-all.c > @@ -152,6 +152,7 @@ typedef struct XenIOState { > > struct xs_handle *xenstore; > MemoryListener memory_listener; > + MemoryListener io_listener; > QLIST_HEAD(, XenPhysmap) physmap; > target_phys_addr_t free_phys_offset; > const XenPhysmap *log_for_dirtybit; > @@ -195,6 +196,31 @@ void xen_hvm_inject_msi(uint64_t addr, uint32_t data) > xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data); > } > > +static void xen_map_iorange(target_phys_addr_t addr, uint64_t size, > + int is_mmio, const char *name) > +{ > + /* Don't register xen.ram */ > + if (is_mmio && !strncmp(name, "xen.ram", 7)) { > + return; > + } > + > + DPRINTF("map %s %s 0x"TARGET_FMT_plx" - 0x"TARGET_FMT_plx"\n", > + (is_mmio) ? "mmio" : "io", name, addr, addr + size - 1); > + > + xen_xc_hvm_map_io_range_to_ioreq_server(xen_xc, xen_domid, serverid, > + is_mmio, addr, addr + size - 1); > +} > + > +static void xen_unmap_iorange(target_phys_addr_t addr, uint64_t size, > + int is_mmio) > +{ > + DPRINTF("unmap %s %s 0x"TARGET_FMT_plx" - 0x"TARGET_FMT_plx"\n", > + (is_mmio) ? "mmio" : "io", name, addr, addr + size - 1); > + > + xen_xc_hvm_unmap_io_range_from_ioreq_server(xen_xc, xen_domid, serverid, > + is_mmio, addr); > +} > + > static void xen_suspend_notifier(Notifier *notifier, void *data) > { > xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); > @@ -527,12 +553,16 @@ static void xen_region_add(MemoryListener *listener, > MemoryRegionSection *section) > { > xen_set_memory(listener, section, true); > + xen_map_iorange(section->offset_within_address_space, > + section->size, 1, section->mr->name); > } > > static void xen_region_del(MemoryListener *listener, > MemoryRegionSection *section) > { > xen_set_memory(listener, section, false); > + xen_unmap_iorange(section->offset_within_address_space, > + section->size, 1); > } > > static void xen_region_nop(MemoryListener *listener, > @@ -651,6 +681,86 @@ static MemoryListener xen_memory_listener = { > .priority = 10, > }; > > +static void xen_io_begin(MemoryListener *listener) > +{ > +} > + > +static void xen_io_commit(MemoryListener *listener) > +{ > +} > + > +static void xen_io_region_add(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > + xen_map_iorange(section->offset_within_address_space, > + section->size, 0, section->mr->name); > +} > + > +static void xen_io_region_del(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > + xen_unmap_iorange(section->offset_within_address_space, > + section->size, 0); > +} > + > +static void xen_io_region_nop(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > +} > + > +static void xen_io_log_start(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > +} > + > +static void xen_io_log_stop(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > +} > + > +static void xen_io_log_sync(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > +} > + > +static void xen_io_log_global_start(MemoryListener *listener) > +{ > +} > + > +static void xen_io_log_global_stop(MemoryListener *listener) > +{ > +} > + > +static void xen_io_eventfd_add(MemoryListener *listener, > + MemoryRegionSection *section, > + bool match_data, uint64_t data, > + EventNotifier *e) > +{ > +} > + > +static void xen_io_eventfd_del(MemoryListener *listener, > + MemoryRegionSection *section, > + bool match_data, uint64_t data, > + EventNotifier *e) > +{ > +} > + > +static MemoryListener xen_io_listener = { > + .begin = xen_io_begin, > + .commit = xen_io_commit, > + .region_add = xen_io_region_add, > + .region_del = xen_io_region_del, > + .region_nop = xen_io_region_nop, > + .log_start = xen_io_log_start, > + .log_stop = xen_io_log_stop, > + .log_sync = xen_io_log_sync, > + .log_global_start = xen_io_log_global_start, > + .log_global_stop = xen_io_log_global_stop, > + .eventfd_add = xen_io_eventfd_add, > + .eventfd_del = xen_io_eventfd_del, > + .priority = 10, > +}; > + > /* VCPU Operations, MMIO, IO ring ... */ > > static void xen_reset_vcpu(void *opaque) > @@ -1239,6 +1349,9 @@ int xen_hvm_init(void) > memory_listener_register(&state->memory_listener, get_system_memory()); > state->log_for_dirtybit = NULL; > > + state->io_listener = xen_io_listener; > + memory_listener_register(&state->io_listener, get_system_io()); > + > /* Initialize backend core & drivers */ > if (xen_be_init() != 0) { > fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__); > -- > Julien Grall >
On 08/23/2012 03:41 PM, Stefano Stabellini wrote: > On Wed, 22 Aug 2012, Julien Grall wrote: > >> Add Memory listener on IO and modify the one on memory. >> Becareful, the first listener is not called is the range is still register with >> register_ioport*. So Xen will never know that this QEMU is handle the range. >> > I don't understand what you mean here. Could you please elaborate? > I made a patch series to remove all ioport_register_* function in differents devices (dma, cirrus, ...): https://lists.gnu.org/archive/html/qemu-devel/2012-08/msg04007.html ioport_register_* don' t use the new memory API, so listener is not called when a new range is registered. I will rework the commit message and send it back.
diff --git a/xen-all.c b/xen-all.c index 5f05838..14e5d3d 100644 --- a/xen-all.c +++ b/xen-all.c @@ -152,6 +152,7 @@ typedef struct XenIOState { struct xs_handle *xenstore; MemoryListener memory_listener; + MemoryListener io_listener; QLIST_HEAD(, XenPhysmap) physmap; target_phys_addr_t free_phys_offset; const XenPhysmap *log_for_dirtybit; @@ -195,6 +196,31 @@ void xen_hvm_inject_msi(uint64_t addr, uint32_t data) xen_xc_hvm_inject_msi(xen_xc, xen_domid, addr, data); } +static void xen_map_iorange(target_phys_addr_t addr, uint64_t size, + int is_mmio, const char *name) +{ + /* Don't register xen.ram */ + if (is_mmio && !strncmp(name, "xen.ram", 7)) { + return; + } + + DPRINTF("map %s %s 0x"TARGET_FMT_plx" - 0x"TARGET_FMT_plx"\n", + (is_mmio) ? "mmio" : "io", name, addr, addr + size - 1); + + xen_xc_hvm_map_io_range_to_ioreq_server(xen_xc, xen_domid, serverid, + is_mmio, addr, addr + size - 1); +} + +static void xen_unmap_iorange(target_phys_addr_t addr, uint64_t size, + int is_mmio) +{ + DPRINTF("unmap %s %s 0x"TARGET_FMT_plx" - 0x"TARGET_FMT_plx"\n", + (is_mmio) ? "mmio" : "io", name, addr, addr + size - 1); + + xen_xc_hvm_unmap_io_range_from_ioreq_server(xen_xc, xen_domid, serverid, + is_mmio, addr); +} + static void xen_suspend_notifier(Notifier *notifier, void *data) { xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); @@ -527,12 +553,16 @@ static void xen_region_add(MemoryListener *listener, MemoryRegionSection *section) { xen_set_memory(listener, section, true); + xen_map_iorange(section->offset_within_address_space, + section->size, 1, section->mr->name); } static void xen_region_del(MemoryListener *listener, MemoryRegionSection *section) { xen_set_memory(listener, section, false); + xen_unmap_iorange(section->offset_within_address_space, + section->size, 1); } static void xen_region_nop(MemoryListener *listener, @@ -651,6 +681,86 @@ static MemoryListener xen_memory_listener = { .priority = 10, }; +static void xen_io_begin(MemoryListener *listener) +{ +} + +static void xen_io_commit(MemoryListener *listener) +{ +} + +static void xen_io_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + xen_map_iorange(section->offset_within_address_space, + section->size, 0, section->mr->name); +} + +static void xen_io_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ + xen_unmap_iorange(section->offset_within_address_space, + section->size, 0); +} + +static void xen_io_region_nop(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + +static void xen_io_log_start(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + +static void xen_io_log_stop(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + +static void xen_io_log_sync(MemoryListener *listener, + MemoryRegionSection *section) +{ +} + +static void xen_io_log_global_start(MemoryListener *listener) +{ +} + +static void xen_io_log_global_stop(MemoryListener *listener) +{ +} + +static void xen_io_eventfd_add(MemoryListener *listener, + MemoryRegionSection *section, + bool match_data, uint64_t data, + EventNotifier *e) +{ +} + +static void xen_io_eventfd_del(MemoryListener *listener, + MemoryRegionSection *section, + bool match_data, uint64_t data, + EventNotifier *e) +{ +} + +static MemoryListener xen_io_listener = { + .begin = xen_io_begin, + .commit = xen_io_commit, + .region_add = xen_io_region_add, + .region_del = xen_io_region_del, + .region_nop = xen_io_region_nop, + .log_start = xen_io_log_start, + .log_stop = xen_io_log_stop, + .log_sync = xen_io_log_sync, + .log_global_start = xen_io_log_global_start, + .log_global_stop = xen_io_log_global_stop, + .eventfd_add = xen_io_eventfd_add, + .eventfd_del = xen_io_eventfd_del, + .priority = 10, +}; + /* VCPU Operations, MMIO, IO ring ... */ static void xen_reset_vcpu(void *opaque) @@ -1239,6 +1349,9 @@ int xen_hvm_init(void) memory_listener_register(&state->memory_listener, get_system_memory()); state->log_for_dirtybit = NULL; + state->io_listener = xen_io_listener; + memory_listener_register(&state->io_listener, get_system_io()); + /* Initialize backend core & drivers */ if (xen_be_init() != 0) { fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
Add Memory listener on IO and modify the one on memory. Becareful, the first listener is not called is the range is still register with register_ioport*. So Xen will never know that this QEMU is handle the range. IO request works as before, the only thing is QEMU will never receive IO request that it can't handle. y Changes to be committed: Signed-off-by: Julien Grall <julien.grall@citrix.com> --- xen-all.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 113 insertions(+), 0 deletions(-)