[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v9 05/13] xen: Add vmware_port support



On 02/23/15 10:05, Jan Beulich wrote:
>>>> On 17.02.15 at 00:05, <dslutz@xxxxxxxxxxx> 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
> 

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.