[Qemu-devel] [PATCH v6 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 Reviewed-by: Paul Durrant --- v6: Do we need a forward declaration? Nope. Drooped. Added Reviewed-by from Paul Durrant. 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 | 108 ++-- 2 files changed, 125 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..7c6291a 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 */ @@ -773,7 +798,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] = vmport_regs->ecx; +env->regs[R_EDX] = vmport_regs->edx; +env->regs[R_ESI] = vmport_regs->esi; +env->regs[R_EDI] = vmp
Re: [Qemu-devel] [PATCH v6 1/1] xen-hvm.c: Add support for Xen access to vmport
On Mon, 20 Oct 2014, Don Slutz wrote: > 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 > Reviewed-by: Paul Durrant > --- > v6: > Do we need a forward declaration? > Nope. Drooped. > Added Reviewed-by from Paul Durrant. > > 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 | 108 > ++-- > 2 files changed, 125 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 Use QEMU_BUILD_BUG_ON, please do not define your own. But aside from this, it is OK for me. > #endif /* QEMU_HW_XEN_COMMON_H */ > diff --git a/xen-hvm.c b/xen-hvm.c > index 05e522c..7c6291a 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 */ > @@ -773,7 +798,50 @@ static void cpu_ioreq_move(ioreq_t *req) > } > } > > -static void handle_ioreq(io
Re: [Qemu-devel] [PATCH v6 1/1] xen-hvm.c: Add support for Xen access to vmport
On 10/20/14 11:03, Stefano Stabellini wrote: On Mon, 20 Oct 2014, Don Slutz wrote: 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 Reviewed-by: Paul Durrant --- v6: Do we need a forward declaration? Nope. Drooped. Added Reviewed-by from Paul Durrant. 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 | 108 ++-- 2 files changed, 125 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 Use QEMU_BUILD_BUG_ON, please do not define your own. But aside from this, it is OK for me. Sigh, I looked for this and failed to find it. Will switch. v7 soon. -Don Slutz #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/xen-hvm.c b/xen-hvm.c index 05e522c..7c6291a 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 */ @@ -773,7 +798,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) +{ +X