* [PATCH qemu-traditional] switch to the new ioreq server API
@ 2017-09-06 9:28 Vitaly Kuznetsov
2017-09-06 9:36 ` Paul Durrant
0 siblings, 1 reply; 3+ messages in thread
From: Vitaly Kuznetsov @ 2017-09-06 9:28 UTC (permalink / raw)
To: xen-devel; +Cc: Paul Durrant, Ian Jackson
Instead of using implicit ioreq server creation side-effect upon reading
HVM params switch qemu-traditional to using explicit APIs. This opens a
possibility for removing the above mentioned side-effect and special
'default_ioreq_server' code pathes in Xen hypervisor in the future.
This also solves an issue with soft reset when qemu-traditional is being
used. Xen c/s e7dabe5 ("x86/hvm: don't unconditionally create a default
ioreq server") disabled ioreq server creation after domain was created
for the first time and this is needed for soft reset.
IOREQ_TYPE_PCI_CONFIG handling code is stolen as-is from qemu-upstream.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
hw/pci.c | 5 ++
hw/xen_common.h | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/xen_machine_fv.c | 31 ++++++++--
i386-dm/exec-dm.c | 7 +++
i386-dm/helper2.c | 31 +++++++---
vl.c | 9 +++
| 3 +
7 files changed, 236 insertions(+), 13 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index c4232856..d6cafb3e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -34,6 +34,7 @@
#ifdef CONFIG_PASSTHROUGH
#include "hw/pass-through.h"
#endif
+#include "hw/xen_common.h"
extern int igd_passthru;
@@ -248,6 +249,10 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
return NULL;
found: ;
}
+
+ xen_map_pcidev(xc_handle, domid, ioservid, 0,
+ PCI_SLOT(devfn), PCI_FUNC(devfn));
+
pci_dev = qemu_mallocz(instance_size);
pci_dev->bus = bus;
pci_dev->devfn = devfn;
diff --git a/hw/xen_common.h b/hw/xen_common.h
index cc48892f..5e172bb2 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -33,4 +33,167 @@
# define xen_wmb() wmb()
#endif
+extern uint16_t ioservid;
+
+#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040500
+static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom,
+ uint16_t *ioservid)
+{
+ return 0;
+}
+
+static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ xen_pfn_t *ioreq_pfn,
+ xen_pfn_t *bufioreq_pfn,
+ uint32_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;
+}
+
+static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ bool enable)
+{
+ return 0;
+}
+
+static inline void xen_map_memory_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+}
+
+static inline void xen_unmap_memory_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+}
+
+static inline void xen_map_io_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+}
+
+static inline void xen_unmap_io_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+}
+
+static inline void xen_map_pcidev(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint8_t bus, uint8_t device,
+ uint8_t function)
+{
+}
+
+static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint8_t bus, uint8_t device,
+ uint8_t function)
+{
+}
+#else
+static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom,
+ uint16_t *ioservid)
+{
+ int rc = xc_hvm_create_ioreq_server(xc, dom, 1, ioservid);
+
+ return rc;
+}
+
+static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ xen_pfn_t *ioreq_pfn,
+ xen_pfn_t *bufioreq_pfn,
+ uint32_t *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(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ bool enable)
+{
+ return xc_hvm_set_ioreq_server_state(xc, dom, ioservid, enable);
+}
+
+static inline void xen_map_memory_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+ xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 1, start, end);
+}
+
+static inline void xen_unmap_memory_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+ xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 1, start, end);
+}
+
+static inline void xen_map_io_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+ xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 0, start, end);
+}
+
+static inline void xen_unmap_io_section(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint64_t start, uint64_t end)
+{
+ xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 0, start, end);
+}
+
+static inline void xen_map_pcidev(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint8_t bus, uint8_t device,
+ uint8_t function)
+{
+ xc_hvm_map_pcidev_to_ioreq_server(xc, dom, ioservid, 0,
+ bus, device, function);
+}
+
+static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
+ uint16_t ioservid,
+ uint8_t bus, uint8_t device,
+ uint8_t function)
+{
+ xc_hvm_unmap_pcidev_from_ioreq_server(xc, dom, ioservid, 0,
+ bus, device, function);
+}
+#endif
+
#endif /* QEMU_HW_XEN_COMMON_H */
diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c
index b385d6a5..edb8167d 100644
--- a/hw/xen_machine_fv.c
+++ b/hw/xen_machine_fv.c
@@ -277,7 +277,8 @@ static void xen_init_fv(ram_addr_t ram_size, int vga_ram_size,
const char *initrd_filename, const char *cpu_model,
const char *direct_pci)
{
- unsigned long ioreq_pfn;
+ unsigned long ioreq_pfn, bufioreq_pfn;
+ extern uint32_t bufioreq_evtchn;
extern void *shared_page;
extern void *buffered_io_page;
#ifdef __ia64__
@@ -286,6 +287,7 @@ static void xen_init_fv(ram_addr_t ram_size, int vga_ram_size,
extern void *buffered_pio_page;
int i;
#endif
+ int rc;
#if defined(__i386__) || defined(__x86_64__)
@@ -298,7 +300,21 @@ static void xen_init_fv(ram_addr_t ram_size, int vga_ram_size,
#ifdef CONFIG_STUBDOM /* the hvmop is not supported on older hypervisors */
xc_set_hvm_param(xc_handle, domid, HVM_PARAM_DM_DOMAIN, DOMID_SELF);
#endif
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
+ rc = xen_create_ioreq_server(xc_handle, domid, &ioservid);
+ if (rc < 0) {
+ fprintf(logfile, "failed to create ioreq server: error %d\n", errno);
+ exit(-1);
+ }
+
+ fprintf(logfile, "created ioreq server %d\n", ioservid);
+
+ rc = xen_get_ioreq_server_info(xc_handle, domid, ioservid, &ioreq_pfn,
+ &bufioreq_pfn, &bufioreq_evtchn);
+ if (rc < 0) {
+ fprintf(logfile, "failed to get ioreq server info: error %d\n", errno);
+ exit(-1);
+ }
+
fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
PROT_READ|PROT_WRITE, ioreq_pfn);
@@ -307,15 +323,20 @@ static void xen_init_fv(ram_addr_t ram_size, int vga_ram_size,
exit(-1);
}
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
- fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
+ fprintf(logfile, "buffered io page at pfn %lx\n", bufioreq_pfn);
buffered_io_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
- PROT_READ|PROT_WRITE, ioreq_pfn);
+ PROT_READ|PROT_WRITE, bufioreq_pfn);
if (buffered_io_page == NULL) {
fprintf(logfile, "map buffered IO page returned error %d\n", errno);
exit(-1);
}
+ rc = xen_set_ioreq_server_state(xc_handle, domid, ioservid, true);
+ if (rc < 0) {
+ fprintf(logfile, "failed to enable ioreq server %d\n", errno);
+ exit(-1);
+ }
+
#if defined(__ia64__)
xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFPIOREQ_PFN, &ioreq_pfn);
fprintf(logfile, "buffered pio page at pfn %lx\n", ioreq_pfn);
diff --git a/i386-dm/exec-dm.c b/i386-dm/exec-dm.c
index 96274d9d..783685ce 100644
--- a/i386-dm/exec-dm.c
+++ b/i386-dm/exec-dm.c
@@ -40,6 +40,7 @@
#include "pc.h"
#include "disas.h"
#include "qemu-xen.h"
+#include "xen_common.h"
//#define DEBUG_TB_INVALIDATE
//#define DEBUG_FLUSH
@@ -308,6 +309,9 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
mmio[mmio_cnt].io_index = phys_offset;
mmio[mmio_cnt].start = start_addr;
mmio[mmio_cnt++].size = size;
+
+ xen_map_memory_section(xc_handle, domid, ioservid, start_addr,
+ start_addr + size -1);
}
static int get_free_io_mem_idx(void)
@@ -476,6 +480,9 @@ void unregister_iomem(target_phys_addr_t start)
(unsigned long)(mmio[index].start),
(unsigned long)(mmio[index].start + mmio[index].size));
mmio[index].size = 0;
+ xen_unmap_memory_section(xc_handle, domid, ioservid,
+ mmio[index].start,
+ mmio[index].start + mmio[index].size - 1);
}
}
diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c
index 78093fef..ba9d2cee 100644
--- a/i386-dm/helper2.c
+++ b/i386-dm/helper2.c
@@ -100,6 +100,9 @@ long time_offset = 0;
shared_iopage_t *shared_page = NULL;
+uint16_t ioservid;
+
+uint32_t bufioreq_evtchn;
#define BUFFER_IO_MAX_DELAY 100
buffered_iopage_t *buffered_io_page = NULL;
QEMUTimer *buffered_io_timer;
@@ -120,7 +123,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
CPUX86State *env;
static int inited;
int i, rc;
- unsigned long bufioreq_evtchn;
env = qemu_mallocz(sizeof(CPUX86State));
if (!env)
@@ -158,13 +160,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
}
ioreq_local_port[i] = rc;
}
- rc = xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_EVTCHN,
- &bufioreq_evtchn);
- if (rc < 0) {
- fprintf(logfile, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN error=%d\n",
- errno);
- return NULL;
- }
rc = xenevtchn_bind_interdomain(xce_handle, domid, (uint32_t)bufioreq_evtchn);
if (rc == -1) {
fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
@@ -472,11 +467,31 @@ static void cpu_ioreq_timeoffset(CPUState *env, ioreq_t *req)
static void __handle_ioreq(CPUState *env, ioreq_t *req)
{
+ uint32_t sbdf, val;
+
if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
(req->size < sizeof(target_ulong)))
req->data &= ((target_ulong)1 << (8 * req->size)) - 1;
switch (req->type) {
+ case IOREQ_TYPE_PCI_CONFIG:
+ sbdf = req->addr >> 32;
+
+ /* Fake a write to port 0xCF8 so that
+ * the config space access will target the
+ * correct device model.
+ */
+ val = (1u << 31) |
+ ((req->addr & 0x0f00) << 16) |
+ ((sbdf & 0xffff) << 8) |
+ (req->addr & 0xfc);
+ do_outp(env, 0xcf8, 4, val);
+
+ /* Now issue the config space access via
+ * port 0xCFC
+ */
+ req->addr = 0xcfc | (req->addr & 0x03);
+ cpu_ioreq_pio(env, req);
case IOREQ_TYPE_PIO:
cpu_ioreq_pio(env, req);
break;
diff --git a/vl.c b/vl.c
index c3c5d630..c8d9896d 100644
--- a/vl.c
+++ b/vl.c
@@ -46,6 +46,7 @@
#include "hw/pci.h"
#include "hw/xen.h"
+#include "hw/xen_common.h"
#include <stdlib.h>
#include "qemu-xen.h"
@@ -390,6 +391,9 @@ int register_ioport_read(int start, int length, int size,
hw_error("register_ioport_read: invalid opaque");
ioport_opaque[i] = opaque;
}
+
+ xen_map_io_section(xc_handle, domid, ioservid, start, start + length - 1);
+
return 0;
}
@@ -415,6 +419,9 @@ int register_ioport_write(int start, int length, int size,
hw_error("register_ioport_write: invalid opaque");
ioport_opaque[i] = opaque;
}
+
+ xen_map_io_section(xc_handle, domid, ioservid, start, start + length - 1);
+
return 0;
}
@@ -433,6 +440,8 @@ void isa_unassign_ioport(int start, int length)
ioport_opaque[i] = NULL;
}
+
+ xen_unmap_io_section(xc_handle, domid, ioservid, start, start + length - 1);
}
/***********************************************************/
--git a/xen-vl-extra.c b/xen-vl-extra.c
index 206ac658..c346e779 100644
--- a/xen-vl-extra.c
+++ b/xen-vl-extra.c
@@ -117,6 +117,9 @@ void do_pci_del(char *devname)
else
acpi_php_del(devfn);
+ xen_unmap_pcidev(xc_handle, domid, ioservid, 0,
+ PCI_SLOT(devfn), PCI_FUNC(devfn));
+
free(devname_cpy);
}
--
2.13.5
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH qemu-traditional] switch to the new ioreq server API
2017-09-06 9:28 [PATCH qemu-traditional] switch to the new ioreq server API Vitaly Kuznetsov
@ 2017-09-06 9:36 ` Paul Durrant
2017-09-21 8:35 ` Vitaly Kuznetsov
0 siblings, 1 reply; 3+ messages in thread
From: Paul Durrant @ 2017-09-06 9:36 UTC (permalink / raw)
To: 'Vitaly Kuznetsov', xen-devel@lists.xen.org; +Cc: Ian Jackson
> -----Original Message-----
> From: Vitaly Kuznetsov [mailto:vkuznets@redhat.com]
> Sent: 06 September 2017 10:29
> To: xen-devel@lists.xen.org
> Cc: Paul Durrant <Paul.Durrant@citrix.com>; Ian Jackson
> <Ian.Jackson@citrix.com>
> Subject: [PATCH qemu-traditional] switch to the new ioreq server API
>
> Instead of using implicit ioreq server creation side-effect upon reading
> HVM params switch qemu-traditional to using explicit APIs. This opens a
> possibility for removing the above mentioned side-effect and special
> 'default_ioreq_server' code pathes in Xen hypervisor in the future.
>
> This also solves an issue with soft reset when qemu-traditional is being
> used. Xen c/s e7dabe5 ("x86/hvm: don't unconditionally create a default
> ioreq server") disabled ioreq server creation after domain was created
> for the first time and this is needed for soft reset.
>
> IOREQ_TYPE_PCI_CONFIG handling code is stolen as-is from qemu-
> upstream.
>
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> hw/pci.c | 5 ++
> hw/xen_common.h | 163
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/xen_machine_fv.c | 31 ++++++++--
> i386-dm/exec-dm.c | 7 +++
> i386-dm/helper2.c | 31 +++++++---
> vl.c | 9 +++
> xen-vl-extra.c | 3 +
> 7 files changed, 236 insertions(+), 13 deletions(-)
>
> diff --git a/hw/pci.c b/hw/pci.c
> index c4232856..d6cafb3e 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -34,6 +34,7 @@
> #ifdef CONFIG_PASSTHROUGH
> #include "hw/pass-through.h"
> #endif
> +#include "hw/xen_common.h"
>
> extern int igd_passthru;
>
> @@ -248,6 +249,10 @@ PCIDevice *pci_register_device(PCIBus *bus, const
> char *name,
> return NULL;
> found: ;
> }
> +
> + xen_map_pcidev(xc_handle, domid, ioservid, 0,
> + PCI_SLOT(devfn), PCI_FUNC(devfn));
> +
> pci_dev = qemu_mallocz(instance_size);
> pci_dev->bus = bus;
> pci_dev->devfn = devfn;
> diff --git a/hw/xen_common.h b/hw/xen_common.h
> index cc48892f..5e172bb2 100644
> --- a/hw/xen_common.h
> +++ b/hw/xen_common.h
> @@ -33,4 +33,167 @@
> # define xen_wmb() wmb()
> #endif
>
> +extern uint16_t ioservid;
> +
> +#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040500
> +static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom,
> + uint16_t *ioservid)
> +{
> + return 0;
> +}
> +
> +static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + xen_pfn_t *ioreq_pfn,
> + xen_pfn_t *bufioreq_pfn,
> + uint32_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;
> +}
> +
> +static inline int xen_set_ioreq_server_state(xc_interface *xc, domid_t
> dom,
> + uint16_t ioservid,
> + bool enable)
> +{
> + return 0;
> +}
> +
> +static inline void xen_map_memory_section(xc_interface *xc, domid_t
> dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> +}
> +
> +static inline void xen_unmap_memory_section(xc_interface *xc, domid_t
> dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> +}
> +
> +static inline void xen_map_io_section(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> +}
> +
> +static inline void xen_unmap_io_section(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> +}
> +
> +static inline void xen_map_pcidev(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint8_t bus, uint8_t device,
> + uint8_t function)
> +{
> +}
> +
> +static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint8_t bus, uint8_t device,
> + uint8_t function)
> +{
> +}
> +#else
> +static inline int xen_create_ioreq_server(xc_interface *xc, domid_t dom,
> + uint16_t *ioservid)
> +{
> + int rc = xc_hvm_create_ioreq_server(xc, dom, 1, ioservid);
> +
> + return rc;
> +}
> +
> +static inline int xen_get_ioreq_server_info(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + xen_pfn_t *ioreq_pfn,
> + xen_pfn_t *bufioreq_pfn,
> + uint32_t *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(xc_interface *xc, domid_t
> dom,
> + uint16_t ioservid,
> + bool enable)
> +{
> + return xc_hvm_set_ioreq_server_state(xc, dom, ioservid, enable);
> +}
> +
> +static inline void xen_map_memory_section(xc_interface *xc, domid_t
> dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> + xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 1, start, end);
> +}
> +
> +static inline void xen_unmap_memory_section(xc_interface *xc, domid_t
> dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> + xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 1, start,
> end);
> +}
> +
> +static inline void xen_map_io_section(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> + xc_hvm_map_io_range_to_ioreq_server(xc, dom, ioservid, 0, start, end);
> +}
> +
> +static inline void xen_unmap_io_section(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint64_t start, uint64_t end)
> +{
> + xc_hvm_unmap_io_range_from_ioreq_server(xc, dom, ioservid, 0, start,
> end);
> +}
> +
> +static inline void xen_map_pcidev(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint8_t bus, uint8_t device,
> + uint8_t function)
> +{
> + xc_hvm_map_pcidev_to_ioreq_server(xc, dom, ioservid, 0,
> + bus, device, function);
> +}
> +
> +static inline void xen_unmap_pcidev(xc_interface *xc, domid_t dom,
> + uint16_t ioservid,
> + uint8_t bus, uint8_t device,
> + uint8_t function)
> +{
> + xc_hvm_unmap_pcidev_from_ioreq_server(xc, dom, ioservid, 0,
> + bus, device, function);
> +}
> +#endif
> +
> #endif /* QEMU_HW_XEN_COMMON_H */
> diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c
> index b385d6a5..edb8167d 100644
> --- a/hw/xen_machine_fv.c
> +++ b/hw/xen_machine_fv.c
> @@ -277,7 +277,8 @@ static void xen_init_fv(ram_addr_t ram_size, int
> vga_ram_size,
> const char *initrd_filename, const char *cpu_model,
> const char *direct_pci)
> {
> - unsigned long ioreq_pfn;
> + unsigned long ioreq_pfn, bufioreq_pfn;
> + extern uint32_t bufioreq_evtchn;
> extern void *shared_page;
> extern void *buffered_io_page;
> #ifdef __ia64__
> @@ -286,6 +287,7 @@ static void xen_init_fv(ram_addr_t ram_size, int
> vga_ram_size,
> extern void *buffered_pio_page;
> int i;
> #endif
> + int rc;
>
> #if defined(__i386__) || defined(__x86_64__)
>
> @@ -298,7 +300,21 @@ static void xen_init_fv(ram_addr_t ram_size, int
> vga_ram_size,
> #ifdef CONFIG_STUBDOM /* the hvmop is not supported on older
> hypervisors */
> xc_set_hvm_param(xc_handle, domid, HVM_PARAM_DM_DOMAIN,
> DOMID_SELF);
> #endif
> - xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN,
> &ioreq_pfn);
> + rc = xen_create_ioreq_server(xc_handle, domid, &ioservid);
> + if (rc < 0) {
> + fprintf(logfile, "failed to create ioreq server: error %d\n", errno);
> + exit(-1);
> + }
> +
> + fprintf(logfile, "created ioreq server %d\n", ioservid);
> +
> + rc = xen_get_ioreq_server_info(xc_handle, domid, ioservid, &ioreq_pfn,
> + &bufioreq_pfn, &bufioreq_evtchn);
> + if (rc < 0) {
> + fprintf(logfile, "failed to get ioreq server info: error %d\n", errno);
> + exit(-1);
> + }
> +
> fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
> shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
> PROT_READ|PROT_WRITE, ioreq_pfn);
> @@ -307,15 +323,20 @@ static void xen_init_fv(ram_addr_t ram_size, int
> vga_ram_size,
> exit(-1);
> }
>
> - xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN,
> &ioreq_pfn);
> - fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
> + fprintf(logfile, "buffered io page at pfn %lx\n", bufioreq_pfn);
> buffered_io_page = xc_map_foreign_range(xc_handle, domid,
> XC_PAGE_SIZE,
> - PROT_READ|PROT_WRITE, ioreq_pfn);
> + PROT_READ|PROT_WRITE, bufioreq_pfn);
> if (buffered_io_page == NULL) {
> fprintf(logfile, "map buffered IO page returned error %d\n", errno);
> exit(-1);
> }
>
> + rc = xen_set_ioreq_server_state(xc_handle, domid, ioservid, true);
> + if (rc < 0) {
> + fprintf(logfile, "failed to enable ioreq server %d\n", errno);
> + exit(-1);
> + }
> +
> #if defined(__ia64__)
> xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFPIOREQ_PFN,
> &ioreq_pfn);
> fprintf(logfile, "buffered pio page at pfn %lx\n", ioreq_pfn);
> diff --git a/i386-dm/exec-dm.c b/i386-dm/exec-dm.c
> index 96274d9d..783685ce 100644
> --- a/i386-dm/exec-dm.c
> +++ b/i386-dm/exec-dm.c
> @@ -40,6 +40,7 @@
> #include "pc.h"
> #include "disas.h"
> #include "qemu-xen.h"
> +#include "xen_common.h"
>
> //#define DEBUG_TB_INVALIDATE
> //#define DEBUG_FLUSH
> @@ -308,6 +309,9 @@ void
> cpu_register_physical_memory(target_phys_addr_t start_addr,
> mmio[mmio_cnt].io_index = phys_offset;
> mmio[mmio_cnt].start = start_addr;
> mmio[mmio_cnt++].size = size;
> +
> + xen_map_memory_section(xc_handle, domid, ioservid, start_addr,
> + start_addr + size -1);
> }
>
> static int get_free_io_mem_idx(void)
> @@ -476,6 +480,9 @@ void unregister_iomem(target_phys_addr_t start)
> (unsigned long)(mmio[index].start),
> (unsigned long)(mmio[index].start + mmio[index].size));
> mmio[index].size = 0;
> + xen_unmap_memory_section(xc_handle, domid, ioservid,
> + mmio[index].start,
> + mmio[index].start + mmio[index].size - 1);
> }
> }
>
> diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c
> index 78093fef..ba9d2cee 100644
> --- a/i386-dm/helper2.c
> +++ b/i386-dm/helper2.c
> @@ -100,6 +100,9 @@ long time_offset = 0;
>
> shared_iopage_t *shared_page = NULL;
>
> +uint16_t ioservid;
> +
> +uint32_t bufioreq_evtchn;
> #define BUFFER_IO_MAX_DELAY 100
> buffered_iopage_t *buffered_io_page = NULL;
> QEMUTimer *buffered_io_timer;
> @@ -120,7 +123,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
> CPUX86State *env;
> static int inited;
> int i, rc;
> - unsigned long bufioreq_evtchn;
>
> env = qemu_mallocz(sizeof(CPUX86State));
> if (!env)
> @@ -158,13 +160,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
> }
> ioreq_local_port[i] = rc;
> }
> - rc = xc_get_hvm_param(xc_handle, domid,
> HVM_PARAM_BUFIOREQ_EVTCHN,
> - &bufioreq_evtchn);
> - if (rc < 0) {
> - fprintf(logfile, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN
> error=%d\n",
> - errno);
> - return NULL;
> - }
> rc = xenevtchn_bind_interdomain(xce_handle, domid,
> (uint32_t)bufioreq_evtchn);
> if (rc == -1) {
> fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
> @@ -472,11 +467,31 @@ static void cpu_ioreq_timeoffset(CPUState *env,
> ioreq_t *req)
>
> static void __handle_ioreq(CPUState *env, ioreq_t *req)
> {
> + uint32_t sbdf, val;
> +
> if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
> (req->size < sizeof(target_ulong)))
> req->data &= ((target_ulong)1 << (8 * req->size)) - 1;
>
> switch (req->type) {
> + case IOREQ_TYPE_PCI_CONFIG:
> + sbdf = req->addr >> 32;
> +
> + /* Fake a write to port 0xCF8 so that
> + * the config space access will target the
> + * correct device model.
> + */
> + val = (1u << 31) |
> + ((req->addr & 0x0f00) << 16) |
> + ((sbdf & 0xffff) << 8) |
> + (req->addr & 0xfc);
> + do_outp(env, 0xcf8, 4, val);
> +
> + /* Now issue the config space access via
> + * port 0xCFC
> + */
> + req->addr = 0xcfc | (req->addr & 0x03);
> + cpu_ioreq_pio(env, req);
> case IOREQ_TYPE_PIO:
> cpu_ioreq_pio(env, req);
> break;
> diff --git a/vl.c b/vl.c
> index c3c5d630..c8d9896d 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -46,6 +46,7 @@
>
> #include "hw/pci.h"
> #include "hw/xen.h"
> +#include "hw/xen_common.h"
> #include <stdlib.h>
>
> #include "qemu-xen.h"
> @@ -390,6 +391,9 @@ int register_ioport_read(int start, int length, int size,
> hw_error("register_ioport_read: invalid opaque");
> ioport_opaque[i] = opaque;
> }
> +
> + xen_map_io_section(xc_handle, domid, ioservid, start, start + length - 1);
> +
> return 0;
> }
>
> @@ -415,6 +419,9 @@ int register_ioport_write(int start, int length, int size,
> hw_error("register_ioport_write: invalid opaque");
> ioport_opaque[i] = opaque;
> }
> +
> + xen_map_io_section(xc_handle, domid, ioservid, start, start + length - 1);
> +
> return 0;
> }
>
> @@ -433,6 +440,8 @@ void isa_unassign_ioport(int start, int length)
>
> ioport_opaque[i] = NULL;
> }
> +
> + xen_unmap_io_section(xc_handle, domid, ioservid, start, start + length -
> 1);
> }
>
>
> /**********************************************************
> */
> diff --git a/xen-vl-extra.c b/xen-vl-extra.c
> index 206ac658..c346e779 100644
> --- a/xen-vl-extra.c
> +++ b/xen-vl-extra.c
> @@ -117,6 +117,9 @@ void do_pci_del(char *devname)
> else
> acpi_php_del(devfn);
>
> + xen_unmap_pcidev(xc_handle, domid, ioservid, 0,
> + PCI_SLOT(devfn), PCI_FUNC(devfn));
> +
> free(devname_cpy);
> }
>
> --
> 2.13.5
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH qemu-traditional] switch to the new ioreq server API
2017-09-06 9:36 ` Paul Durrant
@ 2017-09-21 8:35 ` Vitaly Kuznetsov
0 siblings, 0 replies; 3+ messages in thread
From: Vitaly Kuznetsov @ 2017-09-21 8:35 UTC (permalink / raw)
To: Ian Jackson; +Cc: Paul Durrant, xen-devel@lists.xen.org
Paul Durrant <Paul.Durrant@citrix.com> writes:
>> -----Original Message-----
>> From: Vitaly Kuznetsov [mailto:vkuznets@redhat.com]
>> Sent: 06 September 2017 10:29
>> To: xen-devel@lists.xen.org
>> Cc: Paul Durrant <Paul.Durrant@citrix.com>; Ian Jackson
>> <Ian.Jackson@citrix.com>
>> Subject: [PATCH qemu-traditional] switch to the new ioreq server API
>>
>> Instead of using implicit ioreq server creation side-effect upon reading
>> HVM params switch qemu-traditional to using explicit APIs. This opens a
>> possibility for removing the above mentioned side-effect and special
>> 'default_ioreq_server' code pathes in Xen hypervisor in the future.
>>
>> This also solves an issue with soft reset when qemu-traditional is being
>> used. Xen c/s e7dabe5 ("x86/hvm: don't unconditionally create a default
>> ioreq server") disabled ioreq server creation after domain was created
>> for the first time and this is needed for soft reset.
>>
>> IOREQ_TYPE_PCI_CONFIG handling code is stolen as-is from qemu-
>> upstream.
>>
>> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>
> Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
>
Ian,
could you please have a look?
Thanks!
--
Vitaly
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-09-21 8:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-06 9:28 [PATCH qemu-traditional] switch to the new ioreq server API Vitaly Kuznetsov
2017-09-06 9:36 ` Paul Durrant
2017-09-21 8:35 ` Vitaly Kuznetsov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).