All of lore.kernel.org
 help / color / mirror / Atom feed
From: Don Slutz <dslutz@verizon.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: xen-devel@lists.xensource.com,
	"Marcel Apfelbaum" <marcel.a@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	qemu-devel@nongnu.org, "Don Slutz" <dslutz@verizon.com>,
	"Alexander Graf" <agraf@suse.de>,
	"Anthony Liguori" <aliguori@amazon.com>,
	"Andreas Färber" <afaerber@suse.de>
Subject: Re: [Qemu-devel] [PATCH v2 1/1] xen-hvm.c: Add support for Xen access to vmport
Date: Fri, 03 Oct 2014 09:32:08 -0400	[thread overview]
Message-ID: <542EA558.3010108@terremark.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1410031047160.17038@kaball.uk.xensource.com>

On 10/03/14 05:52, Stefano Stabellini wrote:
> On Thu, 2 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
>>
>> Add new array to XenIOState that allows selection of current_cpu by
>> ioreq_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 <dslutz@verizon.com>
>> ---
>> v2:
>>     More info in commit message.
>>         Added vmware_ioreq_t
>>        Added cpu_by_ioreq_id.
>>        Set current_cpu in regs_to_cpu(), clear in regs_from_cpu().
>>        Drop all changes to vmport.c
>>
>>   xen-hvm.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>>   1 file changed, 137 insertions(+), 15 deletions(-)
>>
>> diff --git a/xen-hvm.c b/xen-hvm.c
>> index 05e522c..d80f21c 100644
>> --- a/xen-hvm.c
>> +++ b/xen-hvm.c
>> @@ -41,6 +41,31 @@ 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_ioreq {
>> +        uint32_t esi;
>> +        uint32_t edi;
>> +        uint32_t eax;
>> +        uint32_t ebx;
>> +        uint32_t ecx;
>> +        uint32_t edx;
>> +        uint32_t vp_eport; /* evtchn for notifications to/from device model */
>> +        uint16_t addr;
>> +        uint8_t  state:4;
>> +        uint8_t  dir:1;    /* 1=read, 0=write */
>> +        uint8_t  size:3;
>> +        uint8_t  type;     /* I/O type */
>> +};
>> +typedef struct vmware_ioreq vmware_ioreq_t;
>> +#endif
> Why here instead of include/hw/xen/xen_common.h?
>

See code comment above.  Copied here just to make sure.


+
+/* 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
+ */



