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

Re: [Xen-devel] [PATCH V5] x86/vm_event: Added support for VM_EVENT_REASON_INTERRUPT



> From: Razvan Cojocaru [mailto:rcojocaru@xxxxxxxxxxxxxxx]
> Sent: Saturday, November 12, 2016 12:09 AM
> 
> Added support for a new event type, VM_EVENT_REASON_INTERRUPT,
> which is now fired in a one-shot manner when enabled via the new
> VM_EVENT_FLAG_GET_NEXT_INTERRUPT vm_event response flag.
> The patch also fixes the behaviour of the xc_hvm_inject_trap()
> hypercall, which would lead to non-architectural interrupts
> overwriting pending (specifically reinjected) architectural ones.
> 
> Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
> Acked-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
> 
> ---
> Changes since V4:
>  - Fixed typo in vm_event_monitor_next_interrupt()
>    ( v->arch.monitor.next_interrupt_enabled should have been set
>    to true, not false ).
> 
> Changes in V4 since V3:
>  - Const-ified struct vmcb_struct *vmcb in svm_get_pending_event().
>  - Made next_interrupt_enabled into a bool.
> ---
>  xen/arch/x86/hvm/hvm.c            | 22 +++++++++++++++++++++-
>  xen/arch/x86/hvm/monitor.c        | 14 ++++++++++++++
>  xen/arch/x86/hvm/svm/svm.c        | 15 +++++++++++++++
>  xen/arch/x86/hvm/vmx/vmx.c        | 20 ++++++++++++++++++++
>  xen/arch/x86/vm_event.c           |  5 +++++
>  xen/common/vm_event.c             |  3 +++
>  xen/include/asm-arm/vm_event.h    |  6 ++++++
>  xen/include/asm-x86/domain.h      |  4 ++++
>  xen/include/asm-x86/hvm/hvm.h     |  1 +
>  xen/include/asm-x86/hvm/monitor.h |  2 ++
>  xen/include/asm-x86/monitor.h     |  3 ++-
>  xen/include/public/domctl.h       |  1 +
>  xen/include/public/vm_event.h     | 18 ++++++++++++++++++
>  xen/include/xen/vm_event.h        |  2 ++
>  14 files changed, 114 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 704fd64..93af5b8 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -469,6 +469,12 @@ void hvm_migrate_pirqs(struct vcpu *v)
>      spin_unlock(&d->event_lock);
>  }
> 
> +static bool hvm_get_pending_event(struct vcpu *v, struct hvm_trap *info)
> +{
> +    info->cr2 = v->arch.hvm_vcpu.guest_cr[2];
> +    return hvm_funcs.get_pending_event(v, info);
> +}
> +
>  void hvm_do_resume(struct vcpu *v)
>  {
>      check_wakeup_from_wait();
> @@ -535,9 +541,23 @@ void hvm_do_resume(struct vcpu *v)
>      /* Inject pending hw/sw trap */
>      if ( v->arch.hvm_vcpu.inject_trap.vector != -1 )
>      {
> -        hvm_inject_trap(&v->arch.hvm_vcpu.inject_trap);
> +        if ( !hvm_event_pending(v) )
> +            hvm_inject_trap(&v->arch.hvm_vcpu.inject_trap);
> +
>          v->arch.hvm_vcpu.inject_trap.vector = -1;
>      }
> +
> +    if ( unlikely(v->arch.vm_event) && 
> v->arch.monitor.next_interrupt_enabled )
> +    {
> +        struct hvm_trap info;
> +
> +        if ( hvm_get_pending_event(v, &info) )
> +        {
> +            hvm_monitor_interrupt(info.vector, info.type, info.error_code,
> +                                  info.cr2);
> +            v->arch.monitor.next_interrupt_enabled = false;
> +        }
> +    }
>  }
> 
>  static int hvm_print_line(
> diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
> index 401a8c6..69a88ad 100644
> --- a/xen/arch/x86/hvm/monitor.c
> +++ b/xen/arch/x86/hvm/monitor.c
> @@ -150,6 +150,20 @@ int hvm_monitor_cpuid(unsigned long insn_length, 
> unsigned int
> leaf,
>      return monitor_traps(curr, 1, &req);
>  }
> 
> +void hvm_monitor_interrupt(unsigned int vector, unsigned int type,
> +                           unsigned int err, uint64_t cr2)
> +{
> +    vm_event_request_t req = {
> +        .reason = VM_EVENT_REASON_INTERRUPT,
> +        .u.interrupt.x86.vector = vector,
> +        .u.interrupt.x86.type = type,
> +        .u.interrupt.x86.error_code = err,
> +        .u.interrupt.x86.cr2 = cr2,
> +    };
> +
> +    monitor_traps(current, 1, &req);
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
> index c9dbbea..7fe27e4 100644
> --- a/xen/arch/x86/hvm/svm/svm.c
> +++ b/xen/arch/x86/hvm/svm/svm.c
> @@ -2222,6 +2222,20 @@ static void svm_invlpg(struct vcpu *v, unsigned long 
> vaddr)
>      svm_asid_g_invlpg(v, vaddr);
>  }
> 
> +static bool svm_get_pending_event(struct vcpu *v, struct hvm_trap *info)
> +{
> +    const struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
> +
> +    if ( vmcb->eventinj.fields.v )
> +        return false;
> +
> +    info->vector = vmcb->eventinj.fields.vector;
> +    info->type = vmcb->eventinj.fields.type;
> +    info->error_code = vmcb->eventinj.fields.errorcode;
> +
> +    return true;
> +}
> +
>  static struct hvm_function_table __initdata svm_function_table = {
>      .name                 = "SVM",
>      .cpu_up_prepare       = svm_cpu_up_prepare,
> @@ -2252,6 +2266,7 @@ static struct hvm_function_table __initdata 
> svm_function_table
> = {
>      .inject_trap          = svm_inject_trap,
>      .init_hypercall_page  = svm_init_hypercall_page,
>      .event_pending        = svm_event_pending,
> +    .get_pending_event    = svm_get_pending_event,
>      .invlpg               = svm_invlpg,
>      .cpuid_intercept      = svm_cpuid_intercept,
>      .wbinvd_intercept     = svm_wbinvd_intercept,
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 9a8f694..961a20b 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -2134,6 +2134,25 @@ static int vmx_set_mode(struct vcpu *v, int mode)
>      return 0;
>  }
> 
> +static bool vmx_get_pending_event(struct vcpu *v, struct hvm_trap *info)
> +{
> +    unsigned long intr_info, error_code;
> +
> +    vmx_vmcs_enter(v);
> +    __vmread(VM_ENTRY_INTR_INFO, &intr_info);
> +    __vmread(VM_ENTRY_EXCEPTION_ERROR_CODE, &error_code);
> +    vmx_vmcs_exit(v);
> +
> +    if ( !(intr_info & INTR_INFO_VALID_MASK) )
> +        return false;
> +
> +    info->vector = MASK_EXTR(intr_info, INTR_INFO_VECTOR_MASK);
> +    info->type = MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK);
> +    info->error_code = error_code;
> +
> +    return true;
> +}
> +

Looks not working with APICv virtual interrupt delivery...

Thanks
Kevin

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

 


Rackspace

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