From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42922) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bU9dR-0005OZ-C5 for qemu-devel@nongnu.org; Mon, 01 Aug 2016 05:35:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bU9dN-0006g1-Qg for qemu-devel@nongnu.org; Mon, 01 Aug 2016 05:35:44 -0400 Received: from smtp.ctxuk.citrix.com ([185.25.65.24]:54529 helo=SMTP.EU.CITRIX.COM) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bU9dN-0006fn-CK for qemu-devel@nongnu.org; Mon, 01 Aug 2016 05:35:41 -0400 From: Paul Durrant Date: Mon, 1 Aug 2016 09:35:38 +0000 Message-ID: <73ddce73d8c04d1783cb87ea07733cc4@AMSPEX02CL03.citrite.net> References: <1470042985-680-1-git-send-email-paul.durrant@citrix.com> In-Reply-To: <1470042985-680-1-git-send-email-paul.durrant@citrix.com> Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH] xen: handle inbound migration of VMs without ioreq server pages List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paul Durrant , "xen-devel@lists.xenproject.org" , "qemu-devel@nongnu.org" Cc: Stefano Stabellini , Anthony Perard , Olaf Hering > -----Original Message----- > From: Paul Durrant [mailto:paul.durrant@citrix.com] > Sent: 01 August 2016 10:16 > To: xen-devel@lists.xenproject.org; qemu-devel@nongnu.org > Cc: Paul Durrant; Stefano Stabellini; Anthony Perard > Subject: [PATCH] xen: handle inbound migration of VMs without ioreq serve= r > pages >=20 > 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"). >=20 > 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. >=20 > Signed-off-by: Paul Durrant > Cc: Stefano Stabellini > Cc: Anthony Perard Apologies, this should also be 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(-) >=20 > 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, >=20 > #endif >=20 > +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 *bufio= req_evtchn) > +{ > + unsigned long param; > + int rc; > + > + rc =3D 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 =3D param; > + > + rc =3D 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 =3D param; > + > + rc =3D 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 =3D param; > + > + return 0; > +} > + > /* Xen before 4.5 */ > #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 450 >=20 > @@ -154,10 +190,9 @@ static inline void xen_unmap_pcidev(xc_interface > *xc, domid_t dom, > { > } >=20 > -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; > } >=20 > static inline void xen_destroy_ioreq_server(xc_interface *xc, domid_t do= m, > @@ -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_evtc= hn) > { > - unsigned long param; > - int rc; > - > - rc =3D 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 =3D param; > - > - rc =3D 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 =3D param; > - > - rc =3D 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 =3D param; > - > - return 0; > + return xen_get_default_ioreq_server_info(xc, dom, ioreq_pfn, > bufioreq_pfn, > + bufioreq_evtchn); > } >=20 > static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t d= om, > @@ -212,6 +220,8 @@ static inline int > xen_set_ioreq_server_state(xc_interface *xc, domid_t dom, > /* Xen 4.5 */ > #else >=20 > +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 =3D int128_get64(section->size); > hwaddr end_addr =3D start_addr + size - 1; >=20 > + 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 =3D int128_get64(section->size); > hwaddr end_addr =3D start_addr + size - 1; >=20 > + 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 =3D int128_get64(section->size); > hwaddr end_addr =3D start_addr + size - 1; >=20 > + 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 =3D int128_get64(section->size); > hwaddr end_addr =3D start_addr + size - 1; >=20 > + 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->dev= fn)); > 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->d= evfn)); > 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)); > } >=20 > -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 =3D xc_hvm_create_ioreq_server(xc, dom, > HVM_IOREQSRV_BUFIOREQ_ATOMIC, > ioservid); >=20 > if (rc =3D=3D 0) { > trace_xen_ioreq_server_create(*ioservid); > + return; > } >=20 > - return rc; > + *ioservid =3D 0; > + use_default_ioreq_server =3D true; > + trace_xen_default_ioreq_server(); > } >=20 > static inline void xen_destroy_ioreq_server(xc_interface *xc, domid_t do= m, > 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_evtc= hn) > { > + 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; > } >=20 > - rc =3D 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); >=20 > state->exit.notify =3D xen_exit_notifier; > qemu_add_exit_notifier(&state->exit); > -- > 2.1.4