>>   #if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a
>>   static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
>>   {
>> @@ -81,6 +106,7 @@ typedef struct XenIOState {
>>       shared_iopage_t *shared_page;
>>       buffered_iopage_t *buffered_io_page;
>>       QEMUTimer *buffered_io_timer;
>> +    CPUState **cpu_by_ioreq_id;
>>       /* the evtchn port for polling the notification, */
>>       evtchn_port_t *ioreq_local_port;
>>       /* evtchn local port for buffered io */
>> @@ -101,6 +127,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)
>> @@ -596,11 +624,23 @@ static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
>>       ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
>>   
>>       if (req->state != STATE_IOREQ_READY) {
>> -        DPRINTF("I/O request not ready: "
>> -                "%x, ptr: %x, port: %"PRIx64", "
>> -                "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
>> -                req->state, req->data_is_ptr, req->addr,
>> -                req->data, req->count, req->size);
>> +        if (req->type != IOREQ_TYPE_VMWARE_PORT) {
>> +            DPRINTF("I/O request not ready: "
>> +                    "%x, ptr: %x, port: %"PRIx64", "
>> +                    "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %"
>> +                    FMT_ioreq_size "\n",
>> +                    req->state, req->data_is_ptr, req->addr,
>> +                    req->data, req->count, req->size);
>> +        } else {
>> +#ifdef DEBUG_XEN_HVM
>> +            vmware_ioreq_t *vp = (vmware_ioreq_t *)req;
>> +            DPRINTF("I/O VMware request not ready: "
>> +                    "%x, ptr: 0, port: %x, data: %x"
>> +                    ", count: 1, size: %d\n",
>> +                    vp->state, (uint16_t)vp->edx, vp->eax,
>> +                    vp->size);
>> +#endif
>> +        }
>>           return NULL;
>>       }
>>   
>> @@ -773,10 +813,73 @@ static void cpu_ioreq_move(ioreq_t *req)
>>       }
>>   }
>>   
>> -static void handle_ioreq(ioreq_t *req)
>> +static void regs_to_cpu(XenIOState *state, vmware_ioreq_t *vmport_req)
>> +{
>> +    X86CPU *cpu;
>> +    CPUX86State *env;
>> +
>> +    if (!state->cpu_by_ioreq_id[0]) {
>> +        CPUState *cpu_state;
>> +
>> +        CPU_FOREACH(cpu_state) {
>> +            state->cpu_by_ioreq_id[cpu_state->cpu_index] = cpu_state;
>> +        }
>> +    }
> This is just the initialization, isn't it?
> It would be best to move it to an initialization function then.
>

A new initialization function would need to be added.  A new call to it 
would need
to be added (not sure where the best place is).  Since the overhead here is
small I went with the less intrusive change.

>> +    current_cpu = state->cpu_by_ioreq_id[state->send_vcpu];
>> +    cpu = X86_CPU(current_cpu);
>> +    env = &cpu->env;
>> +    env->regs[R_EAX] = vmport_req->eax;
>> +    env->regs[R_EBX] = vmport_req->ebx;
>> +    env->regs[R_ECX] = vmport_req->ecx;
>> +    env->regs[R_EDX] = vmport_req->edx;
>> +    env->regs[R_ESI] = vmport_req->esi;
>> +    env->regs[R_EDI] = vmport_req->edi;
>> +}
>> +
>> +static void regs_from_cpu(XenIOState *state, vmware_ioreq_t *vmport_req,
>> +                          ioreq_t *req)
>> +{
>> +    X86CPU *cpu = X86_CPU(current_cpu);
>> +    CPUX86State *env = &cpu->env;
>> +
>> +    assert(sizeof(*vmport_req) == sizeof(*req));
>> +    assert(offsetof(ioreq_t, type) == offsetof(vmware_ioreq_t, type));
>> +    assert(offsetof(ioreq_t, vp_eport) == offsetof(vmware_ioreq_t, vp_eport));
>> +
>> +    vmport_req->eax = env->regs[R_EAX];
>> +    vmport_req->ebx = env->regs[R_EBX];
>> +    vmport_req->ecx = env->regs[R_ECX];
>> +    vmport_req->edx = env->regs[R_EDX];
>> +    vmport_req->esi = env->regs[R_ESI];
>> +    vmport_req->edi = env->regs[R_EDI];
>> +    current_cpu = NULL;
>> +}
>> +
>> +static void handle_vmport_ioreq(XenIOState *state, vmware_ioreq_t *vmport_req)
>> +{
>> +    ioreq_t req;
>> +
>> +    memset(&req, 0x00, sizeof(req));
>> +
>> +    req.size = vmport_req->size;
>> +    req.count = 1;
>> +    req.addr = vmport_req->addr;
>> +    req.data = vmport_req->eax;
>> +    req.state = STATE_IOREQ_READY;
>> +    req.dir = vmport_req->dir;
>> +    req.df = 0;
>> +    req.type = IOREQ_TYPE_PIO;
>> +    req.data_is_ptr = 0;
>> +
>> +    regs_to_cpu(state, vmport_req);
>> +    handle_ioreq(state, &req);
>> +    regs_from_cpu(state, vmport_req, &req);
>> +}
> I think that this is far better than the previous version
>      
>    

Good.

    -Don Slutz

WARNING: multiple messages have this Message-ID (diff)
From: Don Slutz <dslutz@verizon.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: xen-devel@lists.xensource.com,
	"Marcel Apfelbaum" <marcel.a@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	qemu-devel@nongnu.org, "Don Slutz" <dslutz@verizon.com>,
	"Alexander Graf" <agraf@suse.de>,
	"Anthony Liguori" <aliguori@amazon.com>,
	"Andreas Färber" <afaerber@suse.de>
Subject: Re: [PATCH v2 1/1] xen-hvm.c: Add support for Xen access to vmport
Date: Fri, 03 Oct 2014 09:32:08 -0400	[thread overview]
Message-ID: <542EA558.3010108@terremark.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1410031047160.17038@kaball.uk.xensource.com>

