[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] xen: handle inbound migration of VMs without ioreq server pages



> -----Original Message-----
> From: Paul Durrant [mailto:paul.durrant@xxxxxxxxxx]
> Sent: 01 August 2016 10:16
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx; qemu-devel@xxxxxxxxxx
> Cc: Paul Durrant; Stefano Stabellini; Anthony Perard
> Subject: [PATCH] xen: handle inbound migration of VMs without ioreq server
> pages
> 
> 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 <paul.durrant@xxxxxxxxxx>
> Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> Cc: Anthony Perard <anthony.perard@xxxxxxxxxx>

Apologies, this should also be

Reported-by: Olaf Hering <olaf@xxxxxxxxx>

> ---
>  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, &param);
> +    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,
> &param);
> +    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,
> +                          &param);
> +    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, &param);
> -    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,
> &param);
> -    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,
> -                          &param);
> -    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);
> --
> 2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.