aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-07-02 19:14:25 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-07-02 19:14:25 +0100
commitc83338238b18c9547ad6c8bb80270dcb7da2b898 (patch)
tree23222dbf7892903fc5b08b9b338ec58b71d32d4e
parentd6a6cef8c150d4001d0370229c49bac7bc2bf9b2 (diff)
downloadxen-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.c22
-rw-r--r--xen/arch/x86/hvm/vpt.c3
-rw-r--r--xen/common/kernel.c3
-rw-r--r--xen/include/asm-x86/domain.h4
-rw-r--r--xen/include/asm-x86/hvm/hvm.h15
-rw-r--r--xen/include/asm-x86/hvm/irq.h4
-rw-r--r--xen/include/public/features.h3
-rw-r--r--xen/include/public/hvm/params.h3
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