On 10/03/14 05:52, Stefano Stabellini wrote:
> On Thu, 2 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
>>
>> Add new array to XenIOState that allows selection of current_cpu by
>> ioreq_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 <dslutz@verizon.com>
>> ---
>> v2:
>>     More info in commit message.
>>         Added vmware_ioreq_t
>>        Added cpu_by_ioreq_id.
>>        Set current_cpu in regs_to_cpu(), clear in regs_from_cpu().
>>        Drop all changes to vmport.c
>>
>>   xen-hvm.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>>   1 file changed, 137 insertions(+), 15 deletions(-)
>>
>> diff --git a/xen-hvm.c b/xen-hvm.c
>> index 05e522c..d80f21c 100644
>> --- a/xen-hvm.c
>> +++ b/xen-hvm.c
>> @@ -41,6 +41,31 @@ 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_ioreq {
>> +        uint32_t esi;
>> +        uint32_t edi;
>> +        uint32_t eax;
>> +        uint32_t ebx;
>> +        uint32_t ecx;
>> +        uint32_t edx;
>> +        uint32_t vp_eport; /* evtchn for notifications to/from device model */
>> +        uint16_t addr;
>> +        uint8_t  state:4;
>> +        uint8_t  dir:1;    /* 1=read, 0=write */
>> +        uint8_t  size:3;
>> +        uint8_t  type;     /* I/O type */
>> +};
>> +typedef struct vmware_ioreq vmware_ioreq_t;
>> +#endif
> Why here instead of include/hw/xen/xen_common.h?
>

See code comment above.  Copied here just to make sure.


+
+/* 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
+ */



>>   #if __XEN_LATEST_INTERFACE_VERSION__ < 0x0003020a
>>   static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
>>   {
>> @@ -81,6 +106,7 @@ typedef struct XenIOState {
>>       shared_iopage_t *shared_page;
>>       buffered_iopage_t *buffered_io_page;
>>       QEMUTimer *buffered_io_timer;
>> +    CPUState **cpu_by_ioreq_id;
>>       /* the evtchn port for polling the notification, */
>>       evtchn_port_t *ioreq_local_port;
>>       /* evtchn local port for buffered io */
>> @@ -101,6 +127,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)
>> @@ -596,11 +624,23 @@ static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
>>       ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
>>   
>>       if (req->state != STATE_IOREQ_READY) {
>> -        DPRINTF("I/O request not ready: "
>> -                "%x, ptr: %x, port: %"PRIx64", "
>> -                "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %" FMT_ioreq_size "\n",
>> -                req->state, req->data_is_ptr, req->addr,
>> -                req->data, req->count, req->size);
>> +        if (req->type != IOREQ_TYPE_VMWARE_PORT) {
>> +            DPRINTF("I/O request not ready: "
>> +                    "%x, ptr: %x, port: %"PRIx64", "
>> +                    "data: %"PRIx64", count: %" FMT_ioreq_size ", size: %"
>> +                    FMT_ioreq_size "\n",
>> +                    req->state, req->data_is_ptr, req->addr,
>> +                    req->data, req->count, req->size);
>> +        } else {
>> +#ifdef DEBUG_XEN_HVM
>> +            vmware_ioreq_t *vp = (vmware_ioreq_t *)req;
>> +            DPRINTF("I/O VMware request not ready: "
>> +                    "%x, ptr: 0, port: %x, data: %x"
>> +                    ", count: 1, size: %d\n",
>> +                    vp->state, (uint16_t)vp->edx, vp->eax,
>> +                    vp->size);
>> +#endif
>> +        }
>>           return NULL;
>>       }
>>   
>> @@ -773,10 +813,73 @@ static void cpu_ioreq_move(ioreq_t *req)
>>       }
>>   }
>>   
>> -static void handle_ioreq(ioreq_t *req)
>> +static void regs_to_cpu(XenIOState *state, vmware_ioreq_t *vmport_req)
>> +{
>> +    X86CPU *cpu;
>> +    CPUX86State *env;
>> +
>> +    if (!state->cpu_by_ioreq_id[0]) {
>> +        CPUState *cpu_state;
>> +
>> +        CPU_FOREACH(cpu_state) {
>> +            state->cpu_by_ioreq_id[cpu_state->cpu_index] = cpu_state;
>> +        }
>> +    }
> This is just the initialization, isn't it?
> It would be best to move it to an initialization function then.
>

A new initialization function would need to be added.  A new call to it 
would need
to be added (not sure where the best place is).  Since the overhead here is
small I went with the less intrusive change.

>> +    current_cpu = state->cpu_by_ioreq_id[state->send_vcpu];
>> +    cpu = X86_CPU(current_cpu);
>> +    env = &cpu->env;
>> +    env->regs[R_EAX] = vmport_req->eax;
>> +    env->regs[R_EBX] = vmport_req->ebx;
>> +    env->regs[R_ECX] = vmport_req->ecx;
>> +    env->regs[R_EDX] = vmport_req->edx;
>> +    env->regs[R_ESI] = vmport_req->esi;
>> +    env->regs[R_EDI] = vmport_req->edi;
>> +}
>> +
>> +static void regs_from_cpu(XenIOState *state, vmware_ioreq_t *vmport_req,
>> +                          ioreq_t *req)
>> +{
>> +    X86CPU *cpu = X86_CPU(current_cpu);
>> +    CPUX86State *env = &cpu->env;
>> +
>> +    assert(sizeof(*vmport_req) == sizeof(*req));
>> +    assert(offsetof(ioreq_t, type) == offsetof(vmware_ioreq_t, type));
>> +    assert(offsetof(ioreq_t, vp_eport) == offsetof(vmware_ioreq_t, vp_eport));
>> +
>> +    vmport_req->eax = env->regs[R_EAX];
>> +    vmport_req->ebx = env->regs[R_EBX];
>> +    vmport_req->ecx = env->regs[R_ECX];
>> +    vmport_req->edx = env->regs[R_EDX];
>> +    vmport_req->esi = env->regs[R_ESI];
>> +    vmport_req->edi = env->regs[R_EDI];
>> +    current_cpu = NULL;
>> +}
>> +
>> +static void handle_vmport_ioreq(XenIOState *state, vmware_ioreq_t *vmport_req)
>> +{
>> +    ioreq_t req;
>> +
>> +    memset(&req, 0x00, sizeof(req));
>> +
>> +    req.size = vmport_req->size;
>> +    req.count = 1;
>> +    req.addr = vmport_req->addr;
>> +    req.data = vmport_req->eax;
>> +    req.state = STATE_IOREQ_READY;
>> +    req.dir = vmport_req->dir;
>> +    req.df = 0;
>> +    req.type = IOREQ_TYPE_PIO;
>> +    req.data_is_ptr = 0;
>> +
>> +    regs_to_cpu(state, vmport_req);
>> +    handle_ioreq(state, &req);
>> +    regs_from_cpu(state, vmport_req, &req);
>> +}
> I think that this is far better than the previous version
>      
>    

