# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 61b3b357d827ce0d803b7fee2e72e65cfe2aec41
# Parent 93e27f7ca8a83da233a90ae11c75745c86ec639a
# Parent d88e98fd4f7a6d007b3f905a1f3c36c53fd7427a
Merge xen-unstable into xen-ia64-unstable
diff -r 93e27f7ca8a8 -r 61b3b357d827 .hgignore
--- a/.hgignore Thu Sep 29 22:22:02 2005
+++ b/.hgignore Thu Sep 29 23:28:44 2005
@@ -158,6 +158,7 @@
^tools/xenstore/xs_dom0_test$
^tools/xenstore/xs_random$
^tools/xenstore/xs_stress$
+^tools/xenstore/xs_tdb_dump$
^tools/xenstore/xs_test$
^tools/xenstore/xs_watch_stress$
^tools/xentrace/xenctx$
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 Thu Sep
29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 Thu Sep
29 23:28:44 2005
@@ -2684,7 +2684,7 @@
#
# File systems
#
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
@@ -2913,7 +2913,7 @@
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
CONFIG_SECURITY=y
# CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=m
+CONFIG_SECURITY_CAPABILITIES=y
CONFIG_SECURITY_ROOTPLUG=m
CONFIG_SECURITY_SECLVL=m
CONFIG_SECURITY_SELINUX=y
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c Thu Sep 29
23:28:44 2005
@@ -112,6 +112,10 @@
#ifdef CONFIG_HOTPLUG_CPU
#include <asm/nmi.h>
+#ifdef CONFIG_SMP
+extern void smp_suspend(void);
+extern void smp_resume(void);
+#endif
/* We don't actually take CPU down, just spin without interrupts. */
static inline void play_dead(void)
{
@@ -120,6 +124,14 @@
HYPERVISOR_yield();
__flush_tlb_all();
+ /*
+ * Restore IPI/IRQ mappings before marking online to prevent
+ * race between pending interrupts and restoration of handler.
+ */
+#ifdef CONFIG_SMP
+ local_irq_enable(); /* XXX Needed for smp_resume(). Clean me up. */
+ smp_resume();
+#endif
cpu_set(smp_processor_id(), cpu_online_map);
}
#else
@@ -135,10 +147,6 @@
* low exit latency (ie sit in a loop waiting for
* somebody to say that they'd like to reschedule)
*/
-#ifdef CONFIG_SMP
-extern void smp_suspend(void);
-extern void smp_resume(void);
-#endif
void cpu_idle (void)
{
int cpu = _smp_processor_id();
@@ -166,9 +174,6 @@
HYPERVISOR_vcpu_down(cpu);
#endif
play_dead();
-#ifdef CONFIG_SMP
- smp_resume();
-#endif
local_irq_enable();
}
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c Thu Sep 29 23:28:44 2005
@@ -131,21 +131,9 @@
static inline void __send_IPI_one(unsigned int cpu, int vector)
{
- unsigned int evtchn;
-
- evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
- // printk("send_IPI_mask_bitmask cpu %d vector %d evtchn %d\n", cpu,
vector, evtchn);
- if (evtchn) {
-#if 0
- shared_info_t *s = HYPERVISOR_shared_info;
- while (synch_test_bit(evtchn, &s->evtchn_pending[0]) ||
- synch_test_bit(evtchn, &s->evtchn_mask[0]))
- ;
-#endif
- notify_via_evtchn(evtchn);
- } else
- printk("send_IPI to unbound port %d/%d",
- cpu, vector);
+ int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+ BUG_ON(evtchn < 0);
+ notify_remote_via_evtchn(evtchn);
}
void __send_IPI_shortcut(unsigned int shortcut, int vector)
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Thu Sep 29
23:28:44 2005
@@ -446,27 +446,6 @@
static int cpucount;
-
-static irqreturn_t ldebug_interrupt(
- int irq, void *dev_id, struct pt_regs *regs)
-{
- return IRQ_HANDLED;
-}
-
-static DEFINE_PER_CPU(int, ldebug_irq);
-static char ldebug_name[NR_CPUS][15];
-
-void ldebug_setup(void)
-{
- int cpu = smp_processor_id();
-
- per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG);
- sprintf(ldebug_name[cpu], "ldebug%d", cpu);
- BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt,
- SA_INTERRUPT, ldebug_name[cpu], NULL));
-}
-
-
extern void local_setup_timer(void);
/*
@@ -484,7 +463,6 @@
while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
rep_nop();
local_setup_timer();
- ldebug_setup();
smp_intr_init();
local_irq_enable();
/*
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Thu Sep 29 23:28:44 2005
@@ -186,8 +186,8 @@
"mov %4,%%eax ; "
"mov %%edx,%4 ; "
"mul %5 ; "
+ "xor %5,%5 ; "
"add %4,%%eax ; "
- "xor %5,%5 ; "
"adc %5,%%edx ; "
: "=A" (product), "=r" (tmp1), "=r" (tmp2)
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
@@ -836,13 +836,6 @@
cpu_clear(smp_processor_id(), nohz_cpu_mask);
}
-void time_suspend(void)
-{
- /* nothing */
- teardown_irq(per_cpu(timer_irq, 0), &irq_timer);
- unbind_virq_from_irq(VIRQ_TIMER);
-}
-
/* No locking required. We are only CPU running, and interrupts are off. */
void time_resume(void)
{
@@ -854,9 +847,6 @@
per_cpu(processed_system_time, 0) = processed_system_time;
update_wallclock();
-
- per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
- (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
}
#ifdef CONFIG_SMP
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c Thu Sep 29 23:28:44 2005
@@ -209,7 +209,10 @@
{
unsigned long *p, page;
- page = __pa(per_cpu(cur_pgd, smp_processor_id()));
+ preempt_disable();
+ page = __pa(per_cpu(cur_pgd, smp_processor_id()));
+ preempt_enable();
+
p = (unsigned long *)__va(page);
p += (address >> 30) * 2;
printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
@@ -237,7 +240,12 @@
{
unsigned long page;
+ preempt_disable();
page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id()))
+ [address >> 22];
+ preempt_enable();
+
+ page = ((unsigned long *) per_cpu(cur_pgd, get_cpu()))
[address >> 22];
printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
machine_to_phys(page));
@@ -567,7 +575,9 @@
pmd_t *pmd, *pmd_k;
pte_t *pte_k;
+ preempt_disable();
pgd = index + per_cpu(cur_pgd, smp_processor_id());
+ preempt_enable();
pgd_k = init_mm.pgd + index;
if (!pgd_present(*pgd_k))
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/kernel/devmem.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c Thu Sep 29 23:28:44 2005
@@ -144,3 +144,13 @@
.mmap = mmap_mem,
.open = open_mem,
};
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Thu Sep 29 23:28:44 2005
@@ -3,7 +3,7 @@
*
* Communication via Xen event channels.
*
- * Copyright (c) 2002-2004, K A Fraser
+ * Copyright (c) 2002-2005, K A Fraser
*
* This file may be distributed separately from the Linux kernel, or
* incorporated into other software packages, subject to the following license:
@@ -73,27 +73,33 @@
static u8 cpu_evtchn[NR_EVENT_CHANNELS];
static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32];
-#define active_evtchns(cpu,sh,idx) \
- ((sh)->evtchn_pending[idx] & \
- cpu_evtchn_mask[cpu][idx] & \
- ~(sh)->evtchn_mask[idx])
-
-void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-{
- clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
- set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
- cpu_evtchn[chn] = cpu;
+#define active_evtchns(cpu,sh,idx) \
+ ((sh)->evtchn_pending[idx] & \
+ cpu_evtchn_mask[cpu][idx] & \
+ ~(sh)->evtchn_mask[idx])
+
+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+{
+ clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
+ set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
+ cpu_evtchn[chn] = cpu;
+}
+
+static void init_evtchn_cpu_bindings(void)
+{
+ /* By default all event channels notify CPU#0. */
+ memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
+ memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
}
#else
-#define active_evtchns(cpu,sh,idx) \
- ((sh)->evtchn_pending[idx] & \
- ~(sh)->evtchn_mask[idx])
-
-void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-{
-}
+#define active_evtchns(cpu,sh,idx) \
+ ((sh)->evtchn_pending[idx] & \
+ ~(sh)->evtchn_mask[idx])
+#define bind_evtchn_to_cpu(chn,cpu) ((void)0)
+#define init_evtchn_cpu_bindings() ((void)0)
+
#endif
/* Upcall to generic IRQ layer. */
@@ -108,9 +114,9 @@
#elif defined (__x86_64__)
#define IRQ_REG orig_rax
#endif
-#define do_IRQ(irq, regs) do { \
- (regs)->IRQ_REG = (irq); \
- do_IRQ((regs)); \
+#define do_IRQ(irq, regs) do { \
+ (regs)->IRQ_REG = (irq); \
+ do_IRQ((regs)); \
} while (0)
#endif
@@ -123,249 +129,241 @@
*/
void force_evtchn_callback(void)
{
- (void)HYPERVISOR_xen_version(0, NULL);
+ (void)HYPERVISOR_xen_version(0, NULL);
}
EXPORT_SYMBOL(force_evtchn_callback);
/* NB. Interrupts are disabled on entry. */
asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
{
- u32 l1, l2;
- unsigned int l1i, l2i, port;
- int irq, cpu = smp_processor_id();
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_data[cpu];
-
- vcpu_info->evtchn_upcall_pending = 0;
-
- /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
- l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
- while ( l1 != 0 )
- {
- l1i = __ffs(l1);
- l1 &= ~(1 << l1i);
+ u32 l1, l2;
+ unsigned int l1i, l2i, port;
+ int irq, cpu = smp_processor_id();
+ shared_info_t *s = HYPERVISOR_shared_info;
+ vcpu_info_t *vcpu_info = &s->vcpu_data[cpu];
+
+ vcpu_info->evtchn_upcall_pending = 0;
+
+ /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+ l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
+ while (l1 != 0) {
+ l1i = __ffs(l1);
+ l1 &= ~(1 << l1i);
- while ( (l2 = active_evtchns(cpu, s, l1i)) != 0 )
- {
- l2i = __ffs(l2);
- l2 &= ~(1 << l2i);
+ while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
+ l2i = __ffs(l2);
+ l2 &= ~(1 << l2i);
- port = (l1i << 5) + l2i;
- if ( (irq = evtchn_to_irq[port]) != -1 ) {
- do_IRQ(irq, regs);
- } else
- evtchn_device_upcall(port);
- }
- }
+ port = (l1i << 5) + l2i;
+ if ((irq = evtchn_to_irq[port]) != -1)
+ do_IRQ(irq, regs);
+ else
+ evtchn_device_upcall(port);
+ }
+ }
}
EXPORT_SYMBOL(evtchn_do_upcall);
static int find_unbound_irq(void)
{
- int irq;
-
- for ( irq = 0; irq < NR_IRQS; irq++ )
- if ( irq_bindcount[irq] == 0 )
- break;
-
- if ( irq == NR_IRQS )
- panic("No available IRQ to bind to: increase NR_IRQS!\n");
-
- return irq;
+ int irq;
+
+ for (irq = 0; irq < NR_IRQS; irq++)
+ if (irq_bindcount[irq] == 0)
+ break;
+
+ if (irq == NR_IRQS)
+ panic("No available IRQ to bind to: increase NR_IRQS!\n");
+
+ return irq;
}
int bind_virq_to_irq(int virq)
{
- evtchn_op_t op;
- int evtchn, irq;
- int cpu = smp_processor_id();
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (irq = per_cpu(virq_to_irq, cpu)[virq]) == -1 )
- {
- 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;
-
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- per_cpu(virq_to_irq, cpu)[virq] = irq;
-
- bind_evtchn_to_cpu(evtchn, cpu);
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
+ evtchn_op_t op;
+ int evtchn, irq;
+ int cpu = smp_processor_id();
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
+ op.cmd = EVTCHNOP_bind_virq;
+ op.u.bind_virq.virq = virq;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ evtchn = op.u.bind_virq.port;
+
+ irq = find_unbound_irq();
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ per_cpu(virq_to_irq, cpu)[virq] = irq;
+
+ bind_evtchn_to_cpu(evtchn, cpu);
+ }
+
+ irq_bindcount[irq]++;
+
+ spin_unlock(&irq_mapping_update_lock);
- return irq;
+ return irq;
}
EXPORT_SYMBOL(bind_virq_to_irq);
void unbind_virq_from_irq(int virq)
{
- evtchn_op_t op;
- int cpu = smp_processor_id();
- int irq = per_cpu(virq_to_irq, cpu)[virq];
- int evtchn = irq_to_evtchn[irq];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- 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);
-
- /*
- * This is a slight hack. Interdomain ports can be allocated directly
- * by userspace, and at that point they get bound by Xen to vcpu 0. We
- * therefore need to make sure that if we get an event on an event
- * channel we don't know about vcpu 0 handles it. Binding channels to
- * vcpu 0 when closing them achieves this.
- */
- bind_evtchn_to_cpu(evtchn, 0);
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- per_cpu(virq_to_irq, cpu)[virq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
+ evtchn_op_t op;
+ int cpu = smp_processor_id();
+ int irq = per_cpu(virq_to_irq, cpu)[virq];
+ int evtchn = irq_to_evtchn[irq];
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if (--irq_bindcount[irq] == 0) {
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+ /*
+ * This is a slight hack. Interdomain ports can be allocated
+ * directly by userspace, and at that point they get bound by
+ * Xen to vcpu 0. We therefore need to make sure that if we get
+ * an event on an event channel we don't know about vcpu 0
+ * handles it. Binding channels to vcpu 0 when closing them
+ * achieves this.
+ */
+ bind_evtchn_to_cpu(evtchn, 0);
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ per_cpu(virq_to_irq, cpu)[virq] = -1;
+ }
+
+ spin_unlock(&irq_mapping_update_lock);
}
EXPORT_SYMBOL(unbind_virq_from_irq);
int bind_ipi_to_irq(int ipi)
{
- evtchn_op_t op;
- int evtchn, irq;
- int cpu = smp_processor_id();
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0 )
- {
- op.cmd = EVTCHNOP_bind_ipi;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to bind virtual IPI %d on cpu %d\n", ipi, cpu);
- evtchn = op.u.bind_ipi.port;
-
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
-
- bind_evtchn_to_cpu(evtchn, cpu);
- }
- else
- {
- irq = evtchn_to_irq[evtchn];
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
-
- return irq;
+ evtchn_op_t op;
+ int evtchn, irq;
+ int cpu = smp_processor_id();
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
+ op.cmd = EVTCHNOP_bind_ipi;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ evtchn = op.u.bind_ipi.port;
+
+ irq = find_unbound_irq();
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
+
+ bind_evtchn_to_cpu(evtchn, cpu);
+ } else {
+ irq = evtchn_to_irq[evtchn];
+ }
+
+ irq_bindcount[irq]++;
+
+ spin_unlock(&irq_mapping_update_lock);
+
+ return irq;
}
EXPORT_SYMBOL(bind_ipi_to_irq);
void unbind_ipi_from_irq(int ipi)
{
- evtchn_op_t op;
- int cpu = smp_processor_id();
- int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
- int irq = evtchn_to_irq[evtchn];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- 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 IPI %d on cpu %d\n", ipi, cpu);
-
- /* See comments in unbind_virq_from_irq */
- bind_evtchn_to_cpu(evtchn, 0);
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- per_cpu(ipi_to_evtchn, cpu)[ipi] = 0;
- }
-
- spin_unlock(&irq_mapping_update_lock);
+ evtchn_op_t op;
+ int cpu = smp_processor_id();
+ int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
+ int irq = evtchn_to_irq[evtchn];
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if (--irq_bindcount[irq] == 0) {
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+ /* See comments in unbind_virq_from_irq */
+ bind_evtchn_to_cpu(evtchn, 0);
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ per_cpu(ipi_to_evtchn, cpu)[ipi] = -1;
+ }
+
+ spin_unlock(&irq_mapping_update_lock);
}
EXPORT_SYMBOL(unbind_ipi_from_irq);
int bind_evtchn_to_irq(unsigned int evtchn)
{
- int irq;
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (irq = evtchn_to_irq[evtchn]) == -1 )
- {
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
+ int irq;
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((irq = evtchn_to_irq[evtchn]) == -1) {
+ irq = find_unbound_irq();
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+ }
+
+ irq_bindcount[irq]++;
+
+ spin_unlock(&irq_mapping_update_lock);
- return irq;
+ return irq;
}
EXPORT_SYMBOL(bind_evtchn_to_irq);
-void unbind_evtchn_from_irq(unsigned int evtchn)
-{
- int irq = evtchn_to_irq[evtchn];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
+void unbind_evtchn_from_irq(unsigned int irq)
+{
+ evtchn_op_t op;
+ int evtchn = irq_to_evtchn[irq];
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ }
+
+ spin_unlock(&irq_mapping_update_lock);
}
EXPORT_SYMBOL(unbind_evtchn_from_irq);
int bind_evtchn_to_irqhandler(
- unsigned int evtchn,
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags,
- const char *devname,
- void *dev_id)
-{
- unsigned int irq;
- int retval;
-
- irq = bind_evtchn_to_irq(evtchn);
- retval = request_irq(irq, handler, irqflags, devname, dev_id);
- if ( retval != 0 )
- unbind_evtchn_from_irq(evtchn);
-
- return retval;
+ unsigned int evtchn,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id)
+{
+ unsigned int irq;
+ int retval;
+
+ irq = bind_evtchn_to_irq(evtchn);
+ retval = request_irq(irq, handler, irqflags, devname, dev_id);
+ if (retval != 0)
+ unbind_evtchn_from_irq(irq);
+
+ return irq;
}
EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
-void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
-{
- unsigned int irq = evtchn_to_irq[evtchn];
- free_irq(irq, dev_id);
- unbind_evtchn_from_irq(evtchn);
+void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
+{
+ free_irq(irq, dev_id);
+ unbind_evtchn_from_irq(irq);
}
EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
@@ -378,50 +376,50 @@
/* Rebind an evtchn so that it gets delivered to a specific cpu */
static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
{
- evtchn_op_t op;
- int evtchn;
-
- spin_lock(&irq_mapping_update_lock);
- evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn)) {
- spin_unlock(&irq_mapping_update_lock);
- return;
- }
-
- /* Tell Xen to send future instances of this interrupt to other vcpu. */
- op.cmd = EVTCHNOP_bind_vcpu;
- op.u.bind_vcpu.port = evtchn;
- op.u.bind_vcpu.vcpu = tcpu;
-
- /*
- * If this fails, it usually just indicates that we're dealing with a virq
- * or IPI channel, which don't actually need to be rebound. Ignore it,
- * but don't do the xenlinux-level rebind in that case.
- */
- if (HYPERVISOR_event_channel_op(&op) >= 0)
- bind_evtchn_to_cpu(evtchn, tcpu);
-
- spin_unlock(&irq_mapping_update_lock);
-
- /*
- * Now send the new target processor a NOP IPI. When this returns, it
- * will check for any pending interrupts, and so service any that got
- * delivered to the wrong processor by mistake.
- *
- * XXX: The only time this is called with interrupts disabled is from the
- * hotplug/hotunplug path. In that case, all cpus are stopped with
- * interrupts disabled, and the missed interrupts will be picked up when
- * they start again. This is kind of a hack.
- */
- if (!irqs_disabled())
- smp_call_function(do_nothing_function, NULL, 0, 0);
+ evtchn_op_t op;
+ int evtchn;
+
+ spin_lock(&irq_mapping_update_lock);
+ evtchn = irq_to_evtchn[irq];
+ if (!VALID_EVTCHN(evtchn)) {
+ spin_unlock(&irq_mapping_update_lock);
+ return;
+ }
+
+ /* Send future instances of this interrupt to other vcpu. */
+ op.cmd = EVTCHNOP_bind_vcpu;
+ op.u.bind_vcpu.port = evtchn;
+ op.u.bind_vcpu.vcpu = tcpu;
+
+ /*
+ * If this fails, it usually just indicates that we're dealing with a
+ * virq or IPI channel, which don't actually need to be rebound. Ignore
+ * it, but don't do the xenlinux-level rebind in that case.
+ */
+ if (HYPERVISOR_event_channel_op(&op) >= 0)
+ bind_evtchn_to_cpu(evtchn, tcpu);
+
+ spin_unlock(&irq_mapping_update_lock);
+
+ /*
+ * Now send the new target processor a NOP IPI. When this returns, it
+ * will check for any pending interrupts, and so service any that got
+ * delivered to the wrong processor by mistake.
+ *
+ * XXX: The only time this is called with interrupts disabled is from
+ * the hotplug/hotunplug path. In that case, all cpus are stopped with
+ * interrupts disabled, and the missed interrupts will be picked up
+ * when they start again. This is kind of a hack.
+ */
+ if (!irqs_disabled())
+ smp_call_function(do_nothing_function, NULL, 0, 0);
}
static void set_affinity_irq(unsigned irq, cpumask_t dest)
{
- unsigned tcpu = first_cpu(dest);
- rebind_irq_to_cpu(irq, tcpu);
+ unsigned tcpu = first_cpu(dest);
+ rebind_irq_to_cpu(irq, tcpu);
}
/*
@@ -430,83 +428,84 @@
static unsigned int startup_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
-
- if ( !VALID_EVTCHN(evtchn) )
- return 0;
- unmask_evtchn(evtchn);
- return 0;
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn))
+ unmask_evtchn(evtchn);
+ return 0;
}
static void shutdown_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
-
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
}
static void enable_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
-
- unmask_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn))
+ unmask_evtchn(evtchn);
}
static void disable_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
-
- mask_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
}
static void ack_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
-
- mask_evtchn(evtchn);
- clear_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn)) {
+ mask_evtchn(evtchn);
+ clear_evtchn(evtchn);
+ }
}
static void end_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
-
- if ( !(irq_desc[irq].status & IRQ_DISABLED) )
- unmask_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
+ unmask_evtchn(evtchn);
}
static struct hw_interrupt_type dynirq_type = {
- "Dynamic-irq",
- startup_dynirq,
- shutdown_dynirq,
- enable_dynirq,
- disable_dynirq,
- ack_dynirq,
- end_dynirq,
- set_affinity_irq
+ "Dynamic-irq",
+ startup_dynirq,
+ shutdown_dynirq,
+ enable_dynirq,
+ disable_dynirq,
+ ack_dynirq,
+ end_dynirq,
+ set_affinity_irq
};
static inline void pirq_unmask_notify(int pirq)
{
- physdev_op_t op;
- if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) )
- {
- op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
- (void)HYPERVISOR_physdev_op(&op);
- }
+ physdev_op_t op;
+ if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
+ op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
+ (void)HYPERVISOR_physdev_op(&op);
+ }
}
static inline void pirq_query_unmask(int pirq)
{
- physdev_op_t op;
- op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
- op.u.irq_status_query.irq = pirq;
- (void)HYPERVISOR_physdev_op(&op);
- clear_bit(pirq, &pirq_needs_unmask_notify[0]);
- if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
- set_bit(pirq, &pirq_needs_unmask_notify[0]);
+ physdev_op_t op;
+ op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
+ op.u.irq_status_query.irq = pirq;
+ (void)HYPERVISOR_physdev_op(&op);
+ clear_bit(pirq, &pirq_needs_unmask_notify[0]);
+ if (op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
+ set_bit(pirq, &pirq_needs_unmask_notify[0]);
}
/*
@@ -517,218 +516,252 @@
static unsigned int startup_pirq(unsigned int irq)
{
- evtchn_op_t op;
- int evtchn;
-
- op.cmd = EVTCHNOP_bind_pirq;
- op.u.bind_pirq.pirq = irq;
- /* NB. We are happy to share unless we are probing. */
- op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- {
- if ( !probing_irq(irq) ) /* Some failures are expected when probing. */
- printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq);
- return 0;
- }
- evtchn = op.u.bind_pirq.port;
-
- pirq_query_unmask(irq_to_pirq(irq));
-
- bind_evtchn_to_cpu(evtchn, 0);
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
-
- return 0;
+ evtchn_op_t op;
+ int evtchn;
+
+ op.cmd = EVTCHNOP_bind_pirq;
+ op.u.bind_pirq.pirq = irq;
+ /* NB. We are happy to share unless we are probing. */
+ op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+ if (HYPERVISOR_event_channel_op(&op) != 0) {
+ if ( !probing_irq(irq) )
+ printk(KERN_INFO "Failed to obtain physical "
+ "IRQ %d\n", irq);
+ return 0;
+ }
+ evtchn = op.u.bind_pirq.port;
+
+ pirq_query_unmask(irq_to_pirq(irq));
+
+ bind_evtchn_to_cpu(evtchn, 0);
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+
+ return 0;
}
static void shutdown_pirq(unsigned int irq)
{
- evtchn_op_t op;
- int evtchn = irq_to_evtchn[irq];
-
- if ( !VALID_EVTCHN(evtchn) )
- return;
-
- mask_evtchn(evtchn);
-
- 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 physical IRQ %d\n", irq);
-
- bind_evtchn_to_cpu(evtchn, 0);
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
+ evtchn_op_t op;
+ int evtchn = irq_to_evtchn[irq];
+
+ if (!VALID_EVTCHN(evtchn))
+ return;
+
+ mask_evtchn(evtchn);
+
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
+ bind_evtchn_to_cpu(evtchn, 0);
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
}
static void enable_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn)) {
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+ }
}
static void disable_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
}
static void ack_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
- clear_evtchn(evtchn);
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn)) {
+ mask_evtchn(evtchn);
+ clear_evtchn(evtchn);
+ }
}
static void end_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- if ( !(irq_desc[irq].status & IRQ_DISABLED) )
- {
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
- }
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+ }
}
static struct hw_interrupt_type pirq_type = {
- "Phys-irq",
- startup_pirq,
- shutdown_pirq,
- enable_pirq,
- disable_pirq,
- ack_pirq,
- end_pirq,
- set_affinity_irq
+ "Phys-irq",
+ startup_pirq,
+ shutdown_pirq,
+ enable_pirq,
+ disable_pirq,
+ ack_pirq,
+ end_pirq,
+ set_affinity_irq
};
void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
- int evtchn = irq_to_evtchn[i];
- shared_info_t *s = HYPERVISOR_shared_info;
- if ( !VALID_EVTCHN(evtchn) )
- return;
- BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
- synch_set_bit(evtchn, &s->evtchn_pending[0]);
-}
-
-void irq_suspend(void)
-{
- int pirq, virq, irq, evtchn;
- int cpu = smp_processor_id(); /* XXX */
-
- /* Unbind VIRQs from event channels. */
- for ( virq = 0; virq < NR_VIRQS; virq++ )
- {
- if ( (irq = per_cpu(virq_to_irq, cpu)[virq]) == -1 )
- continue;
- evtchn = irq_to_evtchn[irq];
-
- /* Mark the event channel as unused in our table. */
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- }
-
- /* Check that no PIRQs are still bound. */
- for ( pirq = 0; pirq < NR_PIRQS; pirq++ )
- if ( (evtchn = irq_to_evtchn[pirq_to_irq(pirq)]) != -1 )
- panic("Suspend attempted while PIRQ %d bound to evtchn %d.\n",
- pirq, evtchn);
+ int evtchn = irq_to_evtchn[i];
+ shared_info_t *s = HYPERVISOR_shared_info;
+ if (!VALID_EVTCHN(evtchn))
+ return;
+ BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
+ synch_set_bit(evtchn, &s->evtchn_pending[0]);
+}
+
+void notify_remote_via_irq(int irq)
+{
+ int evtchn = irq_to_evtchn[irq];
+
+ if (VALID_EVTCHN(evtchn))
+ notify_remote_via_evtchn(evtchn);
}
void irq_resume(void)
{
- evtchn_op_t op;
- int virq, irq, evtchn;
- int cpu = smp_processor_id(); /* XXX */
-
- 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 = per_cpu(virq_to_irq, cpu)[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;
+ evtchn_op_t op;
+ int cpu, pirq, virq, ipi, irq, evtchn;
+
+ init_evtchn_cpu_bindings();
+
+ /* New event-channel space is not 'live' yet. */
+ for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
+ mask_evtchn(evtchn);
+
+ /* Check that no PIRQs are still bound. */
+ for (pirq = 0; pirq < NR_PIRQS; pirq++)
+ BUG_ON(irq_to_evtchn[pirq_to_irq(pirq)] != -1);
+
+ /* Secondary CPUs must have no VIRQ or IPI bindings. */
+ for (cpu = 1; cpu < NR_CPUS; cpu++) {
+ for (virq = 0; virq < NR_VIRQS; virq++)
+ BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
+ for (ipi = 0; ipi < NR_IPIS; ipi++)
+ BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
+ }
+
+ /* No IRQ -> event-channel mappings. */
+ for (irq = 0; irq < NR_IRQS; irq++)
+ irq_to_evtchn[irq] = -1;
+
+ /* Primary CPU: rebind VIRQs automatically. */
+ for (virq = 0; virq < NR_VIRQS; virq++) {
+ if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
+ continue;
+
+ /* Get a new binding from Xen. */
+ op.cmd = EVTCHNOP_bind_virq;
+ op.u.bind_virq.virq = virq;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ evtchn = op.u.bind_virq.port;
- /* Record the new mapping. */
- bind_evtchn_to_cpu(evtchn, 0);
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- /* Ready for use. */
- unmask_evtchn(evtchn);
- }
+ /* Record the new mapping. */
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ /* Ready for use. */
+ unmask_evtchn(evtchn);
+ }
+
+ /* Primary CPU: rebind IPIs automatically. */
+ for (ipi = 0; ipi < NR_IPIS; ipi++) {
+ if ((evtchn = per_cpu(ipi_to_evtchn, 0)[ipi]) == -1)
+ continue;
+
+ irq = evtchn_to_irq[evtchn];
+ evtchn_to_irq[evtchn] = -1;
+
+ /* Get a new binding from Xen. */
+ op.cmd = EVTCHNOP_bind_ipi;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+ evtchn = op.u.bind_ipi.port;
+
+ /* Record the new mapping. */
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ /* Ready for use. */
+ unmask_evtchn(evtchn);
+ }
+
+ /* Remove defunct event-channel -> IRQ mappings. */
+ for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
+ if ((evtchn_to_irq[evtchn] != -1) &&
+ (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
+ evtchn_to_irq[evtchn] = -1;
+ }
}
void __init init_IRQ(void)
{
- int i;
- int cpu;
-
- irq_ctx_init(0);
-
- spin_lock_init(&irq_mapping_update_lock);
-
-#ifdef CONFIG_SMP
- /* By default all event channels notify CPU#0. */
- memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
-#endif
-
- for ( cpu = 0; cpu < NR_CPUS; cpu++ ) {
- /* No VIRQ -> IRQ mappings. */
- for ( i = 0; i < NR_VIRQS; i++ )
- per_cpu(virq_to_irq, cpu)[i] = -1;
- }
-
- /* No event-channel -> IRQ mappings. */
- for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
- {
- evtchn_to_irq[i] = -1;
- mask_evtchn(i); /* No event channels are 'live' right now. */
- }
-
- /* No IRQ -> event-channel mappings. */
- for ( i = 0; i < NR_IRQS; i++ )
- irq_to_evtchn[i] = -1;
-
- for ( i = 0; i < NR_DYNIRQS; i++ )
- {
- /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
- irq_bindcount[dynirq_to_irq(i)] = 0;
-
- irq_desc[dynirq_to_irq(i)].status = IRQ_DISABLED;
- irq_desc[dynirq_to_irq(i)].action = 0;
- irq_desc[dynirq_to_irq(i)].depth = 1;
- irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
- }
-
- for ( i = 0; i < NR_PIRQS; i++ )
- {
- /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
- irq_bindcount[pirq_to_irq(i)] = 1;
-
- irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED;
- irq_desc[pirq_to_irq(i)].action = 0;
- irq_desc[pirq_to_irq(i)].depth = 1;
- irq_desc[pirq_to_irq(i)].handler = &pirq_type;
- }
-}
+ int i;
+ int cpu;
+
+ irq_ctx_init(0);
+
+ spin_lock_init(&irq_mapping_update_lock);
+
+ init_evtchn_cpu_bindings();
+
+ /* No VIRQ or IPI bindings. */
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ for (i = 0; i < NR_VIRQS; i++)
+ per_cpu(virq_to_irq, cpu)[i] = -1;
+ for (i = 0; i < NR_IPIS; i++)
+ per_cpu(ipi_to_evtchn, cpu)[i] = -1;
+ }
+
+ /* No event-channel -> IRQ mappings. */
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+ evtchn_to_irq[i] = -1;
+ mask_evtchn(i); /* No event channels are 'live' right now. */
+ }
+
+ /* No IRQ -> event-channel mappings. */
+ for (i = 0; i < NR_IRQS; i++)
+ irq_to_evtchn[i] = -1;
+
+ /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
+ for (i = 0; i < NR_DYNIRQS; i++) {
+ irq_bindcount[dynirq_to_irq(i)] = 0;
+
+ irq_desc[dynirq_to_irq(i)].status = IRQ_DISABLED;
+ irq_desc[dynirq_to_irq(i)].action = 0;
+ irq_desc[dynirq_to_irq(i)].depth = 1;
+ irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
+ }
+
+ /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
+ for (i = 0; i < NR_PIRQS; i++)
+ {
+ irq_bindcount[pirq_to_irq(i)] = 1;
+
+ irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED;
+ irq_desc[pirq_to_irq(i)].action = 0;
+ irq_desc[pirq_to_irq(i)].depth = 1;
+ irq_desc[pirq_to_irq(i)].handler = &pirq_type;
+ }
+}
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/kernel/fixup.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/fixup.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/fixup.c Thu Sep 29 23:28:44 2005
@@ -37,51 +37,57 @@
#define DP(_f, _args...) printk(KERN_ALERT " " _f "\n" , ## _args )
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define __LINKAGE fastcall
-#else
-#define __LINKAGE asmlinkage
-#endif
+fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
+{
+ static unsigned long printed = 0;
+ char info[100];
+ int i;
-__LINKAGE void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
-{
- static unsigned long printed = 0;
- char info[100];
- int i;
+ if (test_and_set_bit(0, &printed))
+ return;
- if ( !test_and_set_bit(0, &printed) )
- {
- HYPERVISOR_vm_assist(VMASST_CMD_disable,
- VMASST_TYPE_4gb_segments_notify);
+ HYPERVISOR_vm_assist(
+ VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
- sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
+ sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
- DP("");
- DP("***************************************************************");
- DP("***************************************************************");
- DP("** WARNING: Currently emulating unsupported memory accesses **");
- DP("** in /lib/tls libraries. The emulation is very **");
- DP("** slow. To ensure full performance you should **");
- DP("** execute the following as root: **");
- DP("** mv /lib/tls /lib/tls.disabled **");
- DP("** Offending process: %-38.38s **", info);
- DP("***************************************************************");
- DP("***************************************************************");
- DP("");
- for ( i = 5; i > 0; i-- )
- {
- printk("Pausing... %d", i);
- mdelay(1000);
- printk("\b\b\b\b\b\b\b\b\b\b\b\b");
- }
- printk("Continuing...\n\n");
- }
+ DP("");
+ DP("***************************************************************");
+ DP("***************************************************************");
+ DP("** WARNING: Currently emulating unsupported memory accesses **");
+ DP("** in /lib/tls libraries. The emulation is very **");
+ DP("** slow. To ensure full performance you should **");
+ DP("** execute the following as root: **");
+ DP("** mv /lib/tls /lib/tls.disabled **");
+ DP("** Offending process: %-38.38s **", info);
+ DP("***************************************************************");
+ DP("***************************************************************");
+ DP("");
+
+ for (i = 5; i > 0; i--) {
+ printk("Pausing... %d", i);
+ mdelay(1000);
+ printk("\b\b\b\b\b\b\b\b\b\b\b\b");
+ }
+
+ printk("Continuing...\n\n");
}
static int __init fixup_init(void)
{
- HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
- return 0;
+ HYPERVISOR_vm_assist(
+ VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
+ return 0;
}
__initcall(fixup_init);
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Thu Sep 29 23:28:44 2005
@@ -1,13 +1,10 @@
/******************************************************************************
* gnttab.c
*
- * Two sets of functionality:
- * 1. Granting foreign access to our memory reservation.
- * 2. Accessing others' memory reservations via grant references.
- * (i.e., mechanisms for both sender and recipient of grant references)
+ * Granting foreign access to our memory reservation.
*
* Copyright (c) 2005, Christopher Clark
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-2005, K A Fraser
*/
#include <linux/config.h>
@@ -23,15 +20,15 @@
#include <asm/synch_bitops.h>
#if 1
-#define ASSERT(_p) \
- if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
- #_p , __LINE__, __FILE__); *(int*)0=0; }
+#define ASSERT(_p) \
+ if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
+ #_p , __LINE__, __FILE__); *(int*)0=0; }
#else
#define ASSERT(_p) ((void)0)
#endif
-#define WPRINTK(fmt, args...) \
- printk(KERN_WARNING "xen_grant: " fmt, ##args)
+#define WPRINTK(fmt, args...) \
+ printk(KERN_WARNING "xen_grant: " fmt, ##args)
EXPORT_SYMBOL(gnttab_grant_foreign_access);
@@ -49,11 +46,14 @@
EXPORT_SYMBOL(gnttab_grant_foreign_access_ref);
EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref);
+/* External tools reserve first few grant table entries. */
+#define NR_RESERVED_ENTRIES 8
+
#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
-static int gnttab_free_count = NR_GRANT_ENTRIES;
+static int gnttab_free_count;
static grant_ref_t gnttab_free_head;
static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
@@ -64,22 +64,22 @@
static int
get_free_entries(int count)
{
- unsigned long flags;
- int ref;
- grant_ref_t head;
- spin_lock_irqsave(&gnttab_list_lock, flags);
- if (gnttab_free_count < count) {
+ unsigned long flags;
+ int ref;
+ grant_ref_t head;
+ spin_lock_irqsave(&gnttab_list_lock, flags);
+ if (gnttab_free_count < count) {
+ spin_unlock_irqrestore(&gnttab_list_lock, flags);
+ return -1;
+ }
+ ref = head = gnttab_free_head;
+ gnttab_free_count -= count;
+ while (count-- > 1)
+ head = gnttab_list[head];
+ gnttab_free_head = gnttab_list[head];
+ gnttab_list[head] = GNTTAB_LIST_END;
spin_unlock_irqrestore(&gnttab_list_lock, flags);
- return -1;
- }
- ref = head = gnttab_free_head;
- gnttab_free_count -= count;
- while (count-- > 1)
- head = gnttab_list[head];
- gnttab_free_head = gnttab_list[head];
- gnttab_list[head] = GNTTAB_LIST_END;
- spin_unlock_irqrestore(&gnttab_list_lock, flags);
- return ref;
+ return ref;
}
#define get_free_entry() get_free_entries(1)
@@ -87,38 +87,41 @@
static void
do_free_callbacks(void)
{
- struct gnttab_free_callback *callback = gnttab_free_callback_list, *next;
- gnttab_free_callback_list = NULL;
- while (callback) {
- next = callback->next;
- if (gnttab_free_count >= callback->count) {
- callback->next = NULL;
- callback->fn(callback->arg);
- } else {
- callback->next = gnttab_free_callback_list;
- gnttab_free_callback_list = callback;
- }
- callback = next;
- }
+ struct gnttab_free_callback *callback, *next;
+
+ callback = gnttab_free_callback_list;
+ gnttab_free_callback_list = NULL;
+
+ while (callback != NULL) {
+ next = callback->next;
+ if (gnttab_free_count >= callback->count) {
+ callback->next = NULL;
+ callback->fn(callback->arg);
+ } else {
+ callback->next = gnttab_free_callback_list;
+ gnttab_free_callback_list = callback;
+ }
+ callback = next;
+ }
}
static inline void
check_free_callbacks(void)
{
- if (unlikely(gnttab_free_callback_list))
- do_free_callbacks();
+ if (unlikely(gnttab_free_callback_list))
+ do_free_callbacks();
}
static void
put_free_entry(grant_ref_t ref)
{
- unsigned long flags;
- spin_lock_irqsave(&gnttab_list_lock, flags);
- gnttab_list[ref] = gnttab_free_head;
- gnttab_free_head = ref;
- gnttab_free_count++;
- check_free_callbacks();
- spin_unlock_irqrestore(&gnttab_list_lock, flags);
+ unsigned long flags;
+ spin_lock_irqsave(&gnttab_list_lock, flags);
+ gnttab_list[ref] = gnttab_free_head;
+ gnttab_free_head = ref;
+ gnttab_free_count++;
+ check_free_callbacks();
+ spin_unlock_irqrestore(&gnttab_list_lock, flags);
}
/*
@@ -128,187 +131,189 @@
int
gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
{
- int ref;
+ int ref;
- if ( unlikely((ref = get_free_entry()) == -1) )
- return -ENOSPC;
-
- shared[ref].frame = frame;
- shared[ref].domid = domid;
- wmb();
- shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
-
- return ref;
+ if (unlikely((ref = get_free_entry()) == -1))
+ return -ENOSPC;
+
+ shared[ref].frame = frame;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+
+ return ref;
}
void
gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
unsigned long frame, int readonly)
{
- shared[ref].frame = frame;
- shared[ref].domid = domid;
- wmb();
- shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
+ shared[ref].frame = frame;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
}
int
gnttab_query_foreign_access(grant_ref_t ref)
{
- u16 nflags;
-
- nflags = shared[ref].flags;
-
- return ( nflags & (GTF_reading|GTF_writing) );
+ u16 nflags;
+
+ nflags = shared[ref].flags;
+
+ return (nflags & (GTF_reading|GTF_writing));
}
void
gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
{
- u16 flags, nflags;
-
- nflags = shared[ref].flags;
- do {
- if ( (flags = nflags) & (GTF_reading|GTF_writing) )
- printk(KERN_ALERT "WARNING: g.e. still in use!\n");
- }
- while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags );
+ u16 flags, nflags;
+
+ nflags = shared[ref].flags;
+ do {
+ if ( (flags = nflags) & (GTF_reading|GTF_writing) )
+ printk(KERN_ALERT "WARNING: g.e. still in use!\n");
+ }
+ while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
+ flags);
}
void
gnttab_end_foreign_access(grant_ref_t ref, int readonly)
{
- gnttab_end_foreign_access_ref(ref, readonly);
- put_free_entry(ref);
+ gnttab_end_foreign_access_ref(ref, readonly);
+ put_free_entry(ref);
}
int
gnttab_grant_foreign_transfer(domid_t domid)
{
- int ref;
-
- if ( unlikely((ref = get_free_entry()) == -1) )
- return -ENOSPC;
-
- shared[ref].frame = 0;
- shared[ref].domid = domid;
- wmb();
- shared[ref].flags = GTF_accept_transfer;
-
- return ref;
+ int ref;
+
+ if (unlikely((ref = get_free_entry()) == -1))
+ return -ENOSPC;
+
+ shared[ref].frame = 0;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_accept_transfer;
+
+ return ref;
}
void
gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
{
- shared[ref].frame = 0;
- shared[ref].domid = domid;
- wmb();
- shared[ref].flags = GTF_accept_transfer;
+ shared[ref].frame = 0;
+ shared[ref].domid = domid;
+ wmb();
+ shared[ref].flags = GTF_accept_transfer;
}
unsigned long
gnttab_end_foreign_transfer_ref(grant_ref_t ref)
{
- unsigned long frame = 0;
- u16 flags;
-
- flags = shared[ref].flags;
-
- /*
- * If a transfer is committed then wait for the frame address to appear.
- * Otherwise invalidate the grant entry against future use.
- */
- if ( likely(flags != GTF_accept_transfer) ||
- (synch_cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
- while ( unlikely((frame = shared[ref].frame) == 0) )
- cpu_relax();
-
- return frame;
+ unsigned long frame = 0;
+ u16 flags;
+
+ flags = shared[ref].flags;
+
+ /*
+ * If a transfer is committed then wait for the frame address to
+ * appear. Otherwise invalidate the grant entry against future use.
+ */
+ if (likely(flags != GTF_accept_transfer) ||
+ (synch_cmpxchg(&shared[ref].flags, flags, 0) !=
+ GTF_accept_transfer))
+ while (unlikely((frame = shared[ref].frame) == 0))
+ cpu_relax();
+
+ return frame;
}
unsigned long
gnttab_end_foreign_transfer(grant_ref_t ref)
{
- unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
- put_free_entry(ref);
- return frame;
+ unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
+ put_free_entry(ref);
+ return frame;
}
void
gnttab_free_grant_reference(grant_ref_t ref)
{
- put_free_entry(ref);
+ put_free_entry(ref);
}
void
gnttab_free_grant_references(grant_ref_t head)
{
- grant_ref_t ref;
- unsigned long flags;
- int count = 1;
- if (head == GNTTAB_LIST_END)
- return;
- spin_lock_irqsave(&gnttab_list_lock, flags);
- ref = head;
- while (gnttab_list[ref] != GNTTAB_LIST_END) {
- ref = gnttab_list[ref];
- count++;
- }
- gnttab_list[ref] = gnttab_free_head;
- gnttab_free_head = head;
- gnttab_free_count += count;
- check_free_callbacks();
- spin_unlock_irqrestore(&gnttab_list_lock, flags);
+ grant_ref_t ref;
+ unsigned long flags;
+ int count = 1;
+ if (head == GNTTAB_LIST_END)
+ return;
+ spin_lock_irqsave(&gnttab_list_lock, flags);
+ ref = head;
+ while (gnttab_list[ref] != GNTTAB_LIST_END) {
+ ref = gnttab_list[ref];
+ count++;
+ }
+ gnttab_list[ref] = gnttab_free_head;
+ gnttab_free_head = head;
+ gnttab_free_count += count;
+ check_free_callbacks();
+ spin_unlock_irqrestore(&gnttab_list_lock, flags);
}
int
gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
{
- int h = get_free_entries(count);
-
- if (h == -1)
- return -ENOSPC;
-
- *head = h;
-
- return 0;
+ int h = get_free_entries(count);
+
+ if (h == -1)
+ return -ENOSPC;
+
+ *head = h;
+
+ return 0;
}
int
gnttab_claim_grant_reference(grant_ref_t *private_head)
{
- grant_ref_t g = *private_head;
- if (unlikely(g == GNTTAB_LIST_END))
- return -ENOSPC;
- *private_head = gnttab_list[g];
- return g;
+ grant_ref_t g = *private_head;
+ if (unlikely(g == GNTTAB_LIST_END))
+ return -ENOSPC;
+ *private_head = gnttab_list[g];
+ return g;
}
void
gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release)
{
- gnttab_list[release] = *private_head;
- *private_head = release;
+ gnttab_list[release] = *private_head;
+ *private_head = release;
}
void
gnttab_request_free_callback(struct gnttab_free_callback *callback,
void (*fn)(void *), void *arg, u16 count)
{
- unsigned long flags;
- spin_lock_irqsave(&gnttab_list_lock, flags);
- if (callback->next)
- goto out;
- callback->fn = fn;
- callback->arg = arg;
- callback->count = count;
- callback->next = gnttab_free_callback_list;
- gnttab_free_callback_list = callback;
- check_free_callbacks();
+ unsigned long flags;
+ spin_lock_irqsave(&gnttab_list_lock, flags);
+ if (callback->next)
+ goto out;
+ callback->fn = fn;
+ callback->arg = arg;
+ callback->count = count;
+ callback->next = gnttab_free_callback_list;
+ gnttab_free_callback_list = callback;
+ check_free_callbacks();
out:
- spin_unlock_irqrestore(&gnttab_list_lock, flags);
+ spin_unlock_irqrestore(&gnttab_list_lock, flags);
}
/*
@@ -323,79 +328,83 @@
grant_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long data)
{
- int ret;
- privcmd_hypercall_t hypercall;
-
- /* XXX Need safety checks here if using for anything other
- * than debugging */
- return -ENOSYS;
-
- if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
- return -ENOSYS;
-
- if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
- return -EFAULT;
-
- if ( hypercall.op != __HYPERVISOR_grant_table_op )
- return -ENOSYS;
-
- /* hypercall-invoking asm taken from privcmd.c */
- __asm__ __volatile__ (
- "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
- "movl 4(%%eax),%%ebx ;"
- "movl 8(%%eax),%%ecx ;"
- "movl 12(%%eax),%%edx ;"
- "movl 16(%%eax),%%esi ;"
- "movl 20(%%eax),%%edi ;"
- "movl (%%eax),%%eax ;"
- TRAP_INSTR "; "
- "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
- : "=a" (ret) : "0" (&hypercall) : "memory" );
-
- return ret;
+ int ret;
+ privcmd_hypercall_t hypercall;
+
+ /*
+ * XXX Need safety checks here if using for anything other
+ * than debugging.
+ */
+ return -ENOSYS;
+
+ if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
+ return -ENOSYS;
+
+ if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
+ return -EFAULT;
+
+ if ( hypercall.op != __HYPERVISOR_grant_table_op )
+ return -ENOSYS;
+
+ /* hypercall-invoking asm taken from privcmd.c */
+ __asm__ __volatile__ (
+ "pushl %%ebx; pushl %%ecx; pushl %%edx; "
+ "pushl %%esi; pushl %%edi; "
+ "movl 4(%%eax),%%ebx ;"
+ "movl 8(%%eax),%%ecx ;"
+ "movl 12(%%eax),%%edx ;"
+ "movl 16(%%eax),%%esi ;"
+ "movl 20(%%eax),%%edi ;"
+ "movl (%%eax),%%eax ;"
+ TRAP_INSTR "; "
+ "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
+ : "=a" (ret) : "0" (&hypercall) : "memory" );
+
+ return ret;
}
static struct file_operations grant_file_ops = {
- ioctl: grant_ioctl,
+ ioctl: grant_ioctl,
};
static int
grant_read(char *page, char **start, off_t off, int count, int *eof,
void *data)
{
- int len;
- unsigned int i;
- grant_entry_t *gt;
-
- gt = (grant_entry_t *)shared;
- len = 0;
-
- for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
- /* TODO: safety catch here until this can handle >PAGE_SIZE output */
- if (len > (PAGE_SIZE - 200))
- {
- len += sprintf( page + len, "Truncated.\n");
- break;
- }
-
- if ( gt[i].flags )
- len += sprintf( page + len,
- "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame
(0x%x)\n",
- i,
- gt[i].flags,
- gt[i].domid,
- gt[i].frame );
-
- *eof = 1;
- return len;
+ int len;
+ unsigned int i;
+ grant_entry_t *gt;
+
+ gt = (grant_entry_t *)shared;
+ len = 0;
+
+ for (i = 0; i < NR_GRANT_ENTRIES; i++) {
+ if (len > (PAGE_SIZE - 200)) {
+ len += sprintf( page + len, "Truncated.\n");
+ break;
+ }
+ }
+
+ if (gt[i].flags) {
+ len += sprintf(page + len,
+ "Grant: ref (0x%x) flags (0x%hx) "
+ "dom (0x%hx) frame (0x%x)\n",
+ i,
+ gt[i].flags,
+ gt[i].domid,
+ gt[i].frame );
+ }
+
+ *eof = 1;
+ return len;
}
static int
grant_write(struct file *file, const char __user *buffer, unsigned long count,
void *data)
{
- /* TODO: implement this */
- return -ENOSYS;
+ /* TODO: implement this */
+ return -ENOSYS;
}
#endif /* CONFIG_PROC_FS */
@@ -403,70 +412,81 @@
int
gnttab_resume(void)
{
- gnttab_setup_table_t setup;
- unsigned long frames[NR_GRANT_FRAMES];
- int i;
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = NR_GRANT_FRAMES;
- setup.frame_list = frames;
-
- BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0);
- BUG_ON(setup.status != 0);
-
- for ( i = 0; i < NR_GRANT_FRAMES; i++ )
- set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
-
- return 0;
+ gnttab_setup_table_t setup;
+ unsigned long frames[NR_GRANT_FRAMES];
+ int i;
+
+ setup.dom = DOMID_SELF;
+ setup.nr_frames = NR_GRANT_FRAMES;
+ setup.frame_list = frames;
+
+ BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
+ BUG_ON(setup.status != 0);
+
+ for (i = 0; i < NR_GRANT_FRAMES; i++)
+ set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
+
+ return 0;
}
int
gnttab_suspend(void)
{
- int i;
-
- for ( i = 0; i < NR_GRANT_FRAMES; i++ )
- clear_fixmap(FIX_GNTTAB_END - i);
-
- return 0;
+ int i;
+
+ for (i = 0; i < NR_GRANT_FRAMES; i++)
+ clear_fixmap(FIX_GNTTAB_END - i);
+
+ return 0;
}
static int __init
gnttab_init(void)
{
- int i;
-
- if (xen_init() < 0)
- return -ENODEV;
-
- BUG_ON(gnttab_resume());
-
- shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
-
- for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
- gnttab_list[i] = i + 1;
-
+ int i;
+
+ if (xen_init() < 0)
+ return -ENODEV;
+
+ BUG_ON(gnttab_resume());
+
+ shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
+
+ for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
+ gnttab_list[i] = i + 1;
+ gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
+ gnttab_free_head = NR_RESERVED_ENTRIES;
+
#ifdef CONFIG_PROC_FS
- /*
- * /proc/xen/grant : used by libxc to access grant tables
- */
- if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
- {
- WPRINTK("Unable to create grant xen proc entry\n");
- return -1;
- }
-
- grant_file_ops.read = grant_pde->proc_fops->read;
- grant_file_ops.write = grant_pde->proc_fops->write;
-
- grant_pde->proc_fops = &grant_file_ops;
-
- grant_pde->read_proc = &grant_read;
- grant_pde->write_proc = &grant_write;
+ /*
+ * /proc/xen/grant : used by libxc to access grant tables
+ */
+ if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
+ WPRINTK("Unable to create grant xen proc entry\n");
+ return -1;
+ }
+
+ grant_file_ops.read = grant_pde->proc_fops->read;
+ grant_file_ops.write = grant_pde->proc_fops->write;
+
+ grant_pde->proc_fops = &grant_file_ops;
+
+ grant_pde->read_proc = &grant_read;
+ grant_pde->write_proc = &grant_write;
#endif
- printk("Grant table initialized\n");
- return 0;
+ printk("Grant table initialized\n");
+ return 0;
}
__initcall(gnttab_init);
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Thu Sep 29 23:28:44 2005
@@ -12,7 +12,6 @@
#include <asm-xen/evtchn.h>
#include <asm/hypervisor.h>
#include <asm-xen/xen-public/dom0_ops.h>
-#include <asm-xen/queues.h>
#include <asm-xen/xenbus.h>
#include <linux/cpu.h>
#include <linux/kthread.h>
@@ -43,12 +42,10 @@
HYPERVISOR_shutdown();
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
int reboot_thru_bios = 0; /* for dmi_scan.c */
EXPORT_SYMBOL(machine_restart);
EXPORT_SYMBOL(machine_halt);
EXPORT_SYMBOL(machine_power_off);
-#endif
/******************************************************************************
@@ -66,227 +63,194 @@
static int __do_suspend(void *ignore)
{
- int i, j, k, fpp;
-
-#ifdef CONFIG_XEN_USB_FRONTEND
- extern void usbif_resume();
-#else
-#define usbif_resume() do{}while(0)
-#endif
-
- extern int gnttab_suspend(void);
- extern int gnttab_resume(void);
-
- extern void time_suspend(void);
- extern void time_resume(void);
- extern unsigned long max_pfn;
- extern unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[];
+ int i, j, k, fpp;
+
+ extern int gnttab_suspend(void);
+ extern int gnttab_resume(void);
+
+ extern void time_resume(void);
+ extern unsigned long max_pfn;
+ extern unsigned long *pfn_to_mfn_frame_list_list;
+ extern unsigned long *pfn_to_mfn_frame_list[];
#ifdef CONFIG_SMP
- extern void smp_suspend(void);
- extern void smp_resume(void);
-
- static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
- cpumask_t prev_online_cpus, prev_present_cpus;
-
- void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
- int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
-#endif
-
- extern void xencons_suspend(void);
- extern void xencons_resume(void);
-
- int err = 0;
-
- BUG_ON(smp_processor_id() != 0);
- BUG_ON(in_interrupt());
+ static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
+ cpumask_t prev_online_cpus, prev_present_cpus;
+
+ void save_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
+ int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
+#endif
+
+ extern void xencons_resume(void);
+
+ int err = 0;
+
+ BUG_ON(smp_processor_id() != 0);
+ BUG_ON(in_interrupt());
#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
- if (num_online_cpus() > 1) {
- printk(KERN_WARNING
- "Can't suspend SMP guests without CONFIG_HOTPLUG_CPU\n");
- return -EOPNOTSUPP;
- }
-#endif
-
- preempt_disable();
+ if (num_online_cpus() > 1) {
+ printk(KERN_WARNING "Can't suspend SMP guests "
+ "without CONFIG_HOTPLUG_CPU\n");
+ return -EOPNOTSUPP;
+ }
+#endif
+
+ xenbus_suspend();
+
+ preempt_disable();
#ifdef CONFIG_SMP
- /* Take all of the other cpus offline. We need to be careful not
- to get preempted between the final test for num_online_cpus()
- == 1 and disabling interrupts, since otherwise userspace could
- bring another cpu online, and then we'd be stuffed. At the
- same time, cpu_down can reschedule, so we need to enable
- preemption while doing that. This kind of sucks, but should be
- correct. */
- /* (We don't need to worry about other cpus bringing stuff up,
- since by the time num_online_cpus() == 1, there aren't any
- other cpus) */
- cpus_clear(prev_online_cpus);
- while (num_online_cpus() > 1) {
+ /* Take all of the other cpus offline. We need to be careful not
+ to get preempted between the final test for num_online_cpus()
+ == 1 and disabling interrupts, since otherwise userspace could
+ bring another cpu online, and then we'd be stuffed. At the
+ same time, cpu_down can reschedule, so we need to enable
+ preemption while doing that. This kind of sucks, but should be
+ correct. */
+ /* (We don't need to worry about other cpus bringing stuff up,
+ since by the time num_online_cpus() == 1, there aren't any
+ other cpus) */
+ cpus_clear(prev_online_cpus);
+ while (num_online_cpus() > 1) {
+ preempt_enable();
+ for_each_online_cpu(i) {
+ if (i == 0)
+ continue;
+ err = cpu_down(i);
+ if (err != 0) {
+ printk(KERN_CRIT "Failed to take all CPUs "
+ "down: %d.\n", err);
+ goto out_reenable_cpus;
+ }
+ cpu_set(i, prev_online_cpus);
+ }
+ preempt_disable();
+ }
+#endif
+
+ __cli();
+
preempt_enable();
- for_each_online_cpu(i) {
- if (i == 0)
- continue;
- err = cpu_down(i);
- if (err != 0) {
- printk(KERN_CRIT "Failed to take all CPUs down: %d.\n", err);
- goto out_reenable_cpus;
- }
- cpu_set(i, prev_online_cpus);
- }
- preempt_disable();
- }
-#endif
-
- __cli();
-
- preempt_enable();
#ifdef CONFIG_SMP
- cpus_clear(prev_present_cpus);
- for_each_present_cpu(i) {
- if (i == 0)
- continue;
- save_vcpu_context(i, &suspended_cpu_records[i]);
- cpu_set(i, prev_present_cpus);
- }
-#endif
+ cpus_clear(prev_present_cpus);
+ for_each_present_cpu(i) {
+ if (i == 0)
+ continue;
+ save_vcpu_context(i, &suspended_cpu_records[i]);
+ cpu_set(i, prev_present_cpus);
+ }
+#endif
+
+ gnttab_suspend();
#ifdef __i386__
- mm_pin_all();
- kmem_cache_shrink(pgd_cache);
-#endif
-
- time_suspend();
-
-#ifdef CONFIG_SMP
- smp_suspend();
-#endif
-
- xenbus_suspend();
-
- xencons_suspend();
-
- irq_suspend();
-
- gnttab_suspend();
-
- HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
- clear_fixmap(FIX_SHARED_INFO);
-
- xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
- xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn);
-
- /* We'll stop somewhere inside this hypercall. When it returns,
- we'll start resuming after the restore. */
- HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
-
- shutting_down = SHUTDOWN_INVALID;
-
- set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-
- HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-
- memset(empty_zero_page, 0, PAGE_SIZE);
+ mm_pin_all();
+ kmem_cache_shrink(pgd_cache);
+#endif
+
+ HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
+ clear_fixmap(FIX_SHARED_INFO);
+
+ xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
+ xen_start_info->console_mfn = mfn_to_pfn(xen_start_info->console_mfn);
+
+ /* We'll stop somewhere inside this hypercall. When it returns,
+ we'll start resuming after the restore. */
+ HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+
+ shutting_down = SHUTDOWN_INVALID;
+
+ set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+
+ HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+
+ memset(empty_zero_page, 0, PAGE_SIZE);
- HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+ HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
virt_to_mfn(pfn_to_mfn_frame_list_list);
- fpp = PAGE_SIZE/sizeof(unsigned long);
- for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ )
- {
- if ( (j % fpp) == 0 )
- {
- k++;
- pfn_to_mfn_frame_list_list[k] =
- virt_to_mfn(pfn_to_mfn_frame_list[k]);
- j=0;
- }
- pfn_to_mfn_frame_list[k][j] =
- virt_to_mfn(&phys_to_machine_mapping[i]);
- }
- HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-
- gnttab_resume();
-
- irq_resume();
-
- xencons_resume();
-
- xenbus_resume();
+ fpp = PAGE_SIZE/sizeof(unsigned long);
+ for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
+ if ((j % fpp) == 0) {
+ k++;
+ pfn_to_mfn_frame_list_list[k] =
+ virt_to_mfn(pfn_to_mfn_frame_list[k]);
+ j = 0;
+ }
+ pfn_to_mfn_frame_list[k][j] =
+ virt_to_mfn(&phys_to_machine_mapping[i]);
+ }
+ HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+
+ gnttab_resume();
+
+ irq_resume();
+
+ time_resume();
#ifdef CONFIG_SMP
- smp_resume();
-#endif
-
- time_resume();
-
- usbif_resume();
-
-#ifdef CONFIG_SMP
- for_each_cpu_mask(i, prev_present_cpus)
- restore_vcpu_context(i, &suspended_cpu_records[i]);
-#endif
-
- __sti();
+ for_each_cpu_mask(i, prev_present_cpus)
+ restore_vcpu_context(i, &suspended_cpu_records[i]);
+#endif
+
+ __sti();
+
+ xencons_resume();
+
+ xenbus_resume();
#ifdef CONFIG_SMP
out_reenable_cpus:
- for_each_cpu_mask(i, prev_online_cpus) {
- j = cpu_up(i);
- if (j != 0) {
- printk(KERN_CRIT "Failed to bring cpu %d back up (%d).\n",
- i, j);
- err = j;
- }
- }
-#endif
-
- return err;
+ for_each_cpu_mask(i, prev_online_cpus) {
+ j = cpu_up(i);
+ if (j != 0) {
+ printk(KERN_CRIT "Failed to bring cpu "
+ "%d back up (%d).\n",
+ i, j);
+ err = j;
+ }
+ }
+#endif
+
+ return err;
}
static int shutdown_process(void *__unused)
{
- static char *envp[] = { "HOME=/", "TERM=linux",
- "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
- static char *restart_argv[] = { "/sbin/reboot", NULL };
- static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
-
- extern asmlinkage long sys_reboot(int magic1, int magic2,
- unsigned int cmd, void *arg);
-
- daemonize(
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- "shutdown"
-#endif
- );
-
- switch ( shutting_down )
- {
- case SHUTDOWN_POWEROFF:
- if ( execve("/sbin/poweroff", poweroff_argv, envp) < 0 )
- {
- sys_reboot(LINUX_REBOOT_MAGIC1,
- LINUX_REBOOT_MAGIC2,
- LINUX_REBOOT_CMD_POWER_OFF,
- NULL);
- }
- break;
-
- case SHUTDOWN_REBOOT:
- if ( execve("/sbin/reboot", restart_argv, envp) < 0 )
- {
- sys_reboot(LINUX_REBOOT_MAGIC1,
- LINUX_REBOOT_MAGIC2,
- LINUX_REBOOT_CMD_RESTART,
- NULL);
- }
- break;
- }
-
- shutting_down = SHUTDOWN_INVALID; /* could try again */
-
- return 0;
+ static char *envp[] = { "HOME=/", "TERM=linux",
+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+ static char *restart_argv[] = { "/sbin/reboot", NULL };
+ static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
+
+ extern asmlinkage long sys_reboot(int magic1, int magic2,
+ unsigned int cmd, void *arg);
+
+ daemonize("shutdown");
+
+ switch (shutting_down) {
+ case SHUTDOWN_POWEROFF:
+ if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) {
+ sys_reboot(LINUX_REBOOT_MAGIC1,
+ LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_POWER_OFF,
+ NULL);
+ }
+ break;
+
+ case SHUTDOWN_REBOOT:
+ if (execve("/sbin/reboot", restart_argv, envp) < 0) {
+ sys_reboot(LINUX_REBOOT_MAGIC1,
+ LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART,
+ NULL);
+ }
+ break;
+ }
+
+ shutting_down = SHUTDOWN_INVALID; /* could try again */
+
+ return 0;
}
static struct task_struct *kthread_create_on_cpu(int (*f)(void *arg),
@@ -294,113 +258,109 @@
const char *name,
int cpu)
{
- struct task_struct *p;
- p = kthread_create(f, arg, name);
- kthread_bind(p, cpu);
- wake_up_process(p);
- return p;
+ struct task_struct *p;
+ p = kthread_create(f, arg, name);
+ kthread_bind(p, cpu);
+ wake_up_process(p);
+ return p;
}
static void __shutdown_handler(void *unused)
{
- int err;
-
- if ( shutting_down != SHUTDOWN_SUSPEND )
- {
- err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES);
- if ( err < 0 )
- printk(KERN_ALERT "Error creating shutdown process!\n");
- }
- else
- {
- kthread_create_on_cpu(__do_suspend, NULL, "suspender", 0);
- }
+ int err;
+
+ if (shutting_down != SHUTDOWN_SUSPEND) {
+ err = kernel_thread(shutdown_process, NULL,
+ CLONE_FS | CLONE_FILES);
+ if ( err < 0 )
+ printk(KERN_ALERT "Error creating shutdown "
+ "process!\n");
+ } else {
+ kthread_create_on_cpu(__do_suspend, NULL, "suspender", 0);
+ }
}
static void shutdown_handler(struct xenbus_watch *watch, const char *node)
{
- static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
- char *str;
- int err;
+ static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
+ char *str;
+ int err;
again:
- err = xenbus_transaction_start();
- if (err)
- return;
- str = (char *)xenbus_read("control", "shutdown", NULL);
- /* Ignore read errors and empty reads. */
- if (XENBUS_IS_ERR_READ(str)) {
- xenbus_transaction_end(1);
- return;
- }
-
- xenbus_write("control", "shutdown", "");
-
- err = xenbus_transaction_end(0);
- if (err == -EAGAIN) {
+ err = xenbus_transaction_start();
+ if (err)
+ return;
+ str = (char *)xenbus_read("control", "shutdown", NULL);
+ /* Ignore read errors and empty reads. */
+ if (XENBUS_IS_ERR_READ(str)) {
+ xenbus_transaction_end(1);
+ return;
+ }
+
+ xenbus_write("control", "shutdown", "");
+
+ err = xenbus_transaction_end(0);
+ if (err == -EAGAIN) {
+ kfree(str);
+ goto again;
+ }
+
+ if (strcmp(str, "poweroff") == 0)
+ shutting_down = SHUTDOWN_POWEROFF;
+ else if (strcmp(str, "reboot") == 0)
+ shutting_down = SHUTDOWN_REBOOT;
+ else if (strcmp(str, "suspend") == 0)
+ shutting_down = SHUTDOWN_SUSPEND;
+ else {
+ printk("Ignoring shutdown request: %s\n", str);
+ shutting_down = SHUTDOWN_INVALID;
+ }
+
kfree(str);
- goto again;
- }
-
- if (strcmp(str, "poweroff") == 0)
- shutting_down = SHUTDOWN_POWEROFF;
- else if (strcmp(str, "reboot") == 0)
- shutting_down = SHUTDOWN_REBOOT;
- else if (strcmp(str, "suspend") == 0)
- shutting_down = SHUTDOWN_SUSPEND;
- else {
- printk("Ignoring shutdown request: %s\n", str);
- shutting_down = SHUTDOWN_INVALID;
- }
-
- kfree(str);
-
- if (shutting_down != SHUTDOWN_INVALID)
- schedule_work(&shutdown_work);
+
+ if (shutting_down != SHUTDOWN_INVALID)
+ schedule_work(&shutdown_work);
}
#ifdef CONFIG_MAGIC_SYSRQ
static void sysrq_handler(struct xenbus_watch *watch, const char *node)
{
- char sysrq_key = '\0';
- int err;
+ char sysrq_key = '\0';
+ int err;
again:
- err = xenbus_transaction_start();
- if (err)
- return;
- if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
- printk(KERN_ERR "Unable to read sysrq code in control/sysrq\n");
- xenbus_transaction_end(1);
- return;
- }
-
- if (sysrq_key != '\0')
- xenbus_printf("control", "sysrq", "%c", '\0');
-
- err = xenbus_transaction_end(0);
- if (err == -EAGAIN)
- goto again;
-
- if (sysrq_key != '\0') {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- handle_sysrq(sysrq_key, NULL, NULL);
-#else
- handle_sysrq(sysrq_key, NULL, NULL, NULL);
-#endif
- }
+ err = xenbus_transaction_start();
+ if (err)
+ return;
+ if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) {
+ printk(KERN_ERR "Unable to read sysrq code in "
+ "control/sysrq\n");
+ xenbus_transaction_end(1);
+ return;
+ }
+
+ if (sysrq_key != '\0')
+ xenbus_printf("control", "sysrq", "%c", '\0');
+
+ err = xenbus_transaction_end(0);
+ if (err == -EAGAIN)
+ goto again;
+
+ if (sysrq_key != '\0') {
+ handle_sysrq(sysrq_key, NULL, NULL);
+ }
}
#endif
static struct xenbus_watch shutdown_watch = {
- .node = "control/shutdown",
- .callback = shutdown_handler
+ .node = "control/shutdown",
+ .callback = shutdown_handler
};
#ifdef CONFIG_MAGIC_SYSRQ
static struct xenbus_watch sysrq_watch = {
- .node ="control/sysrq",
- .callback = sysrq_handler
+ .node ="control/sysrq",
+ .callback = sysrq_handler
};
#endif
@@ -413,39 +373,50 @@
unsigned long event,
void *data)
{
- int err1 = 0;
+ int err1 = 0;
#ifdef CONFIG_MAGIC_SYSRQ
- int err2 = 0;
-#endif
-
- BUG_ON(down_trylock(&xenbus_lock) == 0);
-
- err1 = register_xenbus_watch(&shutdown_watch);
+ int err2 = 0;
+#endif
+
+ BUG_ON(down_trylock(&xenbus_lock) == 0);
+
+ err1 = register_xenbus_watch(&shutdown_watch);
#ifdef CONFIG_MAGIC_SYSRQ
- err2 = register_xenbus_watch(&sysrq_watch);
-#endif
-
- if (err1) {
- printk(KERN_ERR "Failed to set shutdown watcher\n");
- }
+ err2 = register_xenbus_watch(&sysrq_watch);
+#endif
+
+ if (err1) {
+ printk(KERN_ERR "Failed to set shutdown watcher\n");
+ }
#ifdef CONFIG_MAGIC_SYSRQ
- if (err2) {
- printk(KERN_ERR "Failed to set sysrq watcher\n");
- }
-#endif
-
- return NOTIFY_DONE;
+ if (err2) {
+ printk(KERN_ERR "Failed to set sysrq watcher\n");
+ }
+#endif
+
+ return NOTIFY_DONE;
}
static int __init setup_shutdown_event(void)
{
- xenstore_notifier.notifier_call = setup_shutdown_watcher;
-
- register_xenstore_notifier(&xenstore_notifier);
+ xenstore_notifier.notifier_call = setup_shutdown_watcher;
+
+ register_xenstore_notifier(&xenstore_notifier);
- return 0;
+ return 0;
}
subsys_initcall(setup_shutdown_event);
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
+#
diff -r 93e27f7ca8a8 -r 61b3b357d827 linux-2.6-xen-sparse/arch/xen/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/smp.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/smp.c Thu Sep 29 23:28:44 2005
@@ -11,6 +11,15 @@
int setup_profiling_timer(unsigned int multiplier)
{
printk("setup_profiling_timer\n");
-
return 0;
}
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/xen_proc.c Thu Sep 29 23:28:44 2005
@@ -6,13 +6,23 @@
struct proc_dir_entry *create_xen_proc_entry(const char *name, mode_t mode)
{
- if ( xen_base == NULL )
- if ( (xen_base = proc_mkdir("xen", &proc_root)) == NULL )
- panic("Couldn't create /proc/xen");
- return create_proc_entry(name, mode, xen_base);
+ if ( xen_base == NULL )
+ if ( (xen_base = proc_mkdir("xen", &proc_root)) == NULL )
+ panic("Couldn't create /proc/xen");
+ return create_proc_entry(name, mode, xen_base);
}
void remove_xen_proc_entry(const char *name)
{
- remove_proc_entry(name, xen_base);
+ remove_proc_entry(name, xen_base);
}
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S Thu Sep 29
23:28:44 2005
@@ -536,7 +536,7 @@
CFI_ENDPROC
.endm
-#ifdef CONFIG_SMP
+#if 0
ENTRY(reschedule_interrupt)
apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Thu Sep 29
23:28:44 2005
@@ -31,14 +31,9 @@
static inline void __send_IPI_one(unsigned int cpu, int vector)
{
- unsigned int evtchn;
- Dprintk("%s\n", __FUNCTION__);
-
- evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
- if (evtchn)
- notify_via_evtchn(evtchn);
- else
- printk("send_IPI to unbound port %d/%d", cpu, vector);
+ int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+ BUG_ON(evtchn < 0);
+ notify_remote_via_evtchn(evtchn);
}
void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int
dest)
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Thu Sep 29
23:28:44 2005
@@ -771,11 +771,14 @@
virt_to_mfn(&phys_to_machine_mapping[i]);
}
HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-
-
-
-
-
+ }
+
+ if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
+ {
+ acpi_disabled = 1;
+#ifdef CONFIG_ACPI_BOOT
+ acpi_ht = 0;
+#endif
}
#endif
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Thu Sep 29
23:28:44 2005
@@ -445,25 +445,6 @@
}
#ifdef CONFIG_XEN
-static irqreturn_t ldebug_interrupt(
- int irq, void *dev_id, struct pt_regs *regs)
-{
- return IRQ_HANDLED;
-}
-
-static DEFINE_PER_CPU(int, ldebug_irq);
-static char ldebug_name[NR_CPUS][15];
-
-void ldebug_setup(void)
-{
- int cpu = smp_processor_id();
-
- per_cpu(ldebug_irq, cpu) = bind_virq_to_irq(VIRQ_DEBUG);
- sprintf(ldebug_name[cpu], "ldebug%d", cpu);
- BUG_ON(request_irq(per_cpu(ldebug_irq, cpu), ldebug_interrupt,
- SA_INTERRUPT, ldebug_name[cpu], NULL));
-}
-
extern void local_setup_timer(void);
#endif
@@ -498,7 +479,6 @@
enable_APIC_timer();
#else
local_setup_timer();
- ldebug_setup();
smp_intr_init();
local_irq_enable();
#endif
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Thu Sep 29 23:28:44 2005
@@ -149,7 +149,9 @@
pmd_t *pmd;
pte_t *pte;
+ preempt_disable();
pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
+ preempt_enable();
pgd += pgd_index(address);
printk("PGD %lx ", pgd_val(*pgd));
@@ -252,7 +254,9 @@
/* On Xen the line below does not always work. Needs investigating! */
/*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
+ preempt_disable();
pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
+ preempt_enable();
pgd += pgd_index(address);
pgd_ref = pgd_offset_k(address);
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Sep 29
23:28:44 2005
@@ -481,7 +481,7 @@
spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
/* Kick the relevant domain. */
- notify_via_evtchn(blkif->evtchn);
+ notify_remote_via_irq(blkif->irq);
}
void blkif_deschedule(blkif_t *blkif)
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 29 23:28:44 2005
@@ -44,7 +44,7 @@
unsigned int handle;
/* Physical parameters of the comms window. */
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* Comms information. */
blkif_back_ring_t blk_ring;
struct vm_struct *blk_ring_area;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Sep 29
23:28:44 2005
@@ -71,8 +71,6 @@
evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
int err;
- BUG_ON(blkif->remote_evtchn);
-
if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
return -ENOMEM;
@@ -94,13 +92,12 @@
}
blkif->evtchn = op.u.bind_interdomain.port1;
- blkif->remote_evtchn = evtchn;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
SHARED_RING_INIT(sring);
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
- bind_evtchn_to_irqhandler(
+ blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
blkif->status = CONNECTED;
@@ -109,20 +106,12 @@
static void free_blkif(void *arg)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
blkif_t *blkif = (blkif_t *)arg;
- op.u.close.port = blkif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = blkif->remote_evtchn;
- op.u.close.dom = blkif->domid;
- HYPERVISOR_event_channel_op(&op);
+ if (blkif->irq)
+ unbind_evtchn_from_irqhandler(blkif->irq, blkif);
vbd_free(&blkif->vbd);
-
- if (blkif->evtchn)
- unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Sep 29 23:28:44 2005
@@ -80,6 +80,15 @@
return;
}
+ /* Map the shared frame, irq etc. */
+ err = blkif_map(be->blkif, ring_ref, evtchn);
+ if (err) {
+ xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
+ ring_ref, evtchn);
+ return;
+ }
+ /* XXX From here on should 'blkif_unmap' on error. */
+
again:
/* Supply the information about the device the frontend needs */
err = xenbus_transaction_start();
@@ -109,14 +118,6 @@
if (err) {
xenbus_dev_error(be->dev, err, "writing %s/sector-size",
be->dev->nodename);
- goto abort;
- }
-
- /* Map the shared frame, irq etc. */
- err = blkif_map(be->blkif, ring_ref, evtchn);
- if (err) {
- xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
- ring_ref, evtchn);
goto abort;
}
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Sep 29
23:28:44 2005
@@ -57,10 +57,7 @@
#define MAXIMUM_OUTSTANDING_BLOCK_REQS \
(BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
-#define GRANTREF_INVALID (1<<15)
-#define GRANT_INVALID_REF (0xFFFF)
-
-static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */
+#define GRANT_INVALID_REF 0
static void kick_pending_request_queues(struct blkfront_info *info);
@@ -84,22 +81,10 @@
info->shadow_free = id;
}
-static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r)
-{
-
- s->req = *r;
-}
-
-static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s)
-{
-
- *r = s->req;
-}
-
static inline void flush_requests(struct blkfront_info *info)
{
RING_PUSH_REQUESTS(&info->ring);
- notify_via_evtchn(info->evtchn);
+ notify_remote_via_irq(info->irq);
}
static void kick_pending_request_queues(struct blkfront_info *info)
@@ -235,7 +220,7 @@
rq_data_dir(req) );
info->shadow[id].frame[ring_req->nr_segments] =
- buffer_mfn;
+ mfn_to_pfn(buffer_mfn);
ring_req->frame_and_sects[ring_req->nr_segments] =
blkif_fas_from_gref(ref, fsect, lsect);
@@ -247,7 +232,7 @@
info->ring.req_prod_pvt++;
/* Keep a private copy so we can reissue requests when recovering. */
- pickle_request(&info->shadow[id], ring_req);
+ info->shadow[id].req = *ring_req;
gnttab_free_grant_references(gref_head);
@@ -312,7 +297,7 @@
spin_lock_irqsave(&blkif_io_lock, flags);
- if (unlikely(info->connected != BLKIF_STATE_CONNECTED || recovery)) {
+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
spin_unlock_irqrestore(&blkif_io_lock, flags);
return IRQ_HANDLED;
}
@@ -372,8 +357,9 @@
if (info->ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->ring_ref, 0);
info->ring_ref = GRANT_INVALID_REF;
- unbind_evtchn_from_irqhandler(info->evtchn, info);
- info->evtchn = 0;
+ if (info->irq)
+ unbind_evtchn_from_irqhandler(info->irq, info);
+ info->evtchn = info->irq = 0;
}
static void blkif_recover(struct blkfront_info *info)
@@ -401,36 +387,30 @@
if (copy[i].request == 0)
continue;
- /* Grab a request slot and unpickle shadow state into it. */
+ /* Grab a request slot and copy shadow state into it. */
req = RING_GET_REQUEST(
&info->ring, info->ring.req_prod_pvt);
- unpickle_request(req, ©[i]);
+ *req = copy[i].req;
/* We get a new request id, and must reset the shadow state. */
req->id = GET_ID_FROM_FREELIST(info);
memcpy(&info->shadow[req->id], ©[i], sizeof(copy[i]));
/* Rewrite any grant references invalidated by susp/resume. */
- for (j = 0; j < req->nr_segments; j++) {
- if ( req->frame_and_sects[j] & GRANTREF_INVALID )
- gnttab_grant_foreign_access_ref(
- blkif_gref_from_fas(
- req->frame_and_sects[j]),
- info->backend_id,
- info->shadow[req->id].frame[j],
- rq_data_dir(
- (struct request *)
- info->shadow[req->id].request));
- req->frame_and_sects[j] &= ~GRANTREF_INVALID;
- }
+ for (j = 0; j < req->nr_segments; j++)
+ gnttab_grant_foreign_access_ref(
+ blkif_gref_from_fas(req->frame_and_sects[j]),
+ info->backend_id,
+ pfn_to_mfn(info->shadow[req->id].frame[j]),
+ rq_data_dir(
+ (struct request *)
+ info->shadow[req->id].request));
info->shadow[req->id].req = *req;
info->ring.req_prod_pvt++;
}
kfree(copy);
-
- recovery = 0;
/* info->ring->req_prod will be set when we flush_requests().*/
wmb();
@@ -438,7 +418,7 @@
/* Kicks things back into life. */
flush_requests(info);
- /* Now safe to left other people use the interface. */
+ /* Now safe to let other people use the interface. */
info->connected = BLKIF_STATE_CONNECTED;
}
@@ -450,10 +430,12 @@
err = bind_evtchn_to_irqhandler(
info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
- if (err != 0) {
+ if (err <= 0) {
WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
return;
}
+
+ info->irq = err;
}
@@ -487,8 +469,8 @@
return;
}
+ info->connected = BLKIF_STATE_CONNECTED;
xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
- info->connected = BLKIF_STATE_CONNECTED;
blkif_state = BLKIF_STATE_CONNECTED;
@@ -591,17 +573,6 @@
goto abort_transaction;
}
- info->backend = backend;
- backend = NULL;
-
- info->watch.node = info->backend;
- info->watch.callback = watch_for_status;
- err = register_xenbus_watch(&info->watch);
- if (err) {
- message = "registering watch on backend";
- goto abort_transaction;
- }
-
err = xenbus_transaction_end(0);
if (err) {
if (err == -EAGAIN)
@@ -610,10 +581,17 @@
goto destroy_blkring;
}
- out:
- if (backend)
- kfree(backend);
- return err;
+ info->watch.node = backend;
+ info->watch.callback = watch_for_status;
+ err = register_xenbus_watch(&info->watch);
+ if (err) {
+ message = "registering watch on backend";
+ goto destroy_blkring;
+ }
+
+ info->backend = backend;
+
+ return 0;
abort_transaction:
xenbus_transaction_end(1);
@@ -621,7 +599,10 @@
xenbus_dev_error(dev, err, "%s", message);
destroy_blkring:
blkif_free(info);
- goto out;
+ out:
+ if (backend)
+ kfree(backend);
+ return err;
}
/* Setup supplies the backend dir, virtual device.
@@ -702,9 +683,6 @@
kfree(info->backend);
info->backend = NULL;
- recovery = 1;
- blkif_free(info);
-
return 0;
}
@@ -713,11 +691,12 @@
struct blkfront_info *info = dev->data;
int err;
- /* FIXME: Check geometry hasn't changed here... */
+ blkif_free(info);
+
err = talk_to_backend(dev, info);
- if (!err) {
+ if (!err)
blkif_recover(info);
- }
+
return err;
}
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Sep 29 23:28:44 2005
@@ -123,7 +123,7 @@
int backend_id;
int ring_ref;
blkif_front_ring_t ring;
- unsigned int evtchn;
+ unsigned int evtchn, irq;
struct xlbd_major_info *mi;
request_queue_t *rq;
struct work_struct work;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Thu Sep 29 23:28:44 2005
@@ -842,7 +842,7 @@
spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
/* Kick the relevant domain. */
- notify_via_evtchn(blkif->evtchn);
+ notify_remote_via_irq(blkif->irq);
}
static struct miscdevice blktap_miscdev = {
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Sep 29 23:28:44 2005
@@ -46,7 +46,7 @@
unsigned int handle;
/* Physical parameters of the comms window. */
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* Comms information. */
blkif_back_ring_t blk_ring;
struct vm_struct *blk_ring_area;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Thu Sep 29
23:28:44 2005
@@ -71,8 +71,6 @@
evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
int err;
- BUG_ON(blkif->remote_evtchn);
-
if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -93,35 +91,26 @@
return err;
}
-
blkif->evtchn = op.u.bind_interdomain.port1;
- blkif->remote_evtchn = evtchn;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
SHARED_RING_INIT(sring);
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
- bind_evtchn_to_irqhandler(
+ blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
- blkif->status = CONNECTED;
+
+ blkif->status = CONNECTED;
return 0;
}
static void free_blkif(void *arg)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
blkif_t *blkif = (blkif_t *)arg;
- op.u.close.port = blkif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = blkif->remote_evtchn;
- op.u.close.dom = blkif->domid;
- HYPERVISOR_event_channel_op(&op);
-
- if (blkif->evtchn)
- unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
+ if (blkif->irq)
+ unbind_evtchn_from_irqhandler(blkif->irq, blkif);
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Thu Sep 29
23:28:44 2005
@@ -21,7 +21,6 @@
#include <linux/err.h>
#include "xencons_ring.h"
-
struct ring_head
{
u32 cons;
@@ -29,6 +28,7 @@
char buf[0];
} __attribute__((packed));
+static int xencons_irq;
#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
@@ -46,7 +46,8 @@
/* don't block - write as much as possible and return */
-static int __xencons_ring_send(struct ring_head *ring, const char *data,
unsigned len)
+static int __xencons_ring_send(
+ struct ring_head *ring, const char *data, unsigned len)
{
int copied = 0;
@@ -63,13 +64,9 @@
int xencons_ring_send(const char *data, unsigned len)
{
- struct ring_head *out = outring();
- int sent = 0;
-
- sent = __xencons_ring_send(out, data, len);
- notify_via_evtchn(xen_start_info->console_evtchn);
+ int sent = __xencons_ring_send(outring(), data, len);
+ notify_remote_via_irq(xencons_irq);
return sent;
-
}
@@ -97,32 +94,28 @@
{
int err;
+ if (xencons_irq)
+ unbind_evtchn_from_irqhandler(xencons_irq, inring());
+ xencons_irq = 0;
+
if (!xen_start_info->console_evtchn)
return 0;
- err = bind_evtchn_to_irqhandler(xen_start_info->console_evtchn,
- handle_input, 0, "xencons", inring());
- if (err) {
+ err = bind_evtchn_to_irqhandler(
+ xen_start_info->console_evtchn,
+ handle_input, 0, "xencons", inring());
+ if (err <= 0) {
xprintk("XEN console request irq failed %i\n", err);
return err;
}
+ xencons_irq = err;
+
return 0;
-}
-
-void xencons_suspend(void)
-{
-
- if (!xen_start_info->console_evtchn)
- return;
-
- unbind_evtchn_from_irqhandler(xen_start_info->console_evtchn,
- inring());
}
void xencons_resume(void)
{
-
(void)xencons_ring_init();
}
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 29 23:28:44 2005
@@ -21,8 +21,6 @@
#include <asm-xen/xen-public/grant_table.h>
#include <asm-xen/gnttab.h>
#include <asm-xen/driver_util.h>
-
-#define GRANT_INVALID_REF (0xFFFF)
#if 0
#define ASSERT(_p) \
@@ -52,7 +50,7 @@
u16 rx_shmem_handle;
grant_ref_t rx_shmem_ref;
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* The shared rings and indexes. */
netif_tx_interface_t *tx;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Sep 29
23:28:44 2005
@@ -15,18 +15,17 @@
spin_lock_bh(&dev->xmit_lock);
netif->active = 1;
spin_unlock_bh(&dev->xmit_lock);
- (void)bind_evtchn_to_irqhandler(
- netif->evtchn, netif_be_int, 0, dev->name, netif);
+ enable_irq(netif->irq);
netif_schedule_work(netif);
}
static void __netif_down(netif_t *netif)
{
struct net_device *dev = netif->dev;
+ disable_irq(netif->irq);
spin_lock_bh(&dev->xmit_lock);
netif->active = 0;
spin_unlock_bh(&dev->xmit_lock);
- unbind_evtchn_from_irqhandler(netif->evtchn, netif);
netif_deschedule_work(netif);
}
@@ -203,7 +202,10 @@
}
netif->evtchn = op.u.bind_interdomain.port1;
- netif->remote_evtchn = evtchn;
+
+ netif->irq = bind_evtchn_to_irqhandler(
+ netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
+ disable_irq(netif->irq);
netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
netif->rx = (netif_rx_interface_t *)
@@ -224,21 +226,15 @@
static void free_netif_callback(void *arg)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
netif_t *netif = (netif_t *)arg;
/*
- * These can't be done in netif_disconnect() because at that point
+ * This can't be done in netif_disconnect() because at that point
* there may be outstanding requests in the network stack whose
* asynchronous responses must still be notified to the remote driver.
*/
-
- op.u.close.port = netif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = netif->remote_evtchn;
- op.u.close.dom = netif->domid;
- HYPERVISOR_event_channel_op(&op);
+ if (netif->irq)
+ unbind_evtchn_from_irqhandler(netif->irq, netif);
unregister_netdev(netif->dev);
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Sep 29
23:28:44 2005
@@ -42,7 +42,7 @@
static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
static gnttab_transfer_t grant_rx_op[MAX_PENDING_REQS];
-static unsigned char rx_notify[NR_EVENT_CHANNELS];
+static unsigned char rx_notify[NR_IRQS];
/* Don't currently gate addition of an interface to the tx scheduling list. */
#define tx_work_exists(_if) (1)
@@ -209,7 +209,7 @@
{
netif_t *netif = NULL;
s8 status;
- u16 size, id, evtchn;
+ u16 size, id, irq;
multicall_entry_t *mcl;
mmu_update_t *mmu;
gnttab_transfer_t *gop;
@@ -320,16 +320,16 @@
gop->status, netif->domid);
/* XXX SMH: should free 'old_mfn' here */
status = NETIF_RSP_ERROR;
- }
- evtchn = netif->evtchn;
+ }
+ irq = netif->irq;
id = netif->rx->ring[
MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
if (make_rx_response(netif, id, status,
(unsigned long)skb->data & ~PAGE_MASK,
size, skb->proto_csum_valid) &&
- (rx_notify[evtchn] == 0)) {
- rx_notify[evtchn] = 1;
- notify_list[notify_nr++] = evtchn;
+ (rx_notify[irq] == 0)) {
+ rx_notify[irq] = 1;
+ notify_list[notify_nr++] = irq;
}
netif_put(netif);
@@ -339,9 +339,9 @@
}
while (notify_nr != 0) {
- evtchn = notify_list[--notify_nr];
- rx_notify[evtchn] = 0;
- notify_via_evtchn(evtchn);
+ irq = notify_list[--notify_nr];
+ rx_notify[irq] = 0;
+ notify_remote_via_irq(irq);
}
/* More work to do? */
@@ -434,7 +434,6 @@
gop->host_addr = MMAP_VADDR(pending_idx);
gop->dev_bus_addr = 0;
gop->handle = grant_tx_ref[pending_idx];
- grant_tx_ref[pending_idx] = GRANT_INVALID_REF;
gop++;
}
BUG_ON(HYPERVISOR_grant_table_op(
@@ -718,7 +717,7 @@
mb(); /* Update producer before checking event threshold. */
if (i == netif->tx->event)
- notify_via_evtchn(netif->evtchn);
+ notify_remote_via_irq(netif->irq);
}
static int make_rx_response(netif_t *netif,
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Sep 29
23:28:44 2005
@@ -1,7 +1,7 @@
/******************************************************************************
* Virtual network driver for conversing with remote driver backends.
*
- * Copyright (c) 2002-2004, K A Fraser
+ * Copyright (c) 2002-2005, K A Fraser
*
* This file may be distributed separately from the Linux kernel, or
* incorporated into other software packages, subject to the following license:
@@ -57,7 +57,7 @@
#include <asm-xen/xen-public/grant_table.h>
#include <asm-xen/gnttab.h>
-#define GRANT_INVALID_REF (0xFFFF)
+#define GRANT_INVALID_REF 0
#ifndef __GFP_NOWARN
#define __GFP_NOWARN 0
@@ -127,7 +127,7 @@
spinlock_t rx_lock;
unsigned int handle;
- unsigned int evtchn;
+ unsigned int evtchn, irq;
/* What is the status of our connection to the remote backend? */
#define BEST_CLOSED 0
@@ -457,7 +457,7 @@
/* Only notify Xen if we really have to. */
mb();
if (np->tx->TX_TEST_IDX == i)
- notify_via_evtchn(np->evtchn);
+ notify_remote_via_irq(np->irq);
return 0;
@@ -700,6 +700,7 @@
struct net_private *np;
int i, requeue_idx;
netif_tx_request_t *tx;
+ struct sk_buff *skb;
np = netdev_priv(dev);
spin_lock_irq(&np->tx_lock);
@@ -711,7 +712,8 @@
np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
np->rx->event = np->tx->event = 1;
- /* Step 2: Rebuild the RX and TX ring contents.
+ /*
+ * Step 2: Rebuild the RX and TX ring contents.
* NB. We could just free the queued TX packets now but we hope
* that sending them out might do some good. We have to rebuild
* the RX ring because some of our pages are currently flipped out
@@ -722,56 +724,59 @@
* them.
*/
- /* Rebuild the TX buffer freelist and the TX ring itself.
+ /*
+ * Rebuild the TX buffer freelist and the TX ring itself.
* NB. This reorders packets. We could keep more private state
* to avoid this but maybe it doesn't matter so much given the
* interface has been down.
*/
for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) {
- if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) {
- struct sk_buff *skb = np->tx_skbs[i];
-
- tx = &np->tx->ring[requeue_idx++].req;
-
- tx->id = i;
- gnttab_grant_foreign_access_ref(
- np->grant_tx_ref[i], np->backend_id,
- virt_to_mfn(np->tx_skbs[i]->data),
- GNTMAP_readonly);
- tx->gref = np->grant_tx_ref[i];
- tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
- tx->size = skb->len;
-
- np->stats.tx_bytes += skb->len;
- np->stats.tx_packets++;
- }
+ if ((unsigned long)np->tx_skbs[i] < __PAGE_OFFSET)
+ continue;
+
+ skb = np->tx_skbs[i];
+
+ tx = &np->tx->ring[requeue_idx++].req;
+
+ tx->id = i;
+ gnttab_grant_foreign_access_ref(
+ np->grant_tx_ref[i], np->backend_id,
+ virt_to_mfn(np->tx_skbs[i]->data),
+ GNTMAP_readonly);
+ tx->gref = np->grant_tx_ref[i];
+ tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
+ tx->size = skb->len;
+ tx->csum_blank = (skb->ip_summed == CHECKSUM_HW);
+
+ np->stats.tx_bytes += skb->len;
+ np->stats.tx_packets++;
}
wmb();
np->tx->req_prod = requeue_idx;
/* Rebuild the RX buffer freelist and the RX ring itself. */
for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) {
- if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
- gnttab_grant_foreign_transfer_ref(
- np->grant_rx_ref[i], np->backend_id);
- np->rx->ring[requeue_idx].req.gref =
- np->grant_rx_ref[i];
- np->rx->ring[requeue_idx].req.id = i;
- requeue_idx++;
- }
- }
-
+ if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
+ continue;
+ gnttab_grant_foreign_transfer_ref(
+ np->grant_rx_ref[i], np->backend_id);
+ np->rx->ring[requeue_idx].req.gref =
+ np->grant_rx_ref[i];
+ np->rx->ring[requeue_idx].req.id = i;
+ requeue_idx++;
+ }
wmb();
np->rx->req_prod = requeue_idx;
- /* Step 3: All public and private state should now be sane. Get
+ /*
+ * Step 3: All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver
* domain a kick because we've probably just requeued some
* packets.
*/
np->backend_state = BEST_CONNECTED;
wmb();
- notify_via_evtchn(np->evtchn);
+ notify_remote_via_irq(np->irq);
network_tx_buf_gc(dev);
if (np->user_state == UST_OPEN)
@@ -798,7 +803,8 @@
#endif
}
-/* Move the vif into connected state.
+/*
+ * Move the vif into connected state.
* Sets the mac and event channel from the message.
* Binds the irq to the event channel.
*/
@@ -809,7 +815,7 @@
memcpy(dev->dev_addr, np->mac, ETH_ALEN);
np->evtchn = evtchn;
network_connect(dev);
- (void)bind_evtchn_to_irqhandler(
+ np->irq = bind_evtchn_to_irqhandler(
np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
(void)send_fake_arp(dev);
show_device(np);
@@ -1049,12 +1055,12 @@
gnttab_end_foreign_access(info->rx_ring_ref, 0);
info->rx_ring_ref = GRANT_INVALID_REF;
- unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
- info->evtchn = 0;
-}
-
-/* Stop network device and free tx/rx queues and irq.
- */
+ if (info->irq)
+ unbind_evtchn_from_irqhandler(info->irq, info->netdev);
+ info->evtchn = info->irq = 0;
+}
+
+/* Stop network device and free tx/rx queues and irq. */
static void shutdown_device(struct net_private *np)
{
/* Stop old i/f to prevent errors whilst we rebuild the state. */
@@ -1148,17 +1154,6 @@
goto abort_transaction;
}
- info->backend = backend;
- backend = NULL;
-
- info->watch.node = info->backend;
- info->watch.callback = watch_for_status;
- err = register_xenbus_watch(&info->watch);
- if (err) {
- message = "registering watch on backend";
- goto abort_transaction;
- }
-
err = xenbus_transaction_end(0);
if (err) {
if (err == -EAGAIN)
@@ -1167,12 +1162,19 @@
goto destroy_ring;
}
+ info->watch.node = backend;
+ info->watch.callback = watch_for_status;
+ err = register_xenbus_watch(&info->watch);
+ if (err) {
+ message = "registering watch on backend";
+ goto destroy_ring;
+ }
+
+ info->backend = backend;
+
netif_state = NETIF_STATE_CONNECTED;
- out:
- if (backend)
- kfree(backend);
- return err;
+ return 0;
abort_transaction:
xenbus_transaction_end(1);
@@ -1180,13 +1182,17 @@
xenbus_dev_error(dev, err, "%s", message);
destroy_ring:
shutdown_device(info);
- goto out;
-}
-
-/* Setup supplies the backend dir, virtual device.
-
- We place an event channel and shared frame entries.
- We watch backend to wait if it's ok. */
+ out:
+ if (backend)
+ kfree(backend);
+ return err;
+}
+
+/*
+ * Setup supplies the backend dir, virtual device.
+ * We place an event channel and shared frame entries.
+ * We watch backend to wait if it's ok.
+ */
static int netfront_probe(struct xenbus_device *dev,
const struct xenbus_device_id *id)
{
@@ -1241,24 +1247,17 @@
static int netfront_suspend(struct xenbus_device *dev)
{
struct netfront_info *info = dev->data;
-
unregister_xenbus_watch(&info->watch);
kfree(info->backend);
info->backend = NULL;
-
+ return 0;
+}
+
+static int netfront_resume(struct xenbus_device *dev)
+{
+ struct netfront_info *info = dev->data;
netif_free(info);
-
- return 0;
-}
-
-static int netfront_resume(struct xenbus_device *dev)
-{
- struct net_private *np = dev->data;
- int err;
-
- err = talk_to_backend(dev, np);
-
- return err;
+ return talk_to_backend(dev, info);
}
static struct xenbus_driver netfront = {
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 29 23:28:44 2005
@@ -35,7 +35,7 @@
/* Physical parameters of the comms window. */
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* The shared rings and indexes. */
tpmif_tx_interface_t *tx;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Sep 29
23:28:44 2005
@@ -120,8 +120,6 @@
evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
int err;
- BUG_ON(tpmif->remote_evtchn);
-
if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -143,12 +141,11 @@
}
tpmif->evtchn = op.u.bind_interdomain.port1;
- tpmif->remote_evtchn = evtchn;
tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
- bind_evtchn_to_irqhandler(tpmif->evtchn,
- tpmif_be_int, 0, "tpmif-backend", tpmif);
+ tpmif->irq = bind_evtchn_to_irqhandler(
+ tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
tpmif->status = CONNECTED;
tpmif->shmem_ref = shared_page;
tpmif->active = 1;
@@ -159,18 +156,10 @@
static void
__tpmif_disconnect_complete(void *arg)
{
- evtchn_op_t op = {.cmd = EVTCHNOP_close };
tpmif_t *tpmif = (tpmif_t *) arg;
- op.u.close.port = tpmif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = tpmif->remote_evtchn;
- op.u.close.dom = tpmif->domid;
- HYPERVISOR_event_channel_op(&op);
-
- if (tpmif->evtchn)
- unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
+ if (tpmif->irq)
+ unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
if (tpmif->tx) {
unmap_frontend_page(tpmif);
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Thu Sep 29
23:28:44 2005
@@ -308,7 +308,7 @@
rc = offset;
DPRINTK("Notifying frontend via event channel %d\n",
tpmif->evtchn);
- notify_via_evtchn(tpmif->evtchn);
+ notify_remote_via_irq(tpmif->irq);
return rc;
}
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Sep 29 23:28:44 2005
@@ -88,6 +88,26 @@
return;
}
+ err = tpmif_map(be->tpmif, ringref, evtchn);
+ if (err) {
+ xenbus_dev_error(be->dev, err,
+ "mapping shared-frame %lu port %u",
+ ringref, evtchn);
+ return;
+ }
+
+ err = tpmif_vtpm_open(be->tpmif,
+ be->frontend_id,
+ be->instance);
+ if (err) {
+ xenbus_dev_error(be->dev, err,
+ "queueing vtpm open packet");
+ /*
+ * Should close down this device and notify FE
+ * about closure.
+ */
+ return;
+ }
/*
* Tell the front-end that we are ready to go -
@@ -104,27 +124,6 @@
"ready", "%lu", ready);
if (err) {
xenbus_dev_error(be->dev, err, "writing 'ready'");
- goto abort;
- }
-
- err = tpmif_map(be->tpmif, ringref, evtchn);
- if (err) {
- xenbus_dev_error(be->dev, err,
- "mapping shared-frame %lu port %u",
- ringref, evtchn);
- goto abort;
- }
-
- err = tpmif_vtpm_open(be->tpmif,
- be->frontend_id,
- be->instance);
- if (err) {
- xenbus_dev_error(be->dev, err,
- "queueing vtpm open packet");
- /*
- * Should close down this device and notify FE
- * about closure.
- */
goto abort;
}
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Thu Sep 29
23:28:44 2005
@@ -292,8 +292,10 @@
free_page((unsigned long)tp->tx);
tp->tx = NULL;
}
- unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
- tp->evtchn = 0;
+
+ if (tpm->irq)
+ unbind_evtchn_from_irqhandler(tp->irq, NULL);
+ tp->evtchn = tpm->irq = 0;
}
@@ -352,17 +354,6 @@
goto abort_transaction;
}
- info->backend = backend;
- backend = NULL;
-
- info->watch.node = info->backend;
- info->watch.callback = watch_for_status;
- err = register_xenbus_watch(&info->watch);
- if (err) {
- message = "registering watch on backend";
- goto abort_transaction;
- }
-
err = xenbus_transaction_end(0);
if (err == -EAGAIN)
goto again;
@@ -371,10 +362,17 @@
goto destroy_tpmring;
}
-out:
- if (backend)
- kfree(backend);
- return err;
+ info->watch.node = backend;
+ info->watch.callback = watch_for_status;
+ err = register_xenbus_watch(&info->watch);
+ if (err) {
+ message = "registering watch on backend";
+ goto destroy_tpmring;
+ }
+
+ info->backend = backend;
+
+ return 0;
abort_transaction:
xenbus_transaction_end(1);
@@ -382,7 +380,10 @@
xenbus_dev_error(dev, err, "%s", message);
destroy_tpmring:
destroy_tpmring(info, &my_private);
- goto out;
+out:
+ if (backend)
+ kfree(backend);
+ return err;
}
@@ -502,10 +503,12 @@
err = bind_evtchn_to_irqhandler(
tp->evtchn,
tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
- if ( err != 0 ) {
+ if ( err <= 0 ) {
WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
return;
}
+
+ tp->irq = err;
}
static struct xenbus_device_id tpmfront_ids[] = {
@@ -679,7 +682,7 @@
DPRINTK("Notifying backend via event channel %d\n",
tp->evtchn);
- notify_via_evtchn(tp->evtchn);
+ notify_remote_via_irq(tp->irq);
spin_unlock_irq(&tp->tx_lock);
return offset;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Thu Sep 29
23:28:44 2005
@@ -5,7 +5,7 @@
struct tpm_private
{
tpmif_tx_interface_t *tx;
- unsigned int evtchn;
+ unsigned int evtchn, irq;
int connected;
spinlock_t tx_lock;
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Thu Sep 29
23:28:44 2005
@@ -43,6 +43,8 @@
u8 flags;
char buf[0];
} __attribute__((packed));
+
+static int xenbus_irq;
DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
@@ -145,7 +147,7 @@
data += avail;
len -= avail;
update_output_chunk(out, avail);
- notify_via_evtchn(xen_start_info->store_evtchn);
+ notify_remote_via_irq(xenbus_irq);
} while (len != 0);
return 0;
@@ -190,7 +192,7 @@
pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
/* If it was full, tell them we've taken some. */
if (was_full)
- notify_via_evtchn(xen_start_info->store_evtchn);
+ notify_remote_via_irq(xenbus_irq);
}
/* If we left something, wake watch thread to deal with it. */
@@ -205,31 +207,27 @@
{
int err;
+ if (xenbus_irq)
+ unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
+ xenbus_irq = 0;
+
if (!xen_start_info->store_evtchn)
return 0;
err = bind_evtchn_to_irqhandler(
xen_start_info->store_evtchn, wake_waiting,
0, "xenbus", &xb_waitq);
- if (err) {
+ if (err <= 0) {
printk(KERN_ERR "XENBUS request irq failed %i\n", err);
- unbind_evtchn_from_irq(xen_start_info->store_evtchn);
return err;
}
+ xenbus_irq = err;
+
/* FIXME zero out page -- domain builder should probably do this*/
memset(mfn_to_virt(xen_start_info->store_mfn), 0, PAGE_SIZE);
return 0;
-}
-
-void xb_suspend_comms(void)
-{
-
- if (!xen_start_info->store_evtchn)
- return;
-
- unbind_evtchn_from_irqhandler(xen_start_info->store_evtchn, &xb_waitq);
}
/*
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Thu Sep 29
23:28:44 2005
@@ -30,7 +30,6 @@
int xs_init(void);
int xb_init_comms(void);
-void xb_suspend_comms(void);
/* Low level routines. */
int xb_write(const void *data, unsigned len);
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Thu Sep 29
23:28:44 2005
@@ -607,7 +607,6 @@
down(&xenbus_lock);
bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
- xb_suspend_comms();
}
void xenbus_resume(void)
@@ -651,7 +650,6 @@
int err = 0;
/* Initialize xenstore comms unless already done. */
- printk("store_evtchn = %i\n", xen_start_info->store_evtchn);
err = xs_init();
if (err) {
printk("XENBUS: Error initializing xenstore comms:"
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
Thu Sep 29 23:28:44 2005
@@ -80,11 +80,9 @@
* the usable vector space is 0x20-0xff (224 vectors)
*/
-#define NR_IPIS 8
-
-#define RESCHEDULE_VECTOR 1
-#define INVALIDATE_TLB_VECTOR 2
-#define CALL_FUNCTION_VECTOR 3
+#define RESCHEDULE_VECTOR 0
+#define CALL_FUNCTION_VECTOR 1
+#define NR_IPIS 2
/*
* The maximum number of vectors supported by i386 processors
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
Thu Sep 29 23:28:44 2005
@@ -78,11 +78,9 @@
* the usable vector space is 0x20-0xff (224 vectors)
*/
-#define NR_IPIS 8
-
-#define RESCHEDULE_VECTOR 1
-#define INVALIDATE_TLB_VECTOR 2
-#define CALL_FUNCTION_VECTOR 3
+#define RESCHEDULE_VECTOR 0
+#define CALL_FUNCTION_VECTOR 1
+#define NR_IPIS 2
/*
* The maximum number of vectors supported by i386 processors
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/balloon.h
--- a/linux-2.6-xen-sparse/include/asm-xen/balloon.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/balloon.h Thu Sep 29 23:28:44 2005
@@ -58,3 +58,13 @@
#define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)
#endif /* __ASM_BALLOON_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/driver_util.h
--- a/linux-2.6-xen-sparse/include/asm-xen/driver_util.h Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/driver_util.h Thu Sep 29
23:28:44 2005
@@ -14,3 +14,13 @@
extern void unlock_vm_area(struct vm_struct *area);
#endif /* __ASM_XEN_DRIVER_UTIL_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Thu Sep 29 23:28:44 2005
@@ -4,7 +4,7 @@
* Communication via Xen event channels.
* Also definitions for the device that demuxes notifications to userspace.
*
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-2005, K A Fraser
*
* This file may be distributed separately from the Linux kernel, or
* incorporated into other software packages, subject to the following license:
@@ -51,24 +51,36 @@
extern int bind_ipi_to_irq(int ipi);
extern void unbind_ipi_from_irq(int ipi);
-/* Dynamically bind an event-channel port to Linux IRQ space. */
+/*
+ * Dynamically bind an event-channel port to Linux IRQ space.
+ * BIND: Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
+ */
extern int bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int evtchn);
+extern void unbind_evtchn_from_irq(unsigned int irq);
/*
* Dynamically bind an event-channel port to an IRQ-like callback handler.
* On some platforms this may not be implemented via the Linux IRQ subsystem.
- * You *cannot* trust the irq argument passed to the callback handler.
+ * The IRQ argument passed to the callback handler is the same as returned
+ * from the bind call. It may not correspond to a Linux IRQ number.
+ * BIND: Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
*/
extern int bind_evtchn_to_irqhandler(
- unsigned int evtchn,
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags,
- const char *devname,
- void *dev_id);
-extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
+ unsigned int evtchn,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id);
+extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
-extern void irq_suspend(void);
+/*
+ * Unlike notify_remote_via_evtchn(), this is safe to use across
+ * save/restore. Notifications on a broken connection are silently dropped.
+ */
+void notify_remote_via_irq(int irq);
+
extern void irq_resume(void);
/* Entry point for notifications into Linux subsystems. */
@@ -79,42 +91,42 @@
static inline void mask_evtchn(int port)
{
- shared_info_t *s = HYPERVISOR_shared_info;
- synch_set_bit(port, &s->evtchn_mask[0]);
+ shared_info_t *s = HYPERVISOR_shared_info;
+ synch_set_bit(port, &s->evtchn_mask[0]);
}
static inline void unmask_evtchn(int port)
{
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
+ shared_info_t *s = HYPERVISOR_shared_info;
+ vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
- synch_clear_bit(port, &s->evtchn_mask[0]);
+ synch_clear_bit(port, &s->evtchn_mask[0]);
- /*
- * The following is basically the equivalent of 'hw_resend_irq'. Just like
- * a real IO-APIC we 'lose the interrupt edge' if the channel is masked.
- */
- if ( synch_test_bit (port, &s->evtchn_pending[0]) &&
- !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel) )
- {
- vcpu_info->evtchn_upcall_pending = 1;
- if ( !vcpu_info->evtchn_upcall_mask )
- force_evtchn_callback();
- }
+ /*
+ * The following is basically the equivalent of 'hw_resend_irq'. Just
+ * like a real IO-APIC we 'lose the interrupt edge' if the channel is
+ * masked.
+ */
+ if (synch_test_bit (port, &s->evtchn_pending[0]) &&
+ !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel)) {
+ vcpu_info->evtchn_upcall_pending = 1;
+ if (!vcpu_info->evtchn_upcall_mask)
+ force_evtchn_callback();
+ }
}
static inline void clear_evtchn(int port)
{
- shared_info_t *s = HYPERVISOR_shared_info;
- synch_clear_bit(port, &s->evtchn_pending[0]);
+ shared_info_t *s = HYPERVISOR_shared_info;
+ synch_clear_bit(port, &s->evtchn_pending[0]);
}
-static inline int notify_via_evtchn(int port)
+static inline void notify_remote_via_evtchn(int port)
{
- evtchn_op_t op;
- op.cmd = EVTCHNOP_send;
- op.u.send.local_port = port;
- return HYPERVISOR_event_channel_op(&op);
+ evtchn_op_t op;
+ op.cmd = EVTCHNOP_send;
+ op.u.send.local_port = port;
+ (void)HYPERVISOR_event_channel_op(&op);
}
/*
@@ -133,3 +145,13 @@
#define EVTCHN_UNBIND _IO('E', 3)
#endif /* __ASM_EVTCHN_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/foreign_page.h
--- a/linux-2.6-xen-sparse/include/asm-xen/foreign_page.h Thu Sep 29
22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/foreign_page.h Thu Sep 29
23:28:44 2005
@@ -28,3 +28,13 @@
( (void (*) (struct page *)) (page)->mapping )
#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h Thu Sep 29 23:28:44 2005
@@ -6,7 +6,7 @@
* 2. Accessing others' memory reservations via grant references.
* (i.e., mechanisms for both sender and recipient of grant references)
*
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-2005, K A Fraser
* Copyright (c) 2005, Christopher Clark
*/
@@ -25,10 +25,10 @@
#endif
struct gnttab_free_callback {
- struct gnttab_free_callback *next;
- void (*fn)(void *);
- void *arg;
- u16 count;
+ struct gnttab_free_callback *next;
+ void (*fn)(void *);
+ void *arg;
+ u16 count;
};
int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
@@ -73,3 +73,13 @@
#endif
#endif /* __ASM_GNTTAB_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/xen_proc.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xen_proc.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xen_proc.h Thu Sep 29 23:28:44 2005
@@ -6,8 +6,18 @@
#include <linux/proc_fs.h>
extern struct proc_dir_entry *create_xen_proc_entry(
- const char *name, mode_t mode);
+ const char *name, mode_t mode);
extern void remove_xen_proc_entry(
- const char *name);
+ const char *name);
#endif /* __ASM_XEN_PROC_H__ */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Thu Sep 29 22:22:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Thu Sep 29 23:28:44 2005
@@ -139,3 +139,13 @@
#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
#endif /* _ASM_XEN_XENBUS_H */
+
+/*
+ * Local variables:
+ * c-file-style: "linux"
+ * indent-tabs-mode: t
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Thu Sep 29 22:22:02 2005
+++ b/tools/console/daemon/io.c Thu Sep 29 23:28:44 2005
@@ -399,7 +399,7 @@
while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
dom = lookup_domain(dominfo.domid);
- if (dominfo.dying || dominfo.crashed || dominfo.shutdown) {
+ if (dominfo.dying) {
if (dom)
shutdown_domain(dom);
} else {
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/debugger/gdb/README
--- a/tools/debugger/gdb/README Thu Sep 29 22:22:02 2005
+++ b/tools/debugger/gdb/README Thu Sep 29 23:28:44 2005
@@ -20,10 +20,18 @@
To debug a running guest:
1. Use 'xm list' to discover its domain id ($domid).
- 2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid'
- 3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU'
+ 2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid'.
+ 3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU'.
4. From within the gdb client session:
# directory /path/to/linux-2.6.xx-xenU [*]
# target remote 127.0.0.1:9999
# bt
# disass
+
+To debug a crashed guest:
+ 1. Add '(enable-dump yes)' to /etc/xen/xend-config.sxp before
+ starting xend.
+ 2. When the domain crashes, a core file is written to
+ '/var/xen/dump/<domain-name>.<domain-id>.core'.
+ 3. Run 'gdbserver-xen 127.0.0.1:9999 --file <core-file>'.
+ 4. Connect to the server as for a running guest.
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/gen.c
--- a/tools/firmware/vmxassist/gen.c Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/gen.c Thu Sep 29 23:28:44 2005
@@ -23,7 +23,7 @@
#include <vm86.h>
int
-main()
+main(void)
{
printf("/* MACHINE GENERATED; DO NOT EDIT */\n");
printf("#define VMX_ASSIST_CTX_GS_SEL 0x%x\n",
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/head.S
--- a/tools/firmware/vmxassist/head.S Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/head.S Thu Sep 29 23:28:44 2005
@@ -110,6 +110,10 @@
_start:
cli
+ /* save register parameters to C land */
+ movl %edx, booting_cpu
+ movl %ebx, booting_vector
+
/* clear bss */
cld
xorb %al, %al
@@ -128,7 +132,6 @@
/* go ... */
call main
jmp halt
-
/*
* Something bad happened, print invoking %eip and loop forever
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/setup.c Thu Sep 29 23:28:44 2005
@@ -29,6 +29,9 @@
#define min(a, b) ((a) > (b) ? (b) : (a))
+/* Which CPU are we booting, and what is the initial CS segment? */
+int booting_cpu, booting_vector;
+
unsigned long long gdt[] __attribute__ ((aligned(32))) = {
0x0000000000000000ULL, /* 0x00: reserved */
0x0000890000000000ULL, /* 0x08: 32-bit TSS */
@@ -201,12 +204,17 @@
initialize_real_mode = 0;
regs->eflags |= EFLAGS_VM | 0x02;
regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000;
- regs->cs = 0xF000; /* ROM BIOS POST entry point */
-#ifdef TEST
- regs->eip = 0xFFE0;
+ if (booting_cpu == 0) {
+ regs->cs = 0xF000; /* ROM BIOS POST entry point */
+#ifdef TEST
+ regs->eip = 0xFFE0;
#else
- regs->eip = 0xFFF0;
-#endif
+ regs->eip = 0xFFF0;
+#endif
+ } else {
+ regs->cs = booting_vector << 8; /* AP entry point */
+ regs->eip = 0;
+ }
regs->uesp = 0;
regs->uss = 0;
printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
@@ -215,8 +223,8 @@
mode = VM86_REAL; /* becomes previous mode */
set_mode(regs, VM86_REAL);
- /* this should get us into 16-bit mode */
- return;
+ /* this should get us into 16-bit mode */
+ return;
} else {
/* go from protected to real mode */
regs->eflags |= EFLAGS_VM;
@@ -334,7 +342,12 @@
{
unsigned long cr0;
- printf("Start BIOS ...\n");
+ if (booting_cpu == 0)
+ printf("Start BIOS ...\n");
+ else
+ printf("Start AP %d from %08x ...\n",
+ booting_cpu, booting_vector << 12);
+
initialize_real_mode = 1;
cr0 = get_cr0();
#ifndef TEST
@@ -345,20 +358,28 @@
}
int
-main()
-{
- banner();
+main(void)
+{
+ if (booting_cpu == 0)
+ banner();
+
#ifdef TEST
setup_paging();
#endif
+
setup_gdt();
setup_idt();
+
#ifndef TEST
- set_cr4(get_cr4() | CR4_VME);
-#endif
+ set_cr4(get_cr4() | CR4_VME);
+#endif
+
setup_ctx();
- setup_pic();
+
+ if (booting_cpu == 0)
+ setup_pic();
+
start_bios();
+
return 0;
}
-
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/vm86.c Thu Sep 29 23:28:44 2005
@@ -470,10 +470,21 @@
unsigned long long entry;
/* protected mode: use seg as index into gdt */
- if (sel == 0 || sel > oldctx.gdtr_limit)
+ if (sel > oldctx.gdtr_limit)
return 0;
+ if (sel == 0) {
+ arbytes->fields.null_bit = 1;
+ return 1;
+ }
+
entry = ((unsigned long long *) oldctx.gdtr_base)[sel >> 3];
+
+ /* Check the P bit fisrt*/
+ if (!((entry >> (15+32)) & 0x1) && sel != 0) {
+ return 0;
+ }
+
*base = (((entry >> (56-24)) & 0xFF000000) |
((entry >> (32-16)) & 0x00FF0000) |
((entry >> ( 16)) & 0x0000FFFF));
@@ -519,22 +530,42 @@
if (load_seg(regs->ves, &oldctx.es_base,
&oldctx.es_limit, &oldctx.es_arbytes))
oldctx.es_sel = regs->ves;
+ else {
+ load_seg(0, &oldctx.es_base,&oldctx.es_limit, &oldctx.es_arbytes);
+ oldctx.es_sel = 0;
+ }
if (load_seg(regs->uss, &oldctx.ss_base,
&oldctx.ss_limit, &oldctx.ss_arbytes))
oldctx.ss_sel = regs->uss;
+ else {
+ load_seg(0, &oldctx.ss_base, &oldctx.ss_limit, &oldctx.ss_arbytes);
+ oldctx.ss_sel = 0;
+ }
if (load_seg(regs->vds, &oldctx.ds_base,
&oldctx.ds_limit, &oldctx.ds_arbytes))
oldctx.ds_sel = regs->vds;
+ else {
+ load_seg(0, &oldctx.ds_base, &oldctx.ds_limit, &oldctx.ds_arbytes);
+ oldctx.ds_sel = 0;
+ }
if (load_seg(regs->vfs, &oldctx.fs_base,
&oldctx.fs_limit, &oldctx.fs_arbytes))
oldctx.fs_sel = regs->vfs;
+ else {
+ load_seg(0, &oldctx.fs_base, &oldctx.fs_limit, &oldctx.fs_arbytes);
+ oldctx.fs_sel = 0;
+ }
if (load_seg(regs->vgs, &oldctx.gs_base,
&oldctx.gs_limit, &oldctx.gs_arbytes))
oldctx.gs_sel = regs->vgs;
+ else {
+ load_seg(0, &oldctx.gs_base, &oldctx.gs_limit, &oldctx.gs_arbytes);
+ oldctx.gs_sel = 0;
+ }
/* initialize jump environment to warp back to protected mode */
regs->cs = CODE_SELECTOR;
@@ -752,6 +783,9 @@
goto invalid;
}
break;
+ case 0x09: /* wbinvd */
+ asm volatile ( "wbinvd" );
+ return OPC_EMULATED;
case 0x20: /* mov Rd, Cd (1h) */
case 0x22:
if (!movcr(regs, prefix, opc))
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/firmware/vmxassist/vmxloader.c
--- a/tools/firmware/vmxassist/vmxloader.c Thu Sep 29 22:22:02 2005
+++ b/tools/firmware/vmxassist/vmxloader.c Thu Sep 29 23:28:44 2005
@@ -132,11 +132,12 @@
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
}
#endif
-
+
puts("Loading VMXAssist ...\n");
memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
+
puts("Go ...\n");
- ((void (*)())TEXTADDR)();
+ asm volatile ( "jmp *%%eax" : : "a" (TEXTADDR), "d" (0) );
+
return 0;
}
-
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Thu Sep 29 22:22:02 2005
+++ b/tools/ioemu/vl.c Thu Sep 29 23:28:44 2005
@@ -2385,7 +2385,8 @@
setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long
*mem_page_array, unsigned long *page_table_array, unsigned long v_start,
unsigned long v_end)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
- l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
+ l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL};
+ l2_pgentry_t *vl2e=NULL, *vl2_table = NULL;
unsigned long l1tab;
unsigned long ppt_alloc = 0;
unsigned long count;
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/web/SrvBase.py
--- a/tools/python/xen/web/SrvBase.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/web/SrvBase.py Thu Sep 29 23:28:44 2005
@@ -81,7 +81,14 @@
req.write("Operation not implemented: " + op)
return ''
else:
- return op_method(op, req)
+ try:
+ return op_method(op, req)
+ except Exception, exn:
+ log.exception("Request %s failed.", op)
+ if req.useSxp():
+ return ['xend.err', "Exception: " + str(exn)]
+ else:
+ return "<p>%s</p>" % str(exn)
def print_path(self, req):
"""Print the path with hyperlinks.
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/web/http.py
--- a/tools/python/xen/web/http.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/web/http.py Thu Sep 29 23:28:44 2005
@@ -22,6 +22,7 @@
from mimetools import Message
from cStringIO import StringIO
import math
+import socket
import time
import cgi
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/PrettyPrint.py
--- a/tools/python/xen/xend/PrettyPrint.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/PrettyPrint.py Thu Sep 29 23:28:44 2005
@@ -39,9 +39,9 @@
print '***PrettyItem>output>', self
pass
- def prettyprint(self, _, width):
+ def prettyprint(self, _):
print '***PrettyItem>prettyprint>', self
- return width
+ return self.width
class PrettyString(PrettyItem):
@@ -52,7 +52,7 @@
def output(self, out):
out.write(self.value)
- def prettyprint(self, line, _):
+ def prettyprint(self, line):
line.output(self)
def show(self, out):
@@ -63,7 +63,7 @@
def output(self, out):
out.write(' ' * self.width)
- def prettyprint(self, line, _):
+ def prettyprint(self, line):
line.output(self)
def show(self, out):
@@ -80,7 +80,7 @@
def output(self, out):
out.write(' ' * self.width)
- def prettyprint(self, line, _):
+ def prettyprint(self, line):
if line.breaks(self.space):
self.active = 1
line.newline(self.indent)
@@ -97,7 +97,7 @@
block.newline()
block.addtoline(self)
- def prettyprint(self, line, _):
+ def prettyprint(self, line):
line.newline(0)
line.output(self)
@@ -127,7 +127,7 @@
lastbreak.space = (width - lastwidth)
self.width = width
- def prettyprint(self, line, _):
+ def prettyprint(self, line):
for x in self.content:
x.prettyprint(line)
@@ -168,7 +168,7 @@
def addtoline(self, x):
self.lines[-1].write(x)
- def prettyprint(self, line, _):
+ def prettyprint(self, line):
self.indent = line.used
line.block = self
if not line.fits(self.width):
@@ -252,7 +252,7 @@
self.block = self.block.parent
def prettyprint(self, out=sys.stdout):
- self.top.prettyprint(Line(out, self.width), self.width)
+ self.top.prettyprint(Line(out, self.width))
class SXPPrettyPrinter(PrettyPrinter):
"""An SXP prettyprinter.
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendCheckpoint.py Thu Sep 29 23:28:44 2005
@@ -10,8 +10,12 @@
import sxp
from string import join
from struct import pack, unpack, calcsize
+
from xen.util.xpopen import xPopen3
+
import xen.lowlevel.xc
+
+import XendDomainInfo
from xen.xend.xenstore.xsutil import IntroduceDomain
from XendError import XendError
@@ -74,7 +78,7 @@
if l.rstrip() == "suspend":
log.info("suspending %d" % dominfo.domid)
xd.domain_shutdown(dominfo.domid, reason='suspend')
- dominfo.state_wait("suspended")
+ dominfo.state_wait(XendDomainInfo.STATE_VM_SUSPENDED)
log.info("suspend %d done" % dominfo.domid)
child.tochild.write("done\n")
child.tochild.flush()
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendClient.py Thu Sep 29 23:28:44 2005
@@ -302,12 +302,6 @@
{'op' : 'devices',
'type' : type })
- def xend_domain_device(self, id, type, idx):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device',
- 'type' : type,
- 'idx' : idx })
-
def xend_domain_device_create(self, id, config):
return self.xendPost(self.domainurl(id),
{'op' : 'device_create',
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendDomain.py Thu Sep 29 23:28:44 2005
@@ -28,16 +28,11 @@
from xen.xend import sxp
from xen.xend import XendRoot
from xen.xend import XendCheckpoint
-from xen.xend.XendDomainInfo import XendDomainInfo, shutdown_reason
+from xen.xend.XendDomainInfo import XendDomainInfo
from xen.xend import EventServer
from xen.xend.XendError import XendError
from xen.xend.XendLogging import log
-from xen.xend import scheduler
from xen.xend.server import relocate
-from xen.xend.uuid import getUuid
-from xen.xend.xenstore import XenNode, DBMap
-from xen.xend.xenstore.xstransact import xstransact
-from xen.xend.xenstore.xsutil import GetDomainPath
xc = xen.lowlevel.xc.new()
@@ -47,14 +42,7 @@
__all__ = [ "XendDomain" ]
-SHUTDOWN_TIMEOUT = 30
-PRIV_DOMAIN = 0
-
-def is_dead(dom):
- return dom['crashed'] or dom['shutdown'] or (
- dom['dying'] and not(dom['running'] or dom['paused'] or
- dom['blocked']))
-
+PRIV_DOMAIN = 0
class XendDomainDict(dict):
def get_by_name(self, name):
@@ -77,11 +65,8 @@
# So we stuff the XendDomain instance (self) into xroot's components.
xroot.add_component("xen.xend.XendDomain", self)
self.domains = XendDomainDict()
- self.domroot = "/domain"
- self.vmroot = "/domain"
- self.dbmap = DBMap(db=XenNode(self.vmroot))
self.watchReleaseDomain()
- self.initial_refresh()
+ self.refresh()
self.dom0_setup()
def list(self):
@@ -110,9 +95,7 @@
return map(lambda x: x.getName(), doms)
def onReleaseDomain(self):
- self.reap()
self.refresh()
- self.domain_restarts()
def watchReleaseDomain(self):
from xen.xend.xenstore.xswatch import xswatch
@@ -141,43 +124,22 @@
dominfo = dominfo[0]
return dominfo
- def initial_refresh(self):
- """Refresh initial domain info from db.
- """
- doms = self.xen_domains()
- self.dbmap.readDB() # XXX only needed for "xend"
- for dom in doms.values():
- domid = dom['dom']
- dompath = GetDomainPath(domid)
- if not dompath:
- continue
- vmpath = xstransact.Read(dompath, "vm")
- if not vmpath:
- continue
- uuid = xstransact.Read(vmpath, "uuid")
- if not uuid:
- continue
- log.info("recreating domain %d, uuid %s" % (domid, uuid))
- dompath = "/".join(dompath.split("/")[0:-1])
- try:
- dominfo = XendDomainInfo.recreate(uuid, dompath, domid, dom)
- except Exception, ex:
- log.exception("Error recreating domain info: id=%d", domid)
- continue
- self._add_domain(dominfo)
- self.reap()
- self.refresh()
- self.domain_restarts()
+
+ def recreate_domain(self, xeninfo):
+ """Refresh initial domain info from db."""
+
+ dominfo = XendDomainInfo.recreate(xeninfo)
+ self._add_domain(dominfo)
+ return dominfo
+
def dom0_setup(self):
dom0 = self.domain_lookup(PRIV_DOMAIN)
if not dom0:
- dom0 = self.dom0_unknown()
- dom0.dom0_init_store()
+ dom0 = self.recreate_domain(self.xen_domain(PRIV_DOMAIN))
+ dom0.dom0_init_store()
dom0.dom0_enforce_vcpus()
- def close(self):
- pass
def _add_domain(self, info, notify=True):
"""Add a domain entry to the tables.
@@ -193,70 +155,45 @@
eserver.inject('xend.domain.create', [info.getName(),
info.getDomid()])
- def _delete_domain(self, id, notify=True):
+ def _delete_domain(self, domid, notify=True):
"""Remove a domain from the tables.
@param id: domain id
@param notify: send a domain died event if true
"""
- info = self.domains.get(id)
+ info = self.domains.get(domid)
if info:
- del self.domains[id]
+ del self.domains[domid]
info.cleanup()
info.delete()
if notify:
eserver.inject('xend.domain.died', [info.getName(),
info.getDomid()])
- # XXX this should not be needed
- for domdb in self.dbmap.values():
- if not domdb.has_key("xend"):
- continue
- db = domdb.addChild("xend")
- try:
- domid = int(domdb["domid"].getData())
- except:
- domid = None
- if (domid is None) or (domid == id):
- domdb.delete()
-
- def reap(self):
- """Look for domains that have crashed or stopped.
- Tidy them up.
- """
- doms = self.xen_domains()
- for d in doms.values():
- if not is_dead(d):
- continue
- domid = d['dom']
- dominfo = self.domains.get(domid)
- if not dominfo or dominfo.is_terminated():
- continue
- log.debug('domain died name=%s domid=%d', dominfo.getName(), domid)
- if d['crashed'] and xroot.get_enable_dump():
- self.domain_dumpcore(domid)
- if d['shutdown']:
- reason = shutdown_reason(d['shutdown_reason'])
- log.debug('shutdown name=%s id=%d reason=%s',
- dominfo.getName(), domid, reason)
- if reason == 'suspend':
- dominfo.state_set("suspended")
- continue
- if reason in ['poweroff', 'reboot']:
- self.domain_restart_schedule(domid, reason)
- dominfo.destroy()
+
def refresh(self):
"""Refresh domain list from Xen.
"""
doms = self.xen_domains()
- # Remove entries for domains that no longer exist.
- # Update entries for existing domains.
for d in self.domains.values():
info = doms.get(d.getDomid())
if info:
d.update(info)
- elif not d.restart_pending():
+ else:
self._delete_domain(d.getDomid())
+ for d in doms:
+ if d not in self.domains:
+ try:
+ self.recreate_domain(doms[d])
+ except:
+ log.exception(
+ "Failed to recreate information for domain %d. "
+ "Destroying it in the hope of recovery.", d)
+ try:
+ xc.domain_destroy(dom = d)
+ except:
+ log.exception('Destruction of %d failed.', d)
+
def update_domain(self, id):
"""Update information for a single domain.
@@ -277,32 +214,8 @@
@param config: configuration
@return: domain
"""
- dominfo = XendDomainInfo.create(self.dbmap.getPath(), config)
+ dominfo = XendDomainInfo.create(config)
self._add_domain(dominfo)
- return dominfo
-
- def domain_restart(self, dominfo):
- """Restart a domain.
-
- @param dominfo: domain object
- """
- log.info("Restarting domain: name=%s id=%s", dominfo.getName(),
- dominfo.getDomid())
- eserver.inject("xend.domain.restart",
- [dominfo.getName(), dominfo.getDomid(), "begin"])
- try:
- dominfo.restart()
- log.info('Restarted domain name=%s id=%s', dominfo.getName(),
- dominfo.getDomid())
- eserver.inject("xend.domain.restart",
- [dominfo.getName(), dominfo.getDomid(),
- "success"])
- self.domain_unpause(dominfo.getDomid())
- except Exception, ex:
- log.exception("Exception restarting domain: name=%s id=%s",
- dominfo.getName(), dominfo.getDomid())
- eserver.inject("xend.domain.restart",
- [dominfo.getName(), dominfo.getDomid(), "fail"])
return dominfo
def domain_configure(self, config):
@@ -318,13 +231,12 @@
nested = sxp.child_value(config, 'config')
if nested:
config = nested
- return XendDomainInfo.restore(self.dbmap.getPath(), config)
-
- def domain_restore(self, src, progress=False):
+ return XendDomainInfo.restore(config)
+
+ def domain_restore(self, src):
"""Restore a domain from file.
@param src: source file
- @param progress: output progress if true
"""
try:
@@ -345,33 +257,7 @@
self.update_domain(id)
return self.domains.get(id)
- def dom0_unknown(self):
- dom0 = PRIV_DOMAIN
- uuid = None
- info = self.xen_domain(dom0)
- dompath = GetDomainPath(dom0)
- if dompath:
- vmpath = xstransact.Read(dompath, "vm")
- if vmpath:
- uuid = xstransact.Read(vmpath, "uuid")
- if not uuid:
- uuid = dompath.split("/")[-1]
- dompath = "/".join(dompath.split("/")[0:-1])
- if not uuid:
- uuid = getUuid()
- dompath = self.domroot
- log.info("Creating entry for unknown xend domain: id=%d uuid=%s",
- dom0, uuid)
- try:
- dominfo = XendDomainInfo.recreate(uuid, dompath, dom0, info)
- self._add_domain(dominfo)
- return dominfo
- except Exception, exn:
- log.exception(exn)
- raise XendError("Error recreating xend domain info: id=%d: %s" %
- (dom0, str(exn)))
-
-
+
def domain_lookup(self, id):
return self.domains.get(id)
@@ -410,8 +296,9 @@
return xc.domain_pause(dom=dominfo.getDomid())
except Exception, ex:
raise XendError(str(ex))
-
- def domain_shutdown(self, id, reason='poweroff'):
+
+
+ def domain_shutdown(self, domid, reason='poweroff'):
"""Shutdown domain (nicely).
- poweroff: restart according to exit code and restart mode
- reboot: restart on exit
@@ -422,89 +309,13 @@
@param id: domain id
@param reason: shutdown type: poweroff, reboot, suspend, halt
"""
- dominfo = self.domain_lookup(id)
- self.domain_restart_schedule(dominfo.getDomid(), reason, force=True)
- eserver.inject('xend.domain.shutdown', [dominfo.getName(),
- dominfo.getDomid(), reason])
- if reason == 'halt':
- reason = 'poweroff'
- val = dominfo.shutdown(reason)
- if not reason in ['suspend']:
- self.domain_shutdowns()
- return val
-
-
- def domain_sysrq(self, id, key):
+ self.callInfo(domid, XendDomainInfo.shutdown, reason)
+
+
+ def domain_sysrq(self, domid, key):
"""Send a SysRq to the specified domain."""
- return self.callInfo(id, XendDomainInfo.send_sysrq, key)
-
-
- def domain_shutdowns(self):
- """Process pending domain shutdowns.
- Destroys domains whose shutdowns have timed out.
- """
- timeout = SHUTDOWN_TIMEOUT + 1
- for dominfo in self.domains.values():
- if not dominfo.shutdown_pending:
- # domain doesn't need shutdown
- continue
- id = dominfo.getDomid()
- left = dominfo.shutdown_time_left(SHUTDOWN_TIMEOUT)
- if left <= 0:
- # Shutdown expired - destroy domain.
- try:
- log.info("Domain shutdown timeout expired: name=%s id=%s",
- dominfo.getName(), id)
- self.domain_destroy(id, reason=
- dominfo.shutdown_pending['reason'])
- except Exception:
- pass
- else:
- # Shutdown still pending.
- timeout = min(timeout, left)
- if timeout <= SHUTDOWN_TIMEOUT:
- # Pending shutdowns remain - reschedule.
- scheduler.later(timeout, self.domain_shutdowns)
-
- def domain_restart_schedule(self, id, reason, force=False):
- """Schedule a restart for a domain if it needs one.
-
- @param id: domain id
- @param reason: shutdown reason
- """
- log.debug('domain_restart_schedule> %d %s %d', id, reason, force)
- dominfo = self.domain_lookup(id)
- if not dominfo:
- return
- restart = (force and reason == 'reboot') or
dominfo.restart_needed(reason)
- if restart:
- log.info('Scheduling restart for domain: name=%s id=%s',
- dominfo.getName(), dominfo.getDomid())
- eserver.inject("xend.domain.restart",
- [dominfo.getName(), dominfo.getDomid(),
- "schedule"])
- dominfo.restarting()
- else:
- log.info('Cancelling restart for domain: name=%s id=%s',
- dominfo.getName(), dominfo.getDomid())
- eserver.inject("xend.domain.restart",
- [dominfo.getName(), dominfo.getDomid(), "cancel"])
- dominfo.restart_cancel()
-
- def domain_restarts(self):
- """Execute any scheduled domain restarts for domains that have gone.
- """
- doms = self.xen_domains()
- for dominfo in self.domains.values():
- if not dominfo.restart_pending():
- continue
- info = doms.get(dominfo.getDomid())
- if info:
- # Don't execute restart for domains still running.
- continue
- # Remove it from the restarts.
- log.info('restarting: %s' % dominfo.getName())
- self.domain_restart(dominfo)
+ return self.callInfo(domid, XendDomainInfo.send_sysrq, key)
+
def domain_destroy(self, domid, reason='halt'):
"""Terminate domain immediately.
@@ -517,7 +328,6 @@
if domid == PRIV_DOMAIN:
raise XendError("Cannot destroy privileged domain %i" % domid)
- self.domain_restart_schedule(domid, reason, force=True)
dominfo = self.domain_lookup(domid)
if dominfo:
val = dominfo.destroy()
@@ -554,12 +364,11 @@
return None
- def domain_save(self, id, dst, progress=False):
+ def domain_save(self, id, dst):
"""Start saving a domain to file.
@param id: domain id
@param dst: destination file
- @param progress: output progress if true
"""
try:
@@ -659,14 +468,6 @@
def domain_devtype_ls(self, domid, devtype):
"""Get list of device sxprs for the specified domain."""
return self.callInfo(domid, XendDomainInfo.getDeviceSxprs, devtype)
-
-
- def domain_devtype_get(self, domid, devtype, devid):
- """Get a device from a domain.
-
- @return: device object (or None)
- """
- return self.callInfo(domid, XendDomainInfo.getDevice, devtype, devid)
def domain_vif_limit_set(self, id, vif, credit, period):
@@ -730,10 +531,16 @@
## private:
def callInfo(self, domid, fn, *args, **kwargs):
- self.refresh()
- dominfo = self.domains.get(domid)
- if dominfo:
- return fn(dominfo, *args, **kwargs)
+ try:
+ self.refresh()
+ dominfo = self.domains.get(domid)
+ if dominfo:
+ return fn(dominfo, *args, **kwargs)
+ except XendError:
+ raise
+ except Exception, exn:
+ log.exception("")
+ raise XendError(str(exn))
def instance():
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Thu Sep 29 23:28:44 2005
@@ -35,7 +35,9 @@
from xen.xend.server.channel import EventChannel
from xen.xend import image
+from xen.xend import scheduler
from xen.xend import sxp
+from xen.xend import XendRoot
from xen.xend.XendBootloader import bootloader
from xen.xend.XendLogging import log
from xen.xend.XendError import XendError, VmError
@@ -43,7 +45,7 @@
from xen.xend.uuid import getUuid
from xen.xend.xenstore.xstransact import xstransact
-from xen.xend.xenstore.xsutil import IntroduceDomain
+from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
"""Shutdown code for poweroff."""
DOMAIN_POWEROFF = 0
@@ -75,9 +77,6 @@
RESTART_NEVER,
]
-STATE_RESTART_PENDING = 'pending'
-STATE_RESTART_BOOTING = 'booting'
-
STATE_VM_OK = "ok"
STATE_VM_TERMINATED = "terminated"
STATE_VM_SUSPENDED = "suspended"
@@ -92,7 +91,29 @@
SIF_TPM_BE_DOMAIN = (1<<7)
+SHUTDOWN_TIMEOUT = 30
+
+
+DOMROOT = '/domain'
+VMROOT = '/domain'
+
+
xc = xen.lowlevel.xc.new()
+xroot = XendRoot.instance()
+
+
+## Configuration entries that we expect to round-trip -- be read from the
+# config file or xc, written to save-files (i.e. through sxpr), and reused as
+# config on restart or restore, all without munging. Some configuration
+# entries are munged for backwards compatibility reasons, or because they
+# don't come out of xc in the same form as they are specified in the config
+# file, so those are handled separately.
+ROUNDTRIPPING_CONFIG_ENTRIES = [
+ ('name', str),
+ ('ssidref', int),
+ ('cpu_weight', float),
+ ('bootloader', str)
+ ]
def domain_exists(name):
@@ -133,47 +154,64 @@
MINIMUM_RESTART_TIME = 20
- def create(cls, dompath, config):
+ def create(cls, config):
"""Create a VM from a configuration.
- @param dompath: The path to all domain information
@param config configuration
@raise: VmError for invalid configuration
"""
- log.debug("XendDomainInfo.create(%s, ...)", dompath)
+ log.debug("XendDomainInfo.create(...)")
- vm = cls(getUuid(), dompath, cls.parseConfig(config))
+ vm = cls(getUuid(), cls.parseConfig(config))
vm.construct()
+ vm.refreshShutdown()
return vm
create = classmethod(create)
- def recreate(cls, uuid, dompath, domid, info):
- """Create the VM object for an existing domain.
-
- @param dompath: The path to all domain information
- @param info: domain info from xc
- """
-
- log.debug("XendDomainInfo.recreate(%s, %s, %s, %s)", uuid, dompath,
- domid, info)
-
- return cls(uuid, dompath, info, domid, True)
+ def recreate(cls, xeninfo):
+ """Create the VM object for an existing domain."""
+
+ log.debug("XendDomainInfo.recreate(%s)", xeninfo)
+
+ domid = xeninfo['dom']
+ try:
+ dompath = GetDomainPath(domid)
+ if not dompath:
+ raise XendError(
+ 'No domain path in store for existing domain %d' % domid)
+ vmpath = xstransact.Read(dompath, "vm")
+ if not vmpath:
+ raise XendError(
+ 'No vm path in store for existing domain %d' % domid)
+ uuid = xstransact.Read(vmpath, "uuid")
+ if not uuid:
+ raise XendError(
+ 'No vm/uuid path in store for existing domain %d' % domid)
+
+ except Exception, exn:
+ log.warn(str(exn))
+ uuid = getUuid()
+
+ log.info("Recreating domain %d, uuid %s", domid, uuid)
+
+ vm = cls(uuid, xeninfo, domid, True)
+ vm.refreshShutdown(xeninfo)
+ return vm
recreate = classmethod(recreate)
- def restore(cls, dompath, config, uuid = None):
+ def restore(cls, config, uuid = None):
"""Create a domain and a VM object to do a restore.
- @param dompath: The path to all domain information
@param config: domain configuration
@param uuid: uuid to use
"""
- log.debug("XendDomainInfo.restore(%s, %s, %s)", dompath, config, uuid)
+ log.debug("XendDomainInfo.restore(%s, %s)", config, uuid)
if not uuid:
uuid = getUuid()
@@ -183,14 +221,12 @@
except TypeError, exn:
raise VmError('Invalid ssidref in config: %s' % exn)
- log.debug('restoring with ssidref = %d' % ssidref)
-
- vm = cls(uuid, dompath, cls.parseConfig(config),
+ vm = cls(uuid, cls.parseConfig(config),
xc.domain_create(ssidref = ssidref))
- vm.clear_shutdown()
vm.create_channel()
vm.configure()
vm.exportToDB()
+ vm.refreshShutdown()
return vm
restore = classmethod(restore)
@@ -214,33 +250,28 @@
log.debug("parseConfig: config is %s" % str(config))
result = {}
- imagecfg = "()"
-
- result['name'] = get_cfg('name')
- result['ssidref'] = get_cfg('ssidref', int)
+
+ for e in ROUNDTRIPPING_CONFIG_ENTRIES:
+ result[e[0]] = get_cfg(e[0], e[1])
+
result['memory'] = get_cfg('memory', int)
result['mem_kb'] = get_cfg('mem_kb', int)
result['maxmem'] = get_cfg('maxmem', int)
result['maxmem_kb'] = get_cfg('maxmem_kb', int)
result['cpu'] = get_cfg('cpu', int)
- result['cpu_weight'] = get_cfg('cpu_weight', float)
- result['bootloader'] = get_cfg('bootloader')
result['restart_mode'] = get_cfg('restart')
+ result['image'] = get_cfg('image')
try:
- imagecfg = get_cfg('image')
-
- if imagecfg:
- result['image'] = imagecfg
- result['vcpus'] = int(sxp.child_value(imagecfg, 'vcpus',
- 1))
+ if result['image']:
+ result['vcpus'] = int(sxp.child_value(result['image'],
+ 'vcpus', 1))
else:
result['vcpus'] = 1
except TypeError, exn:
raise VmError(
'Invalid configuration setting: vcpus = %s: %s' %
- (sxp.child_value(imagecfg, 'vcpus', 1),
- str(exn)))
+ (sxp.child_value(result['image'], 'vcpus', 1), str(exn)))
result['backend'] = []
for c in sxp.children(config, 'backend'):
@@ -258,12 +289,12 @@
parseConfig = classmethod(parseConfig)
- def __init__(self, uuid, parentpath, info, domid = None, augment = False):
+ def __init__(self, uuid, info, domid = None, augment = False):
self.uuid = uuid
self.info = info
- self.path = parentpath + "/" + uuid
+ self.path = DOMROOT + "/" + uuid
if domid:
self.domid = domid
@@ -283,26 +314,26 @@
self.store_mfn = None
self.console_channel = None
self.console_mfn = None
-
- #todo: state: running, suspended
+
self.state = STATE_VM_OK
self.state_updated = threading.Condition()
- self.shutdown_pending = None
-
- self.restart_state = None
- self.restart_time = None
- self.restart_count = 0
-
+
self.writeVm("uuid", self.uuid)
self.storeDom("vm", self.path)
def augmentInfo(self):
+ """Augment self.info, as given to us through {@link #recreate}, with
+ values taken from the store. This recovers those values known to xend
+ but not to the hypervisor.
+ """
def useIfNeeded(name, val):
if not self.infoIsSet(name) and val is not None:
self.info[name] = val
params = (("name", str),
+ ("restart-mode", str),
+ ("image", str),
("start-time", float))
from_store = self.gatherVm(*params)
@@ -322,12 +353,17 @@
defaultInfo('name', lambda: "Domain-%d" % self.domid)
defaultInfo('ssidref', lambda: 0)
defaultInfo('restart_mode', lambda: RESTART_ONREBOOT)
+ defaultInfo('cpu', lambda: None)
defaultInfo('cpu_weight', lambda: 1.0)
defaultInfo('bootloader', lambda: None)
defaultInfo('backend', lambda: [])
defaultInfo('device', lambda: [])
+ defaultInfo('image', lambda: None)
self.check_name(self.info['name'])
+
+ if isinstance(self.info['image'], str):
+ self.info['image'] = sxp.from_string(self.info['image'])
# Internally, we keep only maxmem_KiB, and not maxmem or maxmem_kb
# (which come from outside, and are in MiB and KiB respectively).
@@ -451,17 +487,16 @@
'domid': str(self.domid),
'uuid': self.uuid,
- 'restart_time': str(self.restart_time),
-
- 'xend/state': self.state,
- 'xend/restart_count': str(self.restart_count),
'xend/restart_mode': str(self.info['restart_mode']),
'memory/target': str(self.info['memory_KiB'])
}
for (k, v) in self.info.items():
- to_store[k] = str(v)
+ if v:
+ to_store[k] = str(v)
+
+ to_store['image'] = sxp.to_string(self.info['image'])
log.debug("Storing %s" % str(to_store))
@@ -511,6 +546,88 @@
def getBackendFlags(self):
return reduce(lambda x, y: x | backendFlags[y],
self.info['backend'], 0)
+
+
+ def refreshShutdown(self, xeninfo = None):
+ if xeninfo is None:
+ xeninfo = dom_get(self.domid)
+ if xeninfo is None:
+ # The domain no longer exists. This will occur if we have
+ # scheduled a timer to check for shutdown timeouts and the
+ # shutdown succeeded.
+ return
+
+ if xeninfo['dying']:
+ # Dying means that a domain has been destroyed, but has not yet
+ # been cleaned up by Xen. This could persist indefinitely if,
+ # for example, another domain has some of its pages mapped.
+ # We might like to diagnose this problem in the future, but for
+ # now all we can sensibly do is ignore it.
+ pass
+
+ elif xeninfo['crashed']:
+ log.warn('Domain has crashed: name=%s id=%d.',
+ self.info['name'], self.domid)
+
+ if xroot.get_enable_dump():
+ self.dumpCore()
+
+ self.maybeRestart('crashed')
+
+ elif xeninfo['shutdown']:
+ reason = shutdown_reason(xeninfo['shutdown_reason'])
+
+ log.info('Domain has shutdown: name=%s id=%d reason=%s.',
+ self.info['name'], self.domid, reason)
+
+ self.clearRestart()
+
+ if reason == 'suspend':
+ self.state_set(STATE_VM_SUSPENDED)
+ # Don't destroy the domain. XendCheckpoint will do this once
+ # it has finished.
+ elif reason in ['poweroff', 'reboot']:
+ self.maybeRestart(reason)
+ else:
+ self.destroy()
+
+ else:
+ # Domain is alive. If we are shutting it down, then check
+ # the timeout on that, and destroy it if necessary.
+
+ sst = self.readVm('xend/shutdown_start_time')
+ if sst:
+ sst = float(sst)
+ timeout = SHUTDOWN_TIMEOUT - time.time() + sst
+ if timeout < 0:
+ log.info(
+ "Domain shutdown timeout expired: name=%s id=%s",
+ self.info['name'], self.domid)
+ self.destroy()
+ else:
+ log.debug(
+ "Scheduling refreshShutdown on domain %d in %ds.",
+ self.domid, timeout)
+ scheduler.later(timeout, self.refreshShutdown)
+
+
+ def shutdown(self, reason):
+ if not reason in shutdown_reasons.values():
+ raise XendError('invalid reason:' + reason)
+ self.storeVm("control/shutdown", reason)
+ if not reason == 'suspend':
+ self.storeVm('xend/shutdown_start_time', time.time())
+
+
+ def clearRestart(self):
+ self.removeVm("xend/shutdown_start_time")
+
+
+ def maybeRestart(self, reason):
+ if self.restart_needed(reason):
+ self.restart()
+ else:
+ self.destroy()
def dumpCore(self):
@@ -526,18 +643,32 @@
self.domid, self.info['name'], str(exn))
+ def closeChannel(self, channel, entry):
+ """Close the given channel, if set, and remove the given entry in the
+ store. Nothrow guarantee."""
+
+ try:
+ try:
+ if channel:
+ channel.close()
+ finally:
+ self.removeDom(entry)
+ except Exception, exn:
+ log.exception(exn)
+
+
def closeStoreChannel(self):
"""Close the store channel, if any. Nothrow guarantee."""
-
- try:
- if self.store_channel:
- try:
- self.store_channel.close()
- self.removeDom("store/port")
- finally:
- self.store_channel = None
- except Exception, exn:
- log.exception(exn)
+
+ self.closeChannel(self.store_channel, "store/port")
+ self.store_channel = None
+
+
+ def closeConsoleChannel(self):
+ """Close the console channel, if any. Nothrow guarantee."""
+
+ self.closeChannel(self.console_channel, "console/port")
+ self.console_channel = None
def setConsoleRef(self, ref):
@@ -566,10 +697,13 @@
self.info.update(info)
self.validateInfo()
+ self.refreshShutdown(info)
log.debug("XendDomainInfo.update done on domain %d: %s", self.domid,
self.info)
+
+ ## private:
def state_set(self, state):
self.state_updated.acquire()
@@ -577,13 +711,16 @@
self.state = state
self.state_updated.notifyAll()
self.state_updated.release()
- self.exportToDB()
+
+
+ ## public:
def state_wait(self, state):
self.state_updated.acquire()
while self.state != state:
self.state_updated.wait()
self.state_updated.release()
+
def __str__(self):
s = "<domain"
@@ -597,6 +734,25 @@
__repr__ = __str__
+ def createDevice(self, deviceClass, devconfig):
+ return self.getDeviceController(deviceClass).createDevice(devconfig)
+
+
+ def configureDevice(self, deviceClass, devid, devconfig):
+ return self.getDeviceController(deviceClass).configureDevice(
+ devid, devconfig)
+
+
+ def destroyDevice(self, deviceClass, devid):
+ return self.getDeviceController(deviceClass).destroyDevice(devid)
+
+
+ def getDeviceSxprs(self, deviceClass):
+ return self.getDeviceController(deviceClass).sxprs()
+
+
+ ## private:
+
def getDeviceController(self, name):
if name not in controllerClasses:
raise XendError("unknown device type: " + str(name))
@@ -604,62 +760,53 @@
return controllerClasses[name](self)
- def createDevice(self, deviceClass, devconfig):
- return self.getDeviceController(deviceClass).createDevice(devconfig)
-
-
- def configureDevice(self, deviceClass, devid, devconfig):
- return self.getDeviceController(deviceClass).configureDevice(
- devid, devconfig)
-
-
- def destroyDevice(self, deviceClass, devid):
- return self.getDeviceController(deviceClass).destroyDevice(devid)
-
+ ## public:
def sxpr(self):
sxpr = ['domain',
- ['domid', self.domid],
- ['name', self.info['name']],
- ['memory', self.info['memory_KiB'] / 1024],
- ['ssidref', self.info['ssidref']]]
- if self.uuid:
- sxpr.append(['uuid', self.uuid])
- if self.info:
- sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
-
- if self.infoIsSet('device'):
- for (_, c) in self.info['device']:
- sxpr.append(['device', c])
-
- def stateChar(name):
- if name in self.info:
- if self.info[name]:
- return name[0]
- else:
- return '-'
+ ['domid', self.domid],
+ ['uuid', self.uuid],
+ ['memory', self.info['memory_KiB'] / 1024]]
+
+ for e in ROUNDTRIPPING_CONFIG_ENTRIES:
+ if self.infoIsSet(e[0]):
+ sxpr.append([e[0], self.info[e[0]]])
+
+ sxpr.append(['maxmem', self.info['maxmem_KiB'] / 1024])
+
+ if self.infoIsSet('image'):
+ sxpr.append(['image', self.info['image']])
+
+ if self.infoIsSet('device'):
+ for (_, c) in self.info['device']:
+ sxpr.append(['device', c])
+
+ def stateChar(name):
+ if name in self.info:
+ if self.info[name]:
+ return name[0]
else:
- return '?'
-
- state = reduce(
- lambda x, y: x + y,
- map(stateChar,
- ['running', 'blocked', 'paused', 'shutdown', 'crashed']))
-
- sxpr.append(['state', state])
- if self.infoIsSet('shutdown'):
- reason = shutdown_reason(self.info['shutdown_reason'])
- sxpr.append(['shutdown_reason', reason])
- if self.infoIsSet('cpu_time'):
- sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
- sxpr.append(['vcpus', self.info['vcpus']])
- sxpr.append(['cpumap', self.info['cpumap']])
- if self.infoIsSet('vcpu_to_cpu'):
- sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
- # build a string, using '|' to separate items, show only up
- # to number of vcpus in domain, and trim the trailing '|'
- sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|',
-
self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]])
+ return '-'
+ else:
+ return '?'
+
+ state = reduce(
+ lambda x, y: x + y,
+ map(stateChar,
+ ['running', 'blocked', 'paused', 'shutdown', 'crashed',
+ 'dying']))
+
+ sxpr.append(['state', state])
+ if self.infoIsSet('shutdown'):
+ reason = shutdown_reason(self.info['shutdown_reason'])
+ sxpr.append(['shutdown_reason', reason])
+ if self.infoIsSet('cpu_time'):
+ sxpr.append(['cpu_time', self.info['cpu_time']/1e9])
+ sxpr.append(['vcpus', self.info['vcpus']])
+ sxpr.append(['cpumap', self.info['cpumap']])
+ if self.infoIsSet('vcpu_to_cpu'):
+ sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]])
+ sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()])
if self.infoIsSet('start_time'):
up_time = time.time() - self.info['start_time']
@@ -674,13 +821,16 @@
sxpr.append(['console_channel', self.console_channel.sxpr()])
if self.console_mfn:
sxpr.append(['console_mfn', self.console_mfn])
- if self.restart_count:
- sxpr.append(['restart_count', self.restart_count])
- if self.restart_state:
- sxpr.append(['restart_state', self.restart_state])
- if self.restart_time:
- sxpr.append(['restart_time', str(self.restart_time)])
+
return sxpr
+
+
+ ## private:
+
+ def prettyVCpuMap(self):
+ return '|'.join(map(str,
+ self.info['vcpu_to_cpu'][0:self.info['vcpus']]))
+
def check_name(self, name):
"""Check if a vm name is valid. Valid names contain alphabetic
characters,
@@ -719,11 +869,19 @@
@param config: configuration
@raise: VmError on error
"""
- # todo - add support for scheduling params?
+
+ log.debug('XendDomainInfo.construct: %s %s',
+ str(self.domid),
+ str(self.info['ssidref']))
+
+ self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
+
+ if self.domid <= 0:
+ raise VmError('Creating domain failed: name=%s' %
+ self.info['name'])
+
try:
self.initDomain()
-
- # Create domain devices.
self.construct_image()
self.configure()
self.exportToDB()
@@ -737,30 +895,23 @@
def initDomain(self):
- log.debug('XendDomainInfo.initDomain: %s %s %s %s)',
+ log.debug('XendDomainInfo.initDomain: %s %s %s',
str(self.domid),
str(self.info['memory_KiB']),
- str(self.info['ssidref']),
str(self.info['cpu_weight']))
- self.domid = xc.domain_create(dom = self.domid or 0,
- ssidref = self.info['ssidref'])
-
- if 'image' not in self.info:
+ if not self.infoIsSet('image'):
raise VmError('Missing image in configuration')
self.image = image.create(self,
self.info['image'],
self.info['device'])
- if self.domid <= 0:
- raise VmError('Creating domain failed: name=%s' %
- self.info['name'])
-
if self.info['bootloader']:
self.image.handleBootloading()
xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
+ # XXX Merge with configure_maxmem?
m = self.image.getDomainMemory(self.info['memory_KiB'])
xc.domain_setmaxmem(self.domid, m)
xc.domain_memory_increase_reservation(self.domid, m, 0, 0)
@@ -794,6 +945,8 @@
self.configure_vcpus(self.info['vcpus'])
+ ## public:
+
def delete(self):
"""Delete the vm's db.
"""
@@ -803,48 +956,46 @@
log.warning("error in domain db delete: %s", ex)
- def destroy_domain(self):
- """Destroy the vm's domain.
- The domain will not finally go away unless all vm
- devices have been released.
- """
- if self.domid is None:
- return
- try:
- xc.domain_destroy(dom=self.domid)
- except Exception, err:
- log.exception("Domain destroy failed: %s", self.info['name'])
-
def cleanup(self):
- """Cleanup vm resources: release devices.
- """
- self.state = STATE_VM_TERMINATED
+ """Cleanup vm resources: release devices. Nothrow guarantee."""
+
+ self.state_set(STATE_VM_TERMINATED)
self.release_devices()
self.closeStoreChannel()
- if self.console_channel:
- # notify processes using this console?
- try:
- self.console_channel.close()
- self.console_channel = None
- except:
- pass
+ self.closeConsoleChannel()
+
if self.image:
try:
self.image.destroy()
- self.image = None
except:
- pass
+ log.exception(
+ "XendDomainInfo.cleanup: image.destroy() failed.")
+ self.image = None
+
def destroy(self):
- """Cleanup vm and destroy domain.
- """
-
- log.debug("XendDomainInfo.destroy")
-
- self.destroy_domain()
+ """Cleanup vm and destroy domain. Nothrow guarantee."""
+
+ log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
+
self.cleanup()
- self.exportToDB()
- return 0
+
+ try:
+ self.removeVm()
+ except Exception:
+ log.exception("Removing VM path failed.")
+
+ try:
+ self.removeDom()
+ except Exception:
+ log.exception("Removing domain path failed.")
+
+ try:
+ if self.domid is not None:
+ xc.domain_destroy(dom=self.domid)
+ except Exception:
+ log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
+
def is_terminated(self):
"""Check if a domain has been terminated.
@@ -852,8 +1003,7 @@
return self.state == STATE_VM_TERMINATED
def release_devices(self):
- """Release all vm devices.
- """
+ """Release all vm devices. Nothrow guarantee."""
while True:
t = xstransact("%s/device" % self.path)
@@ -865,8 +1015,8 @@
# Log and swallow any exceptions in removal --
# there's nothing more we can do.
log.exception(
- "Device release failed: %s; %s; %s; %s" %
- (self.info['name'], n, d, str(ex)))
+ "Device release failed: %s; %s; %s",
+ self.info['name'], n, d)
if t.commit():
break
@@ -902,8 +1052,7 @@
@raise: VmError for invalid devices
"""
- if not self.rebooting():
- self.create_configured_devices()
+ self.create_configured_devices()
if self.image:
self.image.createDeviceModel()
@@ -942,23 +1091,6 @@
return reason == 'reboot'
return False
- def restart_cancel(self):
- """Cancel a vm restart.
- """
- self.restart_state = None
-
- def restarting(self):
- """Put the vm into restart mode.
- """
- self.restart_state = STATE_RESTART_PENDING
-
- def restart_pending(self):
- """Test if the vm has a pending restart.
- """
- return self.restart_state == STATE_RESTART_PENDING
-
- def rebooting(self):
- return self.restart_state == STATE_RESTART_BOOTING
def restart_check(self):
"""Check if domain restart is OK.
@@ -976,23 +1108,37 @@
self.restart_time = tnow
self.restart_count += 1
+
def restart(self):
- """Restart the domain after it has exited.
- Reuses the domain id
-
- """
+ """Restart the domain after it has exited. """
+
+ # self.restart_check()
+ self.cleanup()
+
+ config = self.sxpr()
+
+ if self.readVm('xend/restart_in_progress'):
+ log.error('Xend failed during restart of domain %d. '
+ 'Refusing to restart to avoid loops.',
+ self.domid)
+ self.destroy()
+ return
+
+ self.writeVm('xend/restart_in_progress', 'True')
+
try:
- self.clear_shutdown()
- self.state = STATE_VM_OK
- self.shutdown_pending = None
- self.restart_check()
- self.exportToDB()
- self.restart_state = STATE_RESTART_BOOTING
- self.configure_bootloader()
- self.construct()
- self.exportToDB()
+ self.destroy()
+ try:
+ xd = get_component('xen.xend.XendDomain')
+ xd.domain_unpause(xd.domain_create(config).getDomid())
+ except Exception, exn:
+ log.exception('Failed to restart domain %d.', self.domid)
finally:
- self.restart_state = None
+ self.removeVm('xend/restart_in_progress')
+
+ # self.configure_bootloader()
+ # self.exportToDB()
+
def configure_bootloader(self):
if not self.info['bootloader']:
@@ -1006,7 +1152,8 @@
if dev:
disk = sxp.child_value(dev, "uname")
fn = blkdev_uname_to_file(disk)
- blcfg = bootloader(self.info['bootloader'], fn, 1,
self.info['vcpus'])
+ blcfg = bootloader(self.info['bootloader'], fn, 1,
+ self.info['vcpus'])
if blcfg is None:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
@@ -1023,7 +1170,9 @@
def configure_maxmem(self):
- xc.domain_setmaxmem(self.domid, maxmem_kb = self.info['maxmem_KiB'])
+ if self.image:
+ m = self.image.getDomainMemory(self.info['memory_KiB'])
+ xc.domain_setmaxmem(self.domid, maxmem_kb = m)
def vcpu_hotplug(self, vcpu, state):
@@ -1038,23 +1187,8 @@
availability = "online"
self.storeVm("cpu/%d/availability" % vcpu, availability)
- def shutdown(self, reason):
- if not reason in shutdown_reasons.values():
- raise XendError('invalid reason:' + reason)
- self.storeVm("control/shutdown", reason)
- if not reason in ['suspend']:
- self.shutdown_pending = {'start':time.time(), 'reason':reason}
-
- def clear_shutdown(self):
- self.removeVm("control/shutdown")
-
def send_sysrq(self, key=0):
self.storeVm("control/sysrq", '%c' % key)
-
- def shutdown_time_left(self, timeout):
- if not self.shutdown_pending:
- return 0
- return timeout - (time.time() - self.shutdown_pending['start'])
def dom0_init_store(self):
if not self.store_channel:
@@ -1078,8 +1212,6 @@
def dom0_enforce_vcpus(self):
dom = 0
# get max number of vcpus to use for dom0 from config
- from xen.xend import XendRoot
- xroot = XendRoot.instance()
target = int(xroot.get_dom0_vcpus())
log.debug("number of vcpus to use is %d" % (target))
diff -r 93e27f7ca8a8 -r 61b3b357d827
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/DevController.py Thu Sep 29 23:28:44 2005
@@ -81,6 +81,13 @@
xstransact.Remove(backpath)
+ def sxprs(self):
+ """@return an s-expression describing all the devices of this
+ controller's device-class.
+ """
+ return xstransact.ListRecursive(self.frontendRoot())
+
+
def sxpr(self, devid):
"""@return an s-expression describing the specified device.
"""
@@ -126,8 +133,8 @@
compulsory to use it; subclasses may prefer to allocate IDs based upon
the device configuration instead.
"""
+ path = self.frontendMiscPath()
while True:
- path = self.frontendMiscPath()
t = xstransact(path)
try:
result = t.read("nextDeviceID")
@@ -196,8 +203,11 @@
def frontendPath(self, devid):
- return "%s/device/%s/%d" % (self.vm.getPath(), self.deviceClass,
- devid)
+ return "%s/%d" % (self.frontendRoot(), devid)
+
+
+ def frontendRoot(self):
+ return "%s/device/%s" % (self.vm.getPath(), self.deviceClass)
def frontendMiscPath(self):
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDaemon.py Thu Sep 29 23:28:44 2005
@@ -9,25 +9,23 @@
import sys
import threading
import linecache
-import socket
import pwd
import re
-import StringIO
import traceback
-import time
-import glob
-
-from xen.xend import sxp
-from xen.xend import PrettyPrint
-from xen.xend import EventServer; eserver = EventServer.instance()
-from xen.xend.XendError import XendError
+
+from xen.xend import EventServer
from xen.xend.server import SrvServer
from xen.xend.XendLogging import log
-from xen.xend import XendRoot; xroot = XendRoot.instance()
+from xen.xend import XendRoot
import event
import relocate
from params import *
+
+
+eserver = EventServer.instance()
+xroot = XendRoot.instance()
+
class Daemon:
"""The xend daemon.
@@ -233,7 +231,7 @@
except:
pass
- def print_trace(self, str):
+ def print_trace(self, string):
for i in range(self.traceindent):
ch = " "
if (i % 5):
@@ -241,7 +239,7 @@
else:
ch = '|'
self.tracefile.write(ch)
- self.tracefile.write(str)
+ self.tracefile.write(string)
def trace(self, frame, event, arg):
if not self.traceon:
@@ -289,7 +287,7 @@
try:
os.setuid(pwd.getpwnam(XEND_USER)[2])
return 0
- except KeyError, error:
+ except KeyError:
print >>sys.stderr, "Error: no such user '%s'" % XEND_USER
return 1
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvDmesg.py
--- a/tools/python/xen/xend/server/SrvDmesg.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDmesg.py Thu Sep 29 23:28:44 2005
@@ -13,14 +13,14 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2005 XenSource Ltd
#============================================================================
-import os
-from xen.xend import sxp
from xen.xend import XendDmesg
from xen.web.SrvDir import SrvDir
+
class SrvDmesg(SrvDir):
"""Xen Dmesg output.
@@ -47,6 +47,6 @@
def info(self):
return self.xd.info()
- def op_clear(self, op, req):
+ def op_clear(self, _1, _2):
self.xd.clear()
return 0
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDomain.py Thu Sep 29 23:28:44 2005
@@ -150,17 +150,6 @@
val = fn(req.args, {'dom': self.dom.domid})
return val
- def op_device(self, op, req):
- fn = FormFn(self.xd.domain_devtype_get,
- [['dom', 'int'],
- ['type', 'str'],
- ['idx', 'int']])
- val = fn(req.args, {'dom': self.dom.domid})
- if val:
- return val.sxpr()
- else:
- raise XendError("invalid device")
-
def op_device_create(self, op, req):
fn = FormFn(self.xd.domain_device_create,
[['dom', 'int'],
@@ -172,7 +161,7 @@
fn = FormFn(self.xd.domain_device_refresh,
[['dom', 'int'],
['type', 'str'],
- ['idx', 'str']])
+ ['idx', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val
@@ -180,7 +169,7 @@
fn = FormFn(self.xd.domain_device_destroy,
[['dom', 'int'],
['type', 'str'],
- ['idx', 'str']])
+ ['idx', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val
@@ -188,7 +177,7 @@
fn = FormFn(self.xd.domain_device_configure,
[['dom', 'int'],
['config', 'sxpr'],
- ['idx', 'str']])
+ ['idx', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val
@@ -230,10 +219,6 @@
self.print_path(req)
#self.ls()
req.write('<p>%s</p>' % self.dom)
- if self.dom.config:
- req.write("<code><pre>")
- PrettyPrint.prettyprint(self.dom.config, out=req)
- req.write("</pre></code>")
self.form(req)
req.write('</body></html>')
return ''
diff -r 93e27f7ca8a8 -r 61b3b357d827
tools/python/xen/xend/server/SrvDomainDir.py
--- a/tools/python/xen/xend/server/SrvDomainDir.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvDomainDir.py Thu Sep 29 23:28:44 2005
@@ -38,19 +38,17 @@
self.xd = XendDomain.instance()
def domain(self, x):
- val = None
dom = self.xd.domain_lookup_by_name(x)
if not dom:
raise XendError('No such domain ' + str(x))
- val = SrvDomain(dom)
- return val
+ return SrvDomain(dom)
def get(self, x):
v = SrvDir.get(self, x)
if v is not None:
return v
- v = self.domain(x)
- return v
+ else:
+ return self.domain(x)
def op_create(self, op, req):
"""Create a domain.
@@ -152,11 +150,11 @@
domains = self.xd.list_sorted()
req.write('<ul>')
for d in domains:
- req.write('<li><a href="%s%s"> Domain %s</a>'
- % (url, d.getName(), d.getName()))
- req.write('id=%s' % d.getDomain())
- req.write('memory=%d'% d.getMemoryTarget())
- req.write('ssidref=%d'% d.getSsidref())
+ req.write(
+ '<li><a href="%s%s">Domain %s</a>: id = %s, memory = %d, '
+ 'ssidref = %d.'
+ % (url, d.getName(), d.getName(), d.getDomid(),
+ d.getMemoryTarget(), d.getSsidref()))
req.write('</li>')
req.write('</ul>')
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xend/server/SrvNode.py
--- a/tools/python/xen/xend/server/SrvNode.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/server/SrvNode.py Thu Sep 29 23:28:44 2005
@@ -62,7 +62,7 @@
for d in self.info():
req.write('<li> %10s: %s' % (d[0], str(d[1])))
req.write('<li><a href="%sdmesg">Xen dmesg output</a>' % url)
- req.write('<li><a href="%slog>Xend log</a>' % url)
+ req.write('<li><a href="%slog">Xend log</a>' % url)
req.write('</ul>')
req.write('</body></html>')
diff -r 93e27f7ca8a8 -r 61b3b357d827
tools/python/xen/xend/xenstore/xstransact.py
--- a/tools/python/xen/xend/xenstore/xstransact.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xend/xenstore/xstransact.py Thu Sep 29 23:28:44 2005
@@ -1,4 +1,5 @@
# Copyright (C) 2005 Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>
+# Copyright (C) 2005 XenSource Ltd
# This file is subject to the terms and conditions of the GNU General
# Public License. See the file "COPYING" in the main directory of
@@ -8,6 +9,7 @@
import threading
from xen.lowlevel import xs
from xen.xend.xenstore.xsutil import xshandle
+
class xstransact:
@@ -40,8 +42,15 @@
'%s, while reading %s' % (ex.args[1], path))
def read(self, *args):
- if len(args) == 0:
- raise TypeError
+ """If no arguments are given, return the value at this transaction's
+ path. If one argument is given, treat that argument as a subpath to
+ this transaction's path, and return the value at that path.
+ Otherwise, treat each argument as a subpath to this transaction's
+ path, and return a list composed of the values at each of those
+ instead.
+ """
+ if len(args) == 0:
+ return xshandle().read(self.path)
if len(args) == 1:
return self._read(args[0])
ret = []
@@ -105,12 +114,49 @@
return []
def list(self, *args):
- if len(args) == 0:
- raise TypeError
+ """If no arguments are given, list this transaction's path, returning
+ the entries therein, or the empty list if no entries are found.
+ Otherwise, treat each argument as a subpath to this transaction's
+ path, and return the cumulative listing of each of those instead.
+ """
+ if len(args) == 0:
+ ret = xshandle().ls(self.path)
+ if ret is None:
+ return []
+ else:
+ return ret
+ else:
+ ret = []
+ for key in args:
+ ret.extend(self._list(key))
+ return ret
+
+
+ def list_recursive_(self, subdir, keys):
ret = []
- for key in args:
- ret.extend(self._list(key))
+ for key in keys:
+ new_subdir = subdir + "/" + key
+ l = xshandle().ls(new_subdir)
+ if l:
+ ret.append([key, self.list_recursive_(new_subdir, l)])
+ else:
+ ret.append([key, xshandle().read(new_subdir)])
return ret
+
+
+ def list_recursive(self, *args):
+ """If no arguments are given, list this transaction's path, returning
+ the entries therein, or the empty list if no entries are found.
+ Otherwise, treat each argument as a subpath to this transaction's
+ path, and return the cumulative listing of each of those instead.
+ """
+ if len(args) == 0:
+ args = self.list()
+ if args is None or len(args) == 0:
+ return []
+
+ return self.list_recursive_(self.path, args)
+
def gather(self, *args):
if len(args) and type(args[0]) != tuple:
@@ -163,6 +209,13 @@
def Read(cls, path, *args):
+ """If only one argument is given (path), return the value stored at
+ that path. If two arguments are given, treat the second argument as a
+ subpath within the first, and return the value at the composed path.
+ Otherwise, treat each argument after the first as a subpath to the
+ given path, and return a list composed of the values at each of those
+ instead. This operation is performed inside a transaction.
+ """
while True:
t = cls(path)
try:
@@ -206,6 +259,12 @@
Remove = classmethod(Remove)
def List(cls, path, *args):
+ """If only one argument is given (path), list its contents, returning
+ the entries therein, or the empty list if no entries are found.
+ Otherwise, treat each further argument as a subpath to the given path,
+ and return the cumulative listing of each of those instead. This
+ operation is performed inside a transaction.
+ """
while True:
t = cls(path)
try:
@@ -218,6 +277,25 @@
List = classmethod(List)
+ def ListRecursive(cls, path, *args):
+ """If only one argument is given (path), list its contents
+ recursively, returning the entries therein, or the empty list if no
+ entries are found. Otherwise, treat each further argument as a
+ subpath to the given path, and return the cumulative listing of each
+ of those instead. This operation is performed inside a transaction.
+ """
+ while True:
+ t = cls(path)
+ try:
+ v = t.list_recursive(*args)
+ if t.commit():
+ return v
+ except:
+ t.abort()
+ raise
+
+ ListRecursive = classmethod(ListRecursive)
+
def Gather(cls, path, *args):
while True:
t = cls(path)
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Thu Sep 29 22:22:02 2005
+++ b/tools/python/xen/xm/main.py Thu Sep 29 23:28:44 2005
@@ -175,6 +175,10 @@
dom = args[0] # TODO: should check if this exists
savefile = os.path.abspath(args[1])
+
+ if not os.access(os.path.dirname(savefile), os.W_OK):
+ err("xm save: Unable to create file %s" % savefile)
+ sys.exit(1)
from xen.xend.XendClient import server
server.xend_domain_save(dom, savefile)
@@ -183,6 +187,10 @@
arg_check(args,1,"restore")
savefile = os.path.abspath(args[0])
+
+ if not os.access(savefile, os.R_OK):
+ err("xm restore: Unable to read file %s" % savefile)
+ sys.exit(1)
from xen.xend.XendClient import server
info = server.xend_domain_restore(savefile)
diff -r 93e27f7ca8a8 -r 61b3b357d827 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu Sep 29 22:22:02 2005
+++ b/tools/xenstore/xenstored_domain.c Thu Sep 29 23:28:44 2005
@@ -63,6 +63,8 @@
/* The connection associated with this. */
struct connection *conn;
+ /* Have we noticed that this domain is shutdown? */
+ int shutdown;
};
static LIST_HEAD(domains);
@@ -222,19 +224,25 @@
{
xc_dominfo_t dominfo;
struct domain *domain, *tmp;
- int released = 0;
+ int notify = 0;
list_for_each_entry_safe(domain, tmp, &domains, list) {
if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
&dominfo) == 1 &&
- dominfo.domid == domain->domid &&
- !dominfo.dying && !dominfo.crashed && !dominfo.shutdown)
- continue;
+ dominfo.domid == domain->domid) {
+ if ((dominfo.crashed || dominfo.shutdown)
+ && !domain->shutdown) {
+ domain->shutdown = 1;
+ notify = 1;
+ }
+ if (!dominfo.dying)
+ continue;
+ }
talloc_free(domain->conn);
- released++;
- }
-
- if (released)
+ notify = 1;
+ }
+
+ if (notify)
fire_watches(NULL, "@releaseDomain", false);
}
@@ -272,6 +280,7 @@
struct domain *domain;
domain = talloc(context, struct domain);
domain->port = 0;
+ domain->shutdown = 0;
domain->domid = domid;
domain->path = talloc_strdup(domain, path);
domain->page = xc_map_foreign_range(*xc_handle, domain->domid,
diff -r 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/shadow32.c Thu Sep 29 23:28:44 2005
@@ -755,9 +755,13 @@
/*
* Then free monitor_table.
+ * Note: for VMX guest, only BSP need do this free.
*/
- mfn = pagetable_get_pfn(v->arch.monitor_table);
- free_domheap_page(&frame_table[mfn]);
+ if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
+ mfn = pagetable_get_pfn(v->arch.monitor_table);
+ unmap_domain_page(v->arch.monitor_vtable);
+ free_domheap_page(&frame_table[mfn]);
+ }
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
@@ -1832,7 +1836,7 @@
}
#endif
- FSH_LOG("%s(gpfn=%lx, mfn=%lx) c=%08x t=%08x", __func__,
+ FSH_LOG("%s(gpfn=%lx, mfn=%lx) c=%08x t=%08lx", __func__,
gpfn, mfn, page->count_info, page->u.inuse.type_info);
// XXX this will require some more thought... Cross-domain sharing and
@@ -3013,7 +3017,7 @@
l1_pgentry_t guest_pte = *p_guest_pte;
l1_pgentry_t shadow_pte = *p_shadow_pte;
l1_pgentry_t snapshot_pte = p_snapshot_pte ? *p_snapshot_pte : l1e_empty();
- l1_pgentry_t eff_guest_pte;
+ l1_pgentry_t eff_guest_pte = l1e_empty();
unsigned long mask, eff_guest_pfn, eff_guest_mfn, shadow_mfn;
int errors = 0, guest_writable;
int page_table_page;
@@ -3070,7 +3074,7 @@
if ( (l1e_get_flags(shadow_pte) & _PAGE_RW ) && !guest_writable )
{
- printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08x
page_table_page=%d\n",
+ printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx
page_table_page=%d\n",
eff_guest_pfn, eff_guest_mfn, shadow_mfn,
frame_table[eff_guest_mfn].u.inuse.type_info,
page_table_page);
@@ -3081,7 +3085,7 @@
(l1e_get_flags(shadow_pte) & _PAGE_RW ) &&
!(guest_writable && (l1e_get_flags(eff_guest_pte) & _PAGE_DIRTY)) )
{
- printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08x
page_table_page=%d\n",
+ printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx
page_table_page=%d\n",
eff_guest_pfn, eff_guest_mfn, shadow_mfn,
frame_table[eff_guest_mfn].u.inuse.type_info,
page_table_page);
diff -r 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/shadow_public.c Thu Sep 29 23:28:44 2005
@@ -256,14 +256,15 @@
{
unsigned long mfn;
-// ASSERT( pagetable_val(v->arch.monitor_table) );
/*
* free monitor_table.
+ * Note: for VMX guest, only BSP need do this free.
*/
- //mfn = (pagetable_val(v->arch.monitor_table)) >> PAGE_SHIFT;
- mfn = pagetable_get_pfn(v->arch.monitor_table);
- unmap_domain_page(v->arch.monitor_vtable);
- free_domheap_page(&frame_table[mfn]);
+ if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
+ mfn = pagetable_get_pfn(v->arch.monitor_table);
+ unmap_domain_page(v->arch.monitor_vtable);
+ free_domheap_page(&frame_table[mfn]);
+ }
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
}
@@ -358,9 +359,13 @@
/*
* Then free monitor_table.
+ * Note: for VMX guest, only BSP need do this free.
*/
- mfn = pagetable_get_pfn(v->arch.monitor_table);
- free_domheap_page(&frame_table[mfn]);
+ if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
+ mfn = pagetable_get_pfn(v->arch.monitor_table);
+ unmap_domain_page(v->arch.monitor_vtable);
+ free_domheap_page(&frame_table[mfn]);
+ }
v->arch.monitor_table = mk_pagetable(0);
v->arch.monitor_vtable = 0;
diff -r 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/time.c Thu Sep 29 23:28:44 2005
@@ -119,8 +119,8 @@
"mov %4,%%eax ; "
"mov %%edx,%4 ; "
"mul %5 ; "
+ "xor %5,%5 ; "
"add %4,%%eax ; "
- "xor %5,%5 ; "
"adc %5,%%edx ; "
: "=A" (product), "=r" (tmp1), "=r" (tmp2)
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (scale->mul_frac) );
diff -r 93e27f7ca8a8 -r 61b3b357d827 xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c Thu Sep 29 22:22:02 2005
+++ b/xen/arch/x86/vmx_platform.c Thu Sep 29 23:28:44 2005
@@ -667,6 +667,7 @@
mpcip->instr = inst->instr;
mpcip->operand[0] = inst->operand[0]; /* source */
mpcip->operand[1] = inst->operand[1]; /* destination */
+ mpcip->immediate = inst->immediate;
if (inst->operand[0] & REGISTER) { /* dest is memory */
index = operand_index(inst->operand[0]);
@@ -833,12 +834,16 @@
mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mpcip, regs);
break;
- case INSTR_CMP:
- mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
- break;
-
+ case INSTR_CMP: /* Pass through */
case INSTR_TEST:
- mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mpcip, regs);
+ mpcip->flags = mmio_inst.flags;
+ mpcip->instr = mmio_inst.instr;
+ mpcip->operand[0] = mmio_inst.operand[0]; /* source */
+ mpcip->operand[1] = mmio_inst.operand[1]; /* destination */
+ mpcip->immediate = mmio_inst.immediate;
+
+ /* send the request and wait for the value */
+ send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0,
IOREQ_READ, 0);
break;
default:
diff -r 93e27f7ca8a8 -r 61b3b357d827
linux-2.6-xen-sparse/include/asm-xen/queues.h
--- a/linux-2.6-xen-sparse/include/asm-xen/queues.h Thu Sep 29 22:22:02 2005
+++ /dev/null Thu Sep 29 23:28:44 2005
@@ -1,81 +0,0 @@
-
-/*
- * Oh dear. Task queues were removed from Linux 2.6 and replaced by work
- * queues. Unfortunately the semantics is not the same. With task queues we
- * can defer work until a particular event occurs -- this is not
- * straightforwardly done with work queues (queued work is performed asap, or
- * after some fixed timeout). Conversely, work queues are a (slightly) neater
- * way of deferring work to a process context than using task queues in 2.4.
- *
- * This is a bit of a needless reimplementation -- should have just pulled
- * the code from 2.4, but I tried leveraging work queues to simplify things.
- * They didn't help. :-(
- */
-
-#ifndef __QUEUES_H__
-#define __QUEUES_H__
-
-#include <linux/version.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
-
-struct tq_struct {
- void (*fn)(void *);
- void *arg;
- struct list_head list;
- unsigned long pending;
-};
-#define INIT_TQUEUE(_name, _fn, _arg) \
- do { \
- INIT_LIST_HEAD(&(_name)->list); \
- (_name)->pending = 0; \
- (_name)->fn = (_fn); (_name)->arg = (_arg); \
- } while ( 0 )
-#define DECLARE_TQUEUE(_name, _fn, _arg) \
- struct tq_struct _name = { (_fn), (_arg), LIST_HEAD_INIT((_name).list), 0 }
-
-typedef struct {
- struct list_head list;
- spinlock_t lock;
-} task_queue;
-#define DECLARE_TASK_QUEUE(_name) \
- task_queue _name = { LIST_HEAD_INIT((_name).list), SPIN_LOCK_UNLOCKED }
-
-static inline int queue_task(struct tq_struct *tqe, task_queue *tql)
-{
- unsigned long flags;
- if ( test_and_set_bit(0, &tqe->pending) )
- return 0;
- spin_lock_irqsave(&tql->lock, flags);
- list_add_tail(&tqe->list, &tql->list);
- spin_unlock_irqrestore(&tql->lock, flags);
- return 1;
-}
-
-static inline void run_task_queue(task_queue *tql)
-{
- struct list_head head, *ent;
- struct tq_struct *tqe;
- unsigned long flags;
- void (*fn)(void *);
- void *arg;
-
- spin_lock_irqsave(&tql->lock, flags);
- list_add(&head, &tql->list);
- list_del_init(&tql->list);
- spin_unlock_irqrestore(&tql->lock, flags);
-
- while ( !list_empty(&head) )
- {
- ent = head.next;
- list_del_init(ent);
- tqe = list_entry(ent, struct tq_struct, list);
- fn = tqe->fn;
- arg = tqe->arg;
- wmb();
- tqe->pending = 0;
- fn(arg);
- }
-}
-
-#endif /* __QUEUES_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|