aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/irq.c7
-rw-r--r--xen/arch/x86/memory.c6
-rw-r--r--xen/arch/x86/pdb-stub.c8
-rw-r--r--xen/common/ac_timer.c2
-rw-r--r--xen/common/keyhandler.c55
-rw-r--r--xen/common/perfc.c6
-rw-r--r--xen/common/schedule.c14
-rw-r--r--xen/common/softirq.c16
-rw-r--r--xen/drivers/char/console.c12
-rw-r--r--xen/include/asm-x86/bitops.h21
-rw-r--r--xen/include/xen/keyhandler.h5
-rw-r--r--xen/include/xen/softirq.h12
12 files changed, 85 insertions, 79 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 2ed656549c..b3534c0df5 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -210,16 +210,17 @@ static void __do_IRQ_guest(int irq)
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
- int i, j, pirq;
+ unsigned int i, j, pirq;
u32 m;
shared_info_t *s = d->shared_info;
for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
{
m = d->pirq_mask[i];
- while ( (j = ffs(m)) != 0 )
+ while ( m != 0 )
{
- m &= ~(1 << --j);
+ j = find_first_set_bit(m);
+ m &= ~(1 << j);
pirq = (i << 5) + j;
desc = &irq_desc[pirq];
spin_lock_irq(&desc->lock);
diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c
index 410829cc72..39345ed7a3 100644
--- a/xen/arch/x86/memory.c
+++ b/xen/arch/x86/memory.c
@@ -2261,11 +2261,9 @@ void audit_domains(void)
audit_domain(d);
}
-void audit_domains_key(unsigned char key, void *dev_id,
- struct pt_regs *regs)
+void audit_domains_key(unsigned char key)
{
- open_softirq(MEMAUDIT_SOFTIRQ, audit_domains);
- raise_softirq(MEMAUDIT_SOFTIRQ);
+ audit_domains();
}
#endif
diff --git a/xen/arch/x86/pdb-stub.c b/xen/arch/x86/pdb-stub.c
index 774167c88b..a1eb36b0f2 100644
--- a/xen/arch/x86/pdb-stub.c
+++ b/xen/arch/x86/pdb-stub.c
@@ -1213,17 +1213,12 @@ int pdb_handle_exception(int exceptionVector,
return 0;
}
-void __pdb_key_pressed(void)
+void pdb_key_pressed(unsigned char key)
{
struct pt_regs *regs = (struct pt_regs *)get_execution_context();
pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
}
-void pdb_key_pressed(u_char key, void *dev_id, struct pt_regs *regs)
-{
- raise_softirq(DEBUGGER_SOFTIRQ);
-}
-
void initialize_pdb()
{
extern char opt_pdb[];
@@ -1254,7 +1249,6 @@ void initialize_pdb()
/* Acknowledge any spurious GDB packets. */
pdb_put_char('+');
- open_softirq(DEBUGGER_SOFTIRQ, __pdb_key_pressed);
add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
pdb_initialized = 1;
diff --git a/xen/common/ac_timer.c b/xen/common/ac_timer.c
index 658fea3457..ddef6d33c3 100644
--- a/xen/common/ac_timer.c
+++ b/xen/common/ac_timer.c
@@ -244,7 +244,7 @@ static void ac_timer_softirq_action(void)
}
-static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs)
+static void dump_timerq(unsigned char key)
{
struct ac_timer *t;
unsigned long flags;
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 48860e43c9..96ac0d6bd6 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -5,6 +5,7 @@
#include <xen/console.h>
#include <xen/serial.h>
#include <xen/sched.h>
+#include <xen/softirq.h>
#define KEY_MAX 256
#define STR_MAX 64
@@ -14,6 +15,22 @@ static struct {
char desc[STR_MAX];
} key_table[KEY_MAX];
+static unsigned char keypress_key;
+
+void keypress_softirq(void)
+{
+ key_handler *h;
+ unsigned char key = keypress_key;
+ if ( (h = key_table[key].handler) != NULL )
+ (*h)(key);
+}
+
+void handle_keypress(unsigned char key)
+{
+ keypress_key = key;
+ raise_softirq(KEYPRESS_SOFTIRQ);
+}
+
void add_key_handler(unsigned char key, key_handler *handler, char *desc)
{
key_table[key].handler = handler;
@@ -21,13 +38,7 @@ void add_key_handler(unsigned char key, key_handler *handler, char *desc)
key_table[key].desc[STR_MAX-1] = '\0';
}
-key_handler *get_key_handler(unsigned char key)
-{
- return key_table[key].handler;
-}
-
-static void show_handlers(unsigned char key, void *dev_id,
- struct pt_regs *regs)
+static void show_handlers(unsigned char key)
{
int i;
printk("'%c' pressed -> showing installed handlers\n", key);
@@ -39,23 +50,21 @@ static void show_handlers(unsigned char key, void *dev_id,
}
-static void dump_registers(unsigned char key, void *dev_id,
- struct pt_regs *regs)
+static void dump_registers(unsigned char key)
{
+ struct pt_regs *regs = (struct pt_regs *)get_execution_context();
extern void show_registers(struct pt_regs *regs);
printk("'%c' pressed -> dumping registers\n", key);
show_registers(regs);
}
-static void halt_machine(unsigned char key, void *dev_id,
- struct pt_regs *regs)
+static void halt_machine(unsigned char key)
{
printk("'%c' pressed -> rebooting machine\n", key);
machine_restart(NULL);
}
-void do_task_queues(unsigned char key, void *dev_id,
- struct pt_regs *regs)
+void do_task_queues(unsigned char key)
{
unsigned long flags;
struct domain *d;
@@ -102,26 +111,22 @@ void do_task_queues(unsigned char key, void *dev_id,
read_unlock_irqrestore(&tasklist_lock, flags);
}
-extern void dump_runq(unsigned char key, void *dev_id,
- struct pt_regs *regs);
-extern void print_sched_histo(unsigned char key, void *dev_id,
- struct pt_regs *regs);
-extern void reset_sched_histo(unsigned char key, void *dev_id,
- struct pt_regs *regs);
+extern void dump_runq(unsigned char key);
+extern void print_sched_histo(unsigned char key);
+extern void reset_sched_histo(unsigned char key);
#ifndef NDEBUG
-extern void audit_domains_key(unsigned char key, void *dev_id,
- struct pt_regs *regs);
+extern void audit_domains_key(unsigned char key);
#endif
#ifdef PERF_COUNTERS
-extern void perfc_printall(unsigned char key, void *dev_id,
- struct pt_regs *regs);
-extern void perfc_reset(unsigned char key, void *dev_id,
- struct pt_regs *regs);
+extern void perfc_printall(unsigned char key);
+extern void perfc_reset(unsigned char key);
#endif
void initialize_keytable(void)
{
+ open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
+
add_key_handler('d', dump_registers, "dump registers");
add_key_handler('h', show_handlers, "show this message");
add_key_handler('l', print_sched_histo, "print sched latency histogram");
diff --git a/xen/common/perfc.c b/xen/common/perfc.c
index 631e81787c..3a05c2e071 100644
--- a/xen/common/perfc.c
+++ b/xen/common/perfc.c
@@ -31,7 +31,7 @@ static struct {
struct perfcounter_t perfcounters;
-void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs)
+void perfc_printall(unsigned char key)
{
int i, j, sum;
s_time_t now = NOW();
@@ -73,7 +73,7 @@ void perfc_printall(u_char key, void *dev_id, struct pt_regs *regs)
}
}
-void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
+void perfc_reset(unsigned char key)
{
int i, j, sum;
s_time_t now = NOW();
@@ -82,7 +82,7 @@ void perfc_reset(u_char key, void *dev_id, struct pt_regs *regs)
printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
(u32)(now>>32), (u32)now);
- // leave STATUS counters alone -- don't reset
+ /* leave STATUS counters alone -- don't reset */
for ( i = 0; i < NR_PERFCTRS; i++ )
{
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 138234104d..c037c9e177 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -544,7 +544,7 @@ void schedulers_start(void)
}
-void dump_runq(u_char key, void *dev_id, struct pt_regs *regs)
+void dump_runq(unsigned char key)
{
s_time_t now = NOW();
int i;
@@ -568,7 +568,7 @@ void dump_runq(u_char key, void *dev_id, struct pt_regs *regs)
}
#if defined(WAKE_HISTO) || defined(BLOCKTIME_HISTO)
-void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
+void print_sched_histo(unsigned char key)
{
int i, j, k;
for ( k = 0; k < smp_num_cpus; k++ )
@@ -591,7 +591,7 @@ void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
}
}
-void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
+void reset_sched_histo(unsigned char key)
{
int i, j;
for ( j = 0; j < smp_num_cpus; j++ )
@@ -599,10 +599,6 @@ void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
schedule_data[j].hist[i] = 0;
}
#else
-void print_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
-{
-}
-void reset_sched_histo(u_char key, void *dev_id, struct pt_regs *regs)
-{
-}
+void print_sched_histo(unsigned char key) { }
+void reset_sched_histo(unsigned char key) { }
#endif
diff --git a/xen/common/softirq.c b/xen/common/softirq.c
index 3e1472e94a..166a8163c1 100644
--- a/xen/common/softirq.c
+++ b/xen/common/softirq.c
@@ -21,19 +21,13 @@ static softirq_handler softirq_handlers[NR_SOFTIRQS] __cacheline_aligned;
asmlinkage void do_softirq()
{
- unsigned int pending, cpu = smp_processor_id();
- softirq_handler *h;
+ unsigned int i, pending, cpu = smp_processor_id();
- while ( (pending = xchg(&softirq_pending(cpu), 0)) != 0 )
+ while ( (pending = softirq_pending(cpu)) != 0 )
{
- h = softirq_handlers;
- while ( pending )
- {
- if ( pending & 1 )
- (*h)();
- h++;
- pending >>= 1;
- }
+ i = find_first_set_bit(pending);
+ clear_bit(i, &softirq_pending(cpu));
+ (*softirq_handlers[i])();
}
}
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index 350cf09cbd..a6a979284c 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -245,22 +245,20 @@ static void switch_serial_input(void)
static void __serial_rx(unsigned char c, struct pt_regs *regs)
{
- key_handler *handler;
- struct domain *p;
+ struct domain *d;
if ( xen_rx )
{
- if ( (handler = get_key_handler(c)) != NULL )
- (*handler)(c, NULL, regs);
+ handle_keypress(c);
}
else if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
{
serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod)] = c;
if ( serial_rx_prod++ == serial_rx_cons )
{
- p = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
- send_guest_virq(p, VIRQ_CONSOLE);
- put_domain(p);
+ d = find_domain_by_id(0); /* only DOM0 reads the serial buffer */
+ send_guest_virq(d, VIRQ_CONSOLE);
+ put_domain(d);
}
}
}
diff --git a/xen/include/asm-x86/bitops.h b/xen/include/asm-x86/bitops.h
index 58ae424e54..cf98f2e118 100644
--- a/xen/include/asm-x86/bitops.h
+++ b/xen/include/asm-x86/bitops.h
@@ -340,6 +340,27 @@ static __inline__ int ffs(int x)
return r+1;
}
+/*
+ * These are the preferred 'find first' functions in Xen.
+ * Both return the appropriate bit index, with the l.s.b. having index 0.
+ * If an appropriate bit is not found then the result is undefined.
+ */
+static __inline__ unsigned long find_first_clear_bit(unsigned long word)
+{
+ __asm__("bsf"__OS" %1,%0"
+ :"=r" (word)
+ :"r" (~word));
+ return word;
+}
+
+static __inline__ unsigned long find_first_set_bit(unsigned long word)
+{
+ __asm__("bsf"__OS" %1,%0"
+ :"=r" (word)
+ :"r" (word));
+ return word;
+}
+
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
diff --git a/xen/include/xen/keyhandler.h b/xen/include/xen/keyhandler.h
index 03aa53bab5..d12621ef33 100644
--- a/xen/include/xen/keyhandler.h
+++ b/xen/include/xen/keyhandler.h
@@ -6,11 +6,10 @@
*/
#include <xen/sched.h>
-typedef void key_handler(unsigned char key, void *dev_id,
- struct pt_regs *regs);
+typedef void key_handler(unsigned char key);
extern void add_key_handler(unsigned char key,
key_handler *handler, char *desc);
-extern key_handler *get_key_handler(unsigned char key);
+extern void handle_keypress(unsigned char key);
diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h
index 7bf05b9f46..6180dae775 100644
--- a/xen/include/xen/softirq.h
+++ b/xen/include/xen/softirq.h
@@ -1,13 +1,13 @@
#ifndef __XEN_SOFTIRQ_H__
#define __XEN_SOFTIRQ_H__
+/* Common softirqs come first in the following list. */
#define AC_TIMER_SOFTIRQ 0
-#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 1
-#define DEBUGGER_SOFTIRQ 2
-#define NMI_SOFTIRQ 3
-#define SCHEDULE_SOFTIRQ 4
-#define MEMAUDIT_SOFTIRQ 5
-#define NR_SOFTIRQS 6
+#define SCHEDULE_SOFTIRQ 1
+#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
+#define KEYPRESS_SOFTIRQ 3
+#define NMI_SOFTIRQ 4
+#define NR_SOFTIRQS 5
#ifndef __ASSEMBLY__