Good.

    -Don Slutz

  reply	other threads:[~2014-10-03 13:32 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-02 18:51 [Qemu-devel] [PATCH v2 0/1] Add support for Xen access to vmport Don Slutz
2014-10-02 18:51 ` Don Slutz
2014-10-02 18:51 ` [Qemu-devel] [PATCH v2 1/1] xen-hvm.c: " Don Slutz
2014-10-02 18:51   ` Don Slutz
2014-10-03  9:52   ` [Qemu-devel] " Stefano Stabellini
2014-10-03  9:52     ` Stefano Stabellini
2014-10-03 13:32     ` Don Slutz [this message]
2014-10-03 13:32       ` Don Slutz
2014-10-03 16:23       ` [Qemu-devel] " Stefano Stabellini
2014-10-03 16:23         ` Stefano Stabellini
2014-10-03 18:17         ` [Qemu-devel] " Don Slutz
2014-10-03 18:17           ` Don Slutz
2014-10-06  9:14           ` [Qemu-devel] " Stefano Stabellini
2014-10-06  9:14             ` Stefano Stabellini
2014-10-09 13:53             ` [Qemu-devel] [RFC][PATCH v2x prototype " Don Slutz
2014-10-09 13:53               ` Don Slutz
2014-10-10 13:44               ` [Qemu-devel] " Stefano Stabellini
2014-10-10 13:44                 ` Stefano Stabellini
2014-10-10 14:08                 ` [Qemu-devel] " Don Slutz
2014-10-10 14:08                   ` Don Slutz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=542EA558.3010108@terremark.com \
    --to=dslutz@verizon.com \
    --cc=afaerber@suse.de \
    --cc=agraf@suse.de \
    --cc=aliguori@amazon.com \
    --cc=armbru@redhat.com \
    --cc=marcel.a@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.