diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-07-02 19:14:25 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-07-02 19:14:25 +0100 |
commit | c83338238b18c9547ad6c8bb80270dcb7da2b898 (patch) | |
tree | 23222dbf7892903fc5b08b9b338ec58b71d32d4e | |
parent | d6a6cef8c150d4001d0370229c49bac7bc2bf9b2 (diff) | |
download | xen-c83338238b18c9547ad6c8bb80270dcb7da2b898.tar.gz xen-c83338238b18c9547ad6c8bb80270dcb7da2b898.tar.bz2 xen-c83338238b18c9547ad6c8bb80270dcb7da2b898.zip |
x86 hvm: implement vector callback for evtchn delivery
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset: 21449:10ad9b50b4ca
xen-unstable date: Tue May 25 11:28:58 2010 +0100
-rw-r--r-- | xen/arch/x86/hvm/irq.c | 22 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vpt.c | 3 | ||||
-rw-r--r-- | xen/common/kernel.c | 3 | ||||
-rw-r--r-- | xen/include/asm-x86/domain.h | 4 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/hvm.h | 15 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/irq.h | 4 | ||||
-rw-r--r-- | xen/include/public/features.h | 3 | ||||
-rw-r--r-- | xen/include/public/hvm/params.h | 3 |
8 files changed, 44 insertions, 13 deletions
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 1fb18cd150..b0ab1a5343 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -185,16 +185,16 @@ void hvm_maybe_deassert_evtchn_irq(void) void hvm_assert_evtchn_irq(struct vcpu *v) { - if ( v->vcpu_id != 0 ) - return; - if ( unlikely(in_irq() || !local_irq_is_enabled()) ) { tasklet_schedule(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet); return; } - hvm_set_callback_irq_level(v); + if ( is_hvm_pv_evtchn_vcpu(v) ) + vcpu_kick(v); + else if ( v->vcpu_id == 0 ) + hvm_set_callback_irq_level(v); } void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq) @@ -251,7 +251,7 @@ void hvm_set_callback_via(struct domain *d, uint64_t via) via_type = (uint8_t)(via >> 56) + 1; if ( ((via_type == HVMIRQ_callback_gsi) && (via == 0)) || - (via_type > HVMIRQ_callback_pci_intx) ) + (via_type > HVMIRQ_callback_vector) ) via_type = HVMIRQ_callback_none; spin_lock(&d->arch.hvm_domain.irq_lock); @@ -297,6 +297,9 @@ void hvm_set_callback_via(struct domain *d, uint64_t via) if ( hvm_irq->callback_via_asserted ) __hvm_pci_intx_assert(d, pdev, pintx); break; + case HVMIRQ_callback_vector: + hvm_irq->callback_via.vector = (uint8_t)via; + break; default: break; } @@ -312,6 +315,9 @@ void hvm_set_callback_via(struct domain *d, uint64_t via) case HVMIRQ_callback_pci_intx: printk("PCI INTx Dev 0x%02x Int%c\n", pdev, 'A' + pintx); break; + case HVMIRQ_callback_vector: + printk("Direct Vector 0x%02x\n", (uint8_t)via); + break; default: printk("None\n"); break; @@ -323,6 +329,10 @@ struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v) struct hvm_domain *plat = &v->domain->arch.hvm_domain; int vector; + if ( (plat->irq.callback_via_type == HVMIRQ_callback_vector) + && vcpu_info(v, evtchn_upcall_pending) ) + return hvm_intack_vector(plat->irq.callback_via.vector); + if ( unlikely(v->nmi_pending) ) return hvm_intack_nmi; @@ -364,6 +374,8 @@ struct hvm_intack hvm_vcpu_ack_pending_irq( if ( !vlapic_ack_pending_irq(v, intack.vector) ) intack = hvm_intack_none; break; + case hvm_intsrc_vector: + break; default: intack = hvm_intack_none; break; diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c index ce35a3e049..096d083f74 100644 --- a/xen/arch/x86/hvm/vpt.c +++ b/xen/arch/x86/hvm/vpt.c @@ -286,6 +286,9 @@ void pt_intr_post(struct vcpu *v, struct hvm_intack intack) time_cb *cb; void *cb_priv; + if ( intack.source == hvm_intsrc_vector ) + return; + spin_lock(&v->arch.hvm_vcpu.tm_lock); pt = is_pt_irq(v, intack); diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 3a0c40fce4..f45fb9ab36 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -244,7 +244,8 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg) (1U << XENFEAT_highmem_assist) | (1U << XENFEAT_gnttab_map_avail_bits); else - fi.submap |= (1U << XENFEAT_hvm_safe_pvclock); + fi.submap |= (1U << XENFEAT_hvm_safe_pvclock) | + (1U << XENFEAT_hvm_callback_vector); #endif break; default: diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 35661b85b2..a3c3c0d005 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -18,6 +18,10 @@ #endif #define is_pv_32on64_vcpu(v) (is_pv_32on64_domain((v)->domain)) +#define is_hvm_pv_evtchn_domain(d) (is_hvm_domain(d) && \ + d->arch.hvm_domain.irq.callback_via_type == HVMIRQ_callback_vector) +#define is_hvm_pv_evtchn_vcpu(v) (is_hvm_pv_evtchn_domain(v->domain)) + #define VCPU_TRAP_NMI 1 #define VCPU_TRAP_MCE 2 #define VCPU_TRAP_LAST VCPU_TRAP_MCE diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 4969a046c0..4726596160 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -33,17 +33,20 @@ enum hvm_intsrc { hvm_intsrc_pic, hvm_intsrc_lapic, hvm_intsrc_nmi, - hvm_intsrc_mce + hvm_intsrc_mce, + hvm_intsrc_vector }; struct hvm_intack { uint8_t source; /* enum hvm_intsrc */ uint8_t vector; }; -#define hvm_intack_none ( (struct hvm_intack) { hvm_intsrc_none, 0 } ) -#define hvm_intack_pic(vec) ( (struct hvm_intack) { hvm_intsrc_pic, vec } ) -#define hvm_intack_lapic(vec) ( (struct hvm_intack) { hvm_intsrc_lapic, vec } ) -#define hvm_intack_nmi ( (struct hvm_intack) { hvm_intsrc_nmi, 2 } ) -#define hvm_intack_mce ( (struct hvm_intack) { hvm_intsrc_mce, 18 } ) +#define hvm_intack(src, vec) ((struct hvm_intack) { hvm_intsrc_##src, vec }) +#define hvm_intack_none hvm_intack(none, 0) +#define hvm_intack_pic(vec) hvm_intack(pic, vec) +#define hvm_intack_lapic(vec) hvm_intack(lapic, vec) +#define hvm_intack_nmi hvm_intack(nmi, 2) +#define hvm_intack_mce hvm_intack(mce, 18) +#define hvm_intack_vector(vec) hvm_intack(vector, vec) enum hvm_intblk { hvm_intblk_none, /* not blocked (deliverable) */ hvm_intblk_shadow, /* MOV-SS or STI shadow */ diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h index 1f23124279..06e9884db4 100644 --- a/xen/include/asm-x86/hvm/irq.h +++ b/xen/include/asm-x86/hvm/irq.h @@ -54,12 +54,14 @@ struct hvm_irq { enum { HVMIRQ_callback_none, HVMIRQ_callback_gsi, - HVMIRQ_callback_pci_intx + HVMIRQ_callback_pci_intx, + HVMIRQ_callback_vector } callback_via_type; }; union { uint32_t gsi; struct { uint8_t dev, intx; } pci; + uint32_t vector; } callback_via; /* Number of INTx wires asserting each PCI-ISA link. */ diff --git a/xen/include/public/features.h b/xen/include/public/features.h index e95c7b755a..fef7901294 100644 --- a/xen/include/public/features.h +++ b/xen/include/public/features.h @@ -68,6 +68,9 @@ */ #define XENFEAT_gnttab_map_avail_bits 7 +/* x86: Does this Xen host support the HVM callback vector type? */ +#define XENFEAT_hvm_callback_vector 8 + /* x86: pvclock algorithm is safe to use on HVM */ #define XENFEAT_hvm_safe_pvclock 9 diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 15d828fe14..7e276d92e0 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -33,6 +33,9 @@ * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows: * Domain = val[47:32], Bus = val[31:16], * DevFn = val[15: 8], IntX = val[ 1: 0] + * val[63:56] == 2: val[7:0] is a vector number, check for + * XENFEAT_hvm_callback_vector to know if this delivery + * method is available. * If val == 0 then CPU0 event-channel notifications are not delivered. */ #define HVM_PARAM_CALLBACK_IRQ 0 |