diff mbox

[QEMU,RFC,V2,05/10] xen-memory: register memory/IO range in Xen

Message ID b7c4e2af5c7a7091d99cd8e0d838fb09daa376e5.1345637459.git.julien.grall@citrix.com
State New
Headers show

Commit Message

Julien Grall Aug. 22, 2012, 12:30 p.m. UTC
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(-)

Comments

Stefano Stabellini Aug. 23, 2012, 2:41 p.m. UTC | #1
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
>
Julien Grall Aug. 23, 2012, 5:18 p.m. UTC | #2
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 mbox

Patch

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__);