aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-04-08 17:46:51 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-04-08 17:46:51 +0000
commita46b68439d05c3a6b9575bd60ebaa07d584e8245 (patch)
tree03e2fe9ceb94f79dced44e08776ed48ed35d9305
parentcc30041787a7ce6eb1a47ab9640c9dade8eab255 (diff)
downloadxen-a46b68439d05c3a6b9575bd60ebaa07d584e8245.tar.gz
xen-a46b68439d05c3a6b9575bd60ebaa07d584e8245.tar.bz2
xen-a46b68439d05c3a6b9575bd60ebaa07d584e8245.zip
bitkeeper revision 1.858 (4075900bvZ22M6mUE2F3Vk8eDozqtw)
Add support for suspend/resume to new evtchn-IRQ binding mechanism.
-rw-r--r--xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c63
-rw-r--r--xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c4
-rw-r--r--xenolinux-2.4.25-sparse/include/asm-xen/irq.h3
3 files changed, 70 insertions, 0 deletions
diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c
index a9c8991fb9..4f933057c2 100644
--- a/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c
+++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c
@@ -353,6 +353,69 @@ static struct irqaction misdirect_action = {
NULL
};
+void irq_suspend(void)
+{
+ evtchn_op_t op;
+ int virq, irq, evtchn;
+
+ /* Unbind VIRQs from event channels. */
+ for ( virq = 0; virq < NR_VIRQS; virq++ )
+ {
+ if ( (irq = virq_to_irq[virq]) == -1 )
+ continue;
+ evtchn = irq_to_evtchn[irq];
+
+ /* Inform Xen that we are unbinding. */
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ panic("Failed to unbind virtual IRQ %d\n", virq);
+
+ /* Mark the event channel as unused in our table. */
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ }
+
+ /*
+ * We should now be unbound from all event channels. Stale bindings to
+ * PIRQs and/or inter-domain event channels will cause us to barf here.
+ */
+ for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
+ if ( evtchn_to_irq[evtchn] != -1 )
+ panic("Suspend attempted while bound to evtchn %d.\n", evtchn);
+}
+
+
+void irq_resume(void)
+{
+ evtchn_op_t op;
+ int virq, irq, evtchn;
+
+ for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
+ mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */
+
+ for ( virq = 0; virq < NR_VIRQS; virq++ )
+ {
+ if ( (irq = virq_to_irq[virq]) == -1 )
+ continue;
+
+ /* Get a new binding from Xen. */
+ op.cmd = EVTCHNOP_bind_virq;
+ op.u.bind_virq.virq = virq;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ panic("Failed to bind virtual IRQ %d\n", virq);
+ evtchn = op.u.bind_virq.port;
+
+ /* Record the new mapping. */
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ /* Ready for use. */
+ unmask_evtchn(evtchn);
+ }
+}
+
void __init init_IRQ(void)
{
int i;
diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
index 36faf53832..be7cc61efe 100644
--- a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
+++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c
@@ -1190,6 +1190,8 @@ static void stop_task(void *unused)
ctrl_if_suspend();
+ irq_suspend();
+
HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
clear_fixmap(FIX_SHARED_INFO);
@@ -1203,6 +1205,8 @@ static void stop_task(void *unused)
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
memset(empty_zero_page, 0, PAGE_SIZE);
+ irq_resume();
+
ctrl_if_resume();
time_resume();
diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/irq.h b/xenolinux-2.4.25-sparse/include/asm-xen/irq.h
index a05b99640e..668195e9ca 100644
--- a/xenolinux-2.4.25-sparse/include/asm-xen/irq.h
+++ b/xenolinux-2.4.25-sparse/include/asm-xen/irq.h
@@ -53,4 +53,7 @@ extern void disable_irq(unsigned int);
extern void disable_irq_nosync(unsigned int);
extern void enable_irq(unsigned int);
+extern void irq_suspend(void);
+extern void irq_resume(void);
+
#endif /* _ASM_IRQ_H */