From patchwork Mon Aug 1 09:16:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 9254059 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C60646075F for ; Mon, 1 Aug 2016 09:33:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B414A28335 for ; Mon, 1 Aug 2016 09:33:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A78ED28464; Mon, 1 Aug 2016 09:33:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E262F28335 for ; Mon, 1 Aug 2016 09:33:57 +0000 (UTC) Received: from localhost ([::1]:48700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bU9bh-0003vt-0X for patchwork-qemu-devel@patchwork.kernel.org; Mon, 01 Aug 2016 05:33:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42369) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bU9bH-0003sg-Og for qemu-devel@nongnu.org; Mon, 01 Aug 2016 05:33:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bU9bD-00060C-Hu for qemu-devel@nongnu.org; Mon, 01 Aug 2016 05:33:30 -0400 Received: from smtp.citrix.com ([66.165.176.89]:22992) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bU9bD-0005yz-9S for qemu-devel@nongnu.org; Mon, 01 Aug 2016 05:33:27 -0400 X-IronPort-AV: E=Sophos;i="5.28,454,1464652800"; d="scan'208";a="369547786" From: Paul Durrant To: , Date: Mon, 1 Aug 2016 10:16:25 +0100 Message-ID: <1470042985-680-1-git-send-email-paul.durrant@citrix.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-DLP: MIA1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.165.176.89 Subject: [Qemu-devel] [PATCH] xen: handle inbound migration of VMs without ioreq server pages X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Paul Durrant , Stefano Stabellini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP VMs created on older versions on Xen will not have been provisioned with pages to support creation of non-default ioreq servers. In this case the ioreq server API is not supported and QEMU's only option is to fall back to using the default ioreq server pages as it did prior to commit 3996e85c ("Xen: Use the ioreq-server API when available"). This patch therefore changes the code in xen_common.h to stop considering a failure of xc_hvm_create_ioreq_server() as a hard failure but simply as an indication that the guest is too old to support the ioreq server API. Instead a boolean is set to cause reversion to old behaviour such that the default ioreq server is then used. Signed-off-by: Paul Durrant Cc: Stefano Stabellini Cc: Anthony Perard Reported-by: Olaf Hering --- include/hw/xen/xen_common.h | 123 +++++++++++++++++++++++++++++++------------- trace-events | 1 + xen-hvm.c | 6 +-- 3 files changed, 90 insertions(+), 40 deletions(-) diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 640c31e..8707adc 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -107,6 +107,42 @@ static inline int xen_get_vmport_regs_pfn(xc_interface *xc, domid_t dom, #endif +static inline int xen_get_default_ioreq_server_info(xc_interface *xc, domid_t dom, + xen_pfn_t *ioreq_pfn, + xen_pfn_t *bufioreq_pfn, + evtchn_port_t *bufioreq_evtchn) +{ + unsigned long param; + int rc; + + rc = xc_get_hvm_param(xc, dom, HVM_PARAM_IOREQ_PFN, ¶m); + if (rc < 0) { + fprintf(stderr, "failed to get HVM_PARAM_IOREQ_PFN\n"); + return -1; + } + + *ioreq_pfn = param; + + rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_PFN, ¶m); + if (rc < 0) { + fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_PFN\n"); + return -1; + } + + *bufioreq_pfn = param; + + rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_EVTCHN, + ¶m); + if (rc < 0) { + fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN\n"); + return -1; + } + + *bufioreq_evtchn = param; + + return 0; +} + /* Xen before 4.5 */ #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 450 @@ -154,10 +190,9 @@ static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom, { } -static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom, - ioservid_t *ioservid) +static inline void xen_create_ioreq_server(xc_interface *xc, domid_t dom, + ioservid_t *ioservid) { - return 0; } static inline void xen_destroy_ioreq_server(xc_interface *xc, domid_t dom, @@ -171,35 +206,8 @@ static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom, xen_pfn_t *bufioreq_pfn, evtchn_port_t *bufioreq_evtchn) { - unsigned long param; - int rc; - - rc = xc_get_hvm_param(xc, dom, HVM_PARAM_IOREQ_PFN, ¶m); - if (rc < 0) { - fprintf(stderr, "failed to get HVM_PARAM_IOREQ_PFN\n"); - return -1; - } - - *ioreq_pfn = param; - - rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_PFN, ¶m); - if (rc < 0) { - fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_PFN\n"); - return -1; - } - - *bufioreq_pfn = param; - - rc = xc_get_hvm_param(xc, dom, HVM_PARAM_BUFIOREQ_EVTCHN, - ¶m); - if (rc < 0) { - fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN\n"); - return -1; - } - - *bufioreq_evtchn = param; - - return 0; + return xen_get_default_ioreq_server_info(xc, dom, ioreq_pfn, bufioreq_pfn, + bufioreq_evtchn); } static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom, @@ -212,6 +220,8 @@ static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom, /* Xen 4.5 */ #else +static bool use_default_ioreq_server; + static inline void xen_map_memory_section(xc_interface *xc, domid_t dom, ioservid_t ioservid, MemoryRegionSection *section) @@ -220,6 +230,10 @@ static inline void xen_map_memory_section(xc_interface *xc, domid_t dom, ram_addr_t size = int128_get64(section->size); hwaddr end_addr = start_addr + size - 1; + if (use_default_ioreq_server) { + return; + } + trace_xen_map_mmio_range(ioservid, start_addr, end_addr); xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 1, start_addr, end_addr); @@ -233,6 +247,11 @@ static inline void xen_unmap_memory_section(xc_interface *xc, domid_t dom, ram_addr_t size = int128_get64(section->size); hwaddr end_addr = start_addr + size - 1; + if (use_default_ioreq_server) { + return; + } + + trace_xen_unmap_mmio_range(ioservid, start_addr, end_addr); xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 1, start_addr, end_addr); @@ -246,6 +265,11 @@ static inline void xen_map_io_section(xc_interface *xc, domid_t dom, ram_addr_t size = int128_get64(section->size); hwaddr end_addr = start_addr + size - 1; + if (use_default_ioreq_server) { + return; + } + + trace_xen_map_portio_range(ioservid, start_addr, end_addr); xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 0, start_addr, end_addr); @@ -259,6 +283,10 @@ static inline void xen_unmap_io_section(xc_interface *xc, domid_t dom, ram_addr_t size = int128_get64(section->size); hwaddr end_addr = start_addr + size - 1; + if (use_default_ioreq_server) { + return; + } + trace_xen_unmap_portio_range(ioservid, start_addr, end_addr); xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 0, start_addr, end_addr); @@ -268,6 +296,10 @@ static inline void xen_map_pcidev(xc_interface *xc, domid_t dom, ioservid_t ioservid, PCIDevice *pci_dev) { + if (use_default_ioreq_server) { + return; + } + trace_xen_map_pcidev(ioservid, pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); xc_hvm_map_pcidev_to_ioreq_server(xc, dom, ioservid, @@ -280,6 +312,10 @@ static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom, ioservid_t ioservid, PCIDevice *pci_dev) { + if (use_default_ioreq_server) { + return; + } + trace_xen_unmap_pcidev(ioservid, pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); xc_hvm_unmap_pcidev_from_ioreq_server(xc, dom, ioservid, @@ -288,22 +324,29 @@ static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom, PCI_FUNC(pci_dev->devfn)); } -static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom, - ioservid_t *ioservid) +static inline void xen_create_ioreq_server(xc_interface *xc, domid_t dom, + ioservid_t *ioservid) { int rc = xc_hvm_create_ioreq_server(xc, dom, HVM_IOREQSRV_BUFIOREQ_ATOMIC, ioservid); if (rc == 0) { trace_xen_ioreq_server_create(*ioservid); + return; } - return rc; + *ioservid = 0; + use_default_ioreq_server = true; + trace_xen_default_ioreq_server(); } static inline void xen_destroy_ioreq_server(xc_interface *xc, domid_t dom, ioservid_t ioservid) { + if (use_default_ioreq_server) { + return; + } + trace_xen_ioreq_server_destroy(ioservid); xc_hvm_destroy_ioreq_server(xc, dom, ioservid); } @@ -314,6 +357,12 @@ static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom, xen_pfn_t *bufioreq_pfn, evtchn_port_t *bufioreq_evtchn) { + if (use_default_ioreq_server) { + return xen_get_default_ioreq_server_info(xc, dom, ioreq_pfn, + bufioreq_pfn, + bufioreq_evtchn); + } + return xc_hvm_get_ioreq_server_info(xc, dom, ioservid, ioreq_pfn, bufioreq_pfn, bufioreq_evtchn); @@ -323,6 +372,10 @@ static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom, ioservid_t ioservid, bool enable) { + if (use_default_ioreq_server) { + return 0; + } + trace_xen_ioreq_server_state(ioservid, enable); return xc_hvm_set_ioreq_server_state(xc, dom, ioservid, enable); } diff --git a/trace-events b/trace-events index 52c6a6c..616cc52 100644 --- a/trace-events +++ b/trace-events @@ -60,6 +60,7 @@ spice_vmc_event(int event) "spice vmc event %d" # xen-hvm.c xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx" xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "%#"PRIx64" size %#lx, log_dirty %i" +xen_default_ioreq_server(void) "" xen_ioreq_server_create(uint32_t id) "id: %u" xen_ioreq_server_destroy(uint32_t id) "id: %u" xen_ioreq_server_state(uint32_t id, bool enable) "id: %u: enable: %i" diff --git a/xen-hvm.c b/xen-hvm.c index eb57792..cc3d4b0 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -1203,11 +1203,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory) goto err; } - rc = xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid); - if (rc < 0) { - perror("xen: ioreq server create"); - goto err; - } + xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid); state->exit.notify = xen_exit_notifier; qemu_add_exit_notifier(&state->exit);