[Qemu-devel] [PATCH v5 1/1] xen-hvm.c: Add support for Xen access to vmport
This adds synchronisation of the 6 vcpu registers (only 32bits of them) that vmport.c needs between Xen and QEMU. This is to avoid a 2nd and 3rd exchange between QEMU and Xen to fetch and put these 6 vcpu registers used by the code in vmport.c and vmmouse.c The registers are passed in the new shared page provided by HVM_PARAM_VMPORT_REGS_PFN. Add new array to XenIOState that allows selection of current_cpu by vcpu id. Now pass XenIOState to handle_ioreq(). Add new routines regs_to_cpu(), regs_from_cpu(), and handle_vmport_ioreq(). Signed-off-by: Don Slutz dsl...@verizon.com --- v5: vmware_ioreq_t struct is not really a request any more. Maybe vmware_regs_t? Renamed various parts from vmware_ioreq to vmware_regs. Also HVM_PARAM_VMPORT_IOREQ_PFN to HVM_PARAM_VMPORT_REGS_PFN. cpu_by_ioreq_id name implies the array is indexed by an id carries in the ioreq. Renamed cpu_by_ioreq_id to cpu_by_vcpu_id. Is cpu_get_vmport_ioreq_from_shared_memory worth its own function? Moved in-line. I don't think you need the barrier anyway. Dropped the barrier. Oh, I now realize you mean the same theoretical rather than actual limit, in which case this can be a build time check anyway. Switch to build time check, move to a better place. You could avoid passing state to both of them by setting current_cpu here couldn't you? Yes, moved state usage to handle_vmport_ioreq(). Error out if it fails with error != -ENOSYS. Done. v4: Please try to get rid of the #ifdefs. Moved 2 #ifdefs into hw/xen/xen_common.h include/hw/xen/xen_common.h | 22 + xen-hvm.c | 110 ++-- 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 07731b9..42e3d77 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -164,4 +164,26 @@ void destroy_hvm_domain(bool reboot); /* shutdown/destroy current domain because of an error */ void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +#ifdef HVM_PARAM_VMPORT_REGS_PFN +static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, + unsigned long *vmport_regs_pfn) +{ +return xc_get_hvm_param(xc, dom, HVM_PARAM_VMPORT_REGS_PFN, +vmport_regs_pfn); +} +#else +static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, + unsigned long *vmport_regs_pfn) +{ +return -ENOSYS; +} +#endif + +#if __GNUC__ 4 || (__GNUC__ == 4 __GNUC_MINOR__ = 6) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), !( #cond )); }) +#else +#define BUILD_BUG_ON(cond) ((void)sizeof(struct { int:-!!(cond); })) +#endif + #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/xen-hvm.c b/xen-hvm.c index 05e522c..b5ef683 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -41,6 +41,29 @@ static MemoryRegion *framebuffer; static bool xen_in_migration; /* Compatibility with older version */ + +/* This allows QEMU to build on a system that has Xen 4.5 or earlier + * installed. This here (not in hw/xen/xen_common.h) because xen/hvm/ioreq.h + * needs to be included before this block and hw/xen/xen_common.h needs to + * be included before xen/hvm/ioreq.h + */ +#ifndef IOREQ_TYPE_VMWARE_PORT +#define IOREQ_TYPE_VMWARE_PORT 3 +struct vmware_regs { +uint32_t esi; +uint32_t edi; +uint32_t ebx; +uint32_t ecx; +uint32_t edx; +}; +typedef struct vmware_regs vmware_regs_t; + +struct shared_vmport_iopage { +struct vmware_regs vcpu_vmport_regs[1]; +}; +typedef struct shared_vmport_iopage shared_vmport_iopage_t; +#endif + #if __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) { @@ -79,8 +102,10 @@ typedef struct XenPhysmap { typedef struct XenIOState { shared_iopage_t *shared_page; +shared_vmport_iopage_t *shared_vmport_page; buffered_iopage_t *buffered_io_page; QEMUTimer *buffered_io_timer; +CPUState **cpu_by_vcpu_id; /* the evtchn port for polling the notification, */ evtchn_port_t *ioreq_local_port; /* evtchn local port for buffered io */ @@ -101,6 +126,8 @@ typedef struct XenIOState { Notifier wakeup; } XenIOState; +static void handle_ioreq(XenIOState *state, ioreq_t *req); + /* Xen specific function for piix pci */ int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) @@ -773,7 +800,50 @@ static void cpu_ioreq_move(ioreq_t *req) } } -static void handle_ioreq(ioreq_t *req) +static void regs_to_cpu(vmware_regs_t *vmport_regs, ioreq_t *req) +{ +X86CPU *cpu; +CPUX86State *env; + +cpu = X86_CPU(current_cpu); +env = cpu-env; +env-regs[R_EAX] = req-data; +env-regs[R_EBX] = vmport_regs-ebx; +env-regs[R_ECX] =
Re: [Qemu-devel] [PATCH v5 1/1] xen-hvm.c: Add support for Xen access to vmport
-Original Message- From: Don Slutz [mailto:dsl...@verizon.com] Sent: 20 October 2014 13:19 To: qemu-devel@nongnu.org; Paul Durrant Cc: xen-de...@lists.xensource.com; Alexander Graf; Andreas Färber; Anthony Liguori; Don Slutz; Marcel Apfelbaum; Markus Armbruster; Michael S. Tsirkin; Stefano Stabellini Subject: [PATCH v5 1/1] xen-hvm.c: Add support for Xen access to vmport This adds synchronisation of the 6 vcpu registers (only 32bits of them) that vmport.c needs between Xen and QEMU. This is to avoid a 2nd and 3rd exchange between QEMU and Xen to fetch and put these 6 vcpu registers used by the code in vmport.c and vmmouse.c The registers are passed in the new shared page provided by HVM_PARAM_VMPORT_REGS_PFN. Add new array to XenIOState that allows selection of current_cpu by vcpu id. Now pass XenIOState to handle_ioreq(). Add new routines regs_to_cpu(), regs_from_cpu(), and handle_vmport_ioreq(). Signed-off-by: Don Slutz dsl...@verizon.com --- v5: vmware_ioreq_t struct is not really a request any more. Maybe vmware_regs_t? Renamed various parts from vmware_ioreq to vmware_regs. Also HVM_PARAM_VMPORT_IOREQ_PFN to HVM_PARAM_VMPORT_REGS_PFN. cpu_by_ioreq_id name implies the array is indexed by an id carries in the ioreq. Renamed cpu_by_ioreq_id to cpu_by_vcpu_id. Is cpu_get_vmport_ioreq_from_shared_memory worth its own function? Moved in-line. I don't think you need the barrier anyway. Dropped the barrier. Oh, I now realize you mean the same theoretical rather than actual limit, in which case this can be a build time check anyway. Switch to build time check, move to a better place. You could avoid passing state to both of them by setting current_cpu here couldn't you? Yes, moved state usage to handle_vmport_ioreq(). Error out if it fails with error != -ENOSYS. Done. v4: Please try to get rid of the #ifdefs. Moved 2 #ifdefs into hw/xen/xen_common.h One possible nit, inline below, but... Reviewed-by: Paul Durrant paul.durr...@citrix.com include/hw/xen/xen_common.h | 22 + xen-hvm.c | 110 ++-- 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 07731b9..42e3d77 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -164,4 +164,26 @@ void destroy_hvm_domain(bool reboot); /* shutdown/destroy current domain because of an error */ void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +#ifdef HVM_PARAM_VMPORT_REGS_PFN +static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, + unsigned long *vmport_regs_pfn) +{ +return xc_get_hvm_param(xc, dom, HVM_PARAM_VMPORT_REGS_PFN, +vmport_regs_pfn); +} +#else +static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, + unsigned long *vmport_regs_pfn) +{ +return -ENOSYS; +} +#endif + +#if __GNUC__ 4 || (__GNUC__ == 4 __GNUC_MINOR__ = 6) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), !( #cond )); }) +#else +#define BUILD_BUG_ON(cond) ((void)sizeof(struct { int:-!!(cond); })) +#endif + #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/xen-hvm.c b/xen-hvm.c index 05e522c..b5ef683 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -41,6 +41,29 @@ static MemoryRegion *framebuffer; static bool xen_in_migration; /* Compatibility with older version */ + +/* This allows QEMU to build on a system that has Xen 4.5 or earlier + * installed. This here (not in hw/xen/xen_common.h) because xen/hvm/ioreq.h + * needs to be included before this block and hw/xen/xen_common.h needs to + * be included before xen/hvm/ioreq.h + */ +#ifndef IOREQ_TYPE_VMWARE_PORT +#define IOREQ_TYPE_VMWARE_PORT 3 +struct vmware_regs { +uint32_t esi; +uint32_t edi; +uint32_t ebx; +uint32_t ecx; +uint32_t edx; +}; +typedef struct vmware_regs vmware_regs_t; + +struct shared_vmport_iopage { +struct vmware_regs vcpu_vmport_regs[1]; +}; +typedef struct shared_vmport_iopage shared_vmport_iopage_t; +#endif + #if __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) { @@ -79,8 +102,10 @@ typedef struct XenPhysmap { typedef struct XenIOState { shared_iopage_t *shared_page; +shared_vmport_iopage_t *shared_vmport_page; buffered_iopage_t *buffered_io_page; QEMUTimer *buffered_io_timer; +CPUState **cpu_by_vcpu_id; /* the evtchn port for polling the notification, */ evtchn_port_t *ioreq_local_port; /* evtchn local port for buffered io */ @@ -101,6 +126,8
Re: [Qemu-devel] [PATCH v5 1/1] xen-hvm.c: Add support for Xen access to vmport
On 10/20/14 08:30, Paul Durrant wrote: -Original Message- From: Don Slutz [mailto:dsl...@verizon.com] Sent: 20 October 2014 13:19 To: qemu-devel@nongnu.org; Paul Durrant Cc: xen-de...@lists.xensource.com; Alexander Graf; Andreas Färber; Anthony Liguori; Don Slutz; Marcel Apfelbaum; Markus Armbruster; Michael S. Tsirkin; Stefano Stabellini Subject: [PATCH v5 1/1] xen-hvm.c: Add support for Xen access to vmport This adds synchronisation of the 6 vcpu registers (only 32bits of them) that vmport.c needs between Xen and QEMU. This is to avoid a 2nd and 3rd exchange between QEMU and Xen to fetch and put these 6 vcpu registers used by the code in vmport.c and vmmouse.c The registers are passed in the new shared page provided by HVM_PARAM_VMPORT_REGS_PFN. Add new array to XenIOState that allows selection of current_cpu by vcpu id. Now pass XenIOState to handle_ioreq(). Add new routines regs_to_cpu(), regs_from_cpu(), and handle_vmport_ioreq(). Signed-off-by: Don Slutz dsl...@verizon.com --- v5: vmware_ioreq_t struct is not really a request any more. Maybe vmware_regs_t? Renamed various parts from vmware_ioreq to vmware_regs. Also HVM_PARAM_VMPORT_IOREQ_PFN to HVM_PARAM_VMPORT_REGS_PFN. cpu_by_ioreq_id name implies the array is indexed by an id carries in the ioreq. Renamed cpu_by_ioreq_id to cpu_by_vcpu_id. Is cpu_get_vmport_ioreq_from_shared_memory worth its own function? Moved in-line. I don't think you need the barrier anyway. Dropped the barrier. Oh, I now realize you mean the same theoretical rather than actual limit, in which case this can be a build time check anyway. Switch to build time check, move to a better place. You could avoid passing state to both of them by setting current_cpu here couldn't you? Yes, moved state usage to handle_vmport_ioreq(). Error out if it fails with error != -ENOSYS. Done. v4: Please try to get rid of the #ifdefs. Moved 2 #ifdefs into hw/xen/xen_common.h One possible nit, inline below, but... Reviewed-by: Paul Durrant paul.durr...@citrix.com include/hw/xen/xen_common.h | 22 + xen-hvm.c | 110 ++-- 2 files changed, 127 insertions(+), 5 deletions(-) diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 07731b9..42e3d77 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -164,4 +164,26 @@ void destroy_hvm_domain(bool reboot); /* shutdown/destroy current domain because of an error */ void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +#ifdef HVM_PARAM_VMPORT_REGS_PFN +static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, + unsigned long *vmport_regs_pfn) +{ +return xc_get_hvm_param(xc, dom, HVM_PARAM_VMPORT_REGS_PFN, +vmport_regs_pfn); +} +#else +static inline int xen_get_vmport_regs_pfn(XenXC xc, domid_t dom, + unsigned long *vmport_regs_pfn) +{ +return -ENOSYS; +} +#endif + +#if __GNUC__ 4 || (__GNUC__ == 4 __GNUC_MINOR__ = 6) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), !( #cond )); }) +#else +#define BUILD_BUG_ON(cond) ((void)sizeof(struct { int:-!!(cond); })) +#endif + #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/xen-hvm.c b/xen-hvm.c index 05e522c..b5ef683 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -41,6 +41,29 @@ static MemoryRegion *framebuffer; static bool xen_in_migration; /* Compatibility with older version */ + +/* This allows QEMU to build on a system that has Xen 4.5 or earlier + * installed. This here (not in hw/xen/xen_common.h) because xen/hvm/ioreq.h + * needs to be included before this block and hw/xen/xen_common.h needs to + * be included before xen/hvm/ioreq.h + */ +#ifndef IOREQ_TYPE_VMWARE_PORT +#define IOREQ_TYPE_VMWARE_PORT 3 +struct vmware_regs { +uint32_t esi; +uint32_t edi; +uint32_t ebx; +uint32_t ecx; +uint32_t edx; +}; +typedef struct vmware_regs vmware_regs_t; + +struct shared_vmport_iopage { +struct vmware_regs vcpu_vmport_regs[1]; +}; +typedef struct shared_vmport_iopage shared_vmport_iopage_t; +#endif + #if __XEN_LATEST_INTERFACE_VERSION__ 0x0003020a static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i) { @@ -79,8 +102,10 @@ typedef struct XenPhysmap { typedef struct XenIOState { shared_iopage_t *shared_page; +shared_vmport_iopage_t *shared_vmport_page; buffered_iopage_t *buffered_io_page; QEMUTimer *buffered_io_timer; +CPUState **cpu_by_vcpu_id; /* the evtchn port for polling the notification, */ evtchn_port_t *ioreq_local_port; /* evtchn local port for buffered io */ @@ -101,6 +126,8 @@ typedef struct XenIOState { Notifier wakeup; }