ia64/xen-unstable

view linux-2.6-xen-sparse/kernel/irq/spurious.c @ 12945:79bb96e0ba73

[XEN][POWERPC] Create a Domain Foreign Map space
The following patch creates a Domain Foreign Map space that is uses to
map granted memory into the Linear Map of the domain. The Linear Map
of Linux is the is the Kernel Virtual address space where VA = PA +
PAGE_OFFSET.
Also:
- lots of grant_* interfaces work now
- mm.[ch] cleanups
- first pass at extracting Page Table operations from PAPR interfaces
- get_page_type() fix logic bug
- recognize a grant table mapping by placing its gmfn at the end of
real memory.
- grant table usually mapped like an IO page, so force WIMG bits I=0
- mfn_to_gmfn and pfn2mfn get WAY to complex, need get a simpler model in.
- communicate the Domain Foreign Map to domains using /xen/foreign-map
- make sure all bit definitions are UL where possible
- now that we actually assign Xen heap pages to domains they must be
relinquished
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Sun Oct 08 11:34:24 2006 -0400 (2006-10-08)
parents 6fb0d5ad63d7
children 3adf00179a63
line source
1 /*
2 * linux/kernel/irq/spurious.c
3 *
4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
5 *
6 * This file contains spurious interrupt handling.
7 */
9 #include <linux/irq.h>
10 #include <linux/module.h>
11 #include <linux/kallsyms.h>
12 #include <linux/interrupt.h>
14 static int irqfixup;
16 /*
17 * Recovery handler for misrouted interrupts.
18 */
20 static int misrouted_irq(int irq, struct pt_regs *regs)
21 {
22 int i;
23 irq_desc_t *desc;
24 int ok = 0;
25 int work = 0; /* Did we do work for a real IRQ */
27 for(i = 1; i < NR_IRQS; i++) {
28 struct irqaction *action;
30 if (i == irq) /* Already tried */
31 continue;
32 desc = &irq_desc[i];
33 spin_lock(&desc->lock);
34 action = desc->action;
35 /* Already running on another processor */
36 if (desc->status & IRQ_INPROGRESS) {
37 /*
38 * Already running: If it is shared get the other
39 * CPU to go looking for our mystery interrupt too
40 */
41 if (desc->action && (desc->action->flags & SA_SHIRQ))
42 desc->status |= IRQ_PENDING;
43 spin_unlock(&desc->lock);
44 continue;
45 }
46 /* Honour the normal IRQ locking */
47 desc->status |= IRQ_INPROGRESS;
48 spin_unlock(&desc->lock);
49 while (action) {
50 /* Only shared IRQ handlers are safe to call */
51 if (action->flags & SA_SHIRQ) {
52 if (action->handler(i, action->dev_id, regs) ==
53 IRQ_HANDLED)
54 ok = 1;
55 }
56 action = action->next;
57 }
58 local_irq_disable();
59 /* Now clean up the flags */
60 spin_lock(&desc->lock);
61 action = desc->action;
63 /*
64 * While we were looking for a fixup someone queued a real
65 * IRQ clashing with our walk
66 */
68 while ((desc->status & IRQ_PENDING) && action) {
69 /*
70 * Perform real IRQ processing for the IRQ we deferred
71 */
72 work = 1;
73 spin_unlock(&desc->lock);
74 handle_IRQ_event(i, regs, action);
75 spin_lock(&desc->lock);
76 desc->status &= ~IRQ_PENDING;
77 }
78 desc->status &= ~IRQ_INPROGRESS;
79 /*
80 * If we did actual work for the real IRQ line we must let the
81 * IRQ controller clean up too
82 */
83 if(work)
84 desc->handler->end(i);
85 spin_unlock(&desc->lock);
86 }
87 /* So the caller can adjust the irq error counts */
88 return ok;
89 }
91 /*
92 * If 99,900 of the previous 100,000 interrupts have not been handled
93 * then assume that the IRQ is stuck in some manner. Drop a diagnostic
94 * and try to turn the IRQ off.
95 *
96 * (The other 100-of-100,000 interrupts may have been a correctly
97 * functioning device sharing an IRQ with the failing one)
98 *
99 * Called under desc->lock
100 */
102 static void
103 __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
104 {
105 struct irqaction *action;
107 if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
108 printk(KERN_ERR "irq event %d: bogus return value %x\n",
109 irq, action_ret);
110 } else {
111 printk(KERN_ERR "irq %d: nobody cared (try booting with "
112 "the \"irqpoll\" option)\n", irq);
113 }
114 dump_stack();
115 printk(KERN_ERR "handlers:\n");
116 action = desc->action;
117 while (action) {
118 printk(KERN_ERR "[<%p>]", action->handler);
119 print_symbol(" (%s)",
120 (unsigned long)action->handler);
121 printk("\n");
122 action = action->next;
123 }
124 }
126 static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
127 {
128 static int count = 100;
130 if (count > 0) {
131 count--;
132 __report_bad_irq(irq, desc, action_ret);
133 }
134 }
136 void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
137 struct pt_regs *regs)
138 {
139 if (action_ret != IRQ_HANDLED) {
140 if (!irq_ignore_unhandled(irq))
141 desc->irqs_unhandled++;
142 if (action_ret != IRQ_NONE)
143 report_bad_irq(irq, desc, action_ret);
144 }
146 if (unlikely(irqfixup)) {
147 /* Don't punish working computers */
148 if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
149 int ok = misrouted_irq(irq, regs);
150 if (action_ret == IRQ_NONE)
151 desc->irqs_unhandled -= ok;
152 }
153 }
155 desc->irq_count++;
156 if (desc->irq_count < 100000)
157 return;
159 desc->irq_count = 0;
160 if (desc->irqs_unhandled > 99900) {
161 /*
162 * The interrupt is stuck
163 */
164 __report_bad_irq(irq, desc, action_ret);
165 /*
166 * Now kill the IRQ
167 */
168 printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
169 desc->status |= IRQ_DISABLED;
170 desc->handler->disable(irq);
171 }
172 desc->irqs_unhandled = 0;
173 }
175 int noirqdebug;
177 int __init noirqdebug_setup(char *str)
178 {
179 noirqdebug = 1;
180 printk(KERN_INFO "IRQ lockup detection disabled\n");
181 return 1;
182 }
184 __setup("noirqdebug", noirqdebug_setup);
186 static int __init irqfixup_setup(char *str)
187 {
188 irqfixup = 1;
189 printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
190 printk(KERN_WARNING "This may impact system performance.\n");
191 return 1;
192 }
194 __setup("irqfixup", irqfixup_setup);
196 static int __init irqpoll_setup(char *str)
197 {
198 irqfixup = 2;
199 printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
200 "enabled\n");
201 printk(KERN_WARNING "This may significantly impact system "
202 "performance\n");
203 return 1;
204 }
206 __setup("irqpoll", irqpoll_setup);