# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID a38c292e8390370ec9473a6444bd63be7e437afe
# Parent 40bb46f599d93a8605740bc5800d5e61d8cc1198
# Parent 1f87f39aa0e19527976780a9aab473d9fe191b8a
Merged.
diff -r 40bb46f599d9 -r a38c292e8390 .hgignore
--- a/.hgignore Tue Jan 10 15:21:00 2006
+++ b/.hgignore Tue Jan 24 16:54:34 2006
@@ -163,6 +163,7 @@
^tools/xenstore/xenstore-read$
^tools/xenstore/xenstore-rm$
^tools/xenstore/xenstore-write$
+^tools/xenstore/xenstore-ls$
^tools/xenstore/xenstored$
^tools/xenstore/xenstored_test$
^tools/xenstore/xs_crashme$
@@ -171,7 +172,6 @@
^tools/xenstore/xs_tdb_dump$
^tools/xenstore/xs_test$
^tools/xenstore/xs_watch_stress$
-^tools/xenstore/xsls$
^tools/xentrace/setsize$
^tools/xentrace/tbctl$
^tools/xentrace/xenctx$
diff -r 40bb46f599d9 -r a38c292e8390 docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Tue Jan 10 15:21:00 2006
+++ b/docs/man/xm.pod.1 Tue Jan 24 16:54:34 2006
@@ -374,7 +374,7 @@
configured VCPU count is an error. Trying to set-vcpus to < 1 will be
quietly ignored.
-=item B<vpcu-list> I<[domain-id]>
+=item B<vcpu-list> I<[domain-id]>
Lists VCPU information for a specific domain. If no domain is
specified, VCPU information for all domains will be provided.
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64 Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64 Tue Jan 24
16:54:34 2006
@@ -91,8 +91,7 @@
# CONFIG_IA64_PAGE_SIZE_64KB is not set
CONFIG_IA64_L1_CACHE_SHIFT=7
# CONFIG_NUMA is not set
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
+CONFIG_VIRTUAL_MEM_MAP=n
CONFIG_IA64_CYCLONE=y
CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=18
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 24 16:54:34 2006
@@ -76,7 +76,9 @@
DF_MASK = 0x00000400
NT_MASK = 0x00004000
VM_MASK = 0x00020000
-
+/* Pseudo-eflags. */
+NMI_MASK = 0x80000000
+
/* Offsets into shared_info_t. */
#define evtchn_upcall_pending /* 0 */
#define evtchn_upcall_mask 1
@@ -305,8 +307,8 @@
je ldt_ss # returning to user-space with LDT SS
#endif /* XEN */
restore_nocheck:
- testl $VM_MASK, EFLAGS(%esp)
- jnz resume_vm86
+ testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
+ jnz hypervisor_iret
movb EVENT_MASK(%esp), %al
notb %al # %al == ~saved_mask
XEN_GET_VCPU_INFO(%esi)
@@ -328,11 +330,11 @@
.long 1b,iret_exc
.previous
-resume_vm86:
- XEN_UNBLOCK_EVENTS(%esi)
+hypervisor_iret:
+ andl $~NMI_MASK, EFLAGS(%esp)
RESTORE_REGS
movl %eax,(%esp)
- movl $__HYPERVISOR_switch_vm86,%eax
+ movl $__HYPERVISOR_iret,%eax
int $0x82
ud2
@@ -691,6 +693,15 @@
call do_debug
jmp ret_from_exception
+ENTRY(nmi)
+ pushl %eax
+ SAVE_ALL
+ xorl %edx,%edx # zero error code
+ movl %esp,%eax # pt_regs pointer
+ call do_nmi
+ orl $NMI_MASK, EFLAGS(%esp)
+ jmp restore_all
+
#if 0 /* XEN */
/*
* NMI is doubly nasty. It can happen _while_ we're handling
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c Tue Jan 24
16:54:34 2006
@@ -622,9 +622,11 @@
try_to_freeze(PF_FREEZE);
if (time_after(jiffies,
prev_balance_time+balanced_irq_interval)) {
+ preempt_disable();
do_irq_balance();
prev_balance_time = jiffies;
time_remaining = balanced_irq_interval;
+ preempt_enable();
}
}
return 0;
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Tue Jan 24 16:54:34 2006
@@ -506,18 +506,11 @@
static void io_check_error(unsigned char reason, struct pt_regs * regs)
{
- unsigned long i;
-
printk("NMI: IOCK error (debug interrupt?)\n");
show_registers(regs);
/* Re-enable the IOCK line, wait for a few seconds */
- reason = (reason & 0xf) | 8;
- outb(reason, 0x61);
- i = 2000;
- while (--i) udelay(1000);
- reason &= ~8;
- outb(reason, 0x61);
+ clear_io_check_error(reason);
}
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
@@ -647,12 +640,6 @@
do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
}
#endif
-
-static inline void conditional_sti(struct pt_regs *regs)
-{
- if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
- local_irq_enable();
-}
/*
* Our handling of the processor debug registers is non-trivial.
@@ -686,9 +673,9 @@
if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
SIGTRAP) == NOTIFY_STOP)
return;
-
/* It's safe to allow irq's after DR6 has been saved */
- conditional_sti(regs);
+ if (regs->eflags & X86_EFLAGS_IF)
+ local_irq_enable();
/* Mask out spurious debug traps due to lazy DR7 setting */
if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c Tue Jan 24 16:54:34 2006
@@ -65,7 +65,7 @@
{
pud_t *pud;
pmd_t *pmd_table;
-
+
#ifdef CONFIG_X86_PAE
pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
make_lowmem_page_readonly(pmd_table);
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Jan 24 16:54:34 2006
@@ -290,15 +290,15 @@
const char **vec, unsigned int len)
{
char *str;
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
int err;
if (shutting_down != SHUTDOWN_INVALID)
return;
again:
- xbt = xenbus_transaction_start();
- if (IS_ERR(xbt))
+ err = xenbus_transaction_start(&xbt);
+ if (err)
return;
str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
/* Ignore read errors and empty reads. */
@@ -339,12 +339,12 @@
unsigned int len)
{
char sysrq_key = '\0';
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
int err;
again:
- xbt = xenbus_transaction_start();
- if (IS_ERR(xbt))
+ err = xenbus_transaction_start(&xbt);
+ if (err)
return;
if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
printk(KERN_ERR "Unable to read sysrq code in "
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c Tue Jan 24
16:54:34 2006
@@ -526,7 +526,7 @@
unsigned long __init e820_end_of_ram(void)
{
- unsigned long max_end_pfn;
+ unsigned long max_end_pfn;
if (xen_override_max_pfn == 0) {
max_end_pfn = xen_start_info->nr_pages;
@@ -612,7 +612,7 @@
{
end_user_pfn = memparse(p, from);
end_user_pfn >>= PAGE_SHIFT;
- xen_override_max_pfn = (unsigned long) end_user_pfn;
+ xen_override_max_pfn = (unsigned long) end_user_pfn;
}
/*
diff -r 40bb46f599d9 -r a38c292e8390
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 Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S Tue Jan 24
16:54:34 2006
@@ -57,7 +57,7 @@
#ifndef CONFIG_PREEMPT
#define retint_kernel retint_restore_args
#endif
-
+
/*
* C code is not supposed to know about undefined top of stack. Every time
* a C function with an pt_regs argument is called from the SYSCALL based
@@ -65,7 +65,7 @@
* RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
* manipulation.
*/
-
+
/* %rsp:at FRAMEEND */
.macro FIXUP_TOP_OF_STACK tmp
movq $__USER_CS,CS(%rsp)
@@ -121,19 +121,19 @@
.endm
/*
- * Must be consistent with the definition in arch_x86_64.h:
- * struct switch_to_user {
+ * Must be consistent with the definition in arch-x86_64.h:
+ * struct iret_context {
* u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
* };
* #define VGCF_IN_SYSCALL (1<<8)
*/
- .macro SWITCH_TO_USER flag
+ .macro HYPERVISOR_IRET flag
subq $8*4,%rsp # reuse rip, cs, rflags, rsp, ss in
the stack
movq %rax,(%rsp)
movq %r11,1*8(%rsp)
movq %rcx,2*8(%rsp) # we saved %rcx upon exceptions
movq $\flag,3*8(%rsp)
- movq $__HYPERVISOR_switch_to_user,%rax
+ movq $__HYPERVISOR_iret,%rax
syscall
.endm
@@ -225,7 +225,7 @@
jnz sysret_careful
XEN_UNBLOCK_EVENTS(%rsi)
RESTORE_ARGS 0,8,0
- SWITCH_TO_USER VGCF_IN_SYSCALL
+ HYPERVISOR_IRET VGCF_IN_SYSCALL
/* Handle reschedules */
/* edx: work, edi: workmask */
@@ -417,7 +417,6 @@
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
-
/*
* Interrupt entry/exit.
@@ -479,7 +478,7 @@
orb $3,1*8(%rsp)
iretq
user_mode:
- SWITCH_TO_USER 0
+ HYPERVISOR_IRET 0
/* edi: workmask, edx: work */
retint_careful:
@@ -720,6 +719,18 @@
call evtchn_do_upcall
jmp error_exit
+#ifdef CONFIG_X86_LOCAL_APIC
+ENTRY(nmi)
+ zeroentry do_nmi_callback
+ENTRY(do_nmi_callback)
+ addq $8, %rsp
+ call do_nmi
+ RESTORE_REST
+ XEN_BLOCK_EVENTS(%rsi)
+ GET_THREAD_INFO(%rcx)
+ jmp retint_restore_args
+#endif
+
ALIGN
restore_all_enable_events:
XEN_UNBLOCK_EVENTS(%rsi) # %rsi is already set up...
@@ -734,7 +745,7 @@
orb $3,1*8(%rsp)
iretq
crit_user_mode:
- SWITCH_TO_USER 0
+ HYPERVISOR_IRET 0
14: XEN_LOCKED_BLOCK_EVENTS(%rsi)
XEN_PUT_VCPU_INFO(%rsi)
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c Tue Jan 24
16:54:34 2006
@@ -68,13 +68,13 @@
static void __init setup_boot_cpu_data(void)
{
- int dummy, eax;
+ unsigned int dummy, eax;
/* get vendor info */
- cpuid(0, &boot_cpu_data.cpuid_level,
- (int *)&boot_cpu_data.x86_vendor_id[0],
- (int *)&boot_cpu_data.x86_vendor_id[8],
- (int *)&boot_cpu_data.x86_vendor_id[4]);
+ cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
+ (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
+ (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
+ (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
/* get cpu type */
cpuid(1, &eax, &dummy, &dummy,
@@ -109,7 +109,6 @@
if (s != NULL)
setup_early_printk(s);
#endif
-
#ifdef CONFIG_DISCONTIGMEM
s = strstr(saved_command_line, "numa=");
if (s != NULL)
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c Tue Jan 24
16:54:34 2006
@@ -255,10 +255,8 @@
return 1;
}
-
__setup("noapic", disable_ioapic_setup);
__setup("apic", enable_ioapic_setup);
-
#include <asm/pci-direct.h>
#include <linux/pci_ids.h>
@@ -1146,6 +1144,7 @@
v = inb(0x4d1) << 8 | inb(0x4d0);
printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
}
+
#endif /* 0 */
#else
@@ -1191,6 +1190,7 @@
* Clear the IO-APIC before rebooting:
*/
clear_IO_APIC();
+
#ifndef CONFIG_XEN
disconnect_bsp_APIC();
#endif
@@ -1202,6 +1202,7 @@
*
* by Matt Domsch <Matt_Domsch@xxxxxxxx> Tue Dec 21 12:25:05 CST 1999
*/
+
#ifndef CONFIG_XEN
static void __init setup_ioapic_ids_from_mpc (void)
{
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c Tue Jan 24 16:54:34 2006
@@ -9,18 +9,15 @@
* x86_64-specific irq controller code. (e.g. i8259.c and
* io_apic.c.)
*/
+
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-/*
- * Interrupt statistics:
- */
+#include <asm/io_apic.h>
atomic_t irq_err_count;
-
#ifdef CONFIG_X86_IO_APIC
#ifdef APIC_MISMATCH_DEBUG
atomic_t irq_mis_count;
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c Tue Jan 24 16:54:34 2006
@@ -62,6 +62,7 @@
if (reload) {
#ifdef CONFIG_SMP
cpumask_t mask;
+
preempt_disable();
#endif
make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
@@ -201,6 +202,7 @@
struct user_desc ldt_info;
error = -EINVAL;
+
if (bytecount != sizeof(ldt_info))
goto out;
error = -EFAULT;
diff -r 40bb46f599d9 -r a38c292e8390
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 Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Tue Jan 24
16:54:34 2006
@@ -62,6 +62,7 @@
#include <asm-xen/xen-public/physdev.h>
#include "setup_arch_pre.h"
#include <asm/hypervisor.h>
+#include <asm-xen/xen-public/nmi.h>
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
#define end_pfn_map end_pfn
@@ -304,7 +305,6 @@
}
#endif
-
static __init void parse_cmdline_early (char ** cmdline_p)
{
char c = ' ', *to = command_line, *from = COMMAND_LINE;
@@ -379,6 +379,7 @@
acpi_skip_timer_override = 1;
#endif
#endif
+
#ifndef CONFIG_XEN
if (!memcmp(from, "nolapic", 7) ||
!memcmp(from, "disableapic", 11))
@@ -391,7 +392,8 @@
skip_ioapic_setup = 0;
ioapic_force = 1;
}
-#endif
+#endif
+
if (!memcmp(from, "mem=", 4))
parse_memopt(from+4, &from);
@@ -588,7 +590,7 @@
HYPERVISOR_vm_assist(VMASST_CMD_enable,
VMASST_TYPE_writable_pagetables);
- ARCH_SETUP
+ ARCH_SETUP
#else
ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
drive_info = DRIVE_INFO;
@@ -612,7 +614,7 @@
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
#ifdef CONFIG_XEN
- init_mm.brk = start_pfn << PAGE_SHIFT;
+ init_mm.brk = start_pfn << PAGE_SHIFT;
#else
init_mm.brk = (unsigned long) &_end;
@@ -667,7 +669,6 @@
/* reserve ebda region */
reserve_ebda_region();
#endif
-
#ifdef CONFIG_SMP
/*
@@ -790,8 +791,6 @@
}
-
-
if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
{
acpi_disabled = 1;
@@ -835,7 +834,7 @@
* and also for regions reported as reserved by the e820.
*/
probe_roms();
- e820_reserve_resources();
+ e820_reserve_resources();
#endif
request_resource(&iomem_resource, &video_ram_resource);
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c Tue Jan 24
16:54:34 2006
@@ -33,6 +33,7 @@
#ifdef CONFIG_XEN
#include <asm/hypervisor.h>
#endif
+
char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
@@ -165,7 +166,6 @@
}
#endif
-
void pda_init(int cpu)
{
struct x8664_pda *pda = &cpu_pda[cpu];
@@ -175,9 +175,10 @@
#ifndef CONFIG_XEN
wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
#else
- HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL,
- (unsigned long)(cpu_pda + cpu));
-#endif
+ HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL,
+ (unsigned long)(cpu_pda + cpu));
+#endif
+
pda->me = pda;
pda->cpunumber = cpu;
pda->irqcount = -1;
@@ -201,6 +202,7 @@
}
switch_pt();
+
pda->irqstackptr += IRQSTACKSIZE-64;
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Tue Jan 24 16:54:34 2006
@@ -30,8 +30,9 @@
#include <asm/apicdef.h>
#ifdef CONFIG_XEN
#include <asm-xen/evtchn.h>
-
-#else
+#endif
+
+#ifndef CONFIG_XEN
/*
* Smarter SMP flushing macros.
* c/o Linus Torvalds.
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c Tue Jan 24
16:54:34 2006
@@ -559,9 +559,11 @@
printk("Uhhuh. NMI received. Dazed and confused, but trying to
continue\n");
printk("You probably have a hardware problem with your RAM chips\n");
+#if 0 /* XEN */
/* Clear and disable the memory parity error line. */
reason = (reason & 0xf) | 4;
outb(reason, 0x61);
+#endif /* XEN */
}
static void io_check_error(unsigned char reason, struct pt_regs * regs)
@@ -569,12 +571,14 @@
printk("NMI: IOCK error (debug interrupt?)\n");
show_registers(regs);
+#if 0 /* XEN */
/* Re-enable the IOCK line, wait for a few seconds */
reason = (reason & 0xf) | 8;
outb(reason, 0x61);
mdelay(2000);
reason &= ~8;
outb(reason, 0x61);
+#endif /* XEN */
}
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
@@ -890,7 +894,6 @@
asmlinkage void math_state_restore(void)
{
struct task_struct *me = current;
-
/* clts(); */ /* 'clts' is done for us by Xen during virtual trap. */
if (!used_math())
diff -r 40bb46f599d9 -r a38c292e8390
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 Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Tue Jan 24 16:54:34 2006
@@ -153,7 +153,6 @@
pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
preempt_enable();
pgd += pgd_index(address);
-
printk("PGD %lx ", pgd_val(*pgd));
if (bad_address(pgd)) goto bad;
if (!pgd_present(*pgd)) goto ret;
@@ -258,7 +257,6 @@
pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
preempt_enable();
pgd += pgd_index(address);
-
pgd_ref = pgd_offset_k(address);
if (pgd_none(*pgd_ref))
return -1;
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Tue Jan 24 16:54:34 2006
@@ -40,14 +40,14 @@
#include <asm/proto.h>
#include <asm/smp.h>
+#ifndef Dprintk
+#define Dprintk(x...)
+#endif
+
extern unsigned long *contiguous_bitmap;
#if defined(CONFIG_SWIOTLB)
extern void swiotlb_init(void);
-#endif
-
-#ifndef Dprintk
-#define Dprintk(x...)
#endif
extern char _stext[];
@@ -200,9 +200,9 @@
static inline pud_t *pud_offset_u(unsigned long address)
{
- pud_t *pud = level3_user_pgt;
-
- return pud + pud_index(address);
+ pud_t *pud = level3_user_pgt;
+
+ return pud + pud_index(address);
}
static void set_pte_phys(unsigned long vaddr,
@@ -215,34 +215,27 @@
Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
- pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
-
+ pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
if (pgd_none(*pgd)) {
printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
return;
}
-
- pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
-
+ pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
if (pud_none(*pud)) {
pmd = (pmd_t *) spp_getpage();
-
- make_page_readonly(pmd);
- xen_pmd_pin(__pa(pmd));
+ make_page_readonly(pmd);
+ xen_pmd_pin(__pa(pmd));
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
if (pmd != pmd_offset(pud, 0)) {
printk("PAGETABLE BUG #01! %p <-> %p\n", pmd,
pmd_offset(pud,0));
return;
}
}
-
pmd = pmd_offset(pud, vaddr);
-
if (pmd_none(*pmd)) {
pte = (pte_t *) spp_getpage();
- make_page_readonly(pte);
-
- xen_pte_pin(__pa(pte));
+ make_page_readonly(pte);
+ xen_pte_pin(__pa(pte));
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
if (pte != pte_offset_kernel(pmd, 0)) {
printk("PAGETABLE BUG #02!\n");
@@ -252,11 +245,10 @@
new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
pte = pte_offset_kernel(pmd, vaddr);
-
if (!pte_none(*pte) &&
pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
pte_ERROR(*pte);
- set_pte(pte, new_pte);
+ set_pte(pte, new_pte);
/*
* It's enough to flush this one mapping.
@@ -284,11 +276,11 @@
if (pud_none(*pud)) {
pmd = (pmd_t *) spp_getpage();
- make_page_readonly(pmd);
- xen_pmd_pin(__pa(pmd));
+ make_page_readonly(pmd);
+ xen_pmd_pin(__pa(pmd));
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-
+
if (pmd != pmd_offset(pud, 0)) {
printk("PAGETABLE BUG #01! %p <-> %p\n", pmd,
pmd_offset(pud,0));
return;
@@ -298,8 +290,8 @@
if (pmd_none(*pmd)) {
pte = (pte_t *) spp_getpage();
- make_page_readonly(pte);
- xen_pte_pin(__pa(pte));
+ make_page_readonly(pte);
+ xen_pte_pin(__pa(pte));
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
if (pte != pte_offset_kernel(pmd, 0)) {
@@ -311,12 +303,12 @@
new_pte = pfn_pte_ma(phys >> PAGE_SHIFT, prot);
pte = pte_offset_kernel(pmd, vaddr);
- /*
- * Note that the pte page is already RO, thus we want to use
- * xen_l1_entry_update(), not set_pte().
- */
- xen_l1_entry_update(pte,
- pfn_pte_ma(phys >> PAGE_SHIFT, prot));
+ /*
+ * Note that the pte page is already RO, thus we want to use
+ * xen_l1_entry_update(), not set_pte().
+ */
+ xen_l1_entry_update(pte,
+ pfn_pte_ma(phys >> PAGE_SHIFT, prot));
/*
* It's enough to flush this one mapping.
@@ -347,7 +339,6 @@
}
}
-
/*
* At this point it only supports vsyscall area.
*/
@@ -360,18 +351,18 @@
return;
}
- set_pte_phys(address, phys, prot, SET_FIXMAP_USER);
+ set_pte_phys(address, phys, prot, SET_FIXMAP_USER);
}
unsigned long __initdata table_start, tables_space;
unsigned long get_machine_pfn(unsigned long addr)
{
- pud_t* pud = pud_offset_k(addr);
- pmd_t* pmd = pmd_offset(pud, addr);
- pte_t *pte = pte_offset_kernel(pmd, addr);
-
- return pte_mfn(*pte);
+ pud_t* pud = pud_offset_k(addr);
+ pmd_t* pmd = pmd_offset(pud, addr);
+ pte_t *pte = pte_offset_kernel(pmd, addr);
+
+ return pte_mfn(*pte);
}
static __init void *alloc_static_page(unsigned long *phys)
@@ -411,12 +402,11 @@
static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned
long end)
{
- long i, j, k;
- unsigned long paddr;
+ long i, j, k;
+ unsigned long paddr;
i = pud_index(address);
pud = pud + i;
-
for (; i < PTRS_PER_PUD; pud++, i++) {
unsigned long pmd_phys;
pmd_t *pmd;
@@ -429,38 +419,37 @@
}
pmd = alloc_static_page(&pmd_phys);
- early_make_page_readonly(pmd);
- xen_pmd_pin(pmd_phys);
+ early_make_page_readonly(pmd);
+ xen_pmd_pin(pmd_phys);
set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
-
for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
- unsigned long pte_phys;
- pte_t *pte, *pte_save;
+ unsigned long pte_phys;
+ pte_t *pte, *pte_save;
if (paddr >= end) {
for (; j < PTRS_PER_PMD; j++, pmd++)
set_pmd(pmd, __pmd(0));
break;
}
- pte = alloc_static_page(&pte_phys);
- pte_save = pte;
- for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr +=
PTE_SIZE) {
- if ((paddr >= end) ||
- ((paddr >> PAGE_SHIFT) >=
- xen_start_info->nr_pages)) {
- __set_pte(pte, __pte(0));
- continue;
- }
- if (make_readonly(paddr)) {
- __set_pte(pte,
- __pte(paddr | (_KERNPG_TABLE &
~_PAGE_RW)));
- continue;
- }
- __set_pte(pte, __pte(paddr | _KERNPG_TABLE));
- }
- pte = pte_save;
- early_make_page_readonly(pte);
- xen_pte_pin(pte_phys);
+ pte = alloc_static_page(&pte_phys);
+ pte_save = pte;
+ for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr +=
PTE_SIZE) {
+ if ((paddr >= end) ||
+ ((paddr >> PAGE_SHIFT) >=
+ xen_start_info->nr_pages)) {
+ __set_pte(pte, __pte(0));
+ continue;
+ }
+ if (make_readonly(paddr)) {
+ __set_pte(pte,
+ __pte(paddr | (_KERNPG_TABLE &
~_PAGE_RW)));
+ continue;
+ }
+ __set_pte(pte, __pte(paddr | _KERNPG_TABLE));
+ }
+ pte = pte_save;
+ early_make_page_readonly(pte);
+ xen_pte_pin(pte_phys);
set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
}
}
@@ -506,7 +495,7 @@
level3_kernel_pgt[pud_index(__START_KERNEL_map)] =
__pud(__pa_symbol(level2_kernel_pgt) |
_KERNPG_TABLE | _PAGE_USER);
- memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
+ memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
early_make_page_readonly(init_level4_pgt);
early_make_page_readonly(init_level4_user_pgt);
@@ -618,7 +607,7 @@
void zap_low_mappings(void)
{
- /* this is not required for Xen */
+ /* this is not required for Xen */
#if 0
swap_low_mappings();
#endif
@@ -629,11 +618,11 @@
{
{
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
- /* unsigned int max_dma; */
- /* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >>
PAGE_SHIFT; */
- /* if (end_pfn < max_dma) */
+ /* unsigned int max_dma; */
+ /* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >>
PAGE_SHIFT; */
+ /* if (end_pfn < max_dma) */
zones_size[ZONE_DMA] = end_pfn;
-#if 0
+#if 0
else {
zones_size[ZONE_DMA] = max_dma;
zones_size[ZONE_NORMAL] = end_pfn - max_dma;
@@ -642,16 +631,16 @@
free_area_init(zones_size);
}
- 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, sizeof(empty_zero_page));
+ 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, sizeof(empty_zero_page));
init_mm.context.pinned = 1;
#ifdef CONFIG_XEN_PHYSDEV_ACCESS
{
int i;
- /* Setup mapping of lower 1st MB */
+ /* Setup mapping of lower 1st MB */
for (i = 0; i < NR_FIX_ISAMAPS; i++)
if (xen_start_info->flags & SIF_PRIVILEGED)
set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
@@ -701,7 +690,7 @@
static inline int page_is_ram (unsigned long pagenr)
{
- return 1;
+ return 1;
}
static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
@@ -790,10 +779,10 @@
void free_initmem(void)
{
#ifdef __DO_LATER__
- /*
- * Some pages can be pinned, but some are not. Unpinning such pages
- * triggers BUG().
- */
+ /*
+ * Some pages can be pinned, but some are not. Unpinning such pages
+ * triggers BUG().
+ */
unsigned long addr;
addr = (unsigned long)(&__init_begin);
@@ -801,12 +790,12 @@
ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1);
memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE);
- xen_pte_unpin(__pa(addr));
- make_page_writable(__va(__pa(addr)));
- /*
- * Make pages from __PAGE_OFFSET address as well
- */
- make_page_writable((void *)addr);
+ xen_pte_unpin(__pa(addr));
+ make_page_writable(__va(__pa(addr)));
+ /*
+ * Make pages from __PAGE_OFFSET address as well
+ */
+ make_page_writable((void *)addr);
free_page(addr);
totalram_pages++;
}
@@ -856,7 +845,7 @@
if (pgd_none(*pgd))
return 0;
- pud = pud_offset_k(addr);
+ pud = pud_offset_k(addr);
if (pud_none(*pud))
return 0;
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Tue Jan 24
16:54:34 2006
@@ -544,7 +544,7 @@
kfree(pending_grant_handles);
kfree(pending_vaddrs);
printk("%s: out of memory\n", __FUNCTION__);
- return -1;
+ return -ENOMEM;
}
blkif_interface_init();
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jan 24 16:54:34 2006
@@ -19,16 +19,8 @@
#include <asm-xen/gnttab.h>
#include <asm-xen/driver_util.h>
-#if 0
-#define ASSERT(_p) \
- if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
- __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
struct vbd {
blkif_vdev_t handle; /* what the domain refers to this vbd as */
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c Tue Jan 24 16:54:34 2006
@@ -11,7 +11,6 @@
#define vbd_sz(_v) ((_v)->bdev->bd_part ? \
(_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
-#define bdev_put(_b) blkdev_put(_b)
unsigned long vbd_size(struct vbd *vbd)
{
@@ -69,7 +68,7 @@
void vbd_free(struct vbd *vbd)
{
if (vbd->bdev)
- bdev_put(vbd->bdev);
+ blkdev_put(vbd->bdev);
vbd->bdev = NULL;
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jan 24 16:54:34 2006
@@ -24,12 +24,9 @@
#include <asm-xen/xenbus.h>
#include "common.h"
-
-#if 0
#undef DPRINTK
#define DPRINTK(fmt, args...) \
- printk("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#endif
+ pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__,
##args)
struct backend_info
@@ -302,7 +299,7 @@
*/
static void connect(struct backend_info *be)
{
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
int err;
struct xenbus_device *dev = be->dev;
@@ -310,10 +307,9 @@
/* Supply the information about the device the frontend needs */
again:
- xbt = xenbus_transaction_start();
-
- if (IS_ERR(xbt)) {
- err = PTR_ERR(xbt);
+ err = xenbus_transaction_start(&xbt);
+
+ if (err) {
xenbus_dev_fatal(dev, err, "starting transaction");
return;
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Jan 24
16:54:34 2006
@@ -35,14 +35,6 @@
* IN THE SOFTWARE.
*/
-#if 1
-#define ASSERT(p) \
- if (!(p)) { printk("Assertion '%s' failed, line %d, file %s", #p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p)
-#endif
-
#include <linux/version.h>
#include "block.h"
#include <linux/cdrom.h>
@@ -161,7 +153,7 @@
struct blkfront_info *info)
{
const char *message = NULL;
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
int err;
/* Create shared ring, alloc event channel. */
@@ -170,8 +162,8 @@
goto out;
again:
- xbt = xenbus_transaction_start();
- if (IS_ERR(xbt)) {
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
xenbus_dev_fatal(dev, err, "starting transaction");
goto destroy_blkring;
}
@@ -551,7 +543,7 @@
lsect = fsect + (bvec->bv_len >> 9) - 1;
/* install a grant reference. */
ref = gnttab_claim_grant_reference(&gref_head);
- ASSERT(ref != -ENOSPC);
+ BUG_ON(ref == -ENOSPC);
gnttab_grant_foreign_access_ref(
ref,
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jan 24 16:54:34 2006
@@ -69,11 +69,7 @@
#define WPRINTK(fmt, args...) ((void)0)
#endif
-#if 0
-#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
-#else
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug ( _f , ## _a )
#if 0
#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Tue Jan 24 16:54:34 2006
@@ -19,16 +19,8 @@
#include <asm-xen/gnttab.h>
#include <asm-xen/driver_util.h>
-#if 0
-#define ASSERT(_p) \
- if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
- __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
#define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jan 24 16:54:34 2006
@@ -22,16 +22,8 @@
#include <asm-xen/gnttab.h>
#include <asm-xen/driver_util.h>
-#if 0
-#define ASSERT(_p) \
- if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
- __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
#define IPRINTK(fmt, args...) \
printk(KERN_INFO "xen_net: " fmt, ##args)
#define WPRINTK(fmt, args...) \
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Tue Jan 24
16:54:34 2006
@@ -27,6 +27,7 @@
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/ethtool.h>
#include <net/dst.h>
static int nloopbacks = 8;
@@ -122,6 +123,12 @@
/*dev->mtu = 16*1024;*/
}
+static struct ethtool_ops network_ethtool_ops =
+{
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+};
+
static int __init make_loopback(int i)
{
struct net_device *dev1, *dev2;
@@ -140,6 +147,8 @@
dev1->features |= NETIF_F_NO_CSUM;
dev2->features |= NETIF_F_IP_CSUM;
+
+ SET_ETHTOOL_OPS(dev2, &network_ethtool_ops);
/*
* Initialise a dummy MAC address for the 'dummy backend' interface. We
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Jan 24
16:54:34 2006
@@ -120,7 +120,7 @@
{
netif_t *netif = netdev_priv(dev);
- ASSERT(skb->dev == dev);
+ BUG_ON(skb->dev != dev);
/* Drop the packet if the target domain has no receive buffers. */
if (!netif->active ||
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Jan 24
16:54:34 2006
@@ -154,13 +154,8 @@
};
#endif
-#ifdef DEBUG
-#define DPRINTK(fmt, args...) \
- printk(KERN_ALERT "netfront (%s:%d) " fmt, __FUNCTION__, \
- __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
+#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \
+ __FUNCTION__, __LINE__, ##args)
#define IPRINTK(fmt, args...) \
printk(KERN_INFO "netfront: " fmt, ##args)
#define WPRINTK(fmt, args...) \
@@ -260,7 +255,7 @@
struct netfront_info *info)
{
const char *message;
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
int err;
err = xen_net_read_mac(dev, info->mac);
@@ -275,8 +270,8 @@
goto out;
again:
- xbt = xenbus_transaction_start();
- if (IS_ERR(xbt)) {
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
xenbus_dev_fatal(dev, err, "starting transaction");
goto destroy_ring;
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jan 24 16:54:34 2006
@@ -17,16 +17,8 @@
#include <asm/io.h>
#include <asm/pgalloc.h>
-#if 0
-#define ASSERT(_p) \
- if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
- __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
typedef struct tpmif_st {
struct list_head tpmif_list;
@@ -84,11 +76,6 @@
#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
#endif /* __TPMIF__BACKEND__COMMON_H__ */
/*
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jan 24 16:54:34 2006
@@ -78,7 +78,7 @@
memset(be, 0, sizeof(*be));
- be->is_instance_set = FALSE;
+ be->is_instance_set = 0;
be->dev = dev;
dev->data = be;
@@ -89,7 +89,7 @@
goto fail;
}
- err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
+ err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
if (err) {
goto fail;
}
@@ -109,7 +109,7 @@
= container_of(watch, struct backend_info, backend_watch);
struct xenbus_device *dev = be->dev;
- err = xenbus_scanf(NULL, dev->nodename,
+ err = xenbus_scanf(XBT_NULL, dev->nodename,
"instance","%li", &instance);
if (XENBUS_EXIST_ERR(err)) {
return;
@@ -120,7 +120,7 @@
return;
}
- if (be->is_instance_set != FALSE && be->instance != instance) {
+ if (be->is_instance_set != 0 && be->instance != instance) {
printk(KERN_WARNING
"tpmback: changing instance (from %ld to %ld) "
"not allowed.\n",
@@ -128,7 +128,7 @@
return;
}
- if (be->is_instance_set == FALSE) {
+ if (be->is_instance_set == 0) {
be->tpmif = tpmif_find(dev->otherend_id,
instance);
if (IS_ERR(be->tpmif)) {
@@ -138,7 +138,7 @@
return;
}
be->instance = instance;
- be->is_instance_set = TRUE;
+ be->is_instance_set = 1;
/*
* There's an unfortunate problem:
@@ -177,7 +177,7 @@
break;
case XenbusStateClosing:
- xenbus_switch_state(dev, NULL, XenbusStateClosing);
+ xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
break;
case XenbusStateClosed:
@@ -230,15 +230,14 @@
static void connect(struct backend_info *be)
{
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
int err;
struct xenbus_device *dev = be->dev;
unsigned long ready = 1;
again:
- xbt = xenbus_transaction_start();
- if (IS_ERR(xbt)) {
- err = PTR_ERR(xbt);
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
xenbus_dev_fatal(be->dev, err, "starting transaction");
return;
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Tue Jan 24
16:54:34 2006
@@ -54,14 +54,6 @@
#undef DEBUG
-#if 1
-#define ASSERT(_p) \
- if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
- __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p)
-#endif
-
/* locally visible variables */
static grant_ref_t gref_head;
static struct tpm_private my_private;
@@ -80,12 +72,8 @@
const u8 * buf, size_t count, int userbuffer,
void *remember);
-#if DEBUG
#define DPRINTK(fmt, args...) \
- printk(KERN_ALERT "xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__,
##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
+ pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
#define IPRINTK(fmt, args...) \
printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
#define WPRINTK(fmt, args...) \
@@ -102,11 +90,8 @@
copied = txb->size;
}
if (isuserbuffer) {
- if (copy_from_user(txb->data,
- src,
- copied)) {
+ if (copy_from_user(txb->data, src, copied))
return -EFAULT;
- }
} else {
memcpy(txb->data, src, copied);
}
@@ -196,15 +181,12 @@
static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
const void *ptr)
{
- int rc;
+ int rc = 0;
down(&upperlayer_lock);
- if (upperlayer_tpmfe && upperlayer_tpmfe->receive) {
+ if (upperlayer_tpmfe && upperlayer_tpmfe->receive)
rc = upperlayer_tpmfe->receive(buf, count, ptr);
- } else {
- rc = 0;
- }
up(&upperlayer_lock);
return rc;
@@ -253,8 +235,8 @@
static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
{
- tpmif_set_connected_state(tp, FALSE);
- if ( tp->tx != NULL ) {
+ tpmif_set_connected_state(tp, 0);
+ if (tp->tx != NULL) {
gnttab_end_foreign_access(info->ring_ref, 0,
(unsigned long)tp->tx);
tp->tx = NULL;
@@ -271,7 +253,7 @@
{
const char *message = NULL;
int err;
- struct xenbus_transaction *xbt;
+ xenbus_transaction_t xbt;
err = setup_tpmring(dev, info);
if (err) {
@@ -280,8 +262,8 @@
}
again:
- xbt = xenbus_transaction_start();
- if (IS_ERR(xbt)) {
+ err = xenbus_transaction_start(&xbt);
+ if (err) {
xenbus_dev_fatal(dev, err, "starting transaction");
goto destroy_tpmring;
}
@@ -341,15 +323,15 @@
break;
case XenbusStateConnected:
- tpmif_set_connected_state(tp, TRUE);
+ tpmif_set_connected_state(tp, 1);
break;
case XenbusStateClosing:
- tpmif_set_connected_state(tp, FALSE);
+ tpmif_set_connected_state(tp, 0);
break;
case XenbusStateClosed:
- if (tp->is_suspended == FALSE) {
+ if (tp->is_suspended == 0) {
device_unregister(&dev->dev);
}
break;
@@ -364,7 +346,7 @@
struct tpmfront_info *info;
int handle;
- err = xenbus_scanf(NULL, dev->nodename,
+ err = xenbus_scanf(XBT_NULL, dev->nodename,
"handle", "%i", &handle);
if (XENBUS_EXIST_ERR(err))
return err;
@@ -409,20 +391,19 @@
tpmfront_suspend(struct xenbus_device *dev)
{
struct tpm_private *tp = &my_private;
- u32 ctr = 0;
+ u32 ctr;
/* lock, so no app can send */
down(&suspend_lock);
- tp->is_suspended = TRUE;
-
- while (atomic_read(&tp->tx_busy) && ctr <= 25) {
+ tp->is_suspended = 1;
+
+ for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
if ((ctr % 10) == 0)
printk("TPM-FE [INFO]: Waiting for outstanding
request.\n");
/*
* Wait for a request to be responded to.
*/
interruptible_sleep_on_timeout(&tp->wait_q, 100);
- ctr++;
}
if (atomic_read(&tp->tx_busy)) {
@@ -440,16 +421,13 @@
tpmfront_resume(struct xenbus_device *dev)
{
struct tpmfront_info *info = dev->data;
- int err = talk_to_backend(dev, info);
-
-
- return err;
+ return talk_to_backend(dev, info);
}
static void
tpmif_connect(u16 evtchn, domid_t domid)
{
- int err = 0;
+ int err;
struct tpm_private *tp = &my_private;
tp->evtchn = evtchn;
@@ -493,12 +471,8 @@
{
unsigned int i;
- i = 0;
- while (i < TPMIF_TX_RING_SIZE) {
+ for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
tp->tx_buffers[i] = tx_buffer_alloc();
- i++;
- }
-
return 1;
}
@@ -521,9 +495,7 @@
goto exit;
}
- i = 0;
- while (i < TPMIF_TX_RING_SIZE &&
- offset < received) {
+ for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
struct tx_buffer *txb = tp->tx_buffers[i];
tpmif_tx_request_t *tx;
unsigned int tocopy;
@@ -539,7 +511,6 @@
gnttab_release_grant_reference(&gref_head, tx->ref);
offset += tocopy;
- i++;
}
tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
@@ -583,19 +554,18 @@
return -EBUSY;
}
- if (tp->is_connected != TRUE) {
+ if (tp->is_connected != 1) {
spin_unlock_irq(&tp->tx_lock);
return -EIO;
}
- i = 0;
- while (count > 0 && i < TPMIF_TX_RING_SIZE) {
+ for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
struct tx_buffer *txb = tp->tx_buffers[i];
int copied;
if (NULL == txb) {
- DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
- DPRINTK("Not transmitting anything!\n");
+ DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
+ "Not transmitting anything!\n", i);
spin_unlock_irq(&tp->tx_lock);
return -EFAULT;
}
@@ -603,6 +573,7 @@
isuserbuffer);
if (copied < 0) {
/* An error occurred */
+ spin_unlock_irq(&tp->tx_lock);
return copied;
}
count -= copied;
@@ -618,9 +589,10 @@
txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
/* get the granttable reference for this page */
- tx->ref = gnttab_claim_grant_reference( &gref_head );
-
- if(-ENOSPC == tx->ref ) {
+ tx->ref = gnttab_claim_grant_reference(&gref_head);
+
+ if (-ENOSPC == tx->ref) {
+ spin_unlock_irq(&tp->tx_lock);
DPRINTK(" Grant table claim reference failed in func:%s
line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
return -ENOSPC;
}
@@ -628,7 +600,6 @@
tp->backend_id,
(tx->addr >> PAGE_SHIFT),
0 /*RW*/);
- i++;
wmb();
}
@@ -672,7 +643,7 @@
* should disconnect - assumption is that we will resume
* The semaphore keeps apps from sending.
*/
- if (is_connected == FALSE && tp->is_suspended == TRUE) {
+ if (is_connected == 0 && tp->is_suspended == 1) {
return;
}
@@ -681,8 +652,8 @@
* after being suspended - now resuming.
* This also removes the suspend state.
*/
- if (is_connected == TRUE && tp->is_suspended == TRUE) {
- tp->is_suspended = FALSE;
+ if (is_connected == 1 && tp->is_suspended == 1) {
+ tp->is_suspended = 0;
/* unlock, so apps can resume sending */
up(&suspend_lock);
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Tue Jan 24
16:54:34 2006
@@ -1,10 +1,5 @@
#ifndef TPM_FRONT_H
#define TPM_FRONT_H
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
struct tpm_private {
tpmif_tx_interface_t *tx;
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Tue Jan 24
16:54:34 2006
@@ -34,13 +34,8 @@
/* xenbus_probe.c */
extern char *kasprintf(const char *fmt, ...);
-#if 0
#define DPRINTK(fmt, args...) \
- printk("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
-
+ pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__,
##args)
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
struct xenbus_watch *watch,
@@ -87,7 +82,7 @@
int xenbus_switch_state(struct xenbus_device *dev,
- struct xenbus_transaction *xbt,
+ xenbus_transaction_t xbt,
XenbusState state)
{
/* We check whether the state is currently set to the given value, and
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Jan 24
16:54:34 2006
@@ -47,7 +47,7 @@
struct xenbus_dev_transaction {
struct list_head list;
- struct xenbus_transaction *handle;
+ xenbus_transaction_t handle;
};
struct xenbus_dev_data {
@@ -147,13 +147,11 @@
}
if (u->u.msg.type == XS_TRANSACTION_START) {
- trans->handle = (struct xenbus_transaction *)
- simple_strtoul(reply, NULL, 0);
+ trans->handle = simple_strtoul(reply, NULL, 0);
list_add(&trans->list, &u->transactions);
} else if (u->u.msg.type == XS_TRANSACTION_END) {
list_for_each_entry(trans, &u->transactions, list)
- if ((unsigned long)trans->handle ==
- (unsigned long)u->u.msg.tx_id)
+ if (trans->handle == u->u.msg.tx_id)
break;
BUG_ON(&trans->list == &u->transactions);
list_del(&trans->list);
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Jan 24
16:54:34 2006
@@ -27,12 +27,8 @@
* IN THE SOFTWARE.
*/
-#if 0
#define DPRINTK(fmt, args...) \
- printk("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
+ pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
#include <linux/kernel.h>
#include <linux/err.h>
@@ -470,12 +466,17 @@
DPRINTK("%s", info->nodename);
- if (!strncmp(xendev->nodename, info->nodename, len)) {
- info->dev = xendev;
- get_device(dev);
- return 1;
- }
- return 0;
+ /* Match the info->nodename path, or any subdirectory of that path. */
+ if (strncmp(xendev->nodename, info->nodename, len))
+ return 0;
+
+ /* If the node name is longer, ensure it really is a subdirectory. */
+ if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
+ return 0;
+
+ info->dev = xendev;
+ get_device(dev);
+ return 1;
}
static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Jan 24
16:54:34 2006
@@ -190,7 +190,7 @@
}
/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction *t,
+static void *xs_talkv(xenbus_transaction_t t,
enum xsd_sockmsg_type type,
const struct kvec *iovec,
unsigned int num_vecs,
@@ -201,7 +201,7 @@
unsigned int i;
int err;
- msg.tx_id = (u32)(unsigned long)t;
+ msg.tx_id = t;
msg.req_id = 0;
msg.type = type;
msg.len = 0;
@@ -242,7 +242,7 @@
}
/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction *t,
+static void *xs_single(xenbus_transaction_t t,
enum xsd_sockmsg_type type,
const char *string,
unsigned int *len)
@@ -309,7 +309,7 @@
return ret;
}
-char **xenbus_directory(struct xenbus_transaction *t,
+char **xenbus_directory(xenbus_transaction_t t,
const char *dir, const char *node, unsigned int *num)
{
char *strings, *path;
@@ -329,7 +329,7 @@
EXPORT_SYMBOL(xenbus_directory);
/* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction *t,
+int xenbus_exists(xenbus_transaction_t t,
const char *dir, const char *node)
{
char **d;
@@ -347,7 +347,7 @@
* Returns a kmalloced value: call free() on it after use.
* len indicates length in bytes.
*/
-void *xenbus_read(struct xenbus_transaction *t,
+void *xenbus_read(xenbus_transaction_t t,
const char *dir, const char *node, unsigned int *len)
{
char *path;
@@ -366,7 +366,7 @@
/* Write the value of a single file.
* Returns -err on failure.
*/
-int xenbus_write(struct xenbus_transaction *t,
+int xenbus_write(xenbus_transaction_t t,
const char *dir, const char *node, const char *string)
{
const char *path;
@@ -389,7 +389,7 @@
EXPORT_SYMBOL(xenbus_write);
/* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction *t,
+int xenbus_mkdir(xenbus_transaction_t t,
const char *dir, const char *node)
{
char *path;
@@ -406,7 +406,7 @@
EXPORT_SYMBOL(xenbus_mkdir);
/* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
+int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node)
{
char *path;
int ret;
@@ -424,30 +424,28 @@
/* Start a transaction: changes by others will not be seen during this
* transaction, and changes will not be visible to others until end.
*/
-struct xenbus_transaction *xenbus_transaction_start(void)
+int xenbus_transaction_start(xenbus_transaction_t *t)
{
char *id_str;
- unsigned long id;
down_read(&xs_state.suspend_mutex);
id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL);
if (IS_ERR(id_str)) {
up_read(&xs_state.suspend_mutex);
- return (struct xenbus_transaction *)id_str;
- }
-
- id = simple_strtoul(id_str, NULL, 0);
+ return PTR_ERR(id_str);
+ }
+
+ *t = simple_strtoul(id_str, NULL, 0);
kfree(id_str);
-
- return (struct xenbus_transaction *)id;
+ return 0;
}
EXPORT_SYMBOL(xenbus_transaction_start);
/* End a transaction.
* If abandon is true, transaction is discarded instead of committed.
*/
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
+int xenbus_transaction_end(xenbus_transaction_t t, int abort)
{
char abortstr[2];
int err;
@@ -466,7 +464,7 @@
EXPORT_SYMBOL(xenbus_transaction_end);
/* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction *t,
+int xenbus_scanf(xenbus_transaction_t t,
const char *dir, const char *node, const char *fmt, ...)
{
va_list ap;
@@ -489,7 +487,7 @@
EXPORT_SYMBOL(xenbus_scanf);
/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
+int xenbus_printf(xenbus_transaction_t t,
const char *dir, const char *node, const char *fmt, ...)
{
va_list ap;
@@ -515,7 +513,7 @@
EXPORT_SYMBOL(xenbus_printf);
/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
+int xenbus_gather(xenbus_transaction_t t, const char *dir, ...)
{
va_list ap;
const char *name;
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 24
16:54:34 2006
@@ -32,6 +32,7 @@
#include <asm-xen/xen-public/xen.h>
#include <asm-xen/xen-public/sched.h>
+#include <asm-xen/xen-public/nmi.h>
#define _hypercall0(type, name) \
({ \
@@ -300,6 +301,14 @@
SHUTDOWN_suspend, srec);
}
+static inline int
+HYPERVISOR_nmi_op(
+ unsigned long op,
+ unsigned long arg)
+{
+ return _hypercall2(int, nmi_op, op, arg);
+}
+
#endif /* __HYPERCALL_H__ */
/*
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
Tue Jan 24 16:54:34 2006
@@ -29,6 +29,7 @@
extern void hypervisor_callback(void);
extern void failsafe_callback(void);
+extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
@@ -36,5 +37,7 @@
__KERNEL_CS, (unsigned long)hypervisor_callback,
__KERNEL_CS, (unsigned long)failsafe_callback);
+ HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
+
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Tue Jan
10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Tue Jan
24 16:54:34 2006
@@ -287,9 +287,9 @@
}
static inline int
-HYPERVISOR_switch_to_user(void)
-{
- return _hypercall0(int, switch_to_user);
+HYPERVISOR_iret(void)
+{
+ return _hypercall0(int, iret);
}
static inline int
@@ -305,6 +305,14 @@
{
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
+}
+
+static inline int
+HYPERVISOR_nmi_op(
+ unsigned long op,
+ unsigned long arg)
+{
+ return _hypercall2(int, nmi_op, op, arg);
}
#endif /* __HYPERCALL_H__ */
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h
---
a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h
Tue Jan 10 15:21:00 2006
+++
b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h
Tue Jan 24 16:54:34 2006
@@ -35,6 +35,7 @@
extern void hypervisor_callback(void);
extern void failsafe_callback(void);
+extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
@@ -43,5 +44,9 @@
(unsigned long) failsafe_callback,
(unsigned long) system_call);
+#ifdef CONFIG_X86_LOCAL_APIC
+ HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
+#endif
+
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
}
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h Tue Jan 10
15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h Tue Jan 24
16:54:34 2006
@@ -417,12 +417,7 @@
Other CPUs get synced lazily via the page fault handler. */
static inline pud_t *pud_offset_k(unsigned long address)
{
- unsigned long addr;
-
- addr = pgd_val(init_level4_pgt[pud_index(address)]);
- addr &= PHYSICAL_PAGE_MASK; /* machine physical */
- addr = machine_to_phys(addr);
- return __pud_offset_k((pud_t *)__va(addr), address);
+ return pud_offset(pgd_offset_k(address), address);
}
/* PMD - Level 2 access */
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Jan 24 16:54:34 2006
@@ -37,7 +37,7 @@
#include <asm-xen/xen-public/io/xenbus.h>
#include <asm-xen/xen-public/io/xs_wire.h>
-#define XBT_NULL NULL
+#define XBT_NULL 0
/* Register callback to watch this node. */
struct xenbus_watch
@@ -102,35 +102,35 @@
int xenbus_register_backend(struct xenbus_driver *drv);
void xenbus_unregister_driver(struct xenbus_driver *drv);
-struct xenbus_transaction;
-
-char **xenbus_directory(struct xenbus_transaction *t,
+typedef u32 xenbus_transaction_t;
+
+char **xenbus_directory(xenbus_transaction_t t,
const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction *t,
+void *xenbus_read(xenbus_transaction_t t,
const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction *t,
+int xenbus_write(xenbus_transaction_t t,
const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction *t,
+int xenbus_mkdir(xenbus_transaction_t t,
const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction *t,
+int xenbus_exists(xenbus_transaction_t t,
const char *dir, const char *node);
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
-struct xenbus_transaction *xenbus_transaction_start(void);
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
+int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node);
+int xenbus_transaction_start(xenbus_transaction_t *t);
+int xenbus_transaction_end(xenbus_transaction_t t, int abort);
/* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(struct xenbus_transaction *t,
+int xenbus_scanf(xenbus_transaction_t t,
const char *dir, const char *node, const char *fmt, ...)
__attribute__((format(scanf, 4, 5)));
/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
+int xenbus_printf(xenbus_transaction_t t,
const char *dir, const char *node, const char *fmt, ...)
__attribute__((format(printf, 4, 5)));
/* Generic read function: NULL-terminated triples of name,
* sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
+int xenbus_gather(xenbus_transaction_t t, const char *dir, ...);
/* notifer routines for when the xenstore comes up */
int register_xenstore_notifier(struct notifier_block *nb);
@@ -196,7 +196,7 @@
* XenbusStateClosing, and the error will be saved in the store.
*/
int xenbus_switch_state(struct xenbus_device *dev,
- struct xenbus_transaction *xbt,
+ xenbus_transaction_t xbt,
XenbusState new_state);
diff -r 40bb46f599d9 -r a38c292e8390 tools/examples/xmexample.vti
--- a/tools/examples/xmexample.vti Tue Jan 10 15:21:00 2006
+++ b/tools/examples/xmexample.vti Tue Jan 24 16:54:34 2006
@@ -21,7 +21,7 @@
memory = 256
# A name for your domain. All domains must have different names.
-name = "ExampleVMXDomain"
+name = "ExampleVTIDomain"
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
@@ -30,7 +30,11 @@
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
-#vif = [ 'mac=00:16:3e:00:00:11, bridge=xen-br0' ]
+#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+# type=ioemu specify the NIC is an ioemu device not netfront
+vif = [ 'type=ioemu, bridge=xenbr0' ]
+# for multiple NICs in device model, 3 in this example
+#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
@@ -53,7 +57,7 @@
#============================================================================
# New stuff
-device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm.debug'
+device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
# Advanced users only. Don't touch if you don't know what you're doing
memmap = '/usr/lib/xen/boot/mem-map.sxp'
diff -r 40bb46f599d9 -r a38c292e8390 tools/firmware/vmxassist/acpi_madt.c
--- a/tools/firmware/vmxassist/acpi_madt.c Tue Jan 10 15:21:00 2006
+++ b/tools/firmware/vmxassist/acpi_madt.c Tue Jan 24 16:54:34 2006
@@ -55,7 +55,6 @@
get_hvm_info_table(void)
{
struct hvm_info_table *t;
- int i;
if (table != NULL)
return table;
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/audio/audio.c
--- a/tools/ioemu/audio/audio.c Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/audio/audio.c Tue Jan 24 16:54:34 2006
@@ -257,11 +257,11 @@
switch (hw->fmt) {
case AUD_FMT_S16:
case AUD_FMT_S8:
- memset (buf, len << hw->shift, 0x00);
+ memset (buf, 0x00, len << hw->shift);
break;
case AUD_FMT_U8:
- memset (buf, len << hw->shift, 0x80);
+ memset (buf, 0x80, len << hw->shift);
break;
case AUD_FMT_U16:
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/audio/noaudio.c
--- a/tools/ioemu/audio/noaudio.c Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/audio/noaudio.c Tue Jan 24 16:54:34 2006
@@ -41,7 +41,6 @@
{
NoVoice *no = (NoVoice *) hw;
int rpos, live, decr, samples;
- uint8_t *dst;
st_sample_t *src;
int64_t now = qemu_get_clock (vm_clock);
int64_t ticks = now - no->old_ticks;
@@ -82,7 +81,6 @@
static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
{
- NoVoice *no = (NoVoice *) hw;
hw->freq = freq;
hw->nchannels = nchannels;
hw->fmt = fmt;
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/cpu.h
--- a/tools/ioemu/cpu.h Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/cpu.h Tue Jan 24 16:54:34 2006
@@ -63,6 +63,9 @@
/* MSDOS compatibility mode FPU exception support */
void cpu_set_ferr(CPUX86State *s);
+/* helper2.c */
+void cpu_x86_set_a20(CPUX86State *env, int a20_state);
+
#if defined(__i386__) || defined(__x86_64__)
#define TARGET_PAGE_BITS 12
#elif defined(__ia64__)
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/hw/pc.c Tue Jan 24 16:54:34 2006
@@ -382,8 +382,6 @@
{
char buf[1024];
int ret, linux_boot, initrd_size, i, nb_nics1;
- unsigned long bios_offset, vga_bios_offset;
- int bios_size, isa_bios_size;
PCIBus *pci_bus;
extern void * shared_vram;
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/vl.c Tue Jan 24 16:54:34 2006
@@ -1204,7 +1204,7 @@
return -1;
}
strcat(path, "/console/tty");
- if (!xs_write(xs, NULL, path, pts, strlen(pts))) {
+ if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
fprintf(logfile, "xs_write for console fail");
return -1;
}
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/vl.h Tue Jan 24 16:54:34 2006
@@ -354,6 +354,9 @@
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
+/* port-e9.c */
+void port_e9_init(void);
+
/* block.c */
typedef struct BlockDriverState BlockDriverState;
typedef struct BlockDriver BlockDriver;
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_ia64_stubs.c Tue Jan 24 16:54:34 2006
@@ -23,7 +23,8 @@
}
int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
- uint32_t max_factor, uint32_t flags, int (*suspend)(void))
+ uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+ int (*suspend)(int domid))
{
PERROR("xc_linux_save not implemented\n");
return -1;
@@ -664,15 +665,7 @@
goto error_out;
}
- if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ){
- PERROR("Could not get vcpu context");
- goto error_out;
- }
-
- if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) {
- ERROR("Domain is already constructed");
- goto error_out;
- }
+ memset(ctxt, 0, sizeof(*ctxt));
if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image,
image_size,
control_evtchn, store_evtchn, store_mfn ) < 0 ){
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_linux_build.c Tue Jan 24 16:54:34 2006
@@ -33,10 +33,8 @@
#endif
#ifdef __ia64__
-#define already_built(ctxt) (0)
#define get_tot_pages xc_get_max_pages
#else
-#define already_built(ctxt) ((ctxt)->ctrlreg[3] != 0)
#define get_tot_pages xc_get_tot_pages
#endif
@@ -800,17 +798,7 @@
goto error_out;
}
- if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
- {
- PERROR("Could not get vcpu context");
- goto error_out;
- }
-
- if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) || already_built(ctxt) )
- {
- ERROR("Domain is already constructed");
- goto error_out;
- }
+ memset(ctxt, 0, sizeof(*ctxt));
if ( setup_guest(xc_handle, domid, image, image_size,
initrd_gfd, initrd_size, nr_pages,
@@ -865,6 +853,8 @@
ctxt->user_regs.esi = vstartinfo_start;
ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
+ ctxt->flags = VGCF_IN_KERNEL;
+
/* FPU is set up to default initial state. */
memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_linux_restore.c Tue Jan 24 16:54:34 2006
@@ -170,13 +170,6 @@
}
- /* Only have to worry about vcpu 0 even for SMP */
- if (xc_vcpu_getcontext( xc_handle, dom, 0, &ctxt)) {
- ERR("Could not get vcpu context");
- goto out;
- }
-
-
/* Read the saved P2M frame list */
if(!(p2m_frame_list = malloc(P2M_FL_SIZE))) {
ERR("Couldn't allocate p2m_frame_list array");
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_vmx_build.c Tue Jan 24 16:54:34 2006
@@ -651,18 +651,7 @@
goto error_out;
}
- if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
- {
- PERROR("Could not get vcpu context");
- goto error_out;
- }
-
- if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
- (ctxt->ctrlreg[3] != 0) )
- {
- ERROR("Domain is already constructed");
- goto error_out;
- }
+ memset(ctxt, 0, sizeof(*ctxt));
if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
ctxt, op.u.getdomaininfo.shared_info_frame,
control_evtchn,
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xenguest.h Tue Jan 24 16:54:34 2006
@@ -21,9 +21,9 @@
* @parm dom the id of the domain
* @return 0 on success, -1 on failure
*/
-int xc_linux_save(int xc_handle, int fd, uint32_t dom, uint32_t max_iters,
+int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
- int (*suspend)(int));
+ int (*suspend)(int domid));
/**
diff -r 40bb46f599d9 -r a38c292e8390 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Tue Jan 10 15:21:00 2006
+++ b/tools/python/xen/lowlevel/xs/xs.c Tue Jan 24 16:54:34 2006
@@ -66,7 +66,7 @@
static int parse_transaction_path(XsHandle *self, PyObject *args,
struct xs_handle **xh,
- struct xs_transaction_handle **th,
+ xs_transaction_t *th,
char **path);
@@ -83,7 +83,7 @@
static PyObject *xspy_read(XsHandle *self, PyObject *args)
{
struct xs_handle *xh;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *path;
char *xsval;
@@ -120,7 +120,7 @@
{
static char *arg_spec = "sss#";
struct xs_handle *xh = xshandle(self);
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *thstr;
char *path;
char *data;
@@ -132,7 +132,7 @@
if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path, &data, &data_n))
return NULL;
- th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+ th = strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
result = xs_write(xh, th, path, data, data_n);
@@ -155,7 +155,7 @@
static PyObject *xspy_ls(XsHandle *self, PyObject *args)
{
struct xs_handle *xh;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *path;
char **xsval;
@@ -193,7 +193,7 @@
static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
{
struct xs_handle *xh;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *path;
bool result;
@@ -221,7 +221,7 @@
static PyObject *xspy_rm(XsHandle *self, PyObject *args)
{
struct xs_handle *xh;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *path;
bool result;
@@ -256,7 +256,7 @@
unsigned int perms_n = 0;
int i;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *thstr;
if (!xh)
@@ -264,7 +264,7 @@
if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path))
return NULL;
- th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+ th = strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
perms = xs_get_permissions(xh, th, path, &perms_n);
@@ -312,7 +312,7 @@
int xsperms_n;
PyObject *tuple0 = NULL;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *thstr;
if (!xh)
@@ -320,7 +320,7 @@
if (!PyArg_ParseTuple(args, "ssO", &thstr, &path, &perms))
goto exit;
- th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+ th = strtoul(thstr, NULL, 16);
if (!PyList_Check(perms)) {
PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
@@ -509,7 +509,7 @@
static PyObject *xspy_transaction_start(XsHandle *self)
{
struct xs_handle *xh = xshandle(self);
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char thstr[MAX_STRLEN(unsigned long) + 1];
if (!xh)
@@ -519,7 +519,7 @@
th = xs_transaction_start(xh);
Py_END_ALLOW_THREADS
- if (th == NULL) {
+ if (th == XBT_NULL) {
PyErr_SetFromErrno(PyExc_RuntimeError);
return NULL;
}
@@ -547,7 +547,7 @@
struct xs_handle *xh = xshandle(self);
bool result;
- struct xs_transaction_handle *th;
+ xs_transaction_t th;
char *thstr;
if (!xh)
@@ -556,7 +556,7 @@
&thstr, &abort))
return NULL;
- th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+ th = strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
result = xs_transaction_end(xh, th, abort);
@@ -727,7 +727,7 @@
*/
static int parse_transaction_path(XsHandle *self, PyObject *args,
struct xs_handle **xh,
- struct xs_transaction_handle **th,
+ xs_transaction_t *th,
char **path)
{
char *thstr;
@@ -740,7 +740,7 @@
if (!PyArg_ParseTuple(args, "ss", &thstr, path))
return 0;
- *th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+ *th = strtoul(thstr, NULL, 16);
return 1;
}
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm/Makefile
--- a/tools/vtpm/Makefile Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm/Makefile Tue Jan 24 16:54:34 2006
@@ -10,6 +10,8 @@
# Emulator tarball name
TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
+
+GMP_HEADER = /usr/include/gmp.h
all: build
@@ -55,5 +57,12 @@
patch -p1 <../vtpm.patch
build_sub:
- $(MAKE) -C $(TPM_EMULATOR_DIR)
- $(MAKE) -C $(VTPM_DIR)
+ if [ -e $(GMP_HEADER) ]; then \
+ $(MAKE) -C $(VTPM_DIR); \
+ if [ "$(BUILD_EMULATOR)" = "y" ]; then \
+ $(MAKE) -C $(TPM_EMULATOR_DIR); \
+ fi \
+ else \
+ echo "*** Unable to build VTPMs. libgmp could not be found."; \
+ fi
+
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm/Rules.mk Tue Jan 24 16:54:34 2006
@@ -33,5 +33,7 @@
-include $(DEP_FILES)
+BUILD_EMULATOR = n
+
# Make sure these are just rules
.PHONY : all build install clean
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm_manager/Makefile
--- a/tools/vtpm_manager/Makefile Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm_manager/Makefile Tue Jan 24 16:54:34 2006
@@ -4,13 +4,18 @@
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
SUBDIRS = crypto tcs util manager
+OPENSSL_HEADER = /usr/include/openssl/crypto.h
all: build
build:
- @set -e; for subdir in $(SUBDIRS); do \
- $(MAKE) -C $$subdir $@; \
- done
+ if [ -e $(OPENSSL_HEADER) ]; then \
+ @set -e; for subdir in $(SUBDIRS); do \
+ $(MAKE) -C $$subdir $@; \
+ done; \
+ else \
+ echo "*** Cannot build vtpm_manager: OpenSSL developement files
missing."; \
+ fi
install: build
@set -e; for subdir in $(SUBDIRS); do \
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Tue Jan 24 16:54:34 2006
@@ -151,9 +151,6 @@
&osap) );
// Generate boot key's auth
- Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth,
- sizeof(TPM_AUTHDATA) );
-
TPM_AUTHDATA bootKeyWrapAuth;
memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenmon/Makefile
--- a/tools/xenmon/Makefile Tue Jan 10 15:21:00 2006
+++ b/tools/xenmon/Makefile Tue Jan 24 16:54:34 2006
@@ -13,12 +13,9 @@
INSTALL = install
INSTALL_PROG = $(INSTALL) -m0755
INSTALL_DIR = $(INSTALL) -d -m0755
-INSTALL_DATA = $(INSTALL) -m064
+INSTALL_DATA = $(INSTALL) -m0644
-prefix=/usr/local
-mandir=$(prefix)/share/man
-man1dir=$(mandir)/man1
-sbindir=$(prefix)/sbin
+sbindir=/usr/sbin
XEN_ROOT=../..
include $(XEN_ROOT)/tools/Rules.mk
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstat/libxenstat/src/xenstat.c Tue Jan 24 16:54:34 2006
@@ -705,7 +705,7 @@
snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
- name = xs_read(handle->xshandle, NULL, path, NULL);
+ name = xs_read(handle->xshandle, XBT_NULL, path, NULL);
if (name == NULL)
name = strdup(" ");
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/Makefile Tue Jan 24 16:54:34 2006
@@ -27,7 +27,7 @@
CLIENTS += xenstore-write
CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
-all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xsls
+all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xenstore-ls
testcode: xs_test xenstored_test xs_random
@@ -40,7 +40,7 @@
$(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
$(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
-xsls: xsls.o libxenstore.so
+xenstore-ls: xsls.o libxenstore.so
$(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
xenstored_test: xenstored_core_test.o xenstored_watch_test.o
xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o
fake_libxc.o utils.o tdb.o
@@ -77,7 +77,7 @@
clean: testsuite-clean
rm -f *.o *.opic *.so
rm -f xenstored xs_random xs_stress xs_crashme
- rm -f xs_test xenstored_test xs_tdb_dump xsls $(CLIENTS)
+ rm -f xs_test xenstored_test xs_tdb_dump xenstore-ls $(CLIENTS)
$(RM) $(PROG_DEP)
print-dir:
@@ -129,7 +129,7 @@
tarball: clean
cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/
-install: libxenstore.so xenstored xsls $(CLIENTS)
+install: libxenstore.so xenstored xenstore-ls $(CLIENTS)
$(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
$(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
$(INSTALL_DIR) -p $(DESTDIR)/usr/bin
@@ -137,7 +137,7 @@
$(INSTALL_DIR) -p $(DESTDIR)/usr/include
$(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
$(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin
- $(INSTALL_PROG) xsls $(DESTDIR)/usr/bin
+ $(INSTALL_PROG) xenstore-ls $(DESTDIR)/usr/bin
$(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
$(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR)
$(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/utils.c
--- a/tools/xenstore/utils.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/utils.c Tue Jan 24 16:54:34 2006
@@ -92,23 +92,33 @@
else
fd = open(filename, O_RDONLY, 0);
- if (fd < 0)
+ if (fd == -1)
return NULL;
buffer = malloc(max+1);
+ if (!buffer)
+ goto error;
*size = 0;
while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
*size += ret;
- if (*size == max)
- buffer = realloc(buffer, max *= 2 + 1);
+ if (*size == max) {
+ void *nbuffer;
+ max *= 2;
+ nbuffer = realloc(buffer, max + 1);
+ if (!nbuffer)
+ goto error;
+ buffer = nbuffer;
+ }
}
- if (ret < 0) {
- free(buffer);
- buffer = NULL;
- } else
- ((char *)buffer)[*size] = '\0';
+ if (ret < 0)
+ goto error;
+ ((char *)buffer)[*size] = '\0';
close(fd);
return buffer;
+error:
+ free(buffer);
+ close(fd);
+ return NULL;
}
void release_file(void *data, unsigned long size __attribute__((unused)))
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xenstore_client.c Tue Jan 24 16:54:34 2006
@@ -66,7 +66,7 @@
#if defined(CLIENT_rm)
static int
-do_rm(char *path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
+do_rm(char *path, struct xs_handle *xsh, xs_transaction_t xth)
{
if (xs_rm(xsh, xth, path)) {
return 0;
@@ -81,7 +81,7 @@
static int
perform(int optind, int argc, char **argv, struct xs_handle *xsh,
- struct xs_transaction_handle *xth, int prefix, int tidy)
+ xs_transaction_t xth, int prefix, int tidy)
{
while (optind < argc) {
#if defined(CLIENT_read)
@@ -179,7 +179,7 @@
main(int argc, char **argv)
{
struct xs_handle *xsh;
- struct xs_transaction_handle *xth;
+ xs_transaction_t xth;
int ret = 0, socket = 0;
int prefix = 0;
int tidy = 0;
@@ -243,7 +243,7 @@
again:
xth = xs_transaction_start(xsh);
- if (xth == NULL)
+ if (xth == XBT_NULL)
errx(1, "couldn't start transaction");
ret = perform(optind, argc, argv, xsh, xth, prefix, tidy);
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xenstored_core.c Tue Jan 24 16:54:34 2006
@@ -174,69 +174,27 @@
}
}
-static void trace_io(const struct connection *conn,
- const char *prefix,
- const struct buffered_data *data)
-{
- char string[64];
- unsigned int i;
- time_t now;
- struct tm *tm;
+void trace(const char *fmt, ...)
+{
+ va_list arglist;
+ char *str;
+ char sbuf[1024];
+ int ret;
if (tracefd < 0)
return;
- now = time(NULL);
- tm = localtime(&now);
-
- write(tracefd, prefix, strlen(prefix));
- sprintf(string, " %p %02d:%02d:%02d ", conn, tm->tm_hour, tm->tm_min,
- tm->tm_sec);
- write(tracefd, string, strlen(string));
- write(tracefd, sockmsg_string(data->hdr.msg.type),
- strlen(sockmsg_string(data->hdr.msg.type)));
- write(tracefd, " (", 2);
- for (i = 0; i < data->hdr.msg.len; i++) {
- if (data->buffer[i] == '\0')
- write(tracefd, " ", 1);
- else
- write(tracefd, data->buffer + i, 1);
- }
- write(tracefd, ")\n", 2);
-}
-
-void trace_create(const void *data, const char *type)
-{
- char string[64];
- if (tracefd < 0)
+ /* try to use a static buffer */
+ va_start(arglist, fmt);
+ ret = vsnprintf(sbuf, 1024, fmt, arglist);
+ va_end(arglist);
+
+ if (ret <= 1024) {
+ write(tracefd, sbuf, ret);
return;
-
- write(tracefd, "CREATE ", strlen("CREATE "));
- write(tracefd, type, strlen(type));
- sprintf(string, " %p\n", data);
- write(tracefd, string, strlen(string));
-}
-
-void trace_destroy(const void *data, const char *type)
-{
- char string[64];
- if (tracefd < 0)
- return;
-
- write(tracefd, "DESTROY ", strlen("DESTROY "));
- write(tracefd, type, strlen(type));
- sprintf(string, " %p\n", data);
- write(tracefd, string, strlen(string));
-}
-
-void trace(const char *fmt, ...)
-{
- va_list arglist;
- char *str;
-
- if (tracefd < 0)
- return;
-
+ }
+
+ /* fail back to dynamic allocation */
va_start(arglist, fmt);
str = talloc_vasprintf(NULL, fmt, arglist);
va_end(arglist);
@@ -244,6 +202,38 @@
talloc_free(str);
}
+static void trace_io(const struct connection *conn,
+ const char *prefix,
+ const struct buffered_data *data)
+{
+ unsigned int i;
+ time_t now;
+ struct tm *tm;
+
+ if (tracefd < 0)
+ return;
+
+ now = time(NULL);
+ tm = localtime(&now);
+
+ trace("%s %p %02d:%02d:%02d %s (", prefix, conn,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ sockmsg_string(data->hdr.msg.type));
+
+ for (i = 0; i < data->hdr.msg.len; i++)
+ trace("%c", (data->buffer[i] != '\0') ? data->buffer[i] : ' ');
+ trace(")\n");
+}
+
+void trace_create(const void *data, const char *type)
+{
+ trace("CREATE %s %p\n", type, data);
+}
+
+void trace_destroy(const void *data, const char *type)
+{
+ trace("DESTROY %s %p\n", type, data);
+}
/**
* Signal handler for SIGHUP, which requests that the trace log is reopened
@@ -268,7 +258,7 @@
if (tracefd < 0)
perror("Could not open tracefile");
else
- write(tracefd, "\n***\n", strlen("\n***\n"));
+ trace("\n***\n");
}
}
@@ -1311,11 +1301,10 @@
{
struct connection *new;
- new = talloc(talloc_autofree_context(), struct connection);
+ new = talloc_zero(talloc_autofree_context(), struct connection);
if (!new)
return NULL;
- memset(new, 0, sizeof(*new));
new->fd = -1;
new->write = write;
new->read = read;
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xenstored_domain.c Tue Jan 24 16:54:34 2006
@@ -278,12 +278,12 @@
talloc_set_destructor(domain, destroy_domain);
/* Tell kernel we're interested in this event. */
- bind.remote_domain = domid;
- bind.remote_port = port;
- rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
- if (rc == -1)
- return NULL;
- domain->port = rc;
+ bind.remote_domain = domid;
+ bind.remote_port = port;
+ rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+ if (rc == -1)
+ return NULL;
+ domain->port = rc;
domain->conn = new_connection(writechn, readchn);
domain->conn->domain = domain;
@@ -426,10 +426,10 @@
int result;
unsigned int domid;
- if (!domid_str) {
- send_error(conn, EINVAL);
- return;
- }
+ if (!domid_str) {
+ send_error(conn, EINVAL);
+ return;
+ }
domid = atoi(domid_str);
if (domid == DOMID_SELF)
@@ -461,35 +461,45 @@
static int dom0_init(void)
{
- int rc, fd;
+ int rc, fd;
evtchn_port_t port;
- unsigned long mfn;
- char str[20];
- struct domain *dom0;
-
- fd = open(XENSTORED_PROC_MFN, O_RDONLY);
-
- rc = read(fd, str, sizeof(str));
- str[rc] = '\0';
- mfn = strtoul(str, NULL, 0);
-
- close(fd);
-
- fd = open(XENSTORED_PROC_PORT, O_RDONLY);
-
- rc = read(fd, str, sizeof(str));
- str[rc] = '\0';
- port = strtoul(str, NULL, 0);
-
- close(fd);
-
-
- dom0 = new_domain(NULL, 0, mfn, port);
- talloc_steal(dom0->conn, dom0);
-
- evtchn_notify(dom0->port);
-
- return 0;
+ unsigned long mfn;
+ char str[20];
+ struct domain *dom0;
+
+ fd = open(XENSTORED_PROC_MFN, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rc = read(fd, str, sizeof(str));
+ if (rc == -1)
+ goto outfd;
+ str[rc] = '\0';
+ mfn = strtoul(str, NULL, 0);
+
+ close(fd);
+
+ fd = open(XENSTORED_PROC_PORT, O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ rc = read(fd, str, sizeof(str));
+ if (rc == -1)
+ goto outfd;
+ str[rc] = '\0';
+ port = strtoul(str, NULL, 0);
+
+ close(fd);
+
+ dom0 = new_domain(NULL, 0, mfn, port);
+ talloc_steal(dom0->conn, dom0);
+
+ evtchn_notify(dom0->port);
+
+ return 0;
+outfd:
+ close(fd);
+ return -1;
}
@@ -539,9 +549,9 @@
if (eventchn_fd < 0)
barf_perror("Failed to open evtchn device");
- if (dom0_init() != 0)
- barf_perror("Failed to initialize dom0 state");
-
+ if (dom0_init() != 0)
+ barf_perror("Failed to initialize dom0 state");
+
bind.virq = VIRQ_DOM_EXC;
rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
if (rc == -1)
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xs.c Tue Jan 24 16:54:34 2006
@@ -292,7 +292,7 @@
}
/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */
-static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t,
+static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
enum xsd_sockmsg_type type,
const struct iovec *iovec,
unsigned int num_vecs,
@@ -304,7 +304,7 @@
unsigned int i;
struct sigaction ignorepipe, oldact;
- msg.tx_id = (uint32_t)(unsigned long)t;
+ msg.tx_id = t;
msg.req_id = 0;
msg.type = type;
msg.len = 0;
@@ -368,7 +368,7 @@
}
/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xs_handle *h, struct xs_transaction_handle *t,
+static void *xs_single(struct xs_handle *h, xs_transaction_t t,
enum xsd_sockmsg_type type,
const char *string,
unsigned int *len)
@@ -388,7 +388,7 @@
return true;
}
-char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
+char **xs_directory(struct xs_handle *h, xs_transaction_t t,
const char *path, unsigned int *num)
{
char *strings, *p, **ret;
@@ -420,7 +420,7 @@
* Returns a malloced value: call free() on it after use.
* len indicates length in bytes, not including the nul.
*/
-void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
+void *xs_read(struct xs_handle *h, xs_transaction_t t,
const char *path, unsigned int *len)
{
return xs_single(h, t, XS_READ, path, len);
@@ -429,7 +429,7 @@
/* Write the value of a single file.
* Returns false on failure.
*/
-bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_write(struct xs_handle *h, xs_transaction_t t,
const char *path, const void *data, unsigned int len)
{
struct iovec iovec[2];
@@ -446,7 +446,7 @@
/* Create a new directory.
* Returns false on failure, or success if it already exists.
*/
-bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
const char *path)
{
return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL));
@@ -455,7 +455,7 @@
/* Destroy a file or directory (directories must be empty).
* Returns false on failure, or success if it doesn't exist.
*/
-bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_rm(struct xs_handle *h, xs_transaction_t t,
const char *path)
{
return xs_bool(xs_single(h, t, XS_RM, path, NULL));
@@ -465,7 +465,7 @@
* Returns malloced array, or NULL: call free() after use.
*/
struct xs_permissions *xs_get_permissions(struct xs_handle *h,
- struct xs_transaction_handle *t,
+ xs_transaction_t t,
const char *path, unsigned int *num)
{
char *strings;
@@ -499,7 +499,7 @@
* Returns false on failure.
*/
bool xs_set_permissions(struct xs_handle *h,
- struct xs_transaction_handle *t,
+ xs_transaction_t t,
const char *path,
struct xs_permissions *perms,
unsigned int num_perms)
@@ -634,21 +634,21 @@
/* Start a transaction: changes by others will not be seen during this
* transaction, and changes will not be visible to others until end.
* You can only have one transaction at any time.
- * Returns NULL on failure.
- */
-struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
+ * Returns XBT_NULL on failure.
+ */
+xs_transaction_t xs_transaction_start(struct xs_handle *h)
{
char *id_str;
- unsigned long id;
+ xs_transaction_t id;
id_str = xs_single(h, XBT_NULL, XS_TRANSACTION_START, "", NULL);
if (id_str == NULL)
- return NULL;
+ return XBT_NULL;
id = strtoul(id_str, NULL, 0);
free(id_str);
- return (struct xs_transaction_handle *)id;
+ return id;
}
/* End a transaction.
@@ -656,7 +656,7 @@
* Returns false on failure, which indicates an error: transactions will
* not fail spuriously.
*/
-bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
bool abort)
{
char abortstr[2];
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xs.h Tue Jan 24 16:54:34 2006
@@ -22,10 +22,10 @@
#include <xs_lib.h>
-#define XBT_NULL NULL
+#define XBT_NULL 0
struct xs_handle;
-struct xs_transaction_handle;
+typedef uint32_t xs_transaction_t;
/* On failure, these routines set errno. */
@@ -47,45 +47,45 @@
* Returns a malloced array: call free() on it after use.
* Num indicates size.
*/
-char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
+char **xs_directory(struct xs_handle *h, xs_transaction_t t,
const char *path, unsigned int *num);
/* Get the value of a single file, nul terminated.
* Returns a malloced value: call free() on it after use.
* len indicates length in bytes, not including terminator.
*/
-void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
+void *xs_read(struct xs_handle *h, xs_transaction_t t,
const char *path, unsigned int *len);
/* Write the value of a single file.
* Returns false on failure.
*/
-bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_write(struct xs_handle *h, xs_transaction_t t,
const char *path, const void *data, unsigned int len);
/* Create a new directory.
* Returns false on failure, or success if it already exists.
*/
-bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
const char *path);
/* Destroy a file or directory (and children).
* Returns false on failure, or if it doesn't exist.
*/
-bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_rm(struct xs_handle *h, xs_transaction_t t,
const char *path);
/* Get permissions of node (first element is owner, first perms is "other").
* Returns malloced array, or NULL: call free() after use.
*/
struct xs_permissions *xs_get_permissions(struct xs_handle *h,
- struct xs_transaction_handle *t,
+ xs_transaction_t t,
const char *path, unsigned int *num);
/* Set permissions of node (must be owner).
* Returns false on failure.
*/
-bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_set_permissions(struct xs_handle *h, xs_transaction_t t,
const char *path, struct xs_permissions *perms,
unsigned int num_perms);
@@ -115,14 +115,14 @@
* You can only have one transaction at any time.
* Returns NULL on failure.
*/
-struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h);
+xs_transaction_t xs_transaction_start(struct xs_handle *h);
/* End a transaction.
* If abandon is true, transaction is discarded instead of committed.
* Returns false on failure: if errno == EAGAIN, you have to restart
* transaction.
*/
-bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
bool abort);
/* Introduce a new domain.
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xs_test.c Tue Jan 24 16:54:34 2006
@@ -43,7 +43,7 @@
#define XSTEST
static struct xs_handle *handles[10] = { NULL };
-static struct xs_transaction_handle *txh[10] = { XBT_NULL };
+static xs_transaction_t txh[10] = { XBT_NULL };
static unsigned int timeout_ms = 500;
static bool timeout_suppressed = true;
@@ -535,7 +535,7 @@
*(uint16_t *)((void *)interface + 36) = atoi(eventchn);
if (!xs_introduce_domain(handles[handle], atoi(domid),
- atol(mfn), atoi(eventchn), path)) {
+ atol(mfn), atoi(eventchn))) {
failed(handle);
munmap(interface, getpagesize());
return;
diff -r 40bb46f599d9 -r a38c292e8390 tools/xentrace/Makefile
--- a/tools/xentrace/Makefile Tue Jan 10 15:21:00 2006
+++ b/tools/xentrace/Makefile Tue Jan 24 16:54:34 2006
@@ -33,14 +33,14 @@
install: build
[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
- [ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
+ [ -z "$(LIBBIN)" ] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
[ -d $(DESTDIR)/usr/share/man/man1 ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1
[ -d $(DESTDIR)/usr/share/man/man8 ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8
$(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
- [ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN)
$(DESTDIR)/usr/$(LIBDIR)/xen/bin
+ [ -z "$(LIBBIN)" ] || $(INSTALL_PROG) $(LIBBIN)
$(DESTDIR)/usr/$(LIBDIR)/xen/bin
$(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1
$(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/Makefile Tue Jan 24 16:54:34 2006
@@ -22,6 +22,10 @@
memset.o strlen.o memcpy_mck.o \
__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
+
+ifeq ($(crash_debug),y)
+OBJS += gdbstub.o
+endif
# xen stack unwinder
# unwind_decoder.c is included in unwind.c
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/Rules.mk Tue Jan 24 16:54:34 2006
@@ -23,10 +23,10 @@
-I$(BASEDIR)/include/asm-ia64/linux-xen \
-I$(BASEDIR)/include/asm-ia64/linux-null \
-I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
-CFLAGS += -Wno-pointer-arith -Wredundant-decls
+#CFLAGS += -Wno-pointer-arith -Wredundant-decls
CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127
-CFLAGS += -w -g
+CFLAGS += -g
#CFLAGS += -DVTI_DEBUG
ifeq ($(VALIDATE_VT),y)
CFLAGS += -DVALIDATE_VT
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/asm-offsets.c Tue Jan 24 16:54:34 2006
@@ -15,7 +15,7 @@
#define task_struct vcpu
#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+ asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
#define BLANK() asm volatile("\n->" : : )
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/asm-xsi-offsets.c
--- a/xen/arch/ia64/asm-xsi-offsets.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/asm-xsi-offsets.c Tue Jan 24 16:54:34 2006
@@ -38,7 +38,7 @@
#define task_struct vcpu
#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+ asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
#define BLANK() asm volatile("\n->" : : )
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/linux-xen/sal.c
--- a/xen/arch/ia64/linux-xen/sal.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/linux-xen/sal.c Tue Jan 24 16:54:34 2006
@@ -16,6 +16,7 @@
#ifdef XEN
#include <linux/smp.h>
+#include <xen/lib.h>
#endif
#include <asm/page.h>
#include <asm/sal.h>
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/linux-xen/smp.c Tue Jan 24 16:54:34 2006
@@ -57,8 +57,21 @@
void flush_tlb_mask(cpumask_t mask)
{
#ifdef CONFIG_SMP
- printf("flush_tlb_mask called, not implemented for SMP\n");
- dummy();
+ int cpu;
+
+ cpu = smp_processor_id();
+ if (cpu_isset (cpu, mask)) {
+ cpu_clear(cpu, mask);
+ local_flush_tlb_all ();
+ }
+
+ if (cpus_empty(mask))
+ return;
+
+ for (cpu = 0; cpu < NR_CPUS; ++cpu)
+ if (cpu_isset(cpu, mask))
+ smp_call_function_single
+ (cpu, (void (*)(void *))local_flush_tlb_all, NULL, 1, 1);
#endif
}
//#if CONFIG_SMP || IA64
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/linux-xen/smpboot.c
--- a/xen/arch/ia64/linux-xen/smpboot.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/linux-xen/smpboot.c Tue Jan 24 16:54:34 2006
@@ -64,6 +64,10 @@
#ifdef XEN
#include <asm/hw_irq.h>
int ht_per_core = 1;
+#ifndef CONFIG_SMP
+cpumask_t cpu_online_map = CPU_MASK_CPU0;
+EXPORT_SYMBOL(cpu_online_map);
+#endif
#endif
#ifdef CONFIG_SMP /* ifdef XEN */
@@ -482,9 +486,8 @@
struct vcpu *v;
void *stack;
- if ( (idle = do_createdomain(IDLE_DOMAIN_ID, cpu)) == NULL )
- panic("failed 'createdomain' for CPU %d", cpu);
- v = idle->vcpu[0];
+ v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
+ BUG_ON(v == NULL);
printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/vmx/vlsapic.c Tue Jan 24 16:54:34 2006
@@ -119,7 +119,7 @@
itc_freq = local_cpu_data->itc_freq;
vtm->cfg_max_jump=itc_freq*MAX_JUMP_STEP/1000;
vtm->cfg_min_grun=itc_freq*MIN_GUEST_RUNNING_TIME/1000;
- init_ac_timer(&vtm->vtm_timer, vtm_timer_fn, vcpu, 0);
+ init_timer(&vtm->vtm_timer, vtm_timer_fn, vcpu, 0);
vtm_reset(vcpu);
}
@@ -163,20 +163,20 @@
local_irq_save(spsr);
itv = VCPU(vcpu, itv);
if ( ITV_IRQ_MASK(itv) )
- rem_ac_timer(&vtm->vtm_timer);
+ stop_timer(&vtm->vtm_timer);
vtm_interruption_update(vcpu, vtm);
local_irq_restore(spsr);
}
/*
- * Update interrupt or hook the vtm ac_timer for fire
+ * Update interrupt or hook the vtm timer for fire
* At this point vtm_timer should be removed if itv is masked.
*/
/* Interrupt must be disabled at this point */
extern u64 cycle_to_ns(u64 cyle);
-#define TIMER_SLOP (50*1000) /* ns */ /* copy from ac_timer.c */
+#define TIMER_SLOP (50*1000) /* ns */ /* copy from timer.c */
void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm)
{
uint64_t cur_itc,vitm,vitv;
@@ -198,7 +198,7 @@
if ( diff_last >= 0 ) {
// interrupt already fired.
- rem_ac_timer(&vtm->vtm_timer);
+ stop_timer(&vtm->vtm_timer);
}
else if ( diff_now >= 0 ) {
// ITV is fired.
@@ -207,24 +207,24 @@
/* Both last_itc & cur_itc < itm, wait for fire condition */
else {
expires = NOW() + cycle_to_ns(0-diff_now) + TIMER_SLOP;
- set_ac_timer(&vtm->vtm_timer, expires);
+ set_timer(&vtm->vtm_timer, expires);
}
local_irq_restore(spsr);
}
/*
* Action for vtm when the domain is scheduled out.
- * Remove the ac_timer for vtm.
+ * Remove the timer for vtm.
*/
void vtm_domain_out(VCPU *vcpu)
{
if(!is_idle_domain(vcpu->domain))
- rem_ac_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
+ stop_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
}
/*
* Action for vtm when the domain is scheduled in.
- * Fire vtm IRQ or add the ac_timer for vtm.
+ * Fire vtm IRQ or add the timer for vtm.
*/
void vtm_domain_in(VCPU *vcpu)
{
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/vmx/vmx_process.c Tue Jan 24 16:54:34 2006
@@ -41,6 +41,7 @@
#include <asm/regionreg.h>
#include <asm/privop.h>
#include <asm/ia64_int.h>
+#include <asm/debugger.h>
//#include <asm/hpsim_ssc.h>
#include <asm/dom_fw.h>
#include <asm/vmx_vcpu.h>
@@ -107,6 +108,14 @@
if (running_on_sim) do_ssc(vcpu_get_gr_nat(current,36), regs);
else do_ssc(vcpu_get_gr_nat(current,36), regs);
}
+#endif
+#ifdef CRASH_DEBUG
+ if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
+ IS_VMM_ADDRESS(regs->cr_iip)) {
+ if (iim == 0)
+ show_registers(regs);
+ debugger_trap_fatal(0 /* don't care */, regs);
+ } else
#endif
if (iim == d->arch.breakimm) {
struct ia64_pal_retval y;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/domain.c Tue Jan 24 16:54:34 2006
@@ -65,12 +65,14 @@
unsigned long map_domain_page0(struct domain *);
extern unsigned long dom_fw_setup(struct domain *, char *, int);
+static void init_switch_stack(struct vcpu *v);
/* this belongs in include/asm, but there doesn't seem to be a suitable place
*/
-void free_perdomain_pt(struct domain *d)
-{
- printf("free_perdomain_pt: not implemented\n");
+void arch_domain_destroy(struct domain *d)
+{
+ printf("arch_domain_destroy: not implemented\n");
//free_page((unsigned long)d->mm.perdomain_pt);
+ free_xenheap_page(d->shared_info);
}
static void default_idle(void)
@@ -87,7 +89,6 @@
int cpu = smp_processor_id();
for ( ; ; )
{
- printf ("idle%dD\n", cpu);
#ifdef IA64
// __IRQ_STAT(cpu, idle_timestamp) = jiffies
#else
@@ -145,16 +146,45 @@
struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
{
struct vcpu *v;
-
- if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
+ struct thread_info *ti;
+
+ /* Still keep idle vcpu0 static allocated at compilation, due
+ * to some code from Linux still requires it in early phase.
+ */
+ if (is_idle_domain(d) && !vcpu_id)
+ v = idle_vcpu[0];
+ else {
+ if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
return NULL;
-
- memset(v, 0, sizeof(*v));
- memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch));
- v->arch.privregs =
+ memset(v, 0, sizeof(*v));
+ }
+
+ ti = alloc_thread_info(v);
+ /* Clear thread_info to clear some important fields, like
+ * preempt_count
+ */
+ memset(ti, 0, sizeof(struct thread_info));
+ init_switch_stack(v);
+
+ if (!is_idle_domain(d)) {
+ v->arch.privregs =
alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
- printf("arch_vcpu_info=%p\n", v->arch.privregs);
- memset(v->arch.privregs, 0, PAGE_SIZE);
+ BUG_ON(v->arch.privregs == NULL);
+ memset(v->arch.privregs, 0, PAGE_SIZE);
+
+ if (!vcpu_id)
+ memset(&d->shared_info->evtchn_mask[0], 0xff,
+ sizeof(d->shared_info->evtchn_mask));
+
+ v->vcpu_info = &(d->shared_info->vcpu_info[0]);
+ v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
+ v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
+ v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
+ v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
+ v->arch.starting_rid = d->arch.starting_rid;
+ v->arch.ending_rid = d->arch.ending_rid;
+ v->arch.breakimm = d->arch.breakimm;
+ }
return v;
}
@@ -182,34 +212,21 @@
memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
}
-int arch_do_createdomain(struct vcpu *v)
-{
- struct domain *d = v->domain;
- struct thread_info *ti = alloc_thread_info(v);
-
- /* Clear thread_info to clear some important fields, like preempt_count
*/
- memset(ti, 0, sizeof(struct thread_info));
- init_switch_stack(v);
-
- d->shared_info = (void *)alloc_xenheap_page();
- if (!d->shared_info) {
- printk("ERROR/HALTING: CAN'T ALLOC PAGE\n");
- while (1);
- }
+int arch_domain_create(struct domain *d)
+{
+ // the following will eventually need to be negotiated dynamically
+ d->xen_vastart = XEN_START_ADDR;
+ d->xen_vaend = XEN_END_ADDR;
+ d->shared_info_va = SHAREDINFO_ADDR;
+
+ if (is_idle_domain(d))
+ return 0;
+
+ if ((d->shared_info = (void *)alloc_xenheap_page()) == NULL)
+ goto fail_nomem;
memset(d->shared_info, 0, PAGE_SIZE);
- if (v == d->vcpu[0])
- memset(&d->shared_info->evtchn_mask[0], 0xff,
- sizeof(d->shared_info->evtchn_mask));
-#if 0
- d->vcpu[0].arch.privregs =
- alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
- printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
- memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
-#endif
- v->vcpu_info = &(d->shared_info->vcpu_info[0]);
d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
-
/* We may also need emulation rid for region4, though it's unlikely
* to see guest issue uncacheable access in metaphysical mode. But
* keep such info here may be more sane.
@@ -217,41 +234,27 @@
if (((d->arch.metaphysical_rr0 = allocate_metaphysical_rr()) == -1UL)
|| ((d->arch.metaphysical_rr4 = allocate_metaphysical_rr()) == -1UL))
BUG();
-// VCPU(v, metaphysical_mode) = 1;
- v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
- v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
- v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
- v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
#define DOMAIN_RID_BITS_DEFAULT 18
if (!allocate_rid_range(d,DOMAIN_RID_BITS_DEFAULT)) // FIXME
BUG();
- v->arch.starting_rid = d->arch.starting_rid;
- v->arch.ending_rid = d->arch.ending_rid;
- // the following will eventually need to be negotiated dynamically
- d->xen_vastart = XEN_START_ADDR;
- d->xen_vaend = XEN_END_ADDR;
- d->shared_info_va = SHAREDINFO_ADDR;
d->arch.breakimm = 0x1000;
- v->arch.breakimm = d->arch.breakimm;
-
d->arch.sys_pgnr = 0;
- if (d->domain_id != IDLE_DOMAIN_ID) {
- d->arch.mm = xmalloc(struct mm_struct);
- if (unlikely(!d->arch.mm)) {
- printk("Can't allocate mm_struct for domain
%d\n",d->domain_id);
- return -ENOMEM;
- }
- memset(d->arch.mm, 0, sizeof(*d->arch.mm));
- d->arch.mm->pgd = pgd_alloc(d->arch.mm);
- if (unlikely(!d->arch.mm->pgd)) {
- printk("Can't allocate pgd for domain
%d\n",d->domain_id);
- return -ENOMEM;
- }
- } else
- d->arch.mm = NULL;
- printf ("arch_do_create_domain: domain=%p\n", d);
-
+
+ if ((d->arch.mm = xmalloc(struct mm_struct)) == NULL)
+ goto fail_nomem;
+ memset(d->arch.mm, 0, sizeof(*d->arch.mm));
+
+ if ((d->arch.mm->pgd = pgd_alloc(d->arch.mm)) == NULL)
+ goto fail_nomem;
+
+ printf ("arch_domain_create: domain=%p\n", d);
return 0;
+
+fail_nomem:
+ free_xenheap_page(d->shared_info);
+ xfree(d->arch.mm);
+ pgd_free(d->arch.mm->pgd);
+ return -ENOMEM;
}
void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/hyperprivop.S Tue Jan 24 16:54:34 2006
@@ -12,6 +12,7 @@
#include <asm/offsets.h>
#include <asm/processor.h>
#include <asm/system.h>
+#include <asm/debugger.h>
#include <public/arch-ia64.h>
@@ -549,7 +550,12 @@
(p7) br.spnt.many 1f ;;
cmp.eq p7,p0=r17,r0
(p7) br.spnt.few dispatch_break_fault ;;
-1:
+#ifdef CRASH_DEBUG
+ movl r21=CDB_BREAK_NUM ;;
+ cmp.eq p7,p0=r17,r21
+(p7) br.spnt.few dispatch_break_fault ;;
+#endif
+1:
#if 1 /* special handling in case running on simulator */
movl r20=first_break;;
ld4 r23=[r20];;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/idle0_task.c
--- a/xen/arch/ia64/xen/idle0_task.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/idle0_task.c Tue Jan 24 16:54:34 2006
@@ -11,29 +11,14 @@
.mmlist = LIST_HEAD_INIT(name.mmlist), \
}
-#define IDLE0_EXEC_DOMAIN(_ed,_d) \
+#define IDLE_VCPU(_v) \
{ \
processor: 0, \
- mm: 0, \
- thread: INIT_THREAD, \
- domain: (_d) \
-}
-
-#define IDLE0_DOMAIN(_t) \
-{ \
- domain_id: IDLE_DOMAIN_ID, \
- refcnt: ATOMIC_INIT(1) \
+ domain: 0 \
}
struct mm_struct init_mm = INIT_MM(init_mm);
EXPORT_SYMBOL(init_mm);
-
-struct domain idle0_domain = IDLE0_DOMAIN(idle0_domain);
-#if 0
-struct vcpu idle0_vcpu = IDLE0_EXEC_DOMAIN(idle0_vcpu,
- &idle0_domain);
-#endif
-
/*
* Initial task structure.
@@ -43,15 +28,12 @@
*/
union {
struct {
- struct domain task;
+ struct vcpu task;
} s;
unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
-} init_task_mem asm ("init_task") __attribute__((section(".data.init_task")));
-// = {{
- ;
-//.task = IDLE0_EXEC_DOMAIN(init_task_mem.s.task,&idle0_domain),
-//};
-//};
+} init_task_mem asm ("init_task") __attribute__((section(".data.init_task")))
= {{
+ .task = IDLE_VCPU(init_task_mem.s.task)
+}};
EXPORT_SYMBOL(init_task);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/ivt.S
--- a/xen/arch/ia64/xen/ivt.S Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/ivt.S Tue Jan 24 16:54:34 2006
@@ -15,6 +15,7 @@
#define sys_call_table 0
#define sys_ni_syscall 0
#include <asm/vhpt.h>
+#include <asm/debugger.h>
#endif
/*
* arch/ia64/kernel/ivt.S
@@ -841,6 +842,13 @@
;;
cmp.eq p7,p0=r17,r0
(p7) br.spnt.few dispatch_break_fault ;;
+#ifdef CRASH_DEBUG
+ // panic can occur before domain0 is created.
+ // in such case referencing XSI_PSR_IC causes nested_dtlb_miss
+ movl r18=CDB_BREAK_NUM ;;
+ cmp.eq p7,p0=r17,r18 ;;
+(p7) br.spnt.few dispatch_break_fault ;;
+#endif
movl r18=XSI_PSR_IC
;;
ld8 r19=[r18]
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/mm_init.c
--- a/xen/arch/ia64/xen/mm_init.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/mm_init.c Tue Jan 24 16:54:34 2006
@@ -502,6 +502,7 @@
}
#endif /* CONFIG_VIRTUAL_MEM_MAP */
+#ifndef XEN
static int
count_reserved_pages (u64 start, u64 end, void *arg)
{
@@ -514,6 +515,7 @@
*count += num_reserved;
return 0;
}
+#endif
/*
* Boot command-line option "nolwsys" can be used to disable the use of any
light-weight
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/process.c Tue Jan 24 16:54:34 2006
@@ -31,6 +31,7 @@
#include <asm/dom_fw.h>
#include "hpsim_ssc.h"
#include <xen/multicall.h>
+#include <asm/debugger.h>
extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64);
extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
@@ -652,7 +653,7 @@
ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr,
unsigned long iim)
{
struct domain *d = (struct domain *) current->domain;
- struct vcpu *v = (struct domain *) current;
+ struct vcpu *v = current;
extern unsigned long running_on_sim;
if (first_break) {
@@ -663,7 +664,14 @@
if (iim == 0x80001 || iim == 0x80002) { //FIXME: don't hardcode constant
if (running_on_sim) do_ssc(vcpu_get_gr(current,36), regs);
else do_ssc(vcpu_get_gr(current,36), regs);
- }
+ }
+#ifdef CRASH_DEBUG
+ else if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs)) {
+ if (iim == 0)
+ show_registers(regs);
+ debugger_trap_fatal(0 /* don't care */, regs);
+ }
+#endif
else if (iim == d->arch.breakimm) {
/* by default, do not continue */
v->arch.hypercall_continuation = 0;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/sn_console.c
--- a/xen/arch/ia64/xen/sn_console.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/sn_console.c Tue Jan 24 16:54:34 2006
@@ -4,6 +4,7 @@
* Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
*/
+#include <xen/lib.h>
#include <asm/acpi.h>
#include <asm/sn/sn_sal.h>
#include <xen/serial.h>
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/xenmisc.c Tue Jan 24 16:54:34 2006
@@ -18,6 +18,7 @@
#include <xen/softirq.h>
#include <public/sched.h>
#include <asm/vhpt.h>
+#include <asm/debugger.h>
efi_memory_desc_t ia64_efi_io_md;
EXPORT_SYMBOL(ia64_efi_io_md);
@@ -75,7 +76,7 @@
void raise_actimer_softirq(void)
{
- raise_softirq(AC_TIMER_SOFTIRQ);
+ raise_softirq(TIMER_SOFTIRQ);
}
unsigned long
@@ -202,6 +203,8 @@
{
printk("dump_pageframe_info not implemented\n");
}
+
+int nmi_count(int x) { return x; }
///////////////////////////////
// called from arch/ia64/head.S
@@ -354,6 +357,11 @@
va_end(args);
printf(buf);
if (regs) show_registers(regs);
+ if (regs) {
+ debugger_trap_fatal(0 /* don't care */, regs);
+ } else {
+ debugger_trap_immediate();
+ }
domain_pause_by_systemcontroller(current->domain);
v->domain->shutdown_code = SHUTDOWN_crash;
set_bit(_DOMF_shutdown, v->domain->domain_flags);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/xensetup.c Tue Jan 24 16:54:34 2006
@@ -21,12 +21,13 @@
#include <asm/page.h>
#include <asm/setup.h>
#include <xen/string.h>
+#include <asm/vmx.h>
unsigned long xenheap_phys_end;
char saved_command_line[COMMAND_LINE_SIZE];
-struct vcpu *idle_vcpu[NR_CPUS] = { &idle0_vcpu };
+struct vcpu *idle_vcpu[NR_CPUS];
cpumask_t cpu_present_map;
@@ -156,15 +157,11 @@
unsigned long dom0_memory_start, dom0_memory_size;
unsigned long dom0_initrd_start, dom0_initrd_size;
unsigned long initial_images_start, initial_images_end;
+ struct domain *idle_domain;
running_on_sim = is_platform_hp_ski();
/* Kernel may be relocated by EFI loader */
xen_pstart = ia64_tpa(KERNEL_START);
-
- /* Must do this early -- e.g., spinlocks rely on get_current(). */
- //set_current(&idle0_vcpu);
- ia64_r13 = (void *)&idle0_vcpu;
- idle0_vcpu.domain = &idle0_domain;
early_setup_arch(&cmdline);
@@ -281,18 +278,22 @@
(xenheap_phys_end-__pa(heap_start)) >> 20,
(xenheap_phys_end-__pa(heap_start)) >> 10);
+printk("About to call scheduler_init()\n");
+ scheduler_init();
+ idle_vcpu[0] = (struct vcpu*) ia64_r13;
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
+ BUG_ON(idle_domain == NULL);
+
late_setup_arch(&cmdline);
setup_per_cpu_areas();
mem_init();
-printk("About to call scheduler_init()\n");
- scheduler_init();
local_irq_disable();
init_IRQ ();
printk("About to call init_xen_time()\n");
init_xen_time(); /* initialise the time */
-printk("About to call ac_timer_init()\n");
- ac_timer_init();
+printk("About to call timer_init()\n");
+ timer_init();
#ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in
dom0! */
initialize_keytable();
@@ -308,13 +309,9 @@
}
smp_prepare_cpus(max_cpus);
-
/* We aren't hotplug-capable yet. */
- //BUG_ON(!cpus_empty(cpu_present_map));
for_each_cpu ( i )
cpu_set(i, cpu_present_map);
-
- //BUG_ON(!local_irq_is_enabled());
/* Enable IRQ to receive IPI (needed for ITC sync). */
local_irq_enable();
@@ -342,19 +339,14 @@
/* Create initial domain 0. */
-printk("About to call do_createdomain()\n");
- dom0 = do_createdomain(0, 0);
- init_task.domain = &idle0_domain;
- init_task.processor = 0;
-// init_task.mm = &init_mm;
- init_task.domain->arch.mm = &init_mm;
-// init_task.thread = INIT_THREAD;
- //arch_do_createdomain(current);
+printk("About to call domain_create()\n");
+ dom0 = domain_create(0, 0);
+
#ifdef CLONE_DOMAIN0
{
int i;
for (i = 0; i < CLONE_DOMAIN0; i++) {
- clones[i] = do_createdomain(i+1, 0);
+ clones[i] = domain_create(i+1, 0);
if ( clones[i] == NULL )
panic("Error creating domain0 clone %d\n",i);
}
@@ -431,8 +423,8 @@
local_irq_enable();
- printf("About to call schedulers_start dom0=%p, idle0_dom=%p\n",
- dom0, &idle0_domain);
+ printf("About to call schedulers_start dom0=%p, idle_dom=%p\n",
+ dom0, &idle_domain);
schedulers_start();
domain_unpause_by_systemcontroller(dom0);
@@ -445,9 +437,10 @@
{
char *p=info;
- *p=0;
-
- p+=sprintf(p,"xen_%d.%d_ia64 ",XEN_VERSION,XEN_SUBVERSION);
+ p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
+
+ if (vmx_enabled)
+ p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
*(p-1) = 0;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/xentime.c Tue Jan 24 16:54:34 2006
@@ -196,7 +196,7 @@
//#endif
/* double check, in case we got hit by a (slow) PMI: */
} while (time_after_eq(ia64_get_itc(), new_itm));
- raise_softirq(AC_TIMER_SOFTIRQ);
+ raise_softirq(TIMER_SOFTIRQ);
return IRQ_HANDLED;
}
@@ -235,7 +235,7 @@
return 0;
}
-int reprogram_ac_timer(s_time_t timeout)
+int reprogram_timer(s_time_t timeout)
{
struct vcpu *v = current;
s_time_t expire;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/Makefile Tue Jan 24 16:54:34 2006
@@ -32,7 +32,7 @@
OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
ifneq ($(crash_debug),y)
-OBJS := $(patsubst cdb%.o,,$(OBJS))
+OBJS := $(patsubst gdbstub%.o,,$(OBJS))
endif
default: $(TARGET)
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/apic.c Tue Jan 24 16:54:34 2006
@@ -870,7 +870,7 @@
* returns 1 on success
* returns 0 if the timeout value is too small or in the past.
*/
-int reprogram_ac_timer(s_time_t timeout)
+int reprogram_timer(s_time_t timeout)
{
s_time_t now;
s_time_t expire;
@@ -931,7 +931,7 @@
{
ack_APIC_irq();
perfc_incrc(apic_timer);
- raise_softirq(AC_TIMER_SOFTIRQ);
+ raise_softirq(TIMER_SOFTIRQ);
}
/*
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/domain.c Tue Jan 24 16:54:34 2006
@@ -110,6 +110,20 @@
break;
}
+void __attribute__((noreturn)) __machine_halt(void *unused)
+{
+ for ( ; ; )
+ safe_halt();
+}
+
+void machine_halt(void)
+{
+ watchdog_disable();
+ console_start_sync();
+ smp_call_function(__machine_halt, NULL, 1, 0);
+ __machine_halt(NULL);
+}
+
void machine_restart(char * __unused)
{
int i;
@@ -117,8 +131,7 @@
if ( opt_noreboot )
{
printk("Reboot disabled on cmdline: require manual reset\n");
- for ( ; ; )
- safe_halt();
+ machine_halt();
}
watchdog_disable();
@@ -164,20 +177,6 @@
}
-void __attribute__((noreturn)) __machine_halt(void *unused)
-{
- for ( ; ; )
- safe_halt();
-}
-
-void machine_halt(void)
-{
- watchdog_disable();
- console_start_sync();
- smp_call_function(__machine_halt, NULL, 1, 0);
- __machine_halt(NULL);
-}
-
void dump_pageframe_info(struct domain *d)
{
struct pfn_info *page;
@@ -215,7 +214,6 @@
memset(v, 0, sizeof(*v));
- memcpy(&v->arch, &idle_vcpu[0]->arch, sizeof(v->arch));
v->arch.flags = TF_kernel_mode;
if ( is_idle_domain(d) )
@@ -223,40 +221,31 @@
percpu_ctxt[vcpu_id].curr_vcpu = v;
v->arch.schedule_tail = continue_idle_domain;
}
-
- if ( (v->vcpu_id = vcpu_id) != 0 )
- {
- v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail;
- v->arch.perdomain_ptes =
- d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
- }
+ else
+ {
+ v->arch.schedule_tail = continue_nonidle_domain;
+ }
+
+ v->arch.perdomain_ptes =
+ d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+
+ v->arch.guest_vtable = __linear_l2_table;
+ v->arch.shadow_vtable = __shadow_linear_l2_table;
+#if defined(__x86_64__)
+ v->arch.guest_vl3table = __linear_l3_table;
+ v->arch.guest_vl4table = __linear_l4_table;
+#endif
return v;
}
void free_vcpu_struct(struct vcpu *v)
{
- BUG_ON(v->next_in_list != NULL);
- if ( v->vcpu_id != 0 )
- v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
xfree(v);
}
-void free_perdomain_pt(struct domain *d)
-{
- free_xenheap_pages(
- d->arch.mm_perdomain_pt,
- get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
-
-#ifdef __x86_64__
- free_xenheap_page(d->arch.mm_perdomain_l2);
- free_xenheap_page(d->arch.mm_perdomain_l3);
-#endif
-}
-
-int arch_do_createdomain(struct vcpu *v)
-{
- struct domain *d = v->domain;
+int arch_domain_create(struct domain *d)
+{
l1_pgentry_t gdt_l1e;
int vcpuid, pdpt_order, rc;
#ifdef __x86_64__
@@ -267,9 +256,7 @@
d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
if ( d->arch.mm_perdomain_pt == NULL )
goto fail_nomem;
-
memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
- v->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
/*
* Map Xen segments into every VCPU's GDT, irrespective of whether every
@@ -283,19 +270,11 @@
d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
- v->arch.guest_vtable = __linear_l2_table;
- v->arch.shadow_vtable = __shadow_linear_l2_table;
-
#if defined(__i386__)
- d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
- (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
- spin_lock_init(&d->arch.mapcache.lock);
+ mapcache_init(d);
#else /* __x86_64__ */
-
- v->arch.guest_vl3table = __linear_l3_table;
- v->arch.guest_vl4table = __linear_l4_table;
d->arch.mm_perdomain_l2 = alloc_xenheap_page();
d->arch.mm_perdomain_l3 = alloc_xenheap_page();
@@ -333,10 +312,7 @@
goto fail_nomem;
memset(d->shared_info, 0, PAGE_SIZE);
- v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
-
- v->arch.schedule_tail = continue_nonidle_domain;
}
return 0;
@@ -349,6 +325,20 @@
#endif
free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order);
return -ENOMEM;
+}
+
+void arch_domain_destroy(struct domain *d)
+{
+ free_xenheap_pages(
+ d->arch.mm_perdomain_pt,
+ get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
+
+#ifdef __x86_64__
+ free_xenheap_page(d->arch.mm_perdomain_l2);
+ free_xenheap_page(d->arch.mm_perdomain_l3);
+#endif
+
+ free_xenheap_page(d->shared_info);
}
/* This is called by arch_final_setup_guest and do_boot_vcpu */
@@ -481,14 +471,6 @@
#ifdef __x86_64__
-
-void toggle_guest_mode(struct vcpu *v)
-{
- v->arch.flags ^= TF_kernel_mode;
- __asm__ __volatile__ ( "swapgs" );
- update_pagetables(v);
- write_ptbase(v);
-}
#define loadsegment(seg,value) ({ \
int __r = 1; \
@@ -659,35 +641,6 @@
percpu_ctxt[smp_processor_id()].dirty_segment_mask = dirty_segment_mask;
}
-long do_switch_to_user(void)
-{
- struct cpu_user_regs *regs = guest_cpu_user_regs();
- struct switch_to_user stu;
- struct vcpu *v = current;
-
- if ( unlikely(copy_from_user(&stu, (void *)regs->rsp, sizeof(stu))) ||
- unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
- return -EFAULT;
-
- toggle_guest_mode(v);
-
- regs->rip = stu.rip;
- regs->cs = stu.cs | 3; /* force guest privilege */
- regs->rflags = (stu.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
- regs->rsp = stu.rsp;
- regs->ss = stu.ss | 3; /* force guest privilege */
-
- if ( !(stu.flags & VGCF_IN_SYSCALL) )
- {
- regs->entry_vector = 0;
- regs->r11 = stu.r11;
- regs->rcx = stu.rcx;
- }
-
- /* Saved %rax gets written back to regs->rax in entry.S. */
- return stu.rax;
-}
-
#define switch_kernel_stack(_n,_c) ((void)0)
#elif defined(__i386__)
@@ -785,7 +738,8 @@
if ( unlikely(!cpu_isset(cpu, dirty_mask) && !cpus_empty(dirty_mask)) )
{
/* Other cpus call __sync_lazy_execstate from flush ipi handler. */
- flush_tlb_mask(dirty_mask);
+ if ( !cpus_empty(next->vcpu_dirty_cpumask) )
+ flush_tlb_mask(next->vcpu_dirty_cpumask);
}
local_irq_disable();
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/mm.c Tue Jan 24 16:54:34 2006
@@ -297,7 +297,6 @@
#if defined(__x86_64__)
/* If in user mode, switch to kernel mode just to read LDT mapping. */
- extern void toggle_guest_mode(struct vcpu *);
int user_mode = !(v->arch.flags & TF_kernel_mode);
#define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
#elif defined(__i386__)
@@ -2971,7 +2970,6 @@
#ifdef CONFIG_X86_64
struct vcpu *v = current;
- extern void toggle_guest_mode(struct vcpu *);
int user_mode = !(v->arch.flags & TF_kernel_mode);
#endif
@@ -3001,7 +2999,7 @@
BUG();
}
PTWR_PRINTK("[%c] disconnected_l1va at %p is %"PRIpte"\n",
- PTWR_PRINT_WHICH, ptep, pte.l1);
+ PTWR_PRINT_WHICH, ptep, l1e_get_intpte(pte));
l1e_remove_flags(pte, _PAGE_RW);
/* Write-protect the p.t. page in the guest page table. */
@@ -3019,18 +3017,31 @@
/* NB. INVLPG is a serialising instruction: flushes pending updates. */
flush_tlb_one_mask(d->domain_dirty_cpumask, l1va);
PTWR_PRINTK("[%c] disconnected_l1va at %p now %"PRIpte"\n",
- PTWR_PRINT_WHICH, ptep, pte.l1);
+ PTWR_PRINT_WHICH, ptep, l1e_get_intpte(pte));
/*
* STEP 2. Validate any modified PTEs.
*/
- pl1e = d->arch.ptwr[which].pl1e;
- modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
- unmap_domain_page(pl1e);
- perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
- ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
- d->arch.ptwr[which].prev_nr_updates = modified;
+ if ( likely(d == current->domain) )
+ {
+ pl1e = map_domain_page(l1e_get_pfn(pte));
+ modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
+ unmap_domain_page(pl1e);
+ perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
+ ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
+ d->arch.ptwr[which].prev_nr_updates = modified;
+ }
+ else
+ {
+ /*
+ * Must make a temporary global mapping, since we are running in the
+ * wrong address space, so no access to our own mapcache.
+ */
+ pl1e = map_domain_page_global(l1e_get_pfn(pte));
+ modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
+ unmap_domain_page_global(pl1e);
+ }
/*
* STEP 3. Reattach the L1 p.t. page into the current address space.
@@ -3208,7 +3219,7 @@
{
unsigned long pfn;
struct pfn_info *page;
- l1_pgentry_t pte;
+ l1_pgentry_t *pl1e, pte;
l2_pgentry_t *pl2e, l2e;
int which, flags;
unsigned long l2_idx;
@@ -3345,11 +3356,10 @@
}
/* Temporarily map the L1 page, and make a copy of it. */
- d->arch.ptwr[which].pl1e = map_domain_page(pfn);
- memcpy(d->arch.ptwr[which].page,
- d->arch.ptwr[which].pl1e,
- L1_PAGETABLE_ENTRIES * sizeof(l1_pgentry_t));
-
+ pl1e = map_domain_page(pfn);
+ memcpy(d->arch.ptwr[which].page, pl1e, PAGE_SIZE);
+ unmap_domain_page(pl1e);
+
/* Finally, make the p.t. page writable by the guest OS. */
l1e_add_flags(pte, _PAGE_RW);
if ( unlikely(__put_user(pte.l1,
@@ -3358,7 +3368,6 @@
MEM_LOG("ptwr: Could not update pte at %p", (unsigned long *)
&linear_pg_table[l1_linear_offset(addr)]);
/* Toss the writable pagetable state and crash. */
- unmap_domain_page(d->arch.ptwr[which].pl1e);
d->arch.ptwr[which].l1va = 0;
domain_crash(d);
return 0;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/nmi.c Tue Jan 24 16:54:34 2006
@@ -23,18 +23,20 @@
#include <xen/sched.h>
#include <xen/console.h>
#include <xen/smp.h>
+#include <xen/keyhandler.h>
#include <asm/current.h>
#include <asm/mc146818rtc.h>
#include <asm/msr.h>
#include <asm/mpspec.h>
#include <asm/debugger.h>
#include <asm/div64.h>
+#include <asm/apic.h>
unsigned int nmi_watchdog = NMI_NONE;
static unsigned int nmi_hz = HZ;
static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
static unsigned int nmi_p4_cccr_val;
-static struct ac_timer nmi_timer[NR_CPUS];
+static struct timer nmi_timer[NR_CPUS];
static unsigned int nmi_timer_ticks[NR_CPUS];
/*
@@ -132,7 +134,7 @@
{
int cpu = smp_processor_id();
nmi_timer_ticks[cpu]++;
- set_ac_timer(&nmi_timer[cpu], NOW() + MILLISECS(1000));
+ set_timer(&nmi_timer[cpu], NOW() + MILLISECS(1000));
}
static void disable_lapic_nmi_watchdog(void)
@@ -308,8 +310,6 @@
void __pminit setup_apic_nmi_watchdog(void)
{
- int cpu = smp_processor_id();
-
if (!nmi_watchdog)
return;
@@ -344,49 +344,37 @@
lapic_nmi_owner = LAPIC_NMI_WATCHDOG;
nmi_active = 1;
-
- init_ac_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
}
static unsigned int
last_irq_sums [NR_CPUS],
alert_counter [NR_CPUS];
-static spinlock_t watchdog_lock = SPIN_LOCK_UNLOCKED;
-static unsigned int watchdog_disable_count = 1;
-static unsigned int watchdog_on;
+static atomic_t watchdog_disable_count = ATOMIC_INIT(1);
void watchdog_disable(void)
{
- unsigned long flags;
-
- spin_lock_irqsave(&watchdog_lock, flags);
-
- if ( watchdog_disable_count++ == 0 )
- watchdog_on = 0;
-
- spin_unlock_irqrestore(&watchdog_lock, flags);
+ atomic_inc(&watchdog_disable_count);
}
void watchdog_enable(void)
{
- unsigned int cpu;
- unsigned long flags;
-
- spin_lock_irqsave(&watchdog_lock, flags);
-
- if ( --watchdog_disable_count == 0 )
+ static unsigned long heartbeat_initialised;
+ unsigned int cpu;
+
+ if ( !atomic_dec_and_test(&watchdog_disable_count) ||
+ test_and_set_bit(0, &heartbeat_initialised) )
+ return;
+
+ /*
+ * Activate periodic heartbeats. We cannot do this earlier during
+ * setup because the timer infrastructure is not available.
+ */
+ for_each_online_cpu ( cpu )
{
- watchdog_on = 1;
- /*
- * Ensure periodic heartbeats are active. We cannot do this earlier
- * during setup because the timer infrastructure is not available.
- */
- for_each_online_cpu ( cpu )
- set_ac_timer(&nmi_timer[cpu], NOW());
- }
-
- spin_unlock_irqrestore(&watchdog_lock, flags);
+ init_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
+ set_timer(&nmi_timer[cpu], NOW());
+ }
}
void nmi_watchdog_tick(struct cpu_user_regs * regs)
@@ -395,7 +383,7 @@
sum = nmi_timer_ticks[cpu];
- if ( (last_irq_sums[cpu] == sum) && watchdog_on )
+ if ( (last_irq_sums[cpu] == sum) && !atomic_read(&watchdog_disable_count) )
{
/*
* Ayiee, looks like this CPU is stuck ... wait a few IRQs (5 seconds)
@@ -440,3 +428,51 @@
write_watchdog_counter(NULL);
}
}
+
+/*
+ * For some reason the destination shorthand for self is not valid
+ * when used with the NMI delivery mode. This is documented in Tables
+ * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to
+ * our own APIC ID explicitly which is valid.
+ */
+static void do_nmi_trigger(unsigned char key)
+{
+ u32 id = apic_read(APIC_ID);
+
+ printk("Triggering NMI on APIC ID %x\n", id);
+
+ local_irq_disable();
+ apic_wait_icr_idle();
+ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(id));
+ apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_INT_ASSERT);
+ local_irq_enable();
+}
+
+static void do_nmi_stats(unsigned char key)
+{
+ int i;
+ struct domain *d;
+ struct vcpu *v;
+ printk("CPU\tNMI\n");
+ for_each_cpu(i)
+ printk("%3d\t%3d\n", i, nmi_count(i));
+
+ if ((d = dom0) == NULL)
+ return;
+ if ((v = d->vcpu[0]) == NULL)
+ return;
+ if (v->vcpu_flags & (VCPUF_nmi_pending|VCPUF_nmi_masked))
+ printk("dom0 vpu0: NMI %s%s\n",
+ v->vcpu_flags & VCPUF_nmi_pending ? "pending " : "",
+ v->vcpu_flags & VCPUF_nmi_masked ? "masked " : "");
+ else
+ printk("dom0 vcpu0: NMI neither pending nor masked\n");
+}
+
+static __init int register_nmi_trigger(void)
+{
+ register_keyhandler('n', do_nmi_trigger, "trigger an NMI");
+ register_keyhandler('N', do_nmi_stats, "NMI statistics");
+ return 0;
+}
+__initcall(register_nmi_trigger);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/setup.c Tue Jan 24 16:54:34 2006
@@ -385,7 +385,7 @@
scheduler_init();
- idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
+ idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
BUG_ON(idle_domain == NULL);
set_current(idle_domain->vcpu[0]);
@@ -423,7 +423,7 @@
trap_init();
- ac_timer_init();
+ timer_init();
early_time_init();
@@ -478,7 +478,8 @@
schedulers_start();
- watchdog_enable();
+ if ( opt_watchdog )
+ watchdog_enable();
shadow_mode_init();
@@ -486,7 +487,7 @@
acm_init(&initrdidx, mbi, initial_images_start);
/* Create initial domain 0. */
- dom0 = do_createdomain(0, 0);
+ dom0 = domain_create(0, 0);
if ( dom0 == NULL )
panic("Error creating domain 0\n");
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/shadow.c Tue Jan 24 16:54:34 2006
@@ -469,6 +469,7 @@
{
unsigned long smfn;
l2_pgentry_t *spl2e;
+ int i;
SH_VVLOG("shadow_l2_table(gpfn=%lx, gmfn=%lx)", gpfn, gmfn);
@@ -503,9 +504,11 @@
spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
- spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
- __PAGE_HYPERVISOR);
+ for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+ spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+ l2e_from_page(virt_to_page(page_get_owner(pfn_to_page(gmfn))->
+ arch.mm_perdomain_pt) + i,
+ __PAGE_HYPERVISOR);
if ( shadow_mode_translate(d) ) // NB: not external
{
@@ -2135,6 +2138,7 @@
#if CONFIG_PAGING_LEVELS == 2
unsigned long hl2mfn;
#endif
+ int need_sync = 0;
int max_mode = ( shadow_mode_external(d) ? SHM_external
: shadow_mode_translate(d) ? SHM_translate
@@ -2150,8 +2154,8 @@
if ( max_mode & (SHM_enable | SHM_external) )
{
if ( likely(v->arch.guest_vtable != NULL) )
- unmap_domain_page(v->arch.guest_vtable);
- v->arch.guest_vtable = map_domain_page(gmfn);
+ unmap_domain_page_global(v->arch.guest_vtable);
+ v->arch.guest_vtable = map_domain_page_global(gmfn);
}
/*
@@ -2166,8 +2170,17 @@
#elif CONFIG_PAGING_LEVELS == 4
smfn = shadow_l4_table(d, gpfn, gmfn);
#endif
- }else
- shadow_sync_all(d);
+ }
+ else
+ {
+ /*
+ * move sync later in order to avoid this smfn been
+ * unshadowed occasionally
+ */
+ need_sync = 1;
+ }
+
+
if ( !get_shadow_ref(smfn) )
BUG();
old_smfn = pagetable_get_pfn(v->arch.shadow_table);
@@ -2187,8 +2200,8 @@
)
{
if ( v->arch.shadow_vtable )
- unmap_domain_page(v->arch.shadow_vtable);
- v->arch.shadow_vtable = map_domain_page(smfn);
+ unmap_domain_page_global(v->arch.shadow_vtable);
+ v->arch.shadow_vtable = map_domain_page_global(smfn);
}
#if CONFIG_PAGING_LEVELS == 2
@@ -2204,8 +2217,8 @@
if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
if ( v->arch.hl2_vtable )
- unmap_domain_page(v->arch.hl2_vtable);
- v->arch.hl2_vtable = map_domain_page(hl2mfn);
+ unmap_domain_page_global(v->arch.hl2_vtable);
+ v->arch.hl2_vtable = map_domain_page_global(hl2mfn);
}
/*
@@ -2237,6 +2250,9 @@
local_flush_tlb();
}
#endif /* CONFIG_PAGING_LEVELS == 2 */
+
+ if(likely(need_sync))
+ shadow_sync_all(d);
#if CONFIG_PAGING_LEVELS == 3
/* FIXME: PAE code to be written */
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/shadow32.c Tue Jan 24 16:54:34 2006
@@ -726,6 +726,7 @@
l2_pgentry_t *mpl2e;
struct pfn_info *mmfn_info;
struct domain *d = v->domain;
+ int i;
ASSERT(pagetable_get_paddr(v->arch.monitor_table) == 0);
@@ -733,16 +734,17 @@
ASSERT(mmfn_info != NULL);
mmfn = page_to_pfn(mmfn_info);
- mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
+ mpl2e = (l2_pgentry_t *)map_domain_page_global(mmfn);
memset(mpl2e, 0, PAGE_SIZE);
memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
- mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
- l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
- __PAGE_HYPERVISOR);
+ for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+ mpl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+ l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
+ __PAGE_HYPERVISOR);
// map the phys_to_machine map into the Read-Only MPT space for this domain
mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
@@ -794,7 +796,7 @@
* Then free monitor_table.
*/
mfn = pagetable_get_pfn(v->arch.monitor_table);
- unmap_domain_page(v->arch.monitor_vtable);
+ unmap_domain_page_global(v->arch.monitor_vtable);
free_domheap_page(pfn_to_page(mfn));
v->arch.monitor_table = mk_pagetable(0);
@@ -929,7 +931,7 @@
if ( v->arch.guest_vtable &&
(v->arch.guest_vtable != __linear_l2_table) )
{
- unmap_domain_page(v->arch.guest_vtable);
+ unmap_domain_page_global(v->arch.guest_vtable);
}
if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
v->arch.guest_vtable = __linear_l2_table;
@@ -942,7 +944,7 @@
if ( v->arch.shadow_vtable &&
(v->arch.shadow_vtable != __shadow_linear_l2_table) )
{
- unmap_domain_page(v->arch.shadow_vtable);
+ unmap_domain_page_global(v->arch.shadow_vtable);
}
if ( !(mode & SHM_external) )
v->arch.shadow_vtable = __shadow_linear_l2_table;
@@ -955,7 +957,7 @@
if ( v->arch.hl2_vtable &&
(v->arch.hl2_vtable != __linear_hl2_table) )
{
- unmap_domain_page(v->arch.hl2_vtable);
+ unmap_domain_page_global(v->arch.hl2_vtable);
}
if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
v->arch.hl2_vtable = __linear_hl2_table;
@@ -1508,6 +1510,7 @@
{
unsigned long smfn;
l2_pgentry_t *spl2e;
+ int i;
SH_VVLOG("shadow_l2_table(gpfn=%lx, gmfn=%lx)", gpfn, gmfn);
@@ -1542,9 +1545,11 @@
spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
- spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
- __PAGE_HYPERVISOR);
+ for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+ spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+ l2e_from_page(virt_to_page(page_get_owner(pfn_to_page(gmfn))->
+ arch.mm_perdomain_pt) + i,
+ __PAGE_HYPERVISOR);
if ( shadow_mode_translate(d) ) // NB: not external
{
@@ -2891,6 +2896,7 @@
unsigned long gmfn = pagetable_get_pfn(v->arch.guest_table);
unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
unsigned long smfn, hl2mfn, old_smfn;
+ int need_sync = 0;
int max_mode = ( shadow_mode_external(d) ? SHM_external
: shadow_mode_translate(d) ? SHM_translate
@@ -2906,8 +2912,8 @@
if ( max_mode & (SHM_enable | SHM_external) )
{
if ( likely(v->arch.guest_vtable != NULL) )
- unmap_domain_page(v->arch.guest_vtable);
- v->arch.guest_vtable = map_domain_page(gmfn);
+ unmap_domain_page_global(v->arch.guest_vtable);
+ v->arch.guest_vtable = map_domain_page_global(gmfn);
}
/*
@@ -2916,7 +2922,13 @@
if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_base_page_table))) )
smfn = shadow_l2_table(d, gpfn, gmfn);
else
- shadow_sync_all(d);
+ {
+ /*
+ * move sync later in order to avoid this smfn been
+ * unshadowed occasionally
+ */
+ need_sync = 1;
+ }
if ( !get_shadow_ref(smfn) )
BUG();
old_smfn = pagetable_get_pfn(v->arch.shadow_table);
@@ -2932,8 +2944,8 @@
if ( max_mode == SHM_external )
{
if ( v->arch.shadow_vtable )
- unmap_domain_page(v->arch.shadow_vtable);
- v->arch.shadow_vtable = map_domain_page(smfn);
+ unmap_domain_page_global(v->arch.shadow_vtable);
+ v->arch.shadow_vtable = map_domain_page_global(smfn);
}
/*
@@ -2948,8 +2960,8 @@
if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
if ( v->arch.hl2_vtable )
- unmap_domain_page(v->arch.hl2_vtable);
- v->arch.hl2_vtable = map_domain_page(hl2mfn);
+ unmap_domain_page_global(v->arch.hl2_vtable);
+ v->arch.hl2_vtable = map_domain_page_global(hl2mfn);
}
/*
@@ -2980,6 +2992,9 @@
// XXX - maybe this can be optimized somewhat??
local_flush_tlb();
}
+
+ if(likely(need_sync))
+ shadow_sync_all(d);
}
void clear_all_shadow_status(struct domain *d)
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/shadow_public.c Tue Jan 24 16:54:34 2006
@@ -151,6 +151,8 @@
for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
put_page_from_l1e(pl1e[i], d);
+
+ unmap_domain_page(pl1e);
}
/*
@@ -254,6 +256,7 @@
pae_l3 = map_domain_page(pagetable_get_pfn(d->arch.phys_table));
for (i = 0; i < PDP_ENTRIES; i++)
l3[i] = l3e_from_pfn(l3e_get_pfn(pae_l3[i]), __PAGE_HYPERVISOR);
+ unmap_domain_page(pae_l3);
unmap_domain_page(l4);
unmap_domain_page(l3);
@@ -275,7 +278,7 @@
ASSERT( mmfn_info );
mmfn = page_to_pfn(mmfn_info);
- mpl4e = (l4_pgentry_t *) map_domain_page(mmfn);
+ mpl4e = (l4_pgentry_t *) map_domain_page_global(mmfn);
memcpy(mpl4e, &idle_pg_table[0], PAGE_SIZE);
mpl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
@@ -298,7 +301,7 @@
* free monitor_table.
*/
mfn = pagetable_get_pfn(v->arch.monitor_table);
- unmap_domain_page(v->arch.monitor_vtable);
+ unmap_domain_page_global(v->arch.monitor_vtable);
free_domheap_page(pfn_to_page(mfn));
v->arch.monitor_table = mk_pagetable(0);
@@ -325,6 +328,7 @@
l2_pgentry_t *mpl2e;
struct pfn_info *mmfn_info;
struct domain *d = v->domain;
+ int i;
ASSERT(pagetable_get_paddr(v->arch.monitor_table) == 0);
@@ -332,16 +336,17 @@
ASSERT(mmfn_info != NULL);
mmfn = page_to_pfn(mmfn_info);
- mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
+ mpl2e = (l2_pgentry_t *)map_domain_page_global(mmfn);
memset(mpl2e, 0, PAGE_SIZE);
memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
- mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
- l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
- __PAGE_HYPERVISOR);
+ for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+ mpl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+ l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
+ __PAGE_HYPERVISOR);
// map the phys_to_machine map into the Read-Only MPT space for this domain
mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
@@ -393,7 +398,7 @@
* Then free monitor_table.
*/
mfn = pagetable_get_pfn(v->arch.monitor_table);
- unmap_domain_page(v->arch.monitor_vtable);
+ unmap_domain_page_global(v->arch.monitor_vtable);
free_domheap_page(pfn_to_page(mfn));
v->arch.monitor_table = mk_pagetable(0);
@@ -977,7 +982,7 @@
if ( v->arch.guest_vtable &&
(v->arch.guest_vtable != __linear_l2_table) )
{
- unmap_domain_page(v->arch.guest_vtable);
+ unmap_domain_page_global(v->arch.guest_vtable);
}
if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
v->arch.guest_vtable = __linear_l2_table;
@@ -990,7 +995,7 @@
if ( v->arch.shadow_vtable &&
(v->arch.shadow_vtable != __shadow_linear_l2_table) )
{
- unmap_domain_page(v->arch.shadow_vtable);
+ unmap_domain_page_global(v->arch.shadow_vtable);
}
if ( !(mode & SHM_external) && d->arch.ops->guest_paging_levels == 2)
v->arch.shadow_vtable = __shadow_linear_l2_table;
@@ -1004,7 +1009,7 @@
if ( v->arch.hl2_vtable &&
(v->arch.hl2_vtable != __linear_hl2_table) )
{
- unmap_domain_page(v->arch.hl2_vtable);
+ unmap_domain_page_global(v->arch.hl2_vtable);
}
if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
v->arch.hl2_vtable = __linear_hl2_table;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/time.c Tue Jan 24 16:54:34 2006
@@ -17,7 +17,7 @@
#include <xen/config.h>
#include <xen/init.h>
#include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/smp.h>
#include <xen/irq.h>
#include <xen/softirq.h>
@@ -56,7 +56,7 @@
s_time_t stime_local_stamp;
s_time_t stime_master_stamp;
struct time_scale tsc_scale;
- struct ac_timer calibration_timer;
+ struct timer calibration_timer;
} __cacheline_aligned;
static struct cpu_time cpu_time[NR_CPUS];
@@ -163,7 +163,7 @@
/* Rough hack to allow accurate timers to sort-of-work with no APIC. */
if ( !cpu_has_apic )
- raise_softirq(AC_TIMER_SOFTIRQ);
+ raise_softirq(TIMER_SOFTIRQ);
if ( using_pit )
pit_overflow();
@@ -342,7 +342,7 @@
/* Protected by platform_timer_lock. */
static u64 hpet_counter64, hpet_overflow_period;
static u32 hpet_stamp;
-static struct ac_timer hpet_overflow_timer;
+static struct timer hpet_overflow_timer;
static void hpet_overflow(void *unused)
{
@@ -354,7 +354,7 @@
hpet_stamp = counter;
spin_unlock_irq(&platform_timer_lock);
- set_ac_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period);
+ set_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period);
}
static u64 read_hpet_count(void)
@@ -430,7 +430,7 @@
(void)do_div(hpet_overflow_period, (u32)hpet_rate);
}
- init_ac_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0);
+ init_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0);
hpet_overflow(NULL);
platform_timer_stamp = hpet_counter64;
@@ -459,7 +459,7 @@
/* Protected by platform_timer_lock. */
static u64 cyclone_counter64;
static u32 cyclone_stamp;
-static struct ac_timer cyclone_overflow_timer;
+static struct timer cyclone_overflow_timer;
static volatile u32 *cyclone_timer; /* Cyclone MPMC0 register */
static void cyclone_overflow(void *unused)
@@ -472,7 +472,7 @@
cyclone_stamp = counter;
spin_unlock_irq(&platform_timer_lock);
- set_ac_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
+ set_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
}
static u64 read_cyclone_count(void)
@@ -510,7 +510,7 @@
read_platform_count = read_cyclone_count;
- init_ac_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
+ init_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
cyclone_overflow(NULL);
platform_timer_stamp = cyclone_counter64;
set_time_scale(&platform_timer_scale, CYCLONE_TIMER_FREQ);
@@ -876,7 +876,7 @@
cpu_time[cpu].stime_master_stamp = curr_master_stime;
out:
- set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
+ set_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
if ( cpu == 0 )
platform_time_calibration();
@@ -896,9 +896,9 @@
cpu_time[cpu].stime_master_stamp = now;
cpu_time[cpu].stime_local_stamp = now;
- init_ac_timer(&cpu_time[cpu].calibration_timer,
+ init_timer(&cpu_time[cpu].calibration_timer,
local_time_calibration, NULL, cpu);
- set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
+ set_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
}
/* Late init function (after all CPUs are booted). */
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/traps.c Tue Jan 24 16:54:34 2006
@@ -130,9 +130,19 @@
static void show_guest_stack(struct cpu_user_regs *regs)
{
int i;
- unsigned long *stack = (unsigned long *)regs->esp, addr;
-
- printk("Guest stack trace from "__OP"sp=%p:\n ", stack);
+ unsigned long *stack, addr;
+
+ if ( VM86_MODE(regs) )
+ {
+ stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
+ printk("Guest stack trace from ss:sp = %04x:%04x (VM86)\n ",
+ regs->ss, (uint16_t)(regs->esp & 0xffff));
+ }
+ else
+ {
+ stack = (unsigned long *)regs->esp;
+ printk("Guest stack trace from "__OP"sp=%p:\n ", stack);
+ }
for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
{
@@ -596,7 +606,6 @@
u16 x;
#if defined(__x86_64__)
/* If in user mode, switch to kernel mode just to read I/O bitmap. */
- extern void toggle_guest_mode(struct vcpu *);
int user_mode = !(v->arch.flags & TF_kernel_mode);
#define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
#elif defined(__i386__)
@@ -964,16 +973,26 @@
case 0x30: /* WRMSR */
/* Ignore the instruction if unprivileged. */
if ( !IS_PRIV(v->domain) )
- DPRINTK("Non-priv domain attempted WRMSR(%p,%08lx,%08lx).\n",
- _p(regs->ecx), (long)regs->eax, (long)regs->edx);
+ {
+ u32 l, h;
+ if ( (rdmsr_user(regs->ecx, l, h) != 0) ||
+ (regs->ecx != MSR_EFER) ||
+ (regs->eax != l) || (regs->edx != h) )
+ DPRINTK("Non-priv domain attempted WRMSR %p from "
+ "%08x:%08x to %08lx:%08lx.\n",
+ _p(regs->ecx), h, l, (long)regs->edx, (long)regs->eax);
+ }
else if ( wrmsr_user(regs->ecx, regs->eax, regs->edx) )
goto fail;
break;
case 0x32: /* RDMSR */
if ( !IS_PRIV(v->domain) )
- DPRINTK("Non-priv domain attempted RDMSR(%p,%08lx,%08lx).\n",
- _p(regs->ecx), (long)regs->eax, (long)regs->edx);
+ {
+ if ( regs->ecx != MSR_EFER )
+ DPRINTK("Non-priv domain attempted RDMSR %p.\n",
+ _p(regs->ecx));
+ }
/* Everyone can read the MSR space. */
if ( rdmsr_user(regs->ecx, regs->eax, regs->edx) )
goto fail;
@@ -1080,26 +1099,23 @@
return 0;
}
-
-/* Defer dom0 notification to softirq context (unsafe in NMI context). */
-static unsigned long nmi_dom0_softirq_reason;
-#define NMI_DOM0_PARITY_ERR 0
-#define NMI_DOM0_IO_ERR 1
-#define NMI_DOM0_UNKNOWN 2
-
-static void nmi_dom0_softirq(void)
-{
- if ( dom0 == NULL )
+static void nmi_softirq(void)
+{
+ /* Only used to defer wakeup of dom0,vcpu0 to a safe (non-NMI) context. */
+ evtchn_notify(dom0->vcpu[0]);
+}
+
+static void nmi_dom0_report(unsigned int reason_idx)
+{
+ struct domain *d;
+
+ if ( (d = dom0) == NULL )
return;
- if ( test_and_clear_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason) )
- send_guest_virq(dom0->vcpu[0], VIRQ_PARITY_ERR);
-
- if ( test_and_clear_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason) )
- send_guest_virq(dom0->vcpu[0], VIRQ_IO_ERR);
-
- if ( test_and_clear_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason) )
- send_guest_virq(dom0->vcpu[0], VIRQ_NMI);
+ set_bit(reason_idx, &d->shared_info->arch.nmi_reason);
+
+ if ( test_and_set_bit(_VCPUF_nmi_pending, &d->vcpu[0]->vcpu_flags) )
+ raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */
}
asmlinkage void mem_parity_error(struct cpu_user_regs *regs)
@@ -1107,8 +1123,7 @@
switch ( opt_nmi[0] )
{
case 'd': /* 'dom0' */
- set_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason);
- raise_softirq(NMI_DOM0_SOFTIRQ);
+ nmi_dom0_report(_XEN_NMIREASON_parity_error);
case 'i': /* 'ignore' */
break;
default: /* 'fatal' */
@@ -1127,8 +1142,7 @@
switch ( opt_nmi[0] )
{
case 'd': /* 'dom0' */
- set_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason);
- raise_softirq(NMI_DOM0_SOFTIRQ);
+ nmi_dom0_report(_XEN_NMIREASON_io_error);
case 'i': /* 'ignore' */
break;
default: /* 'fatal' */
@@ -1147,8 +1161,7 @@
switch ( opt_nmi[0] )
{
case 'd': /* 'dom0' */
- set_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason);
- raise_softirq(NMI_DOM0_SOFTIRQ);
+ nmi_dom0_report(_XEN_NMIREASON_unknown);
case 'i': /* 'ignore' */
break;
default: /* 'fatal' */
@@ -1347,7 +1360,7 @@
cpu_init();
- open_softirq(NMI_DOM0_SOFTIRQ, nmi_dom0_softirq);
+ open_softirq(NMI_SOFTIRQ, nmi_softirq);
}
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx.c Tue Jan 24 16:54:34 2006
@@ -98,19 +98,18 @@
/* unmap IO shared page */
struct domain *d = v->domain;
if ( d->arch.vmx_platform.shared_page_va )
- unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
+ unmap_domain_page_global(
+ (void *)d->arch.vmx_platform.shared_page_va);
}
destroy_vmcs(&v->arch.arch_vmx);
free_monitor_pagetable(v);
vpit = &v->domain->arch.vmx_platform.vmx_pit;
- if ( active_ac_timer(&(vpit->pit_timer)) )
- rem_ac_timer(&vpit->pit_timer);
- if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) )
- rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
+ kill_timer(&vpit->pit_timer);
+ kill_timer(&v->arch.arch_vmx.hlt_timer);
if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
{
- rem_ac_timer(&VLAPIC(v)->vlapic_timer);
+ kill_timer(&VLAPIC(v)->vlapic_timer);
xfree(VLAPIC(v));
}
}
@@ -1599,7 +1598,7 @@
next_wakeup = next_pit;
}
if ( next_wakeup != - 1 )
- set_ac_timer(¤t->arch.arch_vmx.hlt_timer, next_wakeup);
+ set_timer(¤t->arch.arch_vmx.hlt_timer, next_wakeup);
do_block();
}
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_intercept.c Tue Jan 24 16:54:34 2006
@@ -356,19 +356,19 @@
vpit->pending_intr_nr++;
if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
vpit->scheduled += vpit->period;
- set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+ set_timer(&vpit->pit_timer, vpit->scheduled);
}
}
void pickup_deactive_ticks(struct vmx_virpit *vpit)
{
- if ( !active_ac_timer(&(vpit->pit_timer)) ) {
+ if ( !active_timer(&(vpit->pit_timer)) ) {
/* pick up missed timer tick */
missed_ticks(vpit);
vpit->scheduled += vpit->period;
- set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+ set_timer(&vpit->pit_timer, vpit->scheduled);
}
}
@@ -385,14 +385,14 @@
/* load init count*/
if (p->state == STATE_IORESP_HOOK) {
/* set up actimer, handle re-init */
- if ( active_ac_timer(&(vpit->pit_timer)) ) {
+ if ( active_timer(&(vpit->pit_timer)) ) {
VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel
%lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) );
- rem_ac_timer(&(vpit->pit_timer));
+ stop_timer(&(vpit->pit_timer));
reinit = 1;
}
else {
- init_ac_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
+ init_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
}
/* init count for this channel */
@@ -431,7 +431,7 @@
}
vpit->scheduled = NOW() + vpit->period;
- set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+ set_timer(&vpit->pit_timer, vpit->scheduled);
/*restore the state*/
p->state = STATE_IORESP_READY;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_io.c Tue Jan 24 16:54:34 2006
@@ -819,7 +819,7 @@
if ( !vpit->first_injected ) {
vpit->pending_intr_nr = 0;
vpit->scheduled = NOW() + vpit->period;
- set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+ set_timer(&vpit->pit_timer, vpit->scheduled);
vpit->first_injected = 1;
} else {
vpit->pending_intr_nr--;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_vlapic.c
--- a/xen/arch/x86/vmx_vlapic.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_vlapic.c Tue Jan 24 16:54:34 2006
@@ -391,7 +391,7 @@
(262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter;
vlapic->vlapic_timer.expires = cur + offset;
- set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
+ set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: "
"bus_scale %x now %08x%08x expire %08x%08x "
@@ -739,7 +739,7 @@
case APIC_TMICT:
if (vlapic_timer_active(vlapic))
- rem_ac_timer(&(vlapic->vlapic_timer));
+ stop_timer(&(vlapic->vlapic_timer));
vlapic->timer_initial = val;
vlapic->timer_current = val;
@@ -846,7 +846,7 @@
vlapic->timer_current = vlapic->timer_initial;
offset = vlapic->timer_current * (262144/get_apic_bus_scale()) *
vlapic->timer_divide_counter;
vlapic->vlapic_timer.expires = NOW() + offset;
- set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
+ set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
}else {
vlapic->timer_current = 0;
}
@@ -986,7 +986,7 @@
vmx_vioapic_add_lapic(vlapic, v);
- init_ac_timer(&vlapic->vlapic_timer,
+ init_timer(&vlapic->vlapic_timer,
vlapic_timer_fn, vlapic, v->processor);
#ifdef VLAPIC_NO_BIOS
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_vmcs.c Tue Jan 24 16:54:34 2006
@@ -193,7 +193,7 @@
domain_crash_synchronous();
}
- p = map_domain_page(mpfn);
+ p = map_domain_page_global(mpfn);
if (p == NULL) {
printk("Can not map io request shared page for VMX domain.\n");
domain_crash_synchronous();
@@ -341,7 +341,7 @@
vlapic_init(v);
vmx_set_host_env(v);
- init_ac_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
+ init_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
error |= __vmwrite(GUEST_LDTR_BASE, 0);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/asm-offsets.c
--- a/xen/arch/x86/x86_32/asm-offsets.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/asm-offsets.c Tue Jan 24 16:54:34 2006
@@ -65,6 +65,10 @@
arch.guest_context.kernel_ss);
OFFSET(VCPU_kernel_sp, struct vcpu,
arch.guest_context.kernel_sp);
+ OFFSET(VCPU_flags, struct vcpu, vcpu_flags);
+ OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
+ DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending);
+ DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked);
BLANK();
OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/domain_page.c Tue Jan 24 16:54:34 2006
@@ -1,14 +1,9 @@
/******************************************************************************
* domain_page.h
*
- * Allow temporary mapping of domain pages. Based on ideas from the
- * Linux PKMAP code -- the copyrights and credits are retained below.
- */
-
-/*
- * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@xxxxxxx
- * Gerhard Wichert, Siemens AG, Gerhard.Wichert@xxxxxxxxxxxxxx *
- * Copyright (C) 1999 Ingo Molnar <mingo@xxxxxxxxxx>
+ * Allow temporary mapping of domain pages.
+ *
+ * Copyright (c) 2003-2006, Keir Fraser <keir@xxxxxxxxxxxxx>
*/
#include <xen/config.h>
@@ -20,84 +15,203 @@
#include <asm/flushtlb.h>
#include <asm/hardirq.h>
-#define MAPCACHE_ORDER 10
-#define MAPCACHE_ENTRIES (1 << MAPCACHE_ORDER)
-
-/* Use a spare PTE bit to mark entries ready for recycling. */
-#define READY_FOR_TLB_FLUSH (1<<10)
-
-static void flush_all_ready_maps(void)
-{
- struct mapcache *cache = ¤t->domain->arch.mapcache;
- unsigned int i;
-
- for ( i = 0; i < MAPCACHE_ENTRIES; i++ )
- if ( (l1e_get_flags(cache->l1tab[i]) & READY_FOR_TLB_FLUSH) )
- cache->l1tab[i] = l1e_empty();
-}
-
-void *map_domain_pages(unsigned long pfn, unsigned int order)
+void *map_domain_page(unsigned long pfn)
{
unsigned long va;
- unsigned int idx, i, flags, vcpu = current->vcpu_id;
- struct mapcache *cache = ¤t->domain->arch.mapcache;
-#ifndef NDEBUG
- unsigned int flush_count = 0;
-#endif
+ unsigned int idx, i, vcpu = current->vcpu_id;
+ struct domain *d;
+ struct mapcache *cache;
+ struct vcpu_maphash_entry *hashent;
ASSERT(!in_irq());
+
perfc_incrc(map_domain_page_count);
/* If we are the idle domain, ensure that we run on our own page tables. */
- if ( unlikely(is_idle_vcpu(current)) )
+ d = current->domain;
+ if ( unlikely(is_idle_domain(d)) )
__sync_lazy_execstate();
+ cache = &d->arch.mapcache;
+
+ hashent = &cache->vcpu_maphash[vcpu].hash[MAPHASH_HASHFN(pfn)];
+ if ( hashent->pfn == pfn )
+ {
+ idx = hashent->idx;
+ hashent->refcnt++;
+ ASSERT(hashent->refcnt != 0);
+ ASSERT(l1e_get_pfn(cache->l1tab[idx]) == pfn);
+ goto out;
+ }
+
spin_lock(&cache->lock);
/* Has some other CPU caused a wrap? We must flush if so. */
- if ( cache->epoch != cache->shadow_epoch[vcpu] )
- {
+ if ( unlikely(cache->epoch != cache->shadow_epoch[vcpu]) )
+ {
+ cache->shadow_epoch[vcpu] = cache->epoch;
+ if ( NEED_FLUSH(tlbflush_time[smp_processor_id()],
+ cache->tlbflush_timestamp) )
+ {
+ perfc_incrc(domain_page_tlb_flush);
+ local_flush_tlb();
+ }
+ }
+
+ idx = find_next_zero_bit(cache->inuse, MAPCACHE_ENTRIES, cache->cursor);
+ if ( unlikely(idx >= MAPCACHE_ENTRIES) )
+ {
+ /* /First/, clean the garbage map and update the inuse list. */
+ for ( i = 0; i < ARRAY_SIZE(cache->garbage); i++ )
+ {
+ unsigned long x = xchg(&cache->garbage[i], 0);
+ cache->inuse[i] &= ~x;
+ }
+
+ /* /Second/, flush TLBs. */
perfc_incrc(domain_page_tlb_flush);
local_flush_tlb();
- cache->shadow_epoch[vcpu] = cache->epoch;
- }
-
- do {
- idx = cache->cursor = (cache->cursor + 1) & (MAPCACHE_ENTRIES - 1);
- if ( unlikely(idx == 0) )
- {
- ASSERT(flush_count++ == 0);
- flush_all_ready_maps();
- perfc_incrc(domain_page_tlb_flush);
- local_flush_tlb();
- cache->shadow_epoch[vcpu] = ++cache->epoch;
- }
-
- flags = 0;
- for ( i = 0; i < (1U << order); i++ )
- flags |= l1e_get_flags(cache->l1tab[idx+i]);
- }
- while ( flags & _PAGE_PRESENT );
-
- for ( i = 0; i < (1U << order); i++ )
- cache->l1tab[idx+i] = l1e_from_pfn(pfn+i, __PAGE_HYPERVISOR);
+ cache->shadow_epoch[vcpu] = ++cache->epoch;
+ cache->tlbflush_timestamp = tlbflush_current_time();
+
+ idx = find_first_zero_bit(cache->inuse, MAPCACHE_ENTRIES);
+ ASSERT(idx < MAPCACHE_ENTRIES);
+ }
+
+ set_bit(idx, cache->inuse);
+ cache->cursor = idx + 1;
spin_unlock(&cache->lock);
+ cache->l1tab[idx] = l1e_from_pfn(pfn, __PAGE_HYPERVISOR);
+
+ out:
va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT);
return (void *)va;
}
-void unmap_domain_pages(void *va, unsigned int order)
-{
- unsigned int idx, i;
+void unmap_domain_page(void *va)
+{
+ unsigned int idx;
struct mapcache *cache = ¤t->domain->arch.mapcache;
+ unsigned long pfn;
+ struct vcpu_maphash_entry *hashent;
+
+ ASSERT(!in_irq());
ASSERT((void *)MAPCACHE_VIRT_START <= va);
ASSERT(va < (void *)MAPCACHE_VIRT_END);
idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
-
- for ( i = 0; i < (1U << order); i++ )
- l1e_add_flags(cache->l1tab[idx+i], READY_FOR_TLB_FLUSH);
-}
+ pfn = l1e_get_pfn(cache->l1tab[idx]);
+ hashent = &cache->vcpu_maphash[current->vcpu_id].hash[MAPHASH_HASHFN(pfn)];
+
+ if ( hashent->idx == idx )
+ {
+ ASSERT(hashent->pfn == pfn);
+ ASSERT(hashent->refcnt != 0);
+ hashent->refcnt--;
+ }
+ else if ( hashent->refcnt == 0 )
+ {
+ if ( hashent->idx != MAPHASHENT_NOTINUSE )
+ {
+ /* /First/, zap the PTE. */
+ ASSERT(l1e_get_pfn(cache->l1tab[hashent->idx]) == hashent->pfn);
+ cache->l1tab[hashent->idx] = l1e_empty();
+ /* /Second/, mark as garbage. */
+ set_bit(hashent->idx, cache->garbage);
+ }
+
+ /* Add newly-freed mapping to the maphash. */
+ hashent->pfn = pfn;
+ hashent->idx = idx;
+ }
+ else
+ {
+ /* /First/, zap the PTE. */
+ cache->l1tab[idx] = l1e_empty();
+ /* /Second/, mark as garbage. */
+ set_bit(idx, cache->garbage);
+ }
+}
+
+void mapcache_init(struct domain *d)
+{
+ unsigned int i, j;
+
+ d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
+ (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
+ spin_lock_init(&d->arch.mapcache.lock);
+
+ /* Mark all maphash entries as not in use. */
+ for ( i = 0; i < MAX_VIRT_CPUS; i++ )
+ for ( j = 0; j < MAPHASH_ENTRIES; j++ )
+ d->arch.mapcache.vcpu_maphash[i].hash[j].idx =
+ MAPHASHENT_NOTINUSE;
+}
+
+#define GLOBALMAP_BITS (IOREMAP_MBYTES << (20 - PAGE_SHIFT))
+static unsigned long inuse[BITS_TO_LONGS(GLOBALMAP_BITS)];
+static unsigned long garbage[BITS_TO_LONGS(GLOBALMAP_BITS)];
+static unsigned int inuse_cursor;
+static spinlock_t globalmap_lock = SPIN_LOCK_UNLOCKED;
+
+void *map_domain_page_global(unsigned long pfn)
+{
+ l2_pgentry_t *pl2e;
+ l1_pgentry_t *pl1e;
+ unsigned int idx, i;
+ unsigned long va;
+
+ ASSERT(!in_irq() && local_irq_is_enabled());
+
+ spin_lock(&globalmap_lock);
+
+ idx = find_next_zero_bit(inuse, GLOBALMAP_BITS, inuse_cursor);
+ va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
+ if ( unlikely(va >= FIXADDR_START) )
+ {
+ /* /First/, clean the garbage map and update the inuse list. */
+ for ( i = 0; i < ARRAY_SIZE(garbage); i++ )
+ {
+ unsigned long x = xchg(&garbage[i], 0);
+ inuse[i] &= ~x;
+ }
+
+ /* /Second/, flush all TLBs to get rid of stale garbage mappings. */
+ flush_tlb_all();
+
+ idx = find_first_zero_bit(inuse, GLOBALMAP_BITS);
+ va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
+ ASSERT(va < FIXADDR_START);
+ }
+
+ set_bit(idx, inuse);
+ inuse_cursor = idx + 1;
+
+ spin_unlock(&globalmap_lock);
+
+ pl2e = virt_to_xen_l2e(va);
+ pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(va);
+ *pl1e = l1e_from_pfn(pfn, __PAGE_HYPERVISOR);
+
+ return (void *)va;
+}
+
+void unmap_domain_page_global(void *va)
+{
+ unsigned long __va = (unsigned long)va;
+ l2_pgentry_t *pl2e;
+ l1_pgentry_t *pl1e;
+ unsigned int idx;
+
+ /* /First/, we zap the PTE. */
+ pl2e = virt_to_xen_l2e(__va);
+ pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(__va);
+ *pl1e = l1e_empty();
+
+ /* /Second/, we add to the garbage map. */
+ idx = (__va - IOREMAP_VIRT_START) >> PAGE_SHIFT;
+ set_bit(idx, garbage);
+}
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/entry.S Tue Jan 24 16:54:34 2006
@@ -326,7 +326,9 @@
shl $IRQSTAT_shift,%eax
test %ecx,irq_stat(%eax,1)
jnz process_softirqs
-/*test_guest_events:*/
+ btr $_VCPUF_nmi_pending,VCPU_flags(%ebx)
+ jc process_nmi
+test_guest_events:
movl VCPU_vcpu_info(%ebx),%eax
testb $0xFF,VCPUINFO_upcall_mask(%eax)
jnz restore_all_guest
@@ -348,7 +350,24 @@
sti
call do_softirq
jmp test_all_events
-
+
+ ALIGN
+process_nmi:
+ movl VCPU_nmi_addr(%ebx),%eax
+ test %eax,%eax
+ jz test_all_events
+ bts $_VCPUF_nmi_masked,VCPU_flags(%ebx)
+ jc 1f
+ sti
+ leal VCPU_trap_bounce(%ebx),%edx
+ movl %eax,TRAPBOUNCE_eip(%edx)
+ movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
+ movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
+ call create_bounce_frame
+ jmp test_all_events
+1: bts $_VCPUF_nmi_pending,VCPU_flags(%ebx)
+ jmp test_guest_events
+
/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK: */
/* {EIP, CS, EFLAGS, [ESP, SS]} */
/* %edx == trap_bounce, %ebx == struct vcpu */
@@ -620,9 +639,7 @@
jne defer_nmi
continue_nmi:
- movl $(__HYPERVISOR_DS),%edx
- movl %edx,%ds
- movl %edx,%es
+ SET_XEN_SEGMENTS(d)
movl %esp,%edx
pushl %edx
call do_nmi
@@ -659,42 +676,6 @@
GET_GUEST_REGS(%ecx)
movl %eax,UREGS_eax(%ecx)
jmp do_sched_op
-
-do_switch_vm86:
- # Reset the stack pointer
- GET_GUEST_REGS(%ecx)
- movl %ecx,%esp
-
- # GS:ESI == Ring-1 stack activation
- movl UREGS_esp(%esp),%esi
-VFLT1: mov UREGS_ss(%esp),%gs
-
- # ES:EDI == Ring-0 stack activation
- leal UREGS_eip(%esp),%edi
-
- # Restore the hypercall-number-clobbered EAX on our stack frame
-VFLT2: movl %gs:(%esi),%eax
- movl %eax,UREGS_eax(%esp)
- addl $4,%esi
-
- # Copy the VM86 activation from the ring-1 stack to the ring-0 stack
- movl $(UREGS_user_sizeof-UREGS_eip)/4,%ecx
-VFLT3: movl %gs:(%esi),%eax
- stosl
- addl $4,%esi
- loop VFLT3
-
- # Fix up EFLAGS: IOPL=0, IF=1, VM=1
- andl $~X86_EFLAGS_IOPL,UREGS_eflags(%esp)
- orl $X86_EFLAGS_IF|X86_EFLAGS_VM,UREGS_eflags(%esp)
-
- jmp test_all_events
-
-.section __ex_table,"a"
- .long VFLT1,domain_crash_synchronous
- .long VFLT2,domain_crash_synchronous
- .long VFLT3,domain_crash_synchronous
-.previous
.data
@@ -744,11 +725,12 @@
.long do_grant_table_op /* 20 */
.long do_vm_assist
.long do_update_va_mapping_otherdomain
- .long do_switch_vm86
+ .long do_iret
.long do_vcpu_op
.long do_ni_hypercall /* 25 */
.long do_mmuext_op
- .long do_acm_op /* 27 */
+ .long do_acm_op
+ .long do_nmi_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
@@ -777,11 +759,12 @@
.byte 3 /* do_grant_table_op */ /* 20 */
.byte 2 /* do_vm_assist */
.byte 5 /* do_update_va_mapping_otherdomain */
- .byte 0 /* do_switch_vm86 */
+ .byte 0 /* do_iret */
.byte 3 /* do_vcpu_op */
.byte 0 /* do_ni_hypercall */ /* 25 */
.byte 4 /* do_mmuext_op */
.byte 1 /* do_acm_op */
+ .byte 2 /* do_nmi_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/traps.c Tue Jan 24 16:54:34 2006
@@ -157,6 +157,64 @@
__asm__ __volatile__ ( "hlt" );
}
+asmlinkage unsigned long do_iret(void)
+{
+ struct cpu_user_regs *regs = guest_cpu_user_regs();
+ u32 eflags;
+
+ /* Check worst-case stack frame for overlap with Xen protected area. */
+ if ( unlikely(!access_ok(regs->esp, 40)) )
+ domain_crash_synchronous();
+
+ /* Pop and restore EAX (clobbered by hypercall). */
+ if ( unlikely(__copy_from_user(®s->eax, (void __user *)regs->esp, 4)) )
+ domain_crash_synchronous();
+ regs->esp += 4;
+
+ /* Pop and restore CS and EIP. */
+ if ( unlikely(__copy_from_user(®s->eip, (void __user *)regs->esp, 8)) )
+ domain_crash_synchronous();
+ regs->esp += 8;
+
+ /*
+ * Pop, fix up and restore EFLAGS. We fix up in a local staging area
+ * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
+ */
+ if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
+ domain_crash_synchronous();
+ regs->esp += 4;
+ regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
+
+ if ( VM86_MODE(regs) )
+ {
+ /* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
+ if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 24) )
+ domain_crash_synchronous();
+ }
+ else if ( unlikely(RING_0(regs)) )
+ {
+ domain_crash_synchronous();
+ }
+ else if ( !RING_1(regs) )
+ {
+ /* Return to ring 2/3: pop and restore ESP and SS. */
+ if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 8) )
+ domain_crash_synchronous();
+ }
+
+ /* No longer in NMI context. */
+ clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags);
+
+ /* Restore upcall mask from saved value. */
+ current->vcpu_info->evtchn_upcall_mask = regs->saved_upcall_mask;
+
+ /*
+ * The hypercall exit path will overwrite EAX with this return
+ * value.
+ */
+ return regs->eax;
+}
+
BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
asmlinkage void smp_deferred_nmi(struct cpu_user_regs regs)
{
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_64/asm-offsets.c Tue Jan 24 16:54:34 2006
@@ -65,6 +65,10 @@
arch.guest_context.syscall_callback_eip);
OFFSET(VCPU_kernel_sp, struct vcpu,
arch.guest_context.kernel_sp);
+ OFFSET(VCPU_flags, struct vcpu, vcpu_flags);
+ OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
+ DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending);
+ DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked);
BLANK();
OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_64/entry.S Tue Jan 24 16:54:34 2006
@@ -171,7 +171,9 @@
leaq irq_stat(%rip),%rcx
testl $~0,(%rcx,%rax,1)
jnz process_softirqs
-/*test_guest_events:*/
+ btr $_VCPUF_nmi_pending,VCPU_flags(%rbx)
+ jc process_nmi
+test_guest_events:
movq VCPU_vcpu_info(%rbx),%rax
testb $0xFF,VCPUINFO_upcall_mask(%rax)
jnz restore_all_guest
@@ -322,6 +324,23 @@
call do_softirq
jmp test_all_events
+ ALIGN
+/* %rbx: struct vcpu */
+process_nmi:
+ movq VCPU_nmi_addr(%rbx),%rax
+ test %rax,%rax
+ jz test_all_events
+ bts $_VCPUF_nmi_masked,VCPU_flags(%rbx)
+ jc 1f
+ sti
+ leaq VCPU_trap_bounce(%rbx),%rdx
+ movq %rax,TRAPBOUNCE_eip(%rdx)
+ movw $(TBF_INTERRUPT|TBF_SLOW_IRET),TRAPBOUNCE_flags(%rdx)
+ call create_bounce_frame
+ jmp test_all_events
+1: bts $_VCPUF_nmi_pending,VCPU_flags(%rbx)
+ jmp test_guest_events
+
/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK: */
/* { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS } */
/* %rdx: trap_bounce, %rbx: struct vcpu */
@@ -339,6 +358,9 @@
1: /* In kernel context already: push new frame at existing %rsp. */
movq UREGS_rsp+8(%rsp),%rsi
andb $0xfc,UREGS_cs+8(%rsp) # Indicate kernel context to guest.
+ testw $(TBF_SLOW_IRET),TRAPBOUNCE_flags(%rdx)
+ jz 2f
+ orb $0x01,UREGS_cs+8(%rsp)
2: andq $~0xf,%rsi # Stack frames are 16-byte aligned.
movq $HYPERVISOR_VIRT_START,%rax
cmpq %rax,%rsi
@@ -569,7 +591,7 @@
SAVE_ALL
movq %rsp,%rdi
call do_nmi
- jmp restore_all_xen
+ jmp ret_from_intr
do_arch_sched_op:
# Ensure we return success even if we return via schedule_tail()
@@ -626,11 +648,12 @@
.quad do_grant_table_op /* 20 */
.quad do_vm_assist
.quad do_update_va_mapping_otherdomain
- .quad do_switch_to_user
+ .quad do_iret
.quad do_vcpu_op
.quad do_set_segment_base /* 25 */
.quad do_mmuext_op
.quad do_acm_op
+ .quad do_nmi_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.quad do_ni_hypercall
.endr
@@ -659,11 +682,12 @@
.byte 3 /* do_grant_table_op */ /* 20 */
.byte 2 /* do_vm_assist */
.byte 4 /* do_update_va_mapping_otherdomain */
- .byte 0 /* do_switch_to_user */
+ .byte 0 /* do_iret */
.byte 3 /* do_vcpu_op */
.byte 2 /* do_set_segment_base */ /* 25 */
.byte 4 /* do_mmuext_op */
.byte 1 /* do_acm_op */
+ .byte 2 /* do_nmi_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_64/traps.c Tue Jan 24 16:54:34 2006
@@ -12,6 +12,7 @@
#include <asm/current.h>
#include <asm/flushtlb.h>
#include <asm/msr.h>
+#include <asm/shadow.h>
#include <asm/vmx.h>
void show_registers(struct cpu_user_regs *regs)
@@ -113,6 +114,52 @@
__asm__ __volatile__ ( "hlt" );
}
+void toggle_guest_mode(struct vcpu *v)
+{
+ v->arch.flags ^= TF_kernel_mode;
+ __asm__ __volatile__ ( "swapgs" );
+ update_pagetables(v);
+ write_ptbase(v);
+}
+
+long do_iret(void)
+{
+ struct cpu_user_regs *regs = guest_cpu_user_regs();
+ struct iret_context iret_saved;
+ struct vcpu *v = current;
+
+ if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp,
+ sizeof(iret_saved))) )
+ domain_crash_synchronous();
+
+ /* Returning to user mode? */
+ if ( (iret_saved.cs & 3) == 3 )
+ {
+ if ( unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
+ return -EFAULT;
+ toggle_guest_mode(v);
+ }
+
+ regs->rip = iret_saved.rip;
+ regs->cs = iret_saved.cs | 3; /* force guest privilege */
+ regs->rflags = (iret_saved.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
+ regs->rsp = iret_saved.rsp;
+ regs->ss = iret_saved.ss | 3; /* force guest privilege */
+
+ if ( !(iret_saved.flags & VGCF_IN_SYSCALL) )
+ {
+ regs->entry_vector = 0;
+ regs->r11 = iret_saved.r11;
+ regs->rcx = iret_saved.rcx;
+ }
+
+ /* No longer in NMI context. */
+ clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags);
+
+ /* Saved %rax gets written back to regs->rax in entry.S. */
+ return iret_saved.rax;
+}
+
asmlinkage void syscall_enter(void);
void __init percpu_traps_init(void)
{
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/Makefile
--- a/xen/common/Makefile Tue Jan 10 15:21:00 2006
+++ b/xen/common/Makefile Tue Jan 24 16:54:34 2006
@@ -3,6 +3,9 @@
ifneq ($(perfc),y)
OBJS := $(subst perfc.o,,$(OBJS))
+endif
+ifneq ($(crash_debug),y)
+OBJS := $(patsubst gdbstub.o,,$(OBJS))
endif
default: common.o
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/dom0_ops.c Tue Jan 24 16:54:34 2006
@@ -208,7 +208,7 @@
pro = i;
ret = -ENOMEM;
- if ( (d = do_createdomain(dom, pro)) == NULL )
+ if ( (d = domain_create(dom, pro)) == NULL )
break;
memcpy(d->handle, op->u.createdomain.handle,
@@ -323,7 +323,7 @@
new_affinity = v->cpu_affinity;
memcpy(cpus_addr(new_affinity),
&op->u.setvcpuaffinity.cpumap,
- min((int)BITS_TO_LONGS(NR_CPUS),
+ min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)),
(int)sizeof(op->u.setvcpuaffinity.cpumap)));
ret = vcpu_set_affinity(v, &new_affinity);
@@ -450,6 +450,10 @@
if ( (v = d->vcpu[op->u.getvcpucontext.vcpu]) == NULL )
goto getvcpucontext_out;
+ ret = -ENODATA;
+ if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+ goto getvcpucontext_out;
+
ret = -ENOMEM;
if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
goto getvcpucontext_out;
@@ -501,7 +505,7 @@
op->u.getvcpuinfo.cpumap = 0;
memcpy(&op->u.getvcpuinfo.cpumap,
cpus_addr(v->cpu_affinity),
- min((int)BITS_TO_LONGS(NR_CPUS),
+ min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)),
(int)sizeof(op->u.getvcpuinfo.cpumap)));
ret = 0;
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/domain.c
--- a/xen/common/domain.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/domain.c Tue Jan 24 16:54:34 2006
@@ -29,7 +29,7 @@
struct domain *dom0;
-struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
+struct domain *domain_create(domid_t dom_id, unsigned int cpu)
{
struct domain *d, **pd;
struct vcpu *v;
@@ -46,25 +46,27 @@
INIT_LIST_HEAD(&d->page_list);
INIT_LIST_HEAD(&d->xenpage_list);
+ rangeset_domain_initialise(d);
+
if ( !is_idle_domain(d) )
+ {
set_bit(_DOMF_ctrl_pause, &d->domain_flags);
-
- if ( !is_idle_domain(d) &&
- ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
- goto fail1;
-
+ if ( evtchn_init(d) != 0 )
+ goto fail1;
+ if ( grant_table_create(d) != 0 )
+ goto fail2;
+ }
+
+ if ( arch_domain_create(d) != 0 )
+ goto fail3;
+
if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
- goto fail2;
-
- rangeset_domain_initialise(d);
+ goto fail4;
d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
d->irq_caps = rangeset_new(d, "Interrupts", 0);
-
- if ( (d->iomem_caps == NULL) ||
- (d->irq_caps == NULL) ||
- (arch_do_createdomain(v) != 0) )
- goto fail3;
+ if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
+ goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */
if ( !is_idle_domain(d) )
{
@@ -82,12 +84,16 @@
return d;
+ fail4:
+ arch_domain_destroy(d);
fail3:
+ if ( !is_idle_domain(d) )
+ grant_table_destroy(d);
+ fail2:
+ if ( !is_idle_domain(d) )
+ evtchn_destroy(d);
+ fail1:
rangeset_domain_destroy(d);
- fail2:
- grant_table_destroy(d);
- fail1:
- evtchn_destroy(d);
free_domain(d);
return NULL;
}
@@ -256,16 +262,16 @@
/* Release resources belonging to task @p. */
-void domain_destruct(struct domain *d)
+void domain_destroy(struct domain *d)
{
struct domain **pd;
atomic_t old, new;
BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
- /* May be already destructed, or get_domain() can race us. */
+ /* May be already destroyed, or get_domain() can race us. */
_atomic_set(old, 0);
- _atomic_set(new, DOMAIN_DESTRUCTED);
+ _atomic_set(new, DOMAIN_DESTROYED);
old = atomic_compareandswap(old, new, &d->refcnt);
if ( _atomic_read(old) != 0 )
return;
@@ -287,8 +293,7 @@
evtchn_destroy(d);
grant_table_destroy(d);
- free_perdomain_pt(d);
- free_xenheap_page(d->shared_info);
+ arch_domain_destroy(d);
free_domain(d);
@@ -369,15 +374,16 @@
if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
return -EINVAL;
- if ( !test_bit(_DOMF_ctrl_pause, &d->domain_flags) )
- return -EINVAL;
-
if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
return -ENOMEM;
+
+ domain_pause(d);
rc = -EFAULT;
if ( copy_from_user(c, setvcpucontext->ctxt, sizeof(*c)) == 0 )
rc = arch_set_info_guest(v, c);
+
+ domain_unpause(d);
xfree(c);
return rc;
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/kernel.c
--- a/xen/common/kernel.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/kernel.c Tue Jan 24 16:54:34 2006
@@ -11,6 +11,7 @@
#include <xen/compile.h>
#include <xen/sched.h>
#include <asm/current.h>
+#include <public/nmi.h>
#include <public/version.h>
void cmdline_parse(char *cmdline)
@@ -146,6 +147,43 @@
}
return -ENOSYS;
+}
+
+long do_nmi_op(unsigned int cmd, void *arg)
+{
+ struct vcpu *v = current;
+ struct domain *d = current->domain;
+ long rc = 0;
+
+ switch ( cmd )
+ {
+ case XENNMI_register_callback:
+ if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
+ {
+ rc = -EINVAL;
+ }
+ else
+ {
+ v->nmi_addr = (unsigned long)arg;
+#ifdef CONFIG_X86
+ /*
+ * If no handler was registered we can 'lose the NMI edge'.
+ * Re-assert it now.
+ */
+ if ( d->shared_info->arch.nmi_reason != 0 )
+ set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
+#endif
+ }
+ break;
+ case XENNMI_unregister_callback:
+ v->nmi_addr = 0;
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
}
long do_vm_assist(unsigned int cmd, unsigned int type)
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/memory.c
--- a/xen/common/memory.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/memory.c Tue Jan 24 16:54:34 2006
@@ -38,10 +38,7 @@
if ( (extent_order != 0) &&
!multipage_allocation_permitted(current->domain) )
- {
- DPRINTK("Only I/O-capable domains may allocate multi-page extents.\n");
return 0;
- }
for ( i = 0; i < nr_extents; i++ )
{
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/sched_bvt.c
--- a/xen/common/sched_bvt.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/sched_bvt.c Tue Jan 24 16:54:34 2006
@@ -20,7 +20,7 @@
#include <xen/delay.h>
#include <xen/event.h>
#include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/perfc.h>
#include <xen/sched-if.h>
#include <xen/softirq.h>
@@ -45,9 +45,9 @@
limits*/
s32 warp_value; /* virtual time warp */
s_time_t warpl; /* warp limit */
- struct ac_timer warp_timer; /* deals with warpl */
+ struct timer warp_timer; /* deals with warpl */
s_time_t warpu; /* unwarp time requirement */
- struct ac_timer unwarp_timer; /* deals with warpu */
+ struct timer unwarp_timer; /* deals with warpu */
struct bvt_vcpu_info vcpu_inf[MAX_VIRT_CPUS];
};
@@ -98,9 +98,9 @@
static void warp_timer_fn(void *data)
{
struct bvt_dom_info *inf = data;
- unsigned int cpu = inf->domain->vcpu[0]->processor;
-
- spin_lock_irq(&schedule_data[cpu].schedule_lock);
+ struct vcpu *v = inf->domain->vcpu[0];
+
+ vcpu_schedule_lock_irq(v);
inf->warp = 0;
@@ -108,28 +108,28 @@
if ( inf->warpu == 0 )
{
inf->warpback = 0;
- cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
- }
-
- set_ac_timer(&inf->unwarp_timer, NOW() + inf->warpu);
-
- spin_unlock_irq(&schedule_data[cpu].schedule_lock);
+ cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
+ }
+
+ set_timer(&inf->unwarp_timer, NOW() + inf->warpu);
+
+ vcpu_schedule_unlock_irq(v);
}
static void unwarp_timer_fn(void *data)
{
struct bvt_dom_info *inf = data;
- unsigned int cpu = inf->domain->vcpu[0]->processor;
-
- spin_lock_irq(&schedule_data[cpu].schedule_lock);
+ struct vcpu *v = inf->domain->vcpu[0];
+
+ vcpu_schedule_lock_irq(v);
if ( inf->warpback )
{
inf->warp = 1;
- cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
+ cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);
}
- spin_unlock_irq(&schedule_data[cpu].schedule_lock);
+ vcpu_schedule_unlock_irq(v);
}
static inline u32 calc_avt(struct vcpu *d, s_time_t now)
@@ -168,6 +168,7 @@
static int bvt_alloc_task(struct vcpu *v)
{
struct domain *d = v->domain;
+ struct bvt_dom_info *inf;
if ( (d->sched_priv == NULL) )
{
@@ -176,32 +177,12 @@
memset(d->sched_priv, 0, sizeof(struct bvt_dom_info));
}
- v->sched_priv = &BVT_INFO(d)->vcpu_inf[v->vcpu_id];
-
- BVT_INFO(d)->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
- BVT_INFO(d)->vcpu_inf[v->vcpu_id].vcpu = v;
-
- return 0;
-}
-
-/*
- * Add and remove a domain
- */
-static void bvt_add_task(struct vcpu *v)
-{
- struct bvt_dom_info *inf = BVT_INFO(v->domain);
- struct bvt_vcpu_info *einf = EBVT_INFO(v);
- ASSERT(inf != NULL);
- ASSERT(v != NULL);
-
- /* Allocate per-CPU context if this is the first domain to be added. */
- if ( CPU_INFO(v->processor) == NULL )
- {
- schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
- BUG_ON(CPU_INFO(v->processor) == NULL);
- INIT_LIST_HEAD(RUNQUEUE(v->processor));
- CPU_SVT(v->processor) = 0;
- }
+ inf = BVT_INFO(d);
+
+ v->sched_priv = &inf->vcpu_inf[v->vcpu_id];
+
+ inf->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
+ inf->vcpu_inf[v->vcpu_id].vcpu = v;
if ( v->vcpu_id == 0 )
{
@@ -214,11 +195,28 @@
inf->warpl = MILLISECS(2000);
inf->warpu = MILLISECS(1000);
/* Initialise the warp timers. */
- init_ac_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
- init_ac_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
- }
-
- einf->vcpu = v;
+ init_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
+ init_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
+ }
+
+ return 0;
+}
+
+/*
+ * Add and remove a domain
+ */
+static void bvt_add_task(struct vcpu *v)
+{
+ struct bvt_vcpu_info *einf = EBVT_INFO(v);
+
+ /* Allocate per-CPU context if this is the first domain to be added. */
+ if ( CPU_INFO(v->processor) == NULL )
+ {
+ schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
+ BUG_ON(CPU_INFO(v->processor) == NULL);
+ INIT_LIST_HEAD(RUNQUEUE(v->processor));
+ CPU_SVT(v->processor) = 0;
+ }
if ( is_idle_vcpu(v) )
{
@@ -271,7 +269,7 @@
if ( is_idle_vcpu(curr) || (einf->evt <= curr_evt) )
cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
else if ( schedule_data[cpu].s_timer.expires > r_time )
- set_ac_timer(&schedule_data[cpu].s_timer, r_time);
+ set_timer(&schedule_data[cpu].s_timer, r_time);
}
@@ -305,8 +303,14 @@
*/
static void bvt_free_task(struct domain *d)
{
- ASSERT(d->sched_priv != NULL);
- xfree(d->sched_priv);
+ struct bvt_dom_info *inf = BVT_INFO(d);
+
+ ASSERT(inf != NULL);
+
+ kill_timer(&inf->warp_timer);
+ kill_timer(&inf->unwarp_timer);
+
+ xfree(inf);
}
/* Control the scheduler. */
@@ -355,10 +359,10 @@
inf->warpu = MILLISECS(warpu);
/* If the unwarp timer set up it needs to be removed */
- rem_ac_timer(&inf->unwarp_timer);
+ stop_timer(&inf->unwarp_timer);
/* If we stop warping the warp timer needs to be removed */
if ( !warpback )
- rem_ac_timer(&inf->warp_timer);
+ stop_timer(&inf->warp_timer);
}
else if ( cmd->direction == SCHED_INFO_GET )
{
@@ -405,7 +409,7 @@
prev_einf->evt = calc_evt(prev, prev_einf->avt);
if(prev_inf->warpback && prev_inf->warpl > 0)
- rem_ac_timer(&prev_inf->warp_timer);
+ stop_timer(&prev_inf->warp_timer);
__del_from_runqueue(prev);
@@ -455,7 +459,7 @@
}
if ( next_einf->inf->warp && next_einf->inf->warpl > 0 )
- set_ac_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
+ set_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
/* Extract the domain pointers from the dom infos */
next = next_einf->vcpu;
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/sched_sedf.c Tue Jan 24 16:54:34 2006
@@ -9,7 +9,7 @@
#include <xen/sched.h>
#include <xen/sched-if.h>
#include <public/sched_ctl.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/softirq.h>
#include <xen/time.h>
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/schedule.c
--- a/xen/common/schedule.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/schedule.c Tue Jan 24 16:54:34 2006
@@ -21,7 +21,7 @@
#include <xen/delay.h>
#include <xen/event.h>
#include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/perfc.h>
#include <xen/sched-if.h>
#include <xen/softirq.h>
@@ -71,17 +71,31 @@
: (typeof(ops.fn(__VA_ARGS__)))0 )
/* Per-CPU periodic timer sends an event to the currently-executing domain. */
-static struct ac_timer t_timer[NR_CPUS];
+static struct timer t_timer[NR_CPUS];
+
+struct domain *alloc_domain(void)
+{
+ struct domain *d;
+
+ if ( (d = xmalloc(struct domain)) != NULL )
+ memset(d, 0, sizeof(*d));
+
+ return d;
+}
void free_domain(struct domain *d)
{
+ struct vcpu *v;
int i;
+ for_each_vcpu ( d, v )
+ sched_rem_domain(v);
+
SCHED_OP(free_task, d);
for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
- if ( d->vcpu[i] != NULL )
- free_vcpu_struct(d->vcpu[i]);
+ if ( (v = d->vcpu[i]) != NULL )
+ free_vcpu_struct(v);
xfree(d);
}
@@ -100,48 +114,33 @@
v->vcpu_id = vcpu_id;
v->processor = cpu_id;
atomic_set(&v->pausecnt, 0);
+ v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
v->cpu_affinity = is_idle_domain(d) ?
cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
- d->vcpu[vcpu_id] = v;
+ if ( (vcpu_id != 0) && !is_idle_domain(d) )
+ set_bit(_VCPUF_down, &v->vcpu_flags);
if ( SCHED_OP(alloc_task, v) < 0 )
{
- d->vcpu[vcpu_id] = NULL;
free_vcpu_struct(v);
return NULL;
}
+ d->vcpu[vcpu_id] = v;
+ if ( vcpu_id != 0 )
+ d->vcpu[v->vcpu_id-1]->next_in_list = v;
+
sched_add_domain(v);
- if ( vcpu_id != 0 )
- {
- v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
- d->vcpu[v->vcpu_id-1]->next_in_list = v;
- set_bit(_VCPUF_down, &v->vcpu_flags);
- }
-
return v;
}
-struct domain *alloc_domain(void)
-{
- struct domain *d;
-
- if ( (d = xmalloc(struct domain)) != NULL )
- memset(d, 0, sizeof(*d));
-
- return d;
-}
-
-/*
- * Add and remove a domain
- */
void sched_add_domain(struct vcpu *v)
{
/* Initialise the per-domain timer. */
- init_ac_timer(&v->timer, dom_timer_fn, v, v->processor);
+ init_timer(&v->timer, dom_timer_fn, v, v->processor);
if ( is_idle_vcpu(v) )
{
@@ -156,7 +155,7 @@
void sched_rem_domain(struct vcpu *v)
{
- rem_ac_timer(&v->timer);
+ kill_timer(&v->timer);
SCHED_OP(rem_task, v);
TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
}
@@ -165,26 +164,19 @@
{
unsigned long flags;
- spin_lock_irqsave(&schedule_data[v->processor].schedule_lock, flags);
+ vcpu_schedule_lock_irqsave(v, flags);
if ( likely(!vcpu_runnable(v)) )
SCHED_OP(sleep, v);
- spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
+ vcpu_schedule_unlock_irqrestore(v, flags);
TRACE_2D(TRC_SCHED_SLEEP, v->domain->domain_id, v->vcpu_id);
-}
+}
void vcpu_sleep_sync(struct vcpu *v)
{
vcpu_sleep_nosync(v);
- /*
- * We can be sure that the VCPU is finally descheduled after the running
- * flag is cleared and the scheduler lock is released. We also check that
- * the domain continues to be unrunnable, in case someone else wakes it.
- */
- while ( !vcpu_runnable(v) &&
- (test_bit(_VCPUF_running, &v->vcpu_flags) ||
- spin_is_locked(&schedule_data[v->processor].schedule_lock)) )
+ while ( !vcpu_runnable(v) && test_bit(_VCPUF_running, &v->vcpu_flags) )
cpu_relax();
sync_vcpu_execstate(v);
@@ -194,20 +186,23 @@
{
unsigned long flags;
- spin_lock_irqsave(&schedule_data[v->processor].schedule_lock, flags);
+ vcpu_schedule_lock_irqsave(v, flags);
if ( likely(vcpu_runnable(v)) )
{
SCHED_OP(wake, v);
v->wokenup = NOW();
}
- spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
+ vcpu_schedule_unlock_irqrestore(v, flags);
TRACE_2D(TRC_SCHED_WAKE, v->domain->domain_id, v->vcpu_id);
}
int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
{
- if ( cpus_empty(*affinity) )
+ cpumask_t online_affinity;
+
+ cpus_and(online_affinity, *affinity, cpu_online_map);
+ if ( cpus_empty(online_affinity) )
return -EINVAL;
return SCHED_OP(set_affinity, v, affinity);
@@ -282,9 +277,9 @@
struct vcpu *v = current;
if ( timeout == 0 )
- rem_ac_timer(&v->timer);
+ stop_timer(&v->timer);
else
- set_ac_timer(&v->timer, timeout);
+ set_timer(&v->timer, timeout);
return 0;
}
@@ -311,68 +306,42 @@
{
struct domain *d;
struct vcpu *v;
- int cpu;
-#if NR_CPUS <=32
- unsigned long have_lock;
- #else
- unsigned long long have_lock;
-#endif
- int succ;
-
- #define __set_cpu_bit(cpu, data) data |= ((typeof(data))1)<<cpu
- #define __get_cpu_bit(cpu, data) (data & ((typeof(data))1)<<cpu)
- #define __clear_cpu_bits(data) data = ((typeof(data))0)
- if ( cmd->sched_id != ops.sched_id )
- return -EINVAL;
-
- if ( cmd->direction != SCHED_INFO_PUT && cmd->direction != SCHED_INFO_GET )
+ if ( (cmd->sched_id != ops.sched_id) ||
+ ((cmd->direction != SCHED_INFO_PUT) &&
+ (cmd->direction != SCHED_INFO_GET)) )
return -EINVAL;
d = find_domain_by_id(cmd->domain);
if ( d == NULL )
return -ESRCH;
- /* acquire locks on all CPUs on which vcpus of this domain run */
- do {
- succ = 0;
- __clear_cpu_bits(have_lock);
- for_each_vcpu ( d, v )
- {
- cpu = v->processor;
- if ( !__get_cpu_bit(cpu, have_lock) )
- {
- /* if we don't have a lock on this CPU: acquire it*/
- if ( spin_trylock(&schedule_data[cpu].schedule_lock) )
- {
- /*we have this lock!*/
- __set_cpu_bit(cpu, have_lock);
- succ = 1;
- }
- else
- {
- /*we didn,t get this lock -> free all other locks too!*/
- for ( cpu = 0; cpu < NR_CPUS; cpu++ )
- if ( __get_cpu_bit(cpu, have_lock) )
- spin_unlock(&schedule_data[cpu].schedule_lock);
- /* and start from the beginning! */
- succ = 0;
- /* leave the "for_each_domain_loop" */
- break;
- }
- }
- }
- } while ( !succ );
+ /*
+ * Most VCPUs we can simply pause. If we are adjusting this VCPU then
+ * we acquire the local schedule_lock to guard against concurrent updates.
+ */
+ for_each_vcpu ( d, v )
+ {
+ if ( v == current )
+ vcpu_schedule_lock_irq(v);
+ else
+ vcpu_pause(v);
+ }
SCHED_OP(adjdom, d, cmd);
- for ( cpu = 0; cpu < NR_CPUS; cpu++ )
- if ( __get_cpu_bit(cpu, have_lock) )
- spin_unlock(&schedule_data[cpu].schedule_lock);
- __clear_cpu_bits(have_lock);
-
TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
+
+ for_each_vcpu ( d, v )
+ {
+ if ( v == current )
+ vcpu_schedule_unlock_irq(v);
+ else
+ vcpu_unpause(v);
+ }
+
put_domain(d);
+
return 0;
}
@@ -395,7 +364,7 @@
spin_lock_irq(&schedule_data[cpu].schedule_lock);
- rem_ac_timer(&schedule_data[cpu].s_timer);
+ stop_timer(&schedule_data[cpu].s_timer);
prev->cpu_time += now - prev->lastschd;
@@ -409,7 +378,7 @@
next->lastschd = now;
- set_ac_timer(&schedule_data[cpu].s_timer, now + r_time);
+ set_timer(&schedule_data[cpu].s_timer, now + r_time);
if ( unlikely(prev == next) )
{
@@ -451,6 +420,7 @@
}
#endif
+ ASSERT(!test_bit(_VCPUF_running, &next->vcpu_flags));
set_bit(_VCPUF_running, &next->vcpu_flags);
spin_unlock_irq(&schedule_data[cpu].schedule_lock);
@@ -492,7 +462,7 @@
/* Periodic tick timer: send timer event to current domain */
static void t_timer_fn(void *unused)
{
- struct vcpu *v = current;
+ struct vcpu *v = current;
unsigned int cpu = smp_processor_id();
schedule_data[cpu].tick++;
@@ -505,7 +475,7 @@
page_scrub_schedule_work();
- set_ac_timer(&t_timer[cpu], NOW() + MILLISECS(10));
+ set_timer(&t_timer[cpu], NOW() + MILLISECS(10));
}
/* Domain timer function, sends a virtual timer interrupt to domain */
@@ -527,8 +497,8 @@
for ( i = 0; i < NR_CPUS; i++ )
{
spin_lock_init(&schedule_data[i].schedule_lock);
- init_ac_timer(&schedule_data[i].s_timer, s_timer_fn, NULL, i);
- init_ac_timer(&t_timer[i], t_timer_fn, NULL, i);
+ init_timer(&schedule_data[i].s_timer, s_timer_fn, NULL, i);
+ init_timer(&t_timer[i], t_timer_fn, NULL, i);
}
for ( i = 0; schedulers[i] != NULL; i++ )
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/xmalloc.c
--- a/xen/common/xmalloc.c Tue Jan 10 15:21:00 2006
+++ b/xen/common/xmalloc.c Tue Jan 24 16:54:34 2006
@@ -30,7 +30,7 @@
#include <xen/config.h>
#include <xen/mm.h>
#include <xen/spinlock.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/cache.h>
#include <xen/prefetch.h>
diff -r 40bb46f599d9 -r a38c292e8390 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c Tue Jan 10 15:21:00 2006
+++ b/xen/drivers/char/ns16550.c Tue Jan 24 16:54:34 2006
@@ -33,7 +33,7 @@
/* UART with IRQ line: interrupt-driven I/O. */
struct irqaction irqaction;
/* UART with no IRQ line: periodically-polled I/O. */
- struct ac_timer timer;
+ struct timer timer;
unsigned int timeout_ms;
} ns16550_com[2] = { { 0 } };
@@ -138,7 +138,7 @@
if ( ns_read_reg(uart, LSR) & LSR_THRE )
serial_tx_interrupt(port, regs);
- set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+ set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
}
static int ns16550_tx_empty(struct serial_port *port)
@@ -214,8 +214,8 @@
bits = uart->data_bits + uart->stop_bits + !!uart->parity;
uart->timeout_ms = max_t(
unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
- init_ac_timer(&uart->timer, ns16550_poll, port, 0);
- set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+ init_timer(&uart->timer, ns16550_poll, port, 0);
+ set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
}
else
{
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/config.h Tue Jan 24 16:54:34 2006
@@ -92,7 +92,7 @@
//#define __acquire(x) (void)0
//#define __release(x) (void)0
//#define __cond_lock(x) (x)
-#define __must_check
+//#define __must_check
#define __deprecated
#ifndef RELOC_HIDE
# define RELOC_HIDE(ptr, off) \
@@ -121,7 +121,7 @@
// from include/asm-ia64/smp.h
#ifdef CONFIG_SMP
-#warning "Lots of things to fix to enable CONFIG_SMP!"
+//#warning "Lots of things to fix to enable CONFIG_SMP!"
#endif
#define get_cpu() smp_processor_id()
#define put_cpu() do {} while(0)
@@ -140,10 +140,6 @@
#undef free_task_struct
#undef alloc_task_struct
#define get_thread_info(v) alloc_thread_info(v)
-
-// initial task has a different name in Xen
-//#define idle0_task init_task
-#define idle0_vcpu init_task
// avoid redefining task_t in asm/thread_info.h
#define task_t struct domain
@@ -160,7 +156,7 @@
#define platform_outl __ia64_outl
// FIXME: This just overrides a use in a typedef (not allowed in ia64,
-// or maybe just in older gcc's?) used in ac_timer.c but should be OK
+// or maybe just in older gcc's?) used in timer.c but should be OK
// (and indeed is probably required!) elsewhere
#undef __cacheline_aligned
#undef ____cacheline_aligned
@@ -187,7 +183,9 @@
struct exception_table_entry *finish);
void sort_main_extable(void);
+#if 0 /* Already defined in xen/lib.h */
#define printk printf
+#endif
#undef __ARCH_IRQ_STAT
@@ -205,7 +203,6 @@
#define OPT_CONSOLE_STR "com2"
#endif
-#define __attribute_used__ __attribute__ ((unused))
#define __nocast
// see include/asm-x86/atomic.h (different from standard linux)
@@ -255,9 +252,6 @@
#define seq_printf(a,b...) printf(b)
#define CONFIG_BLK_DEV_INITRD // needed to reserve memory for domain0
-// needed for newer ACPI code
-#define asmlinkage
-
#define FORCE_CRASH() asm("break 0;;");
void dummy_called(char *function);
@@ -306,13 +300,8 @@
#endif
-// FOLLOWING ADDED FOR XEN POST-NGIO and/or LINUX 2.6.7
-
-// following derived from linux/include/linux/compiler-gcc3.h
-// problem because xen (over?)simplifies include/xen/compiler.h
-#if __GNUC_MAJOR < 3 || __GNUC_MINOR__ >= 3
-# define __attribute_used__ __attribute__((__used__))
-#else
-# define __attribute_used__ __attribute__((__unused__))
-#endif
+#ifndef __ASSEMBLY__
+#include <linux/linkage.h>
+#endif
+
#endif /* _IA64_CONFIG_H_ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/debugger.h
--- a/xen/include/asm-ia64/debugger.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/debugger.h Tue Jan 24 16:54:34 2006
@@ -24,6 +24,54 @@
#include <xen/softirq.h>
+// this number is an arbitary number which is not used for any other purpose
+// __builtin_trap(), FORCE_CRASH() 0x0
+// ski 0x80001, 0x80002
+// kdb 0x80100, 0x80101
+// kprobe 0x80200, jprobe 0x80300
+// kgdb 0x6665
+// gdb 0x99998 (#define IA64_BREAKPOINT 0x00003333300LL)
+
+// cdb should handle 0 and CDB_BREAK_NUM.
+#define CDB_BREAK_NUM 0x80800
+
+
+#ifndef __ASSEMBLY__
+
+#include <xen/gdbstub.h>
+
+// NOTE: on xen struct pt_regs = struct cpu_user_regs
+// see include/asm-ia64/linux-xen/asm/ptrace.h
+#ifdef CRASH_DEBUG
+// crash_debug=y
+
+/* The main trap handlers use these helper macros which include early bail. */
+static inline int debugger_trap_entry(
+ unsigned int vector, struct cpu_user_regs *regs)
+{
+ return 0;
+}
+
+extern int __trap_to_cdb(struct cpu_user_regs *r);
+static inline int debugger_trap_fatal(
+ unsigned int vector, struct cpu_user_regs *regs)
+{
+ (void)__trap_to_gdb(regs, vector);
+ return 0;
+}
+
+#define ____debugger_trap_immediate(b) __asm__ __volatile__ ("break.m "#b"\n")
+#define __debugger_trap_immediate(b) ____debugger_trap_immediate(b)
+#define debugger_trap_immediate() __debugger_trap_immediate(CDB_BREAK_NUM)
+
+//XXX temporal work around
+#ifndef CONFIG_SMP
+#define smp_send_stop() /* nothing */
+#endif
+
+#elif defined DOMU_DEBUG
+// domu_debug=y
+#warning "domu_debug is not implemented yet."
/* The main trap handlers use these helper macros which include early bail. */
static inline int debugger_trap_entry(
unsigned int vector, struct cpu_user_regs *regs)
@@ -37,6 +85,23 @@
return 0;
}
-#define debugger_trap_immediate() do {} while(0)
+#define debugger_trap_immediate() ((void)0)
+#else
+/* The main trap handlers use these helper macros which include early bail. */
+static inline int debugger_trap_entry(
+ unsigned int vector, struct cpu_user_regs *regs)
+{
+ return 0;
+}
+
+static inline int debugger_trap_fatal(
+ unsigned int vector, struct cpu_user_regs *regs)
+{
+ return 0;
+}
+
+#define debugger_trap_immediate() ((void)0)
+#endif
+#endif // __ASSEMBLLY__
#endif /* __ASM_DEBUGGER_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/domain.h Tue Jan 24 16:54:34 2006
@@ -9,8 +9,6 @@
#include <public/arch-ia64.h>
#include <asm/vmx_platform.h>
#include <xen/list.h>
-
-extern int arch_do_createdomain(struct vcpu *);
extern void domain_relinquish_resources(struct domain *);
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/linux-xen/asm/ptrace.h
--- a/xen/include/asm-ia64/linux-xen/asm/ptrace.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/linux-xen/asm/ptrace.h Tue Jan 24 16:54:34 2006
@@ -110,6 +110,7 @@
return (struct cpu_user_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
}
+struct pt_regs *guest_cpu_user_regs(void);
#else
struct pt_regs {
diff -r 40bb46f599d9 -r a38c292e8390
xen/include/asm-ia64/linux-xen/linux/interrupt.h
--- a/xen/include/asm-ia64/linux-xen/linux/interrupt.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/linux-xen/linux/interrupt.h Tue Jan 24 16:54:34 2006
@@ -104,6 +104,7 @@
al. should be converted to tasklets, not to softirqs.
*/
+#ifndef XEN
enum
{
HI_SOFTIRQ=0,
@@ -113,6 +114,7 @@
SCSI_SOFTIRQ,
TASKLET_SOFTIRQ
};
+#endif
/* softirq mask and active fields moved to irq_cpustat_t in
* asm/hardirq.h to get better cache usage. KAO
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/mm.h Tue Jan 24 16:54:34 2006
@@ -67,10 +67,12 @@
} free;
} u;
+#if 0
// following added for Linux compiling
page_flags_t flags;
atomic_t _count;
struct list_head lru; // is this the same as above "list"?
+#endif
};
#define set_page_count(p,v) atomic_set(&(p)->_count, v - 1)
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/vmmu.h Tue Jan 24 16:54:34 2006
@@ -151,8 +151,8 @@
typedef u64 *(THASH_FN)(PTA pta, u64 va);
typedef u64 *(TTAG_FN)(PTA pta, u64 va);
typedef u64 *(GET_MFN_FN)(domid_t d, u64 gpfn, u64 pages);
-typedef void *(REM_NOTIFIER_FN)(struct hash_cb *hcb, thash_data_t *entry);
-typedef void (RECYCLE_FN)(struct hash_cb *hc, u64 para);
+typedef void *(REM_NOTIFIER_FN)(struct thash_cb *hcb, thash_data_t *entry);
+typedef void (RECYCLE_FN)(struct thash_cb *hc, u64 para);
typedef ia64_rr (GET_RR_FN)(struct vcpu *vcpu, u64 reg);
typedef thash_data_t *(FIND_OVERLAP_FN)(struct thash_cb *hcb,
u64 va, u64 ps, int rid, char cl, search_section_t s_sect);
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/vtm.h
--- a/xen/include/asm-ia64/vtm.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/vtm.h Tue Jan 24 16:54:34 2006
@@ -23,7 +23,7 @@
#ifndef _VTM_H_
#define _VTM_H_
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/types.h>
#define MAX_JUMP_STEP (5000) /* 500ms, max jump step */
@@ -46,7 +46,7 @@
uint64_t cfg_max_jump; // max jump within one time suspendsion
uint64_t cfg_min_grun; // min guest running time since last jump
// uint64_t latest_read_itc; // latest guest read ITC
- struct ac_timer vtm_timer;
+ struct timer vtm_timer;
// int triggered;
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/debugger.h
--- a/xen/include/asm-x86/debugger.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/debugger.h Tue Jan 24 16:54:34 2006
@@ -42,19 +42,19 @@
#if defined(CRASH_DEBUG)
-extern int __trap_to_cdb(struct cpu_user_regs *r);
+#include <xen/gdbstub.h>
#define __debugger_trap_entry(_v, _r) (0)
static inline int __debugger_trap_fatal(
unsigned int vector, struct cpu_user_regs *regs)
{
- (void)__trap_to_cdb(regs);
+ (void)__trap_to_gdb(regs, vector);
return (vector == TRAP_int3); /* int3 is harmless */
}
/* Int3 is a trivial way to gather cpu_user_regs context. */
-#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
+#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
#elif 0
@@ -73,7 +73,7 @@
}
/* Int3 is a trivial way to gather cpu_user_regs context. */
-#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
+#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
#else
@@ -100,6 +100,8 @@
}
#define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
+#ifndef debugger_trap_immediate
#define debugger_trap_immediate() (__debugger_trap_immediate())
+#endif
#endif /* __X86_DEBUGGER_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/domain.h Tue Jan 24 16:54:34 2006
@@ -13,12 +13,43 @@
unsigned long eip;
};
+#define MAPHASH_ENTRIES 8
+#define MAPHASH_HASHFN(pfn) ((pfn) & (MAPHASH_ENTRIES-1))
+#define MAPHASHENT_NOTINUSE ((u16)~0U)
+struct vcpu_maphash {
+ struct vcpu_maphash_entry {
+ unsigned long pfn;
+ uint16_t idx;
+ uint16_t refcnt;
+ } hash[MAPHASH_ENTRIES];
+} __cacheline_aligned;
+
+#define MAPCACHE_ORDER 10
+#define MAPCACHE_ENTRIES (1 << MAPCACHE_ORDER)
struct mapcache {
+ /* The PTEs that provide the mappings, and a cursor into the array. */
l1_pgentry_t *l1tab;
unsigned int cursor;
+
+ /* Protects map_domain_page(). */
+ spinlock_t lock;
+
+ /* Garbage mappings are flushed from TLBs in batches called 'epochs'. */
unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS];
- spinlock_t lock;
+ u32 tlbflush_timestamp;
+
+ /* Which mappings are in use, and which are garbage to reap next epoch? */
+ unsigned long inuse[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
+ unsigned long garbage[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
+
+ /* Lock-free per-VCPU hash of recently-used mappings. */
+ struct vcpu_maphash vcpu_maphash[MAX_VIRT_CPUS];
};
+
+extern void mapcache_init(struct domain *);
+
+/* x86/64: toggle guest between kernel and user modes. */
+extern void toggle_guest_mode(struct vcpu *);
struct arch_domain
{
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/mm.h Tue Jan 24 16:54:34 2006
@@ -309,16 +309,13 @@
unsigned long l1va;
/* Copy of the p.t. page, taken before guest is given write access. */
l1_pgentry_t *page;
- /* A temporary Xen mapping of the actual p.t. page. */
- l1_pgentry_t *pl1e;
/* Index in L2 page table where this L1 p.t. is always hooked. */
unsigned int l2_idx; /* NB. Only used for PTWR_PT_ACTIVE. */
/* Info about last ptwr update batch. */
unsigned int prev_nr_updates;
- /* Exec domain which created writable mapping. */
+ /* VCPU which created writable mapping. */
struct vcpu *vcpu;
- /* EIP of the address which took the original write fault
- used for stats collection only */
+ /* EIP of the original write fault (stats collection only). */
unsigned long eip;
};
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/nmi.h
--- a/xen/include/asm-x86/nmi.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/nmi.h Tue Jan 24 16:54:34 2006
@@ -1,6 +1,8 @@
#ifndef ASM_NMI_H
#define ASM_NMI_H
+
+#include <public/nmi.h>
struct cpu_user_regs;
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/processor.h Tue Jan 24 16:54:34 2006
@@ -123,6 +123,7 @@
#define TBF_EXCEPTION_ERRCODE 2
#define TBF_INTERRUPT 8
#define TBF_FAILSAFE 16
+#define TBF_SLOW_IRET 32
/* 'arch_vcpu' flags values */
#define _TF_kernel_mode 0
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/vmx_vlapic.h
--- a/xen/include/asm-x86/vmx_vlapic.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/vmx_vlapic.h Tue Jan 24 16:54:34 2006
@@ -187,7 +187,7 @@
uint32_t timer_current;
uint32_t timer_divconf;
uint32_t timer_divide_counter;
- struct ac_timer vlapic_timer;
+ struct timer vlapic_timer;
int intr_pending_count[MAX_VECTOR];
s_time_t timer_current_update;
uint32_t icr_high;
@@ -216,7 +216,7 @@
static inline int vlapic_timer_active(struct vlapic *vlapic)
{
- return active_ac_timer(&(vlapic->vlapic_timer));
+ return active_timer(&(vlapic->vlapic_timer));
}
int vlapic_find_highest_irr(struct vlapic *vlapic);
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/vmx_vmcs.h Tue Jan 24 16:54:34 2006
@@ -100,7 +100,7 @@
void *io_bitmap_a, *io_bitmap_b;
struct vlapic *vlapic;
u64 tsc_offset;
- struct ac_timer hlt_timer; /* hlt ins emulation wakeup timer */
+ struct timer hlt_timer; /* hlt ins emulation wakeup timer */
};
#define vmx_schedule_tail(next) \
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/vmx_vpit.h
--- a/xen/include/asm-x86/vmx_vpit.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/vmx_vpit.h Tue Jan 24 16:54:34 2006
@@ -6,7 +6,7 @@
#include <xen/lib.h>
#include <xen/time.h>
#include <xen/errno.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <asm/vmx_vmcs.h>
#include <asm/vmx_vpic.h>
@@ -23,7 +23,7 @@
u64 inject_point; /* the time inject virt intr */
u64 shift; /* save the value of offset - drift */
s_time_t scheduled; /* scheduled timer interrupt */
- struct ac_timer pit_timer; /* periodic timer for mode 2*/
+ struct timer pit_timer; /* periodic timer for mode 2*/
unsigned int channel; /* the pit channel, counter 0~2 */
unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
u32 period; /* pit frequency in ns */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/arch-ia64.h Tue Jan 24 16:54:34 2006
@@ -9,7 +9,7 @@
/* Maximum number of virtual CPUs in multi-processor guests. */
/* WARNING: before changing this, check that shared_info fits on a page */
-#define MAX_VIRT_CPUS 1
+#define MAX_VIRT_CPUS 4
#ifndef __ASSEMBLY__
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/arch-x86_32.h Tue Jan 24 16:54:34 2006
@@ -135,6 +135,7 @@
unsigned long max_pfn; /* max pfn that appears in table */
/* Frame containing list of mfns containing list of mfns containing p2m. */
unsigned long pfn_to_mfn_frame_list_list;
+ unsigned long nmi_reason;
} arch_shared_info_t;
typedef struct {
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/arch-x86_64.h Tue Jan 24 16:54:34 2006
@@ -88,11 +88,20 @@
#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
/*
- * int HYPERVISOR_switch_to_user(void)
+ * int HYPERVISOR_iret(void)
* All arguments are on the kernel stack, in the following format.
* Never returns if successful. Current kernel context is lost.
+ * The saved CS is mapped as follows:
+ * RING0 -> RING3 kernel mode.
+ * RING1 -> RING3 kernel mode.
+ * RING2 -> RING3 kernel mode.
+ * RING3 -> RING3 user mode.
+ * However RING0 indicates that the guest kernel should return to iteself
+ * directly with
+ * orb $3,1*8(%rsp)
+ * iretq
* If flags contains VGCF_IN_SYSCALL:
- * Restore RAX, RIP, RFLAGS, RSP.
+ * Restore RAX, RIP, RFLAGS, RSP.
* Discard R11, RCX, CS, SS.
* Otherwise:
* Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
@@ -100,10 +109,19 @@
*/
/* Guest exited in SYSCALL context? Return to guest with SYSRET? */
#define VGCF_IN_SYSCALL (1<<8)
+struct iret_context {
+ /* Top of stack (%rsp at point of hypercall). */
+ uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
+ /* Bottom of iret stack frame. */
+};
+/*
+ * For compatibility with HYPERVISOR_switch_to_user which is the old
+ * name for HYPERVISOR_iret.
+ */
struct switch_to_user {
/* Top of stack (%rsp at point of hypercall). */
uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
- /* Bottom of switch_to_user stack frame. */
+ /* Bottom of iret stack frame. */
};
/*
@@ -202,6 +220,7 @@
unsigned long max_pfn; /* max pfn that appears in table */
/* Frame containing list of mfns containing list of mfns containing p2m. */
unsigned long pfn_to_mfn_frame_list_list;
+ unsigned long nmi_reason;
} arch_shared_info_t;
typedef struct {
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/xen.h
--- a/xen/include/public/xen.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/xen.h Tue Jan 24 16:54:34 2006
@@ -53,12 +53,14 @@
#define __HYPERVISOR_grant_table_op 20
#define __HYPERVISOR_vm_assist 21
#define __HYPERVISOR_update_va_mapping_otherdomain 22
-#define __HYPERVISOR_switch_vm86 23 /* x86/32 only */
-#define __HYPERVISOR_switch_to_user 23 /* x86/64 only */
+#define __HYPERVISOR_iret 23 /* x86 only */
+#define __HYPERVISOR_switch_vm86 23 /* x86/32 only (obsolete name) */
+#define __HYPERVISOR_switch_to_user 23 /* x86/64 only (obsolete name) */
#define __HYPERVISOR_vcpu_op 24
#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
#define __HYPERVISOR_mmuext_op 26
#define __HYPERVISOR_acm_op 27
+#define __HYPERVISOR_nmi_op 28
/*
* VIRTUAL INTERRUPTS
@@ -69,10 +71,7 @@
#define VIRQ_DEBUG 1 /* Request guest to dump debug info. */
#define VIRQ_CONSOLE 2 /* (DOM0) Bytes received on emergency console. */
#define VIRQ_DOM_EXC 3 /* (DOM0) Exceptional event for some domain. */
-#define VIRQ_PARITY_ERR 4 /* (DOM0) NMI parity error (port 0x61, bit 7). */
-#define VIRQ_IO_ERR 5 /* (DOM0) NMI I/O error (port 0x61, bit 6). */
#define VIRQ_DEBUGGER 6 /* (DOM0) A domain has paused for debugging. */
-#define VIRQ_NMI 7 /* (DOM0) Unknown NMI (not from ISA port 0x61).*/
#define NR_VIRQS 8
/*
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/domain.h Tue Jan 24 16:54:34 2006
@@ -13,12 +13,12 @@
extern void free_vcpu_struct(struct vcpu *v);
-extern int arch_do_createdomain(struct vcpu *v);
+extern int arch_domain_create(struct domain *d);
+
+extern void arch_domain_destroy(struct domain *d);
extern int arch_set_info_guest(
struct vcpu *v, struct vcpu_guest_context *c);
-
-extern void free_perdomain_pt(struct domain *d);
extern void domain_relinquish_resources(struct domain *d);
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/domain_page.h
--- a/xen/include/xen/domain_page.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/domain_page.h Tue Jan 24 16:54:34 2006
@@ -2,6 +2,8 @@
* domain_page.h
*
* Allow temporary mapping of domain page frames into Xen space.
+ *
+ * Copyright (c) 2003-2006, Keir Fraser <keir@xxxxxxxxxxxxx>
*/
#ifndef __XEN_DOMAIN_PAGE_H__
@@ -10,22 +12,27 @@
#include <xen/config.h>
#include <xen/mm.h>
-#define map_domain_page(pfn) map_domain_pages(pfn,0)
-#define unmap_domain_page(va) unmap_domain_pages(va,0)
-
#ifdef CONFIG_DOMAIN_PAGE
/*
- * Maps a given range of page frames, returning the mapped virtual address. The
- * pages are now accessible until a corresponding call to unmap_domain_page().
+ * Map a given page frame, returning the mapped virtual address. The page is
+ * then accessible within the current VCPU until a corresponding unmap call.
*/
-extern void *map_domain_pages(unsigned long pfn, unsigned int order);
+extern void *map_domain_page(unsigned long pfn);
/*
- * Pass a VA within the first page of a range previously mapped with
- * map_omain_pages(). Those pages will then be removed from the mapping lists.
+ * Pass a VA within a page previously mapped in the context of the
+ * currently-executing VCPU via a call to map_domain_pages().
*/
-extern void unmap_domain_pages(void *va, unsigned int order);
+extern void unmap_domain_page(void *va);
+
+/*
+ * Similar to the above calls, except the mapping is accessible in all
+ * address spaces (not just within the VCPU that created the mapping). Global
+ * mappings can also be unmapped from any context.
+ */
+extern void *map_domain_page_global(unsigned long pfn);
+extern void unmap_domain_page_global(void *va);
#define DMCACHE_ENTRY_VALID 1U
#define DMCACHE_ENTRY_HELD 2U
@@ -87,8 +94,11 @@
#else /* !CONFIG_DOMAIN_PAGE */
-#define map_domain_pages(pfn,order) phys_to_virt((pfn)<<PAGE_SHIFT)
-#define unmap_domain_pages(va,order) ((void)((void)(va),(void)(order)))
+#define map_domain_page(pfn) phys_to_virt((pfn)<<PAGE_SHIFT)
+#define unmap_domain_page(va) ((void)(va))
+
+#define map_domain_page_global(pfn) phys_to_virt((pfn)<<PAGE_SHIFT)
+#define unmap_domain_page_global(va) ((void)(va))
struct domain_mmap_cache {
};
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/perfc_defn.h
--- a/xen/include/xen/perfc_defn.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/perfc_defn.h Tue Jan 24 16:54:34 2006
@@ -32,7 +32,7 @@
PERFCOUNTER_CPU(irq_time, "cycles spent in irq handler")
PERFCOUNTER_CPU(apic_timer, "apic timer interrupts")
-PERFCOUNTER_CPU(ac_timer_max, "ac_timer max error (ns)")
+PERFCOUNTER_CPU(timer_max, "timer max error (ns)")
PERFCOUNTER_CPU(sched_irq, "sched: timer")
PERFCOUNTER_CPU(sched_run, "sched: runs through scheduler")
PERFCOUNTER_CPU(sched_ctx, "sched: context switches")
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/sched-if.h
--- a/xen/include/xen/sched-if.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/sched-if.h Tue Jan 24 16:54:34 2006
@@ -16,16 +16,47 @@
struct vcpu *curr; /* current task */
struct vcpu *idle; /* idle task for this cpu */
void *sched_priv;
- struct ac_timer s_timer; /* scheduling timer */
+ struct timer s_timer; /* scheduling timer */
unsigned long tick; /* current periodic 'tick' */
#ifdef BUCKETS
u32 hist[BUCKETS]; /* for scheduler latency histogram */
#endif
} __cacheline_aligned;
+extern struct schedule_data schedule_data[];
+
+static inline void vcpu_schedule_lock(struct vcpu *v)
+{
+ unsigned int cpu;
+
+ for ( ; ; )
+ {
+ cpu = v->processor;
+ spin_lock(&schedule_data[cpu].schedule_lock);
+ if ( likely(v->processor == cpu) )
+ break;
+ spin_unlock(&schedule_data[cpu].schedule_lock);
+ }
+}
+
+#define vcpu_schedule_lock_irq(v) \
+ do { local_irq_disable(); vcpu_schedule_lock(v); } while ( 0 )
+#define vcpu_schedule_lock_irqsave(v, flags) \
+ do { local_irq_save(flags); vcpu_schedule_lock(v); } while ( 0 )
+
+static inline void vcpu_schedule_unlock(struct vcpu *v)
+{
+ spin_unlock(&schedule_data[v->processor].schedule_lock);
+}
+
+#define vcpu_schedule_unlock_irq(v) \
+ do { vcpu_schedule_unlock(v); local_irq_enable(); } while ( 0 )
+#define vcpu_schedule_unlock_irqrestore(v, flags) \
+ do { vcpu_schedule_unlock(v); local_irq_restore(flags); } while ( 0 )
+
struct task_slice {
struct vcpu *task;
- s_time_t time;
+ s_time_t time;
};
struct scheduler {
@@ -48,6 +79,4 @@
void (*dump_cpu_state) (int);
};
-extern struct schedule_data schedule_data[];
-
#endif /* __XEN_SCHED_IF_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/sched.h Tue Jan 24 16:54:34 2006
@@ -9,7 +9,7 @@
#include <public/xen.h>
#include <public/dom0_ops.h>
#include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
#include <xen/grant_table.h>
#include <xen/rangeset.h>
#include <asm/domain.h>
@@ -63,7 +63,7 @@
struct vcpu *next_in_list;
- struct ac_timer timer; /* one-shot timer for timeout values */
+ struct timer timer; /* one-shot timer for timeout values */
unsigned long sleep_tick; /* tick at which this vcpu started sleep */
s_time_t lastschd; /* time this domain was last scheduled */
@@ -80,6 +80,8 @@
/* Bitmask of CPUs on which this VCPU may run. */
cpumask_t cpu_affinity;
+
+ unsigned long nmi_addr; /* NMI callback address. */
/* Bitmask of CPUs which are holding onto this VCPU's state. */
cpumask_t vcpu_dirty_cpumask;
@@ -183,13 +185,13 @@
struct domain *alloc_domain(void);
void free_domain(struct domain *d);
-#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
+#define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
#define put_domain(_d) \
- if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
+ if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
/*
* Use this when you don't have an existing reference to @d. It returns
- * FALSE if @d is being destructed.
+ * FALSE if @d is being destroyed.
*/
static always_inline int get_domain(struct domain *d)
{
@@ -197,7 +199,7 @@
do
{
old = seen;
- if ( unlikely(_atomic_read(old) & DOMAIN_DESTRUCTED) )
+ if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
return 0;
_atomic_set(new, _atomic_read(old) + 1);
seen = atomic_compareandswap(old, new, &d->refcnt);
@@ -208,15 +210,15 @@
/*
* Use this when you already have, or are borrowing, a reference to @d.
- * In this case we know that @d cannot be destructed under our feet.
+ * In this case we know that @d cannot be destroyed under our feet.
*/
static inline void get_knownalive_domain(struct domain *d)
{
atomic_inc(&d->refcnt);
- ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
+ ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
}
-extern struct domain *do_createdomain(
+extern struct domain *domain_create(
domid_t dom_id, unsigned int cpu);
extern int construct_dom0(
struct domain *d,
@@ -226,7 +228,7 @@
extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *);
struct domain *find_domain_by_id(domid_t dom);
-extern void domain_destruct(struct domain *d);
+extern void domain_destroy(struct domain *d);
extern void domain_kill(struct domain *d);
extern void domain_shutdown(struct domain *d, u8 reason);
extern void domain_pause_for_debugger(void);
@@ -361,6 +363,12 @@
/* VCPU is not-runnable */
#define _VCPUF_down 5
#define VCPUF_down (1UL<<_VCPUF_down)
+ /* NMI callback pending for this VCPU? */
+#define _VCPUF_nmi_pending 8
+#define VCPUF_nmi_pending (1UL<<_VCPUF_nmi_pending)
+ /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
+#define _VCPUF_nmi_masked 9
+#define VCPUF_nmi_masked (1UL<<_VCPUF_nmi_masked)
/*
* Per-domain flags (domain_flags).
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/softirq.h
--- a/xen/include/xen/softirq.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/softirq.h Tue Jan 24 16:54:34 2006
@@ -2,11 +2,11 @@
#define __XEN_SOFTIRQ_H__
/* Common softirqs come first in the following list. */
-#define AC_TIMER_SOFTIRQ 0
+#define TIMER_SOFTIRQ 0
#define SCHEDULE_SOFTIRQ 1
#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
#define KEYPRESS_SOFTIRQ 3
-#define NMI_DOM0_SOFTIRQ 4
+#define NMI_SOFTIRQ 4
#define PAGE_SCRUB_SOFTIRQ 5
#define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ 6
#define NR_SOFTIRQS 7
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h
Tue Jan 24 16:54:34 2006
@@ -0,0 +1,33 @@
+/*
+ * include/asm-xen/asm-i386/mach-xen/mach_traps.h
+ *
+ * Machine specific NMI handling for Xen
+ */
+#ifndef _MACH_TRAPS_H
+#define _MACH_TRAPS_H
+
+#include <linux/bitops.h>
+#include <asm-xen/xen-public/nmi.h>
+
+static inline void clear_mem_error(unsigned char reason) {}
+static inline void clear_io_check_error(unsigned char reason) {}
+
+static inline unsigned char get_nmi_reason(void)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ unsigned char reason = 0;
+
+ /* construct a value which looks like it came from
+ * port 0x61.
+ */
+ if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
+ reason |= 0x40;
+ if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
+ reason |= 0x80;
+
+ return reason;
+}
+
+static inline void reassert_nmi(void) {}
+
+#endif /* !_MACH_TRAPS_H */
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/nmi.h
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/nmi.h Tue Jan 24
16:54:34 2006
@@ -0,0 +1,75 @@
+/*
+ * linux/include/asm-i386/nmi.h
+ */
+#ifndef ASM_NMI_H
+#define ASM_NMI_H
+
+#include <linux/pm.h>
+
+#include <asm-xen/xen-public/nmi.h>
+
+struct pt_regs;
+
+typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
+
+/**
+ * set_nmi_callback
+ *
+ * Set a handler for an NMI. Only one handler may be
+ * set. Return 1 if the NMI was handled.
+ */
+void set_nmi_callback(nmi_callback_t callback);
+
+/**
+ * unset_nmi_callback
+ *
+ * Remove the handler previously set.
+ */
+void unset_nmi_callback(void);
+
+#ifdef CONFIG_PM
+
+/** Replace the PM callback routine for NMI. */
+struct pm_dev * set_nmi_pm_callback(pm_callback callback);
+
+/** Unset the PM callback routine back to the default. */
+void unset_nmi_pm_callback(struct pm_dev * dev);
+
+#else
+
+static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
+{
+ return 0;
+}
+
+static inline void unset_nmi_pm_callback(struct pm_dev * dev)
+{
+}
+
+#endif /* CONFIG_PM */
+
+extern void default_do_nmi(struct pt_regs *);
+extern void die_nmi(char *str, struct pt_regs *regs);
+
+static inline unsigned char get_nmi_reason(void)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ unsigned char reason = 0;
+
+ /* construct a value which looks like it came from
+ * port 0x61.
+ */
+ if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
+ reason |= 0x40;
+ if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
+ reason |= 0x80;
+
+ return reason;
+}
+
+extern int panic_on_timeout;
+extern int unknown_nmi_panic;
+
+extern int check_nmi_watchdog(void);
+
+#endif /* ASM_NMI_H */
diff -r 40bb46f599d9 -r a38c292e8390
patches/linux-2.6.12/i386-mach-io-check-nmi.patch
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/patches/linux-2.6.12/i386-mach-io-check-nmi.patch Tue Jan 24 16:54:34 2006
@@ -0,0 +1,43 @@
+--- ref-linux-2.6.12/arch/i386/kernel/traps.c 2005-12-19 09:23:44.000000000
+0000
++++ linux-2.6.12-xen0/arch/i386/kernel/traps.c 2006-01-05 15:51:52.000000000
+0000
+@@ -521,18 +521,11 @@
+
+ static void io_check_error(unsigned char reason, struct pt_regs * regs)
+ {
+- unsigned long i;
+-
+ printk("NMI: IOCK error (debug interrupt?)\n");
+ show_registers(regs);
+
+ /* Re-enable the IOCK line, wait for a few seconds */
+- reason = (reason & 0xf) | 8;
+- outb(reason, 0x61);
+- i = 2000;
+- while (--i) udelay(1000);
+- reason &= ~8;
+- outb(reason, 0x61);
++ clear_io_check_error(reason);
+ }
+
+ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+--- ref-linux-2.6.12/include/asm-i386/mach-default/mach_traps.h
2005-06-17 20:48:29.000000000 +0100
++++ linux-2.6.12-xen0/include/asm-i386/mach-default/mach_traps.h
2006-01-05 15:52:33.000000000 +0000
+@@ -15,6 +15,18 @@
+ outb(reason, 0x61);
+ }
+
++static inline void clear_io_check_error(unsigned char reason)
++{
++ unsigned long i;
++
++ reason = (reason & 0xf) | 8;
++ outb(reason, 0x61);
++ i = 2000;
++ while (--i) udelay(1000);
++ reason &= ~8;
++ outb(reason, 0x61);
++}
++
+ static inline unsigned char get_nmi_reason(void)
+ {
+ return inb(0x61);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/gdbstub.c
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/gdbstub.c Tue Jan 24 16:54:34 2006
@@ -0,0 +1,811 @@
+/*
+ * ia64-specific cdb routines
+ * cdb xen/ia64 by Isaku Yamahta <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ * some routines are stolen from kgdb/ia64.
+ */
+/*
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+/*
+ * Copyright (C) 2000-2001 VERITAS Software Corporation.
+ */
+/*
+ * Contributor: Lake Stevens Instrument Division$
+ * Written by: Glenn Engel $
+ * Updated by: Amit Kale<akale@xxxxxxxxxxx>
+ * Modified for 386 by Jim Kingdon, Cygnus Support.
+ * Origianl kgdb, compatibility with 2.1.xx kernel by David Grothe
<dave@xxxxxxxx>
+ *
+ */
+
+
+#include <xen/lib.h>
+#include <asm/byteorder.h>
+#include <asm/debugger.h>
+#include <asm/uaccess.h>
+
+#define USE_UNWIND
+
+#ifdef USE_UNWIND
+#include <asm/unwind.h>
+#endif
+
+/* Printk isn't particularly safe just after we've trapped to the
+ debugger. so avoid it. */
+#define dbg_printk(...)
+//#define dbg_printk(...) printk(__VA_ARGS__)
+
+u16
+gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
+{
+ /* XXX */
+ return 1;
+}
+
+void
+gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+ gdb_send_reply("", ctx);
+}
+
+void
+gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
+ struct gdb_context *ctx)
+{
+ /* XXX TODO */
+ gdb_send_reply("E02", ctx);
+}
+
+/* Like copy_from_user, but safe to call with interrupts disabled.
+ Trust me, and don't look behind the curtain. */
+unsigned
+gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
+{
+ int val;
+ __asm__ __volatile__(
+ "cmp4.eq p6, p0 = r0, %1\n"
+ "(p6) br.cond.dptk 2f\n"
+ "[1:]\n"
+ ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
+ "[99:] ld1 %0 = [%3], 1\n"
+ ";;\n"
+ ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
+ "[99:] st1 [%2] = %0, 1\n"
+ "adds %1 = -1, %1\n"
+ ";;\n"
+ "cmp4.eq p0, p6 = r0, %1\n"
+ "(p6) br.cond.dptk 1b\n"
+ "[2:]\n"
+ : "=r"(val), "=r"(len), "=r"(dest), "=r"(src)
+ : "1"(len), "2"(dest), "3"(src)
+ : "memory", "p6");
+ return len;
+}
+
+unsigned int
+gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
+{
+ /* XXX */
+ return len;
+}
+
+#define NUM_REGS 590
+#define REGISTER_BYTES (NUM_REGS*8+128*8)
+#define REGISTER_BYTE(N) (((N) * 8)
\
+ + ((N) <= IA64_FR0_REGNUM ? \
+ 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
+#define REGISTER_SIZE(N) \
+ (((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
+#define IA64_GR0_REGNUM 0
+#define IA64_FR0_REGNUM 128
+#define IA64_FR127_REGNUM (IA64_FR0_REGNUM+127)
+#define IA64_PR0_REGNUM 256
+#define IA64_BR0_REGNUM 320
+#define IA64_VFP_REGNUM 328
+#define IA64_PR_REGNUM 330
+#define IA64_IP_REGNUM 331
+#define IA64_PSR_REGNUM 332
+#define IA64_CFM_REGNUM 333
+#define IA64_AR0_REGNUM 334
+#define IA64_NAT0_REGNUM 462
+#define IA64_NAT31_REGNUM (IA64_NAT0_REGNUM+31)
+#define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM+32)
+#define IA64_RSC_REGNUM (IA64_AR0_REGNUM+16)
+#define IA64_BSP_REGNUM (IA64_AR0_REGNUM+17)
+#define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM+18)
+#define IA64_RNAT_REGNUM (IA64_AR0_REGNUM+19)
+#define IA64_FCR_REGNUM (IA64_AR0_REGNUM+21)
+#define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM+24)
+#define IA64_CSD_REGNUM (IA64_AR0_REGNUM+25)
+#define IA64_SSD_REGNUM (IA64_AR0_REGNUM+26)
+#define IA64_CFLG_REGNUM (IA64_AR0_REGNUM+27)
+#define IA64_FSR_REGNUM (IA64_AR0_REGNUM+28)
+#define IA64_FIR_REGNUM (IA64_AR0_REGNUM+29)
+#define IA64_FDR_REGNUM (IA64_AR0_REGNUM+30)
+#define IA64_CCV_REGNUM (IA64_AR0_REGNUM+32)
+#define IA64_UNAT_REGNUM (IA64_AR0_REGNUM+36)
+#define IA64_FPSR_REGNUM (IA64_AR0_REGNUM+40)
+#define IA64_ITC_REGNUM (IA64_AR0_REGNUM+44)
+#define IA64_PFS_REGNUM (IA64_AR0_REGNUM+64)
+#define IA64_LC_REGNUM (IA64_AR0_REGNUM+65)
+#define IA64_EC_REGNUM (IA64_AR0_REGNUM+66)
+
+#ifndef USE_UNWIND
+struct regs_to_cpu_user_resgs_index {
+ unsigned int reg;
+ unsigned int ptregoff;
+};
+
+#define ptoff(V) ((unsigned int)&((struct cpu_user_regs*)0x0)->V)
+
+// gr
+static const struct regs_to_cpu_user_resgs_index
+gr_reg_to_cpu_user_regs_index[] = {
+ {IA64_GR0_REGNUM + 8, ptoff(r8)},
+ {IA64_GR0_REGNUM + 9, ptoff(r9)},
+ {IA64_GR0_REGNUM + 10, ptoff(r10)},
+ {IA64_GR0_REGNUM + 11, ptoff(r11)},
+ {IA64_GR0_REGNUM + 1, ptoff(r1)},
+ {IA64_GR0_REGNUM + 12, ptoff(r12)},
+ {IA64_GR0_REGNUM + 13, ptoff(r13)},
+ {IA64_GR0_REGNUM + 15, ptoff(r15)},
+
+ {IA64_GR0_REGNUM + 14, ptoff(r14)},
+ {IA64_GR0_REGNUM + 2, ptoff(r2)},
+ {IA64_GR0_REGNUM + 3, ptoff(r3)},
+ {IA64_GR0_REGNUM + 16, ptoff(r16)},
+ {IA64_GR0_REGNUM + 17, ptoff(r17)},
+ {IA64_GR0_REGNUM + 18, ptoff(r18)},
+ {IA64_GR0_REGNUM + 19, ptoff(r19)},
+ {IA64_GR0_REGNUM + 20, ptoff(r20)},
+ {IA64_GR0_REGNUM + 21, ptoff(r21)},
+ {IA64_GR0_REGNUM + 22, ptoff(r22)},
+ {IA64_GR0_REGNUM + 23, ptoff(r23)},
+ {IA64_GR0_REGNUM + 24, ptoff(r24)},
+ {IA64_GR0_REGNUM + 25, ptoff(r25)},
+ {IA64_GR0_REGNUM + 26, ptoff(r26)},
+ {IA64_GR0_REGNUM + 27, ptoff(r27)},
+ {IA64_GR0_REGNUM + 28, ptoff(r28)},
+ {IA64_GR0_REGNUM + 29, ptoff(r29)},
+ {IA64_GR0_REGNUM + 30, ptoff(r30)},
+ {IA64_GR0_REGNUM + 31, ptoff(r31)},
+
+ {IA64_GR0_REGNUM + 4, ptoff(r4)},
+ {IA64_GR0_REGNUM + 5, ptoff(r5)},
+ {IA64_GR0_REGNUM + 6, ptoff(r6)},
+ {IA64_GR0_REGNUM + 7, ptoff(r7)},
+};
+static const int gr_reg_to_cpu_user_regs_index_max =
+ sizeof(gr_reg_to_cpu_user_regs_index) /
+ sizeof(gr_reg_to_cpu_user_regs_index[0]);
+
+// br
+static const struct regs_to_cpu_user_resgs_index
+br_reg_to_cpu_user_regs_index[] = {
+ {IA64_BR0_REGNUM + 0, ptoff(b0)},
+ {IA64_BR0_REGNUM + 6, ptoff(b6)},
+ {IA64_BR0_REGNUM + 7, ptoff(b7)},
+};
+static const int br_reg_to_cpu_user_regs_index_max =
+ sizeof(br_reg_to_cpu_user_regs_index) /
+ sizeof(br_reg_to_cpu_user_regs_index[0]);
+
+// f
+static const struct regs_to_cpu_user_resgs_index
+fr_reg_to_cpu_user_regs_index[] = {
+ {IA64_FR0_REGNUM + 6, ptoff(f6)},
+ {IA64_FR0_REGNUM + 7, ptoff(f7)},
+ {IA64_FR0_REGNUM + 8, ptoff(f8)},
+ {IA64_FR0_REGNUM + 9, ptoff(f9)},
+ {IA64_FR0_REGNUM + 10, ptoff(f10)},
+ {IA64_FR0_REGNUM + 11, ptoff(f11)},
+};
+static const int fr_reg_to_cpu_user_regs_index_max =
+ sizeof(fr_reg_to_cpu_user_regs_index) /
+ sizeof(fr_reg_to_cpu_user_regs_index[0]);
+
+
+void
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+ struct gdb_context *ctx)
+{
+ unsigned long reg = IA64_IP_REGNUM;
+ char buf[9];
+ int i;
+
+ dbg_printk("Register read regnum = 0x%lx\n", regnum);
+ if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) {
+ for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) {
+ if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) {
+ reg = *(unsigned long*)(((char*)regs) +
gr_reg_to_cpu_user_regs_index[i].ptregoff);
+ break;
+ }
+ }
+ if (i == gr_reg_to_cpu_user_regs_index_max) {
+ goto out_err;
+ }
+ } else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) {
+ for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) {
+ if (br_reg_to_cpu_user_regs_index[i].reg == regnum) {
+ reg = *(unsigned long*)(((char*)regs) +
br_reg_to_cpu_user_regs_index[i].ptregoff);
+ break;
+ }
+ }
+ if (i == br_reg_to_cpu_user_regs_index_max) {
+ goto out_err;
+ }
+ } else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM +
11) {
+ for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) {
+ if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) {
+ reg = *(unsigned long*)(((char*)regs) +
fr_reg_to_cpu_user_regs_index[i].ptregoff);
+ break;
+ }
+ }
+ if (i == fr_reg_to_cpu_user_regs_index_max) {
+ goto out_err;
+ }
+ } else if (regnum == IA64_CSD_REGNUM) {
+ reg = regs->ar_csd;
+ } else if (regnum == IA64_SSD_REGNUM) {
+ reg = regs->ar_ssd;
+ } else if (regnum == IA64_PSR_REGNUM) {
+ reg = regs->cr_ipsr;
+ } else if (regnum == IA64_IP_REGNUM) {
+ reg = regs->cr_iip;
+ } else if (regnum == IA64_CFM_REGNUM) {
+ reg = regs->cr_ifs;
+ } else if (regnum == IA64_UNAT_REGNUM) {
+ reg = regs->ar_unat;
+ } else if (regnum == IA64_PFS_REGNUM) {
+ reg = regs->ar_pfs;
+ } else if (regnum == IA64_RSC_REGNUM) {
+ reg = regs->ar_rsc;
+ } else if (regnum == IA64_RNAT_REGNUM) {
+ reg = regs->ar_rnat;
+ } else if (regnum == IA64_BSPSTORE_REGNUM) {
+ reg = regs->ar_bspstore;
+ } else if (regnum == IA64_PR_REGNUM) {
+ reg = regs->pr;
+ } else if (regnum == IA64_FPSR_REGNUM) {
+ reg = regs->ar_fpsr;
+ } else if (regnum == IA64_CCV_REGNUM) {
+ reg = regs->ar_ccv;
+ } else {
+ // emul_unat, rfi_pfs
+ goto out_err;
+ }
+
+ dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg);
+ sprintf(buf, "%.08lx", swab64(reg));
+out:
+ return gdb_send_reply(buf, ctx);
+
+out_err:
+ dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
+ sprintf(buf, "%s", "x");
+ goto out;
+}
+#else
+
+#define ptoff(V) ((unsigned int) &((struct pt_regs *)0x0)->V)
+struct reg_to_ptreg_index {
+ unsigned int reg;
+ unsigned int ptregoff;
+};
+
+static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
+ {IA64_GR0_REGNUM + 1, ptoff(r1)},
+ {IA64_GR0_REGNUM + 2, ptoff(r2)},
+ {IA64_GR0_REGNUM + 3, ptoff(r3)},
+ {IA64_GR0_REGNUM + 8, ptoff(r8)},
+ {IA64_GR0_REGNUM + 9, ptoff(r9)},
+ {IA64_GR0_REGNUM + 10, ptoff(r10)},
+ {IA64_GR0_REGNUM + 11, ptoff(r11)},
+ {IA64_GR0_REGNUM + 12, ptoff(r12)},
+ {IA64_GR0_REGNUM + 13, ptoff(r13)},
+ {IA64_GR0_REGNUM + 14, ptoff(r14)},
+ {IA64_GR0_REGNUM + 15, ptoff(r15)},
+ {IA64_GR0_REGNUM + 16, ptoff(r16)},
+ {IA64_GR0_REGNUM + 17, ptoff(r17)},
+ {IA64_GR0_REGNUM + 18, ptoff(r18)},
+ {IA64_GR0_REGNUM + 19, ptoff(r19)},
+ {IA64_GR0_REGNUM + 20, ptoff(r20)},
+ {IA64_GR0_REGNUM + 21, ptoff(r21)},
+ {IA64_GR0_REGNUM + 22, ptoff(r22)},
+ {IA64_GR0_REGNUM + 23, ptoff(r23)},
+ {IA64_GR0_REGNUM + 24, ptoff(r24)},
+ {IA64_GR0_REGNUM + 25, ptoff(r25)},
+ {IA64_GR0_REGNUM + 26, ptoff(r26)},
+ {IA64_GR0_REGNUM + 27, ptoff(r27)},
+ {IA64_GR0_REGNUM + 28, ptoff(r28)},
+ {IA64_GR0_REGNUM + 29, ptoff(r29)},
+ {IA64_GR0_REGNUM + 30, ptoff(r30)},
+ {IA64_GR0_REGNUM + 31, ptoff(r31)},
+};
+
+static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
+ {IA64_BR0_REGNUM, ptoff(b0)},
+ {IA64_BR0_REGNUM + 6, ptoff(b6)},
+ {IA64_BR0_REGNUM + 7, ptoff(b7)},
+};
+
+static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = {
+ {IA64_PFS_REGNUM, ptoff(ar_pfs)},
+ {IA64_UNAT_REGNUM, ptoff(ar_unat)},
+ {IA64_RNAT_REGNUM, ptoff(ar_rnat)},
+ {IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)},
+ {IA64_RSC_REGNUM, ptoff(ar_rsc)},
+ {IA64_CSD_REGNUM, ptoff(ar_csd)},
+ {IA64_SSD_REGNUM, ptoff(ar_ssd)},
+ {IA64_FPSR_REGNUM, ptoff(ar_fpsr)},
+ {IA64_CCV_REGNUM, ptoff(ar_ccv)},
+};
+
+#ifndef XEN
+extern atomic_t cpu_doing_single_step;
+#endif
+
+static int kgdb_gr_reg(int regnum, struct unw_frame_info *info,
+ unsigned long *reg, int rw)
+{
+ char nat;
+
+ if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
+ (regnum >= (IA64_GR0_REGNUM + 4) &&
+ regnum <= (IA64_GR0_REGNUM + 7)))
+ return !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
+ reg, &nat, rw);
+ else
+ return 0;
+}
+static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+ int i, result = 1;
+ char nat;
+
+ if (!((regnum >= (IA64_GR0_REGNUM + 2) &&
+ regnum <= (IA64_GR0_REGNUM + 3)) ||
+ (regnum >= (IA64_GR0_REGNUM + 8) &&
+ regnum <= (IA64_GR0_REGNUM + 15)) ||
+ (regnum >= (IA64_GR0_REGNUM + 16) &&
+ regnum <= (IA64_GR0_REGNUM + 31))))
+ return 0;
+ else if (rw && ptregs) {
+ for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
+ if (gr_reg_to_ptreg_index[i].reg == regnum) {
+ *((unsigned long *)(((void *)ptregs) +
+ gr_reg_to_ptreg_index[i].ptregoff)) = *reg;
+ break;
+ }
+ } else if (!rw && ptregs) {
+ for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
+ if (gr_reg_to_ptreg_index[i].reg == regnum) {
+ *reg = *((unsigned long *)
+ (((void *)ptregs) +
+ gr_reg_to_ptreg_index[i].ptregoff));
+ break;
+ }
+ } else
+ result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
+ reg, &nat, rw);
+ return result;
+}
+
+static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+ int i, result = 1;
+
+ if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))
+ return 0;
+
+ switch (regnum) {
+ case IA64_BR0_REGNUM:
+ case IA64_BR0_REGNUM + 6:
+ case IA64_BR0_REGNUM + 7:
+ if (rw) {
+ for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
+ if (br_reg_to_ptreg_index[i].reg == regnum) {
+ *((unsigned long *)
+ (((void *)ptregs) +
+ br_reg_to_ptreg_index[i].ptregoff)) =
+ *reg;
+ break;
+ }
+ } else
+ for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
+ if (br_reg_to_ptreg_index[i].reg == regnum) {
+ *reg = *((unsigned long *)
+ (((void *)ptregs) +
+ br_reg_to_ptreg_index[i].
+ ptregoff));
+ break;
+ }
+ break;
+ case IA64_BR0_REGNUM + 1:
+ case IA64_BR0_REGNUM + 2:
+ case IA64_BR0_REGNUM + 3:
+ case IA64_BR0_REGNUM + 4:
+ case IA64_BR0_REGNUM + 5:
+ result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,
+ reg, rw);
+ break;
+ }
+
+ return result;
+}
+
+static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg,
+ struct ia64_fpreg *freg, int rw)
+{
+ int result = 1;
+
+ if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
+ return 0;
+
+ switch (regnum) {
+ case IA64_FR0_REGNUM + 6:
+ case IA64_FR0_REGNUM + 7:
+ case IA64_FR0_REGNUM + 8:
+ case IA64_FR0_REGNUM + 9:
+ case IA64_FR0_REGNUM + 10:
+ case IA64_FR0_REGNUM + 11:
+ case IA64_FR0_REGNUM + 12:
+ if (rw) {
+#ifndef XEN
+ char *ptr = inbuffer;
+
+ freg->u.bits[0] = *reg;
+ kgdb_hex2long(&ptr, &freg->u.bits[1]);
+ *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
+ *freg;
+#else
+ printk("%s: %d: writing to fpreg is not supported.\n",
+ __func__, __LINE__);
+#endif
+ break;
+ } else if (!ptregs)
+ result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
+ freg, rw);
+ else
+#ifndef XEN
+ *freg =
+ *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
+#else
+ //XXX struct ia64_fpreg and struct pt_fpreg are same.
+ *freg = *((struct ia64_fpreg*)(&ptregs->f6 +
+
(regnum - (IA64_FR0_REGNUM + 6))));
+#endif
+ break;
+ default:
+ if (!rw)
+ result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
+ freg, rw);
+ else
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+ int result = 0, i;
+
+ if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
+ return 0;
+
+ if (rw && ptregs) {
+ for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
+ if (ar_reg_to_ptreg_index[i].reg == regnum) {
+ *((unsigned long *) (((void *)ptregs) +
+ ar_reg_to_ptreg_index[i].ptregoff)) =
+ *reg;
+ result = 1;
+ break;
+ }
+ } else if (ptregs) {
+ for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
+ if (ar_reg_to_ptreg_index[i].reg == regnum) {
+ *reg = *((unsigned long *) (((void *)ptregs) +
+ ar_reg_to_ptreg_index[i].ptregoff));
+ result = 1;
+ break;
+ }
+ }
+
+ if (result)
+ return result;
+
+ result = 1;
+
+ switch (regnum) {
+ case IA64_CSD_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
+ break;
+ case IA64_SSD_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
+ break;
+ case IA64_UNAT_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_RNAT_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_BSPSTORE_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_PFS_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_LC_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
+ break;
+ case IA64_EC_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
+ break;
+ case IA64_FPSR_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
+ break;
+ case IA64_RSC_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
+ break;
+ case IA64_CCV_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
+ break;
+ default:
+ result = 0;
+ }
+
+ return result;
+}
+
+#ifndef XEN
+void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
+ struct pt_regs *ptregs)
+#else
+static int
+kgdb_get_reg(int regnum, struct unw_frame_info *info,
+ struct cpu_user_regs* ptregs,
+ unsigned long* __reg, struct ia64_fpreg* __freg)
+#endif
+{
+ unsigned long reg, size = 0, *mem = ®
+ struct ia64_fpreg freg;
+
+ if (kgdb_gr_reg(regnum, info, ®, 0) ||
+ kgdb_gr_ptreg(regnum, ptregs, info, ®, 0) ||
+ kgdb_br_reg(regnum, ptregs, info, ®, 0) ||
+ kgdb_ar_reg(regnum, ptregs, info, ®, 0))
+ size = sizeof(reg);
+ else if (kgdb_fr_reg(regnum, NULL, ptregs, info, ®, &freg, 0)) {
+ size = sizeof(freg);
+ mem = (unsigned long *)&freg;
+ } else if (regnum == IA64_IP_REGNUM) {
+ if (!ptregs) {
+ unw_get_ip(info, ®);
+ size = sizeof(reg);
+ } else {
+ reg = ptregs->cr_iip;
+ size = sizeof(reg);
+ }
+ } else if (regnum == IA64_CFM_REGNUM) {
+ if (!ptregs)
+ unw_get_cfm(info, ®);
+ else
+ reg = ptregs->cr_ifs;
+ size = sizeof(reg);
+ } else if (regnum == IA64_PSR_REGNUM) {
+#ifndef XEN
+ if (!ptregs && kgdb_usethread)
+ ptregs = (struct pt_regs *)
+ ((unsigned long)kgdb_usethread +
+ IA64_STK_OFFSET) - 1;
+#endif
+ if (ptregs)
+ reg = ptregs->cr_ipsr;
+ size = sizeof(reg);
+ } else if (regnum == IA64_PR_REGNUM) {
+ if (ptregs)
+ reg = ptregs->pr;
+ else
+ unw_access_pr(info, ®, 0);
+ size = sizeof(reg);
+ } else if (regnum == IA64_BSP_REGNUM) {
+ unw_get_bsp(info, ®);
+ size = sizeof(reg);
+ }
+
+#ifndef XEN
+ if (size) {
+ kgdb_mem2hex((char *) mem, outbuffer, size);
+ outbuffer[size*2] = 0;
+ }
+ else
+ strcpy(outbuffer, "E0");
+
+ return;
+#else
+ if (size) {
+ if (size == sizeof(reg)) {
+ *__reg = reg;
+ } else {
+ BUG_ON(size != sizeof(freg));
+ *__freg = freg;
+ }
+ return 0;
+ }
+
+ return -1;
+#endif
+}
+
+#ifndef XEN
+static int inline kgdb_get_blocked_state(struct task_struct *p,
+ struct unw_frame_info *unw)
+#else
+static int
+kgdb_get_blocked_state(struct vcpu *p,
+ struct cpu_user_regs *regs,
+ struct unw_frame_info *unw)
+#endif
+{
+ unsigned long ip;
+ int count = 0;
+
+#ifndef XEN
+ unw_init_from_blocked_task(unw, p);
+#endif
+ ip = 0UL;
+ do {
+ if (unw_unwind(unw) < 0)
+ return -1;
+ unw_get_ip(unw, &ip);
+#ifndef XEN
+ if (!in_sched_functions(ip))
+ break;
+#else
+ dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip);
+ if (ip == regs->cr_iip)
+ break;
+#endif
+ } while (count++ < 16);
+
+ if (!ip)
+ return -1;
+ else
+ return 0;
+}
+
+struct gdb_callback_arg
+{
+ struct cpu_user_regs* regs;
+ unsigned long regnum;
+ unsigned long* reg;
+ struct pt_fpreg* freg;
+
+ int error;
+ // 1: not supported
+ // 0: success
+ // -1: failure
+};
+
+static void
+gdb_get_reg_callback(struct unw_frame_info* info, void* __arg)
+{
+ struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg;
+
+ if (kgdb_get_blocked_state(current, arg->regs, info) < 0) {
+ dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__);
+ arg->error = -1;
+ return;
+ }
+ //XXX struct ia64_fpreg and struct pt_fpreg are same.
+ if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg,
+ (struct ia64_fpreg*)arg->freg) < 0) {
+ dbg_printk("%s: kgdb_get_reg failed\n", __func__);
+ arg->error = 1;
+ return;
+ }
+ arg->error = 0;
+ return;
+}
+
+void
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+ struct gdb_context *ctx)
+{
+ struct gdb_callback_arg arg;
+ unsigned long reg;
+ struct pt_fpreg freg;
+ char buf[16 * 2 + 1];
+
+ if (regnum >= NUM_REGS) {
+ dbg_printk("%s: regnum %ld\n", __func__, regnum);
+ goto out_err;
+ }
+
+ arg.regs = regs;
+ arg.regnum = regnum;
+ arg.reg = ®
+ arg.freg = &freg;
+ arg.error = 0;
+ unw_init_running(&gdb_get_reg_callback, (void*)&arg);
+ if (arg.error < 0) {
+ dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);
+ goto out_err;
+ }
+
+ if (arg.error > 0) {
+ // notify gdb that this register is not supported.
+ // see fetch_register_using_p() in gdb/remote.c.
+ sprintf(buf, "%s", "x");
+ } else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM +
127) {
+ sprintf(buf, "%.016lx", swab64(freg.u.bits[0]));
+ sprintf(buf + 16, "%.016lx", swab64(freg.u.bits[1]));
+ } else {
+ sprintf(buf, "%.016lx", swab64(reg));
+ }
+out:
+ return gdb_send_reply(buf, ctx);
+
+out_err:
+ dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
+ sprintf(buf, "%s", "E0");
+ goto out;
+}
+#endif
+
+void
+gdb_arch_resume(struct cpu_user_regs *regs,
+ unsigned long addr, unsigned long type,
+ struct gdb_context *ctx)
+{
+ /* XXX */
+ if (type == GDB_STEP) {
+ gdb_send_reply("S01", ctx);
+ }
+}
+
+void
+gdb_arch_print_state(struct cpu_user_regs *regs)
+{
+ /* XXX */
+}
+
+void
+gdb_arch_enter(struct cpu_user_regs *regs)
+{
+ /* nothing */
+}
+
+void
+gdb_arch_exit(struct cpu_user_regs *regs)
+{
+ /* nothing */
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/gdbstub.c
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/gdbstub.c Tue Jan 24 16:54:34 2006
@@ -0,0 +1,146 @@
+/*
+ * x86-specific gdb stub routines
+ * based on x86 cdb(xen/arch/x86/cdb.c), but Extensively modified.
+ *
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan. K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <asm/debugger.h>
+
+u16
+gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
+{
+ /* XXX */
+ return 1;
+}
+
+void
+gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
+ GDB_REG(regs->eax);
+ GDB_REG(regs->ecx);
+ GDB_REG(regs->edx);
+ GDB_REG(regs->ebx);
+ GDB_REG(regs->esp);
+ GDB_REG(regs->ebp);
+ GDB_REG(regs->esi);
+ GDB_REG(regs->edi);
+ GDB_REG(regs->eip);
+ GDB_REG(regs->eflags);
+#undef GDB_REG
+#define GDB_SEG_REG(s) gdb_write_to_packet_hex(s, sizeof(u32), ctx);
+ /* sizeof(segment) = 16bit */
+ /* but gdb requires its return value as 32bit value */
+ GDB_SEG_REG(regs->cs);
+ GDB_SEG_REG(regs->ss);
+ GDB_SEG_REG(regs->ds);
+ GDB_SEG_REG(regs->es);
+ GDB_SEG_REG(regs->fs);
+ GDB_SEG_REG(regs->gs);
+#undef GDB_SEG_REG
+ gdb_send_packet(ctx);
+}
+
+void
+gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
+ struct gdb_context *ctx)
+{
+ /* XXX TODO */
+ gdb_send_reply("E02", ctx);
+}
+
+void
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+ struct gdb_context *ctx)
+{
+ gdb_send_reply("", ctx);
+}
+
+/* Like copy_from_user, but safe to call with interrupts disabled.
+ Trust me, and don't look behind the curtain. */
+unsigned
+gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
+{
+ int __d0, __d1, __d2;
+ ASSERT(!local_irq_is_enabled());
+ __asm__ __volatile__(
+ "1: rep; movsb\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ "3: addl $4, %%esp\n"
+ " jmp 2b\n"
+ ".previous\n"
+ ".section __pre_ex_table,\"a\"\n"
+ " "__FIXUP_ALIGN"\n"
+ " "__FIXUP_WORD" 1b,3b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " "__FIXUP_ALIGN"\n"
+ " "__FIXUP_WORD" 1b,2b\n"
+ ".previous\n"
+ : "=c"(__d2), "=D" (__d0), "=S" (__d1)
+ : "0"(len), "1"(dest), "2"(src)
+ : "memory");
+ ASSERT(!local_irq_is_enabled());
+ return __d2;
+}
+
+unsigned int
+gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
+{
+ /* XXX */
+ return len;
+}
+
+void
+gdb_arch_resume(struct cpu_user_regs *regs,
+ unsigned long addr, unsigned long type,
+ struct gdb_context *ctx)
+{
+ /* XXX */
+ if (type == GDB_STEP) {
+ gdb_send_reply("S01", ctx);
+ }
+}
+
+void
+gdb_arch_print_state(struct cpu_user_regs *regs)
+{
+ /* XXX */
+}
+
+void
+gdb_arch_enter(struct cpu_user_regs *regs)
+{
+ /* nothing */
+}
+
+void
+gdb_arch_exit(struct cpu_user_regs *regs)
+{
+ /* nothing */
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/gdbstub.c
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/common/gdbstub.c Tue Jan 24 16:54:34 2006
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan. K.K.
+ *
+ * gdbstub arch neutral part
+ * Based on x86 cdb (xen/arch/x86/cdb.c) and ppc gdbstub(xen/common/gdbstub.c)
+ * But extensively modified.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * gdbstub: implements the architecture independant parts of the
+ * gdb remote protocol.
+ */
+
+/* We try to avoid assuming much about what the rest of the system is
+ doing. In particular, dynamic memory allocation is out of the
+ question. */
+
+/* Resuming after we've stopped used to work, but more through luck
+ than any actual intention. It doesn't at the moment. */
+
+#include <xen/lib.h>
+#include <asm/uaccess.h>
+#include <xen/spinlock.h>
+#include <xen/serial.h>
+#include <xen/irq.h>
+#include <asm/debugger.h>
+#include <xen/init.h>
+#include <xen/smp.h>
+#include <xen/console.h>
+
+/* Printk isn't particularly safe just after we've trapped to the
+ debugger. so avoid it. */
+#define dbg_printk(...)
+/*#define dbg_printk(...) printk(__VA_ARGS__)*/
+
+#define GDB_RETRY_MAX 10
+
+static char opt_gdb[30] = "none";
+string_param("gdb", opt_gdb);
+
+/* value <-> char (de)serialzers */
+char
+hex2char(unsigned long x)
+{
+ const char array[] = "0123456789abcdef";
+
+ return array[x & 15];
+}
+
+int
+char2hex(unsigned char c)
+{
+ if ( (c >= '0') && (c <= '9') )
+ return c - '0';
+ else if ( (c >= 'a') && (c <= 'f') )
+ return c - 'a' + 10;
+ else if ( (c >= 'A') && (c <= 'F') )
+ return c - 'A' + 10;
+ else
+ BUG();
+ return -1;
+}
+
+char
+str2hex(const char *str)
+{
+ return (char2hex(str[0]) << 4) | char2hex(str[1]);
+}
+
+unsigned long
+str2ulong(const char *str, unsigned long bytes)
+{
+ unsigned long x = 0;
+ unsigned long i = 0;
+
+ while ( *str && (i < (bytes * 2)) )
+ {
+ x <<= 4;
+ x += char2hex(*str);
+ ++str;
+ ++i;
+ }
+
+ return x;
+}
+
+/* gdb io wrappers */
+static signed long
+gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
+{
+ int i;
+ for ( i = 0; i < len; i++ )
+ serial_putc(ctx->serhnd, buf[i]);
+ return i;
+}
+
+static int
+gdb_io_write_char(u8 data, struct gdb_context *ctx)
+{
+ return gdb_io_write((char*)&data, 1, ctx);
+}
+
+static unsigned char
+gdb_io_read(struct gdb_context *ctx)
+{
+ return serial_getc(ctx->serhnd);
+}
+
+/* Receive a command. Returns -1 on csum error, 0 otherwise. */
+/* Does not acknowledge. */
+static int
+attempt_receive_packet(struct gdb_context *ctx)
+{
+ u8 csum;
+ u8 received_csum;
+ u8 ch;
+
+ /* Skip over everything up to the first '$' */
+ while ( (ch = gdb_io_read(ctx)) != '$' )
+ continue;
+
+ csum = 0;
+ for ( ctx->in_bytes = 0;
+ ctx->in_bytes < sizeof(ctx->in_buf);
+ ctx->in_bytes++ )
+ {
+ ch = gdb_io_read(ctx);
+ if ( ch == '#' )
+ break;
+ ctx->in_buf[ctx->in_bytes] = ch;
+ csum += ch;
+ }
+
+ if ( ctx->in_bytes == sizeof(ctx->in_buf) )
+ {
+ dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
+ return -1;
+ }
+
+ ctx->in_buf[ctx->in_bytes] = '\0';
+ received_csum = char2hex(gdb_io_read(ctx)) * 16 +
+ char2hex(gdb_io_read(ctx));
+
+ return (received_csum == csum) ? 0 : -1;
+}
+
+/* Receive a command, discarding up to ten packets with csum
+ * errors. Acknowledges all received packets. */
+static int
+receive_command(struct gdb_context *ctx)
+{
+ int r, count = 0;
+
+ count = 0;
+ do {
+ r = attempt_receive_packet(ctx);
+ gdb_io_write_char((r < 0) ? '-' : '+', ctx);
+ count++;
+ } while ( (r < 0) && (count < GDB_RETRY_MAX) );
+
+ return r;
+}
+
+/* routines to send reply packets */
+
+static void
+gdb_start_packet(struct gdb_context *ctx)
+{
+ ctx->out_buf[0] = '$';
+ ctx->out_offset = 1;
+ ctx->out_csum = 0;
+}
+
+static void
+gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
+{
+ ctx->out_csum += data;
+ ctx->out_buf[ctx->out_offset] = data;
+ ctx->out_offset++;
+}
+
+void
+gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
+{
+ int x;
+ for ( x = 0; x < count; x++ )
+ gdb_write_to_packet_char(buf[x], ctx);
+}
+
+void
+gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
+{
+ gdb_write_to_packet(buf, strlen(buf), ctx);
+}
+
+void
+gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
+{
+ char buf[sizeof(unsigned long) * 2 + 1];
+ int i = sizeof(unsigned long) * 2;
+ int width = int_size * 2;
+
+ buf[sizeof(unsigned long) * 2] = 0;
+
+ switch ( int_size )
+ {
+ case sizeof(u8):
+ case sizeof(u16):
+ case sizeof(u32):
+ case sizeof(u64):
+ break;
+ default:
+ dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
+ __func__, x, int_size);
+ break;
+ }
+
+ do {
+ buf[--i] = hex2char(x & 15);
+ x >>= 4;
+ } while ( x );
+
+ while ( (i + width) > (sizeof(unsigned long) * 2) )
+ buf[--i] = '0';
+
+ gdb_write_to_packet(&buf[i], width, ctx);
+}
+
+static int
+gdb_check_ack(struct gdb_context *ctx)
+{
+ u8 c = gdb_io_read(ctx);
+
+ switch ( c )
+ {
+ case '+':
+ return 1;
+ case '-':
+ return 0;
+ default:
+ printk("Bad ack: %c\n", c);
+ return 0;
+ }
+}
+
+/* Return 0 if the reply was successfully received, !0 otherwise. */
+void
+gdb_send_packet(struct gdb_context *ctx)
+{
+ char buf[3];
+ int count;
+
+ sprintf(buf, "%.02x\n", ctx->out_csum);
+
+ gdb_write_to_packet_char('#', ctx);
+ gdb_write_to_packet(buf, 2, ctx);
+
+ count = 0;
+ do {
+ gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
+ } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
+
+ if ( count == GDB_RETRY_MAX )
+ dbg_printk("WARNING: %s reached max retry %d\n",
+ __func__, GDB_RETRY_MAX);
+}
+
+void
+gdb_send_reply(const char *buf, struct gdb_context *ctx)
+{
+ gdb_start_packet(ctx);
+ gdb_write_to_packet_str(buf, ctx);
+ gdb_send_packet(ctx);
+}
+
+/* arch neutral command handlers */
+
+static void
+gdb_cmd_signum(struct gdb_context *ctx)
+{
+ gdb_write_to_packet_char('S', ctx);
+ gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
+ gdb_send_packet(ctx);
+}
+
+static void
+gdb_cmd_read_mem(unsigned long addr, unsigned long length,
+ struct gdb_context *ctx)
+{
+ int x, r;
+ unsigned char val;
+
+ dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
+ length);
+
+ for ( x = 0; x < length; x++ )
+ {
+ r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
+ if ( r != 0 )
+ {
+ dbg_printk("Error reading from %lx.\n", addr + x);
+ break;
+ }
+ gdb_write_to_packet_hex(val, sizeof(val), ctx);
+ }
+
+ if ( x == 0 )
+ gdb_write_to_packet_str("E05", ctx);
+
+ dbg_printk("Read done.\n");
+
+ gdb_send_packet(ctx);
+}
+
+static void
+gdb_cmd_write_mem(unsigned long addr, unsigned long length,
+ const char *buf, struct gdb_context *ctx)
+{
+ int x, r;
+ unsigned char val;
+
+ dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
+
+ for ( x = 0; x < length; x++, addr++, buf += 2 )
+ {
+ val = str2ulong(buf, sizeof(val));
+ r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
+ if ( r != 0 )
+ {
+ dbg_printk("Error writing to %lx.\n", addr);
+ break;
+ }
+ }
+
+ gdb_write_to_packet_str((x != length) ? "OK" : "E11", ctx);
+
+ dbg_printk("Write done.\n");
+
+ gdb_send_packet(ctx);
+}
+
+/* command dispatcher */
+static int
+process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+ char *ptr;
+ unsigned long addr, length;
+ int resume = 0;
+
+ /* XXX check ctx->in_bytes >= 2 or similar. */
+
+ gdb_start_packet(ctx);
+ switch ( ctx->in_buf[0] )
+ {
+ case '?': /* query signal number */
+ gdb_cmd_signum(ctx);
+ break;
+ case 'H': /* thread operations */
+ gdb_send_reply("OK", ctx);
+ break;
+ case 'g': /* Read registers */
+ gdb_arch_read_reg_array(regs, ctx);
+ ASSERT(!local_irq_is_enabled());
+ break;
+ case 'G': /* Write registers */
+ gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
+ break;
+ case 'm': /* Read memory */
+ addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+ if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
+ {
+ gdb_send_reply("E03", ctx);
+ return 0;
+ }
+ length = simple_strtoul(ptr + 1, &ptr, 16);
+ if ( ptr[0] != 0 )
+ {
+ gdb_send_reply("E04", ctx);
+ return 0;
+ }
+ gdb_cmd_read_mem(addr, length, ctx);
+ ASSERT(!local_irq_is_enabled());
+ break;
+ case 'M': /* Write memory */
+ addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+ if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ':') )
+ {
+ gdb_send_reply("E03", ctx);
+ return 0;
+ }
+ length = simple_strtoul(ptr + 1, &ptr, 16);
+ gdb_cmd_write_mem(addr, length, ptr, ctx);
+ break;
+ case 'p': /* read register */
+ addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+ if ( ptr == (ctx->in_buf + 1) )
+ {
+ gdb_send_reply("E03", ctx);
+ return 0;
+ }
+ if ( ptr[0] != 0 )
+ {
+ gdb_send_reply("E04", ctx);
+ return 0;
+ }
+ gdb_arch_read_reg(addr, regs, ctx);
+ break;
+ case 'Z': /* We need to claim to support these or gdb
+ won't let you continue the process. */
+ case 'z':
+ gdb_send_reply("OK", ctx);
+ break;
+
+ case 'D':
+ ctx->currently_attached = 0;
+ gdb_send_reply("OK", ctx);
+ /* fall through */
+ case 'k':
+ ctx->connected = 0;
+ /* fall through */
+ case 's': /* Single step */
+ case 'c': /* Resume at current address */
+ {
+ unsigned long addr = ~((unsigned long)0);
+ unsigned long type = GDB_CONTINUE;
+ if ( ctx->in_buf[0] == 's' )
+ type = GDB_STEP;
+ if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
+ ctx->in_buf[1] )
+ addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
+ if ( ctx->in_buf[0] != 'D' )
+ ctx->currently_attached = 1;
+ resume = 1;
+ gdb_arch_resume(regs, addr, type, ctx);
+ break;
+ }
+
+ default:
+ gdb_send_reply("", ctx);
+ break;
+ }
+ return resume;
+}
+
+static struct gdb_context
+__gdb_ctx = {
+ .serhnd = -1,
+ .currently_attached = 0,
+ .running = ATOMIC_INIT(1),
+ .connected = 0,
+ .signum = 1,
+ .in_bytes = 0,
+ .out_offset = 0,
+ .out_csum = 0,
+};
+static struct gdb_context *gdb_ctx = &__gdb_ctx;
+
+/* trap handler: main entry point */
+int
+__trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
+{
+ int resume = 0;
+ int r;
+ unsigned flags;
+
+ if ( gdb_ctx->serhnd < 0 )
+ {
+ dbg_printk("Debugger not ready yet.\n");
+ return 0;
+ }
+
+ /* We rely on our caller to ensure we're only on one processor
+ * at a time... We should probably panic here, but given that
+ * we're a debugger we should probably be a little tolerant of
+ * things going wrong. */
+ /* We don't want to use a spin lock here, because we're doing
+ two distinct things:
+
+ 1 -- we don't want to run on more than one processor at a time,
+ and
+ 2 -- we want to do something sensible if we re-enter ourselves.
+
+ Spin locks are good for 1, but useless for 2. */
+ if ( !atomic_dec_and_test(&gdb_ctx->running) )
+ {
+ printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
+ atomic_inc(&gdb_ctx->running);
+ return 0;
+ }
+
+ if ( !gdb_ctx->connected )
+ {
+ printk("GDB connection activated\n");
+ gdb_arch_print_state(regs);
+ gdb_ctx->connected = 1;
+ }
+
+ smp_send_stop();
+
+ /* Try to make things a little more stable by disabling
+ interrupts while we're here. */
+ local_irq_save(flags);
+
+ watchdog_disable();
+ console_start_sync();
+
+ /* Shouldn't really do this, but otherwise we stop for no
+ obvious reason, which is Bad */
+ printk("Waiting for GDB to attach to Gdb\n");
+
+ gdb_arch_enter(regs);
+ gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
+ /* If gdb is already attached, tell it we've stopped again. */
+ if ( gdb_ctx->currently_attached )
+ {
+ gdb_start_packet(gdb_ctx);
+ gdb_cmd_signum(gdb_ctx);
+ }
+
+ while ( resume == 0 )
+ {
+ ASSERT(!local_irq_is_enabled());
+ r = receive_command(gdb_ctx);
+ ASSERT(!local_irq_is_enabled());
+ if ( r < 0 )
+ {
+ dbg_printk("GDB disappeared, trying to resume Xen...\n");
+ resume = 1;
+ }
+ else
+ {
+ ASSERT(!local_irq_is_enabled());
+ resume = process_command(regs, gdb_ctx);
+ ASSERT(!local_irq_is_enabled());
+ }
+ }
+
+ gdb_arch_exit(regs);
+ console_end_sync();
+ watchdog_enable();
+ atomic_inc(&gdb_ctx->running);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/*
+ * initialization
+ * XXX TODO
+ * This should be an explicit call from architecture code.
+ * initcall is far too late for some early debugging, and only the
+ * architecture code knows when this call can be made.
+ */
+static int
+initialize_gdb(void)
+{
+ if ( !strcmp(opt_gdb, "none") )
+ return 0;
+ gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
+ if ( gdb_ctx->serhnd == -1 )
+ panic("Can't parse %s as GDB serial info.\n", opt_gdb);
+
+ printk("Gdb initialised.\n");
+ return 0;
+}
+
+__initcall(initialize_gdb);
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/timer.c
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/common/timer.c Tue Jan 24 16:54:34 2006
@@ -0,0 +1,308 @@
+/******************************************************************************
+ * timer.c
+ *
+ * Copyright (c) 2002-2003 Rolf Neugebauer
+ * Copyright (c) 2002-2005 K A Fraser
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/types.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/lib.h>
+#include <xen/smp.h>
+#include <xen/perfc.h>
+#include <xen/time.h>
+#include <xen/softirq.h>
+#include <xen/timer.h>
+#include <xen/keyhandler.h>
+#include <asm/system.h>
+#include <asm/desc.h>
+
+/*
+ * We pull handlers off the timer list this far in future,
+ * rather than reprogramming the time hardware.
+ */
+#define TIMER_SLOP (50*1000) /* ns */
+
+struct timers {
+ spinlock_t lock;
+ struct timer **heap;
+ struct timer *running;
+} __cacheline_aligned;
+
+struct timers timers[NR_CPUS];
+
+extern int reprogram_timer(s_time_t timeout);
+
+/****************************************************************************
+ * HEAP OPERATIONS.
+ */
+
+#define GET_HEAP_SIZE(_h) ((int)(((u16 *)(_h))[0]))
+#define SET_HEAP_SIZE(_h,_v) (((u16 *)(_h))[0] = (u16)(_v))
+
+#define GET_HEAP_LIMIT(_h) ((int)(((u16 *)(_h))[1]))
+#define SET_HEAP_LIMIT(_h,_v) (((u16 *)(_h))[1] = (u16)(_v))
+
+/* Sink down element @pos of @heap. */
+static void down_heap(struct timer **heap, int pos)
+{
+ int sz = GET_HEAP_SIZE(heap), nxt;
+ struct timer *t = heap[pos];
+
+ while ( (nxt = (pos << 1)) <= sz )
+ {
+ if ( ((nxt+1) <= sz) && (heap[nxt+1]->expires < heap[nxt]->expires) )
+ nxt++;
+ if ( heap[nxt]->expires > t->expires )
+ break;
+ heap[pos] = heap[nxt];
+ heap[pos]->heap_offset = pos;
+ pos = nxt;
+ }
+
+ heap[pos] = t;
+ t->heap_offset = pos;
+}
+
+/* Float element @pos up @heap. */
+static void up_heap(struct timer **heap, int pos)
+{
+ struct timer *t = heap[pos];
+
+ while ( (pos > 1) && (t->expires < heap[pos>>1]->expires) )
+ {
+ heap[pos] = heap[pos>>1];
+ heap[pos]->heap_offset = pos;
+ pos >>= 1;
+ }
+
+ heap[pos] = t;
+ t->heap_offset = pos;
+}
+
+
+/* Delete @t from @heap. Return TRUE if new top of heap. */
+static int remove_entry(struct timer **heap, struct timer *t)
+{
+ int sz = GET_HEAP_SIZE(heap);
+ int pos = t->heap_offset;
+
+ t->heap_offset = 0;
+
+ if ( unlikely(pos == sz) )
+ {
+ SET_HEAP_SIZE(heap, sz-1);
+ goto out;
+ }
+
+ heap[pos] = heap[sz];
+ heap[pos]->heap_offset = pos;
+
+ SET_HEAP_SIZE(heap, --sz);
+
+ if ( (pos > 1) && (heap[pos]->expires < heap[pos>>1]->expires) )
+ up_heap(heap, pos);
+ else
+ down_heap(heap, pos);
+
+ out:
+ return (pos == 1);
+}
+
+
+/* Add new entry @t to @heap. Return TRUE if new top of heap. */
+static int add_entry(struct timer ***pheap, struct timer *t)
+{
+ struct timer **heap = *pheap;
+ int sz = GET_HEAP_SIZE(heap);
+
+ /* Copy the heap if it is full. */
+ if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
+ {
+ /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
+ int old_limit = GET_HEAP_LIMIT(heap);
+ int new_limit = ((old_limit + 1) << 4) - 1;
+ heap = xmalloc_array(struct timer *, new_limit + 1);
+ BUG_ON(heap == NULL);
+ memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
+ SET_HEAP_LIMIT(heap, new_limit);
+ if ( old_limit != 0 )
+ xfree(*pheap);
+ *pheap = heap;
+ }
+
+ SET_HEAP_SIZE(heap, ++sz);
+ heap[sz] = t;
+ t->heap_offset = sz;
+ up_heap(heap, sz);
+ return (t->heap_offset == 1);
+}
+
+
+/****************************************************************************
+ * TIMER OPERATIONS.
+ */
+
+static inline void __add_timer(struct timer *timer)
+{
+ int cpu = timer->cpu;
+ if ( add_entry(&timers[cpu].heap, timer) )
+ cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
+}
+
+
+static inline void __stop_timer(struct timer *timer)
+{
+ int cpu = timer->cpu;
+ if ( remove_entry(timers[cpu].heap, timer) )
+ cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
+}
+
+
+void set_timer(struct timer *timer, s_time_t expires)
+{
+ int cpu = timer->cpu;
+ unsigned long flags;
+
+ spin_lock_irqsave(&timers[cpu].lock, flags);
+ if ( active_timer(timer) )
+ __stop_timer(timer);
+ timer->expires = expires;
+ if ( likely(!timer->killed) )
+ __add_timer(timer);
+ spin_unlock_irqrestore(&timers[cpu].lock, flags);
+}
+
+
+void stop_timer(struct timer *timer)
+{
+ int cpu = timer->cpu;
+ unsigned long flags;
+
+ spin_lock_irqsave(&timers[cpu].lock, flags);
+ if ( active_timer(timer) )
+ __stop_timer(timer);
+ spin_unlock_irqrestore(&timers[cpu].lock, flags);
+}
+
+
+void kill_timer(struct timer *timer)
+{
+ int cpu = timer->cpu;
+ unsigned long flags;
+
+ BUG_ON(timers[cpu].running == timer);
+
+ spin_lock_irqsave(&timers[cpu].lock, flags);
+ if ( active_timer(timer) )
+ __stop_timer(timer);
+ timer->killed = 1;
+ spin_unlock_irqrestore(&timers[cpu].lock, flags);
+
+ for_each_online_cpu ( cpu )
+ while ( timers[cpu].running == timer )
+ cpu_relax();
+}
+
+
+static void timer_softirq_action(void)
+{
+ int cpu = smp_processor_id();
+ struct timer *t, **heap;
+ s_time_t now;
+ void (*fn)(void *);
+ void *data;
+
+ spin_lock_irq(&timers[cpu].lock);
+
+ do {
+ heap = timers[cpu].heap;
+ now = NOW();
+
+ while ( (GET_HEAP_SIZE(heap) != 0) &&
+ ((t = heap[1])->expires < (now + TIMER_SLOP)) )
+ {
+ remove_entry(heap, t);
+
+ timers[cpu].running = t;
+
+ fn = t->function;
+ data = t->data;
+
+ spin_unlock_irq(&timers[cpu].lock);
+ (*fn)(data);
+ spin_lock_irq(&timers[cpu].lock);
+
+ /* Heap may have grown while the lock was released. */
+ heap = timers[cpu].heap;
+ }
+
+ timers[cpu].running = NULL;
+ }
+ while ( !reprogram_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
+
+ spin_unlock_irq(&timers[cpu].lock);
+}
+
+
+static void dump_timerq(unsigned char key)
+{
+ struct timer *t;
+ unsigned long flags;
+ s_time_t now = NOW();
+ int i, j;
+
+ printk("Dumping timer queues: NOW=0x%08X%08X\n",
+ (u32)(now>>32), (u32)now);
+
+ for_each_online_cpu( i )
+ {
+ printk("CPU[%02d] ", i);
+ spin_lock_irqsave(&timers[i].lock, flags);
+ for ( j = 1; j <= GET_HEAP_SIZE(timers[i].heap); j++ )
+ {
+ t = timers[i].heap[j];
+ printk (" %d : %p ex=0x%08X%08X %p\n",
+ j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
+ }
+ spin_unlock_irqrestore(&timers[i].lock, flags);
+ printk("\n");
+ }
+}
+
+
+void __init timer_init(void)
+{
+ static struct timer *dummy_heap;
+ int i;
+
+ open_softirq(TIMER_SOFTIRQ, timer_softirq_action);
+
+ /*
+ * All CPUs initially share an empty dummy heap. Only those CPUs that
+ * are brought online will be dynamically allocated their own heap.
+ */
+ SET_HEAP_SIZE(&dummy_heap, 0);
+ SET_HEAP_LIMIT(&dummy_heap, 0);
+
+ for ( i = 0; i < NR_CPUS; i++ )
+ {
+ spin_lock_init(&timers[i].lock);
+ timers[i].heap = &dummy_heap;
+ }
+
+ register_keyhandler('a', dump_timerq, "dump timer queues");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/nmi.h
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/nmi.h Tue Jan 24 16:54:34 2006
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * nmi.h
+ *
+ * NMI callback registration and reason codes.
+ *
+ * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
+ */
+
+#ifndef __XEN_PUBLIC_NMI_H__
+#define __XEN_PUBLIC_NMI_H__
+
+/*
+ * NMI reason codes:
+ * Currently these are x86-specific, stored in arch_shared_info.nmi_reason.
+ */
+ /* I/O-check error reported via ISA port 0x61, bit 6. */
+#define _XEN_NMIREASON_io_error 0
+#define XEN_NMIREASON_io_error (1UL << _XEN_NMIREASON_io_error)
+ /* Parity error reported via ISA port 0x61, bit 7. */
+#define _XEN_NMIREASON_parity_error 1
+#define XEN_NMIREASON_parity_error (1UL << _XEN_NMIREASON_parity_error)
+ /* Unknown hardware-generated NMI. */
+#define _XEN_NMIREASON_unknown 2
+#define XEN_NMIREASON_unknown (1UL << _XEN_NMIREASON_unknown)
+
+/*
+ * long nmi_op(unsigned int cmd, void *arg)
+ * NB. All ops return zero on success, else a negative error code.
+ */
+
+/*
+ * Register NMI callback for this (calling) VCPU. Currently this only makes
+ * sense for domain 0, vcpu 0. All other callers will be returned EINVAL.
+ * arg == address of callback function.
+ */
+#define XENNMI_register_callback 0
+
+/*
+ * Deregister NMI callback for this (calling) VCPU.
+ * arg == NULL.
+ */
+#define XENNMI_unregister_callback 1
+
+#endif /* __XEN_PUBLIC_NMI_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/gdbstub.h
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/gdbstub.h Tue Jan 24 16:54:34 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2005 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM Corporation
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan. K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __XEN_GDBSTUB_H__
+#define __XEN_GDBSTUB_H__
+
+/* value <-> char (de)serialzers for arch specific gdb backends */
+char hex2char(unsigned long x);
+int char2hex(unsigned char c);
+char str2hex(const char *str);
+unsigned long str2ulong(const char *str, unsigned long bytes);
+
+struct gdb_context {
+ int serhnd;
+ int currently_attached:1;
+ atomic_t running;
+ unsigned long connected;
+ u8 signum;
+
+ char in_buf[PAGE_SIZE];
+ unsigned long in_bytes;
+
+ char out_buf[PAGE_SIZE];
+ unsigned long out_offset;
+ u8 out_csum;
+};
+
+/* interface to arch specific routines */
+void gdb_write_to_packet(
+ const char *buf, int count, struct gdb_context *ctx);
+void gdb_write_to_packet_hex(
+ unsigned long x, int int_size, struct gdb_context *ctx);
+void gdb_send_packet(struct gdb_context *ctx);
+void gdb_send_reply(const char *buf, struct gdb_context *ctx);
+
+/* gdb stub trap handler: entry point */
+int __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie);
+
+/* arch specific routines */
+u16 gdb_arch_signal_num(
+ struct cpu_user_regs *regs, unsigned long cookie);
+void gdb_arch_read_reg_array(
+ struct cpu_user_regs *regs, struct gdb_context *ctx);
+void gdb_arch_write_reg_array(
+ struct cpu_user_regs *regs, const char* buf, struct gdb_context *ctx);
+void gdb_arch_read_reg(
+ unsigned long regnum, struct cpu_user_regs *regs, struct gdb_context *ctx);
+unsigned int gdb_arch_copy_from_user(
+ void *dest, const void *src, unsigned len);
+unsigned int gdb_arch_copy_to_user(
+ void *dest, const void *src, unsigned len);
+void gdb_arch_resume(
+ struct cpu_user_regs *regs, unsigned long addr,
+ unsigned long type, struct gdb_context *ctx);
+void gdb_arch_print_state(struct cpu_user_regs *regs);
+void gdb_arch_enter(struct cpu_user_regs *regs);
+void gdb_arch_exit(struct cpu_user_regs *regs);
+
+#define GDB_CONTINUE 0
+#define GDB_STEP 1
+
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGSEGV 11
+#define SIGALRM 14
+#define SIGTERM 15
+
+#endif /* __XEN_GDBSTUB_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/timer.h
--- /dev/null Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/timer.h Tue Jan 24 16:54:34 2006
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * timer.h
+ *
+ * Copyright (c) 2002-2003 Rolf Neugebauer
+ * Copyright (c) 2002-2005 K A Fraser
+ */
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include <xen/spinlock.h>
+#include <xen/time.h>
+#include <xen/string.h>
+
+struct timer {
+ /* System time expiry value (nanoseconds since boot). */
+ s_time_t expires;
+ /* CPU on which this timer will be installed and executed. */
+ unsigned int cpu;
+ /* On expiry, '(*function)(data)' will be executed in softirq context. */
+ void (*function)(void *);
+ void *data;
+ /* Timer-heap offset. */
+ unsigned int heap_offset;
+ /* Has this timer been killed (cannot be activated)? */
+ int killed;
+};
+
+/*
+ * All functions below can be called for any CPU from any CPU in any context.
+ */
+
+/* Returns TRUE if the given timer is on a timer list. */
+static __inline__ int active_timer(struct timer *timer)
+{
+ return (timer->heap_offset != 0);
+}
+
+/*
+ * It initialises the static fields of the timer structure.
+ * It can be called multiple times to reinitialise a single (inactive) timer.
+ */
+static __inline__ void init_timer(
+ struct timer *timer,
+ void (*function)(void *),
+ void *data,
+ unsigned int cpu)
+{
+ memset(timer, 0, sizeof(*timer));
+ timer->function = function;
+ timer->data = data;
+ timer->cpu = cpu;
+}
+
+/*
+ * Set the expiry time and activate a timer (which must previously have been
+ * initialised by init_timer).
+ */
+extern void set_timer(struct timer *timer, s_time_t expires);
+
+/*
+ * Deactivate a timer (which must previously have been initialised by
+ * init_timer). This function has no effect if the timer is not currently
+ * active.
+ */
+extern void stop_timer(struct timer *timer);
+
+/*
+ * Deactivate a timer and prevent it from being re-set (future calls to
+ * set_timer will silently fail). When this function returns it is guaranteed
+ * that the timer callback handler is not running on any CPU.
+ */
+extern void kill_timer(struct timer *timer);
+
+/*
+ * Initialisation. Must be called before any other timer function.
+ */
+extern void timer_init(void);
+
+#endif /* _TIMER_H_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/blkfront/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/Kconfig Tue Jan 10 15:21:00 2006
+++ /dev/null Tue Jan 24 16:54:34 2006
@@ -1,6 +0,0 @@
-
-config XENBLOCK
- tristate "Block device driver"
- depends on ARCH_XEN
- help
- Block device driver for Xen
diff -r 40bb46f599d9 -r a38c292e8390
linux-2.6-xen-sparse/drivers/xen/netfront/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/Kconfig Tue Jan 10 15:21:00 2006
+++ /dev/null Tue Jan 24 16:54:34 2006
@@ -1,6 +0,0 @@
-
-config XENNET
- tristate "Xen network driver"
- depends on NETDEVICES && ARCH_XEN
- help
- Network driver for Xen
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/cdb.c
--- a/xen/arch/x86/cdb.c Tue Jan 10 15:21:00 2006
+++ /dev/null Tue Jan 24 16:54:34 2006
@@ -1,414 +0,0 @@
-/* Simple hacked-up version of pdb for use in post-mortem debugging of
- Xen and domain 0. This should be a little cleaner, hopefully. Note
- that we can't share a serial line with PDB. */
-/* We try to avoid assuming much about what the rest of the system is
- doing. In particular, dynamic memory allocation is out of the
- question. */
-/* Resuming after we've stopped used to work, but more through luck
- than any actual intention. It doesn't at the moment. */
-#include <xen/lib.h>
-#include <asm/uaccess.h>
-#include <xen/spinlock.h>
-#include <xen/serial.h>
-#include <xen/irq.h>
-#include <asm/debugger.h>
-#include <xen/init.h>
-#include <xen/smp.h>
-#include <xen/console.h>
-#include <asm/apic.h>
-
-/* Printk isn't particularly safe just after we've trapped to the
- debugger. so avoid it. */
-#define dbg_printk(...)
-
-static char opt_cdb[30] = "none";
-string_param("cdb", opt_cdb);
-
-struct xendbg_context {
- int serhnd;
- u8 reply_csum;
- int currently_attached:1;
-};
-
-/* Like copy_from_user, but safe to call with interrupts disabled.
-
- Trust me, and don't look behind the curtain. */
-static unsigned
-dbg_copy_from_user(void *dest, const void *src, unsigned len)
-{
- int __d0, __d1, __d2;
- ASSERT(!local_irq_is_enabled());
- __asm__ __volatile__(
- "1: rep; movsb\n"
- "2:\n"
- ".section .fixup,\"ax\"\n"
- "3: addl $4, %%esp\n"
- " jmp 2b\n"
- ".previous\n"
- ".section __pre_ex_table,\"a\"\n"
- " .align 4\n"
- " .long 1b,3b\n"
- ".previous\n"
- ".section __ex_table,\"a\"\n"
- " .align 4\n"
- " .long 1b,2b\n"
- ".previous\n"
- : "=c"(__d2), "=D" (__d0), "=S" (__d1)
- : "0"(len), "1"(dest), "2"(src)
- : "memory");
- ASSERT(!local_irq_is_enabled());
- return __d2;
-}
-
-static void
-xendbg_put_char(u8 data, struct xendbg_context *ctx)
-{
- ctx->reply_csum += data;
- serial_putc(ctx->serhnd, data);
-}
-
-static int
-hex_char_val(unsigned char c)
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- else if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- else
- BUG();
- return -1;
-}
-
-/* Receive a command. Returns -1 on csum error, 0 otherwise. */
-/* Does not acknowledge. */
-static int
-attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
-{
- int count;
- u8 csum;
- u8 received_csum;
- u8 ch;
-
- /* Skip over everything up to the first '$' */
- while ((ch = serial_getc(ctx->serhnd)) != '$')
- ;
- csum = 0;
- for (count = 0; count < 4096; count++) {
- ch = serial_getc(ctx->serhnd);
- if (ch == '#')
- break;
- recv_buf[count] = ch;
- csum += ch;
- }
- if (count == 4096) {
- dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
- return -1;
- }
- recv_buf[count] = 0;
- received_csum = hex_char_val(serial_getc(ctx->serhnd)) * 16 +
- hex_char_val(serial_getc(ctx->serhnd));
- if (received_csum == csum) {
- return 0;
- } else {
- return -1;
- }
-}
-
-/* Send a string of bytes to the debugger. */
-static void
-xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
-{
- int x;
- for (x = 0; x < count; x++)
- xendbg_put_char(buf[x], ctx);
-}
-
-/* Receive a command, discarding up to ten packets with csum
- * errors. Acknowledges all received packets. */
-static int
-receive_command(char *recv_buf, struct xendbg_context *ctx)
-{
- int r;
- int count;
-
- count = 0;
- do {
- r = attempt_receive_packet(recv_buf, ctx);
- if (r < 0)
- xendbg_put_char('-', ctx);
- else
- xendbg_put_char('+', ctx);
- count++;
- } while (r < 0 && count < 10);
- return r;
-}
-
-static void
-xendbg_start_reply(struct xendbg_context *ctx)
-{
- xendbg_put_char('$', ctx);
- ctx->reply_csum = 0;
-}
-
-/* Return 0 if the reply was successfully received, !0 otherwise. */
-static int
-xendbg_finish_reply(struct xendbg_context *ctx)
-{
- char ch;
- char buf[3];
-
- sprintf(buf, "%.02x\n", ctx->reply_csum);
-
- xendbg_put_char('#', ctx);
- xendbg_send(buf, 2, ctx);
-
- ch = serial_getc(ctx->serhnd);
- if (ch == '+')
- return 0;
- else
- return 1;
-}
-
-/* Swap the order of the bytes in a work. */
-static inline unsigned
-bswab32(unsigned val)
-{
- return (((val >> 0) & 0xff) << 24) |
- (((val >> 8) & 0xff) << 16) |
- (((val >> 16) & 0xff) << 8) |
- (((val >> 24) & 0xff) << 0);
-}
-
-static int
-handle_memory_read_command(unsigned long addr, unsigned long length,
- struct xendbg_context *ctx)
-{
- int x;
- unsigned char val;
- int r;
- char buf[2];
-
- dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
- length);
- xendbg_start_reply(ctx);
- for (x = 0; x < length; x++) {
- r = dbg_copy_from_user(&val, (void *)(addr + x), 1);
- if (r != 0) {
- dbg_printk("Error reading from %lx.\n", addr + x);
- break;
- }
- sprintf(buf, "%.02x", val);
- xendbg_send(buf, 2, ctx);
- }
- if (x == 0)
- xendbg_send("E05", 3, ctx);
- dbg_printk("Read done.\n");
- return xendbg_finish_reply(ctx);
-}
-
-static int
-xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
-{
- xendbg_start_reply(ctx);
- xendbg_send(buf, strlen(buf), ctx);
- return xendbg_finish_reply(ctx);
-}
-
-static int
-handle_register_read_command(struct cpu_user_regs *regs, struct xendbg_context
*ctx)
-{
- char buf[121];
-
- sprintf(buf,
-
"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
- bswab32(regs->eax),
- bswab32(regs->ecx),
- bswab32(regs->edx),
- bswab32(regs->ebx),
- bswab32(regs->esp),
- bswab32(regs->ebp),
- bswab32(regs->esi),
- bswab32(regs->edi),
- bswab32(regs->eip),
- bswab32(regs->eflags),
- bswab32(regs->cs),
- bswab32(regs->ss),
- bswab32(regs->ds),
- bswab32(regs->es),
- bswab32(regs->fs),
- bswab32(regs->gs));
- return xendbg_send_reply(buf, ctx);
-}
-
-static int
-process_command(char *received_packet, struct cpu_user_regs *regs,
- struct xendbg_context *ctx)
-{
- char *ptr;
- unsigned long addr, length;
- int retry;
- int counter;
- int resume = 0;
-
- /* Repeat until gdb acks the reply */
- counter = 0;
- do {
- switch (received_packet[0]) {
- case 'g': /* Read registers */
- retry = handle_register_read_command(regs, ctx);
- ASSERT(!local_irq_is_enabled());
- break;
- case 'm': /* Read memory */
- addr = simple_strtoul(received_packet + 1, &ptr, 16);
- if (ptr == received_packet + 1 ||
- ptr[0] != ',') {
- xendbg_send_reply("E03", ctx);
- return 0;
- }
- length = simple_strtoul(ptr + 1, &ptr, 16);
- if (ptr[0] != 0) {
- xendbg_send_reply("E04", ctx);
- return 0;
- }
- retry =
- handle_memory_read_command(addr,
- length,
- ctx);
- ASSERT(!local_irq_is_enabled());
- break;
- case 'G': /* Write registers */
- case 'M': /* Write memory */
- retry = xendbg_send_reply("E02", ctx);
- break;
- case 'D':
- resume = 1;
- ctx->currently_attached = 0;
- retry = xendbg_send_reply("", ctx);
- break;
- case 'c': /* Resume at current address */
- ctx->currently_attached = 1;
- resume = 1;
- retry = 0;
- break;
- case 'Z': /* We need to claim to support these or gdb
- won't let you continue the process. */
- case 'z':
- retry = xendbg_send_reply("OK", ctx);
- break;
-
- case 's': /* Single step */
- case '?':
- retry = xendbg_send_reply("S01", ctx);
- break;
- default:
- retry = xendbg_send_reply("", ctx);
- break;
- }
- counter++;
- } while (retry == 1 && counter < 10);
- if (retry) {
- dbg_printk("WARNING: gdb disappeared when we were trying to
send it a reply.\n");
- return 1;
- }
- return resume;
-}
-
-static struct xendbg_context
-xdb_ctx = {
- serhnd : -1
-};
-
-int
-__trap_to_cdb(struct cpu_user_regs *regs)
-{
- int resume = 0;
- int r;
- static atomic_t xendbg_running = ATOMIC_INIT(1);
- static char recv_buf[4096];
- unsigned flags;
-
- if (xdb_ctx.serhnd < 0) {
- dbg_printk("Debugger not ready yet.\n");
- return 0;
- }
-
- /* We rely on our caller to ensure we're only on one processor
- * at a time... We should probably panic here, but given that
- * we're a debugger we should probably be a little tolerant of
- * things going wrong. */
- /* We don't want to use a spin lock here, because we're doing
- two distinct things:
-
- 1 -- we don't want to run on more than one processor at a time,
- and
- 2 -- we want to do something sensible if we re-enter ourselves.
-
- Spin locks are good for 1, but useless for 2. */
- if (!atomic_dec_and_test(&xendbg_running)) {
- printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
- atomic_inc(&xendbg_running);
- return 0;
- }
-
- smp_send_stop();
-
- /* Try to make things a little more stable by disabling
- interrupts while we're here. */
- local_irq_save(flags);
-
- watchdog_disable();
- console_start_sync();
-
- /* Shouldn't really do this, but otherwise we stop for no
- obvious reason, which is Bad */
- printk("Waiting for GDB to attach to XenDBG\n");
-
- /* If gdb is already attached, tell it we've stopped again. */
- if (xdb_ctx.currently_attached) {
- do {
- r = xendbg_send_reply("S01", &xdb_ctx);
- } while (r != 0);
- }
-
- while (resume == 0) {
- ASSERT(!local_irq_is_enabled());
- r = receive_command(recv_buf, &xdb_ctx);
- ASSERT(!local_irq_is_enabled());
- if (r < 0) {
- dbg_printk("GDB disappeared, trying to resume
Xen...\n");
- resume = 1;
- } else {
- ASSERT(!local_irq_is_enabled());
- resume = process_command(recv_buf, regs, &xdb_ctx);
- ASSERT(!local_irq_is_enabled());
- }
- }
-
- console_end_sync();
- watchdog_enable();
- atomic_inc(&xendbg_running);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static int
-initialize_xendbg(void)
-{
- if (!strcmp(opt_cdb, "none"))
- return 0;
- xdb_ctx.serhnd = serial_parse_handle(opt_cdb);
- if (xdb_ctx.serhnd == -1)
- panic("Can't parse %s as CDB serial info.\n", opt_cdb);
-
- /* Acknowledge any spurious GDB packets. */
- xendbg_put_char('+', &xdb_ctx);
-
- printk("Xendbg initialised.\n");
- return 0;
-}
-
-__initcall(initialize_xendbg);
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/ac_timer.c
--- a/xen/common/ac_timer.c Tue Jan 10 15:21:00 2006
+++ /dev/null Tue Jan 24 16:54:34 2006
@@ -1,286 +0,0 @@
-/******************************************************************************
- * ac_timer.c
- *
- * Copyright (c) 2002-2003 Rolf Neugebauer
- * Copyright (c) 2002-2005 K A Fraser
- */
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/types.h>
-#include <xen/errno.h>
-#include <xen/sched.h>
-#include <xen/lib.h>
-#include <xen/smp.h>
-#include <xen/perfc.h>
-#include <xen/time.h>
-#include <xen/softirq.h>
-#include <xen/ac_timer.h>
-#include <xen/keyhandler.h>
-#include <asm/system.h>
-#include <asm/desc.h>
-
-/*
- * We pull handlers off the timer list this far in future,
- * rather than reprogramming the time hardware.
- */
-#define TIMER_SLOP (50*1000) /* ns */
-
-struct ac_timers {
- spinlock_t lock;
- struct ac_timer **heap;
- unsigned int softirqs;
-} __cacheline_aligned;
-
-struct ac_timers ac_timers[NR_CPUS];
-
-extern int reprogram_ac_timer(s_time_t timeout);
-
-/****************************************************************************
- * HEAP OPERATIONS.
- */
-
-#define GET_HEAP_SIZE(_h) ((int)(((u16 *)(_h))[0]))
-#define SET_HEAP_SIZE(_h,_v) (((u16 *)(_h))[0] = (u16)(_v))
-
-#define GET_HEAP_LIMIT(_h) ((int)(((u16 *)(_h))[1]))
-#define SET_HEAP_LIMIT(_h,_v) (((u16 *)(_h))[1] = (u16)(_v))
-
-/* Sink down element @pos of @heap. */
-static void down_heap(struct ac_timer **heap, int pos)
-{
- int sz = GET_HEAP_SIZE(heap), nxt;
- struct ac_timer *t = heap[pos];
-
- while ( (nxt = (pos << 1)) <= sz )
- {
- if ( ((nxt+1) <= sz) && (heap[nxt+1]->expires < heap[nxt]->expires) )
- nxt++;
- if ( heap[nxt]->expires > t->expires )
- break;
- heap[pos] = heap[nxt];
- heap[pos]->heap_offset = pos;
- pos = nxt;
- }
-
- heap[pos] = t;
- t->heap_offset = pos;
-}
-
-/* Float element @pos up @heap. */
-static void up_heap(struct ac_timer **heap, int pos)
-{
- struct ac_timer *t = heap[pos];
-
- while ( (pos > 1) && (t->expires < heap[pos>>1]->expires) )
- {
- heap[pos] = heap[pos>>1];
- heap[pos]->heap_offset = pos;
- pos >>= 1;
- }
-
- heap[pos] = t;
- t->heap_offset = pos;
-}
-
-
-/* Delete @t from @heap. Return TRUE if new top of heap. */
-static int remove_entry(struct ac_timer **heap, struct ac_timer *t)
-{
- int sz = GET_HEAP_SIZE(heap);
- int pos = t->heap_offset;
-
- t->heap_offset = 0;
-
- if ( unlikely(pos == sz) )
- {
- SET_HEAP_SIZE(heap, sz-1);
- goto out;
- }
-
- heap[pos] = heap[sz];
- heap[pos]->heap_offset = pos;
-
- SET_HEAP_SIZE(heap, --sz);
-
- if ( (pos > 1) && (heap[pos]->expires < heap[pos>>1]->expires) )
- up_heap(heap, pos);
- else
- down_heap(heap, pos);
-
- out:
- return (pos == 1);
-}
-
-
-/* Add new entry @t to @heap. Return TRUE if new top of heap. */
-static int add_entry(struct ac_timer ***pheap, struct ac_timer *t)
-{
- struct ac_timer **heap = *pheap;
- int sz = GET_HEAP_SIZE(heap);
-
- /* Copy the heap if it is full. */
- if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
- {
- /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
- int old_limit = GET_HEAP_LIMIT(heap);
- int new_limit = ((old_limit + 1) << 4) - 1;
- heap = xmalloc_array(struct ac_timer *, new_limit + 1);
- BUG_ON(heap == NULL);
- memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
- SET_HEAP_LIMIT(heap, new_limit);
- if ( old_limit != 0 )
- xfree(*pheap);
- *pheap = heap;
- }
-
- SET_HEAP_SIZE(heap, ++sz);
- heap[sz] = t;
- t->heap_offset = sz;
- up_heap(heap, sz);
- return (t->heap_offset == 1);
-}
-
-
-/****************************************************************************
- * TIMER OPERATIONS.
- */
-
-static inline void __add_ac_timer(struct ac_timer *timer)
-{
- int cpu = timer->cpu;
- if ( add_entry(&ac_timers[cpu].heap, timer) )
- cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
-}
-
-
-static inline void __rem_ac_timer(struct ac_timer *timer)
-{
- int cpu = timer->cpu;
- if ( remove_entry(ac_timers[cpu].heap, timer) )
- cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
-}
-
-
-void set_ac_timer(struct ac_timer *timer, s_time_t expires)
-{
- int cpu = timer->cpu;
- unsigned long flags;
-
- spin_lock_irqsave(&ac_timers[cpu].lock, flags);
- ASSERT(timer != NULL);
- if ( active_ac_timer(timer) )
- __rem_ac_timer(timer);
- timer->expires = expires;
- __add_ac_timer(timer);
- spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
-}
-
-
-void rem_ac_timer(struct ac_timer *timer)
-{
- int cpu = timer->cpu;
- unsigned long flags;
-
- spin_lock_irqsave(&ac_timers[cpu].lock, flags);
- ASSERT(timer != NULL);
- if ( active_ac_timer(timer) )
- __rem_ac_timer(timer);
- spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
-}
-
-
-static void ac_timer_softirq_action(void)
-{
- int cpu = smp_processor_id();
- struct ac_timer *t, **heap;
- s_time_t now;
- void (*fn)(void *);
-
- spin_lock_irq(&ac_timers[cpu].lock);
-
- do {
- heap = ac_timers[cpu].heap;
- now = NOW();
-
- while ( (GET_HEAP_SIZE(heap) != 0) &&
- ((t = heap[1])->expires < (now + TIMER_SLOP)) )
- {
- remove_entry(heap, t);
-
- if ( (fn = t->function) != NULL )
- {
- void *data = t->data;
- spin_unlock_irq(&ac_timers[cpu].lock);
- (*fn)(data);
- spin_lock_irq(&ac_timers[cpu].lock);
- }
-
- /* Heap may have grown while the lock was released. */
- heap = ac_timers[cpu].heap;
- }
- }
- while ( !reprogram_ac_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
-
- spin_unlock_irq(&ac_timers[cpu].lock);
-}
-
-
-static void dump_timerq(unsigned char key)
-{
- struct ac_timer *t;
- unsigned long flags;
- s_time_t now = NOW();
- int i, j;
-
- printk("Dumping ac_timer queues: NOW=0x%08X%08X\n",
- (u32)(now>>32), (u32)now);
-
- for_each_online_cpu( i )
- {
- printk("CPU[%02d] ", i);
- spin_lock_irqsave(&ac_timers[i].lock, flags);
- for ( j = 1; j <= GET_HEAP_SIZE(ac_timers[i].heap); j++ )
- {
- t = ac_timers[i].heap[j];
- printk (" %d : %p ex=0x%08X%08X %p\n",
- j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
- }
- spin_unlock_irqrestore(&ac_timers[i].lock, flags);
- printk("\n");
- }
-}
-
-
-void __init ac_timer_init(void)
-{
- static struct ac_timer *dummy_heap;
- int i;
-
- open_softirq(AC_TIMER_SOFTIRQ, ac_timer_softirq_action);
-
- /*
- * All CPUs initially share an empty dummy heap. Only those CPUs that
- * are brought online will be dynamically allocated their own heap.
- */
- SET_HEAP_SIZE(&dummy_heap, 0);
- SET_HEAP_LIMIT(&dummy_heap, 0);
-
- for ( i = 0; i < NR_CPUS; i++ )
- {
- spin_lock_init(&ac_timers[i].lock);
- ac_timers[i].heap = &dummy_heap;
- }
-
- register_keyhandler('a', dump_timerq, "dump ac_timer queues");
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/ac_timer.h
--- a/xen/include/xen/ac_timer.h Tue Jan 10 15:21:00 2006
+++ /dev/null Tue Jan 24 16:54:34 2006
@@ -1,81 +0,0 @@
-/******************************************************************************
- * ac_timer.h
- *
- * Copyright (c) 2002-2003 Rolf Neugebauer
- * Copyright (c) 2002-2005 K A Fraser
- */
-
-#ifndef _AC_TIMER_H_
-#define _AC_TIMER_H_
-
-#include <xen/spinlock.h>
-#include <xen/time.h>
-#include <xen/string.h>
-
-struct ac_timer {
- /* System time expiry value (nanoseconds since boot). */
- s_time_t expires;
- /* CPU on which this timer will be installed and executed. */
- unsigned int cpu;
- /* On expiry, '(*function)(data)' will be executed in softirq context. */
- void (*function)(void *);
- void *data;
- /* Timer-heap offset. */
- unsigned int heap_offset;
-};
-
-/*
- * All functions below can be called for any CPU from any CPU in any context.
- */
-
-/* Returns TRUE if the given timer is on a timer list. */
-static __inline__ int active_ac_timer(struct ac_timer *timer)
-{
- return (timer->heap_offset != 0);
-}
-
-/*
- * It initialises the static fields of the ac_timer structure.
- * It can be called multiple times to reinitialise a single (inactive) timer.
- */
-static __inline__ void init_ac_timer(
- struct ac_timer *timer,
- void (*function)(void *),
- void *data,
- unsigned int cpu)
-{
- memset(timer, 0, sizeof(*timer));
- timer->function = function;
- timer->data = data;
- timer->cpu = cpu;
-}
-
-/*
- * Set the expiry time and activate a timer (which must previously have been
- * initialised by init_ac_timer).
- */
-extern void set_ac_timer(struct ac_timer *timer, s_time_t expires);
-
-/*
- * Deactivate a timer (which must previously have been initialised by
- * init_ac_timer). This function has no effect if the timer is not currently
- * active.
- */
-extern void rem_ac_timer(struct ac_timer *timer);
-
-/*
- * Initialisation. Must be called before any other ac_timer function.
- */
-extern void ac_timer_init(void);
-
-#endif /* _AC_TIMER_H_ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|