From: Don Slutz <dslutz@verizon.com>
To: George Dunlap <george.dunlap@eu.citrix.com>,
Don Slutz <dslutz@verizon.com>,
xen-devel@lists.xen.org
Cc: Kevin Tian <kevin.tian@intel.com>, Keir Fraser <keir@xen.org>,
Ian Campbell <ian.campbell@citrix.com>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
Jun Nakajima <jun.nakajima@intel.com>,
Eddie Dong <eddie.dong@intel.com>,
Ian Jackson <ian.jackson@eu.citrix.com>, Tim Deegan <tim@xen.org>,
Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>,
Jan Beulich <jbeulich@suse.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: Re: [PATCH for-4.5 v6 04/16] xen: Add vmware_port support
Date: Wed, 24 Sep 2014 12:48:31 -0400 [thread overview]
Message-ID: <5422F5DF.5070902@terremark.com> (raw)
In-Reply-To: <5422EAEB.2050807@eu.citrix.com>
On 09/24/14 12:01, George Dunlap wrote:
> On 09/20/2014 07:07 PM, Don Slutz wrote:
>> This includes adding is_vmware_port_enabled
>>
>> This is a new domain_create() flag, DOMCRF_vmware_port. It is
>> passed to domctl as XEN_DOMCTL_CDF_vmware_port.
>>
>> This enables limited support of VMware's hyper-call.
>>
>> This is both a more complete support then in currently provided by
>> QEMU and/or KVM and less. The missing part requires QEMU changes
>> and has been left out until the QEMU patches are accepted upstream.
>>
>> VMware's hyper-call is also known as VMware Backdoor I/O Port.
>>
>> Note: this support does not depend on vmware_hw being non-zero.
>>
>> Summary is that VMware treats "in (%dx),%eax" (or "out %eax,(%dx)")
>> to port 0x5658 specially. Note: since many operations return data
>> in EAX, "in (%dx),%eax" is the one to use. The other lengths like
>> "in (%dx),%al" will still do things, only AL part of EAX will be
>> changed. For "out %eax,(%dx)" of all lengths, EAX will remain
>> unchanged.
>>
>> Also this instruction is allowed to be used from ring 3. To
>> support this the vmexit for GP needs to be enabled. I have not
>> fully tested that nested HVM is doing the right thing for this.
>>
>> An open source example of using this is:
>>
>> http://open-vm-tools.sourceforge.net/
>>
>> Which only uses "inl (%dx)". Also
>>
>> http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
>>
>>
>> The support included is enough to allow VMware tools to install in a
>> HVM domU.
>>
>> For a debug=y build there is a new command line option
>> vmport_debug=. It enabled output to the console of various
>> stages of handling the "in (%dx)" instruction.
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>
> [snip]
>
>> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
>> index 7b1dfe6..e2e4aad 100644
>> --- a/xen/arch/x86/domain.c
>> +++ b/xen/arch/x86/domain.c
>> @@ -510,6 +510,8 @@ int arch_domain_create(struct domain *d, unsigned
>> int domcr_flags)
>> d->arch.hvm_domain.mem_sharing_enabled = 0;
>> d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity);
>> + d->arch.hvm_domain.is_vmware_port_enabled =
>> + (domcr_flags & DOMCRF_vmware_port);
>
> Should this be "!!(domcr..."?
>
I do not think it is needed, but happy to change to that.
>> diff --git a/xen/arch/x86/hvm/vmware/vmport.c
>> b/xen/arch/x86/hvm/vmware/vmport.c
>> new file mode 100644
>> index 0000000..811c303
>> --- /dev/null
>> +++ b/xen/arch/x86/hvm/vmware/vmport.c
>> @@ -0,0 +1,326 @@
>> +/*
>> + * HVM VMPORT emulation
>> + *
>> + * Copyright (C) 2012 Verizon Corporation
>> + *
>> + * This file is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License Version 2 (GPLv2)
>> + * as published by the Free Software Foundation.
>> + *
>> + * This file is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + * General Public License for more details.
>> <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <xen/config.h>
>> +#include <xen/lib.h>
>> +#include <asm/hvm/hvm.h>
>> +#include <asm/hvm/support.h>
>> +#include <asm/hvm/vmport.h>
>> +
>> +#include "backdoor_def.h"
>> +#include "guest_msg_def.h"
>> +
>> +#define MAX_INST_LEN 15
>> +
>> +#ifndef NDEBUG
>> +unsigned int opt_vmport_debug __read_mostly;
>> +integer_param("vmport_debug", opt_vmport_debug);
>> +#endif
>> +
>> +/* More VMware defines */
>> +
>> +#define VMWARE_GUI_AUTO_GRAB 0x001
>> +#define VMWARE_GUI_AUTO_UNGRAB 0x002
>> +#define VMWARE_GUI_AUTO_SCROLL 0x004
>> +#define VMWARE_GUI_AUTO_RAISE 0x008
>> +#define VMWARE_GUI_EXCHANGE_SELECTIONS 0x010
>> +#define VMWARE_GUI_WARP_CURSOR_ON_UNGRAB 0x020
>> +#define VMWARE_GUI_FULL_SCREEN 0x040
>> +
>> +#define VMWARE_GUI_TO_FULL_SCREEN 0x080
>> +#define VMWARE_GUI_TO_WINDOW 0x100
>> +
>> +#define VMWARE_GUI_AUTO_RAISE_DISABLED 0x200
>> +
>> +#define VMWARE_GUI_SYNC_TIME 0x400
>> +
>> +/* When set, toolboxes should not show the cursor options page. */
>> +#define VMWARE_DISABLE_CURSOR_OPTIONS 0x800
>> +
>> +void vmport_register(struct domain *d)
>> +{
>> + register_portio_handler(d, BDOOR_PORT, 4, vmport_ioport);
>> +}
>> +
>> +int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t
>> *val)
>> +{
>> + struct cpu_user_regs *regs = guest_cpu_user_regs();
>> + uint32_t cmd = regs->rcx & 0xffff;
>> + uint32_t magic = regs->rax;
>> + int rc = X86EMUL_OKAY;
>> +
>> + if ( magic == BDOOR_MAGIC )
>> + {
>> + uint64_t saved_rax = regs->rax;
>> + uint64_t value;
>> +
>> + VMPORT_DBG_LOG(VMPORT_LOG_TRACE,
>> + "VMware trace dir=%d bytes=%u ip=%"PRIx64"
>> cmd=%d ax=%"
>> + PRIx64" bx=%"PRIx64" cx=%"PRIx64"
>> dx=%"PRIx64" si=%"
>> + PRIx64" di=%"PRIx64"\n", dir, bytes,
>> + regs->rip, cmd, regs->rax, regs->rbx, regs->rcx,
>> + regs->rdx, regs->rsi, regs->rdi);
>> + switch ( cmd )
>> + {
>> + case BDOOR_CMD_GETMHZ:
>> + /* ... */
>> + regs->rbx = BDOOR_MAGIC;
>> + regs->rax = current->domain->arch.tsc_khz / 1000;
>> + break;
>> + case BDOOR_CMD_GETVERSION:
>> + /* ... */
>> + regs->rbx = BDOOR_MAGIC;
>> + /* VERSION_MAGIC */
>> + regs->rax = 6;
>> + /* Claim we are an ESX. VMX_TYPE_SCALABLE_SERVER */
>> + regs->rcx = 2;
>> + break;
>> + case BDOOR_CMD_GETSCREENSIZE:
>> + /* We have no screen size */
>> + regs->rax = 0;
>> + break;
>> + case BDOOR_CMD_GETHWVERSION:
>> + /* vmware_hw */
>> + regs->rax = 0;
>> + if ( is_hvm_vcpu(current) )
>> + {
>> + struct hvm_domain *hd =
>> ¤t->domain->arch.hvm_domain;
>> +
>> + regs->rax = hd->params[HVM_PARAM_VMWARE_HW];
>> + }
>> + if ( !regs->rax )
>> + regs->rax = 4; /* Act like version 4 */
>> + break;
>> + case BDOOR_CMD_GETHZ:
>> + value = current->domain->arch.tsc_khz * 1000;
>> + /* apic-frequency (bus speed) */
>> + regs->rcx = (uint32_t)(1000000000ULL / APIC_BUS_CYCLE_NS);
>> + /* High part of tsc-frequency */
>> + regs->rbx = (uint32_t)(value >> 32);
>> + /* Low part of tsc-frequency */
>> + regs->rax = value;
>
> Either the comment or the code here is wrong -- this is clearly not
> the lower 32 bits, at least on 64-bit guests. :-)
>
Opps, it should have included the (uint32_t) cast also. Will fix.
> If the code is right -- that is, if a 32-bit guest find this truncated
> automatically, but a 64-bit guest find all 64 bits here (and thus not
> have to reconstruct it) -- you should make the comment more
> informative; for example:
> /* On 32-bit systems this will be the lower 32 bits. 64-bit systems
> can just use the full value from rax. */
>
> (Word-wrapped, of course.)
>
> Hmm -- looks like regs->rax will be clipped to 32 bits for a 4-byte IO
> read? In which case the comment here should reflect this, but you
> have the same basic issue for BDOOR_CMD_GETTIMEFUL regs->rdx (which
> will not be clipped, I don't think).
>
It will also be "adjusted" for 2 or 1 byte IO. rdx does not get clipped
later, but is clipped to 32bits (see below).
>> + break;
>> + case BDOOR_CMD_GETTIME:
>> + value = get_localtime_us(current->domain);
>> + /* hostUsecs */
>> + regs->rbx = (uint32_t)(value % 1000000UL);
>> + /* hostSecs */
>> + regs->rax = value / 1000000ULL;
>> + /* maxTimeLag */
>> + regs->rcx = 0;
>> + break;
>> + case BDOOR_CMD_GETTIMEFULL:
>> + value = get_localtime_us(current->domain);
>> + /* ... */
>> + regs->rax = BDOOR_MAGIC;
>> + /* hostUsecs */
>> + regs->rbx = (uint32_t)(value % 1000000UL);
>> + /* High part of hostSecs */
>> + regs->rsi = (uint32_t)((value / 1000000ULL) >> 32);
>> + /* Low part of hostSecs */
>> + regs->rdx = (uint32_t)(value / 1000000ULL);
>
> Same here.
>
But the (uint32_t) does make it just 32bits.
>> + /* maxTimeLag */
>> + regs->rcx = 0;
>> + break;
>> + case BDOOR_CMD_GETGUIOPTIONS:
>> + regs->rax = VMWARE_GUI_AUTO_GRAB | VMWARE_GUI_AUTO_UNGRAB |
>> + VMWARE_GUI_AUTO_RAISE_DISABLED | VMWARE_GUI_SYNC_TIME |
>> + VMWARE_DISABLE_CURSOR_OPTIONS;
>> + break;
>> + case BDOOR_CMD_SETGUIOPTIONS:
>> + regs->rax = 0x0;
>> + break;
>> + default:
>> + VMPORT_DBG_LOG(VMPORT_LOG_ERROR,
>> + "VMware bytes=%d dir=%d cmd=%d",
>> + bytes, dir, cmd);
>> + break;
>> + }
>> + VMPORT_DBG_LOG(VMPORT_LOG_VMWARE_AFTER,
>> + "VMware after ip=%"PRIx64" cmd=%d
>> ax=%"PRIx64" bx=%"
>> + PRIx64" cx=%"PRIx64" dx=%"PRIx64"
>> si=%"PRIx64" di=%"
>> + PRIx64"\n",
>> + regs->rip, cmd, regs->rax, regs->rbx, regs->rcx,
>> + regs->rdx, regs->rsi, regs->rdi);
>> + if ( dir == IOREQ_READ )
>> + {
>> + switch ( bytes )
>> + {
>> + case 1:
>> + regs->rax = (saved_rax & 0xffffff00) | (regs->rax &
>> 0xff);
>> + break;
>> + case 2:
>> + regs->rax = (saved_rax & 0xffff0000) | (regs->rax &
>> 0xffff);
>> + break;
>> + case 4:
>> + regs->rax = (uint32_t)regs->rax;
>> + break;
>> + }
>> + *val = regs->rax;
>> + }
>> + else
>> + regs->rax = saved_rax;
>> + }
>> + else
>> + {
>> + rc = X86EMUL_UNHANDLEABLE;
>> + VMPORT_DBG_LOG(VMPORT_LOG_ERROR,
>> + "Not VMware %x vs %x; ip=%"PRIx64" ax=%"PRIx64
>> + " bx=%"PRIx64" cx=%"PRIx64" dx=%"PRIx64"
>> si=%"PRIx64
>> + " di=%"PRIx64"",
>> + magic, BDOOR_MAGIC, regs->rip, regs->rax,
>> regs->rbx,
>> + regs->rcx, regs->rdx, regs->rsi, regs->rdi);
>> + }
>> +
>> + return rc;
>> +}
>> +
>> +int vmport_gp_check(struct cpu_user_regs *regs, struct vcpu *v,
>> + unsigned long *inst_len, unsigned long inst_addr,
>> + unsigned long ei1, unsigned long ei2)
>
> I've wondered, in another e-mail, whether it would make more sense to
> try to re-use the normal Xen emulation code, instead of duplicating
> its IO instruction decoding stuff here.
>
Since this is only called on a #GP, I do not what to attempt to emulate
the instruction by the normal way. In fact the normal Xen emulation
should say "do a #GP", not do the VMware hypercall.
I will say that I had not looked into getting the normal Xen emulation
"fixed" for this case. In all my testing, I have not see this issue.
With the patch:
Subject: [Xen-devel] [PATCH 5/6] x86/hvm: Forced Emulation Prefix for debug
builds of Xen
Message-ID: <1411484611-31027-6-git-send-email-andrew.cooper3@citrix.com>
I need to look into this.
> I think I probably wouldn't make that a blocker for acceptance,
> though. However...
>
Thanks.
>> +{
>> + ASSERT(v->domain->arch.hvm_domain.is_vmware_port_enabled);
>
> At the moment I think this ASSERT is misplaced; there are no checks
> for this anywhere in the handler path to this point. If at any time
> in the future (or for any other reason) #GP exiting gets enabled (for
> example, if the introspection stuff wants to be notifed on #GPs),
> you'll end up going through this path whether or not
> is_vmware_port_enabled is true.
>
> I think you should instead "if(!is_vmware_port_enabled) return" here.
> That would effectively isolate these new changes from being able to
> introduce security issues for VMs which don't enable vmware_port,
> making it less risky to accept as-is.
>
Ok, it was a return in an older version. Happy to switch back.
> [snip]
>
>> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
>> index fc1f882..6fe9389 100644
>> --- a/xen/arch/x86/hvm/vmx/vmcs.c
>> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
>> @@ -1102,6 +1102,8 @@ static int construct_vmcs(struct vcpu *v)
>> v->arch.hvm_vmx.exception_bitmap = HVM_TRAP_MASK
>> | (paging_mode_hap(d) ? 0 : (1U << TRAP_page_fault))
>> + | (v->domain->arch.hvm_domain.is_vmware_port_enabled ?
>> + (1U << TRAP_gp_fault) : 0)
>> | (1U << TRAP_no_device);
>
> Probably not mandatory, but it might be nice to pull this bitmap logic
> into a function, so that you don't have the code duplication (here and
> in vmx_update_guest_cr()).
>
Ok, Will keep it in mind.
-Don Slutz
> -George
next prev parent reply other threads:[~2014-09-24 16:48 UTC|newest]
Thread overview: 93+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-20 18:07 [PATCH for-4.5 v6 00/16] Xen VMware tools support Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 01/16] xen: Add support for VMware cpuid leaves Don Slutz
2014-09-22 11:49 ` Andrew Cooper
2014-09-22 16:53 ` Don Slutz
2014-09-24 14:33 ` George Dunlap
2014-09-20 18:07 ` [PATCH for-4.5 v6 02/16] tools: Add vmware_hw support Don Slutz
2014-09-22 13:34 ` Ian Campbell
2014-09-22 22:08 ` Don Slutz
2014-09-24 14:44 ` George Dunlap
2014-09-24 21:06 ` Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 03/16] vmware: Add VMware provided include files Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 04/16] xen: Add vmware_port support Don Slutz
2014-09-23 17:16 ` Boris Ostrovsky
2014-09-24 8:28 ` Jan Beulich
2014-09-26 19:09 ` Don Slutz
2014-09-24 16:01 ` George Dunlap
2014-09-24 16:48 ` Don Slutz [this message]
2014-09-24 17:42 ` Andrew Cooper
2014-09-20 18:07 ` [PATCH for-4.5 v6 05/16] tools: " Don Slutz
2014-09-22 13:41 ` Ian Campbell
2014-09-22 16:34 ` Andrew Cooper
2014-09-22 21:22 ` Don Slutz
2014-09-24 16:24 ` George Dunlap
2014-09-24 18:25 ` Don Slutz
2014-09-22 16:42 ` Don Slutz
2014-09-23 12:20 ` Ian Campbell
2014-09-24 16:31 ` Don Slutz
2014-09-24 16:44 ` George Dunlap
2014-09-24 18:29 ` Don Slutz
2014-09-25 11:24 ` Ian Campbell
2014-09-25 14:17 ` George Dunlap
2014-09-25 14:21 ` Ian Campbell
2014-09-26 19:19 ` Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 06/16] xen: Convert vmware_port to xentrace usage Don Slutz
2014-09-24 17:27 ` George Dunlap
2014-09-24 19:07 ` Don Slutz
2014-09-25 15:14 ` George Dunlap
2014-09-29 18:10 ` Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 07/16] tools: " Don Slutz
2014-09-25 15:18 ` George Dunlap
2014-09-20 18:07 ` [PATCH for-4.5 v6 08/16] xen: Add limited support of VMware's hyper-call rpc Don Slutz
2014-09-22 13:47 ` Ian Campbell
2014-09-22 21:18 ` Don Slutz
2014-09-23 12:34 ` Ian Campbell
2014-09-23 22:03 ` Slutz, Donald Christopher
2014-09-25 16:28 ` George Dunlap
2014-09-20 18:07 ` [PATCH for-4.5 v6 09/16] tools: " Don Slutz
2014-09-22 13:52 ` Ian Campbell
2014-09-22 21:32 ` Don Slutz
2014-09-23 12:35 ` Ian Campbell
2014-09-20 18:07 ` [PATCH for-4.5 v6 10/16] Add VMware tool's triggers Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 11/16] Add live migration of VMware's hyper-call RPC Don Slutz
2014-09-20 18:07 ` [PATCH for-4.5 v6 12/16] Add dump of HVM_SAVE_CODE(VMPORT) to xen-hvmctx Don Slutz
2014-09-20 18:07 ` [OPTIONAL][PATCH for-4.5 v6 13/16] Add xen-hvm-param Don Slutz
2014-09-20 18:07 ` [OPTIONAL][PATCH for-4.5 v6 14/16] Add xen-vmware-guestinfo Don Slutz
2014-09-20 18:07 ` [OPTIONAL][PATCH for-4.5 v6 15/16] Add xen-list-vmware-guestinfo Don Slutz
2014-09-20 18:07 ` [OPTIONAL][PATCH for-4.5 v6 16/16] Add xen-hvm-send-trigger Don Slutz
2014-09-22 13:56 ` [PATCH for-4.5 v6 00/16] Xen VMware tools support Ian Campbell
2014-09-22 15:19 ` George Dunlap
2014-09-22 15:34 ` Ian Campbell
2014-09-22 15:38 ` George Dunlap
2014-09-22 15:50 ` Ian Campbell
2014-09-22 15:55 ` George Dunlap
2014-09-22 17:19 ` Don Slutz
2014-09-22 22:00 ` Tian, Kevin
2014-09-23 12:30 ` Ian Campbell
2014-09-23 12:35 ` George Dunlap
2014-09-23 12:40 ` Ian Campbell
2014-09-24 15:52 ` George Dunlap
2014-09-24 18:09 ` Don Slutz
2014-09-24 17:19 ` Don Slutz
2014-09-24 20:21 ` Konrad Rzeszutek Wilk
2014-09-26 19:03 ` Don Slutz
2014-09-26 19:28 ` Konrad Rzeszutek Wilk
2014-09-25 11:35 ` Ian Campbell
2014-09-22 16:18 ` Jan Beulich
2014-09-22 18:32 ` Don Slutz
2014-09-25 10:37 ` Tim Deegan
2014-09-26 20:00 ` Don Slutz
2014-09-29 6:50 ` Jan Beulich
2014-09-29 13:27 ` George Dunlap
2014-09-29 13:49 ` Jan Beulich
2014-09-29 23:13 ` Don Slutz
2014-09-30 7:05 ` Jan Beulich
2014-09-30 10:02 ` George Dunlap
2014-09-30 22:11 ` Slutz, Donald Christopher
2014-09-30 10:09 ` George Dunlap
2014-09-30 22:23 ` Slutz, Donald Christopher
2014-10-02 10:05 ` Tim Deegan
2014-10-02 19:20 ` Don Slutz
2014-10-03 7:09 ` Tim Deegan
2014-09-22 15:52 ` Andrew Cooper
2014-09-22 18:39 ` 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=5422F5DF.5070902@terremark.com \
--to=dslutz@verizon.com \
--cc=Aravind.Gopalakrishnan@amd.com \
--cc=andrew.cooper3@citrix.com \
--cc=boris.ostrovsky@oracle.com \
--cc=eddie.dong@intel.com \
--cc=george.dunlap@eu.citrix.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=jun.nakajima@intel.com \
--cc=keir@xen.org \
--cc=kevin.tian@intel.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xen.org \
/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.