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

Re: [Xen-devel] [PATCH] vm_event: Allow subscribing to write events for specific MSR-s



On 04/12/16 20:49, Tamas K Lengyel wrote:
>     diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c
>     index 1fec412..1be058a 100644
>     --- a/xen/arch/x86/monitor.c
>     +++ b/xen/arch/x86/monitor.c
>     @@ -20,6 +20,7 @@
>       */
> 
>      #include <asm/monitor.h>
>     +#include <asm/vm_event.h>
>      #include <public/vm_event.h>
> 
>      int arch_monitor_domctl_event(struct domain *d,
>     @@ -77,25 +78,25 @@ int arch_monitor_domctl_event(struct domain *d,
> 
>          case XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR:
>          {
>     -        bool_t old_status = ad->monitor.mov_to_msr_enabled;
>     +        bool_t old_status;
>     +        int rc;
>     +        u32 msr = mop->u.mov_to_msr.msr;
> 
>     -        if ( unlikely(old_status == requested_status) )
>     -            return -EEXIST;
>     +        domain_pause(d);
> 
>     -        if ( requested_status && mop->u.mov_to_msr.extended_capture &&
>     -             !hvm_enable_msr_exit_interception(d) )
>     -            return -EOPNOTSUPP;
>     +        old_status = vm_event_is_msr_enabled(d, msr);
> 
>     -        domain_pause(d);
>     +        if ( unlikely(old_status == requested_status) )
>     +            return -EEXIST;
> 
> 
> Moving this test after the domain gets paused will leave the guest
> paused on error condition. Any reason why this rearrangement is necessary?

The rearrangement is necessary because vm_event_is_msr_enabled() uses
the per-domain bitmap to do its job, so I thought having the domain
paused when checking it would work best.

Leaving the domain paused there is an oversight, I need to correct that,
so thanks for noticing!

>     -        if ( requested_status && mop->u.mov_to_msr.extended_capture )
>     -            ad->monitor.mov_to_msr_extended = 1;
>     +        if ( requested_status )
>     +            rc = vm_event_enable_msr(d, msr);
>              else
>     -            ad->monitor.mov_to_msr_extended = 0;
>     +            rc = vm_event_disable_msr(d, msr);
> 
>     -        ad->monitor.mov_to_msr_enabled = requested_status;
>              domain_unpause(d);
>     -        break;
>     +
>     +        return rc;
>          }
> 
>          case XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP:
>     diff --git a/xen/arch/x86/vm_event.c b/xen/arch/x86/vm_event.c
>     index 5635603..b851e39 100644
>     --- a/xen/arch/x86/vm_event.c
>     +++ b/xen/arch/x86/vm_event.c
>     @@ -27,6 +27,13 @@ int vm_event_init_domain(struct domain *d)
>      {
>          struct vcpu *v;
> 
>     +    d->arch.monitor_msr_bitmap = alloc_xenheap_page();
>     +
>     +    if ( !d->arch.monitor_msr_bitmap )
>     +        return -ENOMEM;
>     +
>     +    memset(d->arch.monitor_msr_bitmap, 0, PAGE_SIZE);
>     +
>          for_each_vcpu ( d, v )
>          {
>              if ( v->arch.vm_event )
>     @@ -55,11 +62,66 @@ void vm_event_cleanup_domain(struct domain *d)
>              v->arch.vm_event = NULL;
>          }
> 
>     +    free_xenheap_page(d->arch.monitor_msr_bitmap);
>     +    d->arch.monitor_msr_bitmap = NULL;
>     +
>          d->arch.mem_access_emulate_each_rep = 0;
>          memset(&d->arch.monitor, 0, sizeof(d->arch.monitor));
>          memset(&d->monitor, 0, sizeof(d->monitor));
>      }
> 
>     +int vm_event_enable_msr(struct domain *d, u32 msr)
> 
> 
> This function..
>  
> 
>     +{
>     +    if ( !d->arch.monitor_msr_bitmap )
>     +        return -EINVAL;
>     +
>     +    if ( msr <= 0x1fff )
>     +        set_bit(msr, d->arch.monitor_msr_bitmap +
>     0x000/BYTES_PER_LONG);
>     +    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
>     +    {
>     +        msr &= 0x1fff;
>     +        set_bit(msr, d->arch.monitor_msr_bitmap +
>     0x400/BYTES_PER_LONG);
>     +    }
>     +
>     +    hvm_enable_msr_interception(d, msr);
>     +
>     +    return 0;
>     +}
>     +
>     +int vm_event_disable_msr(struct domain *d, u32 msr)
> 
> 
> ..and this..
>  
> 
>     +{
>     +    if ( !d->arch.monitor_msr_bitmap )
>     +        return -EINVAL;
>     +
>     +    if ( msr <= 0x1fff )
>     +        clear_bit(msr, d->arch.monitor_msr_bitmap +
>     0x000/BYTES_PER_LONG);
>     +    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
>     +    {
>     +        msr &= 0x1fff;
>     +        clear_bit(msr, d->arch.monitor_msr_bitmap +
>     0x400/BYTES_PER_LONG);
>     +    }
>     +
>     +    return 0;
>     +}
>     +
>     +bool_t vm_event_is_msr_enabled(const struct domain *d, u32 msr)
> 
>  
> ..and this one has nothing to do with vm_event really. These belong in
> the monitor.c side.
>  
> 
>     +{
>     +    bool_t rc = 0;
>     +
>     +    if ( !d->arch.monitor_msr_bitmap )
>     +        return 0;
>     +
>     +    if ( msr <= 0x1fff )
>     +        rc = test_bit(msr, d->arch.monitor_msr_bitmap +
>     0x000/BYTES_PER_LONG);
>     +    else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
>     +    {
>     +        msr &= 0x1fff;
>     +        rc = test_bit(msr, d->arch.monitor_msr_bitmap +
>     0x400/BYTES_PER_LONG);
>     +    }
>     +
>     +    return rc;
>     +}
>     +
>      void vm_event_toggle_singlestep(struct domain *d, struct vcpu *v)
>      {
>          if ( !is_hvm_domain(d) || !atomic_read(&v->vm_event_pause_count) )

Fair enough. Will move them.


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