[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/hvm: Add per-vcpu evtchn upcalls
HVM guests have always been confined to using the domain callback via (see HVM_PARAM_CALLBACK_IRQ) to receive event notifications which is an IOAPIC vector and is only used if the event channel is bound to vcpu 0. This patch adds a new HVM op allowing a guest to specify a local APIC vector to use as an upcall notification for a specific vcpu. This therefore allows a guest which sets a vector for a vcpu other than 0 to then bind event channels to that vcpu. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Cc: Keir Fraser <keir@xxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 35 +++++++++++++++++++++++++++++++++++ xen/arch/x86/hvm/irq.c | 9 +++++++++ xen/include/asm-x86/hvm/vcpu.h | 1 + xen/include/public/hvm/hvm_op.h | 16 ++++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 78f519d..684e666 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -5458,6 +5458,36 @@ static int hvmop_destroy_ioreq_server( return rc; } +static int hvmop_set_evtchn_upcall_vector( + XEN_GUEST_HANDLE_PARAM(xen_hvm_set_evtchn_upcall_vector_t) uop) +{ + xen_hvm_set_evtchn_upcall_vector_t op; + struct domain *d; + struct vcpu *v; + int rc; + + if ( copy_from_guest(&op, uop, 1) ) + return -EFAULT; + + d = rcu_lock_current_domain(); + + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + goto out; + + if ( op.vcpu >= d->max_vcpus || (v = d->vcpu[op.vcpu]) == NULL ) + goto out; + + printk(XENLOG_G_INFO "%pv: %s %u\n", v, __func__, op.vector); + + v->arch.hvm_vcpu.evtchn_upcall_vector = op.vector; + rc = 0; + + out: + rcu_unlock_domain(d); + return rc; +} + #define HVMOP_op_mask 0xff long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) @@ -5499,6 +5529,11 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) guest_handle_cast(arg, xen_hvm_destroy_ioreq_server_t)); break; + case HVMOP_set_evtchn_upcall_vector: + rc = hvmop_set_evtchn_upcall_vector( + guest_handle_cast(arg, xen_hvm_set_evtchn_upcall_vector_t)); + break; + case HVMOP_set_param: case HVMOP_get_param: { diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 35f4f94..3e4c0b4 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -152,6 +152,13 @@ void hvm_isa_irq_deassert( spin_unlock(&d->arch.hvm_domain.irq_lock); } +static void hvm_set_upcall_irq(struct vcpu *v) +{ + uint8_t vector = v->arch.hvm_vcpu.evtchn_upcall_vector; + + vlapic_set_irq(vcpu_vlapic(v), vector, 0); +} + static void hvm_set_callback_irq_level(struct vcpu *v) { struct domain *d = v->domain; @@ -220,6 +227,8 @@ void hvm_assert_evtchn_irq(struct vcpu *v) if ( is_hvm_pv_evtchn_vcpu(v) ) vcpu_kick(v); + else if ( v->arch.hvm_vcpu.evtchn_upcall_vector != 0 ) + hvm_set_upcall_irq(v); else if ( v->vcpu_id == 0 ) hvm_set_callback_irq_level(v); } diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h index 01e0665..edd4523 100644 --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -160,6 +160,7 @@ struct hvm_vcpu { } u; struct tasklet assert_evtchn_irq_tasklet; + u8 evtchn_upcall_vector; struct nestedvcpu nvcpu; diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index eeb0a60..33ccf45 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -369,6 +369,22 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_ioreq_server_state_t); #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ +/* + * HVMOP_set_evtchn_upcall_vector: Set a <vector> that should be used for event + * channel upcalls on the specified <vcpu>. If set, + * this vector will be used in preference to the + * domain callback via (see HVM_PARAM_CALLBACK_IRQ) + * and hence allows HVM guests to bind event + * event channels to a vcpu other than 0. + */ +#define HVMOP_set_evtchn_upcall_vector 23 +struct xen_hvm_set_evtchn_upcall_vector { + uint32_t vcpu; + uint8_t vector; +}; +typedef struct xen_hvm_set_evtchn_upcall_vector xen_hvm_set_evtchn_upcall_vector_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_evtchn_upcall_vector_t); + #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ /* -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |