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

Re: [Xen-devel] [PATCH V5 1/3] xen/mem_access: Support for memory-content hiding



On 07/14/2015 03:22 PM, Jan Beulich wrote:
>>>> On 13.07.15 at 19:14, <rcojocaru@xxxxxxxxxxxxxxx> wrote:
>> --- a/xen/arch/x86/domain.c
>> +++ b/xen/arch/x86/domain.c
>> @@ -511,6 +511,8 @@ int vcpu_initialise(struct vcpu *v)
>>  
>>  void vcpu_destroy(struct vcpu *v)
>>  {
>> +    xfree(v->arch.vm_event.emul_read_data);
> 
> Is this still needed now that you have
> vm_event_cleanup_domain()?

I had thought that there might be a code path where
vm_event_cleanup_domain() doesn't get called and yet the domain is being
destroyed, but I can't find anything obvious in the code except a
comment in arch/x86/mm/shadow/common.c - shadow_final_teardown() -
stating that "It is possible for a domain that never got domain_kill()ed
to get here with its shadow allocation intact.".

Since common/domain.c's domain_kill() seems to be the only caller of
vm_event_cleanup(), I took that comment to mean that it could be
possible to end up in vcpu_destroy() without vm_event_cleanup_domain()
having been called, so I took the better-safe-than-sorry approach.

That is also why I'm setting v->arch.vm_event.emul_read_data to NULL in
the vm_event domain cleanup function, so that this xfree() does not
double-free.

But this xfree() is probably not needed, so if confirmed I'll remove it.

>> --- a/xen/arch/x86/hvm/emulate.c
>> +++ b/xen/arch/x86/hvm/emulate.c
>> @@ -67,6 +67,27 @@ static int null_write(const struct hvm_io_handler 
>> *handler,
>>      return X86EMUL_OKAY;
>>  }
>>  
>> +static int set_context_data(void *buffer, unsigned int bytes)
> 
> I think in the context of this function alone, "size" would be better
> than "bytes".

Ack.

>> +{
>> +    struct vcpu *curr = current;
>> +
>> +    if ( !curr->arch.vm_event.emul_read_data )
>> +        return X86EMUL_UNHANDLEABLE;
>> +    else
> 
> Else after the respective if() unconditionally returning is odd.
> Perhaps better to invert the if() condition...

I agree, I only used the else so that I wouldn't need to put safe_bytes
on the stack if I didn't have to. I'll invert the condition.

>> +    {
>> +        unsigned int safe_bytes =
>> +            min(bytes, curr->arch.vm_event.emul_read_data->size);
>> +
>> +        if ( safe_bytes )
>> +            memcpy(buffer, curr->arch.vm_event.emul_read_data->data,
>> +                   safe_bytes);
> 
> So why did you still keep this conditional?

I thought a memcpy() call that ends up doing nothing (copying 0 bytes)
would be expensive and I've tried to optimize the code by not doing the
call if safe_bytes == 0.

Since nobody else seems to think it's worth it, I'll remove it.

>> @@ -1005,6 +1043,36 @@ static int hvmemul_rep_ins(
>>                                 !!(ctxt->regs->eflags & X86_EFLAGS_DF), gpa);
>>  }
>>  
>> +static int hvmemul_rep_outs_set_context(
>> +    enum x86_segment src_seg,
>> +    unsigned long src_offset,
>> +    uint16_t dst_port,
>> +    unsigned int bytes_per_rep,
>> +    unsigned long *reps,
>> +    struct x86_emulate_ctxt *ctxt)
>> +{
>> +    unsigned int bytes = *reps * bytes_per_rep;
>> +    char *buf;
>> +    int rc;
>> +
>> +    buf = xmalloc_array(char, bytes);
>> +
>> +    if ( buf == NULL )
>> +        return X86EMUL_UNHANDLEABLE;
>> +
>> +    rc = set_context_data(buf, bytes);
>> +
>> +    if ( rc != X86EMUL_OKAY )
>> +        goto out;
>> +
>> +    rc = hvmemul_do_pio_buffer(dst_port, bytes, IOREQ_WRITE, buf);
>> +
>> +out:
> 
> Labels should be indented by at least one space. But realistically
> the code wouldn't look worse without any goto...

Understood, will remove the label completely.

>> @@ -1133,7 +1205,20 @@ static int hvmemul_rep_movs(
>>       */
>>      rc = hvm_copy_from_guest_phys(buf, sgpa, bytes);
>>      if ( rc == HVMCOPY_okay )
>> +    {
>> +        if ( unlikely(hvmemul_ctxt->set_context) )
>> +        {
>> +            rc = set_context_data(buf, bytes);
>> +
>> +            if ( rc != X86EMUL_OKAY)
>> +            {
>> +                xfree(buf);
>> +                return rc;
>> +            }
>> +        }
>> +
>>          rc = hvm_copy_to_guest_phys(dgpa, buf, bytes);
>> +    }
> 
> Why do you not bypass hvm_copy_from_guest_phys() here? This
> way it would - afaict - become consistent with the other cases.

You're right, it's unnecessary. Will remove the hvm_copy_from_guest_phys().

>> --- a/xen/arch/x86/vm_event.c
>> +++ b/xen/arch/x86/vm_event.c
>> @@ -23,6 +23,36 @@
>>  #include <xen/sched.h>
>>  #include <asm/hvm/hvm.h>
>>  
>> +int vm_event_init_domain(struct domain *d)
>> +{
>> +    struct vcpu *v;
>> +
>> +    for_each_vcpu( d, v )
> 
> Either you consider for_each_vcpu a keyword-like thing, then this
> is missing a blank before the opening parenthesis, or you don't, in
> which case the blanks immediately inside the parentheses should
> be dropped.

Understood, will fix it.

>> +    {
>> +        if ( v->arch.vm_event.emul_read_data )
>> +            continue;
>> +
>> +        v->arch.vm_event.emul_read_data =
>> +            xzalloc(struct vm_event_emul_read_data);
>> +
>> +        if ( !v->arch.vm_event.emul_read_data )
>> +            return -ENOMEM;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +void vm_event_cleanup_domain(struct domain *d)
>> +{
>> +    struct vcpu *v;
>> +
>> +    for_each_vcpu( d, v )
>> +    {
>> +        xfree(v->arch.vm_event.emul_read_data);
>> +        v->arch.vm_event.emul_read_data = NULL;
>> +    }
>> +}
> 
> There not being a race here is attributed to vm_event_enable()
> being implicitly serialized by the domctl lock, and
> vm_event_disable(), beyond its domctl use, only being on domain
> cleanup paths? Would be nice to have a comment to that effect.

Indeed, that's how I understood it to happen. I'll add a comment.


Thanks,
Razvan

_______________________________________________
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®.