All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/13]  Xen VMware tools support
@ 2015-02-16 23:05 Don Slutz
  2015-02-16 23:05 ` [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h Don Slutz
                   ` (12 more replies)
  0 siblings, 13 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

Changes v8 to v9:
  Overview of changes:
    s/vmware_hw/vmware_hwver/i
    Switch to x86_emulator to handle #GP
    New patch: Move MAX_INST_LEN into x86_emulate.h
    Add QEMU usage, patch #8 "Add IOREQ_TYPE_VMWARE_PORT"
    Split patch "xen: Add vmware_port support" into 2. 1st has same
    name.  New one is "xen: Add ring 3 vmware_port support".
    Added 3 new patches about test_x86_emulator.

  
  Jan Beulich (#2: "xen: Add support for VMware cpuid leaves"):
    Change -EXDEV to EOPNOTSUPP.
      Done.
    adding another subdirectory: xen/arch/x86/hvm/vmware
    Much will depend on the discussion of the subsequent patches.
      TBD.
    So for versions < 7 there's effectively no CPUID support at all?
      Changed to check at entry.
    The comment /* Params for VMware */ seems wrong...
      Changed to /* emulated VMware Hardware Version */
    Also please use d, not _d in #define is_vmware_domain()
      Changed.  Line is now > 80 characters, so split into 2.

  Andrew Cooper (#3: "tools: Add vmware_hwver support"):
      I assumed that s/vmware_hw/vmware_hwver/ is not a big enough
      change to drop the Reviewed-by.  Did a minor edit to the
      commit message to add 7 to the list of values checked.

  Jan Beulich (#4: "vmware: Add VMware provided include file"):
    Either the description is wrong, or the patch is stale.
      stale commit message -- fixed.
    I'd say a file with a single comment line in it would suffice.
      Done.

  Jan Beulich (#5: "xen: Add vmware_port support"):
    Can you explain why a HVM param isn't suitable here?
      Issue with changing QEMU on the fly.
      Andrew Cooper: My recommendation is still to use a creation flag
        So no change.
    Please move SVM's identical definition into ...
      Did this as #1.  No longer needed, but since the patch was ready
      I have included it.
    --Lots of questions about code that no long is part of this patch. --
    With this, is handling other than 32-bit in/out really
    meaningful/correct?
      Added comment about this.
    Since you can't get here for PV, I can't see what you need this.
      Changed to an ASSERT.
    Why version 4?
      Added comment about this.
    -- Several questions about register changes.
      Re-coded to use new_eax and set *val to this.
      Change to generealy use reg->_e..
    These ei1/ei2 checks belong in the callers imo -
      Moved.
    the "port" function parameter isn't even checked
      Add check for exact match.
    If dropping the code is safe without also forbidding the
    combination of nested and VMware emulation.
      Added the forbidding the combination of nested and VMware.
      Mostly do to the cases of the nested virtual code is the one
      to handle VMware stuff if needed, not the root one.  Also I am
      having issues testing xen nested in xen and using hvm.

      

Changes v7 to v8:

  Jan Beulich:
    Coding changes to vmport_ioport. Things like:
-             regs->rax = (uint32_t)~0ul;
+             regs->_eax = ~0u;
      
  Andrew Cooper (#2: "tools: Add vmware_hwver support"):
    Other than these two comments, the rest of the patch looks ok, so...
      Added Reviewed-by after addressing the "Spurious whitepsace change".
      and the wording in the new docs/misc/hypervisor-cpuid.markdown.


Changes v6 to v7:
  summary of changes.

  George Dunlap:
    Any doc about this?
      Added reference to:
        https://sites.google.com/site/chitchatvmback/backdoor
      Last updated: Feb. 2008

  George Dunlap & Jan Beulich
    Too much logging and tracing.
      Dropped a lot of it.  This includes vmport_debug=

  Ian Campbell:
    Any reason RPC code cannot be done in QEMU?
      Not that I know of, so dropped all parts of RPC code.
    Default handling of hvm.vga.kind bad.
      Fixed.
    Default of vmware_port should be based on vmware_hw.
      Done. 

  Tim Deegan:
    CPL check of GETHZ needs to be fixed somewhere.
      Added check for CPL == 0 (assuming this is what VMware is
      checking.  Matches the testing.

  Ian Campbell, Andrew Cooper, George Dunlap, Boris Ostrovsky,
   & Jan Beulich
     Various minor fixes.
    
  Per patch notes:
    #1 "xen: Add support for VMware cpuid leaves":
      Prevent setting of HVM_PARAM_VIRIDIAN if HVM_PARAM_VMWARE_HW set.
    #4 "xen: Add vmware_port support":
      More on AMD in the commit message.
      Switch to only change 32bit part of registers, what VMware
        does.
    #6 "Add xentrace to vmware_port":
      Dropped some of the new traces.
      Added HVMTRACE_ND7.
    #7 "Add xen-hvm-param":
       Was a later patch.  Still optional.
       Fixed formatting.
       Adjust for drop of VMware RPC.

Comments on v3, v4, v5, v6:
  George Dunlap:
    Is there any reason not to merge 05/16 with 03/16?
      The reason I have is that v3 03/16 only contains new files. 2
      from VMware and 1 to allow use of the VMware files.  I added
      xen/arch/x86/hvm/vmware/includeCheck.h at the request of
      Konrad Wilk.

      This patch has many style issues and white space issues.  So I
      want it as a separate patch so as to be clear on what files do
      not meet the coding style.  And why and where they came from.

Changes v5 to v6:
  Boris Ostrovsky & Jan Beulich
    #4 "xen: Add vmware_port support":
    #6 "xen: Convert vmware_port to xentrace usage":
    There is an issue with reading instruction bytes more then once.
      Dropped the attempt to use svm_nextrip_insn_length via
      __get_instruction_length (added in v2).  Just always look
      at upto 15 bytes on AMD.

Changes v4 to v5:
  Re tagged the optional patches.

  Added debug=y build checking that vmx is defining
  VM_EXIT_INTR_ERROR_CODE.

  Boris Ostrovsky:
    #1 "xen: Add support for VMware cpuid leaves":
      Given how is_viridian and is_vmware are defined I think '||' is more
      appropriate.
        Fixed.
    #4 "xen: Add is_vmware_port_enabled":
      we should make sure that svm_vmexit_gp_intercept is not executed for
      any other guest.
        Added an ASSERT on is_vmware_port_enabled.
      magic integers?
        Added #define for them.
    #6 "xen: Convert vmware_port to xentrace usage":
      exitinfo1 is used twice.
        Fixed.
    #7 "tools: Convert vmware_port to xentrace usage":
      'bytes = 0x%(2)d' or 'bytes = %(2)d' ?
        Fixed.
    #8 "xen: Add limited support of VMware's hyper-call rpc":
      PV vs. HVM vs. PVH. So probably 'if(is_hvm_vcpu)'?
        I see no reason to exclude PVH.   Will change to has_hvm_container_vcpu
    #11 "Add live migration of VMware's hyper-call":
      You ASSERTed that vg->key_len is 1 so you may not need the 'if'.
        That is a ASSERT(sizeof, not just ASSERT -- not changed.
      Use real errno, not -1.
        Fixed.
      No ASSERT in vmport_load_domain_ctxt
        Added.

  Jan Beulich & Boris Ostrovsky:
    #8 "xen: Add limited support of VMware's hyper-call rpc":
      The names of all three functions are bogus.
        removed static support routines.
        Also changed in #1.

  Andrew Cooper:
    #2 "tools: Add vmware_hw support":
      Anything looking for Xen according to the Xen cpuid instructions...
        Adjusted doc to new wording.
    #4 "xen: Add is_vmware_port_enabled":
      I am fairly certain that you need some brackets here.
        Added brackets.

  Jan Beulich & Andrew Cooper:
    #1 "xen: Add support for VMware cpuid leaves":
      This hunk is unrelated, but is perhaps something better fixed.
        Added to commit message.
      include <xen/types.h> (IIRC) please.
        Done.
      At least 1 pair of brackets please, especially as the placement of
      brackets affects the result of this particular calculation.
        Switch to "1000000ull / APIC_BUS_CYCLE_NS"      


Changes v3 to v4:
  Ian Campbell:
    Report on both viridian and vmware_hw set.
    Added LIBXL_VGA_INTERFACE_TYPE_VMWARE (vga=vmware).

  Andrew Cooper:
    Add doc for hypervisor-cpuid.

  Boris Ostrovsky:
    Changing regs->error_code may not be a good idea.
      Dropped this.
    
  Jan Beulich & Boris Ostrovsky:
    Only enable vmwxit for GP when vmware_port is set.
      Done.


Changes v2 to v3:

  Add optional unit test tools.
  Re-worked split of changes.

  Jan Beulich:
    for #0:
      I don't think you should be adding a new fine in hvm/ _and_ a new
      subdirectory.
        Moved all files to hvm/vmware that contain code.
    for old #1 (now #1 & #2):
      Is there really a point in enabling both Viridian and VMware extensions?
        I still think so.
      hvmloader change: This needs an explanation
        Dropped as not need now.
      Can you make vmware_hw similar to Viridian, returning success when
      setting the value to what it already is.
        Done.
      You don't seem to be using sub_idx: ...
        Dropped.
      Extra changes...
        Dropped.
    for old #2 (now #3):
      ... these guards have the (theoretical at this point) risk of clashing
      ... the patch is obviously incomplete without this header...
        Did not fix any of these issues.  I will stick with this needs
        to be a 2nd patch that changes the include files to better fit
        in Xen coding.  For now these files are in a sub directory
        which is not part of the normal include search.
        Moved the includeCheck.h file into this patch.
    for old #3 (now #4, #5, #6, #7, #8, #9, #10, #11)
      As I think was said on v1 already - this should be split into smaller
      pieces ...
        Done.
      All this would very likely better go into a separate function placed in
      vmport.c.
        Moved most of the code into vmport.c or vmport_rpc.c.
      In any event I'm rather uncomfortable about vmware_port getting
      enabled unconditionally, ...
        Added vmware_port (done in new patches #4, #5) as an xl.cfg
        option.
      You'll have to go through and fix coding style issues.
        I think I have found all these, but since they do not stand out
        for me, let me know of any left.
      "MAKE_INSTR(IN," name is ambiguous.
        Added all 4 opcodes for in and out that can access this port: INB_DX,
        INL_DX, OUTB_DX, OUTL_DX.
      A VMX-specific function shouldn't be named this way...
        Added new common routine vmport_gp_check() that is called from
        both vmx.c and svm.c which is where all the logic about checking
        for IN ans OUT is done.
        Also fixed naming and added static.
      Ah, here we go (as to using HVM_DBG_LOG()): Isn't this _way_ too
      fine grained?
        I have reduced the number of bits used.  Partialy by switching
        some to xentrace (new patch #6 and #7).
      Right, and zero is an indication that it wasn't found. Also I just
      noticed there's a gdprintk() in that event, which for all other ...
        Made the gdprintk() optional.

End of v3 changes.

This is a small part of the changes needed to allow running Linux
and windows (and others) guests that were built on VMware and run
run them unchanged on Xen.

This small part is the start of Xen support of VMware backdoor I/O
port which is how VMware tools (a standard addition installed on a
guest) communicates to the hypervisor.

I picked this subset to start with because it only has changes in
Xen.

Some of this code is already in QEMU and so KVM has some of this
already.  QEMU supported backdoor commands include VMware mouse
support.  A later patch set exists that links these changes, new
code and Xen changes to QEMU to provide VMware mouse support under
Xen.  The important part is that VMware mouse is an absolute
position mouse and so network delays do not effect usage of the
virtual mouse.

For example from the guest:

[root@C63-min-tools ~]# vmtoolsd --cmd "info-get guestinfo.joejoel"
No value found
[root@C63-min-tools ~]# vmtoolsd --cmd "info-set guestinfo.joejoel short"

[root@C63-min-tools ~]# vmtoolsd --cmd "info-get guestinfo.joejoel"
short
[root@C63-min-tools ~]# vmtoolsd --cmd "info-set guestinfo.joejoel long222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000joel"

[root@C63-min-tools ~]# vmtoolsd --cmd "info-get guestinfo.key1"
data1
[root@C63-min-tools ~]# vmtoolsd --cmd "info-get guestinfo.key2"
No value found
[root@C63-min-tools ~]# vmtoolsd --cmd "info-get guestinfo.key2"
data2
[root@C63-min-tools ~]# 


Most of this code has been reverse engineered by looking at
source code for Linux and open VMware tools.

http://open-vm-tools.sourceforge.net


changes RFC to v2:

Jan Beulich:
  Add xen/arch/x86/hvm/vmware.c for cpuid_vmware_leaves
  Fewer patches

Andrew Cooper:
  use the proper constant for apic_khz
  Follow 839b966e3f587bbb1a0d954230fb3904330dccb6 style changes.
  Changed HVM_PARAM_VMWARE_HW to write once (make is_vmware_domain()
    more static).
  Dropped vmport status stuff.
  Added checks for xzalloc() having failed.
  You should include backdoor_def.h ...
     Every thing I tried did not work better.  So I did not
     change VMPORT_PORT and BDOOR_PORT being the same value.
     I did not try and adjust VMware's include file backdoor_def.h
     to working in other xen source files.
  Switching to s_time_t is not valid. get_sec() is defined:
    unsigned long get_sec(void);
  and so my uses of it should be using unsigned long.  However
  since that is not a fixed width type, I used the uint64_t
  data type which is almost the same, but does allow the 32 bit
  build of libxc, libxl to do the correct thing.


Konrad Rzeszutek Wilk:
  Please don't include the address. It should be, etc
      about the Vmware provided include files.
    I went with no changes to these files.  Even if the files should
    be changed to match xen coding style, etc I still feel that the
    original ones should be added via a patch, and then adjusted in a
    2nd patch.
  Can you use XenBus?
    I would say no.  XenBus (and XenStore) is about domain to domain
    communication.  This is about VMware's hyper-call and providing
    access to VMware's guest info very low speed access.

Olaf Hering:
   Dropped changing of bios-strings.  Still needs some documentation
   about this may be needed to do in a tool stack or set of commands.


Boris Ostrovsky:
  Use svm_nextrip_insn_length()
    Looks like __get_instruction_length() does this, so switched to
    __get_instruction_length().
 
RFC:

See

http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458

for info on detecting VMware.

Linux does not follow this exactly.  It checks for CPUID 1st.  If
that fails, it checks for SMBIOS containing "VMware" (not VMware- or
VMW).

So this patch set provides:

        SMBIOS -- Add string VMware-
        CPUID -- Add VMware's CPUID (Note: currently HyperV (viridian support) breaks this check.)
        Add the magic VMware port
            Allow VMware tools poweroff and reboot
            Enable access to VMware's guest info
            Provide the VMware tools build number


Don Slutz (13):
  hvm: Move MAX_INST_LEN into x86_emulate.h
  xen: Add support for VMware cpuid leaves
  tools: Add vmware_hwver support
  vmware: Add VMware provided include file.
  xen: Add vmware_port support
  xen: Add ring 3 vmware_port support
  tools: Add vmware_port support
  Add IOREQ_TYPE_VMWARE_PORT
  Add xentrace to vmware_port
  test_x86_emulator.c: Add typedef for boot_t
  test_x86_emulator.c: Add emacs block
  test_x86_emulator.c: Add tests for #GP usage
  Add xen-hvm-param

 .gitignore                                   |   1 +
 docs/man/xl.cfg.pod.5                        |  39 +++++-
 docs/misc/hypervisor-cpuid.markdown          |  33 +++++
 tools/libxc/xc_domain_restore.c              |  15 ++
 tools/libxc/xc_domain_save.c                 |  11 ++
 tools/libxc/xc_hvm_build_x86.c               |   5 +-
 tools/libxc/xg_save_restore.h                |   2 +
 tools/libxl/libxl.h                          |  15 ++
 tools/libxl/libxl_create.c                   |  28 +++-
 tools/libxl/libxl_dm.c                       |  16 ++-
 tools/libxl/libxl_dom.c                      |   2 +
 tools/libxl/libxl_internal.h                 |   3 +-
 tools/libxl/libxl_types.idl                  |   3 +
 tools/libxl/xl_cmdimpl.c                     |   5 +
 tools/misc/Makefile                          |   4 +
 tools/misc/xen-hvm-param.c                   | 186 +++++++++++++++++++++++++
 tools/tests/x86_emulator/test_x86_emulator.c | 166 ++++++++++++++++++++++
 tools/xentrace/formats                       |   5 +
 xen/arch/x86/domain.c                        |   2 +
 xen/arch/x86/hvm/Makefile                    |   3 +-
 xen/arch/x86/hvm/emulate.c                   | 110 ++++++++++++++-
 xen/arch/x86/hvm/hvm.c                       | 201 +++++++++++++++++++++++++--
 xen/arch/x86/hvm/io.c                        |  15 ++
 xen/arch/x86/hvm/svm/emulate.c               |   2 -
 xen/arch/x86/hvm/svm/svm.c                   |  31 ++++-
 xen/arch/x86/hvm/svm/vmcb.c                  |   2 +
 xen/arch/x86/hvm/vmware/Makefile             |   2 +
 xen/arch/x86/hvm/vmware/backdoor_def.h       | 167 ++++++++++++++++++++++
 xen/arch/x86/hvm/vmware/cpuid.c              |  75 ++++++++++
 xen/arch/x86/hvm/vmware/includeCheck.h       |   1 +
 xen/arch/x86/hvm/vmware/vmport.c             | 155 +++++++++++++++++++++
 xen/arch/x86/hvm/vmx/vmcs.c                  |   2 +
 xen/arch/x86/hvm/vmx/vmx.c                   |  40 +++++-
 xen/arch/x86/traps.c                         |   8 +-
 xen/arch/x86/x86_emulate/x86_emulate.c       |  29 +++-
 xen/arch/x86/x86_emulate/x86_emulate.h       |  12 ++
 xen/common/domctl.c                          |   3 +
 xen/include/asm-x86/hvm/domain.h             |   6 +-
 xen/include/asm-x86/hvm/emulate.h            |   2 +
 xen/include/asm-x86/hvm/hvm.h                |   9 ++
 xen/include/asm-x86/hvm/trace.h              |  22 +++
 xen/include/asm-x86/hvm/vmport.h             |  33 +++++
 xen/include/asm-x86/hvm/vmware.h             |  33 +++++
 xen/include/public/domctl.h                  |   3 +
 xen/include/public/hvm/hvm_op.h              |   6 +
 xen/include/public/hvm/ioreq.h               |  17 +++
 xen/include/public/hvm/params.h              |   7 +-
 xen/include/public/trace.h                   |   3 +
 xen/include/xen/sched.h                      |   3 +
 49 files changed, 1502 insertions(+), 41 deletions(-)
 create mode 100644 docs/misc/hypervisor-cpuid.markdown
 create mode 100644 tools/misc/xen-hvm-param.c
 create mode 100644 xen/arch/x86/hvm/vmware/Makefile
 create mode 100644 xen/arch/x86/hvm/vmware/backdoor_def.h
 create mode 100644 xen/arch/x86/hvm/vmware/cpuid.c
 create mode 100644 xen/arch/x86/hvm/vmware/includeCheck.h
 create mode 100644 xen/arch/x86/hvm/vmware/vmport.c
 create mode 100644 xen/include/asm-x86/hvm/vmport.h
 create mode 100644 xen/include/asm-x86/hvm/vmware.h

-- 
1.8.4

^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17  9:52   ` Andrew Cooper
  2015-03-03 14:02   ` George Dunlap
  2015-02-16 23:05 ` [PATCH v9 02/13] xen: Add support for VMware cpuid leaves Don Slutz
                   ` (11 subsequent siblings)
  12 siblings, 2 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

Change some hard coded 15 into MAX_INST_LEN

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
 xen/arch/x86/hvm/svm/emulate.c         | 2 --
 xen/arch/x86/hvm/svm/svm.c             | 4 ++--
 xen/arch/x86/hvm/vmx/vmx.c             | 2 +-
 xen/arch/x86/x86_emulate/x86_emulate.c | 4 ++--
 xen/arch/x86/x86_emulate/x86_emulate.h | 2 ++
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/hvm/svm/emulate.c b/xen/arch/x86/hvm/svm/emulate.c
index 37a1ece..6f5c8d3 100644
--- a/xen/arch/x86/hvm/svm/emulate.c
+++ b/xen/arch/x86/hvm/svm/emulate.c
@@ -27,8 +27,6 @@
 #include <asm/hvm/svm/vmcb.h>
 #include <asm/hvm/svm/emulate.h>
 
-#define MAX_INST_LEN 15
-
 static unsigned int is_prefix(u8 opc)
 {
     switch ( opc )
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index a7655bd..4b7b818 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -106,7 +106,7 @@ void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len)
     if ( unlikely(inst_len == 0) )
         return;
 
-    if ( unlikely(inst_len > 15) )
+    if ( unlikely(inst_len > MAX_INST_LEN) )
     {
         gdprintk(XENLOG_ERR, "Bad instruction length %u\n", inst_len);
         svm_crash_or_fault(curr);
@@ -859,7 +859,7 @@ static unsigned int svm_get_insn_bytes(struct vcpu *v, uint8_t *buf)
     if ( len != 0 )
     {
         /* Latch and clear the cached instruction. */
-        memcpy(buf, vmcb->guest_ins, 15);
+        memcpy(buf, vmcb->guest_ins, MAX_INST_LEN);
         v->arch.hvm_svm.cached_insn_len = 0;
     }
 
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 357ef6c..e1c55ce 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1854,7 +1854,7 @@ static int get_instruction_length(void)
     unsigned long len;
 
     __vmread(VM_EXIT_INSTRUCTION_LEN, &len); /* Safe: callers audited */
-    BUG_ON((len < 1) || (len > 15));
+    BUG_ON((len < 1) || (len > MAX_INST_LEN));
     return len;
 }
 
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index f13f07d..42e2588 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -579,8 +579,8 @@ do{ asm volatile (                                                      \
 ({ unsigned long _x = 0, _eip = _regs.eip;                              \
    if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
    _regs.eip += (_size); /* real hardware doesn't truncate */           \
-   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
-                         EXC_GP, 0);                                    \
+   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) >       \
+			 MAX_INST_LEN, EXC_GP, 0);                       \
    rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
    if ( rc ) goto done;                                                 \
    _x;                                                                  \
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h
index bdce861..593b31e 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -24,6 +24,8 @@
 #ifndef __X86_EMULATE_H__
 #define __X86_EMULATE_H__
 
+#define MAX_INST_LEN 15
+
 struct x86_emulate_ctxt;
 
 /* Comprehensive enumeration of x86 segment registers. */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 02/13] xen: Add support for VMware cpuid leaves
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
  2015-02-16 23:05 ` [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 10:02   ` Andrew Cooper
  2015-02-16 23:05 ` [PATCH v9 03/13] tools: Add vmware_hwver support Don Slutz
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

This is done by adding HVM_PARAM_VMWARE_HW. It is set to the VMware
virtual hardware version.

Currently 0, 3-4, 6-11 are good values.  However the
code only checks for == 0 or != 0 or >= 7.

If non-zero then
  Return VMware's cpuid leaves.  If >= 7 return data, else
  return 0.

The support of hypervisor cpuid leaves has not been agreed to.

MicroSoft Hyper-V (AKA viridian) currently must be at 0x40000000.

VMware currently must be at 0x40000000.

KVM currently must be at 0x40000000 (from Seabios).

Xen can be found at the first otherwise unused 0x100 aligned
offset between 0x40000000 and 0x40010000.

http://download.microsoft.com/download/F/B/0/FB0D01A3-8E3A-4F5F-AA59-08C8026D3B8A/requirements-for-implementing-microsoft-hypervisor-interface.docx

http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458

http://lwn.net/Articles/301888/
  Attempted to get this cleaned up.

So based on this, I picked the order:

Xen at 0x40000000 or
Viridian or VMware at 0x40000000 and Xen at 0x40000100

If both Viridian and VMware selected, report an error.

Since I need to change xen/arch/x86/hvm/Makefile; also add
a newline at end of file.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
    s/vmware_hw/vmware_hwver/i
    Change -EXDEV to EOPNOTSUPP.
      Done.
    adding another subdirectory: xen/arch/x86/hvm/vmware
    Much will depend on the discussion of the subsequent patches.
      TBD.
    So for versions < 7 there's effectively no CPUID support at all?
      Changed to check at entry.
    The comment /* Params for VMware */ seems wrong...
      Changed to /* emulated VMware Hardware Version */
    Also please use d, not _d in #define is_vmware_domain()
      Changed.  Line is now > 80 characters, so split into 2.

v7:
      Prevent setting of HVM_PARAM_VIRIDIAN if HVM_PARAM_VMWARE_HW set.
v5:
      Given how is_viridian and is_vmware are defined I think '||' is more
      appropriate.
        Fixed.
      The names of all three functions are bogus.
        removed static support routines.
      This hunk is unrelated, but is perhaps something better fixed.
        Added to commit message.
      include <xen/types.h> (IIRC) please.
        Done.
      At least 1 pair of brackets please, especially as the placement of
      brackets affects the result of this particular calculation.
        Switch to "1000000ull / APIC_BUS_CYCLE_NS"      

 xen/arch/x86/hvm/Makefile        |  3 +-
 xen/arch/x86/hvm/hvm.c           | 32 +++++++++++++++++
 xen/arch/x86/hvm/vmware/Makefile |  1 +
 xen/arch/x86/hvm/vmware/cpuid.c  | 75 ++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/traps.c             |  8 +++--
 xen/include/asm-x86/hvm/hvm.h    |  7 ++++
 xen/include/asm-x86/hvm/vmware.h | 33 ++++++++++++++++++
 xen/include/public/hvm/params.h  |  5 ++-
 8 files changed, 160 insertions(+), 4 deletions(-)
 create mode 100644 xen/arch/x86/hvm/vmware/Makefile
 create mode 100644 xen/arch/x86/hvm/vmware/cpuid.c
 create mode 100644 xen/include/asm-x86/hvm/vmware.h

diff --git a/xen/arch/x86/hvm/Makefile b/xen/arch/x86/hvm/Makefile
index eea5555..77598a6 100644
--- a/xen/arch/x86/hvm/Makefile
+++ b/xen/arch/x86/hvm/Makefile
@@ -1,5 +1,6 @@
 subdir-y += svm
 subdir-y += vmx
+subdir-y += vmware
 
 obj-y += asid.o
 obj-y += emulate.o
@@ -22,4 +23,4 @@ obj-y += vlapic.o
 obj-y += vmsi.o
 obj-y += vpic.o
 obj-y += vpt.o
-obj-y += vpmu.o
\ No newline at end of file
+obj-y += vpmu.o
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index a52c6e0..fefd023 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -60,6 +60,7 @@
 #include <asm/hvm/cacheattr.h>
 #include <asm/hvm/trace.h>
 #include <asm/hvm/nestedhvm.h>
+#include <asm/hvm/vmware.h>
 #include <asm/mtrr.h>
 #include <asm/apic.h>
 #include <public/sched.h>
@@ -4277,6 +4278,9 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
     if ( cpuid_viridian_leaves(input, eax, ebx, ecx, edx) )
         return;
 
+    if ( cpuid_vmware_leaves(input, eax, ebx, ecx, edx) )
+        return;
+
     if ( cpuid_hypervisor_leaves(input, count, eax, ebx, ecx, edx) )
         return;
 
@@ -5752,6 +5756,11 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
                 if ( curr_d == d )
                     break;
 
+                if ( d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] )
+                {
+                    rc = -EOPNOTSUPP;
+                    break;
+                }
                 if ( a.value != d->arch.hvm_domain.params[a.index] )
                 {
                     rc = -EEXIST;
@@ -5900,6 +5909,29 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
 
                 break;
             }
+            case HVM_PARAM_VMWARE_HWVER:
+                /*
+                 * This should only ever be set non-zero one time by
+                 * the tools and is read only by the guest.
+                 */
+                if ( curr_d == d )
+                {
+                    rc = -EPERM;
+                    break;
+                }
+                if ( d->arch.hvm_domain.params[HVM_PARAM_VIRIDIAN] )
+                {
+                    rc = -EXDEV;
+                    break;
+                }
+                if ( d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] &&
+                     d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] !=
+                     a.value )
+                {
+                    rc = -EEXIST;
+                    break;
+                }
+                break;
             }
 
             if ( rc == 0 ) 
diff --git a/xen/arch/x86/hvm/vmware/Makefile b/xen/arch/x86/hvm/vmware/Makefile
new file mode 100644
index 0000000..3fb2e0b
--- /dev/null
+++ b/xen/arch/x86/hvm/vmware/Makefile
@@ -0,0 +1 @@
+obj-y += cpuid.o
diff --git a/xen/arch/x86/hvm/vmware/cpuid.c b/xen/arch/x86/hvm/vmware/cpuid.c
new file mode 100644
index 0000000..70cdabd
--- /dev/null
+++ b/xen/arch/x86/hvm/vmware/cpuid.c
@@ -0,0 +1,75 @@
+/*
+ * arch/x86/hvm/vmware/cpuid.c
+ *
+ * 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/sched.h>
+
+#include <asm/hvm/hvm.h>
+#include <asm/hvm/vmware.h>
+
+/*
+ * VMware hardware version 7 defines some of these cpuid levels,
+ * below is a brief description about those.
+ *
+ *     Leaf 0x40000000, Hypervisor CPUID information
+ * # EAX: The maximum input value for hypervisor CPUID info (0x40000010).
+ * # EBX, ECX, EDX: Hypervisor vendor ID signature. E.g. "VMwareVMware"
+ *
+ *     Leaf 0x40000010, Timing information.
+ * # EAX: (Virtual) TSC frequency in kHz.
+ * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
+ * # ECX, EDX: RESERVED
+ */
+
+int cpuid_vmware_leaves(uint32_t idx, uint32_t *eax, uint32_t *ebx,
+                        uint32_t *ecx, uint32_t *edx)
+{
+    struct domain *d = current->domain;
+
+    if ( !is_vmware_domain(d) ||
+         d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] < 7 )
+        return 0;
+
+    switch ( idx - 0x40000000 )
+    {
+    case 0x0:
+        *eax = 0x40000010;  /* Largest leaf */
+        *ebx = 0x61774d56;  /* "VMwa" */
+        *ecx = 0x4d566572;  /* "reVM" */
+        *edx = 0x65726177;  /* "ware" */
+        break;
+    case 0x10:
+        /* (Virtual) TSC frequency in kHz. */
+        *eax =  d->arch.tsc_khz;
+        /* (Virtual) Bus (local apic timer) frequency in kHz. */
+        *ebx = 1000000ull / APIC_BUS_CYCLE_NS;
+        *ecx = 0;          /* Reserved */
+        *edx = 0;          /* Reserved */
+        break;
+    default:
+        return 0;
+    }
+
+    return 1;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index f5516dc..589e458 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -750,8 +750,12 @@ int cpuid_hypervisor_leaves( uint32_t idx, uint32_t sub_idx,
                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
 {
     struct domain *d = current->domain;
-    /* Optionally shift out of the way of Viridian architectural leaves. */
-    uint32_t base = is_viridian_domain(d) ? 0x40000100 : 0x40000000;
+    /*
+     * Optionally shift out of the way of Viridian or VMware
+     * architectural leaves.
+     */
+    uint32_t base = is_viridian_domain(d) || is_vmware_domain(d) ?
+        0x40000100 : 0x40000000;
     uint32_t limit, dummy;
 
     idx -= base;
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 0dc909b..8ecde89 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -356,6 +356,13 @@ static inline unsigned long hvm_get_shadow_gs_base(struct vcpu *v)
 #define has_viridian_time_ref_count(d) \
     (is_viridian_domain(d) && (viridian_feature_mask(d) & HVMPV_time_ref_count))
 
+#define vmware_feature_mask(d) \
+    (has_hvm_params(d) ? \
+     (d)->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] : 0)
+
+#define is_vmware_domain(d) \
+    (is_hvm_domain(d) && vmware_feature_mask(d))
+
 void hvm_hypervisor_cpuid_leaf(uint32_t sub_idx,
                                uint32_t *eax, uint32_t *ebx,
                                uint32_t *ecx, uint32_t *edx);
diff --git a/xen/include/asm-x86/hvm/vmware.h b/xen/include/asm-x86/hvm/vmware.h
new file mode 100644
index 0000000..8390173
--- /dev/null
+++ b/xen/include/asm-x86/hvm/vmware.h
@@ -0,0 +1,33 @@
+/*
+ * asm-x86/hvm/vmware.h
+ *
+ * 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/>.
+ */
+
+#ifndef ASM_X86_HVM_VMWARE_H__
+#define ASM_X86_HVM_VMWARE_H__
+
+#include <xen/types.h>
+
+int cpuid_vmware_leaves(uint32_t idx, uint32_t *eax, uint32_t *ebx,
+                        uint32_t *ecx, uint32_t *edx);
+
+#endif /* ASM_X86_HVM_VMWARE_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index a2d43bc..974d3a4 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -194,6 +194,9 @@
 /* Location of the VM Generation ID in guest physical address space. */
 #define HVM_PARAM_VM_GENERATION_ID_ADDR 34
 
-#define HVM_NR_PARAMS          35
+/* emulated VMware Hardware Version */
+#define HVM_PARAM_VMWARE_HWVER 35
+
+#define HVM_NR_PARAMS          36
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 03/13] tools: Add vmware_hwver support
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
  2015-02-16 23:05 ` [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h Don Slutz
  2015-02-16 23:05 ` [PATCH v9 02/13] xen: Add support for VMware cpuid leaves Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-03-03 14:14   ` Ian Campbell
  2015-02-16 23:05 ` [PATCH v9 04/13] vmware: Add VMware provided include file Don Slutz
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

This is used to set HVM_PARAM_VMWARE_HWVER. It is set to the
emulated VMware virtual hardware version.

Currently 0, 3-4, 6-11 are good values.  However the code only
checks for == 0, != 0, or < 7.

If non-zero then
  default VGA to VMware's VGA.

Also now allows vga=vmware

Signed-off-by: Don Slutz <dslutz@verizon.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v9:
      I assumed that s/vmware_hw/vmware_hwver/ is not a big enough
      change to drop the Reviewed-by.  Did a minor edit to the
      commit message to add 7 to the list of values checked.

v7:
    Default handling of hvm.vga.kind bad.
      Fixed.
    Default of vmware_port should be based on vmware_hw.
      Done. 

v5:
      Anything looking for Xen according to the Xen cpuid instructions...
        Adjusted doc to new wording.

 docs/man/xl.cfg.pod.5               | 25 +++++++++++++++++++++++--
 docs/misc/hypervisor-cpuid.markdown | 33 +++++++++++++++++++++++++++++++++
 tools/libxc/xc_domain_restore.c     | 15 +++++++++++++++
 tools/libxc/xc_domain_save.c        | 11 +++++++++++
 tools/libxc/xg_save_restore.h       |  2 ++
 tools/libxl/libxl.h                 | 10 ++++++++++
 tools/libxl/libxl_create.c          | 12 +++++++++---
 tools/libxl/libxl_dm.c              |  8 ++++++++
 tools/libxl/libxl_dom.c             |  2 ++
 tools/libxl/libxl_types.idl         |  2 ++
 tools/libxl/xl_cmdimpl.c            |  4 ++++
 11 files changed, 119 insertions(+), 5 deletions(-)
 create mode 100644 docs/misc/hypervisor-cpuid.markdown

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 408653f..905ca8f 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -1271,6 +1271,23 @@ The viridian option can be specified as a boolean. A value of true (1)
 is equivalent to the list [ "defaults" ], and a value of false (0) is
 equivalent to an empty list.
 
+=item B<vmware_hwver=NUMBER>
+
+Turns on or off the exposure of VMware cpuid.  The number is
+VMware's hardware version number, where 0 is off.  If not zero it
+changes the default VGA to VMware's VGA.
+
+The hardware version number (vmware_hwver) come from VMware config files.
+
+=over 4
+
+In a .vmx it is virtualHW.version
+
+In a .ovf it is part of the value of vssd:VirtualSystemType.
+For vssd:VirtualSystemType == vmx-07, vmware_hwver = 7.
+
+=back
+
 =back
 
 =head3 Emulated VGA Graphics Device
@@ -1307,10 +1324,14 @@ later (e.g. Windows XP onwards) then you should enable this.
 stdvga supports more video ram and bigger resolutions than Cirrus.
 This option is deprecated, use vga="stdvga" instead.
 
+The deprecated B<stdvga=0> prevents the usage of vmware by default
+if B<vmware_hwver> is non-zero. 
+
 =item B<vga="STRING">
 
-Selects the emulated video card (none|stdvga|cirrus).
-The default is cirrus.
+Selects the emulated video card (none|stdvga|cirrus|vmware).
+The default is cirrus unless B<vmware_hwver> is non-zero in which case it
+is vmware.
 
 =item B<vnc=BOOLEAN>
 
diff --git a/docs/misc/hypervisor-cpuid.markdown b/docs/misc/hypervisor-cpuid.markdown
new file mode 100644
index 0000000..473f6a6
--- /dev/null
+++ b/docs/misc/hypervisor-cpuid.markdown
@@ -0,0 +1,33 @@
+Hypervisor Cpuid
+================
+
+There is no agreed standard for the use of hypervisor cpuid leaves.
+
+AMD (Vol3, Appendix E.3.9) reserves 0x40000000 to 0x400000ff for
+hypervisor use, while Intel (Vol 2a, 3.2 CPUID) guarantees that no
+existing or future CPUs will use the range 0x40000000 to 0x4fffffff.
+
+Different hypervisors use the space as follows:
+
+MicroSoft Hyper-V (AKA viridian) leaves currently must be at
+0x40000000.
+
+VMware leaves currently must be at 0x40000000.
+
+KVM leaves currently must be at 0x40000000 (from Seabios).
+
+Xen leaves can be found at the first otherwise unused 0x100 aligned
+offset between 0x40000000 and 0x40010000.
+
+http://download.microsoft.com/download/F/B/0/FB0D01A3-8E3A-4F5F-AA59-08C8026D3B8A/requirements-for-implementing-microsoft-hypervisor-interface.docx
+
+http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
+
+http://lwn.net/Articles/301888/
+  Attempted to get this cleaned up.
+
+So if viridian or vmware_hwver is selected, return their format for
+the range 0x40000000 to 0x400000ff. And return Xen format for the
+range 0x40000100 to 0x400001ff.
+
+Otherwise return Xen format for the range 0x40000000 to 0x400000ff.
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index a382701..386ba3c 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -743,6 +743,7 @@ typedef struct {
     uint64_t vm_generationid_addr;
     uint64_t ioreq_server_pfn;
     uint64_t nr_ioreq_server_pages;
+    uint64_t vmware_hwver;
 
     struct toolstack_data_t tdata;
 } pagebuf_t;
@@ -927,6 +928,16 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx,
         }
         return pagebuf_get_one(xch, ctx, buf, fd, dom);
 
+    case XC_SAVE_ID_HVM_VMWARE_HWVER:
+        /* Skip padding 4 bytes then read the vmware hw version. */
+        if ( RDEXACT(fd, &buf->vmware_hwver, sizeof(uint32_t)) ||
+             RDEXACT(fd, &buf->vmware_hwver, sizeof(uint64_t)) )
+        {
+            PERROR("error read the vmware_hwver value");
+            return -1;
+        }
+        return pagebuf_get_one(xch, ctx, buf, fd, dom);
+
     case XC_SAVE_ID_TOOLSTACK:
         {
             if ( RDEXACT(fd, &buf->tdata.len, sizeof(buf->tdata.len)) )
@@ -1774,6 +1785,10 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
         }
     }
 
+    if (pagebuf.vmware_hwver != 0)
+        xc_set_hvm_param(xch, dom, HVM_PARAM_VMWARE_HWVER,
+                         pagebuf.vmware_hwver);
+
     if (pagebuf.acpi_ioport_location == 1) {
         DBGPRINTF("Use new firmware ioport from the checkpoint\n");
         xc_hvm_param_set(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION, 1);
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 254fdb3..40d413f 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1750,6 +1750,17 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
             PERROR("Error when writing the ioreq server gmfn count");
             goto out;
         }
+
+        chunk.id = XC_SAVE_ID_HVM_VMWARE_HWVER;
+        chunk.data = 0;
+        xc_hvm_param_get(xch, dom, HVM_PARAM_VMWARE_HWVER, &chunk.data);
+
+        if ( (chunk.data != 0) &&
+             wrexact(io_fd, &chunk, sizeof(chunk)) )
+        {
+            PERROR("Error when writing the vmware_hwver value");
+            goto out;
+        }
     }
 
     if ( callbacks != NULL && callbacks->toolstack_save != NULL )
diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h
index bdd9009..d73d152 100644
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -262,6 +262,8 @@
 /* These are a pair; it is an error for one to exist without the other */
 #define XC_SAVE_ID_HVM_IOREQ_SERVER_PFN -19
 #define XC_SAVE_ID_HVM_NR_IOREQ_SERVER_PAGES -20
+/* VMware data */
+#define XC_SAVE_ID_HVM_VMWARE_HWVER   -21
 
 /*
 ** We process save/restore/migrate in batches of pages; the below
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index c219f59..0c27e5c 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -163,6 +163,16 @@
 #define LIBXL_HAVE_BUILDINFO_HVM_MMIO_HOLE_MEMKB 1
 
 /*
+ * The libxl_vga_interface_type has the type for vmware.
+ */
+#define LIBXL_HAVE_LIBXL_VGA_INTERFACE_TYPE_VMWARE 1
+
+/*
+ * libxl_domain_build_info has the u.hvm.vmware_hwver field.
+ */
+#define LIBXL_HAVE_BUILDINFO_HVM_VMWARE_HWVER 1
+
+/*
  * libxl ABI compatibility
  *
  * The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 98687bd..8c910c4 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -238,8 +238,12 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
         if (b_info->u.hvm.mmio_hole_memkb == LIBXL_MEMKB_DEFAULT)
             b_info->u.hvm.mmio_hole_memkb = 0;
 
-        if (!b_info->u.hvm.vga.kind)
-            b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
+        if (!b_info->u.hvm.vga.kind) {
+            if (b_info->u.hvm.vmware_hwver)
+                b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_VMWARE;
+            else
+                b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
+        }
 
         switch (b_info->device_model_version) {
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
@@ -442,7 +446,7 @@ int libxl__domain_build(libxl__gc *gc,
         vments[4] = "start_time";
         vments[5] = libxl__sprintf(gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
 
-        localents = libxl__calloc(gc, 9, sizeof(char *));
+        localents = libxl__calloc(gc, 11, sizeof(char *));
         i = 0;
         localents[i++] = "platform/acpi";
         localents[i++] = libxl_defbool_val(info->u.hvm.acpi) ? "1" : "0";
@@ -450,6 +454,8 @@ int libxl__domain_build(libxl__gc *gc,
         localents[i++] = libxl_defbool_val(info->u.hvm.acpi_s3) ? "1" : "0";
         localents[i++] = "platform/acpi_s4";
         localents[i++] = libxl_defbool_val(info->u.hvm.acpi_s4) ? "1" : "0";
+        localents[i++] = "platform/vmware_hwver";
+        localents[i++] = libxl__sprintf(gc, "%"PRId64, info->u.hvm.vmware_hwver);
         if (info->u.hvm.mmio_hole_memkb) {
             uint64_t max_ram_below_4g =
                 (1ULL << 32) - (info->u.hvm.mmio_hole_memkb << 10);
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 8599a6a..b05fa73 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -244,6 +244,9 @@ static char ** libxl__build_device_model_args_old(libxl__gc *gc,
         case LIBXL_VGA_INTERFACE_TYPE_NONE:
             flexarray_append_pair(dm_args, "-vga", "none");
             break;
+        case LIBXL_VGA_INTERFACE_TYPE_VMWARE:
+            flexarray_append_pair(dm_args, "-vga", "vmware");
+            break;
         }
 
         if (b_info->u.hvm.boot) {
@@ -599,6 +602,11 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
             break;
         case LIBXL_VGA_INTERFACE_TYPE_NONE:
             break;
+        case LIBXL_VGA_INTERFACE_TYPE_VMWARE:
+            flexarray_append_pair(dm_args, "-device",
+                GCSPRINTF("vmware-svga,vgamem_mb=%d",
+                libxl__sizekb_to_mb(b_info->video_memkb)));
+            break;
         }
 
         if (b_info->u.hvm.boot) {
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 48d661a..34a36d3 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -294,6 +294,8 @@ static void hvm_set_conf_params(xc_interface *handle, uint32_t domid,
 #if defined(__i386__) || defined(__x86_64__)
     xc_hvm_param_set(handle, domid, HVM_PARAM_HPET_ENABLED,
                     libxl_defbool_val(info->u.hvm.hpet));
+    xc_set_hvm_param(handle, domid, HVM_PARAM_VMWARE_HWVER,
+                     info->u.hvm.vmware_hwver);
 #endif
     xc_hvm_param_set(handle, domid, HVM_PARAM_TIMER_MODE, timer_mode(info));
     xc_hvm_param_set(handle, domid, HVM_PARAM_VPT_ALIGN,
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 02be466..ad596de 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -181,6 +181,7 @@ libxl_vga_interface_type = Enumeration("vga_interface_type", [
     (1, "CIRRUS"),
     (2, "STD"),
     (3, "NONE"),
+    (4, "VMWARE"),
     ], init_val = "LIBXL_VGA_INTERFACE_TYPE_CIRRUS")
 
 libxl_vendor_device = Enumeration("vendor_device", [
@@ -417,6 +418,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("hpet",             libxl_defbool),
                                        ("vpt_align",        libxl_defbool),
                                        ("mmio_hole_memkb",  MemKB),
+                                       ("vmware_hwver",     uint64),
                                        ("timer_mode",       libxl_timer_mode),
                                        ("nested_hvm",       libxl_defbool),
                                        ("smbios_firmware",  string),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 440db78..ca6d0ec 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1280,6 +1280,8 @@ static void parse_config_data(const char *config_source,
                 exit (1);
             }
         }
+        if (!xlu_cfg_get_long(config, "vmware_hwver",  &l, 1))
+            b_info->u.hvm.vmware_hwver = l;
         if (!xlu_cfg_get_long(config, "timer_mode", &l, 1)) {
             const char *s = libxl_timer_mode_to_string(l);
             fprintf(stderr, "WARNING: specifying \"timer_mode\" as an integer is deprecated. "
@@ -1920,6 +1922,8 @@ skip_vfb:
                 b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
             } else if (!strcmp(buf, "none")) {
                 b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_NONE;
+            } else if (!strcmp(buf, "vmware")) {
+                b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_VMWARE;
             } else {
                 fprintf(stderr, "Unknown vga \"%s\" specified\n", buf);
                 exit(1);
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 04/13] vmware: Add VMware provided include file.
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (2 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 03/13] tools: Add vmware_hwver support Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 10:03   ` Andrew Cooper
  2015-02-16 23:05 ` [PATCH v9 05/13] xen: Add vmware_port support Don Slutz
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

This file: backdoor_def.h comes from:

http://packages.vmware.com/tools/esx/3.5latest/rhel4/SRPMS/index.html
 open-vm-tools-kmod-7.4.8-396269.423167.src.rpm
  open-vm-tools-kmod-7.4.8.tar.gz
   vmhgfs/backdoor_def.h

and is unchanged.

Added the badly named include file includeCheck.h also.  It only has
a comment and is provided so that backdoor_def.h can be used without
change.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
    Either the description is wrong, or the patch is stale.
      stale commit message -- fixed.
    I'd say a file with a single comment line in it would suffice.
      Done.


 xen/arch/x86/hvm/vmware/backdoor_def.h | 167 +++++++++++++++++++++++++++++++++
 xen/arch/x86/hvm/vmware/includeCheck.h |   1 +
 2 files changed, 168 insertions(+)
 create mode 100644 xen/arch/x86/hvm/vmware/backdoor_def.h
 create mode 100644 xen/arch/x86/hvm/vmware/includeCheck.h

diff --git a/xen/arch/x86/hvm/vmware/backdoor_def.h b/xen/arch/x86/hvm/vmware/backdoor_def.h
new file mode 100644
index 0000000..e76795f
--- /dev/null
+++ b/xen/arch/x86/hvm/vmware/backdoor_def.h
@@ -0,0 +1,167 @@
+/* **********************************************************
+ * Copyright 1998 VMware, Inc.  All rights reserved. 
+ * **********************************************************
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+ * backdoor_def.h --
+ *
+ * This contains backdoor defines that can be included from
+ * an assembly language file.
+ */
+
+
+
+#ifndef _BACKDOOR_DEF_H_
+#define _BACKDOOR_DEF_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMMEXT
+#define INCLUDE_ALLOW_VMCORE
+#define INCLUDE_ALLOW_VMKERNEL
+#include "includeCheck.h"
+
+/*
+ * If you want to add a new low-level backdoor call for a guest userland
+ * application, please consider using the GuestRpc mechanism instead. --hpreg
+ */
+
+#define BDOOR_MAGIC 0x564D5868
+
+/* Low-bandwidth backdoor port. --hpreg */
+
+#define BDOOR_PORT 0x5658
+
+#define BDOOR_CMD_GETMHZ      		   1
+/*
+ * BDOOR_CMD_APMFUNCTION is used by:
+ *
+ * o The FrobOS code, which instead should either program the virtual chipset
+ *   (like the new BIOS code does, matthias offered to implement that), or not
+ *   use any VM-specific code (which requires that we correctly implement
+ *   "power off on CLI HLT" for SMP VMs, boris offered to implement that)
+ *
+ * o The old BIOS code, which will soon be jettisoned
+ *
+ *  --hpreg
+ */
+#define BDOOR_CMD_APMFUNCTION 		   2
+#define BDOOR_CMD_GETDISKGEO  		   3
+#define BDOOR_CMD_GETPTRLOCATION	      4
+#define BDOOR_CMD_SETPTRLOCATION	      5
+#define BDOOR_CMD_GETSELLENGTH		   6
+#define BDOOR_CMD_GETNEXTPIECE		   7
+#define BDOOR_CMD_SETSELLENGTH		   8
+#define BDOOR_CMD_SETNEXTPIECE		   9
+#define BDOOR_CMD_GETVERSION		      10
+#define BDOOR_CMD_GETDEVICELISTELEMENT	11
+#define BDOOR_CMD_TOGGLEDEVICE		   12
+#define BDOOR_CMD_GETGUIOPTIONS		   13
+#define BDOOR_CMD_SETGUIOPTIONS		   14
+#define BDOOR_CMD_GETSCREENSIZE		   15
+#define BDOOR_CMD_MONITOR_CONTROL       16
+#define BDOOR_CMD_GETHWVERSION          17
+#define BDOOR_CMD_OSNOTFOUND            18
+#define BDOOR_CMD_GETUUID               19
+#define BDOOR_CMD_GETMEMSIZE            20
+#define BDOOR_CMD_HOSTCOPY              21 /* Devel only */
+/* BDOOR_CMD_GETOS2INTCURSOR, 22, is very old and defunct. Reuse. */
+#define BDOOR_CMD_GETTIME               23 /* Deprecated. Use GETTIMEFULL. */
+#define BDOOR_CMD_STOPCATCHUP           24
+#define BDOOR_CMD_PUTCHR	        25 /* Devel only */
+#define BDOOR_CMD_ENABLE_MSG	        26 /* Devel only */
+#define BDOOR_CMD_GOTO_TCL	        27 /* Devel only */
+#define BDOOR_CMD_INITPCIOPROM		28
+#define BDOOR_CMD_INT13			29
+#define BDOOR_CMD_MESSAGE               30
+#define BDOOR_CMD_RSVD0                 31
+#define BDOOR_CMD_RSVD1                 32
+#define BDOOR_CMD_RSVD2                 33
+#define BDOOR_CMD_ISACPIDISABLED	34
+#define BDOOR_CMD_TOE			35 /* Not in use */
+/* BDOOR_CMD_INITLSIOPROM, 36, was merged with 28. Reuse. */
+#define BDOOR_CMD_PATCH_SMBIOS_STRUCTS  37
+#define BDOOR_CMD_MAPMEM                38 /* Devel only */
+#define BDOOR_CMD_ABSPOINTER_DATA	39
+#define BDOOR_CMD_ABSPOINTER_STATUS	40
+#define BDOOR_CMD_ABSPOINTER_COMMAND	41
+#define BDOOR_CMD_TIMER_SPONGE          42
+#define BDOOR_CMD_PATCH_ACPI_TABLES	43
+/* Catch-all to allow synchronous tests */
+#define BDOOR_CMD_DEVEL_FAKEHARDWARE	44 /* Debug only - needed in beta */
+#define BDOOR_CMD_GETHZ      		45
+#define BDOOR_CMD_GETTIMEFULL           46
+#define BDOOR_CMD_STATELOGGER           47
+#define BDOOR_CMD_CHECKFORCEBIOSSETUP	48
+#define BDOOR_CMD_LAZYTIMEREMULATION    49
+#define BDOOR_CMD_BIOSBBS               50
+#define BDOOR_CMD_MAX                   51
+
+/* 
+ * IMPORTANT NOTE: When modifying the behavior of an existing backdoor command,
+ * you must adhere to the semantics expected by the oldest Tools who use that
+ * command. Specifically, do not alter the way in which the command modifies 
+ * the registers. Otherwise backwards compatibility will suffer.
+ */
+
+/* High-bandwidth backdoor port. --hpreg */
+
+#define BDOORHB_PORT 0x5659
+
+#define BDOORHB_CMD_MESSAGE 0
+#define BDOORHB_CMD_MAX 1
+
+/*
+ * There is another backdoor which allows access to certain TSC-related
+ * values using otherwise illegal PMC indices when the pseudo_perfctr
+ * control flag is set.
+ */
+
+#define BDOOR_PMC_HW_TSC      0x10000
+#define BDOOR_PMC_REAL_NS     0x10001
+#define BDOOR_PMC_APPARENT_NS 0x10002
+
+#define IS_BDOOR_PMC(index)  (((index) | 3) == 0x10003)
+#define BDOOR_CMD(ecx)       ((ecx) & 0xffff)
+
+
+#ifdef VMM
+/*
+ *----------------------------------------------------------------------
+ *
+ * Backdoor_CmdRequiresFullyValidVCPU --
+ *
+ *    A few backdoor commands require the full VCPU to be valid
+ *    (including GDTR, IDTR, TR and LDTR). The rest get read/write
+ *    access to GPRs and read access to Segment registers (selectors).
+ *
+ * Result:
+ *    True iff VECX contains a command that require the full VCPU to
+ *    be valid.
+ *
+ *----------------------------------------------------------------------
+ */
+static INLINE Bool
+Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd)
+{
+   return cmd == BDOOR_CMD_RSVD0 ||
+          cmd == BDOOR_CMD_RSVD1 ||
+          cmd == BDOOR_CMD_RSVD2;
+}
+#endif
+
+#endif
diff --git a/xen/arch/x86/hvm/vmware/includeCheck.h b/xen/arch/x86/hvm/vmware/includeCheck.h
new file mode 100644
index 0000000..3b63fa4
--- /dev/null
+++ b/xen/arch/x86/hvm/vmware/includeCheck.h
@@ -0,0 +1 @@
+/* Nothing here.  Just to use backdoor_def.h without change. */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 05/13] xen: Add vmware_port support
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (3 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 04/13] vmware: Add VMware provided include file Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 10:30   ` Andrew Cooper
  2015-02-23 15:05   ` Jan Beulich
  2015-02-16 23:05 ` [PATCH v9 06/13] xen: Add ring 3 " Don Slutz
                   ` (7 subsequent siblings)
  12 siblings, 2 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

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.

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

Some of the best info is at:

https://sites.google.com/site/chitchatvmback/backdoor

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
  Switch to x86_emulator to handle #GP code moved to next patch.
    Can you explain why a HVM param isn't suitable here?
      Issue with changing QEMU on the fly.
      Andrew Cooper: My recommendation is still to use a creation flag
        So no change.
    Please move SVM's identical definition into ...
      Did this as #1.  No longer needed, but since the patch was ready
      I have included it.
    --Lots of questions about code that no long is part of this patch. --
    With this, is handling other than 32-bit in/out really
    meaningful/correct?
      Added comment about this.
    Since you can't get here for PV, I can't see what you need this.
      Changed to an ASSERT.
    Why version 4?
      Added comment about this.
    -- Several questions about register changes.
      Re-coded to use new_eax and set *val to this.
      Change to generealy use reg->_e..
    These ei1/ei2 checks belong in the callers imo -
      Moved.
    the "port" function parameter isn't even checked
      Add check for exact match.
    If dropping the code is safe without also forbidding the
    combination of nested and VMware emulation.
      Added the forbidding the combination of nested and VMware.
      Mostly do to the cases of the nested virtual code is the one
      to handle VMware stuff if needed, not the root one.  Also I am
      having issues testing xen nested in xen and using hvm.

v7:
      More on AMD in the commit message.
      Switch to only change 32bit part of registers, what VMware
        does.
    Too much logging and tracing.
      Dropped a lot of it.  This includes vmport_debug=

v6:
      Dropped the attempt to use svm_nextrip_insn_length via
      __get_instruction_length (added in v2).  Just always look
      at upto 15 bytes on AMD.

v5:
      we should make sure that svm_vmexit_gp_intercept is not executed for
      any other guest.
        Added an ASSERT on is_vmware_port_enabled.
      magic integers?
        Added #define for them.
      I am fairly certain that you need some brackets here.
        Added brackets.

 xen/arch/x86/domain.c            |   2 +
 xen/arch/x86/hvm/hvm.c           |  10 +++
 xen/arch/x86/hvm/vmware/Makefile |   1 +
 xen/arch/x86/hvm/vmware/vmport.c | 142 +++++++++++++++++++++++++++++++++++++++
 xen/common/domctl.c              |   3 +
 xen/include/asm-x86/hvm/domain.h |   3 +
 xen/include/asm-x86/hvm/vmport.h |  32 +++++++++
 xen/include/public/domctl.h      |   3 +
 xen/include/xen/sched.h          |   3 +
 9 files changed, 199 insertions(+)
 create mode 100644 xen/arch/x86/hvm/vmware/vmport.c
 create mode 100644 xen/include/asm-x86/hvm/vmport.h

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index cfe7945..fe45f11 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -518,6 +518,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);
 
     INIT_LIST_HEAD(&d->arch.pdev_list);
 
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index fefd023..812f880 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -61,6 +61,7 @@
 #include <asm/hvm/trace.h>
 #include <asm/hvm/nestedhvm.h>
 #include <asm/hvm/vmware.h>
+#include <asm/hvm/vmport.h>
 #include <asm/mtrr.h>
 #include <asm/apic.h>
 #include <public/sched.h>
@@ -1484,6 +1485,9 @@ int hvm_domain_initialise(struct domain *d)
         goto fail1;
     d->arch.hvm_domain.io_handler->num_slot = 0;
 
+    if ( d->arch.hvm_domain.is_vmware_port_enabled )
+        vmport_register(d);
+
     if ( is_pvh_domain(d) )
     {
         register_portio_handler(d, 0, 0x10003, handle_pvh_io);
@@ -5859,6 +5863,12 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
                     break;
                 if ( a.value > 1 )
                     rc = -EINVAL;
+                /* Prevent nestedhvm with vmport */
+                if ( d->arch.hvm_domain.is_vmware_port_enabled )
+                {
+                    rc = -EINVAL;
+                    break;
+                }
                 /* Remove the check below once we have
                  * shadow-on-shadow.
                  */
diff --git a/xen/arch/x86/hvm/vmware/Makefile b/xen/arch/x86/hvm/vmware/Makefile
index 3fb2e0b..cd8815b 100644
--- a/xen/arch/x86/hvm/vmware/Makefile
+++ b/xen/arch/x86/hvm/vmware/Makefile
@@ -1 +1,2 @@
 obj-y += cpuid.o
+obj-y += vmport.o
diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
new file mode 100644
index 0000000..3d9f30e
--- /dev/null
+++ b/xen/arch/x86/hvm/vmware/vmport.c
@@ -0,0 +1,142 @@
+/*
+ * 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/lib.h>
+#include <asm/hvm/hvm.h>
+#include <asm/hvm/support.h>
+#include <asm/hvm/vmport.h>
+
+#include "backdoor_def.h"
+
+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();
+
+    /*
+     * While VMware expects only 32-bit in, they do support using
+     * other sizes and out.  However they do require only the 1 port
+     * and the correct value in eax.  Since some of the data
+     * returned in eax is smaller the 32 bits and/or you only need
+     * the other registers the dir and bytes do not need any
+     * checking.  The caller will handle the bytes, and dir is
+     * handled below.
+     */
+    if ( port == BDOOR_PORT && regs->_eax == BDOOR_MAGIC )
+    {
+        uint32_t new_eax = BDOOR_MAGIC;
+        uint64_t value;
+        struct vcpu *curr = current;
+        struct domain *d = curr->domain;
+
+        switch ( regs->_ecx & 0xffff )
+        {
+        case BDOOR_CMD_GETMHZ:
+            new_eax = d->arch.tsc_khz / 1000;
+            break;
+        case BDOOR_CMD_GETVERSION:
+            /* MAGIC */
+            regs->_ebx = BDOOR_MAGIC;
+            /* VERSION_MAGIC */
+            new_eax = 6;
+            /* Claim we are an ESX. VMX_TYPE_SCALABLE_SERVER */
+            regs->_ecx = 2;
+            break;
+        case BDOOR_CMD_GETSCREENSIZE:
+            /* We have no screen size */
+            new_eax = ~0u;
+            break;
+        case BDOOR_CMD_GETHWVERSION:
+            /* vmware_hw */
+            ASSERT(is_hvm_vcpu(curr));
+            {
+                struct hvm_domain *hd = &d->arch.hvm_domain;
+
+                new_eax = hd->params[HVM_PARAM_VMWARE_HWVER];
+            }
+            /*
+             * Returning zero is not the best.  VMware was not at
+             * all consistent in the handling of this command until
+             * VMware hardware version 4.  So it is better to claim
+             * 4 then 0.  This should only happen in strange configs.
+             */
+            if ( !new_eax )
+                new_eax = 4;
+            break;
+        case BDOOR_CMD_GETHZ:
+        {
+            struct segment_register sreg;
+
+            hvm_get_segment_register(curr, x86_seg_ss, &sreg);
+            if ( sreg.attr.fields.dpl == 0 )
+            {
+                value = d->arch.tsc_khz * 1000;
+                /* apic-frequency (bus speed) */
+                regs->_ecx = 1000000000ULL / APIC_BUS_CYCLE_NS;
+                /* High part of tsc-frequency */
+                regs->_ebx = value >> 32;
+                /* Low part of tsc-frequency */
+                new_eax = value;
+            }
+            break;
+        }
+        case BDOOR_CMD_GETTIME:
+            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
+            /* hostUsecs */
+            regs->_ebx = value % 1000000UL;
+            /* hostSecs */
+            new_eax = value / 1000000ULL;
+            /* maxTimeLag */
+            regs->_ecx = 1000000;
+            /* offset to GMT in minutes */
+            regs->_edx = d->time_offset_seconds / 60;
+            break;
+        case BDOOR_CMD_GETTIMEFULL:
+            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
+            /* hostUsecs */
+            regs->_ebx = value % 1000000UL;
+            /* hostSecs low 32 bits */
+            regs->_edx = value / 1000000ULL;
+            /* hostSecs high 32 bits */
+            regs->_esi = (value / 1000000ULL) >> 32;
+            /* maxTimeLag */
+            regs->_ecx = 1000000;
+            break;
+        default:
+            new_eax = ~0u;
+            break;
+        }
+        if ( dir == IOREQ_READ )
+            *val = new_eax;
+    }
+    else if ( dir == IOREQ_READ )
+        *val = ~0u;
+
+    return X86EMUL_OKAY;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 452f3d9..e242c2d 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -543,6 +543,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
              ~(XEN_DOMCTL_CDF_hvm_guest
                | XEN_DOMCTL_CDF_pvh_guest
                | XEN_DOMCTL_CDF_hap
+               | XEN_DOMCTL_CDF_vmware_port
                | XEN_DOMCTL_CDF_s3_integrity
                | XEN_DOMCTL_CDF_oos_off)) )
             break;
@@ -586,6 +587,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             domcr_flags |= DOMCRF_s3_integrity;
         if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off )
             domcr_flags |= DOMCRF_oos_off;
+        if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_vmware_port )
+            domcr_flags |= DOMCRF_vmware_port;
 
         d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
         if ( IS_ERR(d) )
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 0702bf5..ab0e4cf 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -122,6 +122,9 @@ struct hvm_domain {
     spinlock_t             uc_lock;
     bool_t                 is_in_uc_mode;
 
+    /* VMware backdoor port available */
+    bool_t                 is_vmware_port_enabled;
+
     /* Pass-through */
     struct hvm_iommu       hvm_iommu;
 
diff --git a/xen/include/asm-x86/hvm/vmport.h b/xen/include/asm-x86/hvm/vmport.h
new file mode 100644
index 0000000..eb3e472
--- /dev/null
+++ b/xen/include/asm-x86/hvm/vmport.h
@@ -0,0 +1,32 @@
+/*
+ * asm/hvm/vmport.h: 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/>.
+ */
+
+#ifndef ASM_X86_HVM_VMPORT_H__
+#define ASM_X86_HVM_VMPORT_H__
+
+void vmport_register(struct domain *d);
+int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val);
+
+#endif /* ASM_X86_HVM_VMPORT_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index b3413a2..28fa767 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -63,6 +63,9 @@ struct xen_domctl_createdomain {
  /* Is this a PVH guest (as opposed to an HVM or PV guest)? */
 #define _XEN_DOMCTL_CDF_pvh_guest     4
 #define XEN_DOMCTL_CDF_pvh_guest      (1U<<_XEN_DOMCTL_CDF_pvh_guest)
+ /* Is VMware backdoor port available? */
+#define _XEN_DOMCTL_CDF_vmware_port   5
+#define XEN_DOMCTL_CDF_vmware_port    (1U<<_XEN_DOMCTL_CDF_vmware_port)
     uint32_t flags;
 };
 typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index ccd7ed8..48bb001 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -546,6 +546,9 @@ struct domain *domain_create(
  /* DOMCRF_pvh: Create PV domain in HVM container. */
 #define _DOMCRF_pvh             5
 #define DOMCRF_pvh              (1U<<_DOMCRF_pvh)
+ /* DOMCRF_vmware_port: Enable use of vmware backdoor port. */
+#define _DOMCRF_vmware_port     6
+#define DOMCRF_vmware_port      (1U<<_DOMCRF_vmware_port)
 
 /*
  * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (4 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 05/13] xen: Add vmware_port support Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 14:38   ` Andrew Cooper
  2015-02-23 15:12   ` Jan Beulich
  2015-02-16 23:05 ` [PATCH v9 07/13] tools: Add " Don Slutz
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

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.

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.

The support included is enough to allow VMware tools to install in a
HVM domU.

Enable no-fault of pio in x86_emulate for VMware port

Also adjust the emulation registers after doing a VMware
backdoor operation.

Add new routine hvm_emulate_one_gp() to be used by the #GP fault
handler.

Some of the best info is at:

https://sites.google.com/site/chitchatvmback/backdoor

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
   Split #GP handling (or skipping of #GP) code out of previous
   patch to help with the review process.
   Switch to x86_emulator to handle #GP
   I think the hvm_emulate_ops_gp() covers all needed ops.  Not able to validate
   all paths though _hvm_emulate_one().

 xen/arch/x86/hvm/emulate.c             | 62 ++++++++++++++++++++++++++++++++--
 xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
 xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
 xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
 xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
 xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
 xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
 xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
 xen/include/asm-x86/hvm/emulate.h      |  2 ++
 xen/include/asm-x86/hvm/vmport.h       |  1 +
 10 files changed, 172 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 636c909..a6a6a5c 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -22,6 +22,7 @@
 #include <asm/hvm/trace.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/svm/svm.h>
+#include <asm/hvm/vmport.h>
 
 static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
 {
@@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
     unsigned long *val,
     struct x86_emulate_ctxt *ctxt)
 {
+    ctxt->do_vmport = 0;
     return X86EMUL_OKAY;
 }
 
@@ -785,6 +787,7 @@ static int hvmemul_write_io_discard(
     unsigned long val,
     struct x86_emulate_ctxt *ctxt)
 {
+    ctxt->do_vmport = 0;
     return X86EMUL_OKAY;
 }
 
@@ -802,6 +805,27 @@ static int hvmemul_wbinvd_discard(
     return X86EMUL_OKAY;
 }
 
+static int hvmemul_write_gp(
+    unsigned int seg,
+    unsigned long offset,
+    void *p_data,
+    unsigned int bytes,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_EXCEPTION;
+}
+
+static int hvmemul_cmpxchg_gp(
+    unsigned int seg,
+    unsigned long offset,
+    void *old,
+    void *new,
+    unsigned int bytes,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_EXCEPTION;
+}
+
 static int hvmemul_cmpxchg(
     enum x86_segment seg,
     unsigned long offset,
@@ -1355,6 +1379,17 @@ static int hvmemul_invlpg(
     return rc;
 }
 
+static int hvmemul_vmport_check(
+    unsigned int first_port,
+    struct x86_emulate_ctxt *ctxt)
+{
+    int rc = vmport_check_port(first_port);
+
+    if (rc)
+        ctxt->do_vmport = 1;
+    return rc;
+}
+
 static const struct x86_emulate_ops hvm_emulate_ops = {
     .read          = hvmemul_read,
     .insn_fetch    = hvmemul_insn_fetch,
@@ -1378,7 +1413,8 @@ static const struct x86_emulate_ops hvm_emulate_ops = {
     .inject_sw_interrupt = hvmemul_inject_sw_interrupt,
     .get_fpu       = hvmemul_get_fpu,
     .put_fpu       = hvmemul_put_fpu,
-    .invlpg        = hvmemul_invlpg
+    .invlpg        = hvmemul_invlpg,
+    .vmport_check  = hvmemul_vmport_check,
 };
 
 static const struct x86_emulate_ops hvm_emulate_ops_no_write = {
@@ -1404,7 +1440,22 @@ static const struct x86_emulate_ops hvm_emulate_ops_no_write = {
     .inject_sw_interrupt = hvmemul_inject_sw_interrupt,
     .get_fpu       = hvmemul_get_fpu,
     .put_fpu       = hvmemul_put_fpu,
-    .invlpg        = hvmemul_invlpg
+    .invlpg        = hvmemul_invlpg,
+    .vmport_check  = hvmemul_vmport_check,
+};
+
+static const struct x86_emulate_ops hvm_emulate_ops_gp = {
+    .read          = hvmemul_read,
+    .insn_fetch    = hvmemul_insn_fetch,
+    .write         = hvmemul_write_gp,
+    .cmpxchg       = hvmemul_cmpxchg_gp,
+    .read_segment  = hvmemul_read_segment,
+    .write_segment = hvmemul_write_segment,
+    .read_io       = hvmemul_read_io,
+    .write_io      = hvmemul_write_io,
+    .inject_hw_exception = hvmemul_inject_hw_exception,
+    .inject_sw_interrupt = hvmemul_inject_sw_interrupt,
+    .vmport_check  = hvmemul_vmport_check,
 };
 
 static int _hvm_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt,
@@ -1521,6 +1572,12 @@ int hvm_emulate_one(
     return _hvm_emulate_one(hvmemul_ctxt, &hvm_emulate_ops);
 }
 
+int hvm_emulate_one_gp(
+    struct hvm_emulate_ctxt *hvmemul_ctxt)
+{
+    return _hvm_emulate_one(hvmemul_ctxt, &hvm_emulate_ops_gp);
+}
+
 int hvm_emulate_one_no_write(
     struct hvm_emulate_ctxt *hvmemul_ctxt)
 {
@@ -1570,6 +1627,7 @@ void hvm_emulate_prepare(
     hvmemul_ctxt->intr_shadow = hvm_funcs.get_interrupt_shadow(current);
     hvmemul_ctxt->ctxt.regs = regs;
     hvmemul_ctxt->ctxt.force_writeback = 1;
+    hvmemul_ctxt->ctxt.do_vmport = 0;
     hvmemul_ctxt->seg_reg_accessed = 0;
     hvmemul_ctxt->seg_reg_dirty = 0;
     hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt);
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 4b7b818..5cb70ae 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -59,6 +59,7 @@
 #include <public/sched.h>
 #include <asm/hvm/vpt.h>
 #include <asm/hvm/trace.h>
+#include <asm/hvm/vmport.h>
 #include <asm/hap.h>
 #include <asm/apic.h>
 #include <asm/debugger.h>
@@ -2120,6 +2121,28 @@ svm_vmexit_do_vmsave(struct vmcb_struct *vmcb,
     return;
 }
 
+static void svm_vmexit_gp_intercept(struct cpu_user_regs *regs,
+                                    struct vcpu *v)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    int rc;
+
+    if ( vmcb->exitinfo1 != 0 || vmcb->exitinfo2 != 0 )
+        rc = X86EMUL_EXCEPTION;
+    else
+    {
+        struct hvm_emulate_ctxt ctxt;
+
+        hvm_emulate_prepare(&ctxt, regs);
+        rc = hvm_emulate_one_gp(&ctxt);
+
+        if ( rc == X86EMUL_OKAY )
+            hvm_emulate_writeback(&ctxt);
+    }
+    if ( rc != X86EMUL_OKAY && rc != X86EMUL_RETRY )
+        hvm_inject_hw_exception(TRAP_gp_fault, vmcb->exitinfo1);
+}
+
 static void svm_vmexit_ud_intercept(struct cpu_user_regs *regs)
 {
     struct hvm_emulate_ctxt ctxt;
@@ -2484,6 +2507,10 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
         break;
     }
 
+    case VMEXIT_EXCEPTION_GP:
+        svm_vmexit_gp_intercept(regs, v);
+        break;
+
     case VMEXIT_EXCEPTION_UD:
         svm_vmexit_ud_intercept(regs);
         break;
diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
index 21292bb..45ead61 100644
--- a/xen/arch/x86/hvm/svm/vmcb.c
+++ b/xen/arch/x86/hvm/svm/vmcb.c
@@ -195,6 +195,8 @@ static int construct_vmcb(struct vcpu *v)
         HVM_TRAP_MASK
         | (1U << TRAP_no_device);
 
+    if ( v->domain->arch.hvm_domain.is_vmware_port_enabled )
+        vmcb->_exception_intercepts |= 1U << TRAP_gp_fault;
     if ( paging_mode_hap(v->domain) )
     {
         vmcb->_np_enable = 1; /* enable nested paging */
diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
index 3d9f30e..2e61682 100644
--- a/xen/arch/x86/hvm/vmware/vmport.c
+++ b/xen/arch/x86/hvm/vmware/vmport.c
@@ -25,6 +25,17 @@ void vmport_register(struct domain *d)
     register_portio_handler(d, BDOOR_PORT, 4, vmport_ioport);
 }
 
+int vmport_check_port(unsigned int port)
+{
+    struct vcpu *curr = current;
+    struct domain *d = curr->domain;
+
+    if ( is_hvm_domain(d) && d->arch.hvm_domain.is_vmware_port_enabled &&
+         port == BDOOR_PORT )
+        return 1;
+    return 0;
+}
+
 int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
 {
     struct cpu_user_regs *regs = guest_cpu_user_regs();
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index d614638..4cc2c9e 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);
     vmx_update_exception_bitmap(v);
 
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index e1c55ce..34026eb 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -44,6 +44,7 @@
 #include <asm/hvm/support.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vmcs.h>
+#include <asm/hvm/vmport.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <asm/hvm/vpic.h>
@@ -1281,6 +1282,8 @@ static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr)
                 v->arch.hvm_vmx.exception_bitmap = HVM_TRAP_MASK
                           | (paging_mode_hap(v->domain) ?
                              0 : (1U << TRAP_page_fault))
+                          | (v->domain->arch.hvm_domain.is_vmware_port_enabled ?
+                             (1U << TRAP_gp_fault) : 0)
                           | (1U << TRAP_no_device);
                 vmx_update_exception_bitmap(v);
                 vmx_update_debug_state(v);
@@ -2632,6 +2635,38 @@ static void vmx_idtv_reinject(unsigned long idtv_info)
     }
 }
 
+static void vmx_vmexit_gp_intercept(struct cpu_user_regs *regs,
+                                    struct vcpu *v)
+{
+    unsigned long exit_qualification;
+    unsigned long ecode;
+    int rc;
+    unsigned long vector;
+
+    __vmread(VM_EXIT_INTR_INFO, &vector);
+    ASSERT(vector & INTR_INFO_VALID_MASK);
+    ASSERT(vector & INTR_INFO_DELIVER_CODE_MASK);
+
+    __vmread(EXIT_QUALIFICATION, &exit_qualification);
+    __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode);
+
+    if ( ecode != 0 || exit_qualification != 0 )
+        rc = X86EMUL_EXCEPTION;
+    else
+    {
+        struct hvm_emulate_ctxt ctxt;
+
+        hvm_emulate_prepare(&ctxt, regs);
+        rc = hvm_emulate_one_gp(&ctxt);
+
+        if ( rc == X86EMUL_OKAY )
+            hvm_emulate_writeback(&ctxt);
+    }
+
+    if ( rc != X86EMUL_OKAY && rc != X86EMUL_RETRY )
+        hvm_inject_hw_exception(TRAP_gp_fault, ecode);
+}
+
 static int vmx_handle_apic_write(void)
 {
     unsigned long exit_qualification;
@@ -2857,6 +2892,9 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
             HVMTRACE_1D(TRAP, vector);
             vmx_fpu_dirty_intercept();
             break;
+        case TRAP_gp_fault:
+            vmx_vmexit_gp_intercept(regs, v);
+            break;
         case TRAP_page_fault:
             __vmread(EXIT_QUALIFICATION, &exit_qualification);
             __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode);
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 42e2588..074b597 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -971,12 +971,20 @@ static int ioport_access_check(
     unsigned int first_port,
     unsigned int bytes,
     struct x86_emulate_ctxt *ctxt,
-    const struct x86_emulate_ops *ops)
+    const struct x86_emulate_ops *ops,
+    bool_t pio)
 {
     unsigned long iobmp;
     struct segment_register tr;
     int rc = X86EMUL_OKAY;
 
+    if ( pio )
+    {
+        fail_if(ops->vmport_check == NULL);
+        if ( ops->vmport_check(first_port, ctxt) )
+            return X86EMUL_OKAY;
+    }
+
     if ( !(ctxt->regs->eflags & EFLG_VM) && mode_iopl() )
         return X86EMUL_OKAY;
 
@@ -2250,7 +2258,7 @@ x86_emulate(
         dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
         dst.mem.seg = x86_seg_es;
         dst.mem.off = truncate_ea_and_reps(_regs.edi, nr_reps, dst.bytes);
-        if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops)) != 0 )
+        if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops, 0)) != 0 )
             goto done;
         if ( (nr_reps > 1) && (ops->rep_ins != NULL) &&
              ((rc = ops->rep_ins(port, dst.mem.seg, dst.mem.off, dst.bytes,
@@ -2279,7 +2287,7 @@ x86_emulate(
         unsigned int port = (uint16_t)_regs.edx;
         dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
         ea.mem.off = truncate_ea_and_reps(_regs.esi, nr_reps, dst.bytes);
-        if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops)) != 0 )
+        if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops, 0)) != 0 )
             goto done;
         if ( (nr_reps > 1) && (ops->rep_outs != NULL) &&
              ((rc = ops->rep_outs(ea.mem.seg, ea.mem.off, port, dst.bytes,
@@ -3393,7 +3401,7 @@ x86_emulate(
                              ? insn_fetch_type(uint8_t)
                              : (uint16_t)_regs.edx);
         op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
-        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
+        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops, 1)) != 0 )
             goto done;
         if ( b & 2 )
         {
@@ -3412,6 +3420,15 @@ x86_emulate(
         }
         if ( rc != 0 )
             goto done;
+	if ( ctxt->do_vmport )
+	{
+            ctxt->do_vmport = 0;
+            _regs._ebx = ctxt->regs->_ebx;
+            _regs._ecx = ctxt->regs->_ecx;
+            _regs._edx = ctxt->regs->_edx;
+            _regs._esi = ctxt->regs->_esi;
+            _regs._edi = ctxt->regs->_edi;
+	}
         break;
     }
 
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h
index 593b31e..e8e4413 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -393,6 +393,11 @@ struct x86_emulate_ops
         enum x86_segment seg,
         unsigned long offset,
         struct x86_emulate_ctxt *ctxt);
+
+    /* vmport_check */
+    int (*vmport_check)(
+        unsigned int port,
+        struct x86_emulate_ctxt *ctxt);
 };
 
 struct cpu_user_regs;
@@ -423,6 +428,9 @@ struct x86_emulate_ctxt
         } flags;
         uint8_t byte;
     } retire;
+
+    /* vmport support */
+    bool_t do_vmport;
 };
 
 /*
diff --git a/xen/include/asm-x86/hvm/emulate.h b/xen/include/asm-x86/hvm/emulate.h
index 5411302..a5e589b 100644
--- a/xen/include/asm-x86/hvm/emulate.h
+++ b/xen/include/asm-x86/hvm/emulate.h
@@ -36,6 +36,8 @@ struct hvm_emulate_ctxt {
 
 int hvm_emulate_one(
     struct hvm_emulate_ctxt *hvmemul_ctxt);
+int hvm_emulate_one_gp(
+    struct hvm_emulate_ctxt *hvmemul_ctxt);
 int hvm_emulate_one_no_write(
     struct hvm_emulate_ctxt *hvmemul_ctxt);
 void hvm_mem_event_emulate_one(bool_t nowrite,
diff --git a/xen/include/asm-x86/hvm/vmport.h b/xen/include/asm-x86/hvm/vmport.h
index eb3e472..e11ca1a 100644
--- a/xen/include/asm-x86/hvm/vmport.h
+++ b/xen/include/asm-x86/hvm/vmport.h
@@ -18,6 +18,7 @@
 #define ASM_X86_HVM_VMPORT_H__
 
 void vmport_register(struct domain *d);
+int vmport_check_port(unsigned int port);
 int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val);
 
 #endif /* ASM_X86_HVM_VMPORT_H__ */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 07/13] tools: Add vmware_port support
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (5 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 06/13] xen: Add ring 3 " Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-03-03 14:23   ` Ian Campbell
  2015-02-16 23:05 ` [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT Don Slutz
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

This new libxl_domain_create_info field is used to set
XEN_DOMCTL_CDF_vmware_port for the xc_domain_create() routine.

In xen it is is_vmware_port_enabled.

If is_vmware_port_enabled then
  enable a limited support of VMware's hyper-call.

VMware's hyper-call is also known as VMware Backdoor I/O Port.

if vmware_port is not specified in the config file, let
"vmware_hwver != 0" be the default value.  This means that only
vmware_hwver = 7 needs to be specified to enable both features.

Note: both vmware_port and nestedhvm cannot be specified at the
same time.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
  s/vmware_hw/vmware_hwver/i
  Added vmware_port and nestedhvm checking.

 docs/man/xl.cfg.pod.5        | 14 ++++++++++++++
 tools/libxl/libxl.h          |  5 +++++
 tools/libxl/libxl_create.c   | 16 ++++++++++++++--
 tools/libxl/libxl_dm.c       |  4 +++-
 tools/libxl/libxl_internal.h |  3 ++-
 tools/libxl/libxl_types.idl  |  1 +
 tools/libxl/xl_cmdimpl.c     |  1 +
 7 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 905ca8f..fb44e64 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -1288,6 +1288,20 @@ For vssd:VirtualSystemType == vmx-07, vmware_hwver = 7.
 
 =back
 
+=item B<vmware_port=BOOLEAN>
+
+Turns on or off the exposure of VMware port.  This is known as
+vmport in QEMU.  Also called VMware Backdoor I/O Port.  Not all
+defined VMware backdoor commands are implemented.  All of the
+ones that Linux kernel uses are defined.
+
+if vmware_port is not specified in the config file, let vmware_hwver != 0
+be the default value.  This means that only vmware_hwver = 7 needs to
+be specified to enable both features.
+
+Note: both vmware_port and nestedhvm cannot be specified at the
+same time.
+
 =back
 
 =head3 Emulated VGA Graphics Device
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 0c27e5c..792b569 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -173,6 +173,11 @@
 #define LIBXL_HAVE_BUILDINFO_HVM_VMWARE_HWVER 1
 
 /*
+ * libxl_domain_create_info has the vmware_port field.
+ */
+#define LIBXL_HAVE_CREATEINFO_VMWARE_PORT 1
+
+/*
  * libxl ABI compatibility
  *
  * The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 8c910c4..439164a 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -26,7 +26,8 @@
 #include <xen/hvm/e820.h>
 
 int libxl__domain_create_info_setdefault(libxl__gc *gc,
-                                         libxl_domain_create_info *c_info)
+                                         libxl_domain_create_info *c_info,
+                                         bool vmware_port_default)
 {
     if (!c_info->type)
         return ERROR_INVAL;
@@ -39,6 +40,7 @@ int libxl__domain_create_info_setdefault(libxl__gc *gc,
         libxl_defbool_setdefault(&c_info->hap, libxl_defbool_val(c_info->pvh));
     }
 
+    libxl_defbool_setdefault(&c_info->vmware_port, vmware_port_default);
     libxl_defbool_setdefault(&c_info->run_hotplug_scripts, true);
     libxl_defbool_setdefault(&c_info->driver_domain, false);
 
@@ -531,6 +533,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
         flags |= XEN_DOMCTL_CDF_hvm_guest;
         flags |= libxl_defbool_val(info->hap) ? XEN_DOMCTL_CDF_hap : 0;
         flags |= libxl_defbool_val(info->oos) ? 0 : XEN_DOMCTL_CDF_oos_off;
+        flags |= libxl_defbool_val(info->vmware_port)? XEN_DOMCTL_CDF_vmware_port : 0;
     } else if (libxl_defbool_val(info->pvh)) {
         flags |= XEN_DOMCTL_CDF_pvh_guest;
         if (!libxl_defbool_val(info->hap)) {
@@ -859,7 +862,9 @@ static void initiate_domain_create(libxl__egc *egc,
         goto error_out;
     }
 
-    ret = libxl__domain_create_info_setdefault(gc, &d_config->c_info);
+    ret = libxl__domain_create_info_setdefault(gc, &d_config->c_info,
+                       d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
+                       d_config->b_info.u.hvm.vmware_hwver);
     if (ret) goto error_out;
 
     ret = libxl__domain_make(gc, &d_config->c_info, &domid);
@@ -876,6 +881,13 @@ static void initiate_domain_create(libxl__egc *egc,
     ret = libxl__domain_build_info_setdefault(gc, &d_config->b_info);
     if (ret) goto error_out;
 
+    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
+        libxl_defbool_val(d_config->b_info.u.hvm.nested_hvm) &&
+        libxl_defbool_val(d_config->c_info.vmware_port)) {
+        LOG(ERROR, "Both vmware_port and nestedhvm can not be enabled\n");
+        ret = ERROR_INVAL;
+        goto error_out;
+    }
     if (!sched_params_valid(gc, domid, &d_config->b_info.sched_params)) {
         LOG(ERROR, "Invalid scheduling parameters\n");
         ret = ERROR_INVAL;
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index b05fa73..c27f9a4 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1061,7 +1061,9 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
     dm_config->c_info.run_hotplug_scripts =
         guest_config->c_info.run_hotplug_scripts;
 
-    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info);
+    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info,
+                       dm_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
+                       dm_config->b_info.u.hvm.vmware_hwver);
     if (ret) goto out;
     ret = libxl__domain_build_info_setdefault(gc, &dm_config->b_info);
     if (ret) goto out;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 934465a..680398c 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1071,7 +1071,8 @@ _hidden int libxl__init_console_from_channel(libxl__gc *gc,
  *     to be called before using any values within these structures.
  */
 _hidden int libxl__domain_create_info_setdefault(libxl__gc *gc,
-                                        libxl_domain_create_info *c_info);
+                                        libxl_domain_create_info *c_info,
+                                        bool vmware_port_default);
 _hidden int libxl__domain_build_info_setdefault(libxl__gc *gc,
                                         libxl_domain_build_info *b_info);
 _hidden int libxl__device_disk_setdefault(libxl__gc *gc,
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index ad596de..0d75673 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -329,6 +329,7 @@ libxl_domain_create_info = Struct("domain_create_info",[
     ("type",         libxl_domain_type),
     ("hap",          libxl_defbool),
     ("oos",          libxl_defbool),
+    ("vmware_port",  libxl_defbool),
     ("ssidref",      uint32),
     ("ssid_label",   string),
     ("name",         string),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index ca6d0ec..59b1811 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1047,6 +1047,7 @@ static void parse_config_data(const char *config_source,
     }
 
     xlu_cfg_get_defbool(config, "oos", &c_info->oos, 0);
+    xlu_cfg_get_defbool(config, "vmware_port", &c_info->vmware_port, 0);
 
     if (!xlu_cfg_get_string (config, "pool", &buf, 0))
         xlu_cfg_replace_string(config, "pool", &c_info->pool_name, 0);
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (6 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 07/13] tools: Add " Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 10:08   ` Paul Durrant
                     ` (2 more replies)
  2015-02-16 23:05 ` [PATCH v9 09/13] Add xentrace to vmware_port Don Slutz
                   ` (4 subsequent siblings)
  12 siblings, 3 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

This adds synchronization 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

In the tools, enable usage of QEMU's vmport code.

The currently most useful VMware port support that QEMU has is the
VMware mouse support.  Xorg included a VMware mouse support that
uses absolute mode.  This make using a mouse in X11 much nicer.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
  New code was presented as an RFC before this.

  Paul Durrant sugested I add support for other IOREQ types
  to HVMOP_map_io_range_to_ioreq_server.
    I have done this.

 tools/libxc/xc_hvm_build_x86.c         |   5 +-
 tools/libxl/libxl_dm.c                 |   4 +
 xen/arch/x86/hvm/emulate.c             |  48 ++++++++++
 xen/arch/x86/hvm/hvm.c                 | 159 ++++++++++++++++++++++++++++++---
 xen/arch/x86/hvm/io.c                  |  15 ++++
 xen/arch/x86/hvm/vmware/vmport.c       |   4 +-
 xen/arch/x86/x86_emulate/x86_emulate.h |   2 +
 xen/include/asm-x86/hvm/domain.h       |   3 +-
 xen/include/asm-x86/hvm/hvm.h          |   2 +
 xen/include/public/hvm/hvm_op.h        |   6 ++
 xen/include/public/hvm/ioreq.h         |  17 ++++
 xen/include/public/hvm/params.h        |   4 +-
 12 files changed, 251 insertions(+), 18 deletions(-)

diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
index c81a25b..e338667 100644
--- a/tools/libxc/xc_hvm_build_x86.c
+++ b/tools/libxc/xc_hvm_build_x86.c
@@ -46,7 +46,8 @@
 #define SPECIALPAGE_IOREQ    5
 #define SPECIALPAGE_IDENT_PT 6
 #define SPECIALPAGE_CONSOLE  7
-#define NR_SPECIAL_PAGES     8
+#define SPECIALPAGE_VMPORT_REGS 8
+#define NR_SPECIAL_PAGES     9
 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
 
 #define NR_IOREQ_SERVER_PAGES 8
@@ -493,6 +494,8 @@ static int setup_guest(xc_interface *xch,
                      special_pfn(SPECIALPAGE_BUFIOREQ));
     xc_hvm_param_set(xch, dom, HVM_PARAM_IOREQ_PFN,
                      special_pfn(SPECIALPAGE_IOREQ));
+    xc_hvm_param_set(xch, dom, HVM_PARAM_VMPORT_REGS_PFN,
+                     special_pfn(SPECIALPAGE_VMPORT_REGS));
     xc_hvm_param_set(xch, dom, HVM_PARAM_CONSOLE_PFN,
                      special_pfn(SPECIALPAGE_CONSOLE));
     xc_hvm_param_set(xch, dom, HVM_PARAM_PAGING_RING_PFN,
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index c27f9a4..620013c 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -765,6 +765,10 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
                                             machinearg, max_ram_below_4g);
             }
         }
+        if (libxl_defbool_val(c_info->vmware_port)) {
+            machinearg = libxl__sprintf(gc, "%s,vmport=on",
+                                        machinearg);
+        }
         flexarray_append(dm_args, machinearg);
         for (i = 0; b_info->extra_hvm && b_info->extra_hvm[i] != NULL; i++)
             flexarray_append(dm_args, b_info->extra_hvm[i]);
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index a6a6a5c..799894b 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -240,6 +240,48 @@ static int hvmemul_do_io(
         }
         break;
     }
+    case X86EMUL_VMPORT_SEND:
+    {
+        struct hvm_ioreq_server *s;
+        vmware_regs_t *vr;
+
+        BUILD_BUG_ON(sizeof(ioreq_t) < sizeof(vmware_regs_t));
+
+        p.type = IOREQ_TYPE_VMWARE_PORT;
+        s = hvm_select_ioreq_server(curr->domain, &p);
+        vr = get_vmport_regs_any(s, curr);
+
+        /*
+         * If there is no suitable backing DM, just ignore accesses.  If
+         * we do not have access to registers to pass to QEMU, just
+         * ignore access.
+         */
+        if ( !s || !vr )
+        {
+            hvm_complete_assist_req(&p);
+            rc = X86EMUL_OKAY;
+            vio->io_state = HVMIO_none;
+        }
+        else
+        {
+            struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+            p.data = regs->rax;
+            vr->ebx = regs->_ebx;
+            vr->ecx = regs->_ecx;
+            vr->edx = regs->_edx;
+            vr->esi = regs->_esi;
+            vr->edi = regs->_edi;
+
+            vio->io_state = HVMIO_handle_pio_awaiting_completion;
+            if ( !hvm_send_assist_req(s, &p) )
+            {
+                rc = X86EMUL_RETRY;
+                vio->io_state = HVMIO_none;
+            }
+        }
+        break;
+    }
     default:
         BUG();
     }
@@ -248,6 +290,12 @@ static int hvmemul_do_io(
     {
         if ( ram_page )
             put_page(ram_page);
+        /*
+         * If X86EMUL_VMPORT_SEND, completion in hvm_io_assist()
+         * with no re-emulation required
+         */
+        if ( rc == X86EMUL_VMPORT_SEND )
+            rc = X86EMUL_OKAY;
         return rc;
     }
 
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 812f880..5b11091 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -392,6 +392,47 @@ static ioreq_t *get_ioreq(struct hvm_ioreq_server *s, struct vcpu *v)
     return &p->vcpu_ioreq[v->vcpu_id];
 }
 
+static vmware_regs_t *get_vmport_regs_one(struct hvm_ioreq_server *s,
+                                          struct vcpu *v)
+{
+    struct hvm_ioreq_vcpu *sv;
+
+    list_for_each_entry ( sv,
+                          &s->ioreq_vcpu_list,
+                          list_entry )
+    {
+        if ( sv->vcpu == v )
+        {
+            shared_vmport_iopage_t *p = s->vmport_ioreq.va;
+            if ( !p )
+                return NULL;
+            return &p->vcpu_vmport_regs[v->vcpu_id];
+        }
+    }
+    return NULL;
+}
+
+vmware_regs_t *get_vmport_regs_any(struct hvm_ioreq_server *s, struct vcpu *v)
+{
+    struct domain *d = v->domain;
+
+    ASSERT((v == current) || !vcpu_runnable(v));
+
+    if ( s )
+        return get_vmport_regs_one(s, v);
+
+    list_for_each_entry ( s,
+                          &d->arch.hvm_domain.ioreq_server.list,
+                          list_entry )
+    {
+        vmware_regs_t *ret = get_vmport_regs_one(s, v);
+
+        if ( ret )
+            return ret;
+    }
+    return NULL;
+}
+
 bool_t hvm_io_pending(struct vcpu *v)
 {
     struct domain *d = v->domain;
@@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)
     clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
 }
 
-static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
+static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int buf)
 {
-    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+    struct hvm_ioreq_page *iorp = NULL;
+
+    switch ( buf )
+    {
+    case 0:
+        iorp = &s->ioreq;
+        break;
+    case 1:
+        iorp = &s->bufioreq;
+        break;
+    case 2:
+        iorp = &s->vmport_ioreq;
+        break;
+    }
+    ASSERT(iorp);
 
     destroy_ring_for_helper(&iorp->va, iorp->page);
 }
 
 static int hvm_map_ioreq_page(
-    struct hvm_ioreq_server *s, bool_t buf, unsigned long gmfn)
+    struct hvm_ioreq_server *s, int buf, unsigned long gmfn)
 {
     struct domain *d = s->domain;
-    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+    struct hvm_ioreq_page *iorp = NULL;
     struct page_info *page;
     void *va;
     int rc;
 
+    switch ( buf )
+    {
+    case 0:
+        iorp = &s->ioreq;
+        break;
+    case 1:
+        iorp = &s->bufioreq;
+        break;
+    case 2:
+        iorp = &s->vmport_ioreq;
+        break;
+    }
+    ASSERT(iorp);
+
     if ( (rc = prepare_ring_for_helper(d, gmfn, &page, &va)) )
         return rc;
 
@@ -736,6 +805,7 @@ static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
 {
     struct domain *d = s->domain;
     unsigned long ioreq_pfn, bufioreq_pfn;
+    unsigned long vmport_ioreq_pfn = d->arch.hvm_domain.params[HVM_PARAM_VMPORT_REGS_PFN];
     int rc;
 
     if ( is_default )
@@ -774,8 +844,16 @@ static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
             goto fail4;
     }
 
+    rc = hvm_map_ioreq_page(s, 2, vmport_ioreq_pfn);
+    if ( rc )
+        goto fail5;
+
     return 0;
 
+fail5:
+    if ( handle_bufioreq )
+        hvm_unmap_ioreq_page(s, 1);
+
 fail4:
     hvm_unmap_ioreq_page(s, 0);
 
@@ -796,6 +874,10 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
 {
     struct domain *d = s->domain;
     bool_t handle_bufioreq = ( s->bufioreq.va != NULL );
+    bool_t handle_vmport_ioreq = ( s->vmport_ioreq.va != NULL );
+
+    if ( handle_vmport_ioreq )
+        hvm_unmap_ioreq_page(s, 2);
 
     if ( handle_bufioreq )
         hvm_unmap_ioreq_page(s, 1);
@@ -835,12 +917,42 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
     for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
     {
         char *name;
+        char *type_name = NULL;
+        unsigned int limit;
 
-        rc = asprintf(&name, "ioreq_server %d %s", s->id,
-                      (i == HVMOP_IO_RANGE_PORT) ? "port" :
-                      (i == HVMOP_IO_RANGE_MEMORY) ? "memory" :
-                      (i == HVMOP_IO_RANGE_PCI) ? "pci" :
-                      "");
+        switch ( i )
+        {
+        case HVMOP_IO_RANGE_PORT:
+            type_name = "port";
+            limit = MAX_NR_IO_RANGES;
+            break;
+        case HVMOP_IO_RANGE_MEMORY:
+            type_name = "memory";
+            limit = MAX_NR_IO_RANGES;
+            break;
+        case HVMOP_IO_RANGE_PCI:
+            type_name = "pci";
+            limit = MAX_NR_IO_RANGES;
+            break;
+        case HVMOP_IO_RANGE_VMWARE_PORT:
+            type_name = "VMware port";
+            limit = 1;
+            break;
+        case HVMOP_IO_RANGE_TIMEOFFSET:
+            type_name = "timeoffset";
+            limit = 1;
+            break;
+        case HVMOP_IO_RANGE_INVALIDATE:
+            type_name = "invalidate";
+            limit = 1;
+            break;
+        default:
+            break;
+        }
+        if ( !type_name )
+            continue;
+
+        rc = asprintf(&name, "ioreq_server %d %s", s->id, type_name);
         if ( rc )
             goto fail;
 
@@ -853,7 +965,12 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
         if ( !s->range[i] )
             goto fail;
 
-        rangeset_limit(s->range[i], MAX_NR_IO_RANGES);
+        rangeset_limit(s->range[i], limit);
+
+        /* VMware port */
+        if ( i == HVMOP_IO_RANGE_VMWARE_PORT &&
+            s->domain->arch.hvm_domain.is_vmware_port_enabled )
+            rc = rangeset_add_range(s->range[i], 1, 1);
     }
 
  done:
@@ -1155,6 +1272,9 @@ static int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
             case HVMOP_IO_RANGE_PORT:
             case HVMOP_IO_RANGE_MEMORY:
             case HVMOP_IO_RANGE_PCI:
+            case HVMOP_IO_RANGE_VMWARE_PORT:
+            case HVMOP_IO_RANGE_TIMEOFFSET:
+            case HVMOP_IO_RANGE_INVALIDATE:
                 r = s->range[type];
                 break;
 
@@ -1206,6 +1326,9 @@ static int hvm_unmap_io_range_from_ioreq_server(struct domain *d, ioservid_t id,
             case HVMOP_IO_RANGE_PORT:
             case HVMOP_IO_RANGE_MEMORY:
             case HVMOP_IO_RANGE_PCI:
+            case HVMOP_IO_RANGE_VMWARE_PORT:
+            case HVMOP_IO_RANGE_TIMEOFFSET:
+            case HVMOP_IO_RANGE_INVALIDATE:
                 r = s->range[type];
                 break;
 
@@ -2429,9 +2552,6 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
     if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
         return NULL;
 
-    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
-        return d->arch.hvm_domain.default_ioreq_server;
-
     cf8 = d->arch.hvm_domain.pci_cf8;
 
     if ( p->type == IOREQ_TYPE_PIO &&
@@ -2474,7 +2594,12 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
         BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
         BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
         BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
+        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
+        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
+        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE != HVMOP_IO_RANGE_INVALIDATE);
         r = s->range[type];
+        if ( !r )
+            continue;
 
         switch ( type )
         {
@@ -2501,6 +2626,13 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
             }
 
             break;
+        case IOREQ_TYPE_VMWARE_PORT:
+        case IOREQ_TYPE_TIMEOFFSET:
+        case IOREQ_TYPE_INVALIDATE:
+            if ( rangeset_contains_singleton(r, 1) )
+                return s;
+
+            break;
         }
     }
 
@@ -2662,6 +2794,7 @@ void hvm_complete_assist_req(ioreq_t *p)
     case IOREQ_TYPE_PCI_CONFIG:
         ASSERT_UNREACHABLE();
         break;
+    case IOREQ_TYPE_VMWARE_PORT:
     case IOREQ_TYPE_COPY:
     case IOREQ_TYPE_PIO:
         if ( p->dir == IOREQ_READ )
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 68fb890..2d06956 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -192,6 +192,21 @@ void hvm_io_assist(ioreq_t *p)
         (void)handle_mmio();
         break;
     case HVMIO_handle_pio_awaiting_completion:
+        if ( p->type == IOREQ_TYPE_VMWARE_PORT )
+        {
+            struct cpu_user_regs *regs = guest_cpu_user_regs();
+            vmware_regs_t *vr = get_vmport_regs_any(NULL, curr);
+
+            if ( vr )
+            {
+                /* Only change the 32bit part of the register */
+                regs->_ebx = vr->ebx;
+                regs->_ecx = vr->ecx;
+                regs->_edx = vr->edx;
+                regs->_esi = vr->esi;
+                regs->_edi = vr->edi;
+            }
+        }
         if ( vio->io_size == 4 ) /* Needs zero extension. */
             guest_cpu_user_regs()->rax = (uint32_t)p->data;
         else
diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
index 2e61682..131bafd 100644
--- a/xen/arch/x86/hvm/vmware/vmport.c
+++ b/xen/arch/x86/hvm/vmware/vmport.c
@@ -130,8 +130,8 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
             regs->_ecx = 1000000;
             break;
         default:
-            new_eax = ~0u;
-            break;
+            /* Let backing DM handle */
+            return X86EMUL_VMPORT_SEND;
         }
         if ( dir == IOREQ_READ )
             *val = new_eax;
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h
index e8e4413..6bf0176 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -112,6 +112,8 @@ struct __packed segment_register {
 #define X86EMUL_RETRY          3
  /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
 #define X86EMUL_CMPXCHG_FAILED 3
+ /* Send part of registers also to DM. */
+#define X86EMUL_VMPORT_SEND    4
 
 /* FPU sub-types which may be requested via ->get_fpu(). */
 enum x86_emulate_fpu_type {
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index ab0e4cf..ad6ec79 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -48,7 +48,7 @@ struct hvm_ioreq_vcpu {
     evtchn_port_t    ioreq_evtchn;
 };
 
-#define NR_IO_RANGE_TYPES (HVMOP_IO_RANGE_PCI + 1)
+#define NR_IO_RANGE_TYPES (HVMOP_IO_RANGE_INVALIDATE + 1)
 #define MAX_NR_IO_RANGES  256
 
 struct hvm_ioreq_server {
@@ -63,6 +63,7 @@ struct hvm_ioreq_server {
     ioservid_t             id;
     struct hvm_ioreq_page  ioreq;
     struct list_head       ioreq_vcpu_list;
+    struct hvm_ioreq_page  vmport_ioreq;
     struct hvm_ioreq_page  bufioreq;
 
     /* Lock to serialize access to buffered ioreq ring */
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 8ecde89..82fe62a 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -534,6 +534,8 @@ extern bool_t opt_hvm_fep;
 #define opt_hvm_fep 0
 #endif
 
+vmware_regs_t *get_vmport_regs_any(struct hvm_ioreq_server *s, struct vcpu *v);
+
 #endif /* __ASM_X86_HVM_HVM_H__ */
 
 /*
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index cde3571..19f8c69 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -314,6 +314,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
  *
  * NOTE: unless an emulation request falls entirely within a range mapped
  * by a secondary emulator, it will not be passed to that emulator.
+ *
+ * NOTE: The 'special' range of 1 is what is checked for outside
+ * of the three types of I/O.
  */
 #define HVMOP_map_io_range_to_ioreq_server 19
 #define HVMOP_unmap_io_range_from_ioreq_server 20
@@ -324,6 +327,9 @@ struct xen_hvm_io_range {
 # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
 # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
 # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
+# define HVMOP_IO_RANGE_VMWARE_PORT 3 /* VMware port special range */
+# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range */
+# define HVMOP_IO_RANGE_INVALIDATE 8 /* INVALIDATE special range */
     uint64_aligned_t start, end; /* IN - inclusive start and end of range */
 };
 typedef struct xen_hvm_io_range xen_hvm_io_range_t;
diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h
index 5b5fedf..6d5ca06 100644
--- a/xen/include/public/hvm/ioreq.h
+++ b/xen/include/public/hvm/ioreq.h
@@ -35,6 +35,7 @@
 #define IOREQ_TYPE_PIO          0 /* pio */
 #define IOREQ_TYPE_COPY         1 /* mmio ops */
 #define IOREQ_TYPE_PCI_CONFIG   2
+#define IOREQ_TYPE_VMWARE_PORT  3
 #define IOREQ_TYPE_TIMEOFFSET   7
 #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
 
@@ -48,6 +49,8 @@
  * 
  * 63....48|47..40|39..35|34..32|31........0
  * SEGMENT |BUS   |DEV   |FN    |OFFSET
+ *
+ * For I/O type IOREQ_TYPE_VMWARE_PORT also use the vmware_regs.
  */
 struct ioreq {
     uint64_t addr;          /* physical address */
@@ -66,11 +69,25 @@ struct ioreq {
 };
 typedef struct ioreq ioreq_t;
 
+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_iopage {
     struct ioreq vcpu_ioreq[1];
 };
 typedef struct shared_iopage shared_iopage_t;
 
+struct shared_vmport_iopage {
+    struct vmware_regs vcpu_vmport_regs[1];
+};
+typedef struct shared_vmport_iopage shared_vmport_iopage_t;
+
 struct buf_ioreq {
     uint8_t  type;   /* I/O type                    */
     uint8_t  pad:1;
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 974d3a4..2f6ccf4 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -50,6 +50,8 @@
 #define HVM_PARAM_PAE_ENABLED  4
 
 #define HVM_PARAM_IOREQ_PFN    5
+/* Extra vmport PFN. */
+#define HVM_PARAM_VMPORT_REGS_PFN 36
 
 #define HVM_PARAM_BUFIOREQ_PFN 6
 #define HVM_PARAM_BUFIOREQ_EVTCHN 26
@@ -197,6 +199,6 @@
 /* emulated VMware Hardware Version */
 #define HVM_PARAM_VMWARE_HWVER 35
 
-#define HVM_NR_PARAMS          36
+#define HVM_NR_PARAMS          37
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (7 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 13:45   ` Andrew Cooper
                     ` (2 more replies)
  2015-02-16 23:05 ` [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t Don Slutz
                   ` (3 subsequent siblings)
  12 siblings, 3 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

Also added missing TRAP_DEBUG & VLAPIC.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
  Dropped unneed VMPORT_UNHANDLED, VMPORT_DECODE.

v7:
      Dropped some of the new traces.
      Added HVMTRACE_ND7.

v6:
      Dropped the attempt to use svm_nextrip_insn_length via
      __get_instruction_length (added in v2).  Just always look
      at upto 15 bytes on AMD.

v5:
      exitinfo1 is used twice.
        Fixed.

 tools/xentrace/formats           |  5 +++++
 xen/arch/x86/hvm/vmware/vmport.c |  4 +++-
 xen/include/asm-x86/hvm/trace.h  | 22 ++++++++++++++++++++++
 xen/include/public/trace.h       |  3 +++
 4 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/tools/xentrace/formats b/tools/xentrace/formats
index 5d7b72a..eec65f4 100644
--- a/tools/xentrace/formats
+++ b/tools/xentrace/formats
@@ -79,6 +79,11 @@
 0x00082020  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INTR_WINDOW [ value = 0x%(1)08x ]
 0x00082021  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  NPF         [ gpa = 0x%(2)08x%(1)08x mfn = 0x%(4)08x%(3)08x qual = 0x%(5)04x p2mt = 0x%(6)04x ]
 0x00082023  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  TRAP        [ vector = 0x%(1)02x ]
+0x00082024  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  TRAP_DEBUG  [ exit_qualification = 0x%(1)08x ]
+0x00082025  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VLAPIC
+0x00082026  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_HANDLED   [ cmd = %(1)d eax = 0x%(2)08x ebx = 0x%(3)08x ecx = 0x%(4)08x edx = 0x%(5)08x esi = 0x%(6)08x edi = 0x%(7)08x ]
+0x00082027  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_IGNORED   [ port = %(1)d eax = 0x%(2)08x ebx = 0x%(3)08x ecx = 0x%(4)08x edx = 0x%(5)08x esi = 0x%(6)08x edi = 0x%(7)08x ]
+0x00082028  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_QEMU      [ eax = 0x%(1)08x ebx = 0x%(2)08x ecx = 0x%(3)08x edx = 0x%(4)08x esi = 0x%(5)08x edi = 0x%(6)08x ]
 
 0x0010f001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_map      [ domid = %(1)d ]
 0x0010f002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_unmap    [ domid = %(1)d ]
diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
index 131bafd..fb191a2 100644
--- a/xen/arch/x86/hvm/vmware/vmport.c
+++ b/xen/arch/x86/hvm/vmware/vmport.c
@@ -17,6 +17,7 @@
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/vmport.h>
+#include <asm/hvm/trace.h>
 
 #include "backdoor_def.h"
 
@@ -55,8 +56,9 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
         uint64_t value;
         struct vcpu *curr = current;
         struct domain *d = curr->domain;
+        uint16_t cmd = regs->_ecx;
 
-        switch ( regs->_ecx & 0xffff )
+        switch ( cmd )
         {
         case BDOOR_CMD_GETMHZ:
             new_eax = d->arch.tsc_khz / 1000;
diff --git a/xen/include/asm-x86/hvm/trace.h b/xen/include/asm-x86/hvm/trace.h
index de802a6..0ad805f 100644
--- a/xen/include/asm-x86/hvm/trace.h
+++ b/xen/include/asm-x86/hvm/trace.h
@@ -54,6 +54,9 @@
 #define DO_TRC_HVM_TRAP             DEFAULT_HVM_MISC
 #define DO_TRC_HVM_TRAP_DEBUG       DEFAULT_HVM_MISC
 #define DO_TRC_HVM_VLAPIC           DEFAULT_HVM_MISC
+#define DO_TRC_HVM_VMPORT_HANDLED   DEFAULT_HVM_IO
+#define DO_TRC_HVM_VMPORT_IGNORED   DEFAULT_HVM_IO
+#define DO_TRC_HVM_VMPORT_QEMU      DEFAULT_HVM_IO
 
 
 #define TRC_PAR_LONG(par) ((par)&0xFFFFFFFF),((par)>>32)
@@ -83,6 +86,25 @@
         }                                                                 \
     } while(0)
 
+#define HVMTRACE_ND7(evt, modifier, cycles, count, d1, d2, d3, d4, d5, d6, d7) \
+    do {                                                                  \
+        if ( unlikely(tb_init_done) && DO_TRC_HVM_ ## evt )               \
+        {                                                                 \
+            struct {                                                      \
+                u32 d[7];                                                 \
+            } _d;                                                         \
+            _d.d[0]=(d1);                                                 \
+            _d.d[1]=(d2);                                                 \
+            _d.d[2]=(d3);                                                 \
+            _d.d[3]=(d4);                                                 \
+            _d.d[4]=(d5);                                                 \
+            _d.d[5]=(d6);                                                 \
+            _d.d[6]=(d7);                                                 \
+            __trace_var(TRC_HVM_ ## evt | (modifier), cycles,             \
+                        sizeof(*_d.d) * count, &_d);                      \
+        }                                                                 \
+    } while(0)
+
 #define HVMTRACE_6D(evt, d1, d2, d3, d4, d5, d6)    \
     HVMTRACE_ND(evt, 0, 0, 6, d1, d2, d3, d4, d5, d6)
 #define HVMTRACE_5D(evt, d1, d2, d3, d4, d5)        \
diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h
index 5211ae7..16b87f9 100644
--- a/xen/include/public/trace.h
+++ b/xen/include/public/trace.h
@@ -227,6 +227,9 @@
 #define TRC_HVM_TRAP             (TRC_HVM_HANDLER + 0x23)
 #define TRC_HVM_TRAP_DEBUG       (TRC_HVM_HANDLER + 0x24)
 #define TRC_HVM_VLAPIC           (TRC_HVM_HANDLER + 0x25)
+#define TRC_HVM_VMPORT_HANDLED   (TRC_HVM_HANDLER + 0x26)
+#define TRC_HVM_VMPORT_IGNORED   (TRC_HVM_HANDLER + 0x27)
+#define TRC_HVM_VMPORT_QEMU      (TRC_HVM_HANDLER + 0x28)
 
 #define TRC_HVM_IOPORT_WRITE    (TRC_HVM_HANDLER + 0x216)
 #define TRC_HVM_IOMEM_WRITE     (TRC_HVM_HANDLER + 0x217)
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (8 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 09/13] Add xentrace to vmware_port Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 14:44   ` Andrew Cooper
  2015-02-16 23:05 ` [PATCH v9 11/13] test_x86_emulator.c: Add emacs block Don Slutz
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

This is needed by me to build this test

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
 tools/tests/x86_emulator/test_x86_emulator.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
index 6f67fc7..03cd0e8 100644
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -9,6 +9,8 @@
 
 #define __packed __attribute__((packed))
 
+typedef bool bool_t;
+
 #include "x86_emulate/x86_emulate.h"
 #include "blowfish.h"
 
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 11/13] test_x86_emulator.c: Add emacs block
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (9 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 14:52   ` Andrew Cooper
  2015-02-16 23:05 ` [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage Don Slutz
  2015-02-16 23:05 ` [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param Don Slutz
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
 tools/tests/x86_emulator/test_x86_emulator.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
index 03cd0e8..02a9f0a 100644
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -936,3 +936,12 @@ int main(int argc, char **argv)
     printf("failed!\n");
     return 1;
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (10 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 11/13] test_x86_emulator.c: Add emacs block Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-24 15:38   ` Jan Beulich
  2015-02-16 23:05 ` [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param Don Slutz
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
 tools/tests/x86_emulator/test_x86_emulator.c | 155 +++++++++++++++++++++++++++
 1 file changed, 155 insertions(+)

diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
index 02a9f0a..985c80e 100644
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -61,6 +61,16 @@ static int write(
     return X86EMUL_OKAY;
 }
 
+static int write_gp(
+    unsigned int seg,
+    unsigned long offset,
+    void *p_data,
+    unsigned int bytes,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_EXCEPTION;
+}
+
 static int cmpxchg(
     unsigned int seg,
     unsigned long offset,
@@ -73,6 +83,17 @@ static int cmpxchg(
     return X86EMUL_OKAY;
 }
 
+static int cmpxchg_gp(
+    unsigned int seg,
+    unsigned long offset,
+    void *old,
+    void *new,
+    unsigned int bytes,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_EXCEPTION;
+}
+
 static int cpuid(
     unsigned int *eax,
     unsigned int *ebx,
@@ -156,6 +177,51 @@ int get_fpu(
     return X86EMUL_OKAY;
 }
 
+static int read_io(
+    unsigned int port,
+    unsigned int bytes,
+    unsigned long *val,
+    struct x86_emulate_ctxt *ctxt)
+{
+    *val = 0xffffffff;
+    return X86EMUL_OKAY;
+}
+
+static int write_io(
+    unsigned int port,
+    unsigned int bytes,
+    unsigned long val,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_OKAY;
+}
+
+static int vmport_check(
+	unsigned int first_port,
+	struct x86_emulate_ctxt *ctxt)
+{
+    if ( first_port == 0x5658 )
+        return 1;
+    else
+        return 0;
+}
+
+static int read_segment(
+    enum x86_segment seg,
+    struct segment_register *reg,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_EXCEPTION;
+}
+
+static int inject_hw_exception(
+    uint8_t vector,
+    int32_t error_code,
+    struct x86_emulate_ctxt *ctxt)
+{
+    return X86EMUL_EXCEPTION;
+}
+
 static struct x86_emulate_ops emulops = {
     .read       = read,
     .insn_fetch = fetch,
@@ -165,6 +231,18 @@ static struct x86_emulate_ops emulops = {
     .get_fpu    = get_fpu,
 };
 
+static struct x86_emulate_ops emulops_gp = {
+    .read       = read,
+    .insn_fetch = fetch,
+    .write      = write_gp,
+    .cmpxchg    = cmpxchg_gp,
+    .read_io    = read_io,
+    .write_io   = write_io,
+    .read_segment = read_segment,
+    .inject_hw_exception = inject_hw_exception,
+    .vmport_check = vmport_check,
+};
+
 int main(int argc, char **argv)
 {
     struct x86_emulate_ctxt ctxt;
@@ -930,6 +1008,83 @@ int main(int argc, char **argv)
         goto fail;
     printf("okay\n");
 
+    for ( j = 0; j <= 1; j++ )
+    {
+        regs.eflags = 0x20002;
+        regs.edx    = 0x5658 + j;
+        printf("Testing %s dx=%x ...       ", "in (%dx),%eax", (int)regs.edx);
+        instr[0] = 0xed; /* in (%dx),%eax or in (%dx),%ax */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        if ( j == 0 && regs.eax == 0x12345678 )
+            goto fail;
+        printf("okay\n");
+
+        printf("Testing %s  dx=%x ...       ", "in (%dx),%al", (int)regs.edx);
+        instr[0] = 0xec; /* in (%dx),%al */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        if ( j == 0 && regs.eax == 0x12345678 )
+            goto fail;
+        printf("okay\n");
+
+        printf("Testing %s dx=%x ...      ", "out %eax,(%dx)", (int)regs.edx);
+        instr[0] = 0xef; /* out %eax,(%dx) or out %ax,(%dx) */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        if ( regs.eax != 0x12345678 )
+            goto fail;
+        printf("okay\n");
+
+        printf("Testing %s  dx=%x ...      ", "out %al,(%dx)", (int)regs.edx);
+        instr[0] = 0xee; /* out %al,(%dx) */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        if ( regs.eax != 0x12345678 )
+            goto fail;
+        printf("okay\n");
+    }
+
     return 0;
 
  fail:
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param
  2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
                   ` (11 preceding siblings ...)
  2015-02-16 23:05 ` [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage Don Slutz
@ 2015-02-16 23:05 ` Don Slutz
  2015-02-17 14:11   ` Andrew Cooper
  12 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-16 23:05 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Don Slutz, Tim Deegan,
	George Dunlap, Aravind Gopalakrishnan, Jan Beulich,
	Andrew Cooper, Boris Ostrovsky, Suravee Suthikulpanit

A tool to get and set hvm param.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
v9:
   Change to output number as weel as string.
   Made all string only lower case.
   Rebase changes.

v7:
       Was a later patch.  Still optional.
       Fixed formatting.
       Adjust for drop of VMware RPC.

 .gitignore                 |   1 +
 tools/misc/Makefile        |   4 +
 tools/misc/xen-hvm-param.c | 186 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 191 insertions(+)
 create mode 100644 tools/misc/xen-hvm-param.c

diff --git a/.gitignore b/.gitignore
index 692e24c..fe01ba3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -171,6 +171,7 @@ tools/misc/xen-tmem-list-parse
 tools/misc/xenperf
 tools/misc/xenpm
 tools/misc/xen-hvmctx
+tools/misc/xen-hvm-param
 tools/misc/gtraceview
 tools/misc/gtracestat
 tools/misc/xenlockprof
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index ccd36af..6b5b8a7 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -19,6 +19,7 @@ INSTALL_SBIN                   += xen-bugtool
 INSTALL_SBIN-$(CONFIG_MIGRATE) += xen-hptool
 INSTALL_SBIN-$(CONFIG_X86)     += xen-hvmcrash
 INSTALL_SBIN-$(CONFIG_X86)     += xen-hvmctx
+INSTALL_SBIN-$(CONFIG_X86)     += xen-hvm-param
 INSTALL_SBIN-$(CONFIG_X86)     += xen-lowmemd
 INSTALL_SBIN-$(CONFIG_X86)     += xen-mfndump
 INSTALL_SBIN                   += xen-ringwatch
@@ -68,6 +69,9 @@ distclean: clean
 xen-hvmctx: xen-hvmctx.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
+xen-hvm-param: xen-hvm-param.o
+	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+
 xen-hvmcrash: xen-hvmcrash.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
diff --git a/tools/misc/xen-hvm-param.c b/tools/misc/xen-hvm-param.c
new file mode 100644
index 0000000..007d00f
--- /dev/null
+++ b/tools/misc/xen-hvm-param.c
@@ -0,0 +1,186 @@
+/*
+ * tools/misc/xen-hvm-param.c
+ *
+ * Copyright (C) 2014 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 <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+
+#include <xenctrl.h>
+
+
+int
+main(int argc, char **argv)
+{
+    xc_interface *xch;
+    int domid;
+    int start_param = 0;
+    int end_param = HVM_NR_PARAMS;
+    int param;
+    int ret = 0;
+    int i;
+    char hvm_param_name[HVM_NR_PARAMS][80];
+
+    unsigned long hvm_param = -1;
+
+    if ( (argc < 2) || (argc > 4) )
+        errx(1, "usage: %s domid [param [new]]", argv[0]);
+
+    for ( i = 0; i < HVM_NR_PARAMS; i++ )
+        snprintf(hvm_param_name[i], sizeof(hvm_param_name[i]),
+                 "Unknown %d", i);
+
+    snprintf(hvm_param_name[HVM_PARAM_CALLBACK_IRQ],
+             sizeof(hvm_param_name[HVM_PARAM_CALLBACK_IRQ]), "callback_irq");
+    snprintf(hvm_param_name[HVM_PARAM_STORE_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_STORE_PFN]), "store_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_STORE_EVTCHN],
+             sizeof(hvm_param_name[HVM_PARAM_STORE_EVTCHN]), "store_evtchn");
+    snprintf(hvm_param_name[HVM_PARAM_PAE_ENABLED],
+             sizeof(hvm_param_name[HVM_PARAM_PAE_ENABLED]), "pae_enabled");
+    snprintf(hvm_param_name[HVM_PARAM_IOREQ_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_IOREQ_PFN]), "ioreq_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_VMPORT_REGS_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_VMPORT_REGS_PFN]), "vmport_regs_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_BUFIOREQ_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_BUFIOREQ_PFN]), "bufioreq_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_VIRIDIAN],
+             sizeof(hvm_param_name[HVM_PARAM_VIRIDIAN]), "viridian");
+    snprintf(hvm_param_name[HVM_PARAM_TIMER_MODE],
+             sizeof(hvm_param_name[HVM_PARAM_TIMER_MODE]), "timer_mode");
+    snprintf(hvm_param_name[HVM_PARAM_HPET_ENABLED],
+             sizeof(hvm_param_name[HVM_PARAM_HPET_ENABLED]), "hpet_enabled");
+    snprintf(hvm_param_name[HVM_PARAM_IDENT_PT],
+             sizeof(hvm_param_name[HVM_PARAM_IDENT_PT]), "ident_pt");
+    snprintf(hvm_param_name[HVM_PARAM_DM_DOMAIN],
+             sizeof(hvm_param_name[HVM_PARAM_DM_DOMAIN]), "dm_domain");
+    snprintf(hvm_param_name[HVM_PARAM_ACPI_S_STATE],
+             sizeof(hvm_param_name[HVM_PARAM_ACPI_S_STATE]), "acpi_s_state");
+    snprintf(hvm_param_name[HVM_PARAM_VM86_TSS],
+             sizeof(hvm_param_name[HVM_PARAM_VM86_TSS]), "vm86_tss");
+    snprintf(hvm_param_name[HVM_PARAM_VPT_ALIGN],
+             sizeof(hvm_param_name[HVM_PARAM_VPT_ALIGN]), "vpt_align");
+    snprintf(hvm_param_name[HVM_PARAM_CONSOLE_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_CONSOLE_PFN]), "console_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_CONSOLE_EVTCHN],
+             sizeof(hvm_param_name[HVM_PARAM_CONSOLE_EVTCHN]),
+             "console_evtchn");
+    snprintf(hvm_param_name[HVM_PARAM_ACPI_IOPORTS_LOCATION],
+             sizeof(hvm_param_name[HVM_PARAM_ACPI_IOPORTS_LOCATION]),
+             "acpi_ioports_location");
+    snprintf(hvm_param_name[HVM_PARAM_MEMORY_EVENT_CR0],
+             sizeof(hvm_param_name[HVM_PARAM_MEMORY_EVENT_CR0]),
+             "memory_event_cr0");
+    snprintf(hvm_param_name[HVM_PARAM_MEMORY_EVENT_CR3],
+             sizeof(hvm_param_name[HVM_PARAM_MEMORY_EVENT_CR3]),
+             "memory_event_cr3");
+    snprintf(hvm_param_name[HVM_PARAM_MEMORY_EVENT_CR4],
+             sizeof(hvm_param_name[HVM_PARAM_MEMORY_EVENT_CR4]),
+             "memory_event_cr4");
+    snprintf(hvm_param_name[HVM_PARAM_MEMORY_EVENT_INT3],
+             sizeof(hvm_param_name[HVM_PARAM_MEMORY_EVENT_INT3]),
+             "memory_event_int3");
+    snprintf(hvm_param_name[HVM_PARAM_NESTEDHVM],
+             sizeof(hvm_param_name[HVM_PARAM_NESTEDHVM]), "nestedhvm");
+    snprintf(hvm_param_name[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP],
+             sizeof(hvm_param_name[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP]),
+             "memory_event_single_step");
+    snprintf(hvm_param_name[HVM_PARAM_MEMORY_EVENT_MSR],
+             sizeof(hvm_param_name[HVM_PARAM_MEMORY_EVENT_MSR]),
+             "memory_event_msr");
+    snprintf(hvm_param_name[HVM_PARAM_BUFIOREQ_EVTCHN],
+             sizeof(hvm_param_name[HVM_PARAM_BUFIOREQ_EVTCHN]),
+             "bufioreq_evtchn");
+    snprintf(hvm_param_name[HVM_PARAM_PAGING_RING_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_PAGING_RING_PFN]),
+             "paging_ring_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_ACCESS_RING_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_ACCESS_RING_PFN]),
+             "access_ring_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_SHARING_RING_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_SHARING_RING_PFN]),
+             "sharing_ring_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_TRIPLE_FAULT_REASON],
+             sizeof(hvm_param_name[HVM_PARAM_TRIPLE_FAULT_REASON]),
+             "triple_fault_reason");
+    snprintf(hvm_param_name[HVM_PARAM_IOREQ_SERVER_PFN],
+             sizeof(hvm_param_name[HVM_PARAM_IOREQ_SERVER_PFN]),
+             "ioreq_server_pfn");
+    snprintf(hvm_param_name[HVM_PARAM_NR_IOREQ_SERVER_PAGES],
+             sizeof(hvm_param_name[HVM_PARAM_NR_IOREQ_SERVER_PAGES]),
+             "nr_ioreq_server_pages");
+    snprintf(hvm_param_name[HVM_PARAM_VM_GENERATION_ID_ADDR],
+             sizeof(hvm_param_name[HVM_PARAM_VM_GENERATION_ID_ADDR]),
+             "vm_generation_id_addr");
+    snprintf(hvm_param_name[HVM_PARAM_VMWARE_HWVER],
+             sizeof(hvm_param_name[HVM_PARAM_VMWARE_HWVER]), "vmware_hwver");
+
+    xch = xc_interface_open(0, 0, 0);
+    if ( !xch )
+        err(1, "failed to open control interface");
+
+    domid = atoi(argv[1]);
+    if ( argc > 2 )
+    {
+        start_param = strtol(argv[2], NULL, 0);
+        end_param = start_param + 1;
+    }
+
+    for ( param = start_param; param < end_param; param++ )
+    {
+        ret = xc_get_hvm_param(xch, domid, param, &hvm_param);
+        if ( ret )
+            err(1, "failed to get hvm param %d for domid %d", param, domid);
+        else
+        {
+            if ( argc == 4 )
+            {
+                long new = strtol(argv[3], NULL, 0);
+
+                ret = xc_set_hvm_param(xch, domid, param, new);
+                if ( ret )
+                    err(1, "failed to set hvm param %d for domid %d", param,
+                        domid);
+                else if ( (param >= 0) && (param < HVM_NR_PARAMS) )
+                    printf("hvm_param(%d:'%s')=0x%lx(%ld) was 0x%lx(%ld)\n",
+                           param, hvm_param_name[param], new, new, hvm_param,
+                           hvm_param);
+                else
+                    printf("hvm_param(%d)=0x%lx(%ld) was 0x%lx(%ld)\n",
+                           param, new, new, hvm_param, hvm_param);
+            }
+            else
+            {
+                if ( (param >= 0) && (param < HVM_NR_PARAMS) )
+                    printf("hvm_param(%d:'%s')=0x%lx(%ld)\n",
+                           param, hvm_param_name[param], hvm_param, hvm_param);
+                else
+                    printf("hvm_param(%d)=0x%lx(%ld)\n", param, hvm_param,
+                           hvm_param);
+            }
+        }
+    }
+    xc_interface_close(xch);
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h
  2015-02-16 23:05 ` [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h Don Slutz
@ 2015-02-17  9:52   ` Andrew Cooper
  2015-02-17 21:31     ` Don Slutz
  2015-03-03 14:02   ` George Dunlap
  1 sibling, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17  9:52 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> Change some hard coded 15 into MAX_INST_LEN
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>

One formatting suggestion.

> ---
>  xen/arch/x86/hvm/svm/emulate.c         | 2 --
>  xen/arch/x86/hvm/svm/svm.c             | 4 ++--
>  xen/arch/x86/hvm/vmx/vmx.c             | 2 +-
>  xen/arch/x86/x86_emulate/x86_emulate.c | 4 ++--
>  xen/arch/x86/x86_emulate/x86_emulate.h | 2 ++
>  5 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/svm/emulate.c b/xen/arch/x86/hvm/svm/emulate.c
> index 37a1ece..6f5c8d3 100644
> --- a/xen/arch/x86/hvm/svm/emulate.c
> +++ b/xen/arch/x86/hvm/svm/emulate.c
> @@ -27,8 +27,6 @@
>  #include <asm/hvm/svm/vmcb.h>
>  #include <asm/hvm/svm/emulate.h>
>  
> -#define MAX_INST_LEN 15
> -
>  static unsigned int is_prefix(u8 opc)
>  {
>      switch ( opc )
> diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
> index a7655bd..4b7b818 100644
> --- a/xen/arch/x86/hvm/svm/svm.c
> +++ b/xen/arch/x86/hvm/svm/svm.c
> @@ -106,7 +106,7 @@ void __update_guest_eip(struct cpu_user_regs *regs, unsigned int inst_len)
>      if ( unlikely(inst_len == 0) )
>          return;
>  
> -    if ( unlikely(inst_len > 15) )
> +    if ( unlikely(inst_len > MAX_INST_LEN) )
>      {
>          gdprintk(XENLOG_ERR, "Bad instruction length %u\n", inst_len);
>          svm_crash_or_fault(curr);
> @@ -859,7 +859,7 @@ static unsigned int svm_get_insn_bytes(struct vcpu *v, uint8_t *buf)
>      if ( len != 0 )
>      {
>          /* Latch and clear the cached instruction. */
> -        memcpy(buf, vmcb->guest_ins, 15);
> +        memcpy(buf, vmcb->guest_ins, MAX_INST_LEN);
>          v->arch.hvm_svm.cached_insn_len = 0;
>      }
>  
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 357ef6c..e1c55ce 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -1854,7 +1854,7 @@ static int get_instruction_length(void)
>      unsigned long len;
>  
>      __vmread(VM_EXIT_INSTRUCTION_LEN, &len); /* Safe: callers audited */
> -    BUG_ON((len < 1) || (len > 15));
> +    BUG_ON((len < 1) || (len > MAX_INST_LEN));
>      return len;
>  }
>  
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
> index f13f07d..42e2588 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -579,8 +579,8 @@ do{ asm volatile (                                                      \
>  ({ unsigned long _x = 0, _eip = _regs.eip;                              \
>     if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
>     _regs.eip += (_size); /* real hardware doesn't truncate */           \
> -   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
> -                         EXC_GP, 0);                                    \
> +   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) >       \
> +			 MAX_INST_LEN, EXC_GP, 0);                       \

This would probably be better with the uint8_t cast on starting on the
next line, which would avoid the need to put a linebreak in the middle
of the comparison.

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

>     rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
>     if ( rc ) goto done;                                                 \
>     _x;                                                                  \
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h
> index bdce861..593b31e 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
> @@ -24,6 +24,8 @@
>  #ifndef __X86_EMULATE_H__
>  #define __X86_EMULATE_H__
>  
> +#define MAX_INST_LEN 15
> +
>  struct x86_emulate_ctxt;
>  
>  /* Comprehensive enumeration of x86 segment registers. */

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 02/13] xen: Add support for VMware cpuid leaves
  2015-02-16 23:05 ` [PATCH v9 02/13] xen: Add support for VMware cpuid leaves Don Slutz
@ 2015-02-17 10:02   ` Andrew Cooper
  2015-02-17 15:57     ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 10:02 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> This is done by adding HVM_PARAM_VMWARE_HW. It is set to the VMware
> virtual hardware version.
>
> Currently 0, 3-4, 6-11 are good values.  However the
> code only checks for == 0 or != 0 or >= 7.
>
> If non-zero then
>   Return VMware's cpuid leaves.  If >= 7 return data, else
>   return 0.
>
> The support of hypervisor cpuid leaves has not been agreed to.
>
> MicroSoft Hyper-V (AKA viridian) currently must be at 0x40000000.
>
> VMware currently must be at 0x40000000.
>
> KVM currently must be at 0x40000000 (from Seabios).
>
> Xen can be found at the first otherwise unused 0x100 aligned
> offset between 0x40000000 and 0x40010000.
>
> http://download.microsoft.com/download/F/B/0/FB0D01A3-8E3A-4F5F-AA59-08C8026D3B8A/requirements-for-implementing-microsoft-hypervisor-interface.docx
>
> http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458
>
> http://lwn.net/Articles/301888/
>   Attempted to get this cleaned up.
>
> So based on this, I picked the order:
>
> Xen at 0x40000000 or
> Viridian or VMware at 0x40000000 and Xen at 0x40000100
>
> If both Viridian and VMware selected, report an error.
>
> Since I need to change xen/arch/x86/hvm/Makefile; also add
> a newline at end of file.
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v9:
>     s/vmware_hw/vmware_hwver/i
>     Change -EXDEV to EOPNOTSUPP.
>       Done.
>     adding another subdirectory: xen/arch/x86/hvm/vmware
>     Much will depend on the discussion of the subsequent patches.
>       TBD.
>     So for versions < 7 there's effectively no CPUID support at all?
>       Changed to check at entry.
>     The comment /* Params for VMware */ seems wrong...
>       Changed to /* emulated VMware Hardware Version */
>     Also please use d, not _d in #define is_vmware_domain()
>       Changed.  Line is now > 80 characters, so split into 2.
>
> v7:
>       Prevent setting of HVM_PARAM_VIRIDIAN if HVM_PARAM_VMWARE_HW set.
> v5:
>       Given how is_viridian and is_vmware are defined I think '||' is more
>       appropriate.
>         Fixed.
>       The names of all three functions are bogus.
>         removed static support routines.
>       This hunk is unrelated, but is perhaps something better fixed.
>         Added to commit message.
>       include <xen/types.h> (IIRC) please.
>         Done.
>       At least 1 pair of brackets please, especially as the placement of
>       brackets affects the result of this particular calculation.
>         Switch to "1000000ull / APIC_BUS_CYCLE_NS"      
>
>  xen/arch/x86/hvm/Makefile        |  3 +-
>  xen/arch/x86/hvm/hvm.c           | 32 +++++++++++++++++
>  xen/arch/x86/hvm/vmware/Makefile |  1 +
>  xen/arch/x86/hvm/vmware/cpuid.c  | 75 ++++++++++++++++++++++++++++++++++++++++
>  xen/arch/x86/traps.c             |  8 +++--
>  xen/include/asm-x86/hvm/hvm.h    |  7 ++++
>  xen/include/asm-x86/hvm/vmware.h | 33 ++++++++++++++++++
>  xen/include/public/hvm/params.h  |  5 ++-
>  8 files changed, 160 insertions(+), 4 deletions(-)
>  create mode 100644 xen/arch/x86/hvm/vmware/Makefile
>  create mode 100644 xen/arch/x86/hvm/vmware/cpuid.c
>  create mode 100644 xen/include/asm-x86/hvm/vmware.h
>
> diff --git a/xen/arch/x86/hvm/Makefile b/xen/arch/x86/hvm/Makefile
> index eea5555..77598a6 100644
> --- a/xen/arch/x86/hvm/Makefile
> +++ b/xen/arch/x86/hvm/Makefile
> @@ -1,5 +1,6 @@
>  subdir-y += svm
>  subdir-y += vmx
> +subdir-y += vmware
>  
>  obj-y += asid.o
>  obj-y += emulate.o
> @@ -22,4 +23,4 @@ obj-y += vlapic.o
>  obj-y += vmsi.o
>  obj-y += vpic.o
>  obj-y += vpt.o
> -obj-y += vpmu.o
> \ No newline at end of file
> +obj-y += vpmu.o
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index a52c6e0..fefd023 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -60,6 +60,7 @@
>  #include <asm/hvm/cacheattr.h>
>  #include <asm/hvm/trace.h>
>  #include <asm/hvm/nestedhvm.h>
> +#include <asm/hvm/vmware.h>
>  #include <asm/mtrr.h>
>  #include <asm/apic.h>
>  #include <public/sched.h>
> @@ -4277,6 +4278,9 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
>      if ( cpuid_viridian_leaves(input, eax, ebx, ecx, edx) )
>          return;
>  
> +    if ( cpuid_vmware_leaves(input, eax, ebx, ecx, edx) )
> +        return;
> +
>      if ( cpuid_hypervisor_leaves(input, count, eax, ebx, ecx, edx) )
>          return;
>  
> @@ -5752,6 +5756,11 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>                  if ( curr_d == d )
>                      break;
>  
> +                if ( d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] )
> +                {
> +                    rc = -EOPNOTSUPP;
> +                    break;
> +                }
>                  if ( a.value != d->arch.hvm_domain.params[a.index] )
>                  {
>                      rc = -EEXIST;
> @@ -5900,6 +5909,29 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>  
>                  break;
>              }
> +            case HVM_PARAM_VMWARE_HWVER:
> +                /*
> +                 * This should only ever be set non-zero one time by
> +                 * the tools and is read only by the guest.
> +                 */
> +                if ( curr_d == d )
> +                {
> +                    rc = -EPERM;
> +                    break;
> +                }
> +                if ( d->arch.hvm_domain.params[HVM_PARAM_VIRIDIAN] )
> +                {
> +                    rc = -EXDEV;
> +                    break;
> +                }
> +                if ( d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] &&
> +                     d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] !=
> +                     a.value )
> +                {
> +                    rc = -EEXIST;
> +                    break;
> +                }
> +                break;
>              }
>  
>              if ( rc == 0 ) 
> diff --git a/xen/arch/x86/hvm/vmware/Makefile b/xen/arch/x86/hvm/vmware/Makefile
> new file mode 100644
> index 0000000..3fb2e0b
> --- /dev/null
> +++ b/xen/arch/x86/hvm/vmware/Makefile
> @@ -0,0 +1 @@
> +obj-y += cpuid.o
> diff --git a/xen/arch/x86/hvm/vmware/cpuid.c b/xen/arch/x86/hvm/vmware/cpuid.c
> new file mode 100644
> index 0000000..70cdabd
> --- /dev/null
> +++ b/xen/arch/x86/hvm/vmware/cpuid.c
> @@ -0,0 +1,75 @@
> +/*
> + * arch/x86/hvm/vmware/cpuid.c
> + *
> + * 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/sched.h>
> +
> +#include <asm/hvm/hvm.h>
> +#include <asm/hvm/vmware.h>
> +
> +/*
> + * VMware hardware version 7 defines some of these cpuid levels,
> + * below is a brief description about those.
> + *
> + *     Leaf 0x40000000, Hypervisor CPUID information
> + * # EAX: The maximum input value for hypervisor CPUID info (0x40000010).
> + * # EBX, ECX, EDX: Hypervisor vendor ID signature. E.g. "VMwareVMware"
> + *
> + *     Leaf 0x40000010, Timing information.
> + * # EAX: (Virtual) TSC frequency in kHz.
> + * # EBX: (Virtual) Bus (local apic timer) frequency in kHz.
> + * # ECX, EDX: RESERVED
> + */
> +
> +int cpuid_vmware_leaves(uint32_t idx, uint32_t *eax, uint32_t *ebx,
> +                        uint32_t *ecx, uint32_t *edx)
> +{
> +    struct domain *d = current->domain;
> +
> +    if ( !is_vmware_domain(d) ||
> +         d->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] < 7 )
> +        return 0;
> +
> +    switch ( idx - 0x40000000 )
> +    {
> +    case 0x0:
> +        *eax = 0x40000010;  /* Largest leaf */
> +        *ebx = 0x61774d56;  /* "VMwa" */
> +        *ecx = 0x4d566572;  /* "reVM" */
> +        *edx = 0x65726177;  /* "ware" */
> +        break;
> +    case 0x10:
> +        /* (Virtual) TSC frequency in kHz. */
> +        *eax =  d->arch.tsc_khz;
> +        /* (Virtual) Bus (local apic timer) frequency in kHz. */
> +        *ebx = 1000000ull / APIC_BUS_CYCLE_NS;
> +        *ecx = 0;          /* Reserved */
> +        *edx = 0;          /* Reserved */
> +        break;
> +    default:
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
> index f5516dc..589e458 100644
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -750,8 +750,12 @@ int cpuid_hypervisor_leaves( uint32_t idx, uint32_t sub_idx,
>                 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
>  {
>      struct domain *d = current->domain;
> -    /* Optionally shift out of the way of Viridian architectural leaves. */
> -    uint32_t base = is_viridian_domain(d) ? 0x40000100 : 0x40000000;
> +    /*
> +     * Optionally shift out of the way of Viridian or VMware
> +     * architectural leaves.
> +     */
> +    uint32_t base = is_viridian_domain(d) || is_vmware_domain(d) ?
> +        0x40000100 : 0x40000000;
>      uint32_t limit, dummy;
>  
>      idx -= base;
> diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
> index 0dc909b..8ecde89 100644
> --- a/xen/include/asm-x86/hvm/hvm.h
> +++ b/xen/include/asm-x86/hvm/hvm.h
> @@ -356,6 +356,13 @@ static inline unsigned long hvm_get_shadow_gs_base(struct vcpu *v)
>  #define has_viridian_time_ref_count(d) \
>      (is_viridian_domain(d) && (viridian_feature_mask(d) & HVMPV_time_ref_count))
>  
> +#define vmware_feature_mask(d) \
> +    (has_hvm_params(d) ? \
> +     (d)->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] : 0)

I can't spot any use of this vmware_feature_mask().  Is it stale?

Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

> +
> +#define is_vmware_domain(d) \
> +    (is_hvm_domain(d) && vmware_feature_mask(d))
> +
>  void hvm_hypervisor_cpuid_leaf(uint32_t sub_idx,
>                                 uint32_t *eax, uint32_t *ebx,
>                                 uint32_t *ecx, uint32_t *edx);
> diff --git a/xen/include/asm-x86/hvm/vmware.h b/xen/include/asm-x86/hvm/vmware.h
> new file mode 100644
> index 0000000..8390173
> --- /dev/null
> +++ b/xen/include/asm-x86/hvm/vmware.h
> @@ -0,0 +1,33 @@
> +/*
> + * asm-x86/hvm/vmware.h
> + *
> + * 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/>.
> + */
> +
> +#ifndef ASM_X86_HVM_VMWARE_H__
> +#define ASM_X86_HVM_VMWARE_H__
> +
> +#include <xen/types.h>
> +
> +int cpuid_vmware_leaves(uint32_t idx, uint32_t *eax, uint32_t *ebx,
> +                        uint32_t *ecx, uint32_t *edx);
> +
> +#endif /* ASM_X86_HVM_VMWARE_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
> index a2d43bc..974d3a4 100644
> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -194,6 +194,9 @@
>  /* Location of the VM Generation ID in guest physical address space. */
>  #define HVM_PARAM_VM_GENERATION_ID_ADDR 34
>  
> -#define HVM_NR_PARAMS          35
> +/* emulated VMware Hardware Version */
> +#define HVM_PARAM_VMWARE_HWVER 35
> +
> +#define HVM_NR_PARAMS          36
>  
>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 04/13] vmware: Add VMware provided include file.
  2015-02-16 23:05 ` [PATCH v9 04/13] vmware: Add VMware provided include file Don Slutz
@ 2015-02-17 10:03   ` Andrew Cooper
  0 siblings, 0 replies; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 10:03 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> This file: backdoor_def.h comes from:
>
> http://packages.vmware.com/tools/esx/3.5latest/rhel4/SRPMS/index.html
>  open-vm-tools-kmod-7.4.8-396269.423167.src.rpm
>   open-vm-tools-kmod-7.4.8.tar.gz
>    vmhgfs/backdoor_def.h
>
> and is unchanged.
>
> Added the badly named include file includeCheck.h also.  It only has
> a comment and is provided so that backdoor_def.h can be used without
> change.
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>

Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>

> ---
> v9:
>     Either the description is wrong, or the patch is stale.
>       stale commit message -- fixed.
>     I'd say a file with a single comment line in it would suffice.
>       Done.
>
>
>  xen/arch/x86/hvm/vmware/backdoor_def.h | 167 +++++++++++++++++++++++++++++++++
>  xen/arch/x86/hvm/vmware/includeCheck.h |   1 +
>  2 files changed, 168 insertions(+)
>  create mode 100644 xen/arch/x86/hvm/vmware/backdoor_def.h
>  create mode 100644 xen/arch/x86/hvm/vmware/includeCheck.h
>
> diff --git a/xen/arch/x86/hvm/vmware/backdoor_def.h b/xen/arch/x86/hvm/vmware/backdoor_def.h
> new file mode 100644
> index 0000000..e76795f
> --- /dev/null
> +++ b/xen/arch/x86/hvm/vmware/backdoor_def.h
> @@ -0,0 +1,167 @@
> +/* **********************************************************
> + * Copyright 1998 VMware, Inc.  All rights reserved. 
> + * **********************************************************
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation version 2 and no later version.
> + *
> + * This program 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.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
> + */
> +
> +/*
> + * backdoor_def.h --
> + *
> + * This contains backdoor defines that can be included from
> + * an assembly language file.
> + */
> +
> +
> +
> +#ifndef _BACKDOOR_DEF_H_
> +#define _BACKDOOR_DEF_H_
> +
> +#define INCLUDE_ALLOW_MODULE
> +#define INCLUDE_ALLOW_USERLEVEL
> +#define INCLUDE_ALLOW_VMMEXT
> +#define INCLUDE_ALLOW_VMCORE
> +#define INCLUDE_ALLOW_VMKERNEL
> +#include "includeCheck.h"
> +
> +/*
> + * If you want to add a new low-level backdoor call for a guest userland
> + * application, please consider using the GuestRpc mechanism instead. --hpreg
> + */
> +
> +#define BDOOR_MAGIC 0x564D5868
> +
> +/* Low-bandwidth backdoor port. --hpreg */
> +
> +#define BDOOR_PORT 0x5658
> +
> +#define BDOOR_CMD_GETMHZ      		   1
> +/*
> + * BDOOR_CMD_APMFUNCTION is used by:
> + *
> + * o The FrobOS code, which instead should either program the virtual chipset
> + *   (like the new BIOS code does, matthias offered to implement that), or not
> + *   use any VM-specific code (which requires that we correctly implement
> + *   "power off on CLI HLT" for SMP VMs, boris offered to implement that)
> + *
> + * o The old BIOS code, which will soon be jettisoned
> + *
> + *  --hpreg
> + */
> +#define BDOOR_CMD_APMFUNCTION 		   2
> +#define BDOOR_CMD_GETDISKGEO  		   3
> +#define BDOOR_CMD_GETPTRLOCATION	      4
> +#define BDOOR_CMD_SETPTRLOCATION	      5
> +#define BDOOR_CMD_GETSELLENGTH		   6
> +#define BDOOR_CMD_GETNEXTPIECE		   7
> +#define BDOOR_CMD_SETSELLENGTH		   8
> +#define BDOOR_CMD_SETNEXTPIECE		   9
> +#define BDOOR_CMD_GETVERSION		      10
> +#define BDOOR_CMD_GETDEVICELISTELEMENT	11
> +#define BDOOR_CMD_TOGGLEDEVICE		   12
> +#define BDOOR_CMD_GETGUIOPTIONS		   13
> +#define BDOOR_CMD_SETGUIOPTIONS		   14
> +#define BDOOR_CMD_GETSCREENSIZE		   15
> +#define BDOOR_CMD_MONITOR_CONTROL       16
> +#define BDOOR_CMD_GETHWVERSION          17
> +#define BDOOR_CMD_OSNOTFOUND            18
> +#define BDOOR_CMD_GETUUID               19
> +#define BDOOR_CMD_GETMEMSIZE            20
> +#define BDOOR_CMD_HOSTCOPY              21 /* Devel only */
> +/* BDOOR_CMD_GETOS2INTCURSOR, 22, is very old and defunct. Reuse. */
> +#define BDOOR_CMD_GETTIME               23 /* Deprecated. Use GETTIMEFULL. */
> +#define BDOOR_CMD_STOPCATCHUP           24
> +#define BDOOR_CMD_PUTCHR	        25 /* Devel only */
> +#define BDOOR_CMD_ENABLE_MSG	        26 /* Devel only */
> +#define BDOOR_CMD_GOTO_TCL	        27 /* Devel only */
> +#define BDOOR_CMD_INITPCIOPROM		28
> +#define BDOOR_CMD_INT13			29
> +#define BDOOR_CMD_MESSAGE               30
> +#define BDOOR_CMD_RSVD0                 31
> +#define BDOOR_CMD_RSVD1                 32
> +#define BDOOR_CMD_RSVD2                 33
> +#define BDOOR_CMD_ISACPIDISABLED	34
> +#define BDOOR_CMD_TOE			35 /* Not in use */
> +/* BDOOR_CMD_INITLSIOPROM, 36, was merged with 28. Reuse. */
> +#define BDOOR_CMD_PATCH_SMBIOS_STRUCTS  37
> +#define BDOOR_CMD_MAPMEM                38 /* Devel only */
> +#define BDOOR_CMD_ABSPOINTER_DATA	39
> +#define BDOOR_CMD_ABSPOINTER_STATUS	40
> +#define BDOOR_CMD_ABSPOINTER_COMMAND	41
> +#define BDOOR_CMD_TIMER_SPONGE          42
> +#define BDOOR_CMD_PATCH_ACPI_TABLES	43
> +/* Catch-all to allow synchronous tests */
> +#define BDOOR_CMD_DEVEL_FAKEHARDWARE	44 /* Debug only - needed in beta */
> +#define BDOOR_CMD_GETHZ      		45
> +#define BDOOR_CMD_GETTIMEFULL           46
> +#define BDOOR_CMD_STATELOGGER           47
> +#define BDOOR_CMD_CHECKFORCEBIOSSETUP	48
> +#define BDOOR_CMD_LAZYTIMEREMULATION    49
> +#define BDOOR_CMD_BIOSBBS               50
> +#define BDOOR_CMD_MAX                   51
> +
> +/* 
> + * IMPORTANT NOTE: When modifying the behavior of an existing backdoor command,
> + * you must adhere to the semantics expected by the oldest Tools who use that
> + * command. Specifically, do not alter the way in which the command modifies 
> + * the registers. Otherwise backwards compatibility will suffer.
> + */
> +
> +/* High-bandwidth backdoor port. --hpreg */
> +
> +#define BDOORHB_PORT 0x5659
> +
> +#define BDOORHB_CMD_MESSAGE 0
> +#define BDOORHB_CMD_MAX 1
> +
> +/*
> + * There is another backdoor which allows access to certain TSC-related
> + * values using otherwise illegal PMC indices when the pseudo_perfctr
> + * control flag is set.
> + */
> +
> +#define BDOOR_PMC_HW_TSC      0x10000
> +#define BDOOR_PMC_REAL_NS     0x10001
> +#define BDOOR_PMC_APPARENT_NS 0x10002
> +
> +#define IS_BDOOR_PMC(index)  (((index) | 3) == 0x10003)
> +#define BDOOR_CMD(ecx)       ((ecx) & 0xffff)
> +
> +
> +#ifdef VMM
> +/*
> + *----------------------------------------------------------------------
> + *
> + * Backdoor_CmdRequiresFullyValidVCPU --
> + *
> + *    A few backdoor commands require the full VCPU to be valid
> + *    (including GDTR, IDTR, TR and LDTR). The rest get read/write
> + *    access to GPRs and read access to Segment registers (selectors).
> + *
> + * Result:
> + *    True iff VECX contains a command that require the full VCPU to
> + *    be valid.
> + *
> + *----------------------------------------------------------------------
> + */
> +static INLINE Bool
> +Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd)
> +{
> +   return cmd == BDOOR_CMD_RSVD0 ||
> +          cmd == BDOOR_CMD_RSVD1 ||
> +          cmd == BDOOR_CMD_RSVD2;
> +}
> +#endif
> +
> +#endif
> diff --git a/xen/arch/x86/hvm/vmware/includeCheck.h b/xen/arch/x86/hvm/vmware/includeCheck.h
> new file mode 100644
> index 0000000..3b63fa4
> --- /dev/null
> +++ b/xen/arch/x86/hvm/vmware/includeCheck.h
> @@ -0,0 +1 @@
> +/* Nothing here.  Just to use backdoor_def.h without change. */

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-16 23:05 ` [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT Don Slutz
@ 2015-02-17 10:08   ` Paul Durrant
  2015-02-18  2:44     ` Don Slutz
  2015-02-24 15:34   ` Jan Beulich
  2015-03-03 14:25   ` Ian Campbell
  2 siblings, 1 reply; 71+ messages in thread
From: Paul Durrant @ 2015-02-17 10:08 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir (Xen.org), Ian Campbell, Tim (Xen.org),
	Eddie Dong, George Dunlap, Jan Beulich, Stefano Stabellini,
	Aravind Gopalakrishnan, Jun Nakajima, Andrew Cooper, Ian Jackson,
	Boris Ostrovsky, Suravee Suthikulpanit

> -----Original Message-----
> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
> bounces@lists.xen.org] On Behalf Of Don Slutz
> Sent: 16 February 2015 23:05
> To: xen-devel@lists.xen.org
> Cc: Kevin Tian; Keir (Xen.org); Ian Campbell; Stefano Stabellini; Jun Nakajima;
> Eddie Dong; Ian Jackson; Don Slutz; Tim (Xen.org); George Dunlap; Aravind
> Gopalakrishnan; Jan Beulich; Andrew Cooper; Boris Ostrovsky; Suravee
> Suthikulpanit
> Subject: [Xen-devel] [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
> 
> This adds synchronization 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
> 
> In the tools, enable usage of QEMU's vmport code.
> 
> The currently most useful VMware port support that QEMU has is the
> VMware mouse support.  Xorg included a VMware mouse support that
> uses absolute mode.  This make using a mouse in X11 much nicer.
> 
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v9:
>   New code was presented as an RFC before this.
> 
>   Paul Durrant sugested I add support for other IOREQ types
>   to HVMOP_map_io_range_to_ioreq_server.
>     I have done this.
> 
>  tools/libxc/xc_hvm_build_x86.c         |   5 +-
>  tools/libxl/libxl_dm.c                 |   4 +
>  xen/arch/x86/hvm/emulate.c             |  48 ++++++++++
>  xen/arch/x86/hvm/hvm.c                 | 159
> ++++++++++++++++++++++++++++++---
>  xen/arch/x86/hvm/io.c                  |  15 ++++
>  xen/arch/x86/hvm/vmware/vmport.c       |   4 +-
>  xen/arch/x86/x86_emulate/x86_emulate.h |   2 +
>  xen/include/asm-x86/hvm/domain.h       |   3 +-
>  xen/include/asm-x86/hvm/hvm.h          |   2 +
>  xen/include/public/hvm/hvm_op.h        |   6 ++
>  xen/include/public/hvm/ioreq.h         |  17 ++++
>  xen/include/public/hvm/params.h        |   4 +-
>  12 files changed, 251 insertions(+), 18 deletions(-)
> 
> diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
> index c81a25b..e338667 100644
> --- a/tools/libxc/xc_hvm_build_x86.c
> +++ b/tools/libxc/xc_hvm_build_x86.c
> @@ -46,7 +46,8 @@
>  #define SPECIALPAGE_IOREQ    5
>  #define SPECIALPAGE_IDENT_PT 6
>  #define SPECIALPAGE_CONSOLE  7
> -#define NR_SPECIAL_PAGES     8
> +#define SPECIALPAGE_VMPORT_REGS 8
> +#define NR_SPECIAL_PAGES     9
>  #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
> 
>  #define NR_IOREQ_SERVER_PAGES 8
> @@ -493,6 +494,8 @@ static int setup_guest(xc_interface *xch,
>                       special_pfn(SPECIALPAGE_BUFIOREQ));
>      xc_hvm_param_set(xch, dom, HVM_PARAM_IOREQ_PFN,
>                       special_pfn(SPECIALPAGE_IOREQ));
> +    xc_hvm_param_set(xch, dom, HVM_PARAM_VMPORT_REGS_PFN,
> +                     special_pfn(SPECIALPAGE_VMPORT_REGS));
>      xc_hvm_param_set(xch, dom, HVM_PARAM_CONSOLE_PFN,
>                       special_pfn(SPECIALPAGE_CONSOLE));
>      xc_hvm_param_set(xch, dom, HVM_PARAM_PAGING_RING_PFN,
> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index c27f9a4..620013c 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -765,6 +765,10 @@ static char **
> libxl__build_device_model_args_new(libxl__gc *gc,
>                                              machinearg, max_ram_below_4g);
>              }
>          }
> +        if (libxl_defbool_val(c_info->vmware_port)) {
> +            machinearg = libxl__sprintf(gc, "%s,vmport=on",
> +                                        machinearg);
> +        }
>          flexarray_append(dm_args, machinearg);
>          for (i = 0; b_info->extra_hvm && b_info->extra_hvm[i] != NULL; i++)
>              flexarray_append(dm_args, b_info->extra_hvm[i]);
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index a6a6a5c..799894b 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -240,6 +240,48 @@ static int hvmemul_do_io(
>          }
>          break;
>      }
> +    case X86EMUL_VMPORT_SEND:
> +    {
> +        struct hvm_ioreq_server *s;
> +        vmware_regs_t *vr;
> +
> +        BUILD_BUG_ON(sizeof(ioreq_t) < sizeof(vmware_regs_t));
> +
> +        p.type = IOREQ_TYPE_VMWARE_PORT;
> +        s = hvm_select_ioreq_server(curr->domain, &p);
> +        vr = get_vmport_regs_any(s, curr);
> +
> +        /*
> +         * If there is no suitable backing DM, just ignore accesses.  If
> +         * we do not have access to registers to pass to QEMU, just
> +         * ignore access.
> +         */
> +        if ( !s || !vr )
> +        {
> +            hvm_complete_assist_req(&p);
> +            rc = X86EMUL_OKAY;
> +            vio->io_state = HVMIO_none;
> +        }
> +        else
> +        {
> +            struct cpu_user_regs *regs = guest_cpu_user_regs();
> +
> +            p.data = regs->rax;
> +            vr->ebx = regs->_ebx;
> +            vr->ecx = regs->_ecx;
> +            vr->edx = regs->_edx;
> +            vr->esi = regs->_esi;
> +            vr->edi = regs->_edi;
> +
> +            vio->io_state = HVMIO_handle_pio_awaiting_completion;
> +            if ( !hvm_send_assist_req(s, &p) )
> +            {
> +                rc = X86EMUL_RETRY;
> +                vio->io_state = HVMIO_none;
> +            }
> +        }
> +        break;
> +    }
>      default:
>          BUG();
>      }
> @@ -248,6 +290,12 @@ static int hvmemul_do_io(
>      {
>          if ( ram_page )
>              put_page(ram_page);
> +        /*
> +         * If X86EMUL_VMPORT_SEND, completion in hvm_io_assist()
> +         * with no re-emulation required
> +         */
> +        if ( rc == X86EMUL_VMPORT_SEND )
> +            rc = X86EMUL_OKAY;
>          return rc;
>      }
> 
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 812f880..5b11091 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -392,6 +392,47 @@ static ioreq_t *get_ioreq(struct hvm_ioreq_server
> *s, struct vcpu *v)
>      return &p->vcpu_ioreq[v->vcpu_id];
>  }
> 
> +static vmware_regs_t *get_vmport_regs_one(struct hvm_ioreq_server *s,
> +                                          struct vcpu *v)
> +{
> +    struct hvm_ioreq_vcpu *sv;
> +
> +    list_for_each_entry ( sv,
> +                          &s->ioreq_vcpu_list,
> +                          list_entry )
> +    {
> +        if ( sv->vcpu == v )
> +        {
> +            shared_vmport_iopage_t *p = s->vmport_ioreq.va;
> +            if ( !p )
> +                return NULL;
> +            return &p->vcpu_vmport_regs[v->vcpu_id];
> +        }
> +    }
> +    return NULL;
> +}
> +
> +vmware_regs_t *get_vmport_regs_any(struct hvm_ioreq_server *s, struct
> vcpu *v)
> +{
> +    struct domain *d = v->domain;
> +
> +    ASSERT((v == current) || !vcpu_runnable(v));
> +
> +    if ( s )
> +        return get_vmport_regs_one(s, v);
> +
> +    list_for_each_entry ( s,
> +                          &d->arch.hvm_domain.ioreq_server.list,
> +                          list_entry )
> +    {
> +        vmware_regs_t *ret = get_vmport_regs_one(s, v);
> +
> +        if ( ret )
> +            return ret;
> +    }
> +    return NULL;
> +}
> +
>  bool_t hvm_io_pending(struct vcpu *v)
>  {
>      struct domain *d = v->domain;
> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct domain
> *d, unsigned long gmfn)
>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
>  }
> 
> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t
> buf)
> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int buf)
>  {
> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> +    struct hvm_ioreq_page *iorp = NULL;
> +
> +    switch ( buf )
> +    {
> +    case 0:
> +        iorp = &s->ioreq;
> +        break;
> +    case 1:
> +        iorp = &s->bufioreq;
> +        break;
> +    case 2:
> +        iorp = &s->vmport_ioreq;
> +        break;

Now that buf is no longer a bool, could we have #defined values for the types rather than magic numbers?

> +    }
> +    ASSERT(iorp);
> 
>      destroy_ring_for_helper(&iorp->va, iorp->page);
>  }
> 
>  static int hvm_map_ioreq_page(
> -    struct hvm_ioreq_server *s, bool_t buf, unsigned long gmfn)
> +    struct hvm_ioreq_server *s, int buf, unsigned long gmfn)
>  {
>      struct domain *d = s->domain;
> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> +    struct hvm_ioreq_page *iorp = NULL;
>      struct page_info *page;
>      void *va;
>      int rc;
> 
> +    switch ( buf )
> +    {
> +    case 0:
> +        iorp = &s->ioreq;
> +        break;
> +    case 1:
> +        iorp = &s->bufioreq;
> +        break;
> +    case 2:
> +        iorp = &s->vmport_ioreq;
> +        break;
> +    }
> +    ASSERT(iorp);
> +
>      if ( (rc = prepare_ring_for_helper(d, gmfn, &page, &va)) )
>          return rc;
> 
> @@ -736,6 +805,7 @@ static int hvm_ioreq_server_map_pages(struct
> hvm_ioreq_server *s,
>  {
>      struct domain *d = s->domain;
>      unsigned long ioreq_pfn, bufioreq_pfn;
> +    unsigned long vmport_ioreq_pfn = d-
> >arch.hvm_domain.params[HVM_PARAM_VMPORT_REGS_PFN];
>      int rc;
> 
>      if ( is_default )
> @@ -774,8 +844,16 @@ static int hvm_ioreq_server_map_pages(struct
> hvm_ioreq_server *s,
>              goto fail4;
>      }
> 
> +    rc = hvm_map_ioreq_page(s, 2, vmport_ioreq_pfn);
> +    if ( rc )
> +        goto fail5;
> +
>      return 0;
> 
> +fail5:
> +    if ( handle_bufioreq )
> +        hvm_unmap_ioreq_page(s, 1);
> +
>  fail4:
>      hvm_unmap_ioreq_page(s, 0);
> 
> @@ -796,6 +874,10 @@ static void hvm_ioreq_server_unmap_pages(struct
> hvm_ioreq_server *s,
>  {
>      struct domain *d = s->domain;
>      bool_t handle_bufioreq = ( s->bufioreq.va != NULL );
> +    bool_t handle_vmport_ioreq = ( s->vmport_ioreq.va != NULL );
> +
> +    if ( handle_vmport_ioreq )
> +        hvm_unmap_ioreq_page(s, 2);
> 
>      if ( handle_bufioreq )
>          hvm_unmap_ioreq_page(s, 1);
> @@ -835,12 +917,42 @@ static int hvm_ioreq_server_alloc_rangesets(struct
> hvm_ioreq_server *s,
>      for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
>      {
>          char *name;
> +        char *type_name = NULL;
> +        unsigned int limit;
> 
> -        rc = asprintf(&name, "ioreq_server %d %s", s->id,
> -                      (i == HVMOP_IO_RANGE_PORT) ? "port" :
> -                      (i == HVMOP_IO_RANGE_MEMORY) ? "memory" :
> -                      (i == HVMOP_IO_RANGE_PCI) ? "pci" :
> -                      "");
> +        switch ( i )
> +        {
> +        case HVMOP_IO_RANGE_PORT:
> +            type_name = "port";
> +            limit = MAX_NR_IO_RANGES;
> +            break;
> +        case HVMOP_IO_RANGE_MEMORY:
> +            type_name = "memory";
> +            limit = MAX_NR_IO_RANGES;
> +            break;
> +        case HVMOP_IO_RANGE_PCI:
> +            type_name = "pci";
> +            limit = MAX_NR_IO_RANGES;
> +            break;
> +        case HVMOP_IO_RANGE_VMWARE_PORT:
> +            type_name = "VMware port";
> +            limit = 1;
> +            break;
> +        case HVMOP_IO_RANGE_TIMEOFFSET:
> +            type_name = "timeoffset";
> +            limit = 1;
> +            break;
> +        case HVMOP_IO_RANGE_INVALIDATE:
> +            type_name = "invalidate";
> +            limit = 1;
> +            break;
> +        default:
> +            break;

Thanks for adding the extra types for timeoffset and invalidate, although I don't think the invalidate type is needed. This ioreq is actually broadcast, so there is no selection required.

  Paul

> +        }
> +        if ( !type_name )
> +            continue;
> +
> +        rc = asprintf(&name, "ioreq_server %d %s", s->id, type_name);
>          if ( rc )
>              goto fail;
> 
> @@ -853,7 +965,12 @@ static int hvm_ioreq_server_alloc_rangesets(struct
> hvm_ioreq_server *s,
>          if ( !s->range[i] )
>              goto fail;
> 
> -        rangeset_limit(s->range[i], MAX_NR_IO_RANGES);
> +        rangeset_limit(s->range[i], limit);
> +
> +        /* VMware port */
> +        if ( i == HVMOP_IO_RANGE_VMWARE_PORT &&
> +            s->domain->arch.hvm_domain.is_vmware_port_enabled )
> +            rc = rangeset_add_range(s->range[i], 1, 1);
>      }
> 
>   done:
> @@ -1155,6 +1272,9 @@ static int
> hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
>              case HVMOP_IO_RANGE_PORT:
>              case HVMOP_IO_RANGE_MEMORY:
>              case HVMOP_IO_RANGE_PCI:
> +            case HVMOP_IO_RANGE_VMWARE_PORT:
> +            case HVMOP_IO_RANGE_TIMEOFFSET:
> +            case HVMOP_IO_RANGE_INVALIDATE:
>                  r = s->range[type];
>                  break;
> 
> @@ -1206,6 +1326,9 @@ static int
> hvm_unmap_io_range_from_ioreq_server(struct domain *d, ioservid_t id,
>              case HVMOP_IO_RANGE_PORT:
>              case HVMOP_IO_RANGE_MEMORY:
>              case HVMOP_IO_RANGE_PCI:
> +            case HVMOP_IO_RANGE_VMWARE_PORT:
> +            case HVMOP_IO_RANGE_TIMEOFFSET:
> +            case HVMOP_IO_RANGE_INVALIDATE:
>                  r = s->range[type];
>                  break;
> 
> @@ -2429,9 +2552,6 @@ struct hvm_ioreq_server
> *hvm_select_ioreq_server(struct domain *d,
>      if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
>          return NULL;
> 
> -    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
> -        return d->arch.hvm_domain.default_ioreq_server;
> -
>      cf8 = d->arch.hvm_domain.pci_cf8;
> 
>      if ( p->type == IOREQ_TYPE_PIO &&
> @@ -2474,7 +2594,12 @@ struct hvm_ioreq_server
> *hvm_select_ioreq_server(struct domain *d,
>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG !=
> HVMOP_IO_RANGE_PCI);
> +        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT !=
> HVMOP_IO_RANGE_VMWARE_PORT);
> +        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET !=
> HVMOP_IO_RANGE_TIMEOFFSET);
> +        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE !=
> HVMOP_IO_RANGE_INVALIDATE);
>          r = s->range[type];
> +        if ( !r )
> +            continue;
> 
>          switch ( type )
>          {
> @@ -2501,6 +2626,13 @@ struct hvm_ioreq_server
> *hvm_select_ioreq_server(struct domain *d,
>              }
> 
>              break;
> +        case IOREQ_TYPE_VMWARE_PORT:
> +        case IOREQ_TYPE_TIMEOFFSET:
> +        case IOREQ_TYPE_INVALIDATE:
> +            if ( rangeset_contains_singleton(r, 1) )
> +                return s;
> +
> +            break;
>          }
>      }
> 
> @@ -2662,6 +2794,7 @@ void hvm_complete_assist_req(ioreq_t *p)
>      case IOREQ_TYPE_PCI_CONFIG:
>          ASSERT_UNREACHABLE();
>          break;
> +    case IOREQ_TYPE_VMWARE_PORT:
>      case IOREQ_TYPE_COPY:
>      case IOREQ_TYPE_PIO:
>          if ( p->dir == IOREQ_READ )
> diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
> index 68fb890..2d06956 100644
> --- a/xen/arch/x86/hvm/io.c
> +++ b/xen/arch/x86/hvm/io.c
> @@ -192,6 +192,21 @@ void hvm_io_assist(ioreq_t *p)
>          (void)handle_mmio();
>          break;
>      case HVMIO_handle_pio_awaiting_completion:
> +        if ( p->type == IOREQ_TYPE_VMWARE_PORT )
> +        {
> +            struct cpu_user_regs *regs = guest_cpu_user_regs();
> +            vmware_regs_t *vr = get_vmport_regs_any(NULL, curr);
> +
> +            if ( vr )
> +            {
> +                /* Only change the 32bit part of the register */
> +                regs->_ebx = vr->ebx;
> +                regs->_ecx = vr->ecx;
> +                regs->_edx = vr->edx;
> +                regs->_esi = vr->esi;
> +                regs->_edi = vr->edi;
> +            }
> +        }
>          if ( vio->io_size == 4 ) /* Needs zero extension. */
>              guest_cpu_user_regs()->rax = (uint32_t)p->data;
>          else
> diff --git a/xen/arch/x86/hvm/vmware/vmport.c
> b/xen/arch/x86/hvm/vmware/vmport.c
> index 2e61682..131bafd 100644
> --- a/xen/arch/x86/hvm/vmware/vmport.c
> +++ b/xen/arch/x86/hvm/vmware/vmport.c
> @@ -130,8 +130,8 @@ int vmport_ioport(int dir, uint32_t port, uint32_t
> bytes, uint32_t *val)
>              regs->_ecx = 1000000;
>              break;
>          default:
> -            new_eax = ~0u;
> -            break;
> +            /* Let backing DM handle */
> +            return X86EMUL_VMPORT_SEND;
>          }
>          if ( dir == IOREQ_READ )
>              *val = new_eax;
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h
> b/xen/arch/x86/x86_emulate/x86_emulate.h
> index e8e4413..6bf0176 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
> @@ -112,6 +112,8 @@ struct __packed segment_register {
>  #define X86EMUL_RETRY          3
>   /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller.
> */
>  #define X86EMUL_CMPXCHG_FAILED 3
> + /* Send part of registers also to DM. */
> +#define X86EMUL_VMPORT_SEND    4
> 
>  /* FPU sub-types which may be requested via ->get_fpu(). */
>  enum x86_emulate_fpu_type {
> diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-
> x86/hvm/domain.h
> index ab0e4cf..ad6ec79 100644
> --- a/xen/include/asm-x86/hvm/domain.h
> +++ b/xen/include/asm-x86/hvm/domain.h
> @@ -48,7 +48,7 @@ struct hvm_ioreq_vcpu {
>      evtchn_port_t    ioreq_evtchn;
>  };
> 
> -#define NR_IO_RANGE_TYPES (HVMOP_IO_RANGE_PCI + 1)
> +#define NR_IO_RANGE_TYPES (HVMOP_IO_RANGE_INVALIDATE + 1)
>  #define MAX_NR_IO_RANGES  256
> 
>  struct hvm_ioreq_server {
> @@ -63,6 +63,7 @@ struct hvm_ioreq_server {
>      ioservid_t             id;
>      struct hvm_ioreq_page  ioreq;
>      struct list_head       ioreq_vcpu_list;
> +    struct hvm_ioreq_page  vmport_ioreq;
>      struct hvm_ioreq_page  bufioreq;
> 
>      /* Lock to serialize access to buffered ioreq ring */
> diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-
> x86/hvm/hvm.h
> index 8ecde89..82fe62a 100644
> --- a/xen/include/asm-x86/hvm/hvm.h
> +++ b/xen/include/asm-x86/hvm/hvm.h
> @@ -534,6 +534,8 @@ extern bool_t opt_hvm_fep;
>  #define opt_hvm_fep 0
>  #endif
> 
> +vmware_regs_t *get_vmport_regs_any(struct hvm_ioreq_server *s, struct
> vcpu *v);
> +
>  #endif /* __ASM_X86_HVM_HVM_H__ */
> 
>  /*
> diff --git a/xen/include/public/hvm/hvm_op.h
> b/xen/include/public/hvm/hvm_op.h
> index cde3571..19f8c69 100644
> --- a/xen/include/public/hvm/hvm_op.h
> +++ b/xen/include/public/hvm/hvm_op.h
> @@ -314,6 +314,9 @@
> DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
>   *
>   * NOTE: unless an emulation request falls entirely within a range mapped
>   * by a secondary emulator, it will not be passed to that emulator.
> + *
> + * NOTE: The 'special' range of 1 is what is checked for outside
> + * of the three types of I/O.
>   */
>  #define HVMOP_map_io_range_to_ioreq_server 19
>  #define HVMOP_unmap_io_range_from_ioreq_server 20
> @@ -324,6 +327,9 @@ struct xen_hvm_io_range {
>  # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
>  # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
>  # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
> +# define HVMOP_IO_RANGE_VMWARE_PORT 3 /* VMware port special
> range */
> +# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range
> */
> +# define HVMOP_IO_RANGE_INVALIDATE 8 /* INVALIDATE special range */
>      uint64_aligned_t start, end; /* IN - inclusive start and end of range */
>  };
>  typedef struct xen_hvm_io_range xen_hvm_io_range_t;
> diff --git a/xen/include/public/hvm/ioreq.h
> b/xen/include/public/hvm/ioreq.h
> index 5b5fedf..6d5ca06 100644
> --- a/xen/include/public/hvm/ioreq.h
> +++ b/xen/include/public/hvm/ioreq.h
> @@ -35,6 +35,7 @@
>  #define IOREQ_TYPE_PIO          0 /* pio */
>  #define IOREQ_TYPE_COPY         1 /* mmio ops */
>  #define IOREQ_TYPE_PCI_CONFIG   2
> +#define IOREQ_TYPE_VMWARE_PORT  3
>  #define IOREQ_TYPE_TIMEOFFSET   7
>  #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
> 
> @@ -48,6 +49,8 @@
>   *
>   * 63....48|47..40|39..35|34..32|31........0
>   * SEGMENT |BUS   |DEV   |FN    |OFFSET
> + *
> + * For I/O type IOREQ_TYPE_VMWARE_PORT also use the vmware_regs.
>   */
>  struct ioreq {
>      uint64_t addr;          /* physical address */
> @@ -66,11 +69,25 @@ struct ioreq {
>  };
>  typedef struct ioreq ioreq_t;
> 
> +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_iopage {
>      struct ioreq vcpu_ioreq[1];
>  };
>  typedef struct shared_iopage shared_iopage_t;
> 
> +struct shared_vmport_iopage {
> +    struct vmware_regs vcpu_vmport_regs[1];
> +};
> +typedef struct shared_vmport_iopage shared_vmport_iopage_t;
> +
>  struct buf_ioreq {
>      uint8_t  type;   /* I/O type                    */
>      uint8_t  pad:1;
> diff --git a/xen/include/public/hvm/params.h
> b/xen/include/public/hvm/params.h
> index 974d3a4..2f6ccf4 100644
> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -50,6 +50,8 @@
>  #define HVM_PARAM_PAE_ENABLED  4
> 
>  #define HVM_PARAM_IOREQ_PFN    5
> +/* Extra vmport PFN. */
> +#define HVM_PARAM_VMPORT_REGS_PFN 36
> 
>  #define HVM_PARAM_BUFIOREQ_PFN 6
>  #define HVM_PARAM_BUFIOREQ_EVTCHN 26
> @@ -197,6 +199,6 @@
>  /* emulated VMware Hardware Version */
>  #define HVM_PARAM_VMWARE_HWVER 35
> 
> -#define HVM_NR_PARAMS          36
> +#define HVM_NR_PARAMS          37
> 
>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
> --
> 1.8.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 05/13] xen: Add vmware_port support
  2015-02-16 23:05 ` [PATCH v9 05/13] xen: Add vmware_port support Don Slutz
@ 2015-02-17 10:30   ` Andrew Cooper
  2015-02-18  2:18     ` Don Slutz
  2015-02-23 15:05   ` Jan Beulich
  1 sibling, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 10:30 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, 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.
>
> 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
>
> Some of the best info is at:
>
> https://sites.google.com/site/chitchatvmback/backdoor
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v9:
>   Switch to x86_emulator to handle #GP code moved to next patch.
>     Can you explain why a HVM param isn't suitable here?
>       Issue with changing QEMU on the fly.
>       Andrew Cooper: My recommendation is still to use a creation flag
>         So no change.
>     Please move SVM's identical definition into ...
>       Did this as #1.  No longer needed, but since the patch was ready
>       I have included it.
>     --Lots of questions about code that no long is part of this patch. --
>     With this, is handling other than 32-bit in/out really
>     meaningful/correct?
>       Added comment about this.
>     Since you can't get here for PV, I can't see what you need this.
>       Changed to an ASSERT.
>     Why version 4?
>       Added comment about this.
>     -- Several questions about register changes.
>       Re-coded to use new_eax and set *val to this.
>       Change to generealy use reg->_e..
>     These ei1/ei2 checks belong in the callers imo -
>       Moved.
>     the "port" function parameter isn't even checked
>       Add check for exact match.
>     If dropping the code is safe without also forbidding the
>     combination of nested and VMware emulation.
>       Added the forbidding the combination of nested and VMware.
>       Mostly do to the cases of the nested virtual code is the one
>       to handle VMware stuff if needed, not the root one.  Also I am
>       having issues testing xen nested in xen and using hvm.
>
> v7:
>       More on AMD in the commit message.
>       Switch to only change 32bit part of registers, what VMware
>         does.
>     Too much logging and tracing.
>       Dropped a lot of it.  This includes vmport_debug=
>
> v6:
>       Dropped the attempt to use svm_nextrip_insn_length via
>       __get_instruction_length (added in v2).  Just always look
>       at upto 15 bytes on AMD.
>
> v5:
>       we should make sure that svm_vmexit_gp_intercept is not executed for
>       any other guest.
>         Added an ASSERT on is_vmware_port_enabled.
>       magic integers?
>         Added #define for them.
>       I am fairly certain that you need some brackets here.
>         Added brackets.
>
>  xen/arch/x86/domain.c            |   2 +
>  xen/arch/x86/hvm/hvm.c           |  10 +++
>  xen/arch/x86/hvm/vmware/Makefile |   1 +
>  xen/arch/x86/hvm/vmware/vmport.c | 142 +++++++++++++++++++++++++++++++++++++++
>  xen/common/domctl.c              |   3 +
>  xen/include/asm-x86/hvm/domain.h |   3 +
>  xen/include/asm-x86/hvm/vmport.h |  32 +++++++++
>  xen/include/public/domctl.h      |   3 +
>  xen/include/xen/sched.h          |   3 +
>  9 files changed, 199 insertions(+)
>  create mode 100644 xen/arch/x86/hvm/vmware/vmport.c
>  create mode 100644 xen/include/asm-x86/hvm/vmport.h
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index cfe7945..fe45f11 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -518,6 +518,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);
>  
>      INIT_LIST_HEAD(&d->arch.pdev_list);
>  
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index fefd023..812f880 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -61,6 +61,7 @@
>  #include <asm/hvm/trace.h>
>  #include <asm/hvm/nestedhvm.h>
>  #include <asm/hvm/vmware.h>
> +#include <asm/hvm/vmport.h>
>  #include <asm/mtrr.h>
>  #include <asm/apic.h>
>  #include <public/sched.h>
> @@ -1484,6 +1485,9 @@ int hvm_domain_initialise(struct domain *d)
>          goto fail1;
>      d->arch.hvm_domain.io_handler->num_slot = 0;
>  
> +    if ( d->arch.hvm_domain.is_vmware_port_enabled )
> +        vmport_register(d);
> +
>      if ( is_pvh_domain(d) )
>      {
>          register_portio_handler(d, 0, 0x10003, handle_pvh_io);
> @@ -5859,6 +5863,12 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>                      break;
>                  if ( a.value > 1 )
>                      rc = -EINVAL;
> +                /* Prevent nestedhvm with vmport */
> +                if ( d->arch.hvm_domain.is_vmware_port_enabled )
> +                {
> +                    rc = -EINVAL;

Probably better as EOPNOTSUPP, as it is a configuration problem.

> +                    break;
> +                }
>                  /* Remove the check below once we have
>                   * shadow-on-shadow.
>                   */
> diff --git a/xen/arch/x86/hvm/vmware/Makefile b/xen/arch/x86/hvm/vmware/Makefile
> index 3fb2e0b..cd8815b 100644
> --- a/xen/arch/x86/hvm/vmware/Makefile
> +++ b/xen/arch/x86/hvm/vmware/Makefile
> @@ -1 +1,2 @@
>  obj-y += cpuid.o
> +obj-y += vmport.o
> diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
> new file mode 100644
> index 0000000..3d9f30e
> --- /dev/null
> +++ b/xen/arch/x86/hvm/vmware/vmport.c
> @@ -0,0 +1,142 @@
> +/*
> + * 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/lib.h>
> +#include <asm/hvm/hvm.h>
> +#include <asm/hvm/support.h>
> +#include <asm/hvm/vmport.h>
> +
> +#include "backdoor_def.h"
> +
> +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)

This function looks as if it should be static.

> +{
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +
> +    /*
> +     * While VMware expects only 32-bit in, they do support using
> +     * other sizes and out.  However they do require only the 1 port
> +     * and the correct value in eax.  Since some of the data
> +     * returned in eax is smaller the 32 bits and/or you only need
> +     * the other registers the dir and bytes do not need any
> +     * checking.  The caller will handle the bytes, and dir is
> +     * handled below.
> +     */
> +    if ( port == BDOOR_PORT && regs->_eax == BDOOR_MAGIC )
> +    {
> +        uint32_t new_eax = BDOOR_MAGIC;
> +        uint64_t value;
> +        struct vcpu *curr = current;
> +        struct domain *d = curr->domain;
> +
> +        switch ( regs->_ecx & 0xffff )
> +        {
> +        case BDOOR_CMD_GETMHZ:
> +            new_eax = d->arch.tsc_khz / 1000;
> +            break;
> +        case BDOOR_CMD_GETVERSION:
> +            /* MAGIC */
> +            regs->_ebx = BDOOR_MAGIC;
> +            /* VERSION_MAGIC */
> +            new_eax = 6;
> +            /* Claim we are an ESX. VMX_TYPE_SCALABLE_SERVER */
> +            regs->_ecx = 2;
> +            break;
> +        case BDOOR_CMD_GETSCREENSIZE:
> +            /* We have no screen size */
> +            new_eax = ~0u;
> +            break;
> +        case BDOOR_CMD_GETHWVERSION:
> +            /* vmware_hw */
> +            ASSERT(is_hvm_vcpu(curr));
> +            {
> +                struct hvm_domain *hd = &d->arch.hvm_domain;
> +
> +                new_eax = hd->params[HVM_PARAM_VMWARE_HWVER];
> +            }
> +            /*
> +             * Returning zero is not the best.  VMware was not at
> +             * all consistent in the handling of this command until
> +             * VMware hardware version 4.  So it is better to claim
> +             * 4 then 0.  This should only happen in strange configs.
> +             */
> +            if ( !new_eax )
> +                new_eax = 4;
> +            break;
> +        case BDOOR_CMD_GETHZ:
> +        {
> +            struct segment_register sreg;
> +
> +            hvm_get_segment_register(curr, x86_seg_ss, &sreg);
> +            if ( sreg.attr.fields.dpl == 0 )
> +            {

Why is GETHZ the only one of these with a CPL check?

> +                value = d->arch.tsc_khz * 1000;
> +                /* apic-frequency (bus speed) */
> +                regs->_ecx = 1000000000ULL / APIC_BUS_CYCLE_NS;
> +                /* High part of tsc-frequency */
> +                regs->_ebx = value >> 32;
> +                /* Low part of tsc-frequency */
> +                new_eax = value;
> +            }
> +            break;
> +        }
> +        case BDOOR_CMD_GETTIME:
> +            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
> +            /* hostUsecs */
> +            regs->_ebx = value % 1000000UL;
> +            /* hostSecs */
> +            new_eax = value / 1000000ULL;
> +            /* maxTimeLag */
> +            regs->_ecx = 1000000;
> +            /* offset to GMT in minutes */
> +            regs->_edx = d->time_offset_seconds / 60;
> +            break;
> +        case BDOOR_CMD_GETTIMEFULL:
> +            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
> +            /* hostUsecs */
> +            regs->_ebx = value % 1000000UL;
> +            /* hostSecs low 32 bits */
> +            regs->_edx = value / 1000000ULL;
> +            /* hostSecs high 32 bits */
> +            regs->_esi = (value / 1000000ULL) >> 32;
> +            /* maxTimeLag */
> +            regs->_ecx = 1000000;
> +            break;
> +        default:
> +            new_eax = ~0u;
> +            break;
> +        }
> +        if ( dir == IOREQ_READ )
> +            *val = new_eax;
> +    }
> +    else if ( dir == IOREQ_READ )
> +        *val = ~0u;
> +
> +    return X86EMUL_OKAY;
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-set-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 452f3d9..e242c2d 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -543,6 +543,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>               ~(XEN_DOMCTL_CDF_hvm_guest
>                 | XEN_DOMCTL_CDF_pvh_guest
>                 | XEN_DOMCTL_CDF_hap
> +               | XEN_DOMCTL_CDF_vmware_port
>                 | XEN_DOMCTL_CDF_s3_integrity
>                 | XEN_DOMCTL_CDF_oos_off)) )
>              break;
> @@ -586,6 +587,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>              domcr_flags |= DOMCRF_s3_integrity;
>          if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off )
>              domcr_flags |= DOMCRF_oos_off;
> +        if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_vmware_port )
> +            domcr_flags |= DOMCRF_vmware_port;
>  
>          d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
>          if ( IS_ERR(d) )
> diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
> index 0702bf5..ab0e4cf 100644
> --- a/xen/include/asm-x86/hvm/domain.h
> +++ b/xen/include/asm-x86/hvm/domain.h
> @@ -122,6 +122,9 @@ struct hvm_domain {
>      spinlock_t             uc_lock;
>      bool_t                 is_in_uc_mode;
>  
> +    /* VMware backdoor port available */
> +    bool_t                 is_vmware_port_enabled;
> +
>      /* Pass-through */
>      struct hvm_iommu       hvm_iommu;
>  
> diff --git a/xen/include/asm-x86/hvm/vmport.h b/xen/include/asm-x86/hvm/vmport.h
> new file mode 100644
> index 0000000..eb3e472
> --- /dev/null
> +++ b/xen/include/asm-x86/hvm/vmport.h
> @@ -0,0 +1,32 @@
> +/*
> + * asm/hvm/vmport.h: 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/>.
> + */
> +
> +#ifndef ASM_X86_HVM_VMPORT_H__
> +#define ASM_X86_HVM_VMPORT_H__
> +
> +void vmport_register(struct domain *d);

I would suggest putting this declaration in hvm.h and forging vmport.h
entirely

~Andrew

> +int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val);
> +
> +#endif /* ASM_X86_HVM_VMPORT_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
> index b3413a2..28fa767 100644
> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -63,6 +63,9 @@ struct xen_domctl_createdomain {
>   /* Is this a PVH guest (as opposed to an HVM or PV guest)? */
>  #define _XEN_DOMCTL_CDF_pvh_guest     4
>  #define XEN_DOMCTL_CDF_pvh_guest      (1U<<_XEN_DOMCTL_CDF_pvh_guest)
> + /* Is VMware backdoor port available? */
> +#define _XEN_DOMCTL_CDF_vmware_port   5
> +#define XEN_DOMCTL_CDF_vmware_port    (1U<<_XEN_DOMCTL_CDF_vmware_port)
>      uint32_t flags;
>  };
>  typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index ccd7ed8..48bb001 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -546,6 +546,9 @@ struct domain *domain_create(
>   /* DOMCRF_pvh: Create PV domain in HVM container. */
>  #define _DOMCRF_pvh             5
>  #define DOMCRF_pvh              (1U<<_DOMCRF_pvh)
> + /* DOMCRF_vmware_port: Enable use of vmware backdoor port. */
> +#define _DOMCRF_vmware_port     6
> +#define DOMCRF_vmware_port      (1U<<_DOMCRF_vmware_port)
>  
>  /*
>   * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-16 23:05 ` [PATCH v9 09/13] Add xentrace to vmware_port Don Slutz
@ 2015-02-17 13:45   ` Andrew Cooper
  2015-02-17 18:22     ` Don Slutz
  2015-02-23 16:57   ` Jan Beulich
  2015-03-03 14:27   ` Ian Campbell
  2 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 13:45 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> Also added missing TRAP_DEBUG & VLAPIC.
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>

This patch doesn't actually add any trace points.

> ---
> v9:
>   Dropped unneed VMPORT_UNHANDLED, VMPORT_DECODE.
>
> v7:
>       Dropped some of the new traces.
>       Added HVMTRACE_ND7.
>
> v6:
>       Dropped the attempt to use svm_nextrip_insn_length via
>       __get_instruction_length (added in v2).  Just always look
>       at upto 15 bytes on AMD.
>
> v5:
>       exitinfo1 is used twice.
>         Fixed.
>
>  tools/xentrace/formats           |  5 +++++
>  xen/arch/x86/hvm/vmware/vmport.c |  4 +++-
>  xen/include/asm-x86/hvm/trace.h  | 22 ++++++++++++++++++++++
>  xen/include/public/trace.h       |  3 +++
>  4 files changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/tools/xentrace/formats b/tools/xentrace/formats
> index 5d7b72a..eec65f4 100644
> --- a/tools/xentrace/formats
> +++ b/tools/xentrace/formats
> @@ -79,6 +79,11 @@
>  0x00082020  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INTR_WINDOW [ value = 0x%(1)08x ]
>  0x00082021  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  NPF         [ gpa = 0x%(2)08x%(1)08x mfn = 0x%(4)08x%(3)08x qual = 0x%(5)04x p2mt = 0x%(6)04x ]
>  0x00082023  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  TRAP        [ vector = 0x%(1)02x ]
> +0x00082024  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  TRAP_DEBUG  [ exit_qualification = 0x%(1)08x ]
> +0x00082025  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VLAPIC
> +0x00082026  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_HANDLED   [ cmd = %(1)d eax = 0x%(2)08x ebx = 0x%(3)08x ecx = 0x%(4)08x edx = 0x%(5)08x esi = 0x%(6)08x edi = 0x%(7)08x ]
> +0x00082027  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_IGNORED   [ port = %(1)d eax = 0x%(2)08x ebx = 0x%(3)08x ecx = 0x%(4)08x edx = 0x%(5)08x esi = 0x%(6)08x edi = 0x%(7)08x ]
> +0x00082028  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_QEMU      [ eax = 0x%(1)08x ebx = 0x%(2)08x ecx = 0x%(3)08x edx = 0x%(4)08x esi = 0x%(5)08x edi = 0x%(6)08x ]
>  
>  0x0010f001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_map      [ domid = %(1)d ]
>  0x0010f002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_unmap    [ domid = %(1)d ]
> diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
> index 131bafd..fb191a2 100644
> --- a/xen/arch/x86/hvm/vmware/vmport.c
> +++ b/xen/arch/x86/hvm/vmware/vmport.c
> @@ -17,6 +17,7 @@
>  #include <asm/hvm/hvm.h>
>  #include <asm/hvm/support.h>
>  #include <asm/hvm/vmport.h>
> +#include <asm/hvm/trace.h>
>  
>  #include "backdoor_def.h"
>  
> @@ -55,8 +56,9 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
>          uint64_t value;
>          struct vcpu *curr = current;
>          struct domain *d = curr->domain;
> +        uint16_t cmd = regs->_ecx;
>  
> -        switch ( regs->_ecx & 0xffff )
> +        switch ( cmd )

This hunk really looks like it belongs in patch 5.

~Andrew

>          {
>          case BDOOR_CMD_GETMHZ:
>              new_eax = d->arch.tsc_khz / 1000;
> diff --git a/xen/include/asm-x86/hvm/trace.h b/xen/include/asm-x86/hvm/trace.h
> index de802a6..0ad805f 100644
> --- a/xen/include/asm-x86/hvm/trace.h
> +++ b/xen/include/asm-x86/hvm/trace.h
> @@ -54,6 +54,9 @@
>  #define DO_TRC_HVM_TRAP             DEFAULT_HVM_MISC
>  #define DO_TRC_HVM_TRAP_DEBUG       DEFAULT_HVM_MISC
>  #define DO_TRC_HVM_VLAPIC           DEFAULT_HVM_MISC
> +#define DO_TRC_HVM_VMPORT_HANDLED   DEFAULT_HVM_IO
> +#define DO_TRC_HVM_VMPORT_IGNORED   DEFAULT_HVM_IO
> +#define DO_TRC_HVM_VMPORT_QEMU      DEFAULT_HVM_IO
>  
>  
>  #define TRC_PAR_LONG(par) ((par)&0xFFFFFFFF),((par)>>32)
> @@ -83,6 +86,25 @@
>          }                                                                 \
>      } while(0)
>  
> +#define HVMTRACE_ND7(evt, modifier, cycles, count, d1, d2, d3, d4, d5, d6, d7) \
> +    do {                                                                  \
> +        if ( unlikely(tb_init_done) && DO_TRC_HVM_ ## evt )               \
> +        {                                                                 \
> +            struct {                                                      \
> +                u32 d[7];                                                 \
> +            } _d;                                                         \
> +            _d.d[0]=(d1);                                                 \
> +            _d.d[1]=(d2);                                                 \
> +            _d.d[2]=(d3);                                                 \
> +            _d.d[3]=(d4);                                                 \
> +            _d.d[4]=(d5);                                                 \
> +            _d.d[5]=(d6);                                                 \
> +            _d.d[6]=(d7);                                                 \
> +            __trace_var(TRC_HVM_ ## evt | (modifier), cycles,             \
> +                        sizeof(*_d.d) * count, &_d);                      \
> +        }                                                                 \
> +    } while(0)
> +
>  #define HVMTRACE_6D(evt, d1, d2, d3, d4, d5, d6)    \
>      HVMTRACE_ND(evt, 0, 0, 6, d1, d2, d3, d4, d5, d6)
>  #define HVMTRACE_5D(evt, d1, d2, d3, d4, d5)        \
> diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h
> index 5211ae7..16b87f9 100644
> --- a/xen/include/public/trace.h
> +++ b/xen/include/public/trace.h
> @@ -227,6 +227,9 @@
>  #define TRC_HVM_TRAP             (TRC_HVM_HANDLER + 0x23)
>  #define TRC_HVM_TRAP_DEBUG       (TRC_HVM_HANDLER + 0x24)
>  #define TRC_HVM_VLAPIC           (TRC_HVM_HANDLER + 0x25)
> +#define TRC_HVM_VMPORT_HANDLED   (TRC_HVM_HANDLER + 0x26)
> +#define TRC_HVM_VMPORT_IGNORED   (TRC_HVM_HANDLER + 0x27)
> +#define TRC_HVM_VMPORT_QEMU      (TRC_HVM_HANDLER + 0x28)
>  
>  #define TRC_HVM_IOPORT_WRITE    (TRC_HVM_HANDLER + 0x216)
>  #define TRC_HVM_IOMEM_WRITE     (TRC_HVM_HANDLER + 0x217)

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param
  2015-02-16 23:05 ` [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param Don Slutz
@ 2015-02-17 14:11   ` Andrew Cooper
  2015-02-18  2:51     ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 14:11 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> A tool to get and set hvm param.
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>

I had completely forgotten that you did a tool like this before.

Here is one I implemented myself,

https://github.com/xenserver/xen-4.5.pg/commit/ec99115818abd1a98f04d5fae2481803ad21db2a

I was specifically trying to make an extendible tool to avoid the
currently state of having $N single-purpose tools, and hopefully
replacing some of the other tools in a more consistent fashion.  e.g.
xen-hvmcrash will only crash an hvm domain, but could very easily be
made to do the same to a PV domain (even using the same hypercalls I
believe, now that some PVH relaxing has occurred).

I have half an extension to this tool which will allow you to dump
various PV rings in the guest, and would like to see about merging
xen-hvmctx and xenctx together into this tool.

Thoughts?

~Andrew

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-16 23:05 ` [PATCH v9 06/13] xen: Add ring 3 " Don Slutz
@ 2015-02-17 14:38   ` Andrew Cooper
  2015-02-18 17:03     ` Don Slutz
  2015-02-23 15:12   ` Jan Beulich
  1 sibling, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 14:38 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> 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.
>
> 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.
>
> The support included is enough to allow VMware tools to install in a
> HVM domU.
>
> Enable no-fault of pio in x86_emulate for VMware port
>
> Also adjust the emulation registers after doing a VMware
> backdoor operation.
>
> Add new routine hvm_emulate_one_gp() to be used by the #GP fault
> handler.
>
> Some of the best info is at:
>
> https://sites.google.com/site/chitchatvmback/backdoor
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>
> ---
> v9:
>    Split #GP handling (or skipping of #GP) code out of previous
>    patch to help with the review process.
>    Switch to x86_emulator to handle #GP
>    I think the hvm_emulate_ops_gp() covers all needed ops.  Not able to validate
>    all paths though _hvm_emulate_one().
>
>  xen/arch/x86/hvm/emulate.c             | 62 ++++++++++++++++++++++++++++++++--
>  xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
>  xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
>  xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
>  xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
>  xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
>  xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
>  xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
>  xen/include/asm-x86/hvm/emulate.h      |  2 ++
>  xen/include/asm-x86/hvm/vmport.h       |  1 +
>  10 files changed, 172 insertions(+), 6 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index 636c909..a6a6a5c 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -22,6 +22,7 @@
>  #include <asm/hvm/trace.h>
>  #include <asm/hvm/support.h>
>  #include <asm/hvm/svm/svm.h>
> +#include <asm/hvm/vmport.h>
>  
>  static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>  {
> @@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
>      unsigned long *val,
>      struct x86_emulate_ctxt *ctxt)
>  {
> +    ctxt->do_vmport = 0;

This looks horribly invasive.

Why are emulation changes needed?  What is wrong with the normal
handling with a registered ioport handler?

~Andrew

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t
  2015-02-16 23:05 ` [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t Don Slutz
@ 2015-02-17 14:44   ` Andrew Cooper
  2015-02-17 22:46     ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 14:44 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> This is needed by me to build this test
>
> Signed-off-by: Don Slutz <dslutz@verizon.com>

That is because you broke it with patch 6 by introducing do_vmport.

~Andrew

> ---
>  tools/tests/x86_emulator/test_x86_emulator.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
> index 6f67fc7..03cd0e8 100644
> --- a/tools/tests/x86_emulator/test_x86_emulator.c
> +++ b/tools/tests/x86_emulator/test_x86_emulator.c
> @@ -9,6 +9,8 @@
>  
>  #define __packed __attribute__((packed))
>  
> +typedef bool bool_t;
> +
>  #include "x86_emulate/x86_emulate.h"
>  #include "blowfish.h"
>  

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 11/13] test_x86_emulator.c: Add emacs block
  2015-02-16 23:05 ` [PATCH v9 11/13] test_x86_emulator.c: Add emacs block Don Slutz
@ 2015-02-17 14:52   ` Andrew Cooper
  2015-03-03 14:28     ` Ian Campbell
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 14:52 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 16/02/15 23:05, Don Slutz wrote:
> Signed-off-by: Don Slutz <dslutz@verizon.com>

Acked-by: Andrew Cooper <andew.cooper@citrix.com>

(Presuming an acceptable extension of maintainership into this area.  It
does after all symlink its way into xen/arch/x86)

> ---
>  tools/tests/x86_emulator/test_x86_emulator.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
> index 03cd0e8..02a9f0a 100644
> --- a/tools/tests/x86_emulator/test_x86_emulator.c
> +++ b/tools/tests/x86_emulator/test_x86_emulator.c
> @@ -936,3 +936,12 @@ int main(int argc, char **argv)
>      printf("failed!\n");
>      return 1;
>  }
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 02/13] xen: Add support for VMware cpuid leaves
  2015-02-17 10:02   ` Andrew Cooper
@ 2015-02-17 15:57     ` Jan Beulich
  2015-02-17 15:59       ` Andrew Cooper
  0 siblings, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-17 15:57 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, KeirFraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Eddie Dong, Ian Jackson,
	Don Slutz, xen-devel, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 17.02.15 at 11:02, <andrew.cooper3@citrix.com> wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> --- a/xen/include/asm-x86/hvm/hvm.h
>> +++ b/xen/include/asm-x86/hvm/hvm.h
>> @@ -356,6 +356,13 @@ static inline unsigned long hvm_get_shadow_gs_base(struct vcpu *v)
>>  #define has_viridian_time_ref_count(d) \
>>      (is_viridian_domain(d) && (viridian_feature_mask(d) & HVMPV_time_ref_count))
>>  
>> +#define vmware_feature_mask(d) \
>> +    (has_hvm_params(d) ? \
>> +     (d)->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] : 0)
> 
> I can't spot any use of this vmware_feature_mask().  Is it stale?

No, it is being used ...

> Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> 
>> +
>> +#define is_vmware_domain(d) \
>> +    (is_hvm_domain(d) && vmware_feature_mask(d))

... here.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 02/13] xen: Add support for VMware cpuid leaves
  2015-02-17 15:57     ` Jan Beulich
@ 2015-02-17 15:59       ` Andrew Cooper
  0 siblings, 0 replies; 71+ messages in thread
From: Andrew Cooper @ 2015-02-17 15:59 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, KeirFraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Eddie Dong, Ian Jackson,
	Don Slutz, xen-devel, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 17/02/15 15:57, Jan Beulich wrote:
>>>> On 17.02.15 at 11:02, <andrew.cooper3@citrix.com> wrote:
>> On 16/02/15 23:05, Don Slutz wrote:
>>> --- a/xen/include/asm-x86/hvm/hvm.h
>>> +++ b/xen/include/asm-x86/hvm/hvm.h
>>> @@ -356,6 +356,13 @@ static inline unsigned long hvm_get_shadow_gs_base(struct vcpu *v)
>>>  #define has_viridian_time_ref_count(d) \
>>>      (is_viridian_domain(d) && (viridian_feature_mask(d) & HVMPV_time_ref_count))
>>>  
>>> +#define vmware_feature_mask(d) \
>>> +    (has_hvm_params(d) ? \
>>> +     (d)->arch.hvm_domain.params[HVM_PARAM_VMWARE_HWVER] : 0)
>> I can't spot any use of this vmware_feature_mask().  Is it stale?
> No, it is being used ...
>
>> Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>
>>> +
>>> +#define is_vmware_domain(d) \
>>> +    (is_hvm_domain(d) && vmware_feature_mask(d))
> ... here.
>
> Jan
>

So it is.  I am clearly blind.

~Andrew

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-17 13:45   ` Andrew Cooper
@ 2015-02-17 18:22     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-17 18:22 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/17/15 08:45, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> Also added missing TRAP_DEBUG & VLAPIC.
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> 
> This patch doesn't actually add any trace points.
> 

Sigh.  They got lost in rebaseing.  Will recover and add to v10.

Here is just the trace parts:

diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 2d06956..752eeb8 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -205,6 +205,9 @@ void hvm_io_assist(ioreq_t *p)
                 regs->_edx = vr->edx;
                 regs->_esi = vr->esi;
                 regs->_edi = vr->edi;
+                HVMTRACE_ND(VMPORT_QEMU, 0, 1/*cycles*/, 6,
+                            p->data, regs->_ebx, regs->_ecx,
+                            regs->_edx, regs->_esi, regs->_edi);
             }
         }
         if ( vio->io_size == 4 ) /* Needs zero extension. */

diff --git a/xen/arch/x86/hvm/vmware/vmport.c
b/xen/arch/x86/hvm/vmware/vmport.c
index 131bafd..de44893 100644
--- a/xen/arch/x86/hvm/vmware/vmport.c
+++ b/xen/arch/x86/hvm/vmware/vmport.c
...

@@ -133,11 +135,20 @@ int vmport_ioport(int dir, uint32_t port, uint32_t
bytes, uint32_t *val)
             /* Let backing DM handle */
             return X86EMUL_VMPORT_SEND;
         }
+        HVMTRACE_ND7(VMPORT_HANDLED, 0, 0/*cycles*/, 7,
+                     cmd, new_eax, regs->_ebx, regs->_ecx,
+                     regs->_edx, regs->_esi, regs->_edi);
         if ( dir == IOREQ_READ )
             *val = new_eax;
     }
-    else if ( dir == IOREQ_READ )
-        *val = ~0u;
+    else
+    {
+        HVMTRACE_ND7(VMPORT_IGNORED, 0, 0/*cycles*/, 7,
+                     port, regs->_eax, regs->_ebx, regs->_ecx,
+                     regs->_edx, regs->_esi, regs->_edi);
+        if ( dir == IOREQ_READ )
+            *val = ~0u;
+    }

     return X86EMUL_OKAY;
 }


>> ---
>> v9:
>>   Dropped unneed VMPORT_UNHANDLED, VMPORT_DECODE.
>>
...
>> diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
>> index 131bafd..fb191a2 100644
>> --- a/xen/arch/x86/hvm/vmware/vmport.c
>> +++ b/xen/arch/x86/hvm/vmware/vmport.c
>> @@ -17,6 +17,7 @@
>>  #include <asm/hvm/hvm.h>
>>  #include <asm/hvm/support.h>
>>  #include <asm/hvm/vmport.h>
>> +#include <asm/hvm/trace.h>
>>  
>>  #include "backdoor_def.h"
>>  
>> @@ -55,8 +56,9 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
>>          uint64_t value;
>>          struct vcpu *curr = current;
>>          struct domain *d = curr->domain;
>> +        uint16_t cmd = regs->_ecx;
>>  
>> -        switch ( regs->_ecx & 0xffff )
>> +        switch ( cmd )
> 
> This hunk really looks like it belongs in patch 5.
> 

That my be, but in patch 5, there is only 1 use of cmd and Jan Beulich
said to drop them.  This patch adds a 2nd use:

+        HVMTRACE_ND7(VMPORT_HANDLED, 0, 0/*cycles*/, 7,
+                     cmd, new_eax, regs->_ebx, regs->_ecx,
+                     regs->_edx, regs->_esi, regs->_edi);

(which was accidentally dropped).

   -Don Slutz

> ~Andrew
> 
>>          {
>>          case BDOOR_CMD_GETMHZ:
>>              new_eax = d->arch.tsc_khz / 1000;
>> diff --git a/xen/include/asm-x86/hvm/trace.h b/xen/include/asm-x86/hvm/trace.h
>> index de802a6..0ad805f 100644
>> --- a/xen/include/asm-x86/hvm/trace.h
>> +++ b/xen/include/asm-x86/hvm/trace.h
>> @@ -54,6 +54,9 @@
>>  #define DO_TRC_HVM_TRAP             DEFAULT_HVM_MISC
>>  #define DO_TRC_HVM_TRAP_DEBUG       DEFAULT_HVM_MISC
>>  #define DO_TRC_HVM_VLAPIC           DEFAULT_HVM_MISC
>> +#define DO_TRC_HVM_VMPORT_HANDLED   DEFAULT_HVM_IO
>> +#define DO_TRC_HVM_VMPORT_IGNORED   DEFAULT_HVM_IO
>> +#define DO_TRC_HVM_VMPORT_QEMU      DEFAULT_HVM_IO
>>  
>>  
>>  #define TRC_PAR_LONG(par) ((par)&0xFFFFFFFF),((par)>>32)
>> @@ -83,6 +86,25 @@
>>          }                                                                 \
>>      } while(0)
>>  
>> +#define HVMTRACE_ND7(evt, modifier, cycles, count, d1, d2, d3, d4, d5, d6, d7) \
>> +    do {                                                                  \
>> +        if ( unlikely(tb_init_done) && DO_TRC_HVM_ ## evt )               \
>> +        {                                                                 \
>> +            struct {                                                      \
>> +                u32 d[7];                                                 \
>> +            } _d;                                                         \
>> +            _d.d[0]=(d1);                                                 \
>> +            _d.d[1]=(d2);                                                 \
>> +            _d.d[2]=(d3);                                                 \
>> +            _d.d[3]=(d4);                                                 \
>> +            _d.d[4]=(d5);                                                 \
>> +            _d.d[5]=(d6);                                                 \
>> +            _d.d[6]=(d7);                                                 \
>> +            __trace_var(TRC_HVM_ ## evt | (modifier), cycles,             \
>> +                        sizeof(*_d.d) * count, &_d);                      \
>> +        }                                                                 \
>> +    } while(0)
>> +
>>  #define HVMTRACE_6D(evt, d1, d2, d3, d4, d5, d6)    \
>>      HVMTRACE_ND(evt, 0, 0, 6, d1, d2, d3, d4, d5, d6)
>>  #define HVMTRACE_5D(evt, d1, d2, d3, d4, d5)        \
>> diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h
>> index 5211ae7..16b87f9 100644
>> --- a/xen/include/public/trace.h
>> +++ b/xen/include/public/trace.h
>> @@ -227,6 +227,9 @@
>>  #define TRC_HVM_TRAP             (TRC_HVM_HANDLER + 0x23)
>>  #define TRC_HVM_TRAP_DEBUG       (TRC_HVM_HANDLER + 0x24)
>>  #define TRC_HVM_VLAPIC           (TRC_HVM_HANDLER + 0x25)
>> +#define TRC_HVM_VMPORT_HANDLED   (TRC_HVM_HANDLER + 0x26)
>> +#define TRC_HVM_VMPORT_IGNORED   (TRC_HVM_HANDLER + 0x27)
>> +#define TRC_HVM_VMPORT_QEMU      (TRC_HVM_HANDLER + 0x28)
>>  
>>  #define TRC_HVM_IOPORT_WRITE    (TRC_HVM_HANDLER + 0x216)
>>  #define TRC_HVM_IOMEM_WRITE     (TRC_HVM_HANDLER + 0x217)
> 

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h
  2015-02-17  9:52   ` Andrew Cooper
@ 2015-02-17 21:31     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-17 21:31 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/17/15 04:52, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> Change some hard coded 15 into MAX_INST_LEN
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> 
> One formatting suggestion.
> 
>> ---
...
>> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
>> index f13f07d..42e2588 100644
>> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
>> @@ -579,8 +579,8 @@ do{ asm volatile (                                                      \
>>  ({ unsigned long _x = 0, _eip = _regs.eip;                              \
>>     if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
>>     _regs.eip += (_size); /* real hardware doesn't truncate */           \
>> -   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
>> -                         EXC_GP, 0);                                    \
>> +   generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) >       \
>> +			 MAX_INST_LEN, EXC_GP, 0);                       \
> 
> This would probably be better with the uint8_t cast on starting on the
> next line, which would avoid the need to put a linebreak in the middle
> of the comparison.
> 

If I am parsing this correctly, you feel that:

   generate_exception_if(                                               \
           (uint8_t)(_regs.eip - ctxt->regs->eip) > MAX_INST_LEN,       \
           EXC_GP, 0);                                                  \
   rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \

is the way to go.  I will plan to change it this way for v10 unless
otherwise notified.

    -Don Slutz

> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t
  2015-02-17 14:44   ` Andrew Cooper
@ 2015-02-17 22:46     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-17 22:46 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/17/15 09:44, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> This is needed by me to build this test
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> 
> That is because you broke it with patch 6 by introducing do_vmport.
> 

Sigh.  Fixed it in patch #6...  This patch will disappear in v10.

   -Don Slutz

> ~Andrew
> 
>> ---
>>  tools/tests/x86_emulator/test_x86_emulator.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
>> index 6f67fc7..03cd0e8 100644
>> --- a/tools/tests/x86_emulator/test_x86_emulator.c
>> +++ b/tools/tests/x86_emulator/test_x86_emulator.c
>> @@ -9,6 +9,8 @@
>>  
>>  #define __packed __attribute__((packed))
>>  
>> +typedef bool bool_t;
>> +
>>  #include "x86_emulate/x86_emulate.h"
>>  #include "blowfish.h"
>>  
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 05/13] xen: Add vmware_port support
  2015-02-17 10:30   ` Andrew Cooper
@ 2015-02-18  2:18     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-18  2:18 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/17/15 05:30, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> This includes adding is_vmware_port_enabled

...

>> @@ -5859,6 +5863,12 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>>                      break;
>>                  if ( a.value > 1 )
>>                      rc = -EINVAL;
>> +                /* Prevent nestedhvm with vmport */
>> +                if ( d->arch.hvm_domain.is_vmware_port_enabled )
>> +                {
>> +                    rc = -EINVAL;
> 
> Probably better as EOPNOTSUPP, as it is a configuration problem.
> 

Will change.

>> +                    break;
>> +                }

>> +int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
> 
> This function looks as if it should be static.
> 

Yes, will fix.

>> +{

>> +        case BDOOR_CMD_GETHZ:
>> +        {
>> +            struct segment_register sreg;
>> +
>> +            hvm_get_segment_register(curr, x86_seg_ss, &sreg);
>> +            if ( sreg.attr.fields.dpl == 0 )
>> +            {
> 
> Why is GETHZ the only one of these with a CPL check?

Testing on an ESX server, this is the only one that checks.

Looking at (which also contains backdoor_def.h):

https://github.com/vmware/open-vm-tools.git

It lists some that check for CPL 0:


don-760:~/gits/open-vm-tools>grep "CPL0"
open-vm-tools/lib/include/backdoor_def.h
#define   BDOOR_CMD_APMFUNCTION               2 /* CPL0 only. */
#define   BDOOR_CMD_OSNOTFOUND               18 /* CPL0 only. */
don-760:~/gits/open-vm-tools>grep "CPL 0"
open-vm-tools/lib/include/backdoor_def.h
#define   BDOOR_CMD_INITPCIOPROM             28 /* CPL 0 only. */
#define   BDOOR_CMD_PATCH_SMBIOS_STRUCTS     37 /* CPL 0 only. */
#define   BDOOR_CMD_PATCH_ACPI_TABLES        43 /* CPL 0 only. */
#define   BDOOR_CMD_CHECKFORCEBIOSSETUP      48 /* CPL 0 only. */
#define   BDOOR_CMD_LAZYTIMEREMULATION       49 /* CPL 0 only. */
#define   BDOOR_CMD_BIOSBBS                  50 /* CPL 0 only. */
#define   BDOOR_CMD_OSNOTMACOSXSERVER        54 /* CPL 0 only. */
#define   BDOOR_CMD_XPMODE                   62 /* CPL 0 only. */
#define   BDOOR_CMD_FIRMWARE_INIT            64 /* CPL 0 only. */
#define   BDOOR_CMD_FIRMWARE_ACPI_SERVICES   65 /* CPL 0 only. */
#define   BDOOR_CMD_EFI_SERIALCON_CONFIG     69 /* CPL 0 only. */
#define   BDOOR_CMD_BUG328986                70 /* CPL 0 only. */
#define   BDOOR_CMD_FIRMWARE_ERROR           71 /* CPL 0 only. */
#define   BDOOR_CMD_EFI_BOOT_CONFIG          73 /* CPL 0 only. */
#define   BDOOR_CMD_GET_HW_MODEL             74 /* CPL 0 only. */
#define   BDOOR_CMD_GET_SVGA_CAPABILITIES    75 /* CPL 0 only. */
#define   BDOOR_CMD_GET_FORCE_X2APIC         76 /* CPL 0 only  */
#define   BDOOR_CMD_SET_PCI_HOLE             77 /* CPL 0 only  */
#define   BDOOR_CMD_GET_PCI_HOLE             78 /* CPL 0 only  */
#define   BDOOR_CMD_GET_PCI_BAR              79 /* CPL 0 only  */
#define   BDOOR_CMD_SHOULD_GENERATE_SYSTEMID 80 /* CPL 0 only  */

but not this one:


don-760:~/gits/open-vm-tools>git grep BDOOR_CMD_GETHZ|cat
open-vm-tools/lib/include/backdoor_def.h:#define   BDOOR_CMD_GETHZ
              45

The file I am using in patch #4 is older, and is missing these
comments.

>From https://sites.google.com/site/chitchatvmback/backdoor#cmd12h
...

(*) On WS4.5/GSX3.2 and later this command works only when the virtual
processor is in privileged mode, such as is real mode DOS and OS kernel.
The command is actually implemented also in WS4.0 but is restricted to
work only in the context of virtual machine BIOS and practically
unavailable in the guest OS. On WS3.x/GSX2.5 it works without restriction.

So some of the comments are right.


>> +                value = d->arch.tsc_khz * 1000;

>> diff --git a/xen/include/asm-x86/hvm/vmport.h b/xen/include/asm-x86/hvm/vmport.h
>> new file mode 100644
>> index 0000000..eb3e472
>> --- /dev/null
>> +++ b/xen/include/asm-x86/hvm/vmport.h
>> @@ -0,0 +1,32 @@
>> +/*
>> + * asm/hvm/vmport.h: 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/>.
>> + */
>> +
>> +#ifndef ASM_X86_HVM_VMPORT_H__
>> +#define ASM_X86_HVM_VMPORT_H__
>> +
>> +void vmport_register(struct domain *d);
> 
> I would suggest putting this declaration in hvm.h and forging vmport.h
> entirely
> 

Ok,

       -Don Slutz

> ~Andrew
> 
>> +int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val);
>> +
>> +#endif /* ASM_X86_HVM_VMPORT_H__ */
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
>> index b3413a2..28fa767 100644
>> --- a/xen/include/public/domctl.h
>> +++ b/xen/include/public/domctl.h
>> @@ -63,6 +63,9 @@ struct xen_domctl_createdomain {
>>   /* Is this a PVH guest (as opposed to an HVM or PV guest)? */
>>  #define _XEN_DOMCTL_CDF_pvh_guest     4
>>  #define XEN_DOMCTL_CDF_pvh_guest      (1U<<_XEN_DOMCTL_CDF_pvh_guest)
>> + /* Is VMware backdoor port available? */
>> +#define _XEN_DOMCTL_CDF_vmware_port   5
>> +#define XEN_DOMCTL_CDF_vmware_port    (1U<<_XEN_DOMCTL_CDF_vmware_port)
>>      uint32_t flags;
>>  };
>>  typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
>> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
>> index ccd7ed8..48bb001 100644
>> --- a/xen/include/xen/sched.h
>> +++ b/xen/include/xen/sched.h
>> @@ -546,6 +546,9 @@ struct domain *domain_create(
>>   /* DOMCRF_pvh: Create PV domain in HVM container. */
>>  #define _DOMCRF_pvh             5
>>  #define DOMCRF_pvh              (1U<<_DOMCRF_pvh)
>> + /* DOMCRF_vmware_port: Enable use of vmware backdoor port. */
>> +#define _DOMCRF_vmware_port     6
>> +#define DOMCRF_vmware_port      (1U<<_DOMCRF_vmware_port)
>>  
>>  /*
>>   * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
> 
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-17 10:08   ` Paul Durrant
@ 2015-02-18  2:44     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-18  2:44 UTC (permalink / raw)
  To: Paul Durrant, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir (Xen.org), Ian Campbell, Tim (Xen.org),
	Eddie Dong, George Dunlap, Jan Beulich, Stefano Stabellini,
	Aravind Gopalakrishnan, Jun Nakajima, Andrew Cooper, Ian Jackson,
	Boris Ostrovsky, Suravee Suthikulpanit

On 02/17/15 05:08, Paul Durrant wrote:
>> -----Original Message-----
>> From: xen-devel-bounces@lists.xen.org [mailto:xen-devel-
>> bounces@lists.xen.org] On Behalf Of Don Slutz
>> Sent: 16 February 2015 23:05


>> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t
>> buf)
>> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int buf)
>>  {
>> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>> +    struct hvm_ioreq_page *iorp = NULL;
>> +
>> +    switch ( buf )
>> +    {
>> +    case 0:
>> +        iorp = &s->ioreq;
>> +        break;
>> +    case 1:
>> +        iorp = &s->bufioreq;
>> +        break;
>> +    case 2:
>> +        iorp = &s->vmport_ioreq;
>> +        break;
> 
> Now that buf is no longer a bool, could we have #defined values for the types rather than magic numbers?
> 

Sure.

>> +    }
>> +    ASSERT(iorp);
>>
>>      destroy_ring_for_helper(&iorp->va, iorp->page);
>>  }

...

>> +        case HVMOP_IO_RANGE_VMWARE_PORT:
>> +            type_name = "VMware port";
>> +            limit = 1;
>> +            break;
>> +        case HVMOP_IO_RANGE_TIMEOFFSET:
>> +            type_name = "timeoffset";
>> +            limit = 1;
>> +            break;
>> +        case HVMOP_IO_RANGE_INVALIDATE:
>> +            type_name = "invalidate";
>> +            limit = 1;
>> +            break;
>> +        default:
>> +            break;
> 
> Thanks for adding the extra types for timeoffset and
> invalidate, although I don't think the invalidate type is
> needed. This ioreq is actually broadcast, so there is no
> selection required.
> 

Ok, will drop the invalidate one.

   -Don Slutz

>   Paul

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param
  2015-02-17 14:11   ` Andrew Cooper
@ 2015-02-18  2:51     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-18  2:51 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/17/15 09:11, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> A tool to get and set hvm param.
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> 
> I had completely forgotten that you did a tool like this before.
> 
> Here is one I implemented myself,
> 
> https://github.com/xenserver/xen-4.5.pg/commit/ec99115818abd1a98f04d5fae2481803ad21db2a
> 
> I was specifically trying to make an extendible tool to avoid the
> currently state of having $N single-purpose tools, and hopefully
> replacing some of the other tools in a more consistent fashion.  e.g.
> xen-hvmcrash will only crash an hvm domain, but could very easily be
> made to do the same to a PV domain (even using the same hypercalls I
> believe, now that some PVH relaxing has occurred).
> 

Having looked at xen-hvmcrash, I am still having questions about when it
would make sense to use.  I would think a pause, dump-core would give a
better info to look at.

> I have half an extension to this tool which will allow you to dump
> various PV rings in the guest, and would like to see about merging
> xen-hvmctx and xenctx together into this tool.
> 

The merging of xen-hvmctx and xenctx is complex.  I do not see that
happening quickly.

> Thoughts?
> 

I combined tool does look good.

These are just the quick thoughts.  May have more later.

   -Don Slutz

> ~Andrew
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-17 14:38   ` Andrew Cooper
@ 2015-02-18 17:03     ` Don Slutz
  2015-02-18 18:19       ` Andrew Cooper
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-18 17:03 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/17/15 09:38, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
>> 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.
>>
>> 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.
>>
>> The support included is enough to allow VMware tools to install in a
>> HVM domU.
>>
>> Enable no-fault of pio in x86_emulate for VMware port
>>
>> Also adjust the emulation registers after doing a VMware
>> backdoor operation.
>>
>> Add new routine hvm_emulate_one_gp() to be used by the #GP fault
>> handler.
>>
>> Some of the best info is at:
>>
>> https://sites.google.com/site/chitchatvmback/backdoor
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>> ---
>> v9:
>>    Split #GP handling (or skipping of #GP) code out of previous
>>    patch to help with the review process.
>>    Switch to x86_emulator to handle #GP
>>    I think the hvm_emulate_ops_gp() covers all needed ops.  Not able to validate
>>    all paths though _hvm_emulate_one().
>>
>>  xen/arch/x86/hvm/emulate.c             | 62 ++++++++++++++++++++++++++++++++--
>>  xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
>>  xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
>>  xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
>>  xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
>>  xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
>>  xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
>>  xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
>>  xen/include/asm-x86/hvm/emulate.h      |  2 ++
>>  xen/include/asm-x86/hvm/vmport.h       |  1 +
>>  10 files changed, 172 insertions(+), 6 deletions(-)
>>
>> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
>> index 636c909..a6a6a5c 100644
>> --- a/xen/arch/x86/hvm/emulate.c
>> +++ b/xen/arch/x86/hvm/emulate.c
>> @@ -22,6 +22,7 @@
>>  #include <asm/hvm/trace.h>
>>  #include <asm/hvm/support.h>
>>  #include <asm/hvm/svm/svm.h>
>> +#include <asm/hvm/vmport.h>
>>
>>  static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>>  {
>> @@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
>>      unsigned long *val,
>>      struct x86_emulate_ctxt *ctxt)
>>  {
>> +    ctxt->do_vmport = 0;
>
> This looks horribly invasive.
>
> Why are emulation changes needed?  What is wrong with the normal
> handling with a registered ioport handler?

Because VMware made a bad way to provide a "hyper call".  They decided to
allow user access to this.  So when a #GP fault should have been 
reported, they instead do the "hyper call".


 From older thread:

Message-ID: <540F5376.6020803@oracle.com>
Date: Tue, 9 Sep 2014 15:22:30 -0400
From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
User-Agent: Mozilla/5.0 (X11; Linux x86_64;
	rv:24.0) Gecko/20100101 Thunderbird/24.2.0
To: Don Slutz <dslutz@verizon.com>, Ian Campbell <Ian.Campbell@citrix.com>
References: <1409585629-25840-1-git-send-email-dslutz@verizon.com>		 
<1409585629-25840-4-git-send-email-dslutz@verizon.com>	 
<1410183310.3680.28.camel@kazak.uk.xensource.com>	 
<540DDFFB.2090504@terremark.com> 
<1410255363.8217.62.camel@kazak.uk.xensource.com>
	<540F3967.5060001@terremark.com>
In-Reply-To: <540F3967.5060001@terremark.com>

...

On 09/09/2014 01:31 PM, Don Slutz wrote:
 > On 09/09/14 05:36, Ian Campbell wrote:
 >> On Mon, 2014-09-08 at 12:57 -0400, Don Slutz wrote:
 >>>>> Also this instruction is allowed to be used from ring 3.  To
 >>>>> support this the vmexit for GP needs to be enabled.
 >>>> Isn't that quite costly?
 >>> Yes.  But since that is how VMware does it, I need to do the same slow
 >>> thing.
 >> Sounds from other subthreads like there might be other better ways? It's
 >> hard to believe that vmware is really trapping every #GP.
 >
 > I have not found a better way.  The simplest statement I have come
 > up with is that this is not a pass thru of the VMware device.  Or the
 > statement (in AMD land): Generate an IOIO #VMEXIT not a GP
 > #VMWEXIT for ioport <x> (or all ports).


    -Don Slutz


> ~Andrew
>

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-18 17:03     ` Don Slutz
@ 2015-02-18 18:19       ` Andrew Cooper
  2015-02-21 13:36         ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-18 18:19 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 18/02/15 17:03, Don Slutz wrote:
> On 02/17/15 09:38, Andrew Cooper wrote:
>> On 16/02/15 23:05, Don Slutz wrote:
>>> 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.
>>>
>>> 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.
>>>
>>> The support included is enough to allow VMware tools to install in a
>>> HVM domU.
>>>
>>> Enable no-fault of pio in x86_emulate for VMware port
>>>
>>> Also adjust the emulation registers after doing a VMware
>>> backdoor operation.
>>>
>>> Add new routine hvm_emulate_one_gp() to be used by the #GP fault
>>> handler.
>>>
>>> Some of the best info is at:
>>>
>>> https://sites.google.com/site/chitchatvmback/backdoor
>>>
>>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>>> ---
>>> v9:
>>>    Split #GP handling (or skipping of #GP) code out of previous
>>>    patch to help with the review process.
>>>    Switch to x86_emulator to handle #GP
>>>    I think the hvm_emulate_ops_gp() covers all needed ops.  Not able
>>> to validate
>>>    all paths though _hvm_emulate_one().
>>>
>>>  xen/arch/x86/hvm/emulate.c             | 62
>>> ++++++++++++++++++++++++++++++++--
>>>  xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
>>>  xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
>>>  xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
>>>  xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
>>>  xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
>>>  xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
>>>  xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
>>>  xen/include/asm-x86/hvm/emulate.h      |  2 ++
>>>  xen/include/asm-x86/hvm/vmport.h       |  1 +
>>>  10 files changed, 172 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
>>> index 636c909..a6a6a5c 100644
>>> --- a/xen/arch/x86/hvm/emulate.c
>>> +++ b/xen/arch/x86/hvm/emulate.c
>>> @@ -22,6 +22,7 @@
>>>  #include <asm/hvm/trace.h>
>>>  #include <asm/hvm/support.h>
>>>  #include <asm/hvm/svm/svm.h>
>>> +#include <asm/hvm/vmport.h>
>>>
>>>  static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>>>  {
>>> @@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
>>>      unsigned long *val,
>>>      struct x86_emulate_ctxt *ctxt)
>>>  {
>>> +    ctxt->do_vmport = 0;
>>
>> This looks horribly invasive.
>>
>> Why are emulation changes needed?  What is wrong with the normal
>> handling with a registered ioport handler?
>
> Because VMware made a bad way to provide a "hyper call".  They decided to
> allow user access to this.  So when a #GP fault should have been
> reported, they instead do the "hyper call".
>

Urgh - now I remember.

Right.  In the case that vmport is active, we start intercepting #GP
faults and emulating access.  That part of the patch looks ok.

However, the rest is very invasive to the emulation infrastructure.

Something along the lines of:

diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 5e9e040..dd40d6a 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3394,7 +3394,8 @@ static int inject_swint(enum x86_swint_type type,
                              ? insn_fetch_type(uint8_t)
                              : (uint16_t)_regs.edx);
         op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
-        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
+        if ( ((rc = ioport_access_check(port, op_bytes, ctxt, ops)) !=
0) ||
+             (ops->vmport_check && ((rc = ops->vmport_check(port,
ctxt)) != 0)) )
             goto done;
         if ( b & 2 )
         {

would be far less invasive and AFAICT, replace the entire rest of your
patch.

In this case, if ioport_access_check() succeeds, or if it fails and
vmport_check subsequently succeeds, the standard ioport dispatch will
run, and hit vmport_ioport().

~Andrew

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-18 18:19       ` Andrew Cooper
@ 2015-02-21 13:36         ` Don Slutz
  2015-02-21 15:40           ` Andrew Cooper
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-21 13:36 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/18/15 13:19, Andrew Cooper wrote:
> On 18/02/15 17:03, Don Slutz wrote:
>> On 02/17/15 09:38, Andrew Cooper wrote:
>>> On 16/02/15 23:05, Don Slutz wrote:
>>>> 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.
>>>>
>>>> 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.
>>>>
>>>> The support included is enough to allow VMware tools to install in a
>>>> HVM domU.
>>>>
>>>> Enable no-fault of pio in x86_emulate for VMware port
>>>>
>>>> Also adjust the emulation registers after doing a VMware
>>>> backdoor operation.
>>>>
>>>> Add new routine hvm_emulate_one_gp() to be used by the #GP fault
>>>> handler.
>>>>
>>>> Some of the best info is at:
>>>>
>>>> https://sites.google.com/site/chitchatvmback/backdoor
>>>>
>>>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>>>> ---
>>>> v9:
>>>>    Split #GP handling (or skipping of #GP) code out of previous
>>>>    patch to help with the review process.
>>>>    Switch to x86_emulator to handle #GP
>>>>    I think the hvm_emulate_ops_gp() covers all needed ops.  Not able
>>>> to validate
>>>>    all paths though _hvm_emulate_one().
>>>>
>>>>  xen/arch/x86/hvm/emulate.c             | 62
>>>> ++++++++++++++++++++++++++++++++--
>>>>  xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
>>>>  xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
>>>>  xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
>>>>  xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
>>>>  xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
>>>>  xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
>>>>  xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
>>>>  xen/include/asm-x86/hvm/emulate.h      |  2 ++
>>>>  xen/include/asm-x86/hvm/vmport.h       |  1 +
>>>>  10 files changed, 172 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
>>>> index 636c909..a6a6a5c 100644
>>>> --- a/xen/arch/x86/hvm/emulate.c
>>>> +++ b/xen/arch/x86/hvm/emulate.c
>>>> @@ -22,6 +22,7 @@
>>>>  #include <asm/hvm/trace.h>
>>>>  #include <asm/hvm/support.h>
>>>>  #include <asm/hvm/svm/svm.h>
>>>> +#include <asm/hvm/vmport.h>
>>>>
>>>>  static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>>>>  {
>>>> @@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
>>>>      unsigned long *val,
>>>>      struct x86_emulate_ctxt *ctxt)
>>>>  {
>>>> +    ctxt->do_vmport = 0;
>>>
>>> This looks horribly invasive.
>>>
>>> Why are emulation changes needed?  What is wrong with the normal
>>> handling with a registered ioport handler?
>>
>> Because VMware made a bad way to provide a "hyper call".  They decided to
>> allow user access to this.  So when a #GP fault should have been
>> reported, they instead do the "hyper call".
>>
> 
> Urgh - now I remember.
> 
> Right.  In the case that vmport is active, we start intercepting #GP
> faults and emulating access.  That part of the patch looks ok.
> 
> However, the rest is very invasive to the emulation infrastructure.
> 
> Something along the lines of:
> 
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
> b/xen/arch/x86/x86_emulate/x86_emulate.c
> index 5e9e040..dd40d6a 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -3394,7 +3394,8 @@ static int inject_swint(enum x86_swint_type type,
>                               ? insn_fetch_type(uint8_t)
>                               : (uint16_t)_regs.edx);
>          op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
> -        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
> +        if ( ((rc = ioport_access_check(port, op_bytes, ctxt, ops)) !=
> 0) ||
> +             (ops->vmport_check && ((rc = ops->vmport_check(port,
> ctxt)) != 0)) )
>              goto done;
>          if ( b & 2 )
>          {
> 
> would be far less invasive and AFAICT, replace the entire rest of your
> patch.
> 
> In this case, if ioport_access_check() succeeds, or if it fails and
> vmport_check subsequently succeeds, the standard ioport dispatch will
> run, and hit vmport_ioport().
> 

Yes, but since vmport_ioport changes guest_cpu_user_regs() which
are different then _regs and get modified by:

    *ctxt->regs = _regs;
 done:
    return rc;

which will drop all changes to other registers by vmport_ioport.  This
is why I added the flag do_vmport. Which must be set in all case where
vmport_ioport is called via x86_emulate.

So I could call on it 1st.  This would make the change smaller.

   -Don Slutz



> ~Andrew
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-21 13:36         ` Don Slutz
@ 2015-02-21 15:40           ` Andrew Cooper
  2015-02-21 16:06             ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-02-21 15:40 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 21/02/15 13:36, Don Slutz wrote:
> On 02/18/15 13:19, Andrew Cooper wrote:
>> On 18/02/15 17:03, Don Slutz wrote:
>>> On 02/17/15 09:38, Andrew Cooper wrote:
>>>> On 16/02/15 23:05, Don Slutz wrote:
>>>>> 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.
>>>>>
>>>>> 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.
>>>>>
>>>>> The support included is enough to allow VMware tools to install in a
>>>>> HVM domU.
>>>>>
>>>>> Enable no-fault of pio in x86_emulate for VMware port
>>>>>
>>>>> Also adjust the emulation registers after doing a VMware
>>>>> backdoor operation.
>>>>>
>>>>> Add new routine hvm_emulate_one_gp() to be used by the #GP fault
>>>>> handler.
>>>>>
>>>>> Some of the best info is at:
>>>>>
>>>>> https://sites.google.com/site/chitchatvmback/backdoor
>>>>>
>>>>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>>>>> ---
>>>>> v9:
>>>>>    Split #GP handling (or skipping of #GP) code out of previous
>>>>>    patch to help with the review process.
>>>>>    Switch to x86_emulator to handle #GP
>>>>>    I think the hvm_emulate_ops_gp() covers all needed ops.  Not able
>>>>> to validate
>>>>>    all paths though _hvm_emulate_one().
>>>>>
>>>>>  xen/arch/x86/hvm/emulate.c             | 62
>>>>> ++++++++++++++++++++++++++++++++--
>>>>>  xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
>>>>>  xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
>>>>>  xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
>>>>>  xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
>>>>>  xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
>>>>>  xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
>>>>>  xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
>>>>>  xen/include/asm-x86/hvm/emulate.h      |  2 ++
>>>>>  xen/include/asm-x86/hvm/vmport.h       |  1 +
>>>>>  10 files changed, 172 insertions(+), 6 deletions(-)
>>>>>
>>>>> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
>>>>> index 636c909..a6a6a5c 100644
>>>>> --- a/xen/arch/x86/hvm/emulate.c
>>>>> +++ b/xen/arch/x86/hvm/emulate.c
>>>>> @@ -22,6 +22,7 @@
>>>>>  #include <asm/hvm/trace.h>
>>>>>  #include <asm/hvm/support.h>
>>>>>  #include <asm/hvm/svm/svm.h>
>>>>> +#include <asm/hvm/vmport.h>
>>>>>
>>>>>  static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>>>>>  {
>>>>> @@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
>>>>>      unsigned long *val,
>>>>>      struct x86_emulate_ctxt *ctxt)
>>>>>  {
>>>>> +    ctxt->do_vmport = 0;
>>>> This looks horribly invasive.
>>>>
>>>> Why are emulation changes needed?  What is wrong with the normal
>>>> handling with a registered ioport handler?
>>> Because VMware made a bad way to provide a "hyper call".  They decided to
>>> allow user access to this.  So when a #GP fault should have been
>>> reported, they instead do the "hyper call".
>>>
>> Urgh - now I remember.
>>
>> Right.  In the case that vmport is active, we start intercepting #GP
>> faults and emulating access.  That part of the patch looks ok.
>>
>> However, the rest is very invasive to the emulation infrastructure.
>>
>> Something along the lines of:
>>
>> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
>> b/xen/arch/x86/x86_emulate/x86_emulate.c
>> index 5e9e040..dd40d6a 100644
>> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
>> @@ -3394,7 +3394,8 @@ static int inject_swint(enum x86_swint_type type,
>>                               ? insn_fetch_type(uint8_t)
>>                               : (uint16_t)_regs.edx);
>>          op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
>> -        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
>> +        if ( ((rc = ioport_access_check(port, op_bytes, ctxt, ops)) !=
>> 0) ||
>> +             (ops->vmport_check && ((rc = ops->vmport_check(port,
>> ctxt)) != 0)) )
>>              goto done;
>>          if ( b & 2 )
>>          {
>>
>> would be far less invasive and AFAICT, replace the entire rest of your
>> patch.
>>
>> In this case, if ioport_access_check() succeeds, or if it fails and
>> vmport_check subsequently succeeds, the standard ioport dispatch will
>> run, and hit vmport_ioport().
>>
> Yes, but since vmport_ioport changes guest_cpu_user_regs() which
> are different then _regs and get modified by:
>
>     *ctxt->regs = _regs;
>  done:
>     return rc;
>
> which will drop all changes to other registers by vmport_ioport.  This
> is why I added the flag do_vmport. Which must be set in all case where
> vmport_ioport is called via x86_emulate.
>
> So I could call on it 1st.  This would make the change smaller.
>
>    -Don Slutz
>

How about this then?

diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 5e9e040..2aea91c 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3393,8 +3393,11 @@ static int inject_swint(enum x86_swint_type type,
         unsigned int port = ((b < 0xe8)
                              ? insn_fetch_type(uint8_t)
                              : (uint16_t)_regs.edx);
+        bool_t vmport = (ops->vmport_check && /* Vmware backdoor? */
+                         (ops->vmport_check(port, ctxt) == 0));
         op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
-        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
+        if ( !vmport &&
+             (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
             goto done;
         if ( b & 2 )
         {
@@ -3413,6 +3416,10 @@ static int inject_swint(enum x86_swint_type type,
         }
         if ( rc != 0 )
             goto done;
+        if ( vmport )
+        {
+            /* fill _regs */
+        }
         break;
     }
 

~Andrew

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-21 15:40           ` Andrew Cooper
@ 2015-02-21 16:06             ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-21 16:06 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan, George Dunlap,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 02/21/15 10:40, Andrew Cooper wrote:
> On 21/02/15 13:36, Don Slutz wrote:
>> On 02/18/15 13:19, Andrew Cooper wrote:
>>> On 18/02/15 17:03, Don Slutz wrote:
>>>> On 02/17/15 09:38, Andrew Cooper wrote:
>>>>> On 16/02/15 23:05, Don Slutz wrote:
>>>>>> 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.
>>>>>>
>>>>>> 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.
>>>>>>
>>>>>> The support included is enough to allow VMware tools to install in a
>>>>>> HVM domU.
>>>>>>
>>>>>> Enable no-fault of pio in x86_emulate for VMware port
>>>>>>
>>>>>> Also adjust the emulation registers after doing a VMware
>>>>>> backdoor operation.
>>>>>>
>>>>>> Add new routine hvm_emulate_one_gp() to be used by the #GP fault
>>>>>> handler.
>>>>>>
>>>>>> Some of the best info is at:
>>>>>>
>>>>>> https://sites.google.com/site/chitchatvmback/backdoor
>>>>>>
>>>>>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>>>>>> ---
>>>>>> v9:
>>>>>>    Split #GP handling (or skipping of #GP) code out of previous
>>>>>>    patch to help with the review process.
>>>>>>    Switch to x86_emulator to handle #GP
>>>>>>    I think the hvm_emulate_ops_gp() covers all needed ops.  Not able
>>>>>> to validate
>>>>>>    all paths though _hvm_emulate_one().
>>>>>>
>>>>>>  xen/arch/x86/hvm/emulate.c             | 62
>>>>>> ++++++++++++++++++++++++++++++++--
>>>>>>  xen/arch/x86/hvm/svm/svm.c             | 27 +++++++++++++++
>>>>>>  xen/arch/x86/hvm/svm/vmcb.c            |  2 ++
>>>>>>  xen/arch/x86/hvm/vmware/vmport.c       | 11 ++++++
>>>>>>  xen/arch/x86/hvm/vmx/vmcs.c            |  2 ++
>>>>>>  xen/arch/x86/hvm/vmx/vmx.c             | 38 +++++++++++++++++++++
>>>>>>  xen/arch/x86/x86_emulate/x86_emulate.c | 25 +++++++++++---
>>>>>>  xen/arch/x86/x86_emulate/x86_emulate.h |  8 +++++
>>>>>>  xen/include/asm-x86/hvm/emulate.h      |  2 ++
>>>>>>  xen/include/asm-x86/hvm/vmport.h       |  1 +
>>>>>>  10 files changed, 172 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
>>>>>> index 636c909..a6a6a5c 100644
>>>>>> --- a/xen/arch/x86/hvm/emulate.c
>>>>>> +++ b/xen/arch/x86/hvm/emulate.c
>>>>>> @@ -22,6 +22,7 @@
>>>>>>  #include <asm/hvm/trace.h>
>>>>>>  #include <asm/hvm/support.h>
>>>>>>  #include <asm/hvm/svm/svm.h>
>>>>>> +#include <asm/hvm/vmport.h>
>>>>>>
>>>>>>  static void hvmtrace_io_assist(int is_mmio, ioreq_t *p)
>>>>>>  {
>>>>>> @@ -776,6 +777,7 @@ static int hvmemul_read_io_discard(
>>>>>>      unsigned long *val,
>>>>>>      struct x86_emulate_ctxt *ctxt)
>>>>>>  {
>>>>>> +    ctxt->do_vmport = 0;
>>>>> This looks horribly invasive.
>>>>>
>>>>> Why are emulation changes needed?  What is wrong with the normal
>>>>> handling with a registered ioport handler?
>>>> Because VMware made a bad way to provide a "hyper call".  They decided to
>>>> allow user access to this.  So when a #GP fault should have been
>>>> reported, they instead do the "hyper call".
>>>>
>>> Urgh - now I remember.
>>>
>>> Right.  In the case that vmport is active, we start intercepting #GP
>>> faults and emulating access.  That part of the patch looks ok.
>>>
>>> However, the rest is very invasive to the emulation infrastructure.
>>>
>>> Something along the lines of:
>>>
>>> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
>>> b/xen/arch/x86/x86_emulate/x86_emulate.c
>>> index 5e9e040..dd40d6a 100644
>>> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
>>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
>>> @@ -3394,7 +3394,8 @@ static int inject_swint(enum x86_swint_type type,
>>>                               ? insn_fetch_type(uint8_t)
>>>                               : (uint16_t)_regs.edx);
>>>          op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
>>> -        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
>>> +        if ( ((rc = ioport_access_check(port, op_bytes, ctxt, ops)) !=
>>> 0) ||
>>> +             (ops->vmport_check && ((rc = ops->vmport_check(port,
>>> ctxt)) != 0)) )
>>>              goto done;
>>>          if ( b & 2 )
>>>          {
>>>
>>> would be far less invasive and AFAICT, replace the entire rest of your
>>> patch.
>>>
>>> In this case, if ioport_access_check() succeeds, or if it fails and
>>> vmport_check subsequently succeeds, the standard ioport dispatch will
>>> run, and hit vmport_ioport().
>>>
>> Yes, but since vmport_ioport changes guest_cpu_user_regs() which
>> are different then _regs and get modified by:
>>
>>     *ctxt->regs = _regs;
>>  done:
>>     return rc;
>>
>> which will drop all changes to other registers by vmport_ioport.  This
>> is why I added the flag do_vmport. Which must be set in all case where
>> vmport_ioport is called via x86_emulate.
>>
>> So I could call on it 1st.  This would make the change smaller.
>>
>>    -Don Slutz
>>
> 
> How about this then?
> 
> diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
> b/xen/arch/x86/x86_emulate/x86_emulate.c
> index 5e9e040..2aea91c 100644
> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -3393,8 +3393,11 @@ static int inject_swint(enum x86_swint_type type,
>          unsigned int port = ((b < 0xe8)
>                               ? insn_fetch_type(uint8_t)
>                               : (uint16_t)_regs.edx);
> +        bool_t vmport = (ops->vmport_check && /* Vmware backdoor? */
> +                         (ops->vmport_check(port, ctxt) == 0));
>          op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
> -        if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
> +        if ( !vmport &&
> +             (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
>              goto done;
>          if ( b & 2 )
>          {
> @@ -3413,6 +3416,10 @@ static int inject_swint(enum x86_swint_type type,
>          }
>          if ( rc != 0 )
>              goto done;
> +        if ( vmport )
> +        {
> +            /* fill _regs */
> +        }
>          break;
>      }
>  

It looks ok.  Will test.

   -Don Slutz


> ~Andrew
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 05/13] xen: Add vmware_port support
  2015-02-16 23:05 ` [PATCH v9 05/13] xen: Add vmware_port support Don Slutz
  2015-02-17 10:30   ` Andrew Cooper
@ 2015-02-23 15:05   ` Jan Beulich
  2015-02-23 16:03     ` Don Slutz
  1 sibling, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-23 15:05 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 17.02.15 at 00:05, <dslutz@verizon.com> 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.

As indicated before, I don't think this is a good use case for a
domain creation flag. Some of the others we have may not be either,
but as I have said quite often recently - let's not make the situation
worse by following bad examples.

> --- /dev/null
> +++ b/xen/arch/x86/hvm/vmware/vmport.c
> @@ -0,0 +1,142 @@
> +/*
> + * 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/lib.h>
> +#include <asm/hvm/hvm.h>
> +#include <asm/hvm/support.h>
> +#include <asm/hvm/vmport.h>
> +
> +#include "backdoor_def.h"
> +
> +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)

static

> +{
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +
> +    /*
> +     * While VMware expects only 32-bit in, they do support using
> +     * other sizes and out.  However they do require only the 1 port
> +     * and the correct value in eax.  Since some of the data
> +     * returned in eax is smaller the 32 bits and/or you only need
> +     * the other registers the dir and bytes do not need any
> +     * checking.  The caller will handle the bytes, and dir is
> +     * handled below.
> +     */
> +    if ( port == BDOOR_PORT && regs->_eax == BDOOR_MAGIC )
> +    {
> +        uint32_t new_eax = BDOOR_MAGIC;
> +        uint64_t value;
> +        struct vcpu *curr = current;
> +        struct domain *d = curr->domain;

currd

> +
> +        switch ( regs->_ecx & 0xffff )
> +        {
> +        case BDOOR_CMD_GETMHZ:
> +            new_eax = d->arch.tsc_khz / 1000;
> +            break;
> +        case BDOOR_CMD_GETVERSION:
> +            /* MAGIC */
> +            regs->_ebx = BDOOR_MAGIC;
> +            /* VERSION_MAGIC */
> +            new_eax = 6;
> +            /* Claim we are an ESX. VMX_TYPE_SCALABLE_SERVER */
> +            regs->_ecx = 2;

Are you sure you don't want to zero the high halves of 64-bit
registers here?

> +            break;
> +        case BDOOR_CMD_GETSCREENSIZE:
> +            /* We have no screen size */
> +            new_eax = ~0u;

Then just have this handled into the default case.

> +            break;
> +        case BDOOR_CMD_GETHWVERSION:
> +            /* vmware_hw */
> +            ASSERT(is_hvm_vcpu(curr));

is_hvm_domain(currd)

And - why here rather than before the switch() or even right at the
start of the function?

> +            {
> +                struct hvm_domain *hd = &d->arch.hvm_domain;
> +
> +                new_eax = hd->params[HVM_PARAM_VMWARE_HWVER];
> +            }
> +            /*
> +             * Returning zero is not the best.  VMware was not at
> +             * all consistent in the handling of this command until
> +             * VMware hardware version 4.  So it is better to claim
> +             * 4 then 0.  This should only happen in strange configs.
> +             */
> +            if ( !new_eax )
> +                new_eax = 4;
> +            break;
> +        case BDOOR_CMD_GETHZ:
> +        {
> +            struct segment_register sreg;
> +
> +            hvm_get_segment_register(curr, x86_seg_ss, &sreg);
> +            if ( sreg.attr.fields.dpl == 0 )
> +            {
> +                value = d->arch.tsc_khz * 1000;
> +                /* apic-frequency (bus speed) */
> +                regs->_ecx = 1000000000ULL / APIC_BUS_CYCLE_NS;
> +                /* High part of tsc-frequency */
> +                regs->_ebx = value >> 32;
> +                /* Low part of tsc-frequency */
> +                new_eax = value;
> +            }
> +            break;
> +        }
> +        case BDOOR_CMD_GETTIME:
> +            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
> +            /* hostUsecs */
> +            regs->_ebx = value % 1000000UL;
> +            /* hostSecs */
> +            new_eax = value / 1000000ULL;
> +            /* maxTimeLag */
> +            regs->_ecx = 1000000;
> +            /* offset to GMT in minutes */
> +            regs->_edx = d->time_offset_seconds / 60;
> +            break;
> +        case BDOOR_CMD_GETTIMEFULL:
> +            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
> +            /* hostUsecs */
> +            regs->_ebx = value % 1000000UL;
> +            /* hostSecs low 32 bits */
> +            regs->_edx = value / 1000000ULL;
> +            /* hostSecs high 32 bits */
> +            regs->_esi = (value / 1000000ULL) >> 32;
> +            /* maxTimeLag */
> +            regs->_ecx = 1000000;
> +            break;

No setting of new_eax?

> +        default:
> +            new_eax = ~0u;

Why is this not the initializer value for the variable then?

> +            break;
> +        }
> +        if ( dir == IOREQ_READ )
> +            *val = new_eax;

With that, is it really correct that OUT updates the other registers
just like IN? If so, this deserves a comment, so that readers won't
think this is in error.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-16 23:05 ` [PATCH v9 06/13] xen: Add ring 3 " Don Slutz
  2015-02-17 14:38   ` Andrew Cooper
@ 2015-02-23 15:12   ` Jan Beulich
  2015-02-23 17:11     ` Don Slutz
  1 sibling, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-23 15:12 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
> Enable no-fault of pio in x86_emulate for VMware port

???

> @@ -393,6 +393,11 @@ struct x86_emulate_ops
>          enum x86_segment seg,
>          unsigned long offset,
>          struct x86_emulate_ctxt *ctxt);
> +
> +    /* vmport_check */
> +    int (*vmport_check)(
> +        unsigned int port,
> +        struct x86_emulate_ctxt *ctxt);

I hope that this will no longer be needed with the adjustments
Andrew suggested. In light of that I only skimmed the patch,
awaiting the next version to be less involved.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 05/13] xen: Add vmware_port support
  2015-02-23 15:05   ` Jan Beulich
@ 2015-02-23 16:03     ` Don Slutz
  2015-02-23 16:28       ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-23 16:03 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 02/23/15 10:05, Jan Beulich wrote:
>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> 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.
> 
> As indicated before, I don't think this is a good use case for a
> domain creation flag. Some of the others we have may not be either,
> but as I have said quite often recently - let's not make the situation
> worse by following bad examples.
> 

I was not sure on the way to go based on the emails.

I will code up a version that has the additional code to make a
HVM_PARAM a write once.  The current way allows multiple write of the
same value and changes from 0 to non-zero.


>> --- /dev/null
>> +++ b/xen/arch/x86/hvm/vmware/vmport.c
>> @@ -0,0 +1,142 @@
>> +/*
>> + * 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/lib.h>
>> +#include <asm/hvm/hvm.h>
>> +#include <asm/hvm/support.h>
>> +#include <asm/hvm/vmport.h>
>> +
>> +#include "backdoor_def.h"
>> +
>> +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)
> 
> static
> 

Andrew already pointed this out.

>> +{
>> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
>> +
>> +    /*
>> +     * While VMware expects only 32-bit in, they do support using
>> +     * other sizes and out.  However they do require only the 1 port
>> +     * and the correct value in eax.  Since some of the data
>> +     * returned in eax is smaller the 32 bits and/or you only need
>> +     * the other registers the dir and bytes do not need any
>> +     * checking.  The caller will handle the bytes, and dir is
>> +     * handled below.
>> +     */
>> +    if ( port == BDOOR_PORT && regs->_eax == BDOOR_MAGIC )
>> +    {
>> +        uint32_t new_eax = BDOOR_MAGIC;
>> +        uint64_t value;
>> +        struct vcpu *curr = current;
>> +        struct domain *d = curr->domain;
> 
> currd
> 

Will change.

>> +
>> +        switch ( regs->_ecx & 0xffff )
>> +        {
>> +        case BDOOR_CMD_GETMHZ:
>> +            new_eax = d->arch.tsc_khz / 1000;
>> +            break;
>> +        case BDOOR_CMD_GETVERSION:
>> +            /* MAGIC */
>> +            regs->_ebx = BDOOR_MAGIC;
>> +            /* VERSION_MAGIC */
>> +            new_eax = 6;
>> +            /* Claim we are an ESX. VMX_TYPE_SCALABLE_SERVER */
>> +            regs->_ecx = 2;
> 
> Are you sure you don't want to zero the high halves of 64-bit
> registers here?
> 

Yes, VMware does not zero the high halves.

>> +            break;
>> +        case BDOOR_CMD_GETSCREENSIZE:
>> +            /* We have no screen size */
>> +            new_eax = ~0u;
> 
> Then just have this handled into the default case.
> 

Will do.

>> +            break;
>> +        case BDOOR_CMD_GETHWVERSION:
>> +            /* vmware_hw */
>> +            ASSERT(is_hvm_vcpu(curr));
> 
> is_hvm_domain(currd)
> 

Ok.

> And - why here rather than before the switch() or even right at the
> start of the function?
> 

Since this was the only place it was needed.  Will move to the start.

>> +            {
>> +                struct hvm_domain *hd = &d->arch.hvm_domain;
>> +
>> +                new_eax = hd->params[HVM_PARAM_VMWARE_HWVER];
>> +            }
>> +            /*
>> +             * Returning zero is not the best.  VMware was not at
>> +             * all consistent in the handling of this command until
>> +             * VMware hardware version 4.  So it is better to claim
>> +             * 4 then 0.  This should only happen in strange configs.
>> +             */
>> +            if ( !new_eax )
>> +                new_eax = 4;
>> +            break;
>> +        case BDOOR_CMD_GETHZ:
>> +        {
>> +            struct segment_register sreg;
>> +
>> +            hvm_get_segment_register(curr, x86_seg_ss, &sreg);
>> +            if ( sreg.attr.fields.dpl == 0 )
>> +            {
>> +                value = d->arch.tsc_khz * 1000;
>> +                /* apic-frequency (bus speed) */
>> +                regs->_ecx = 1000000000ULL / APIC_BUS_CYCLE_NS;
>> +                /* High part of tsc-frequency */
>> +                regs->_ebx = value >> 32;
>> +                /* Low part of tsc-frequency */
>> +                new_eax = value;
>> +            }
>> +            break;
>> +        }
>> +        case BDOOR_CMD_GETTIME:
>> +            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
>> +            /* hostUsecs */
>> +            regs->_ebx = value % 1000000UL;
>> +            /* hostSecs */
>> +            new_eax = value / 1000000ULL;
>> +            /* maxTimeLag */
>> +            regs->_ecx = 1000000;
>> +            /* offset to GMT in minutes */
>> +            regs->_edx = d->time_offset_seconds / 60;
>> +            break;
>> +        case BDOOR_CMD_GETTIMEFULL:
>> +            value = get_localtime_us(d) - d->time_offset_seconds * 1000000ULL;
>> +            /* hostUsecs */
>> +            regs->_ebx = value % 1000000UL;
>> +            /* hostSecs low 32 bits */
>> +            regs->_edx = value / 1000000ULL;
>> +            /* hostSecs high 32 bits */
>> +            regs->_esi = (value / 1000000ULL) >> 32;
>> +            /* maxTimeLag */
>> +            regs->_ecx = 1000000;
>> +            break;
> 
> No setting of new_eax?
> 

This is using the "new_eax = BDOOR_MAGIC" above.

>> +        default:
>> +            new_eax = ~0u;
> 
> Why is this not the initializer value for the variable then?
> 

Because of the use above.  Since you ask, I will switch the usage.

>> +            break;
>> +        }
>> +        if ( dir == IOREQ_READ )
>> +            *val = new_eax;
> 
> With that, is it really correct that OUT updates the other registers
> just like IN? If so, this deserves a comment, so that readers won't
> think this is in error.
> 

Yes.  Will add a comment about this.

> Jan
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 05/13] xen: Add vmware_port support
  2015-02-23 16:03     ` Don Slutz
@ 2015-02-23 16:28       ` Jan Beulich
  0 siblings, 0 replies; 71+ messages in thread
From: Jan Beulich @ 2015-02-23 16:28 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 23.02.15 at 17:03, <dslutz@verizon.com> wrote:
> On 02/23/15 10:05, Jan Beulich wrote:
>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> 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.
>> 
>> As indicated before, I don't think this is a good use case for a
>> domain creation flag. Some of the others we have may not be either,
>> but as I have said quite often recently - let's not make the situation
>> worse by following bad examples.
>> 
> 
> I was not sure on the way to go based on the emails.

I think I said so before - we should come to some conclusion among
maintainers here first. I'm afraid besides Andrew and me no-one
really voiced any opinion; maybe worth for you to send out a
separate request-for-comments on this specific aspect...

>>> +        case BDOOR_CMD_GETVERSION:
>>> +            /* MAGIC */
>>> +            regs->_ebx = BDOOR_MAGIC;
>>> +            /* VERSION_MAGIC */
>>> +            new_eax = 6;
>>> +            /* Claim we are an ESX. VMX_TYPE_SCALABLE_SERVER */
>>> +            regs->_ecx = 2;
>> 
>> Are you sure you don't want to zero the high halves of 64-bit
>> registers here?
>> 
> 
> Yes, VMware does not zero the high halves.

Which then again calls for a comment so that a casual reader won't
be tempted to "fix" this (non-architectural) behavior.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-16 23:05 ` [PATCH v9 09/13] Add xentrace to vmware_port Don Slutz
  2015-02-17 13:45   ` Andrew Cooper
@ 2015-02-23 16:57   ` Jan Beulich
  2015-02-23 19:13     ` Don Slutz
  2015-03-03 14:27   ` Ian Campbell
  2 siblings, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-23 16:57 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
> @@ -55,8 +56,9 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
>          uint64_t value;
>          struct vcpu *curr = current;
>          struct domain *d = curr->domain;
> +        uint16_t cmd = regs->_ecx;
>  
> -        switch ( regs->_ecx & 0xffff )
> +        switch ( cmd )

This surely doesn't belong here.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-23 15:12   ` Jan Beulich
@ 2015-02-23 17:11     ` Don Slutz
  2015-02-24  8:34       ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-23 17:11 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	George Dunlap, Andrew Cooper, Tim Deegan, xen-devel, Eddie Dong,
	Aravind Gopalakrishnan, Jun Nakajima, Suravee Suthikulpanit,
	Boris Ostrovsky, Ian Jackson

On 02/23/15 10:12, Jan Beulich wrote:
>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>> Enable no-fault of pio in x86_emulate for VMware port
> 
> ???
> 
>> @@ -393,6 +393,11 @@ struct x86_emulate_ops
>>          enum x86_segment seg,
>>          unsigned long offset,
>>          struct x86_emulate_ctxt *ctxt);
>> +
>> +    /* vmport_check */
>> +    int (*vmport_check)(
>> +        unsigned int port,
>> +        struct x86_emulate_ctxt *ctxt);
> 
> I hope that this will no longer be needed with the adjustments
> Andrew suggested. In light of that I only skimmed the patch,
> awaiting the next version to be less involved.
> 

My understanding is that it is needed.  The code in
xen/arch/x86/x86_emulate is not to access code directly
in xen/arch/x86/hvm.

tools/tests/x86_emulator/test_x86_emulator.c would not build if
the routine was access directly.


Here is the code that passed my testing:

    case 0xe4: /* in imm8,%al */
    case 0xe5: /* in imm8,%eax */
    case 0xe6: /* out %al,imm8 */
    case 0xe7: /* out %eax,imm8 */
    case 0xec: /* in %dx,%al */
    case 0xed: /* in %dx,%eax */
    case 0xee: /* out %al,%dx */
    case 0xef: /* out %eax,%dx */ {
        unsigned int port = ((b < 0xe8)
                             ? insn_fetch_type(uint8_t)
                             : (uint16_t)_regs.edx);
        bool_t vmport = (ops->vmport_check && /* Vmware backdoor? */
                         (ops->vmport_check(port, ctxt) == 0));
        op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
        if ( !vmport &&
             (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
            goto done;
        if ( b & 2 )
        {
            /* out */
            fail_if(ops->write_io == NULL);
            rc = ops->write_io(port, op_bytes, _regs.eax, ctxt);
        }
        else
        {
            /* in */
            dst.type  = OP_REG;
            dst.bytes = op_bytes;
            dst.reg   = (unsigned long *)&_regs.eax;
            fail_if(ops->read_io == NULL);
            rc = ops->read_io(port, dst.bytes, &dst.val, ctxt);
        }
        if ( rc != 0 )
            goto done;
        if ( vmport )
        {
            _regs._ebx = ctxt->regs->_ebx;
            _regs._ecx = ctxt->regs->_ecx;
            _regs._edx = ctxt->regs->_edx;
            _regs._esi = ctxt->regs->_esi;
            _regs._edi = ctxt->regs->_edi;
        }
        break;
    }


   -Don Slutz

> Jan
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-23 16:57   ` Jan Beulich
@ 2015-02-23 19:13     ` Don Slutz
  2015-02-24  7:19       ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-23 19:13 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 02/23/15 11:57, Jan Beulich wrote:
>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>> @@ -55,8 +56,9 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
>>          uint64_t value;
>>          struct vcpu *curr = current;
>>          struct domain *d = curr->domain;
>> +        uint16_t cmd = regs->_ecx;
>>  
>> -        switch ( regs->_ecx & 0xffff )
>> +        switch ( cmd )
> 
> This surely doesn't belong here.
> 

Ah, this version was missing the diff:

@@ -116,11 +118,20 @@ static int vmport_ioport(int dir, uint32_t port,
uint32_t bytes, uint32_t *val)
             /* Let backing DM handle */
             return X86EMUL_VMPORT_SEND;
         }
+        HVMTRACE_ND7(VMPORT_HANDLED, 0, 0/*cycles*/, 7,
+                     cmd, new_eax, regs->_ebx, regs->_ecx,
+                     regs->_edx, regs->_esi, regs->_edi);
         if ( dir == IOREQ_READ )
             *val = new_eax;
     }
-    else if ( dir == IOREQ_READ )
-        *val = ~0u;
+    else
+    {
+        HVMTRACE_ND7(VMPORT_IGNORED, 0, 0/*cycles*/, 7,
+                     port, regs->_eax, regs->_ebx, regs->_ecx,
+                     regs->_edx, regs->_esi, regs->_edi);
+        if ( dir == IOREQ_READ )
+            *val = ~0u;
+    }

     return X86EMUL_OKAY;
 }

So, should cmd be in this patch or patch #5 (xen: Add vmware_port
support) where you said:

>> +    uint16_t cmd = regs->rcx;
>
> As you already have most other variables needed only inside the if()
> below declared in that scope, please be consistent with this one.
> Albeit the value of this variable is questionable anyway - it's being
> used exactly once.

?

   -Don Slutz

> Jan
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-23 19:13     ` Don Slutz
@ 2015-02-24  7:19       ` Jan Beulich
  0 siblings, 0 replies; 71+ messages in thread
From: Jan Beulich @ 2015-02-24  7:19 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 23.02.15 at 20:13, <dslutz@verizon.com> wrote:
> On 02/23/15 11:57, Jan Beulich wrote:
>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>> @@ -55,8 +56,9 @@ int vmport_ioport(int dir, uint32_t port, uint32_t bytes, 
> uint32_t *val)
>>>          uint64_t value;
>>>          struct vcpu *curr = current;
>>>          struct domain *d = curr->domain;
>>> +        uint16_t cmd = regs->_ecx;
>>>  
>>> -        switch ( regs->_ecx & 0xffff )
>>> +        switch ( cmd )
>> 
>> This surely doesn't belong here.
>> 
> 
> Ah, this version was missing the diff:
> 
> @@ -116,11 +118,20 @@ static int vmport_ioport(int dir, uint32_t port,
> uint32_t bytes, uint32_t *val)
>              /* Let backing DM handle */
>              return X86EMUL_VMPORT_SEND;
>          }
> +        HVMTRACE_ND7(VMPORT_HANDLED, 0, 0/*cycles*/, 7,
> +                     cmd, new_eax, regs->_ebx, regs->_ecx,
> +                     regs->_edx, regs->_esi, regs->_edi);
>          if ( dir == IOREQ_READ )
>              *val = new_eax;
>      }
> -    else if ( dir == IOREQ_READ )
> -        *val = ~0u;
> +    else
> +    {
> +        HVMTRACE_ND7(VMPORT_IGNORED, 0, 0/*cycles*/, 7,
> +                     port, regs->_eax, regs->_ebx, regs->_ecx,
> +                     regs->_edx, regs->_esi, regs->_edi);
> +        if ( dir == IOREQ_READ )
> +            *val = ~0u;
> +    }
> 
>      return X86EMUL_OKAY;
>  }
> 
> So, should cmd be in this patch or patch #5 (xen: Add vmware_port
> support) where you said:
> 
>>> +    uint16_t cmd = regs->rcx;
>>
>> As you already have most other variables needed only inside the if()
>> below declared in that scope, please be consistent with this one.
>> Albeit the value of this variable is questionable anyway - it's being
>> used exactly once.
> 
> ?

In the patch here then.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-23 17:11     ` Don Slutz
@ 2015-02-24  8:34       ` Jan Beulich
  2015-02-24 17:14         ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-24  8:34 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 23.02.15 at 18:11, <dslutz@verizon.com> wrote:
> On 02/23/15 10:12, Jan Beulich wrote:
>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>> @@ -393,6 +393,11 @@ struct x86_emulate_ops
>>>          enum x86_segment seg,
>>>          unsigned long offset,
>>>          struct x86_emulate_ctxt *ctxt);
>>> +
>>> +    /* vmport_check */
>>> +    int (*vmport_check)(
>>> +        unsigned int port,
>>> +        struct x86_emulate_ctxt *ctxt);
>> 
>> I hope that this will no longer be needed with the adjustments
>> Andrew suggested. In light of that I only skimmed the patch,
>> awaiting the next version to be less involved.
>> 
> 
> My understanding is that it is needed.  The code in
> xen/arch/x86/x86_emulate is not to access code directly
> in xen/arch/x86/hvm.
> 
> tools/tests/x86_emulator/test_x86_emulator.c would not build if
> the routine was access directly.
> 
> 
> Here is the code that passed my testing:
> 
>     case 0xe4: /* in imm8,%al */
>     case 0xe5: /* in imm8,%eax */
>     case 0xe6: /* out %al,imm8 */
>     case 0xe7: /* out %eax,imm8 */
>     case 0xec: /* in %dx,%al */
>     case 0xed: /* in %dx,%eax */
>     case 0xee: /* out %al,%dx */
>     case 0xef: /* out %eax,%dx */ {
>         unsigned int port = ((b < 0xe8)
>                              ? insn_fetch_type(uint8_t)
>                              : (uint16_t)_regs.edx);
>         bool_t vmport = (ops->vmport_check && /* Vmware backdoor? */
>                          (ops->vmport_check(port, ctxt) == 0));
>         op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
>         if ( !vmport &&
>              (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
>             goto done;

Hmm, this looks ugly. At the very least - for this to become half
way acceptable - this should not be VMware specific in any way. I.e.
just have a generic (and generically usable) hook here which your
VMware port code then just happens to use.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-16 23:05 ` [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT Don Slutz
  2015-02-17 10:08   ` Paul Durrant
@ 2015-02-24 15:34   ` Jan Beulich
  2015-02-25 20:20     ` Don Slutz
  2015-03-03 14:25   ` Ian Campbell
  2 siblings, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-24 15:34 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)
>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
>  }
>  
> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int buf)
>  {
> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> +    struct hvm_ioreq_page *iorp = NULL;
> +
> +    switch ( buf )
> +    {
> +    case 0:
> +        iorp = &s->ioreq;
> +        break;
> +    case 1:
> +        iorp = &s->bufioreq;
> +        break;
> +    case 2:
> +        iorp = &s->vmport_ioreq;
> +        break;
> +    }

These literals should become an enum.

> @@ -2429,9 +2552,6 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>      if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
>          return NULL;
>  
> -    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
> -        return d->arch.hvm_domain.default_ioreq_server;

Shouldn't this rather be amended than deleted?

> @@ -2474,7 +2594,12 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
> +        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
> +        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
> +        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE != HVMOP_IO_RANGE_INVALIDATE);
>          r = s->range[type];
> +        if ( !r )
> +            continue;

Why, all of the sudden?

> @@ -2501,6 +2626,13 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>              }
>  
>              break;
> +        case IOREQ_TYPE_VMWARE_PORT:
> +        case IOREQ_TYPE_TIMEOFFSET:
> +        case IOREQ_TYPE_INVALIDATE:
> +            if ( rangeset_contains_singleton(r, 1) )
> +                return s;

This literal 1 at least needs explanation (i.e. a comment).

> --- a/xen/arch/x86/hvm/io.c
> +++ b/xen/arch/x86/hvm/io.c
> @@ -192,6 +192,21 @@ void hvm_io_assist(ioreq_t *p)
>          (void)handle_mmio();
>          break;
>      case HVMIO_handle_pio_awaiting_completion:
> +        if ( p->type == IOREQ_TYPE_VMWARE_PORT )
> +        {
> +            struct cpu_user_regs *regs = guest_cpu_user_regs();
> +            vmware_regs_t *vr = get_vmport_regs_any(NULL, curr);
> +
> +            if ( vr )
> +            {
> +                /* Only change the 32bit part of the register */
> +                regs->_ebx = vr->ebx;
> +                regs->_ecx = vr->ecx;
> +                regs->_edx = vr->edx;
> +                regs->_esi = vr->esi;
> +                regs->_edi = vr->edi;
> +            }

If you already nicely scope restrict the variables you add, please
move "regs" into the inner if().

> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
> @@ -112,6 +112,8 @@ struct __packed segment_register {
>  #define X86EMUL_RETRY          3
>   /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
>  #define X86EMUL_CMPXCHG_FAILED 3
> + /* Send part of registers also to DM. */
> +#define X86EMUL_VMPORT_SEND    4

Introducing a new value here seems rather fragile, as various code
paths you don't touch would need auditing that they do the right
thing upon this value being returned. Plus even conceptually this
doesn't belong here - the instruction emulator shouldn't be concerned
with things like VMware emulation.

> --- a/xen/include/public/hvm/hvm_op.h
> +++ b/xen/include/public/hvm/hvm_op.h
> @@ -314,6 +314,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
>   *
>   * NOTE: unless an emulation request falls entirely within a range mapped
>   * by a secondary emulator, it will not be passed to that emulator.
> + *
> + * NOTE: The 'special' range of 1 is what is checked for outside
> + * of the three types of I/O.
>   */
>  #define HVMOP_map_io_range_to_ioreq_server 19
>  #define HVMOP_unmap_io_range_from_ioreq_server 20
> @@ -324,6 +327,9 @@ struct xen_hvm_io_range {
>  # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
>  # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
>  # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
> +# define HVMOP_IO_RANGE_VMWARE_PORT 3 /* VMware port special range */
> +# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range */
> +# define HVMOP_IO_RANGE_INVALIDATE 8 /* INVALIDATE special range */

I can't seem to connect the comment you add above to the three
new #define-s.

> --- a/xen/include/public/hvm/ioreq.h
> +++ b/xen/include/public/hvm/ioreq.h
> @@ -35,6 +35,7 @@
>  #define IOREQ_TYPE_PIO          0 /* pio */
>  #define IOREQ_TYPE_COPY         1 /* mmio ops */
>  #define IOREQ_TYPE_PCI_CONFIG   2
> +#define IOREQ_TYPE_VMWARE_PORT  3
>  #define IOREQ_TYPE_TIMEOFFSET   7
>  #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */

Are you sure (re-)using a value in the middle is safe? Did you check
where the sparseness originates from?


> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -50,6 +50,8 @@
>  #define HVM_PARAM_PAE_ENABLED  4
>  
>  #define HVM_PARAM_IOREQ_PFN    5
> +/* Extra vmport PFN. */
> +#define HVM_PARAM_VMPORT_REGS_PFN 36
>  
>  #define HVM_PARAM_BUFIOREQ_PFN 6
>  #define HVM_PARAM_BUFIOREQ_EVTCHN 26

I don't think this really belongs here - there's no strong association
with HVM_PARAM_IOREQ_PFN afaict.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage
  2015-02-16 23:05 ` [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage Don Slutz
@ 2015-02-24 15:38   ` Jan Beulich
  2015-02-24 18:29     ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-24 15:38 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
> Signed-off-by: Don Slutz <dslutz@verizon.com>

There's a whole lot of stuff being added here, and I easily can't see
where delivery of a #GP would actually be tested. Please explain
here what the tests are supposed to test and why emulops_gp
needs all the function pointers you're adding functions for.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-24  8:34       ` Jan Beulich
@ 2015-02-24 17:14         ` Don Slutz
  2015-02-25  8:39           ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-24 17:14 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 02/24/15 03:34, Jan Beulich wrote:
>>>> On 23.02.15 at 18:11, <dslutz@verizon.com> wrote:
>> On 02/23/15 10:12, Jan Beulich wrote:
>>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>>> @@ -393,6 +393,11 @@ struct x86_emulate_ops
>>>>          enum x86_segment seg,
>>>>          unsigned long offset,
>>>>          struct x86_emulate_ctxt *ctxt);
>>>> +
>>>> +    /* vmport_check */
>>>> +    int (*vmport_check)(
>>>> +        unsigned int port,
>>>> +        struct x86_emulate_ctxt *ctxt);
>>>
>>> I hope that this will no longer be needed with the adjustments
>>> Andrew suggested. In light of that I only skimmed the patch,
>>> awaiting the next version to be less involved.
>>>
>>
>> My understanding is that it is needed.  The code in
>> xen/arch/x86/x86_emulate is not to access code directly
>> in xen/arch/x86/hvm.
>>
>> tools/tests/x86_emulator/test_x86_emulator.c would not build if
>> the routine was access directly.
>>
>>
>> Here is the code that passed my testing:
>>
>>     case 0xe4: /* in imm8,%al */
>>     case 0xe5: /* in imm8,%eax */
>>     case 0xe6: /* out %al,imm8 */
>>     case 0xe7: /* out %eax,imm8 */
>>     case 0xec: /* in %dx,%al */
>>     case 0xed: /* in %dx,%eax */
>>     case 0xee: /* out %al,%dx */
>>     case 0xef: /* out %eax,%dx */ {
>>         unsigned int port = ((b < 0xe8)
>>                              ? insn_fetch_type(uint8_t)
>>                              : (uint16_t)_regs.edx);
>>         bool_t vmport = (ops->vmport_check && /* Vmware backdoor? */
>>                          (ops->vmport_check(port, ctxt) == 0));
>>         op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
>>         if ( !vmport &&
>>              (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
>>             goto done;
> 
> Hmm, this looks ugly. At the very least - for this to become half
> way acceptable - this should not be VMware specific in any way. I.e.
> just have a generic (and generically usable) hook here which your
> VMware port code then just happens to use.
> 

I can see changing the name to something like
"skip_pio_port_access_check".  But to make it more generic it would also
need to return 3 values (enum or #define).

1) do not skip
2) skip but no registers
3) skip and registers.

This is because the code soon below (which was not included in the reply):


+       if ( vmport )
+       {
+            _regs._ebx = ctxt->regs->_ebx;
+            _regs._ecx = ctxt->regs->_ecx;
+            _regs._edx = ctxt->regs->_edx;
+            _regs._esi = ctxt->regs->_esi;
+            _regs._edi = ctxt->regs->_edi;
+       }

Which I think can be made more generic:

   unsigned long save_ip = _regs.eip;
   _regs = *ctxt->regs;
   _regs.eip = save_ip;


(or just switch to rbx etc) is needed here.

Since this is not an architecture feature and I do not expect any real
CPUs to support this, I do not expect any other use.  But I am happy
to make it more generic.

Which I would assume would mean to also have the same set of arguments
as ioport_access_check(), even though most will be ignored.

   -Don Slutz

> Jan
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage
  2015-02-24 15:38   ` Jan Beulich
@ 2015-02-24 18:29     ` Don Slutz
  2015-02-25  8:30       ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-24 18:29 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 02/24/15 10:38, Jan Beulich wrote:
>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> 
> There's a whole lot of stuff being added here, and I easily can't see
> where delivery of a #GP would actually be tested.

Clearly I need more comments.  Short form is that j=1
is the #GP tests.

+        regs.edx    = 0x5658 + j;
...
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }

And the use in the real #GP handler:


+    if ( rc != X86EMUL_OKAY && rc != X86EMUL_RETRY )
+        hvm_inject_hw_exception(TRAP_gp_fault, vmcb->exitinfo1);


Since the test code and x86_emulate.c do not return
X86EMUL_RETRY it was good enough a test for me.


> Please explain
> here what the tests are supposed to test and why emulops_gp
> needs all the function pointers you're adding functions for.

Ok.  Here it is as text:

I added 2 testing "modes", j=0 and j=1.  Testing 4 instructions (all the
basic PIO) in both modes.

In j=0, there should not be an error returned.
In j=1, there should be an error returned.

For IN, eax should change.  For OUT eax should not change.

All 4 PIO instructions are 1 byte long, so eip should only change by 1.



The same as a diff with comments (and v10 code that does more checking):


+    /*
+     * Test out special #GP handling for the VMware port 0x5658.
+     * This is done in two "modes", j=0 and j=1.  Testing 4
+     * instructions (all the basic PIO) in both modes.
+     *
+     * The port used is based on j.
+     *
+     * For IN, eax should change.  For OUT eax should not change.
+     *
+     * All 4 PIO instructions are 1 byte long, so eip should only
+     * change by 1.
+     */
+    for ( j = 0; j <= 1; j++ )
+    {
+        regs.eflags = 0x20002;
+        regs.edx    = 0x5658 + j;
+        printf("Testing %s dx=%x ...       ", "in (%dx),%eax",
(int)regs.edx);
+        instr[0] = 0xed; /* in (%dx),%eax or in (%dx),%ax */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        regs.ebx    = 0;
+        regs.ecx    = 0;
+        regs.esi    = 0;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        /*
+         * In j=0, there should not be an error returned.
+         * In j=1, there should be an error returned.
+         */
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        /* Check for only 1 byte used or 0 if #GP. */
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        /* Check that eax changed in the non #GP case */
+        if ( j == 0 && regs.eax == 0x12345678 )
+            goto fail;
+        /* Check that ebx has the correct value */
+        if ( regs.ebx == j )
+            goto fail;
+        /* Check that ecx has the correct value */
+        if ( regs.ecx == j )
+            goto fail;
+        /* Check that esi has the correct value */
+        if ( regs.esi == j )
+            goto fail;
+        printf("okay\n");
+
+        printf("Testing %s  dx=%x ...       ", "in (%dx),%al",
(int)regs.edx);
+        instr[0] = 0xec; /* in (%dx),%al */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        regs.ebx    = 0;
+        regs.ecx    = 0;
+        regs.esi    = 0;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        /*
+         * In j=0, there should not be an error returned.
+         * In j=1, there should be an error returned.
+         */
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        /* Check for only 1 byte used or 0 if #GP. */
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        /* Check that eax changed in the non #GP case */
+        if ( j == 0 && regs.eax == 0x12345678 )
+            goto fail;
+        /* Check that ebx has the correct value */
+        if ( regs.ebx == j )
+            goto fail;
+        /* Check that ecx has the correct value */
+        if ( regs.ecx == j )
+            goto fail;
+        /* Check that esi has the correct value */
+        if ( regs.esi == j )
+            goto fail;
+        printf("okay\n");
+
+        printf("Testing %s dx=%x ...      ", "out %eax,(%dx)",
(int)regs.edx);
+        instr[0] = 0xef; /* out %eax,(%dx) or out %ax,(%dx) */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        regs.ebx    = 0;
+        regs.ecx    = 0;
+        regs.esi    = 0;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        /*
+         * In j=0, there should not be an error returned.
+         * In j=1, there should be an error returned.
+         */
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        /* Check for only 1 byte used or 0 if #GP. */
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        /* Check that eax did not change */
+        if ( regs.eax != 0x12345678 )
+            goto fail;
+        /* Check that ebx has the correct value */
+        if ( regs.ebx == j )
+            goto fail;
+        /* Check that ecx has the correct value */
+        if ( regs.ecx == j )
+            goto fail;
+        /* Check that esi has the correct value */
+        if ( regs.esi == j )
+            goto fail;
+        printf("okay\n");
+
+        printf("Testing %s  dx=%x ...      ", "out %al,(%dx)",
(int)regs.edx);
+        instr[0] = 0xee; /* out %al,(%dx) */
+        regs.eip    = (unsigned long)&instr[0];
+        regs.eax    = 0x12345678;
+        regs.ebx    = 0;
+        regs.ecx    = 0;
+        regs.esi    = 0;
+        rc = x86_emulate(&ctxt, &emulops_gp);
+        /*
+         * In j=0, there should not be an error returned.
+         * In j=1, there should be an error returned.
+         */
+        if ( rc != X86EMUL_OKAY )
+        {
+            if ( j == 0 )
+                goto fail;
+        }
+        else if ( j == 1 )
+            goto fail;
+        /* Check for only 1 byte used or 0 if #GP. */
+        if ( regs.eip != (unsigned long)&instr[1 - j] )
+            goto fail;
+        /* Check that eax did not change */
+        if ( regs.eax != 0x12345678 )
+            goto fail;
+        /* Check that ebx has the correct value */
+        if ( regs.ebx == j )
+            goto fail;
+        /* Check that ecx has the correct value */
+        if ( regs.ecx == j )
+            goto fail;
+        /* Check that esi has the correct value */
+        if ( regs.esi == j )
+            goto fail;
+        printf("okay\n");
+    }
+


Since it looks to me that with many cpus, it would be possible to pass
all opcodes to hvm_emulate_one_gp() by chaning memory at just the right
time.  So for emulops_gp, I had an attempt at running all the blowfish
code (32 and 64) through the #GP mode code, but it was not working and
so I dropped it after 2 days of poking.

Looks like I did not drop the no longer needed ops for the simple tests
I did add.

So I have checked and read, write_gp, cmpxchg_gp, read_segment,
and inject_hw_exception are not needed.  So that leaves:

static struct x86_emulate_ops emulops_gp = {
    .insn_fetch = fetch,
    .read_io    = read_io,
    .write_io   = write_io,
    .vmport_check = vmport_check,
};

   -Don Slutz

> 
> Jan
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage
  2015-02-24 18:29     ` Don Slutz
@ 2015-02-25  8:30       ` Jan Beulich
  2015-02-25 13:27         ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Jan Beulich @ 2015-02-25  8:30 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 24.02.15 at 19:29, <dslutz@verizon.com> wrote:
> +    /*
> +     * Test out special #GP handling for the VMware port 0x5658.
> +     * This is done in two "modes", j=0 and j=1.  Testing 4
> +     * instructions (all the basic PIO) in both modes.
> +     *
> +     * The port used is based on j.
> +     *
> +     * For IN, eax should change.  For OUT eax should not change.
> +     *
> +     * All 4 PIO instructions are 1 byte long, so eip should only
> +     * change by 1.
> +     */

Thanks, this looks reasonable.

> +        /*
> +         * In j=0, there should not be an error returned.
> +         * In j=1, there should be an error returned.
> +         */
> +        if ( rc != X86EMUL_OKAY )
> +        {
> +            if ( j == 0 )
> +                goto fail;
> +        }
> +        else if ( j == 1 )
> +            goto fail;

I'd appreciate if this could be expressed in a little fewer lines. I'm not
sure

    if ( (rc == X86EMUL_OKAY) == j )
        goto fail;

would be deemed readable, but surely

    if ( rc == X86EMUL_OKAY ? j : !j )
        goto fail;

would suffice.

> So I have checked and read, write_gp, cmpxchg_gp, read_segment,
> and inject_hw_exception are not needed.  So that leaves:
> 
> static struct x86_emulate_ops emulops_gp = {
>     .insn_fetch = fetch,
>     .read_io    = read_io,
>     .write_io   = write_io,
>     .vmport_check = vmport_check,
> };

Quite a bit better, thanks.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 06/13] xen: Add ring 3 vmware_port support
  2015-02-24 17:14         ` Don Slutz
@ 2015-02-25  8:39           ` Jan Beulich
  0 siblings, 0 replies; 71+ messages in thread
From: Jan Beulich @ 2015-02-25  8:39 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 24.02.15 at 18:14, <dslutz@verizon.com> wrote:
> Since this is not an architecture feature and I do not expect any real
> CPUs to support this, I do not expect any other use.  But I am happy
> to make it more generic.

Let's see how this ends up looking - the hook is probably indeed
bogus (from an architectural pov) no matter how you name it.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage
  2015-02-25  8:30       ` Jan Beulich
@ 2015-02-25 13:27         ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-25 13:27 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 02/25/15 03:30, Jan Beulich wrote:
>>>> On 24.02.15 at 19:29, <dslutz@verizon.com> wrote:
>> +    /*
>> +     * Test out special #GP handling for the VMware port 0x5658.
>> +     * This is done in two "modes", j=0 and j=1.  Testing 4
>> +     * instructions (all the basic PIO) in both modes.
>> +     *
>> +     * The port used is based on j.
>> +     *
>> +     * For IN, eax should change.  For OUT eax should not change.
>> +     *
>> +     * All 4 PIO instructions are 1 byte long, so eip should only
>> +     * change by 1.
>> +     */
> 
> Thanks, this looks reasonable.
> 
>> +        /*
>> +         * In j=0, there should not be an error returned.
>> +         * In j=1, there should be an error returned.
>> +         */
>> +        if ( rc != X86EMUL_OKAY )
>> +        {
>> +            if ( j == 0 )
>> +                goto fail;
>> +        }
>> +        else if ( j == 1 )
>> +            goto fail;
> 
> I'd appreciate if this could be expressed in a little fewer lines. I'm not
> sure
> 
>     if ( (rc == X86EMUL_OKAY) == j )
>         goto fail;
> 
> would be deemed readable, but surely
> 
>     if ( rc == X86EMUL_OKAY ? j : !j )
>         goto fail;
> 
> would suffice.

Tried this and it works fine, so switching to:

+        if ( rc == X86EMUL_OKAY ? j : !j )


   -Don Slutz


>> So I have checked and read, write_gp, cmpxchg_gp, read_segment,
>> and inject_hw_exception are not needed.  So that leaves:
>>
>> static struct x86_emulate_ops emulops_gp = {
>>     .insn_fetch = fetch,
>>     .read_io    = read_io,
>>     .write_io   = write_io,
>>     .vmport_check = vmport_check,
>> };
> 
> Quite a bit better, thanks.
> 
> Jan
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-24 15:34   ` Jan Beulich
@ 2015-02-25 20:20     ` Don Slutz
  2015-02-26  8:07       ` Jan Beulich
  0 siblings, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-25 20:20 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Kevin Tian, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	xen-devel, Eddie Dong, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

On 02/24/15 10:34, Jan Beulich wrote:
>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)
>>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
>>  }
>>  
>> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
>> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int buf)
>>  {
>> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>> +    struct hvm_ioreq_page *iorp = NULL;
>> +
>> +    switch ( buf )
>> +    {
>> +    case 0:
>> +        iorp = &s->ioreq;
>> +        break;
>> +    case 1:
>> +        iorp = &s->bufioreq;
>> +        break;
>> +    case 2:
>> +        iorp = &s->vmport_ioreq;
>> +        break;
>> +    }
> 
> These literals should become an enum.
> 

Paul Durrant asked for #defined values.  So it is not clear which way to
go. Will wait for response.


>> @@ -2429,9 +2552,6 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>      if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
>>          return NULL;
>>  
>> -    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
>> -        return d->arch.hvm_domain.default_ioreq_server;
> 
> Shouldn't this rather be amended than deleted?
> 

The reason is below:

>> @@ -2474,7 +2594,12 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
>> +        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
>> +        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
>> +        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE != HVMOP_IO_RANGE_INVALIDATE);
>>          r = s->range[type];
>> +        if ( !r )
>> +            continue;
> 
> Why, all of the sudden?
> 

This is the replacement for the deleted "if" above.  Continue will lead
to the same return that was remove above (it is at the end).  They are
currently the same because all ioreq servers have the same set of
ranges.  But if it would help, I can change "continue" into the "return
default".


>> @@ -2501,6 +2626,13 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>              }
>>  
>>              break;
>> +        case IOREQ_TYPE_VMWARE_PORT:
>> +        case IOREQ_TYPE_TIMEOFFSET:
>> +        case IOREQ_TYPE_INVALIDATE:
>> +            if ( rangeset_contains_singleton(r, 1) )
>> +                return s;
> 
> This literal 1 at least needs explanation (i.e. a comment).
> 

The comment is below (copied here).  Will duplicate it here (with any
adjustments needed):

 + * NOTE: The 'special' range of 1 is what is checked for outside
 + * of the three types of I/O.

How about /* The 'special' range of 1 is checked for being enabled */?

>> --- a/xen/arch/x86/hvm/io.c
>> +++ b/xen/arch/x86/hvm/io.c
>> @@ -192,6 +192,21 @@ void hvm_io_assist(ioreq_t *p)
>>          (void)handle_mmio();
>>          break;
>>      case HVMIO_handle_pio_awaiting_completion:
>> +        if ( p->type == IOREQ_TYPE_VMWARE_PORT )
>> +        {
>> +            struct cpu_user_regs *regs = guest_cpu_user_regs();
>> +            vmware_regs_t *vr = get_vmport_regs_any(NULL, curr);
>> +
>> +            if ( vr )
>> +            {
>> +                /* Only change the 32bit part of the register */
>> +                regs->_ebx = vr->ebx;
>> +                regs->_ecx = vr->ecx;
>> +                regs->_edx = vr->edx;
>> +                regs->_esi = vr->esi;
>> +                regs->_edi = vr->edi;
>> +            }
> 
> If you already nicely scope restrict the variables you add, please
> move "regs" into the inner if().

Will move regs.

> 
>> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
>> @@ -112,6 +112,8 @@ struct __packed segment_register {
>>  #define X86EMUL_RETRY          3
>>   /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
>>  #define X86EMUL_CMPXCHG_FAILED 3
>> + /* Send part of registers also to DM. */
>> +#define X86EMUL_VMPORT_SEND    4
> 
> Introducing a new value here seems rather fragile, as various code
> paths you don't touch would need auditing that they do the right
> thing upon this value being returned. Plus even conceptually this
> doesn't belong here - the instruction emulator shouldn't be concerned
> with things like VMware emulation.
> 

The only place I know of where rc is not checked by name is in
x86_emulate.c.  There are a lot of 0 and != 0 checks.  Also in area of
code there are places that return X86EMUL_OKAY when it looks to me that
the return value is checked for 0 and ignored otherwise.

So I will agree that the use of these defines is complex.  However, I
need a way to pass back X86EMUL_UNHANDLEABLE and send a few registers to
QEMU.  Now since the code path that I need to do this is:

...
 hvmemul_do_io
  hvm_portio_intercept
   hvm_io_intercept
    process_portio_intercept
     vmport_ioport


Since there is only 1 caller to hvm_portio_intercept() --
hvmemul_do_io, and hvmemul_do_io does not let X86EMUL_VMPORT_SEND be
returned. I feel that all code paths currently have been checked.
Adding a return code to me was the simpler code change.  It is possible
to change process_portio_intercept() by adding special code there to
adjust the ioreq_t p there, but that looked worse to me.

I can change to using a bit in the return of portio_action_t that would
be masked in process_portio_intercept() and make the code in
hvmemul_do_io() less clear since the change of p->type changes in
process_portio_intercept(), and change to hvmemul_do_io() is much more
involved.

I am happy to use some other number like 65539 if that would help. Also
any other name like X86EMUL_UNHANDLEABLE_EXTENDED, SPECIAL_DM_HANDLING,
etc would be fine with me.  I have no issue with defining this in a
different header file if that would help.


>> --- a/xen/include/public/hvm/hvm_op.h
>> +++ b/xen/include/public/hvm/hvm_op.h
>> @@ -314,6 +314,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
>>   *
>>   * NOTE: unless an emulation request falls entirely within a range mapped
>>   * by a secondary emulator, it will not be passed to that emulator.
>> + *
>> + * NOTE: The 'special' range of 1 is what is checked for outside
>> + * of the three types of I/O.
>>   */
>>  #define HVMOP_map_io_range_to_ioreq_server 19
>>  #define HVMOP_unmap_io_range_from_ioreq_server 20
>> @@ -324,6 +327,9 @@ struct xen_hvm_io_range {
>>  # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
>>  # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
>>  # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
>> +# define HVMOP_IO_RANGE_VMWARE_PORT 3 /* VMware port special range */
>> +# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range */
>> +# define HVMOP_IO_RANGE_INVALIDATE 8 /* INVALIDATE special range */
> 
> I can't seem to connect the comment you add above to the three
> new #define-s.
> 

Will work on better wording for the comment here and in the code
that is checking for it.  Paul Durrant pointed out that
HVMOP_IO_RANGE_INVALIDATE is not needed and so the plan is to drop it.
Does:

 + * NOTE: The 'special' range of 1 is what is checked for on
 + * VMWARE_PORT and TIMEOFFSET.

help?


>> --- a/xen/include/public/hvm/ioreq.h
>> +++ b/xen/include/public/hvm/ioreq.h
>> @@ -35,6 +35,7 @@
>>  #define IOREQ_TYPE_PIO          0 /* pio */
>>  #define IOREQ_TYPE_COPY         1 /* mmio ops */
>>  #define IOREQ_TYPE_PCI_CONFIG   2
>> +#define IOREQ_TYPE_VMWARE_PORT  3
>>  #define IOREQ_TYPE_TIMEOFFSET   7
>>  #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
> 
> Are you sure (re-)using a value in the middle is safe? Did you check
> where the sparseness originates from?
> 

99% sure.  It looks like a RHEL 5 dom0 still has code for IOREQ_TYPE_OR.
I have no idea how a Xen 4.6 HVM guest would pass a ioreq to Dom0 kernel
instead of to QEMU or QEMU Traditional.

Some background.  When Julien Grall added 2, this was said:


Keir Fraser
2012-Aug-23 13:26 UTC
head link
Re: [XEN][RFC PATCH V2 01/17] hvm: Modify interface to support multiple
ioreq server

On 23/08/2012 14:18, "Ian Campbell" <Ian.Campbell@citrix.com>
wrote:

 >> diff --git a/xen/include/public/hvm/ioreq.h
b/xen/include/public/hvm/ioreq.h
>> index 4022a1d..87aacd3 100644
>> --- a/xen/include/public/hvm/ioreq.h
>> +++ b/xen/include/public/hvm/ioreq.h
>> @@ -34,6 +34,7 @@
>>
>>  #define IOREQ_TYPE_PIO          0 /* pio */
>>  #define IOREQ_TYPE_COPY         1 /* mmio ops */
>> +#define IOREQ_TYPE_PCI_CONFIG   2 /* pci config space ops */
>>  #define IOREQ_TYPE_TIMEOFFSET   7
>>  #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
>
> I wonder why we skip 2-6 now -- perhaps they used to be something else
> and we are avoiding them to avoid strange errors? In which case adding
> the new on as 9 might be a good idea.


They were almost certainly used for representing R-M-W ALU operations back
in the days of the old IO emulator, very long ago. Still, there''s no
harm in
leaving them unused.

 -- Keir

Julien Grall
2012-Aug-24 10:33 UTC

...
> They were almost certainly used for representing R-M-W ALU operations back
> in the days of the old IO emulator, very long ago. Still, there''s
no harm in
> leaving them unused.
>
Ok. So I will use number 9 for IOREQ_TYPE_PCI_CONFIG.

----

I did find the old defn:

dcs-xen-54:~/xen>git show 4ff8936 | grep IOREQ_TYPE_
#define IOREQ_TYPE_PIO          0 /* pio */
#define IOREQ_TYPE_COPY         1 /* mmio ops */
#define IOREQ_TYPE_AND          2
#define IOREQ_TYPE_OR           3
#define IOREQ_TYPE_XOR          4
#define IOREQ_TYPE_XCHG         5
#define IOREQ_TYPE_ADD          6


Which matches what Keir Fraser said.


I did not find why Paul Durrant did not use 9.  I can only find it as 2
in all Paul's patch sets.  Which is closely connected to:

         BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
         BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
         BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);

(a new hyper call arg).  This also did not add a hole in "range" so
Paul Durrant did not have to check for a "range" hole.

So I did just like Paul Durrant did.  He also approved the patch with
this number in QEMU.  Since this is now in upstream QEMU, changing it at
this time is a slower process.  Since the only time QEMU uses its
version is when Xen header files are missing, I do not see how a QEMU
built with its version would be usable as a QEMU for Xen.  So I am
happy to change to a new number like 9.

> 
>> --- a/xen/include/public/hvm/params.h
>> +++ b/xen/include/public/hvm/params.h
>> @@ -50,6 +50,8 @@
>>  #define HVM_PARAM_PAE_ENABLED  4
>>  
>>  #define HVM_PARAM_IOREQ_PFN    5
>> +/* Extra vmport PFN. */
>> +#define HVM_PARAM_VMPORT_REGS_PFN 36
>>  
>>  #define HVM_PARAM_BUFIOREQ_PFN 6
>>  #define HVM_PARAM_BUFIOREQ_EVTCHN 26
> 
> I don't think this really belongs here - there's no strong association
> with HVM_PARAM_IOREQ_PFN afaict.
> 

I am not sure about that.  1/2 the request is passed via IOREQ_PFN the
other half is in VMPORT_REGS_PFN.  However I do not feel strongly about
this and so can move it to the "by number" spot.

   -Don Slutz

> Jan
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-25 20:20     ` Don Slutz
@ 2015-02-26  8:07       ` Jan Beulich
  2015-02-26 11:49         ` Paul Durrant
  2015-02-26 19:52         ` Don Slutz
  0 siblings, 2 replies; 71+ messages in thread
From: Jan Beulich @ 2015-02-26  8:07 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Eddie Dong, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	Kevin Tian, xen-devel, Paul Durrant, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 25.02.15 at 21:20, <dslutz@verizon.com> wrote:
> On 02/24/15 10:34, Jan Beulich wrote:
>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)
>>>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
>>>  }
>>>  
>>> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
>>> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int buf)
>>>  {
>>> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>>> +    struct hvm_ioreq_page *iorp = NULL;
>>> +
>>> +    switch ( buf )
>>> +    {
>>> +    case 0:
>>> +        iorp = &s->ioreq;
>>> +        break;
>>> +    case 1:
>>> +        iorp = &s->bufioreq;
>>> +        break;
>>> +    case 2:
>>> +        iorp = &s->vmport_ioreq;
>>> +        break;
>>> +    }
>> 
>> These literals should become an enum.
>> 
> 
> Paul Durrant asked for #defined values.  So it is not clear which way to
> go. Will wait for response.

Obviously either would be fine. An enum has the potential advantage
of the compiler being able to check switch statements for completeness
(albeit there are cases where this ends up being a disadvantage).

>>> @@ -2429,9 +2552,6 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct 
> domain *d,
>>>      if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
>>>          return NULL;
>>>  
>>> -    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
>>> -        return d->arch.hvm_domain.default_ioreq_server;
>> 
>> Shouldn't this rather be amended than deleted?
>> 
> 
> The reason is below:
> 
>>> @@ -2474,7 +2594,12 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>>>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>>>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
>>> +        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
>>> +        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
>>> +        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE != HVMOP_IO_RANGE_INVALIDATE);
>>>          r = s->range[type];
>>> +        if ( !r )
>>> +            continue;
>> 
>> Why, all of the sudden?
>> 
> 
> This is the replacement for the deleted "if" above.  Continue will lead
> to the same return that was remove above (it is at the end).  They are
> currently the same because all ioreq servers have the same set of
> ranges.  But if it would help, I can change "continue" into the "return
> default".

So further down you talk of the "special range 1" (see there for
further remarks in this regard) - how would r be NULL here in the
first place? That said - yes, making this explicitly do what is
intended (perhaps rather using "break" instead of "return") would
seem very desirable. There simply is no point in continuing the
loop.

>>> @@ -2501,6 +2626,13 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>>              }
>>>  
>>>              break;
>>> +        case IOREQ_TYPE_VMWARE_PORT:
>>> +        case IOREQ_TYPE_TIMEOFFSET:
>>> +        case IOREQ_TYPE_INVALIDATE:
>>> +            if ( rangeset_contains_singleton(r, 1) )
>>> +                return s;
>> 
>> This literal 1 at least needs explanation (i.e. a comment).
>> 
> 
> The comment is below (copied here).  Will duplicate it here (with any
> adjustments needed):
> 
>  + * NOTE: The 'special' range of 1 is what is checked for outside
>  + * of the three types of I/O.
> 
> How about /* The 'special' range of 1 is checked for being enabled */?

Along these lines, yes (fixed for coding style). And then "1" is not
a range of any kind. I suppose writing it as a proper range (e.g.
[1,1]) would already help.

>>> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
>>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
>>> @@ -112,6 +112,8 @@ struct __packed segment_register {
>>>  #define X86EMUL_RETRY          3
>>>   /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
>>>  #define X86EMUL_CMPXCHG_FAILED 3
>>> + /* Send part of registers also to DM. */
>>> +#define X86EMUL_VMPORT_SEND    4
>> 
>> Introducing a new value here seems rather fragile, as various code
>> paths you don't touch would need auditing that they do the right
>> thing upon this value being returned. Plus even conceptually this
>> doesn't belong here - the instruction emulator shouldn't be concerned
>> with things like VMware emulation.
>> 
> 
> The only place I know of where rc is not checked by name is in
> x86_emulate.c.  There are a lot of 0 and != 0 checks.  Also in area of
> code there are places that return X86EMUL_OKAY when it looks to me that
> the return value is checked for 0 and ignored otherwise.

The point aren't the checks against zero, but the ones against the
#define-d values. Code may exist that, after excluding certain
values, assumes that only some specific value can be left. While
we aim at adding ASSERT()s for such cases, I'm nowhere near to
being convinced this is the case everywhere.

> So I will agree that the use of these defines is complex.  However, I
> need a way to pass back X86EMUL_UNHANDLEABLE and send a few registers to
> QEMU.  Now since the code path that I need to do this is:
> 
> ...
>  hvmemul_do_io
>   hvm_portio_intercept
>    hvm_io_intercept
>     process_portio_intercept
>      vmport_ioport
> 
> 
> Since there is only 1 caller to hvm_portio_intercept() --
> hvmemul_do_io, and hvmemul_do_io does not let X86EMUL_VMPORT_SEND be
> returned. I feel that all code paths currently have been checked.
> Adding a return code to me was the simpler code change.  It is possible
> to change process_portio_intercept() by adding special code there to
> adjust the ioreq_t p there, but that looked worse to me.
> 
> I can change to using a bit in the return of portio_action_t that would
> be masked in process_portio_intercept() and make the code in
> hvmemul_do_io() less clear since the change of p->type changes in
> process_portio_intercept(), and change to hvmemul_do_io() is much more
> involved.
> 
> I am happy to use some other number like 65539 if that would help. Also
> any other name like X86EMUL_UNHANDLEABLE_EXTENDED, SPECIAL_DM_HANDLING,
> etc would be fine with me.  I have no issue with defining this in a
> different header file if that would help.

I understand all this is non-trivial and not necessarily obvious. But
as said before - the x86 instruction emulator should please remain
something acting along _only_ architectural specifications. Any
extensions to support things like what you want to do here should
be added using neutral hooks, responsible for keeping state they
need on their own.

>>> --- a/xen/include/public/hvm/hvm_op.h
>>> +++ b/xen/include/public/hvm/hvm_op.h
>>> @@ -314,6 +314,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
>>>   *
>>>   * NOTE: unless an emulation request falls entirely within a range mapped
>>>   * by a secondary emulator, it will not be passed to that emulator.
>>> + *
>>> + * NOTE: The 'special' range of 1 is what is checked for outside
>>> + * of the three types of I/O.
>>>   */
>>>  #define HVMOP_map_io_range_to_ioreq_server 19
>>>  #define HVMOP_unmap_io_range_from_ioreq_server 20
>>> @@ -324,6 +327,9 @@ struct xen_hvm_io_range {
>>>  # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
>>>  # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
>>>  # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
>>> +# define HVMOP_IO_RANGE_VMWARE_PORT 3 /* VMware port special range */
>>> +# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range */
>>> +# define HVMOP_IO_RANGE_INVALIDATE 8 /* INVALIDATE special range */
>> 
>> I can't seem to connect the comment you add above to the three
>> new #define-s.
>> 
> 
> Will work on better wording for the comment here and in the code
> that is checking for it.  Paul Durrant pointed out that
> HVMOP_IO_RANGE_INVALIDATE is not needed and so the plan is to drop it.
> Does:
> 
>  + * NOTE: The 'special' range of 1 is what is checked for on
>  + * VMWARE_PORT and TIMEOFFSET.
> 
> help?

Calling out the affected ones explicitly is certainly better. Beyond
that see my earlier remark.

>>> --- a/xen/include/public/hvm/ioreq.h
>>> +++ b/xen/include/public/hvm/ioreq.h
>>> @@ -35,6 +35,7 @@
>>>  #define IOREQ_TYPE_PIO          0 /* pio */
>>>  #define IOREQ_TYPE_COPY         1 /* mmio ops */
>>>  #define IOREQ_TYPE_PCI_CONFIG   2
>>> +#define IOREQ_TYPE_VMWARE_PORT  3
>>>  #define IOREQ_TYPE_TIMEOFFSET   7
>>>  #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
>> 
>> Are you sure (re-)using a value in the middle is safe? Did you check
>> where the sparseness originates from?
>> 
> 
> 99% sure.  It looks like a RHEL 5 dom0 still has code for IOREQ_TYPE_OR.
> I have no idea how a Xen 4.6 HVM guest would pass a ioreq to Dom0 kernel
> instead of to QEMU or QEMU Traditional.
> 
> Some background.  When Julien Grall added 2, this was said:
> 
> Keir Fraser
> [...]
> They were almost certainly used for representing R-M-W ALU operations back
> in the days of the old IO emulator, very long ago. Still, there''s no
> harm in
> leaving them unused.
> [...]
> I did find the old defn:
> 
> dcs-xen-54:~/xen>git show 4ff8936 | grep IOREQ_TYPE_
> #define IOREQ_TYPE_PIO          0 /* pio */
> #define IOREQ_TYPE_COPY         1 /* mmio ops */
> #define IOREQ_TYPE_AND          2
> #define IOREQ_TYPE_OR           3
> #define IOREQ_TYPE_XOR          4
> #define IOREQ_TYPE_XCHG         5
> #define IOREQ_TYPE_ADD          6
> [...]
> Which matches what Keir Fraser said.
> 
> I did not find why Paul Durrant did not use 9.  I can only find it as 2
> in all Paul's patch sets.  Which is closely connected to:
> 
>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
> 
> (a new hyper call arg).  This also did not add a hole in "range" so
> Paul Durrant did not have to check for a "range" hole.
> 
> So I did just like Paul Durrant did.  He also approved the patch with
> this number in QEMU.  Since this is now in upstream QEMU, changing it at
> this time is a slower process.  Since the only time QEMU uses its
> version is when Xen header files are missing, I do not see how a QEMU
> built with its version would be usable as a QEMU for Xen.  So I am
> happy to change to a new number like 9.

Yes please. I'm not saying we absolutely have to correct the one
Paul added (unless we learn it causes problems), but I think we
should avoid making the same (even if only potential) mistake twice.
Of course it would help to get insight from Paul (now Cc-ed) here.

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-26  8:07       ` Jan Beulich
@ 2015-02-26 11:49         ` Paul Durrant
  2015-02-26 14:55           ` Don Slutz
  2015-02-26 19:52         ` Don Slutz
  1 sibling, 1 reply; 71+ messages in thread
From: Paul Durrant @ 2015-02-26 11:49 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Tim (Xen.org), Kevin Tian, Keir (Xen.org),
	Ian Campbell, Jun Nakajima, Andrew Cooper, Eddie Dong,
	George Dunlap, xen-devel, Stefano Stabellini,
	Aravind Gopalakrishnan, Suravee Suthikulpanit, Ian Jackson,
	Boris Ostrovsky

> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: 26 February 2015 08:08
> To: Don Slutz
> Cc: Aravind Gopalakrishnan; Suravee Suthikulpanit; Andrew Cooper; Ian
> Campbell; Paul Durrant; George Dunlap; Ian Jackson; Stefano Stabellini; Eddie
> Dong; Jun Nakajima; Kevin Tian; xen-devel@lists.xen.org; Boris Ostrovsky;
> Konrad Rzeszutek Wilk; Keir (Xen.org); Tim (Xen.org)
> Subject: Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
> 
> >>> On 25.02.15 at 21:20, <dslutz@verizon.com> wrote:
> > On 02/24/15 10:34, Jan Beulich wrote:
> >>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
> >>> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct
> domain *d, unsigned long gmfn)
> >>>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
> >>>  }
> >>>
> >>> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s,
> bool_t buf)
> >>> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int
> buf)
> >>>  {
> >>> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> >>> +    struct hvm_ioreq_page *iorp = NULL;
> >>> +
> >>> +    switch ( buf )
> >>> +    {
> >>> +    case 0:
> >>> +        iorp = &s->ioreq;
> >>> +        break;
> >>> +    case 1:
> >>> +        iorp = &s->bufioreq;
> >>> +        break;
> >>> +    case 2:
> >>> +        iorp = &s->vmport_ioreq;
> >>> +        break;
> >>> +    }
> >>
> >> These literals should become an enum.
> >>
> >
> > Paul Durrant asked for #defined values.  So it is not clear which way to
> > go. Will wait for response.
> 
> Obviously either would be fine. An enum has the potential advantage
> of the compiler being able to check switch statements for completeness
> (albeit there are cases where this ends up being a disadvantage).
> 

I'm fine with an enum... just not with (repeated) magic numbers in the code.

[snip]
> > Some background.  When Julien Grall added 2, this was said:
> >
> > Keir Fraser
> > [...]
> > They were almost certainly used for representing R-M-W ALU operations
> back
> > in the days of the old IO emulator, very long ago. Still, there''s no
> > harm in
> > leaving them unused.
> > [...]
> > I did find the old defn:
> >
> > dcs-xen-54:~/xen>git show 4ff8936 | grep IOREQ_TYPE_
> > #define IOREQ_TYPE_PIO          0 /* pio */
> > #define IOREQ_TYPE_COPY         1 /* mmio ops */
> > #define IOREQ_TYPE_AND          2
> > #define IOREQ_TYPE_OR           3
> > #define IOREQ_TYPE_XOR          4
> > #define IOREQ_TYPE_XCHG         5
> > #define IOREQ_TYPE_ADD          6
> > [...]
> > Which matches what Keir Fraser said.
> >
> > I did not find why Paul Durrant did not use 9.  I can only find it as 2
> > in all Paul's patch sets.  Which is closely connected to:
> >
> >          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
> >          BUILD_BUG_ON(IOREQ_TYPE_COPY !=
> HVMOP_IO_RANGE_MEMORY);
> >          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG !=
> HVMOP_IO_RANGE_PCI);
> >
> > (a new hyper call arg).  This also did not add a hole in "range" so
> > Paul Durrant did not have to check for a "range" hole.
> >
> > So I did just like Paul Durrant did.  He also approved the patch with
> > this number in QEMU.  Since this is now in upstream QEMU, changing it at
> > this time is a slower process.  Since the only time QEMU uses its
> > version is when Xen header files are missing, I do not see how a QEMU
> > built with its version would be usable as a QEMU for Xen.  So I am
> > happy to change to a new number like 9.
> 
> Yes please. I'm not saying we absolutely have to correct the one
> Paul added (unless we learn it causes problems), but I think we
> should avoid making the same (even if only potential) mistake twice.
> Of course it would help to get insight from Paul (now Cc-ed) here.
> 

I used the hole because I really did not think anyone would ever expect to use an ancient emulator against a recent Xen. Given there has been no fallout I don't see why we can't use the hole.

  Paul

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-26 11:49         ` Paul Durrant
@ 2015-02-26 14:55           ` Don Slutz
  2015-02-26 15:00             ` Paul Durrant
  2015-02-26 15:10             ` Jan Beulich
  0 siblings, 2 replies; 71+ messages in thread
From: Don Slutz @ 2015-02-26 14:55 UTC (permalink / raw)
  To: Paul Durrant, Jan Beulich, Don Slutz
  Cc: Tim (Xen.org), Kevin Tian, Keir (Xen.org),
	Ian Campbell, Jun Nakajima, Andrew Cooper, Eddie Dong,
	George Dunlap, xen-devel, Stefano Stabellini,
	Aravind Gopalakrishnan, Suravee Suthikulpanit, Ian Jackson,
	Boris Ostrovsky

On 02/26/15 06:49, Paul Durrant wrote:
>> -----Original Message-----
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: 26 February 2015 08:08
>> To: Don Slutz
>> Cc: Aravind Gopalakrishnan; Suravee Suthikulpanit; Andrew Cooper; Ian
>> Campbell; Paul Durrant; George Dunlap; Ian Jackson; Stefano Stabellini; Eddie
>> Dong; Jun Nakajima; Kevin Tian; xen-devel@lists.xen.org; Boris Ostrovsky;
>> Konrad Rzeszutek Wilk; Keir (Xen.org); Tim (Xen.org)
>> Subject: Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
>>
>>>>> On 25.02.15 at 21:20, <dslutz@verizon.com> wrote:
>>> On 02/24/15 10:34, Jan Beulich wrote:
>>>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>>>> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct
>> domain *d, unsigned long gmfn)
>>>>>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
>>>>>  }
>>>>>
>>>>> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s,
>> bool_t buf)
>>>>> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int
>> buf)
>>>>>  {
>>>>> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>>>>> +    struct hvm_ioreq_page *iorp = NULL;
>>>>> +
>>>>> +    switch ( buf )
>>>>> +    {
>>>>> +    case 0:
>>>>> +        iorp = &s->ioreq;
>>>>> +        break;
>>>>> +    case 1:
>>>>> +        iorp = &s->bufioreq;
>>>>> +        break;
>>>>> +    case 2:
>>>>> +        iorp = &s->vmport_ioreq;
>>>>> +        break;
>>>>> +    }
>>>>
>>>> These literals should become an enum.
>>>>
>>>
>>> Paul Durrant asked for #defined values.  So it is not clear which way to
>>> go. Will wait for response.
>>
>> Obviously either would be fine. An enum has the potential advantage
>> of the compiler being able to check switch statements for completeness
>> (albeit there are cases where this ends up being a disadvantage).
>>
> 
> I'm fine with an enum... just not with (repeated) magic numbers in the code.
> 

Ok, will use enum.


> [snip]
>>> Some background.  When Julien Grall added 2, this was said:
>>>
>>> Keir Fraser
>>> [...]
>>> They were almost certainly used for representing R-M-W ALU operations
>> back
>>> in the days of the old IO emulator, very long ago. Still, there''s no
>>> harm in
>>> leaving them unused.
>>> [...]
>>> I did find the old defn:
>>>
>>> dcs-xen-54:~/xen>git show 4ff8936 | grep IOREQ_TYPE_
>>> #define IOREQ_TYPE_PIO          0 /* pio */
>>> #define IOREQ_TYPE_COPY         1 /* mmio ops */
>>> #define IOREQ_TYPE_AND          2
>>> #define IOREQ_TYPE_OR           3
>>> #define IOREQ_TYPE_XOR          4
>>> #define IOREQ_TYPE_XCHG         5
>>> #define IOREQ_TYPE_ADD          6
>>> [...]
>>> Which matches what Keir Fraser said.
>>>
>>> I did not find why Paul Durrant did not use 9.  I can only find it as 2
>>> in all Paul's patch sets.  Which is closely connected to:
>>>
>>>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>>>          BUILD_BUG_ON(IOREQ_TYPE_COPY !=
>> HVMOP_IO_RANGE_MEMORY);
>>>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG !=
>> HVMOP_IO_RANGE_PCI);
>>>
>>> (a new hyper call arg).  This also did not add a hole in "range" so
>>> Paul Durrant did not have to check for a "range" hole.
>>>
>>> So I did just like Paul Durrant did.  He also approved the patch with
>>> this number in QEMU.  Since this is now in upstream QEMU, changing it at
>>> this time is a slower process.  Since the only time QEMU uses its
>>> version is when Xen header files are missing, I do not see how a QEMU
>>> built with its version would be usable as a QEMU for Xen.  So I am
>>> happy to change to a new number like 9.
>>
>> Yes please. I'm not saying we absolutely have to correct the one
>> Paul added (unless we learn it causes problems), but I think we
>> should avoid making the same (even if only potential) mistake twice.
>> Of course it would help to get insight from Paul (now Cc-ed) here.
>>
> 
> I used the hole because I really did not think anyone would
> ever expect to use an ancient emulator against a recent
> Xen. Given there has been no fallout I don't see why we can't
> use the hole.


Well, this is a little confusing (I read this as Paul is fine with 3).
Since both Jan Beulich and Keir Fraser want to skip the hole, I will
switch to 9.

   -Don Slutz

>   Paul
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-26 14:55           ` Don Slutz
@ 2015-02-26 15:00             ` Paul Durrant
  2015-02-26 15:10             ` Jan Beulich
  1 sibling, 0 replies; 71+ messages in thread
From: Paul Durrant @ 2015-02-26 15:00 UTC (permalink / raw)
  To: Don Slutz, Jan Beulich
  Cc: Tim (Xen.org), Kevin Tian, Keir (Xen.org),
	Ian Campbell, Jun Nakajima, Andrew Cooper, Eddie Dong,
	George Dunlap, xen-devel, Stefano Stabellini,
	Aravind Gopalakrishnan, Suravee Suthikulpanit, Ian Jackson,
	Boris Ostrovsky

> -----Original Message-----
> From: Don Slutz [mailto:dslutz@verizon.com]
> Sent: 26 February 2015 14:55
> To: Paul Durrant; Jan Beulich; Don Slutz
> Cc: Aravind Gopalakrishnan; Suravee Suthikulpanit; Andrew Cooper; Ian
> Campbell; George Dunlap; Ian Jackson; Stefano Stabellini; Eddie Dong; Jun
> Nakajima; Kevin Tian; xen-devel@lists.xen.org; Boris Ostrovsky; Konrad
> Rzeszutek Wilk; Keir (Xen.org); Tim (Xen.org)
> Subject: Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
> 
> On 02/26/15 06:49, Paul Durrant wrote:
> >> -----Original Message-----
> >> From: Jan Beulich [mailto:JBeulich@suse.com]
> >> Sent: 26 February 2015 08:08
> >> To: Don Slutz
> >> Cc: Aravind Gopalakrishnan; Suravee Suthikulpanit; Andrew Cooper; Ian
> >> Campbell; Paul Durrant; George Dunlap; Ian Jackson; Stefano Stabellini;
> Eddie
> >> Dong; Jun Nakajima; Kevin Tian; xen-devel@lists.xen.org; Boris Ostrovsky;
> >> Konrad Rzeszutek Wilk; Keir (Xen.org); Tim (Xen.org)
> >> Subject: Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
> >>
> >>>>> On 25.02.15 at 21:20, <dslutz@verizon.com> wrote:
> >>> On 02/24/15 10:34, Jan Beulich wrote:
> >>>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
> >>>>> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct
> >> domain *d, unsigned long gmfn)
> >>>>>      clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
> >>>>>  }
> >>>>>
> >>>>> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s,
> >> bool_t buf)
> >>>>> +static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, int
> >> buf)
> >>>>>  {
> >>>>> -    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> >>>>> +    struct hvm_ioreq_page *iorp = NULL;
> >>>>> +
> >>>>> +    switch ( buf )
> >>>>> +    {
> >>>>> +    case 0:
> >>>>> +        iorp = &s->ioreq;
> >>>>> +        break;
> >>>>> +    case 1:
> >>>>> +        iorp = &s->bufioreq;
> >>>>> +        break;
> >>>>> +    case 2:
> >>>>> +        iorp = &s->vmport_ioreq;
> >>>>> +        break;
> >>>>> +    }
> >>>>
> >>>> These literals should become an enum.
> >>>>
> >>>
> >>> Paul Durrant asked for #defined values.  So it is not clear which way to
> >>> go. Will wait for response.
> >>
> >> Obviously either would be fine. An enum has the potential advantage
> >> of the compiler being able to check switch statements for completeness
> >> (albeit there are cases where this ends up being a disadvantage).
> >>
> >
> > I'm fine with an enum... just not with (repeated) magic numbers in the
> code.
> >
> 
> Ok, will use enum.
> 
> 
> > [snip]
> >>> Some background.  When Julien Grall added 2, this was said:
> >>>
> >>> Keir Fraser
> >>> [...]
> >>> They were almost certainly used for representing R-M-W ALU
> operations
> >> back
> >>> in the days of the old IO emulator, very long ago. Still, there''s no
> >>> harm in
> >>> leaving them unused.
> >>> [...]
> >>> I did find the old defn:
> >>>
> >>> dcs-xen-54:~/xen>git show 4ff8936 | grep IOREQ_TYPE_
> >>> #define IOREQ_TYPE_PIO          0 /* pio */
> >>> #define IOREQ_TYPE_COPY         1 /* mmio ops */
> >>> #define IOREQ_TYPE_AND          2
> >>> #define IOREQ_TYPE_OR           3
> >>> #define IOREQ_TYPE_XOR          4
> >>> #define IOREQ_TYPE_XCHG         5
> >>> #define IOREQ_TYPE_ADD          6
> >>> [...]
> >>> Which matches what Keir Fraser said.
> >>>
> >>> I did not find why Paul Durrant did not use 9.  I can only find it as 2
> >>> in all Paul's patch sets.  Which is closely connected to:
> >>>
> >>>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
> >>>          BUILD_BUG_ON(IOREQ_TYPE_COPY !=
> >> HVMOP_IO_RANGE_MEMORY);
> >>>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG !=
> >> HVMOP_IO_RANGE_PCI);
> >>>
> >>> (a new hyper call arg).  This also did not add a hole in "range" so
> >>> Paul Durrant did not have to check for a "range" hole.
> >>>
> >>> So I did just like Paul Durrant did.  He also approved the patch with
> >>> this number in QEMU.  Since this is now in upstream QEMU, changing it
> at
> >>> this time is a slower process.  Since the only time QEMU uses its
> >>> version is when Xen header files are missing, I do not see how a QEMU
> >>> built with its version would be usable as a QEMU for Xen.  So I am
> >>> happy to change to a new number like 9.
> >>
> >> Yes please. I'm not saying we absolutely have to correct the one
> >> Paul added (unless we learn it causes problems), but I think we
> >> should avoid making the same (even if only potential) mistake twice.
> >> Of course it would help to get insight from Paul (now Cc-ed) here.
> >>
> >
> > I used the hole because I really did not think anyone would
> > ever expect to use an ancient emulator against a recent
> > Xen. Given there has been no fallout I don't see why we can't
> > use the hole.
> 
> 
> Well, this is a little confusing (I read this as Paul is fine with 3).
> Since both Jan Beulich and Keir Fraser want to skip the hole, I will
> switch to 9.

I read Keir's comment as meaning he didn't care either way. If Jan wants to use 9 then I have no objection.

  Paul

> 
>    -Don Slutz
> 
> >   Paul
> >

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-26 14:55           ` Don Slutz
  2015-02-26 15:00             ` Paul Durrant
@ 2015-02-26 15:10             ` Jan Beulich
  1 sibling, 0 replies; 71+ messages in thread
From: Jan Beulich @ 2015-02-26 15:10 UTC (permalink / raw)
  To: Don Slutz
  Cc: Tim (Xen.org), Kevin Tian, Keir (Xen.org),
	Ian Campbell, Jun Nakajima, Andrew Cooper, Eddie Dong,
	George Dunlap, xen-devel, Stefano Stabellini, Paul Durrant,
	Aravind Gopalakrishnan, Suravee Suthikulpanit, Ian Jackson,
	Boris Ostrovsky

>>> On 26.02.15 at 15:55, <dslutz@verizon.com> wrote:
> Well, this is a little confusing (I read this as Paul is fine with 3).
> Since both Jan Beulich and Keir Fraser want to skip the hole, I will
> switch to 9.

If not leaving a hole makes the code meaningfully simpler, then go
with what you have. But if the hole left doesn't cause any other
problem for you, then (citing Keir) "there's no harm in leaving them
unused".

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-26  8:07       ` Jan Beulich
  2015-02-26 11:49         ` Paul Durrant
@ 2015-02-26 19:52         ` Don Slutz
  2015-02-27  7:48           ` Jan Beulich
  1 sibling, 1 reply; 71+ messages in thread
From: Don Slutz @ 2015-02-26 19:52 UTC (permalink / raw)
  To: Jan Beulich, Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Eddie Dong, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	Kevin Tian, xen-devel, Paul Durrant, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

[-- Attachment #1: Type: text/plain, Size: 10418 bytes --]

On 02/26/15 03:07, Jan Beulich wrote:
>>>> On 25.02.15 at 21:20, <dslutz@verizon.com> wrote:
>> On 02/24/15 10:34, Jan Beulich wrote:
>>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>>> @@ -501,22 +542,50 @@ static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)

[snip]

>>>> @@ -2429,9 +2552,6 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct 
>> domain *d,
>>>>      if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
>>>>          return NULL;
>>>>  
>>>> -    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
>>>> -        return d->arch.hvm_domain.default_ioreq_server;
>>>
>>> Shouldn't this rather be amended than deleted?
>>>
>>
>> The reason is below:
>>
>>>> @@ -2474,7 +2594,12 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>>>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>>>>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>>>>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
>>>> +        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
>>>> +        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
>>>> +        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE != HVMOP_IO_RANGE_INVALIDATE);
>>>>          r = s->range[type];
>>>> +        if ( !r )
>>>> +            continue;
>>>
>>> Why, all of the sudden?
>>>
>>
>> This is the replacement for the deleted "if" above.  Continue will lead
>> to the same return that was remove above (it is at the end).  They are
>> currently the same because all ioreq servers have the same set of
>> ranges.  But if it would help, I can change "continue" into the "return
>> default".
> 
> So further down you talk of the "special range 1" (see there for
> further remarks in this regard) - how would r be NULL here in the
> first place?

Since there is a hole in the #defines 0,1,2,7,8 (currently) range[6] is
where r will be NULL for example.  However no current code should be
able to get here.  So if you want me to I can drop the "if".

> That said - yes, making this explicitly do what is
> intended (perhaps rather using "break" instead of "return") would
> seem very desirable. There simply is no point in continuing the
> loop.
> 

Will use break if the "if" is not dropped.

>>>> @@ -2501,6 +2626,13 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>>>              }
>>>>  
>>>>              break;
>>>> +        case IOREQ_TYPE_VMWARE_PORT:
>>>> +        case IOREQ_TYPE_TIMEOFFSET:
>>>> +        case IOREQ_TYPE_INVALIDATE:
>>>> +            if ( rangeset_contains_singleton(r, 1) )
>>>> +                return s;
>>>
>>> This literal 1 at least needs explanation (i.e. a comment).
>>>
>>
>> The comment is below (copied here).  Will duplicate it here (with any
>> adjustments needed):
>>
>>  + * NOTE: The 'special' range of 1 is what is checked for outside
>>  + * of the three types of I/O.
>>
>> How about /* The 'special' range of 1 is checked for being enabled */?
> 
> Along these lines, yes (fixed for coding style). And then "1" is not
> a range of any kind. I suppose writing it as a proper range (e.g.
> [1,1]) would already help.
> 

I will adjust to using [1,1].

>>>> --- a/xen/arch/x86/x86_emulate/x86_emulate.h
>>>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.h
>>>> @@ -112,6 +112,8 @@ struct __packed segment_register {
>>>>  #define X86EMUL_RETRY          3
>>>>   /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
>>>>  #define X86EMUL_CMPXCHG_FAILED 3
>>>> + /* Send part of registers also to DM. */
>>>> +#define X86EMUL_VMPORT_SEND    4
>>>
>>> Introducing a new value here seems rather fragile, as various code
>>> paths you don't touch would need auditing that they do the right
>>> thing upon this value being returned. Plus even conceptually this
>>> doesn't belong here - the instruction emulator shouldn't be concerned
>>> with things like VMware emulation.
>>>
>>
>> The only place I know of where rc is not checked by name is in
>> x86_emulate.c.  There are a lot of 0 and != 0 checks.  Also in area of
>> code there are places that return X86EMUL_OKAY when it looks to me that
>> the return value is checked for 0 and ignored otherwise.
> 
> The point aren't the checks against zero, but the ones against the
> #define-d values. Code may exist that, after excluding certain
> values, assumes that only some specific value can be left. While
> we aim at adding ASSERT()s for such cases, I'm nowhere near to
> being convinced this is the case everywhere.
> 
>> So I will agree that the use of these defines is complex.  However, I
>> need a way to pass back X86EMUL_UNHANDLEABLE and send a few registers to
>> QEMU.  Now since the code path that I need to do this is:
>>
>> ...
>>  hvmemul_do_io
>>   hvm_portio_intercept
>>    hvm_io_intercept
>>     process_portio_intercept
>>      vmport_ioport
>>
>>
>> Since there is only 1 caller to hvm_portio_intercept() --
>> hvmemul_do_io, and hvmemul_do_io does not let X86EMUL_VMPORT_SEND be
>> returned. I feel that all code paths currently have been checked.
>> Adding a return code to me was the simpler code change.  It is possible
>> to change process_portio_intercept() by adding special code there to
>> adjust the ioreq_t p there, but that looked worse to me.
>>
>> I can change to using a bit in the return of portio_action_t that would
>> be masked in process_portio_intercept() and make the code in
>> hvmemul_do_io() less clear since the change of p->type changes in
>> process_portio_intercept(), and change to hvmemul_do_io() is much more
>> involved.
>>
>> I am happy to use some other number like 65539 if that would help. Also
>> any other name like X86EMUL_UNHANDLEABLE_EXTENDED, SPECIAL_DM_HANDLING,
>> etc would be fine with me.  I have no issue with defining this in a
>> different header file if that would help.
> 
> I understand all this is non-trivial and not necessarily obvious. But
> as said before - the x86 instruction emulator should please remain
> something acting along _only_ architectural specifications. Any
> extensions to support things like what you want to do here should
> be added using neutral hooks, responsible for keeping state they
> need on their own.
> 


How does (the incorrectly formatted for a smaller diff):

diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index f271dfc..9027ab8 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -219,6 +219,7 @@ static int hvmemul_do_io(
             vio->io_state = HVMIO_handle_mmio_awaiting_completion;
         break;
     case X86EMUL_UNHANDLEABLE:
+        if ( vmport_check_port(p.addr) )
     {
         struct hvm_ioreq_server *s =
             hvm_select_ioreq_server(curr->domain, &p);
@@ -238,8 +239,50 @@ static int hvmemul_do_io(
             else if ( p_data == NULL )
                 rc = X86EMUL_OKAY;
         }
-        break;
     }
+    else
+    {
+        struct hvm_ioreq_server *s;
+        vmware_regs_t *vr;
+
+        BUILD_BUG_ON(sizeof(ioreq_t) < sizeof(vmware_regs_t));
+
+        p.type = IOREQ_TYPE_VMWARE_PORT;
+        s = hvm_select_ioreq_server(curr->domain, &p);
+        vr = get_vmport_regs_any(s, curr);
+
+        /*
+         * If there is no suitable backing DM, just ignore accesses.  If
+         * we do not have access to registers to pass to QEMU, just
+         * ignore access.
+         */
+        if ( !s || !vr )
+        {
+            hvm_complete_assist_req(&p);
+            rc = X86EMUL_OKAY;
+            vio->io_state = HVMIO_none;
+        }
+        else
+        {
+            struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+            p.data = regs->rax;
+            vr->ebx = regs->_ebx;
+            vr->ecx = regs->_ecx;
+            vr->edx = regs->_edx;
+            vr->esi = regs->_esi;
+            vr->edi = regs->_edi;
+
+            vio->io_state = HVMIO_handle_pio_awaiting_completion;
+            if ( !hvm_send_assist_req(s, &p) )
+            {
+                rc = X86EMUL_RETRY;
+                vio->io_state = HVMIO_none;
+            }
+            /* else leave rc as X86EMUL_UNHANDLEABLE for below. */
+        }
+    }
+        break;
     default:
         BUG();
     }
@@ -248,6 +291,13 @@ static int hvmemul_do_io(
     {
         if ( ram_page )
             put_page(ram_page);
+        /*
+         * If rc is still X86EMUL_UNHANDLEABLE, then were are of
+         * type IOREQ_TYPE_VMWARE_PORT, so completion in
+         * hvm_io_assist() with no re-emulation required
+         */
+        if ( rc == X86EMUL_UNHANDLEABLE )
+            rc = X86EMUL_OKAY;
         return rc;
     }


look as the change to emulate.c?

Attached is the perspective version of this patch.


>>>> --- a/xen/include/public/hvm/hvm_op.h
>>>> +++ b/xen/include/public/hvm/hvm_op.h
>>>> @@ -314,6 +314,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
>>>>   *
>>>>   * NOTE: unless an emulation request falls entirely within a range mapped
>>>>   * by a secondary emulator, it will not be passed to that emulator.
>>>> + *
>>>> + * NOTE: The 'special' range of 1 is what is checked for outside
>>>> + * of the three types of I/O.
>>>>   */
>>>>  #define HVMOP_map_io_range_to_ioreq_server 19
>>>>  #define HVMOP_unmap_io_range_from_ioreq_server 20
>>>> @@ -324,6 +327,9 @@ struct xen_hvm_io_range {
>>>>  # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
>>>>  # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
>>>>  # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
>>>> +# define HVMOP_IO_RANGE_VMWARE_PORT 3 /* VMware port special range */
>>>> +# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range */
>>>> +# define HVMOP_IO_RANGE_INVALIDATE 8 /* INVALIDATE special range */
>>>
>>> I can't seem to connect the comment you add above to the three
>>> new #define-s.
>>>
>>
>> Will work on better wording for the comment here and in the code
>> that is checking for it.  Paul Durrant pointed out that
>> HVMOP_IO_RANGE_INVALIDATE is not needed and so the plan is to drop it.
>> Does:
>>
>>  + * NOTE: The 'special' range of 1 is what is checked for on
>>  + * VMWARE_PORT and TIMEOFFSET.
>>
>> help?
> 
> Calling out the affected ones explicitly is certainly better. Beyond
> that see my earlier remark.
> 

Also adjust to [1,1].

Rest is done in a different thread.

   -Don Slutz

> Jan
> 

[-- Attachment #2: 0016-Add-IOREQ_TYPE_VMWARE_PORT.patch --]
[-- Type: text/x-patch, Size: 20757 bytes --]

>From 28dfe010a6c1b791d933a3cbd41fcbdfcfc009c1 Mon Sep 17 00:00:00 2001
From: Don Slutz <dslutz@verizon.com>
Date: Thu, 25 Sep 2014 09:07:39 -0400
Subject: [PATCH 16/19] Add IOREQ_TYPE_VMWARE_PORT

This adds synchronization 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

In the tools, enable usage of QEMU's vmport code.

The currently most useful VMware port support that QEMU has is the
VMware mouse support.  Xorg included a VMware mouse support that
uses absolute mode.  This make using a mouse in X11 much nicer.

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
 tools/libxc/xc_hvm_build_x86.c   |   5 +-
 tools/libxl/libxl_dm.c           |   4 +
 xen/arch/x86/hvm/emulate.c       |  52 +++++++++++-
 xen/arch/x86/hvm/hvm.c           | 170 ++++++++++++++++++++++++++++++++++-----
 xen/arch/x86/hvm/io.c            |  16 ++++
 xen/arch/x86/hvm/vmware/vmport.c |   9 ++-
 xen/include/asm-x86/hvm/domain.h |   3 +-
 xen/include/asm-x86/hvm/hvm.h    |   1 +
 xen/include/public/hvm/hvm_op.h  |   5 ++
 xen/include/public/hvm/ioreq.h   |  17 ++++
 xen/include/public/hvm/params.h  |   4 +-
 11 files changed, 259 insertions(+), 27 deletions(-)

diff --git a/tools/libxc/xc_hvm_build_x86.c b/tools/libxc/xc_hvm_build_x86.c
index c81a25b..e338667 100644
--- a/tools/libxc/xc_hvm_build_x86.c
+++ b/tools/libxc/xc_hvm_build_x86.c
@@ -46,7 +46,8 @@
 #define SPECIALPAGE_IOREQ    5
 #define SPECIALPAGE_IDENT_PT 6
 #define SPECIALPAGE_CONSOLE  7
-#define NR_SPECIAL_PAGES     8
+#define SPECIALPAGE_VMPORT_REGS 8
+#define NR_SPECIAL_PAGES     9
 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x))
 
 #define NR_IOREQ_SERVER_PAGES 8
@@ -493,6 +494,8 @@ static int setup_guest(xc_interface *xch,
                      special_pfn(SPECIALPAGE_BUFIOREQ));
     xc_hvm_param_set(xch, dom, HVM_PARAM_IOREQ_PFN,
                      special_pfn(SPECIALPAGE_IOREQ));
+    xc_hvm_param_set(xch, dom, HVM_PARAM_VMPORT_REGS_PFN,
+                     special_pfn(SPECIALPAGE_VMPORT_REGS));
     xc_hvm_param_set(xch, dom, HVM_PARAM_CONSOLE_PFN,
                      special_pfn(SPECIALPAGE_CONSOLE));
     xc_hvm_param_set(xch, dom, HVM_PARAM_PAGING_RING_PFN,
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index c27f9a4..620013c 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -765,6 +765,10 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
                                             machinearg, max_ram_below_4g);
             }
         }
+        if (libxl_defbool_val(c_info->vmware_port)) {
+            machinearg = libxl__sprintf(gc, "%s,vmport=on",
+                                        machinearg);
+        }
         flexarray_append(dm_args, machinearg);
         for (i = 0; b_info->extra_hvm && b_info->extra_hvm[i] != NULL; i++)
             flexarray_append(dm_args, b_info->extra_hvm[i]);
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index f271dfc..eeaa3ba 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -219,6 +219,7 @@ static int hvmemul_do_io(
             vio->io_state = HVMIO_handle_mmio_awaiting_completion;
         break;
     case X86EMUL_UNHANDLEABLE:
+        if ( vmport_check_port(p.addr) )
     {
         struct hvm_ioreq_server *s =
             hvm_select_ioreq_server(curr->domain, &p);
@@ -238,8 +239,50 @@ static int hvmemul_do_io(
             else if ( p_data == NULL )
                 rc = X86EMUL_OKAY;
         }
-        break;
     }
+    else
+    {
+        struct hvm_ioreq_server *s;
+        vmware_regs_t *vr;
+
+        BUILD_BUG_ON(sizeof(ioreq_t) < sizeof(vmware_regs_t));
+
+        p.type = IOREQ_TYPE_VMWARE_PORT;
+        s = hvm_select_ioreq_server(curr->domain, &p);
+        vr = get_vmport_regs_any(s, curr);
+
+        /*
+         * If there is no suitable backing DM, just ignore accesses.  If
+         * we do not have access to registers to pass to QEMU, just
+         * ignore access.
+         */
+        if ( !s || !vr )
+        {
+            hvm_complete_assist_req(&p);
+            rc = X86EMUL_OKAY;
+            vio->io_state = HVMIO_none;
+        }
+        else
+        {
+            struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+            p.data = regs->rax;
+            vr->ebx = regs->_ebx;
+            vr->ecx = regs->_ecx;
+            vr->edx = regs->_edx;
+            vr->esi = regs->_esi;
+            vr->edi = regs->_edi;
+
+            vio->io_state = HVMIO_handle_pio_awaiting_completion;
+            if ( !hvm_send_assist_req(s, &p) )
+            {
+                rc = X86EMUL_RETRY;
+                vio->io_state = HVMIO_none;
+            }
+            /* else leave rc as X86EMUL_UNHANDLEABLE for below. */
+        }
+    }
+        break;
     default:
         BUG();
     }
@@ -248,6 +291,13 @@ static int hvmemul_do_io(
     {
         if ( ram_page )
             put_page(ram_page);
+        /*
+         * If rc is still X86EMUL_UNHANDLEABLE, then were are of
+         * type IOREQ_TYPE_VMWARE_PORT, so completion in
+         * hvm_io_assist() with no re-emulation required
+         */
+        if ( rc == X86EMUL_UNHANDLEABLE )
+            rc = X86EMUL_OKAY;
         return rc;
     }
 
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 1000a4f..59267dd 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -391,6 +391,47 @@ static ioreq_t *get_ioreq(struct hvm_ioreq_server *s, struct vcpu *v)
     return &p->vcpu_ioreq[v->vcpu_id];
 }
 
+static vmware_regs_t *get_vmport_regs_one(struct hvm_ioreq_server *s,
+                                          struct vcpu *v)
+{
+    struct hvm_ioreq_vcpu *sv;
+
+    list_for_each_entry ( sv,
+                          &s->ioreq_vcpu_list,
+                          list_entry )
+    {
+        if ( sv->vcpu == v )
+        {
+            shared_vmport_iopage_t *p = s->vmport_ioreq.va;
+            if ( !p )
+                return NULL;
+            return &p->vcpu_vmport_regs[v->vcpu_id];
+        }
+    }
+    return NULL;
+}
+
+vmware_regs_t *get_vmport_regs_any(struct hvm_ioreq_server *s, struct vcpu *v)
+{
+    struct domain *d = v->domain;
+
+    ASSERT((v == current) || !vcpu_runnable(v));
+
+    if ( s )
+        return get_vmport_regs_one(s, v);
+
+    list_for_each_entry ( s,
+                          &d->arch.hvm_domain.ioreq_server.list,
+                          list_entry )
+    {
+        vmware_regs_t *ret = get_vmport_regs_one(s, v);
+
+        if ( ret )
+            return ret;
+    }
+    return NULL;
+}
+
 bool_t hvm_io_pending(struct vcpu *v)
 {
     struct domain *d = v->domain;
@@ -500,22 +541,56 @@ static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)
     clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
 }
 
-static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
+typedef enum {
+    IOREQ_PAGE_TYPE_IOREQ,
+    IOREQ_PAGE_TYPE_BUFIOREQ,
+    IOREQ_PAGE_TYPE_VMPORT,
+} ioreq_page_type_t;
+
+static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, ioreq_page_type_t buf)
 {
-    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+    struct hvm_ioreq_page *iorp = NULL;
+
+    switch ( buf )
+    {
+    case IOREQ_PAGE_TYPE_IOREQ:
+        iorp = &s->ioreq;
+        break;
+    case IOREQ_PAGE_TYPE_BUFIOREQ:
+        iorp = &s->bufioreq;
+        break;
+    case IOREQ_PAGE_TYPE_VMPORT:
+        iorp = &s->vmport_ioreq;
+        break;
+    }
+    ASSERT(iorp);
 
     destroy_ring_for_helper(&iorp->va, iorp->page);
 }
 
 static int hvm_map_ioreq_page(
-    struct hvm_ioreq_server *s, bool_t buf, unsigned long gmfn)
+    struct hvm_ioreq_server *s, ioreq_page_type_t buf, unsigned long gmfn)
 {
     struct domain *d = s->domain;
-    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+    struct hvm_ioreq_page *iorp = NULL;
     struct page_info *page;
     void *va;
     int rc;
 
+    switch ( buf )
+    {
+    case IOREQ_PAGE_TYPE_IOREQ:
+        iorp = &s->ioreq;
+        break;
+    case IOREQ_PAGE_TYPE_BUFIOREQ:
+        iorp = &s->bufioreq;
+        break;
+    case IOREQ_PAGE_TYPE_VMPORT:
+        iorp = &s->vmport_ioreq;
+        break;
+    }
+    ASSERT(iorp);
+
     if ( (rc = prepare_ring_for_helper(d, gmfn, &page, &va)) )
         return rc;
 
@@ -734,7 +809,8 @@ static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
                                       bool_t is_default, bool_t handle_bufioreq)
 {
     struct domain *d = s->domain;
-    unsigned long ioreq_pfn, bufioreq_pfn;
+    unsigned long ioreq_pfn, bufioreq_pfn = 0;
+    unsigned long vmport_ioreq_pfn = d->arch.hvm_domain.params[HVM_PARAM_VMPORT_REGS_PFN];
     int rc;
 
     if ( is_default )
@@ -762,21 +838,29 @@ static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
         }
     }
 
-    rc = hvm_map_ioreq_page(s, 0, ioreq_pfn);
+    rc = hvm_map_ioreq_page(s, IOREQ_PAGE_TYPE_IOREQ, ioreq_pfn);
     if ( rc )
         goto fail3;
 
     if ( handle_bufioreq )
     {
-        rc = hvm_map_ioreq_page(s, 1, bufioreq_pfn);
+        rc = hvm_map_ioreq_page(s, IOREQ_PAGE_TYPE_BUFIOREQ, bufioreq_pfn);
         if ( rc )
             goto fail4;
     }
 
+    rc = hvm_map_ioreq_page(s, IOREQ_PAGE_TYPE_VMPORT, vmport_ioreq_pfn);
+    if ( rc )
+        goto fail5;
+
     return 0;
 
+fail5:
+    if ( handle_bufioreq )
+        hvm_unmap_ioreq_page(s, IOREQ_PAGE_TYPE_BUFIOREQ);
+
 fail4:
-    hvm_unmap_ioreq_page(s, 0);
+    hvm_unmap_ioreq_page(s, IOREQ_PAGE_TYPE_IOREQ);
 
 fail3:
     if ( !is_default && handle_bufioreq )
@@ -795,11 +879,15 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
 {
     struct domain *d = s->domain;
     bool_t handle_bufioreq = ( s->bufioreq.va != NULL );
+    bool_t handle_vmport_ioreq = ( s->vmport_ioreq.va != NULL );
+
+    if ( handle_vmport_ioreq )
+        hvm_unmap_ioreq_page(s, IOREQ_PAGE_TYPE_VMPORT);
 
     if ( handle_bufioreq )
-        hvm_unmap_ioreq_page(s, 1);
+        hvm_unmap_ioreq_page(s, IOREQ_PAGE_TYPE_BUFIOREQ);
 
-    hvm_unmap_ioreq_page(s, 0);
+    hvm_unmap_ioreq_page(s, IOREQ_PAGE_TYPE_IOREQ);
 
     if ( !is_default )
     {
@@ -834,12 +922,38 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
     for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
     {
         char *name;
+        char *type_name = NULL;
+        unsigned int limit;
+
+        switch ( i )
+        {
+        case HVMOP_IO_RANGE_PORT:
+            type_name = "port";
+            limit = MAX_NR_IO_RANGES;
+            break;
+        case HVMOP_IO_RANGE_MEMORY:
+            type_name = "memory";
+            limit = MAX_NR_IO_RANGES;
+            break;
+        case HVMOP_IO_RANGE_PCI:
+            type_name = "pci";
+            limit = MAX_NR_IO_RANGES;
+            break;
+        case HVMOP_IO_RANGE_VMWARE_PORT:
+            type_name = "VMware port";
+            limit = 1;
+            break;
+        case HVMOP_IO_RANGE_TIMEOFFSET:
+            type_name = "timeoffset";
+            limit = 1;
+            break;
+        default:
+            break;
+        }
+        if ( !type_name )
+            continue;
 
-        rc = asprintf(&name, "ioreq_server %d %s", s->id,
-                      (i == HVMOP_IO_RANGE_PORT) ? "port" :
-                      (i == HVMOP_IO_RANGE_MEMORY) ? "memory" :
-                      (i == HVMOP_IO_RANGE_PCI) ? "pci" :
-                      "");
+        rc = asprintf(&name, "ioreq_server %d %s", s->id, type_name);
         if ( rc )
             goto fail;
 
@@ -852,7 +966,12 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
         if ( !s->range[i] )
             goto fail;
 
-        rangeset_limit(s->range[i], MAX_NR_IO_RANGES);
+        rangeset_limit(s->range[i], limit);
+
+        /* VMware port */
+        if ( i == HVMOP_IO_RANGE_VMWARE_PORT &&
+            s->domain->arch.hvm_domain.is_vmware_port_enabled )
+            rc = rangeset_add_range(s->range[i], 1, 1);
     }
 
  done:
@@ -1154,6 +1273,8 @@ static int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
             case HVMOP_IO_RANGE_PORT:
             case HVMOP_IO_RANGE_MEMORY:
             case HVMOP_IO_RANGE_PCI:
+            case HVMOP_IO_RANGE_VMWARE_PORT:
+            case HVMOP_IO_RANGE_TIMEOFFSET:
                 r = s->range[type];
                 break;
 
@@ -1205,6 +1326,8 @@ static int hvm_unmap_io_range_from_ioreq_server(struct domain *d, ioservid_t id,
             case HVMOP_IO_RANGE_PORT:
             case HVMOP_IO_RANGE_MEMORY:
             case HVMOP_IO_RANGE_PCI:
+            case HVMOP_IO_RANGE_VMWARE_PORT:
+            case HVMOP_IO_RANGE_TIMEOFFSET:
                 r = s->range[type];
                 break;
 
@@ -2428,9 +2551,6 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
     if ( list_empty(&d->arch.hvm_domain.ioreq_server.list) )
         return NULL;
 
-    if ( p->type != IOREQ_TYPE_COPY && p->type != IOREQ_TYPE_PIO )
-        return d->arch.hvm_domain.default_ioreq_server;
-
     cf8 = d->arch.hvm_domain.pci_cf8;
 
     if ( p->type == IOREQ_TYPE_PIO &&
@@ -2473,7 +2593,11 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
         BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
         BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
         BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
+        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
+        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
         r = s->range[type];
+        if ( !r )
+            break;
 
         switch ( type )
         {
@@ -2500,6 +2624,13 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
             }
 
             break;
+        case IOREQ_TYPE_VMWARE_PORT:
+        case IOREQ_TYPE_TIMEOFFSET:
+            /* The 'special' range of [1,1] is checked for being enabled */
+            if ( rangeset_contains_singleton(r, 1) )
+                return s;
+
+            break;
         }
     }
 
@@ -2661,6 +2792,7 @@ void hvm_complete_assist_req(ioreq_t *p)
     case IOREQ_TYPE_PCI_CONFIG:
         ASSERT_UNREACHABLE();
         break;
+    case IOREQ_TYPE_VMWARE_PORT:
     case IOREQ_TYPE_COPY:
     case IOREQ_TYPE_PIO:
         if ( p->dir == IOREQ_READ )
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 68fb890..7684cf0 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -192,6 +192,22 @@ void hvm_io_assist(ioreq_t *p)
         (void)handle_mmio();
         break;
     case HVMIO_handle_pio_awaiting_completion:
+        if ( p->type == IOREQ_TYPE_VMWARE_PORT )
+        {
+            vmware_regs_t *vr = get_vmport_regs_any(NULL, curr);
+
+            if ( vr )
+            {
+                struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+                /* Only change the 32bit part of the register */
+                regs->_ebx = vr->ebx;
+                regs->_ecx = vr->ecx;
+                regs->_edx = vr->edx;
+                regs->_esi = vr->esi;
+                regs->_edi = vr->edi;
+            }
+        }
         if ( vio->io_size == 4 ) /* Needs zero extension. */
             guest_cpu_user_regs()->rax = (uint32_t)p->data;
         else
diff --git a/xen/arch/x86/hvm/vmware/vmport.c b/xen/arch/x86/hvm/vmware/vmport.c
index 8a05c4b..f3867d6 100644
--- a/xen/arch/x86/hvm/vmware/vmport.c
+++ b/xen/arch/x86/hvm/vmware/vmport.c
@@ -115,7 +115,8 @@ static int vmport_ioport(int dir, uint32_t port, uint32_t bytes, uint32_t *val)
             regs->_ecx = 1000000;
             break;
         default:
-            break;
+            /* Let backing DM handle */
+            return X86EMUL_UNHANDLEABLE;
         }
         if ( dir == IOREQ_READ )
             *val = new_eax;
@@ -134,10 +135,10 @@ void vmport_register(struct domain *d)
 int vmport_check_port(unsigned int port)
 {
     struct vcpu *curr = current;
-    struct domain *d = curr->domain;
+    struct domain *currd = curr->domain;
 
-    if ( is_hvm_domain(d) && d->arch.hvm_domain.is_vmware_port_enabled &&
-         port == BDOOR_PORT )
+    if ( port == BDOOR_PORT && is_hvm_domain(currd) &&
+         currd->arch.hvm_domain.is_vmware_port_enabled )
         return 0;
     return 1;
 }
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index ab0e4cf..248dcee 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -48,7 +48,7 @@ struct hvm_ioreq_vcpu {
     evtchn_port_t    ioreq_evtchn;
 };
 
-#define NR_IO_RANGE_TYPES (HVMOP_IO_RANGE_PCI + 1)
+#define NR_IO_RANGE_TYPES (HVMOP_IO_RANGE_VMWARE_PORT + 1)
 #define MAX_NR_IO_RANGES  256
 
 struct hvm_ioreq_server {
@@ -63,6 +63,7 @@ struct hvm_ioreq_server {
     ioservid_t             id;
     struct hvm_ioreq_page  ioreq;
     struct list_head       ioreq_vcpu_list;
+    struct hvm_ioreq_page  vmport_ioreq;
     struct hvm_ioreq_page  bufioreq;
 
     /* Lock to serialize access to buffered ioreq ring */
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 3cccfff..71d934d 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -536,6 +536,7 @@ extern bool_t opt_hvm_fep;
 
 void vmport_register(struct domain *d);
 int vmport_check_port(unsigned int port);
+vmware_regs_t *get_vmport_regs_any(struct hvm_ioreq_server *s, struct vcpu *v);
 
 #endif /* __ASM_X86_HVM_HVM_H__ */
 
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index cde3571..2dcafc3 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -314,6 +314,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
  *
  * NOTE: unless an emulation request falls entirely within a range mapped
  * by a secondary emulator, it will not be passed to that emulator.
+ *
+ * NOTE: The 'special' range of [1,1] is what is checked for on
+ * TIMEOFFSET and VMWARE_PORT.
  */
 #define HVMOP_map_io_range_to_ioreq_server 19
 #define HVMOP_unmap_io_range_from_ioreq_server 20
@@ -324,6 +327,8 @@ struct xen_hvm_io_range {
 # define HVMOP_IO_RANGE_PORT   0 /* I/O port range */
 # define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
 # define HVMOP_IO_RANGE_PCI    2 /* PCI segment/bus/dev/func range */
+# define HVMOP_IO_RANGE_TIMEOFFSET 7 /* TIMEOFFSET special range */
+# define HVMOP_IO_RANGE_VMWARE_PORT 9 /* VMware port special range */
     uint64_aligned_t start, end; /* IN - inclusive start and end of range */
 };
 typedef struct xen_hvm_io_range xen_hvm_io_range_t;
diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h
index 5b5fedf..2d9dcbe 100644
--- a/xen/include/public/hvm/ioreq.h
+++ b/xen/include/public/hvm/ioreq.h
@@ -37,6 +37,7 @@
 #define IOREQ_TYPE_PCI_CONFIG   2
 #define IOREQ_TYPE_TIMEOFFSET   7
 #define IOREQ_TYPE_INVALIDATE   8 /* mapcache */
+#define IOREQ_TYPE_VMWARE_PORT  9 /* pio + vmport registers */
 
 /*
  * VMExit dispatcher should cooperate with instruction decoder to
@@ -48,6 +49,8 @@
  * 
  * 63....48|47..40|39..35|34..32|31........0
  * SEGMENT |BUS   |DEV   |FN    |OFFSET
+ *
+ * For I/O type IOREQ_TYPE_VMWARE_PORT also use the vmware_regs.
  */
 struct ioreq {
     uint64_t addr;          /* physical address */
@@ -66,11 +69,25 @@ struct ioreq {
 };
 typedef struct ioreq ioreq_t;
 
+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_iopage {
     struct ioreq vcpu_ioreq[1];
 };
 typedef struct shared_iopage shared_iopage_t;
 
+struct shared_vmport_iopage {
+    struct vmware_regs vcpu_vmport_regs[1];
+};
+typedef struct shared_vmport_iopage shared_vmport_iopage_t;
+
 struct buf_ioreq {
     uint8_t  type;   /* I/O type                    */
     uint8_t  pad:1;
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 974d3a4..2f6ccf4 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -50,6 +50,8 @@
 #define HVM_PARAM_PAE_ENABLED  4
 
 #define HVM_PARAM_IOREQ_PFN    5
+/* Extra vmport PFN. */
+#define HVM_PARAM_VMPORT_REGS_PFN 36
 
 #define HVM_PARAM_BUFIOREQ_PFN 6
 #define HVM_PARAM_BUFIOREQ_EVTCHN 26
@@ -197,6 +199,6 @@
 /* emulated VMware Hardware Version */
 #define HVM_PARAM_VMWARE_HWVER 35
 
-#define HVM_NR_PARAMS          36
+#define HVM_NR_PARAMS          37
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
1.7.11.7


[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-26 19:52         ` Don Slutz
@ 2015-02-27  7:48           ` Jan Beulich
  0 siblings, 0 replies; 71+ messages in thread
From: Jan Beulich @ 2015-02-27  7:48 UTC (permalink / raw)
  To: Don Slutz
  Cc: Jun Nakajima, Tim Deegan, Eddie Dong, Keir Fraser, Ian Campbell,
	Stefano Stabellini, George Dunlap, Andrew Cooper, Ian Jackson,
	Kevin Tian, xen-devel, Paul Durrant, Aravind Gopalakrishnan,
	Suravee Suthikulpanit, Boris Ostrovsky

>>> On 26.02.15 at 20:52, <dslutz@verizon.com> wrote:
> On 02/26/15 03:07, Jan Beulich wrote:
>>>>> On 25.02.15 at 21:20, <dslutz@verizon.com> wrote:
>>> On 02/24/15 10:34, Jan Beulich wrote:
>>>>>>> On 17.02.15 at 00:05, <dslutz@verizon.com> wrote:
>>>>> @@ -2474,7 +2594,12 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
>>>>>          BUILD_BUG_ON(IOREQ_TYPE_PIO != HVMOP_IO_RANGE_PORT);
>>>>>          BUILD_BUG_ON(IOREQ_TYPE_COPY != HVMOP_IO_RANGE_MEMORY);
>>>>>          BUILD_BUG_ON(IOREQ_TYPE_PCI_CONFIG != HVMOP_IO_RANGE_PCI);
>>>>> +        BUILD_BUG_ON(IOREQ_TYPE_VMWARE_PORT != HVMOP_IO_RANGE_VMWARE_PORT);
>>>>> +        BUILD_BUG_ON(IOREQ_TYPE_TIMEOFFSET != HVMOP_IO_RANGE_TIMEOFFSET);
>>>>> +        BUILD_BUG_ON(IOREQ_TYPE_INVALIDATE != HVMOP_IO_RANGE_INVALIDATE);
>>>>>          r = s->range[type];
>>>>> +        if ( !r )
>>>>> +            continue;
>>>>
>>>> Why, all of the sudden?
>>>>
>>>
>>> This is the replacement for the deleted "if" above.  Continue will lead
>>> to the same return that was remove above (it is at the end).  They are
>>> currently the same because all ioreq servers have the same set of
>>> ranges.  But if it would help, I can change "continue" into the "return
>>> default".
>> 
>> So further down you talk of the "special range 1" (see there for
>> further remarks in this regard) - how would r be NULL here in the
>> first place?
> 
> Since there is a hole in the #defines 0,1,2,7,8 (currently) range[6] is
> where r will be NULL for example.  However no current code should be
> able to get here.  So if you want me to I can drop the "if".

That's where ASSERT() comes in handy.

>> I understand all this is non-trivial and not necessarily obvious. But
>> as said before - the x86 instruction emulator should please remain
>> something acting along _only_ architectural specifications. Any
>> extensions to support things like what you want to do here should
>> be added using neutral hooks, responsible for keeping state they
>> need on their own.
>> 
> 
> 
> How does (the incorrectly formatted for a smaller diff):

Quite a bit better imo!

Jan

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h
  2015-02-16 23:05 ` [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h Don Slutz
  2015-02-17  9:52   ` Andrew Cooper
@ 2015-03-03 14:02   ` George Dunlap
  2015-03-03 14:08     ` Andrew Cooper
  1 sibling, 1 reply; 71+ messages in thread
From: George Dunlap @ 2015-03-03 14:02 UTC (permalink / raw)
  To: Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan,
	Aravind Gopalakrishnan, Jan Beulich, Andrew Cooper,
	Boris Ostrovsky, Suravee Suthikulpanit

On 02/16/2015 11:05 PM, Don Slutz wrote:
> Change some hard coded 15 into MAX_INST_LEN
> 
> Signed-off-by: Don Slutz <dslutz@verizon.com>

Since it looks like you'll be re-sending the series anyway, it might be
nice to include "No functional changes" in the description, just to make
it clear.

 -George

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h
  2015-03-03 14:02   ` George Dunlap
@ 2015-03-03 14:08     ` Andrew Cooper
  2015-03-03 14:09       ` George Dunlap
  0 siblings, 1 reply; 71+ messages in thread
From: Andrew Cooper @ 2015-03-03 14:08 UTC (permalink / raw)
  To: George Dunlap, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 03/03/15 14:02, George Dunlap wrote:
> On 02/16/2015 11:05 PM, Don Slutz wrote:
>> Change some hard coded 15 into MAX_INST_LEN
>>
>> Signed-off-by: Don Slutz <dslutz@verizon.com>
> Since it looks like you'll be re-sending the series anyway, it might be
> nice to include "No functional changes" in the description, just to make
> it clear.
>
>  -George
>

c/s a7d6ba7

Already committed two weeks ago.

~Andrew

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h
  2015-03-03 14:08     ` Andrew Cooper
@ 2015-03-03 14:09       ` George Dunlap
  0 siblings, 0 replies; 71+ messages in thread
From: George Dunlap @ 2015-03-03 14:09 UTC (permalink / raw)
  To: Andrew Cooper, Don Slutz, xen-devel
  Cc: Kevin Tian, Keir Fraser, Ian Campbell, Stefano Stabellini,
	Jun Nakajima, Eddie Dong, Ian Jackson, Tim Deegan,
	Aravind Gopalakrishnan, Jan Beulich, Boris Ostrovsky,
	Suravee Suthikulpanit

On 03/03/2015 02:08 PM, Andrew Cooper wrote:
> On 03/03/15 14:02, George Dunlap wrote:
>> On 02/16/2015 11:05 PM, Don Slutz wrote:
>>> Change some hard coded 15 into MAX_INST_LEN
>>>
>>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>> Since it looks like you'll be re-sending the series anyway, it might be
>> nice to include "No functional changes" in the description, just to make
>> it clear.
>>
>>  -George
>>
> 
> c/s a7d6ba7
> 
> Already committed two weeks ago.

Er...

/me tries to figure out why he thought that this still needed review...

 -George

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 03/13] tools: Add vmware_hwver support
  2015-02-16 23:05 ` [PATCH v9 03/13] tools: Add vmware_hwver support Don Slutz
@ 2015-03-03 14:14   ` Ian Campbell
  0 siblings, 0 replies; 71+ messages in thread
From: Ian Campbell @ 2015-03-03 14:14 UTC (permalink / raw)
  To: Don Slutz
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	xen-devel, Aravind Gopalakrishnan, Jan Beulich, Andrew Cooper,
	Boris Ostrovsky, Suravee Suthikulpanit

On Mon, 2015-02-16 at 18:05 -0500, Don Slutz wrote:
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index c219f59..0c27e5c 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -163,6 +163,16 @@
>  #define LIBXL_HAVE_BUILDINFO_HVM_MMIO_HOLE_MEMKB 1
>  
>  /*
> + * The libxl_vga_interface_type has the type for vmware.
> + */
> +#define LIBXL_HAVE_LIBXL_VGA_INTERFACE_TYPE_VMWARE 1
> +
> +/*
> + * libxl_domain_build_info has the u.hvm.vmware_hwver field.
> + */
> +#define LIBXL_HAVE_BUILDINFO_HVM_VMWARE_HWVER 1

Since they are arriving together I think you can use a single umbrella
define indicating thatvmware support is available.

> @@ -450,6 +454,8 @@ int libxl__domain_build(libxl__gc *gc,
>          localents[i++] = libxl_defbool_val(info->u.hvm.acpi_s3) ? "1" : "0";
>          localents[i++] = "platform/acpi_s4";
>          localents[i++] = libxl_defbool_val(info->u.hvm.acpi_s4) ? "1" : "0";
> +        localents[i++] = "platform/vmware_hwver";
> +        localents[i++] = libxl__sprintf(gc, "%"PRId64, info->u.hvm.vmware_hwver);

GCSPRINTF could be used here.

> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 48d661a..34a36d3 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -294,6 +294,8 @@ static void hvm_set_conf_params(xc_interface *handle, uint32_t domid,
>  #if defined(__i386__) || defined(__x86_64__)
>      xc_hvm_param_set(handle, domid, HVM_PARAM_HPET_ENABLED,
>                      libxl_defbool_val(info->u.hvm.hpet));
> +    xc_set_hvm_param(handle, domid, HVM_PARAM_VMWARE_HWVER,
> +                     info->u.hvm.vmware_hwver);

Please use xc_hvm_param_set not the deprecated older version.

With those little nits addresses you may add:
Acked-by: Ian Campbell <ian.campbell@citrix.com>

Unless I'm told otherwise I'll assume that this will be committed by the
person who does the hypervisor side.

Ian.

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 07/13] tools: Add vmware_port support
  2015-02-16 23:05 ` [PATCH v9 07/13] tools: Add " Don Slutz
@ 2015-03-03 14:23   ` Ian Campbell
  2015-05-14 23:10     ` Don Slutz
  0 siblings, 1 reply; 71+ messages in thread
From: Ian Campbell @ 2015-03-03 14:23 UTC (permalink / raw)
  To: Don Slutz
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	xen-devel, Aravind Gopalakrishnan, Jan Beulich, Andrew Cooper,
	Boris Ostrovsky, Suravee Suthikulpanit

On Mon, 2015-02-16 at 18:05 -0500, Don Slutz wrote:

> +=item B<vmware_port=BOOLEAN>
> +
> +Turns on or off the exposure of VMware port.  This is known as
> +vmport in QEMU.  Also called VMware Backdoor I/O Port.  Not all
> +defined VMware backdoor commands are implemented.  All of the
> +ones that Linux kernel uses are defined.
> +
> +if vmware_port is not specified in the config file, let vmware_hwver != 0
> +be the default value.  This means that only vmware_hwver = 7 needs to
> +be specified to enable both features.

"If..." at the start of the sentence.

But I think a clearer wording, which avoids users having to know C
syntax would be:

        Defaults to enabled if vmware_hwver is non-zero (i.e. enabled)
        otherwise defaults to disabled.


I think the thing about setting hwver to 7 should be in the hwver space,
as in words to the effect that setting that option enabled vmware_port
support by default.

Also, why is 7 special? The patch which added vmware_hwver didn't seem
to suggest that vmware_hwver = 7 was what was needed.

> +Note: both vmware_port and nestedhvm cannot be specified at the
> +same time.

Drop the "both" here (and in the commit message).

> +
>  =back
>  
>  =head3 Emulated VGA Graphics Device
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index 0c27e5c..792b569 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -173,6 +173,11 @@
>  #define LIBXL_HAVE_BUILDINFO_HVM_VMWARE_HWVER 1
>  
>  /*
> + * libxl_domain_create_info has the vmware_port field.
> + */
> +#define LIBXL_HAVE_CREATEINFO_VMWARE_PORT 1

I think this can be part of the umbrella HAVE I asked you to add
earlier. This probably means the define should be added alongside the
final such interface addition in this series.

> +
> +/*
>   * libxl ABI compatibility
>   *
>   * The only guarantee which libxl makes regarding ABI compatibility
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index 8c910c4..439164a 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -26,7 +26,8 @@
>  #include <xen/hvm/e820.h>
>  
>  int libxl__domain_create_info_setdefault(libxl__gc *gc,
> -                                         libxl_domain_create_info *c_info)
> +                                         libxl_domain_create_info *c_info,
> +                                         bool vmware_port_default)

The need to pass this makes me think that vmware_hwver should probably
be in create info not build info, since the soonest it is needed is
create time. Unless that changes based on the discussion about hwo such
things should be dpone in the other thread of course.

(the split is stupid and annoying, but we are stuck with it)

> @@ -876,6 +881,13 @@ static void initiate_domain_create(libxl__egc *egc,
>      ret = libxl__domain_build_info_setdefault(gc, &d_config->b_info);
>      if (ret) goto error_out;
>  
> +    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
> +        libxl_defbool_val(d_config->b_info.u.hvm.nested_hvm) &&
> +        libxl_defbool_val(d_config->c_info.vmware_port)) {
> +        LOG(ERROR, "Both vmware_port and nestedhvm can not be enabled\n");

"vmware_port and nestedhvm cannot be enabled simultaneously"

> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index b05fa73..c27f9a4 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -1061,7 +1061,9 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
>      dm_config->c_info.run_hotplug_scripts =
>          guest_config->c_info.run_hotplug_scripts;
>  
> -    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info);
> +    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info,
> +                       dm_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
> +                       dm_config->b_info.u.hvm.vmware_hwver);

Isn't this enabling vmware support for the stbudom itself (not the
target domain)? I think this should just be false here.

Ian.

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT
  2015-02-16 23:05 ` [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT Don Slutz
  2015-02-17 10:08   ` Paul Durrant
  2015-02-24 15:34   ` Jan Beulich
@ 2015-03-03 14:25   ` Ian Campbell
  2 siblings, 0 replies; 71+ messages in thread
From: Ian Campbell @ 2015-03-03 14:25 UTC (permalink / raw)
  To: Don Slutz
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	xen-devel, Aravind Gopalakrishnan, Jan Beulich, Andrew Cooper,
	Boris Ostrovsky, Suravee Suthikulpanit

On Mon, 2015-02-16 at 18:05 -0500, Don Slutz wrote:

>  tools/libxc/xc_hvm_build_x86.c         |   5 +-
>  tools/libxl/libxl_dm.c                 |   4 +

I've only looked at these bits.

> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index c27f9a4..620013c 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -765,6 +765,10 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
>                                              machinearg, max_ram_below_4g);
>              }
>          }
> +        if (libxl_defbool_val(c_info->vmware_port)) {
> +            machinearg = libxl__sprintf(gc, "%s,vmport=on",
> +                                        machinearg);

Please use GCSPRINTF, then I think this will fit on one line.

I think you also also don't need the {}'s for a single line if.

With those fixed the tools/* bits are:
Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 09/13] Add xentrace to vmware_port
  2015-02-16 23:05 ` [PATCH v9 09/13] Add xentrace to vmware_port Don Slutz
  2015-02-17 13:45   ` Andrew Cooper
  2015-02-23 16:57   ` Jan Beulich
@ 2015-03-03 14:27   ` Ian Campbell
  2 siblings, 0 replies; 71+ messages in thread
From: Ian Campbell @ 2015-03-03 14:27 UTC (permalink / raw)
  To: Don Slutz
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	xen-devel, Aravind Gopalakrishnan, Jan Beulich, Andrew Cooper,
	Boris Ostrovsky, Suravee Suthikulpanit

On Mon, 2015-02-16 at 18:05 -0500, Don Slutz wrote:
>  tools/xentrace/formats           |  5 +++++
> [...]
> diff --git a/tools/xentrace/formats b/tools/xentrace/formats
> index 5d7b72a..eec65f4 100644
> --- a/tools/xentrace/formats
> +++ b/tools/xentrace/formats
> @@ -79,6 +79,11 @@
>  0x00082020  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INTR_WINDOW [ value = 0x%(1)08x ]
>  0x00082021  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  NPF         [ gpa = 0x%(2)08x%(1)08x mfn = 0x%(4)08x%(3)08x qual = 0x%(5)04x p2mt = 0x%(6)04x ]
>  0x00082023  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  TRAP        [ vector = 0x%(1)02x ]
> +0x00082024  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  TRAP_DEBUG  [ exit_qualification = 0x%(1)08x ]
> +0x00082025  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VLAPIC
> +0x00082026  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_HANDLED   [ cmd = %(1)d eax = 0x%(2)08x ebx = 0x%(3)08x ecx = 0x%(4)08x edx = 0x%(5)08x esi = 0x%(6)08x edi = 0x%(7)08x ]
> +0x00082027  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_IGNORED   [ port = %(1)d eax = 0x%(2)08x ebx = 0x%(3)08x ecx = 0x%(4)08x edx = 0x%(5)08x esi = 0x%(6)08x edi = 0x%(7)08x ]
> +0x00082028  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMPORT_QEMU      [ eax = 0x%(1)08x ebx = 0x%(2)08x ecx = 0x%(3)08x edx = 0x%(4)08x esi = 0x%(5)08x edi = 0x%(6)08x ]

Looks ok to me, so for this tools change:
Acked-by: Ian Campbell <ian.campbell@citrix.com>

but really what is needed is George's nod for xentrace stuff.

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 11/13] test_x86_emulator.c: Add emacs block
  2015-02-17 14:52   ` Andrew Cooper
@ 2015-03-03 14:28     ` Ian Campbell
  2015-03-03 14:31       ` Andrew Cooper
  0 siblings, 1 reply; 71+ messages in thread
From: Ian Campbell @ 2015-03-03 14:28 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	Don Slutz, xen-devel, Aravind Gopalakrishnan, Jan Beulich,
	Boris Ostrovsky, Suravee Suthikulpanit

On Tue, 2015-02-17 at 14:52 +0000, Andrew Cooper wrote:
> On 16/02/15 23:05, Don Slutz wrote:
> > Signed-off-by: Don Slutz <dslutz@verizon.com>
> 
> Acked-by: Andrew Cooper <andew.cooper@citrix.com>
> 
> (Presuming an acceptable extension of maintainership into this area.  It
> does after all symlink its way into xen/arch/x86)

I think MAINTAINERS has since been updated, so I think your ack is now
gospel here. Lucky you.

> 
> > ---
> >  tools/tests/x86_emulator/test_x86_emulator.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c
> > index 03cd0e8..02a9f0a 100644
> > --- a/tools/tests/x86_emulator/test_x86_emulator.c
> > +++ b/tools/tests/x86_emulator/test_x86_emulator.c
> > @@ -936,3 +936,12 @@ int main(int argc, char **argv)
> >      printf("failed!\n");
> >      return 1;
> >  }
> > +
> > +/*
> > + * Local variables:
> > + * mode: C
> > + * c-file-style: "BSD"
> > + * c-basic-offset: 4
> > + * indent-tabs-mode: nil
> > + * End:
> > + */
> 
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 11/13] test_x86_emulator.c: Add emacs block
  2015-03-03 14:28     ` Ian Campbell
@ 2015-03-03 14:31       ` Andrew Cooper
  0 siblings, 0 replies; 71+ messages in thread
From: Andrew Cooper @ 2015-03-03 14:31 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	Don Slutz, xen-devel, Aravind Gopalakrishnan, Jan Beulich,
	Boris Ostrovsky, Suravee Suthikulpanit

On 03/03/15 14:28, Ian Campbell wrote:
> On Tue, 2015-02-17 at 14:52 +0000, Andrew Cooper wrote:
>> On 16/02/15 23:05, Don Slutz wrote:
>>> Signed-off-by: Don Slutz <dslutz@verizon.com>
>> Acked-by: Andrew Cooper <andew.cooper@citrix.com>
>>
>> (Presuming an acceptable extension of maintainership into this area.  It
>> does after all symlink its way into xen/arch/x86)
> I think MAINTAINERS has since been updated, so I think your ack is now
> gospel here. Lucky you.

I think this email was the cause of the MAINTAINERS change.

(Also, this change was already committed in c/s 4f3283f)

~Andrew

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v9 07/13] tools: Add vmware_port support
  2015-03-03 14:23   ` Ian Campbell
@ 2015-05-14 23:10     ` Don Slutz
  0 siblings, 0 replies; 71+ messages in thread
From: Don Slutz @ 2015-05-14 23:10 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Tim Deegan, Kevin Tian, Keir Fraser, Jun Nakajima,
	Stefano Stabellini, George Dunlap, Ian Jackson, Eddie Dong,
	xen-devel, Aravind Gopalakrishnan, Jan Beulich, Andrew Cooper,
	Boris Ostrovsky, Suravee Suthikulpanit

On 03/03/15 09:23, Ian Campbell wrote:
> On Mon, 2015-02-16 at 18:05 -0500, Don Slutz wrote:
> 

I do not see that I ever replied to this :(

>> > +=item B<vmware_port=BOOLEAN>
>> > +
>> > +Turns on or off the exposure of VMware port.  This is known as
>> > +vmport in QEMU.  Also called VMware Backdoor I/O Port.  Not all
>> > +defined VMware backdoor commands are implemented.  All of the
>> > +ones that Linux kernel uses are defined.
>> > +
>> > +if vmware_port is not specified in the config file, let vmware_hwver != 0
>> > +be the default value.  This means that only vmware_hwver = 7 needs to
>> > +be specified to enable both features.
> "If..." at the start of the sentence.
> 
> But I think a clearer wording, which avoids users having to know C
> syntax would be:
> 
>         Defaults to enabled if vmware_hwver is non-zero (i.e. enabled)
>         otherwise defaults to disabled.

Will use this.

> 
> 
> I think the thing about setting hwver to 7 should be in the hwver space,
> as in words to the effect that setting that option enabled vmware_port
> support by default.
> 
> Also, why is 7 special? The patch which added vmware_hwver didn't seem
> to suggest that vmware_hwver = 7 was what was needed.
> 

7 is special because that is when VMware started providing CPUID leaves.


>> > +Note: both vmware_port and nestedhvm cannot be specified at the
>> > +same time.
> Drop the "both" here (and in the commit message).
> 

Will do.

>> > +
>> >  =back
>> >  
>> >  =head3 Emulated VGA Graphics Device
>> > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
>> > index 0c27e5c..792b569 100644
>> > --- a/tools/libxl/libxl.h
>> > +++ b/tools/libxl/libxl.h
>> > @@ -173,6 +173,11 @@
>> >  #define LIBXL_HAVE_BUILDINFO_HVM_VMWARE_HWVER 1
>> >  
>> >  /*
>> > + * libxl_domain_create_info has the vmware_port field.
>> > + */
>> > +#define LIBXL_HAVE_CREATEINFO_VMWARE_PORT 1
> I think this can be part of the umbrella HAVE I asked you to add
> earlier. This probably means the define should be added alongside the
> final such interface addition in this series.
> 

Will switch to only 1 in this patch.

>> > +
>> > +/*
>> >   * libxl ABI compatibility
>> >   *
>> >   * The only guarantee which libxl makes regarding ABI compatibility
>> > diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
>> > index 8c910c4..439164a 100644
>> > --- a/tools/libxl/libxl_create.c
>> > +++ b/tools/libxl/libxl_create.c
>> > @@ -26,7 +26,8 @@
>> >  #include <xen/hvm/e820.h>
>> >  
>> >  int libxl__domain_create_info_setdefault(libxl__gc *gc,
>> > -                                         libxl_domain_create_info *c_info)
>> > +                                         libxl_domain_create_info *c_info,
>> > +                                         bool vmware_port_default)
> The need to pass this makes me think that vmware_hwver should probably
> be in create info not build info, since the soonest it is needed is
> create time. Unless that changes based on the discussion about hwo such
> things should be dpone in the other thread of course.
> 

Moved both to c_info.

> (the split is stupid and annoying, but we are stuck with it)
> 
>> > @@ -876,6 +881,13 @@ static void initiate_domain_create(libxl__egc *egc,
>> >      ret = libxl__domain_build_info_setdefault(gc, &d_config->b_info);
>> >      if (ret) goto error_out;
>> >  
>> > +    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
>> > +        libxl_defbool_val(d_config->b_info.u.hvm.nested_hvm) &&
>> > +        libxl_defbool_val(d_config->c_info.vmware_port)) {
>> > +        LOG(ERROR, "Both vmware_port and nestedhvm can not be enabled\n");
> "vmware_port and nestedhvm cannot be enabled simultaneously"
> 
>> > diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
>> > index b05fa73..c27f9a4 100644
>> > --- a/tools/libxl/libxl_dm.c
>> > +++ b/tools/libxl/libxl_dm.c
>> > @@ -1061,7 +1061,9 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
>> >      dm_config->c_info.run_hotplug_scripts =
>> >          guest_config->c_info.run_hotplug_scripts;
>> >  
>> > -    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info);
>> > +    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info,
>> > +                       dm_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM &&
>> > +                       dm_config->b_info.u.hvm.vmware_hwver);
> Isn't this enabling vmware support for the stbudom itself (not the
> target domain)? I think this should just be false here.
> 

Yes, will drop.

   -Don Slutz


> Ian.
> 
> 

^ permalink raw reply	[flat|nested] 71+ messages in thread

end of thread, other threads:[~2015-05-14 23:10 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-16 23:05 [PATCH v9 00/13] Xen VMware tools support Don Slutz
2015-02-16 23:05 ` [PATCH v9 01/13] hvm: Move MAX_INST_LEN into x86_emulate.h Don Slutz
2015-02-17  9:52   ` Andrew Cooper
2015-02-17 21:31     ` Don Slutz
2015-03-03 14:02   ` George Dunlap
2015-03-03 14:08     ` Andrew Cooper
2015-03-03 14:09       ` George Dunlap
2015-02-16 23:05 ` [PATCH v9 02/13] xen: Add support for VMware cpuid leaves Don Slutz
2015-02-17 10:02   ` Andrew Cooper
2015-02-17 15:57     ` Jan Beulich
2015-02-17 15:59       ` Andrew Cooper
2015-02-16 23:05 ` [PATCH v9 03/13] tools: Add vmware_hwver support Don Slutz
2015-03-03 14:14   ` Ian Campbell
2015-02-16 23:05 ` [PATCH v9 04/13] vmware: Add VMware provided include file Don Slutz
2015-02-17 10:03   ` Andrew Cooper
2015-02-16 23:05 ` [PATCH v9 05/13] xen: Add vmware_port support Don Slutz
2015-02-17 10:30   ` Andrew Cooper
2015-02-18  2:18     ` Don Slutz
2015-02-23 15:05   ` Jan Beulich
2015-02-23 16:03     ` Don Slutz
2015-02-23 16:28       ` Jan Beulich
2015-02-16 23:05 ` [PATCH v9 06/13] xen: Add ring 3 " Don Slutz
2015-02-17 14:38   ` Andrew Cooper
2015-02-18 17:03     ` Don Slutz
2015-02-18 18:19       ` Andrew Cooper
2015-02-21 13:36         ` Don Slutz
2015-02-21 15:40           ` Andrew Cooper
2015-02-21 16:06             ` Don Slutz
2015-02-23 15:12   ` Jan Beulich
2015-02-23 17:11     ` Don Slutz
2015-02-24  8:34       ` Jan Beulich
2015-02-24 17:14         ` Don Slutz
2015-02-25  8:39           ` Jan Beulich
2015-02-16 23:05 ` [PATCH v9 07/13] tools: Add " Don Slutz
2015-03-03 14:23   ` Ian Campbell
2015-05-14 23:10     ` Don Slutz
2015-02-16 23:05 ` [PATCH v9 08/13] Add IOREQ_TYPE_VMWARE_PORT Don Slutz
2015-02-17 10:08   ` Paul Durrant
2015-02-18  2:44     ` Don Slutz
2015-02-24 15:34   ` Jan Beulich
2015-02-25 20:20     ` Don Slutz
2015-02-26  8:07       ` Jan Beulich
2015-02-26 11:49         ` Paul Durrant
2015-02-26 14:55           ` Don Slutz
2015-02-26 15:00             ` Paul Durrant
2015-02-26 15:10             ` Jan Beulich
2015-02-26 19:52         ` Don Slutz
2015-02-27  7:48           ` Jan Beulich
2015-03-03 14:25   ` Ian Campbell
2015-02-16 23:05 ` [PATCH v9 09/13] Add xentrace to vmware_port Don Slutz
2015-02-17 13:45   ` Andrew Cooper
2015-02-17 18:22     ` Don Slutz
2015-02-23 16:57   ` Jan Beulich
2015-02-23 19:13     ` Don Slutz
2015-02-24  7:19       ` Jan Beulich
2015-03-03 14:27   ` Ian Campbell
2015-02-16 23:05 ` [PATCH v9 10/13] test_x86_emulator.c: Add typedef for boot_t Don Slutz
2015-02-17 14:44   ` Andrew Cooper
2015-02-17 22:46     ` Don Slutz
2015-02-16 23:05 ` [PATCH v9 11/13] test_x86_emulator.c: Add emacs block Don Slutz
2015-02-17 14:52   ` Andrew Cooper
2015-03-03 14:28     ` Ian Campbell
2015-03-03 14:31       ` Andrew Cooper
2015-02-16 23:05 ` [PATCH v9 12/13] test_x86_emulator.c: Add tests for #GP usage Don Slutz
2015-02-24 15:38   ` Jan Beulich
2015-02-24 18:29     ` Don Slutz
2015-02-25  8:30       ` Jan Beulich
2015-02-25 13:27         ` Don Slutz
2015-02-16 23:05 ` [OPTIONAL][PATCH v9 13/13] Add xen-hvm-param Don Slutz
2015-02-17 14:11   ` Andrew Cooper
2015-02-18  2:51     ` Don Slutz

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.