[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |