From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:39219) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SAkVi-0007OZ-S2 for qemu-devel@nongnu.org; Thu, 22 Mar 2012 12:05:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SAkVd-0005SR-4m for qemu-devel@nongnu.org; Thu, 22 Mar 2012 12:05:10 -0400 Received: from smtp02.citrix.com ([66.165.176.63]:21091) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SAkVc-0005PP-Pp for qemu-devel@nongnu.org; Thu, 22 Mar 2012 12:05:05 -0400 From: Julien Grall Date: Thu, 22 Mar 2012 16:01:55 +0000 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [QEMU][RFC PATCH 3/6] memory: Add xen memory hook List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: xen-devel@lists.xensource.com, julian.pidancet@citrix.com, Stefano.Stabellini@eu.citrix.com QEMU will now register all memory range (PIO and MMIO) in Xen. We distinct two phases in memory registered : - initialization - running For all range registered during the initialization, QEMU will check with XenStore if it is authorized to use them. After the initialization, QEMU can register all range. Indeed, the new ranges will be for PCI Bar. Signed-off-by: Julien Grall --- exec.c | 9 ++++++ ioport.c | 17 ++++++++++++ xen-all.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 0 deletions(-) diff --git a/exec.c b/exec.c index 780f63f..42d8c56 100644 --- a/exec.c +++ b/exec.c @@ -3557,12 +3557,21 @@ static void core_commit(MemoryListener *listener) static void core_region_add(MemoryListener *listener, MemoryRegionSection *section) { + if (xen_enabled()) { + xen_map_iorange(section->offset_within_address_space, + section->size, 1); + } + cpu_register_physical_memory_log(section, section->readonly); } static void core_region_del(MemoryListener *listener, MemoryRegionSection *section) { + if (xen_enabled()) { + xen_unmap_iorange(section->offset_within_address_space, + section->size, 1); + } } static void core_region_nop(MemoryListener *listener, diff --git a/ioport.c b/ioport.c index 78a3b89..073ed75 100644 --- a/ioport.c +++ b/ioport.c @@ -28,6 +28,7 @@ #include "ioport.h" #include "trace.h" #include "memory.h" +#include "hw/xen.h" /***********************************************************/ /* IO Port */ @@ -155,6 +156,11 @@ int register_ioport_read(pio_addr_t start, int length, int size, i); ioport_opaque[i] = opaque; } + + if (xen_enabled()) { + xen_map_iorange(start, length, 0); + } + return 0; } @@ -175,7 +181,13 @@ int register_ioport_write(pio_addr_t start, int length, int size, i); ioport_opaque[i] = opaque; } + + if (xen_enabled()) { + xen_map_iorange(start, length, 0); + } + return 0; + } static uint32_t ioport_readb_thunk(void *opaque, uint32_t addr) @@ -260,6 +272,11 @@ void isa_unassign_ioport(pio_addr_t start, int length) ioport_destructor_table[start](ioport_opaque[start]); ioport_destructor_table[start] = NULL; } + + if (xen_enabled()) { + xen_unmap_iorange(start, length, 0); + } + for(i = start; i < start + length; i++) { ioport_read_table[0][i] = NULL; ioport_read_table[1][i] = NULL; diff --git a/xen-all.c b/xen-all.c index f007278..366bafe 100644 --- a/xen-all.c +++ b/xen-all.c @@ -124,6 +124,89 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } +static void str_to_range(const char *str, uint64_t *begin, uint64_t *end) +{ + char *buf; + + /* We assume that range is valid */ + *begin = strtoll(str, &buf, 0); + if (buf[0] == '\0') { + *end = *begin; + return; + } + + str = buf + 1; + *end = strtoll(str, &buf, 0); +} + +static int check_range(uint64_t addr, uint64_t size, int is_mmio) +{ + struct xs_handle *xs = NULL; + char **dir; + char *str; + int rc = 1; + int i; + uint64_t begin; + uint64_t end; + char base[70]; + char path[70]; + unsigned int nb; + unsigned int len; + + xs = xs_open(0); + if (!xs) { + fprintf(stderr, "check_range: unable to open xenstore\n"); + return 1; + } + + snprintf(base, sizeof (base), "/local/domain/%u/image/dms/%u/%s", + xen_domid, xen_dmid, (is_mmio) ? "mmio" : "pio"); + dir = xs_directory(xs, XBT_NULL, base, &nb); + + if (dir) { + for (i = 0; i < nb; i++) { + snprintf(path, sizeof (path), "%s/%s", base, dir[i]); + str = xs_read(xs, XBT_NULL, path, &len); + str_to_range(str, &begin, &end); + free(str); + if (addr == begin && (addr + size - 1) == end) { + rc = 0; + break; + } + } + free(dir); + } + + return rc; +} + +void xen_map_iorange(uint64_t addr, uint64_t size, int is_mmio) +{ + static uint64_t previous_addr = ~0; + + /* Don't register multiple times the same ioport */ + if (!is_mmio) { + if (addr == previous_addr) + return; + previous_addr = addr; + } + + if (!is_running) { + if (check_range(addr, size, is_mmio)) { + return; + } + } + + xc_hvm_map_io_range_to_ioreq_server(xen_xc, xen_domid, serverid, is_mmio, + addr, addr + size - 1); +} + +void xen_unmap_iorange(uint64_t addr, uint64_t size, int is_mmio) +{ + 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); -- Julien Grall From mboxrd@z Thu Jan 1 00:00:00 1970 From: Julien Grall Subject: [QEMU][RFC PATCH 3/6] memory: Add xen memory hook Date: Thu, 22 Mar 2012 16:01:55 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: qemu-devel@nongnu.org Cc: xen-devel@lists.xensource.com, julian.pidancet@citrix.com, Stefano.Stabellini@eu.citrix.com List-Id: xen-devel@lists.xenproject.org QEMU will now register all memory range (PIO and MMIO) in Xen. We distinct two phases in memory registered : - initialization - running For all range registered during the initialization, QEMU will check with XenStore if it is authorized to use them. After the initialization, QEMU can register all range. Indeed, the new ranges will be for PCI Bar. Signed-off-by: Julien Grall --- exec.c | 9 ++++++ ioport.c | 17 ++++++++++++ xen-all.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 0 deletions(-) diff --git a/exec.c b/exec.c index 780f63f..42d8c56 100644 --- a/exec.c +++ b/exec.c @@ -3557,12 +3557,21 @@ static void core_commit(MemoryListener *listener) static void core_region_add(MemoryListener *listener, MemoryRegionSection *section) { + if (xen_enabled()) { + xen_map_iorange(section->offset_within_address_space, + section->size, 1); + } + cpu_register_physical_memory_log(section, section->readonly); } static void core_region_del(MemoryListener *listener, MemoryRegionSection *section) { + if (xen_enabled()) { + xen_unmap_iorange(section->offset_within_address_space, + section->size, 1); + } } static void core_region_nop(MemoryListener *listener, diff --git a/ioport.c b/ioport.c index 78a3b89..073ed75 100644 --- a/ioport.c +++ b/ioport.c @@ -28,6 +28,7 @@ #include "ioport.h" #include "trace.h" #include "memory.h" +#include "hw/xen.h" /***********************************************************/ /* IO Port */ @@ -155,6 +156,11 @@ int register_ioport_read(pio_addr_t start, int length, int size, i); ioport_opaque[i] = opaque; } + + if (xen_enabled()) { + xen_map_iorange(start, length, 0); + } + return 0; } @@ -175,7 +181,13 @@ int register_ioport_write(pio_addr_t start, int length, int size, i); ioport_opaque[i] = opaque; } + + if (xen_enabled()) { + xen_map_iorange(start, length, 0); + } + return 0; + } static uint32_t ioport_readb_thunk(void *opaque, uint32_t addr) @@ -260,6 +272,11 @@ void isa_unassign_ioport(pio_addr_t start, int length) ioport_destructor_table[start](ioport_opaque[start]); ioport_destructor_table[start] = NULL; } + + if (xen_enabled()) { + xen_unmap_iorange(start, length, 0); + } + for(i = start; i < start + length; i++) { ioport_read_table[0][i] = NULL; ioport_read_table[1][i] = NULL; diff --git a/xen-all.c b/xen-all.c index f007278..366bafe 100644 --- a/xen-all.c +++ b/xen-all.c @@ -124,6 +124,89 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } +static void str_to_range(const char *str, uint64_t *begin, uint64_t *end) +{ + char *buf; + + /* We assume that range is valid */ + *begin = strtoll(str, &buf, 0); + if (buf[0] == '\0') { + *end = *begin; + return; + } + + str = buf + 1; + *end = strtoll(str, &buf, 0); +} + +static int check_range(uint64_t addr, uint64_t size, int is_mmio) +{ + struct xs_handle *xs = NULL; + char **dir; + char *str; + int rc = 1; + int i; + uint64_t begin; + uint64_t end; + char base[70]; + char path[70]; + unsigned int nb; + unsigned int len; + + xs = xs_open(0); + if (!xs) { + fprintf(stderr, "check_range: unable to open xenstore\n"); + return 1; + } + + snprintf(base, sizeof (base), "/local/domain/%u/image/dms/%u/%s", + xen_domid, xen_dmid, (is_mmio) ? "mmio" : "pio"); + dir = xs_directory(xs, XBT_NULL, base, &nb); + + if (dir) { + for (i = 0; i < nb; i++) { + snprintf(path, sizeof (path), "%s/%s", base, dir[i]); + str = xs_read(xs, XBT_NULL, path, &len); + str_to_range(str, &begin, &end); + free(str); + if (addr == begin && (addr + size - 1) == end) { + rc = 0; + break; + } + } + free(dir); + } + + return rc; +} + +void xen_map_iorange(uint64_t addr, uint64_t size, int is_mmio) +{ + static uint64_t previous_addr = ~0; + + /* Don't register multiple times the same ioport */ + if (!is_mmio) { + if (addr == previous_addr) + return; + previous_addr = addr; + } + + if (!is_running) { + if (check_range(addr, size, is_mmio)) { + return; + } + } + + xc_hvm_map_io_range_to_ioreq_server(xen_xc, xen_domid, serverid, is_mmio, + addr, addr + size - 1); +} + +void xen_unmap_iorange(uint64_t addr, uint64_t size, int is_mmio) +{ + 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); -- Julien Grall