Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:olh:xen-4.7
xen
qemu_xen.b7665c6027c972c23668ee74b878b5c6172185...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File qemu_xen.b7665c6027c972c23668ee74b878b5c617218514.patch of Package xen
From: Paul Durrant <paul.durrant@citrix.com> Date: Mon, 1 Aug 2016 10:16:25 +0100 Subject: b7665c6027c972c23668ee74b878b5c617218514 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@citrix.com> Signed-off-by: Stefano Stabellini <sstabellini@kernel.org> Acked-by: Anthony PERARD <anthony.perard@citrix.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org> --- include/hw/xen/xen_common.h | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------- trace-events | 1 + xen-hvm.c | 6 +----- 3 files changed, 90 insertions(+), 40 deletions(-) --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -186,24 +186,60 @@ static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, } #endif /* Xen before 4.6 */ #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 460 #ifndef HVM_IOREQSRV_BUFIOREQ_ATOMIC #define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2 #endif #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 #ifndef HVM_PARAM_BUFIOREQ_EVTCHN #define HVM_PARAM_BUFIOREQ_EVTCHN 26 #endif #define IOREQ_TYPE_PCI_CONFIG 2 typedef uint16_t ioservid_t; static inline void xen_map_memory_section(XenXC xc, domid_t dom, @@ -233,193 +269,210 @@ static inline void xen_unmap_io_section(XenXC xc, domid_t dom, static inline void xen_map_pcidev(XenXC xc, domid_t dom, ioservid_t ioservid, PCIDevice *pci_dev) { } static inline void xen_unmap_pcidev(XenXC xc, domid_t dom, ioservid_t ioservid, PCIDevice *pci_dev) { } -static inline int xen_create_ioreq_server(XenXC xc, domid_t dom, - ioservid_t *ioservid) +static inline void xen_create_ioreq_server(XenXC xc, domid_t dom, + ioservid_t *ioservid) { - return 0; } static inline void xen_destroy_ioreq_server(XenXC xc, domid_t dom, ioservid_t ioservid) { } static inline int xen_get_ioreq_server_info(XenXC xc, domid_t dom, ioservid_t ioservid, 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; + return xen_get_default_ioreq_server_info(xc, dom, ioreq_pfn, bufioreq_pfn, + bufioreq_evtchn); } static inline int xen_set_ioreq_server_state(XenXC xc, domid_t dom, ioservid_t ioservid, bool enable) { return 0; } /* Xen 4.5 */ #else +static bool use_default_ioreq_server; + static inline void xen_map_memory_section(XenXC xc, domid_t dom, ioservid_t ioservid, MemoryRegionSection *section) { hwaddr start_addr = section->offset_within_address_space; 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); } static inline void xen_unmap_memory_section(XenXC xc, domid_t dom, ioservid_t ioservid, MemoryRegionSection *section) { hwaddr start_addr = section->offset_within_address_space; 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); } static inline void xen_map_io_section(XenXC xc, domid_t dom, ioservid_t ioservid, MemoryRegionSection *section) { hwaddr start_addr = section->offset_within_address_space; 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); } static inline void xen_unmap_io_section(XenXC xc, domid_t dom, ioservid_t ioservid, MemoryRegionSection *section) { hwaddr start_addr = section->offset_within_address_space; 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); } static inline void xen_map_pcidev(XenXC 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, 0, pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); } static inline void xen_unmap_pcidev(XenXC 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, 0, pci_bus_num(pci_dev->bus), PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); } -static inline int xen_create_ioreq_server(XenXC xc, domid_t dom, - ioservid_t *ioservid) +static inline void xen_create_ioreq_server(XenXC 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(XenXC 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); } static inline int xen_get_ioreq_server_info(XenXC xc, domid_t dom, ioservid_t ioservid, xen_pfn_t *ioreq_pfn, 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); } static inline int xen_set_ioreq_server_state(XenXC 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); } #endif #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 460 static inline int xen_xc_domain_add_to_physmap(XenXC xch, uint32_t domid, unsigned int space, unsigned long idx, xen_pfn_t gpfn) { --- a/trace-events +++ b/trace-events @@ -914,24 +914,25 @@ pvscsi_on_cmd_unknown_data(uint32_t data) "data for unknown command 0x:%x" pvscsi_io_write(const char* cmd, uint64_t val) "%s write: %"PRIx64"" pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val) "unknown write address: 0x%lx size: %u bytes value: 0x%"PRIx64"" pvscsi_io_read(const char* cmd, uint64_t status) "%s read: 0x%"PRIx64"" pvscsi_io_read_unknown(unsigned long addr, unsigned sz) "unknown read address: 0x%lx size: %u bytes" pvscsi_init_msi_fail(int res) "failed to initialize MSI, error %d" pvscsi_state(const char* state) "starting %s ..." pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) "%s page: %"PRIx64"" pvscsi_tx_rings_num_pages(const char* label, uint32_t num) "Number of %s pages: %u" # 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" xen_map_mmio_range(uint32_t id, uint64_t start_addr, uint64_t end_addr) "id: %u start: %#"PRIx64" end: %#"PRIx64 xen_unmap_mmio_range(uint32_t id, uint64_t start_addr, uint64_t end_addr) "id: %u start: %#"PRIx64" end: %#"PRIx64 xen_map_portio_range(uint32_t id, uint64_t start_addr, uint64_t end_addr) "id: %u start: %#"PRIx64" end: %#"PRIx64 xen_unmap_portio_range(uint32_t id, uint64_t start_addr, uint64_t end_addr) "id: %u start: %#"PRIx64" end: %#"PRIx64 xen_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x" xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u bdf: %02x.%02x.%02x" handle_ioreq(void *req, uint32_t type, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p type=%d dir=%d df=%d ptr=%d port=%#"PRIx64" data=%#"PRIx64" count=%d size=%d" handle_ioreq_read(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p read type=%d df=%d ptr=%d port=%#"PRIx64" data=%#"PRIx64" count=%d size=%d" handle_ioreq_write(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p write type=%d df=%d ptr=%d port=%#"PRIx64" data=%#"PRIx64" count=%d size=%d" --- a/xen-hvm.c +++ b/xen-hvm.c @@ -1227,29 +1227,25 @@ int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, state->xce_handle = xen_xc_evtchn_open(NULL, 0); if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) { perror("xen: event channel open"); return -1; } state->xenstore = xs_daemon_open(); if (state->xenstore == NULL) { perror("xen: xenstore open"); return -1; } - rc = xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid); - if (rc < 0) { - perror("xen: ioreq server create"); - return -1; - } + xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid); state->exit.notify = xen_exit_notifier; qemu_add_exit_notifier(&state->exit); state->suspend.notify = xen_suspend_notifier; qemu_register_suspend_notifier(&state->suspend); state->wakeup.notify = xen_wakeup_notifier; qemu_register_wakeup_notifier(&state->wakeup); rc = xen_get_ioreq_server_info(xen_xc, xen_domid, state->ioservid, &ioreq_pfn, &bufioreq_pfn,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor