ia64/xen-unstable

changeset 8647:a38c292e8390

Merged.
author emellor@leeni.uk.xensource.com
date Tue Jan 24 17:54:34 2006 +0100 (2006-01-24)
parents 40bb46f599d9 1f87f39aa0e1
children 018e6dc18f97
files
line diff
     1.1 --- a/.hgignore	Tue Jan 10 15:21:00 2006 +0000
     1.2 +++ b/.hgignore	Tue Jan 24 17:54:34 2006 +0100
     1.3 @@ -163,6 +163,7 @@
     1.4  ^tools/xenstore/xenstore-read$
     1.5  ^tools/xenstore/xenstore-rm$
     1.6  ^tools/xenstore/xenstore-write$
     1.7 +^tools/xenstore/xenstore-ls$
     1.8  ^tools/xenstore/xenstored$
     1.9  ^tools/xenstore/xenstored_test$
    1.10  ^tools/xenstore/xs_crashme$
    1.11 @@ -171,7 +172,6 @@
    1.12  ^tools/xenstore/xs_tdb_dump$
    1.13  ^tools/xenstore/xs_test$
    1.14  ^tools/xenstore/xs_watch_stress$
    1.15 -^tools/xenstore/xsls$
    1.16  ^tools/xentrace/setsize$
    1.17  ^tools/xentrace/tbctl$
    1.18  ^tools/xentrace/xenctx$
     2.1 --- a/docs/man/xm.pod.1	Tue Jan 10 15:21:00 2006 +0000
     2.2 +++ b/docs/man/xm.pod.1	Tue Jan 24 17:54:34 2006 +0100
     2.3 @@ -374,7 +374,7 @@ Attempting to set-vcpus to a number larg
     2.4  configured VCPU count is an error.  Trying to set-vcpus to < 1 will be
     2.5  quietly ignored.
     2.6  
     2.7 -=item B<vpcu-list> I<[domain-id]>
     2.8 +=item B<vcpu-list> I<[domain-id]>
     2.9  
    2.10  Lists VCPU information for a specific domain.  If no domain is
    2.11  specified, VCPU information for all domains will be provided.
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64	Tue Jan 10 15:21:00 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64	Tue Jan 24 17:54:34 2006 +0100
     3.3 @@ -91,8 +91,7 @@ CONFIG_IA64_PAGE_SIZE_16KB=y
     3.4  # CONFIG_IA64_PAGE_SIZE_64KB is not set
     3.5  CONFIG_IA64_L1_CACHE_SHIFT=7
     3.6  # CONFIG_NUMA is not set
     3.7 -CONFIG_VIRTUAL_MEM_MAP=y
     3.8 -CONFIG_HOLES_IN_ZONE=y
     3.9 +CONFIG_VIRTUAL_MEM_MAP=n
    3.10  CONFIG_IA64_CYCLONE=y
    3.11  CONFIG_IOSAPIC=y
    3.12  CONFIG_FORCE_MAX_ZONEORDER=18
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S	Tue Jan 10 15:21:00 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S	Tue Jan 24 17:54:34 2006 +0100
     4.3 @@ -76,7 +76,9 @@ IF_MASK		= 0x00000200
     4.4  DF_MASK		= 0x00000400 
     4.5  NT_MASK		= 0x00004000
     4.6  VM_MASK		= 0x00020000
     4.7 -
     4.8 +/* Pseudo-eflags. */
     4.9 +NMI_MASK	= 0x80000000
    4.10 +	
    4.11  /* Offsets into shared_info_t. */
    4.12  #define evtchn_upcall_pending		/* 0 */
    4.13  #define evtchn_upcall_mask		1
    4.14 @@ -305,8 +307,8 @@ restore_all:
    4.15  	je ldt_ss			# returning to user-space with LDT SS
    4.16  #endif /* XEN */
    4.17  restore_nocheck:
    4.18 -	testl $VM_MASK, EFLAGS(%esp)
    4.19 -	jnz resume_vm86
    4.20 +	testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
    4.21 +	jnz hypervisor_iret
    4.22  	movb EVENT_MASK(%esp), %al
    4.23  	notb %al			# %al == ~saved_mask
    4.24  	XEN_GET_VCPU_INFO(%esi)
    4.25 @@ -328,11 +330,11 @@ iret_exc:
    4.26  	.long 1b,iret_exc
    4.27  .previous
    4.28  
    4.29 -resume_vm86:
    4.30 -	XEN_UNBLOCK_EVENTS(%esi)
    4.31 +hypervisor_iret:
    4.32 +	andl $~NMI_MASK, EFLAGS(%esp)
    4.33  	RESTORE_REGS
    4.34  	movl %eax,(%esp)
    4.35 -	movl $__HYPERVISOR_switch_vm86,%eax
    4.36 +	movl $__HYPERVISOR_iret,%eax
    4.37  	int $0x82
    4.38  	ud2
    4.39  
    4.40 @@ -691,6 +693,15 @@ debug_stack_correct:
    4.41  	call do_debug
    4.42  	jmp ret_from_exception
    4.43  
    4.44 +ENTRY(nmi)
    4.45 +	pushl %eax
    4.46 +	SAVE_ALL
    4.47 +	xorl %edx,%edx		# zero error code
    4.48 +	movl %esp,%eax		# pt_regs pointer
    4.49 +	call do_nmi
    4.50 +	orl  $NMI_MASK, EFLAGS(%esp)
    4.51 +	jmp restore_all
    4.52 +
    4.53  #if 0 /* XEN */
    4.54  /*
    4.55   * NMI is doubly nasty. It can happen _while_ we're handling
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c	Tue Jan 10 15:21:00 2006 +0000
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c	Tue Jan 24 17:54:34 2006 +0100
     5.3 @@ -622,9 +622,11 @@ static int balanced_irq(void *unused)
     5.4  		try_to_freeze(PF_FREEZE);
     5.5  		if (time_after(jiffies,
     5.6  				prev_balance_time+balanced_irq_interval)) {
     5.7 +			preempt_disable();
     5.8  			do_irq_balance();
     5.9  			prev_balance_time = jiffies;
    5.10  			time_remaining = balanced_irq_interval;
    5.11 +			preempt_enable();
    5.12  		}
    5.13  	}
    5.14  	return 0;
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Jan 10 15:21:00 2006 +0000
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c	Tue Jan 24 17:54:34 2006 +0100
     6.3 @@ -506,18 +506,11 @@ static void mem_parity_error(unsigned ch
     6.4  
     6.5  static void io_check_error(unsigned char reason, struct pt_regs * regs)
     6.6  {
     6.7 -	unsigned long i;
     6.8 -
     6.9  	printk("NMI: IOCK error (debug interrupt?)\n");
    6.10  	show_registers(regs);
    6.11  
    6.12  	/* Re-enable the IOCK line, wait for a few seconds */
    6.13 -	reason = (reason & 0xf) | 8;
    6.14 -	outb(reason, 0x61);
    6.15 -	i = 2000;
    6.16 -	while (--i) udelay(1000);
    6.17 -	reason &= ~8;
    6.18 -	outb(reason, 0x61);
    6.19 +	clear_io_check_error(reason);
    6.20  }
    6.21  
    6.22  static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
    6.23 @@ -648,12 +641,6 @@ fastcall void do_int3(struct pt_regs *re
    6.24  }
    6.25  #endif
    6.26  
    6.27 -static inline void conditional_sti(struct pt_regs *regs)
    6.28 -{
    6.29 -	if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
    6.30 -		local_irq_enable();
    6.31 -}
    6.32 -
    6.33  /*
    6.34   * Our handling of the processor debug registers is non-trivial.
    6.35   * We do not clear them on entry and exit from the kernel. Therefore
    6.36 @@ -686,9 +673,9 @@ fastcall void do_debug(struct pt_regs * 
    6.37  	if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
    6.38  					SIGTRAP) == NOTIFY_STOP)
    6.39  		return;
    6.40 -
    6.41  	/* It's safe to allow irq's after DR6 has been saved */
    6.42 -	conditional_sti(regs);
    6.43 +	if (regs->eflags & X86_EFLAGS_IF)
    6.44 +		local_irq_enable();
    6.45  
    6.46  	/* Mask out spurious debug traps due to lazy DR7 setting */
    6.47  	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Tue Jan 10 15:21:00 2006 +0000
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c	Tue Jan 24 17:54:34 2006 +0100
     7.3 @@ -65,7 +65,7 @@ static pmd_t * __init one_md_table_init(
     7.4  {
     7.5  	pud_t *pud;
     7.6  	pmd_t *pmd_table;
     7.7 -
     7.8 +		
     7.9  #ifdef CONFIG_X86_PAE
    7.10  	pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
    7.11  	make_lowmem_page_readonly(pmd_table);
     8.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Tue Jan 10 15:21:00 2006 +0000
     8.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Tue Jan 24 17:54:34 2006 +0100
     8.3 @@ -290,15 +290,15 @@ static void shutdown_handler(struct xenb
     8.4  			     const char **vec, unsigned int len)
     8.5  {
     8.6  	char *str;
     8.7 -	struct xenbus_transaction *xbt;
     8.8 +	xenbus_transaction_t xbt;
     8.9  	int err;
    8.10  
    8.11  	if (shutting_down != SHUTDOWN_INVALID)
    8.12  		return;
    8.13  
    8.14   again:
    8.15 -	xbt = xenbus_transaction_start();
    8.16 -	if (IS_ERR(xbt))
    8.17 +	err = xenbus_transaction_start(&xbt);
    8.18 +	if (err)
    8.19  		return;
    8.20  	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
    8.21  	/* Ignore read errors and empty reads. */
    8.22 @@ -339,12 +339,12 @@ static void sysrq_handler(struct xenbus_
    8.23  			  unsigned int len)
    8.24  {
    8.25  	char sysrq_key = '\0';
    8.26 -	struct xenbus_transaction *xbt;
    8.27 +	xenbus_transaction_t xbt;
    8.28  	int err;
    8.29  
    8.30   again:
    8.31 -	xbt  = xenbus_transaction_start();
    8.32 -	if (IS_ERR(xbt))
    8.33 +	err = xenbus_transaction_start(&xbt);
    8.34 +	if (err)
    8.35  		return;
    8.36  	if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
    8.37  		printk(KERN_ERR "Unable to read sysrq code in "
     9.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c	Tue Jan 10 15:21:00 2006 +0000
     9.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c	Tue Jan 24 17:54:34 2006 +0100
     9.3 @@ -526,7 +526,7 @@ extern union xen_start_info_union xen_st
     9.4  
     9.5  unsigned long __init e820_end_of_ram(void)
     9.6  {
     9.7 -        unsigned long max_end_pfn;
     9.8 +	unsigned long max_end_pfn;
     9.9  
    9.10  	if (xen_override_max_pfn == 0) {
    9.11  		max_end_pfn = xen_start_info->nr_pages;
    9.12 @@ -612,7 +612,7 @@ void __init parse_memopt(char *p, char *
    9.13  { 
    9.14  	end_user_pfn = memparse(p, from);
    9.15  	end_user_pfn >>= PAGE_SHIFT;	
    9.16 -        xen_override_max_pfn = (unsigned long) end_user_pfn;
    9.17 +	xen_override_max_pfn = (unsigned long) end_user_pfn;
    9.18  } 
    9.19  
    9.20  /*
    10.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S	Tue Jan 10 15:21:00 2006 +0000
    10.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S	Tue Jan 24 17:54:34 2006 +0100
    10.3 @@ -57,7 +57,7 @@
    10.4  #ifndef CONFIG_PREEMPT
    10.5  #define retint_kernel retint_restore_args
    10.6  #endif	
    10.7 -
    10.8 +	
    10.9  /*
   10.10   * C code is not supposed to know about undefined top of stack. Every time 
   10.11   * a C function with an pt_regs argument is called from the SYSCALL based 
   10.12 @@ -65,7 +65,7 @@
   10.13   * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
   10.14   * manipulation.
   10.15   */        	
   10.16 -
   10.17 +		
   10.18  	/* %rsp:at FRAMEEND */ 
   10.19  	.macro FIXUP_TOP_OF_STACK tmp
   10.20  	movq    $__USER_CS,CS(%rsp)
   10.21 @@ -121,19 +121,19 @@
   10.22  	.endm
   10.23  
   10.24          /*
   10.25 -         * Must be consistent with the definition in arch_x86_64.h:    
   10.26 -         *     struct switch_to_user {
   10.27 +         * Must be consistent with the definition in arch-x86_64.h:    
   10.28 +         *     struct iret_context {
   10.29           *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
   10.30           *     };
   10.31           * #define VGCF_IN_SYSCALL (1<<8) 
   10.32           */
   10.33 -        .macro SWITCH_TO_USER flag
   10.34 +        .macro HYPERVISOR_IRET flag
   10.35          subq $8*4,%rsp                   # reuse rip, cs, rflags, rsp, ss in the stack
   10.36          movq %rax,(%rsp)
   10.37          movq %r11,1*8(%rsp)
   10.38          movq %rcx,2*8(%rsp)              # we saved %rcx upon exceptions
   10.39          movq $\flag,3*8(%rsp)
   10.40 -        movq $__HYPERVISOR_switch_to_user,%rax
   10.41 +        movq $__HYPERVISOR_iret,%rax
   10.42          syscall
   10.43          .endm
   10.44  
   10.45 @@ -225,7 +225,7 @@ sysret_check:
   10.46  	jnz  sysret_careful 
   10.47          XEN_UNBLOCK_EVENTS(%rsi)                
   10.48  	RESTORE_ARGS 0,8,0
   10.49 -        SWITCH_TO_USER VGCF_IN_SYSCALL
   10.50 +        HYPERVISOR_IRET VGCF_IN_SYSCALL
   10.51  
   10.52  	/* Handle reschedules */
   10.53  	/* edx:	work, edi: workmask */	
   10.54 @@ -418,7 +418,6 @@ ENTRY(stub_rt_sigreturn)
   10.55  	jmp int_ret_from_sys_call
   10.56  	CFI_ENDPROC
   10.57  
   10.58 -
   10.59  /* 
   10.60   * Interrupt entry/exit.
   10.61   *
   10.62 @@ -479,7 +478,7 @@ kernel_mode:
   10.63          orb   $3,1*8(%rsp)
   10.64  	iretq
   10.65  user_mode:
   10.66 -	SWITCH_TO_USER 0                        
   10.67 +	HYPERVISOR_IRET 0
   10.68  	
   10.69  	/* edi: workmask, edx: work */	
   10.70  retint_careful:
   10.71 @@ -720,6 +719,18 @@ 11:	movb $0, EVENT_MASK(%rsp)
   10.72  	call evtchn_do_upcall
   10.73          jmp  error_exit
   10.74  
   10.75 +#ifdef CONFIG_X86_LOCAL_APIC
   10.76 +ENTRY(nmi)
   10.77 +	zeroentry do_nmi_callback
   10.78 +ENTRY(do_nmi_callback)
   10.79 +        addq $8, %rsp
   10.80 +        call do_nmi
   10.81 +        RESTORE_REST
   10.82 +        XEN_BLOCK_EVENTS(%rsi)
   10.83 +        GET_THREAD_INFO(%rcx)
   10.84 +        jmp  retint_restore_args
   10.85 +#endif
   10.86 +
   10.87          ALIGN
   10.88  restore_all_enable_events:  
   10.89  	XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
   10.90 @@ -734,7 +745,7 @@ scrit:	/**** START OF CRITICAL REGION **
   10.91          orb   $3,1*8(%rsp)
   10.92          iretq
   10.93  crit_user_mode:
   10.94 -        SWITCH_TO_USER 0
   10.95 +        HYPERVISOR_IRET 0
   10.96          
   10.97  14:	XEN_LOCKED_BLOCK_EVENTS(%rsi)
   10.98  	XEN_PUT_VCPU_INFO(%rsi)
    11.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c	Tue Jan 10 15:21:00 2006 +0000
    11.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c	Tue Jan 24 17:54:34 2006 +0100
    11.3 @@ -68,13 +68,13 @@ static void __init copy_bootdata(char *r
    11.4  
    11.5  static void __init setup_boot_cpu_data(void)
    11.6  {
    11.7 -	int dummy, eax;
    11.8 +	unsigned int dummy, eax;
    11.9  
   11.10  	/* get vendor info */
   11.11 -	cpuid(0, &boot_cpu_data.cpuid_level,
   11.12 -	      (int *)&boot_cpu_data.x86_vendor_id[0],
   11.13 -	      (int *)&boot_cpu_data.x86_vendor_id[8],
   11.14 -	      (int *)&boot_cpu_data.x86_vendor_id[4]);
   11.15 +	cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
   11.16 +	      (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
   11.17 +	      (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
   11.18 +	      (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
   11.19  
   11.20  	/* get cpu type */
   11.21  	cpuid(1, &eax, &dummy, &dummy,
   11.22 @@ -109,7 +109,6 @@ void __init x86_64_start_kernel(char * r
   11.23  	if (s != NULL)
   11.24  		setup_early_printk(s);
   11.25  #endif
   11.26 -
   11.27  #ifdef CONFIG_DISCONTIGMEM
   11.28  	s = strstr(saved_command_line, "numa=");
   11.29  	if (s != NULL)
    12.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c	Tue Jan 10 15:21:00 2006 +0000
    12.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c	Tue Jan 24 17:54:34 2006 +0100
    12.3 @@ -255,11 +255,9 @@ static int __init enable_ioapic_setup(ch
    12.4  	return 1;
    12.5  }
    12.6  
    12.7 -
    12.8  __setup("noapic", disable_ioapic_setup);
    12.9  __setup("apic", enable_ioapic_setup);
   12.10  
   12.11 -
   12.12  #include <asm/pci-direct.h>
   12.13  #include <linux/pci_ids.h>
   12.14  #include <linux/pci.h>
   12.15 @@ -1146,6 +1144,7 @@ void __apicdebuginit print_PIC(void)
   12.16  	v = inb(0x4d1) << 8 | inb(0x4d0);
   12.17  	printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
   12.18  }
   12.19 +
   12.20  #endif  /*  0  */
   12.21  
   12.22  #else
   12.23 @@ -1191,6 +1190,7 @@ void disable_IO_APIC(void)
   12.24  	 * Clear the IO-APIC before rebooting:
   12.25  	 */
   12.26  	clear_IO_APIC();
   12.27 +
   12.28  #ifndef CONFIG_XEN
   12.29  	disconnect_bsp_APIC();
   12.30  #endif
   12.31 @@ -1202,6 +1202,7 @@ void disable_IO_APIC(void)
   12.32   *
   12.33   * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
   12.34   */
   12.35 +
   12.36  #ifndef CONFIG_XEN
   12.37  static void __init setup_ioapic_ids_from_mpc (void)
   12.38  {
    13.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c	Tue Jan 10 15:21:00 2006 +0000
    13.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c	Tue Jan 24 17:54:34 2006 +0100
    13.3 @@ -9,18 +9,15 @@
    13.4   * x86_64-specific irq controller code. (e.g. i8259.c and
    13.5   * io_apic.c.)
    13.6   */
    13.7 -#include <asm/uaccess.h>
    13.8 -#include <linux/module.h>
    13.9 -#include <linux/seq_file.h>
   13.10 -#include <linux/interrupt.h>
   13.11 +
   13.12  #include <linux/kernel_stat.h>
   13.13 -
   13.14 -/*
   13.15 - * Interrupt statistics:
   13.16 - */
   13.17 +#include <linux/interrupt.h>
   13.18 +#include <linux/seq_file.h>
   13.19 +#include <linux/module.h>
   13.20 +#include <asm/uaccess.h>
   13.21 +#include <asm/io_apic.h>
   13.22  
   13.23  atomic_t irq_err_count;
   13.24 -
   13.25  #ifdef CONFIG_X86_IO_APIC
   13.26  #ifdef APIC_MISMATCH_DEBUG
   13.27  atomic_t irq_mis_count;
    14.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c	Tue Jan 10 15:21:00 2006 +0000
    14.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c	Tue Jan 24 17:54:34 2006 +0100
    14.3 @@ -62,6 +62,7 @@ static int alloc_ldt(mm_context_t *pc, u
    14.4  	if (reload) {
    14.5  #ifdef CONFIG_SMP
    14.6  		cpumask_t mask;
    14.7 +
    14.8  		preempt_disable();
    14.9  #endif
   14.10  		make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
   14.11 @@ -201,6 +202,7 @@ static int write_ldt(void __user * ptr, 
   14.12  	struct user_desc ldt_info;
   14.13  
   14.14  	error = -EINVAL;
   14.15 +
   14.16  	if (bytecount != sizeof(ldt_info))
   14.17  		goto out;
   14.18  	error = -EFAULT; 	
    15.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Tue Jan 10 15:21:00 2006 +0000
    15.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c	Tue Jan 24 17:54:34 2006 +0100
    15.3 @@ -62,6 +62,7 @@
    15.4  #include <asm-xen/xen-public/physdev.h>
    15.5  #include "setup_arch_pre.h"
    15.6  #include <asm/hypervisor.h>
    15.7 +#include <asm-xen/xen-public/nmi.h>
    15.8  #define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
    15.9  #define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
   15.10  #define end_pfn_map end_pfn
   15.11 @@ -304,7 +305,6 @@ static void __init probe_roms(void)
   15.12  }
   15.13  #endif
   15.14  
   15.15 -
   15.16  static __init void parse_cmdline_early (char ** cmdline_p)
   15.17  {
   15.18  	char c = ' ', *to = command_line, *from = COMMAND_LINE;
   15.19 @@ -379,6 +379,7 @@ static __init void parse_cmdline_early (
   15.20  			acpi_skip_timer_override = 1;
   15.21  #endif
   15.22  #endif
   15.23 +
   15.24  #ifndef CONFIG_XEN
   15.25  		if (!memcmp(from, "nolapic", 7) ||
   15.26  		    !memcmp(from, "disableapic", 11))
   15.27 @@ -391,7 +392,8 @@ static __init void parse_cmdline_early (
   15.28  			skip_ioapic_setup = 0;
   15.29  			ioapic_force = 1;
   15.30  		}
   15.31 -#endif			
   15.32 +#endif
   15.33 +			
   15.34  		if (!memcmp(from, "mem=", 4))
   15.35  			parse_memopt(from+4, &from); 
   15.36  
   15.37 @@ -588,7 +590,7 @@ void __init setup_arch(char **cmdline_p)
   15.38  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
   15.39  			     VMASST_TYPE_writable_pagetables);
   15.40  
   15.41 -        ARCH_SETUP
   15.42 +	ARCH_SETUP
   15.43  #else
   15.44   	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
   15.45   	drive_info = DRIVE_INFO;
   15.46 @@ -612,7 +614,7 @@ void __init setup_arch(char **cmdline_p)
   15.47  	init_mm.end_code = (unsigned long) &_etext;
   15.48  	init_mm.end_data = (unsigned long) &_edata;
   15.49  #ifdef CONFIG_XEN
   15.50 -        init_mm.brk = start_pfn << PAGE_SHIFT;
   15.51 +	init_mm.brk = start_pfn << PAGE_SHIFT;
   15.52  #else
   15.53  	init_mm.brk = (unsigned long) &_end;	
   15.54  
   15.55 @@ -668,7 +670,6 @@ void __init setup_arch(char **cmdline_p)
   15.56  	reserve_ebda_region();
   15.57  #endif
   15.58  
   15.59 -
   15.60  #ifdef CONFIG_SMP
   15.61  	/*
   15.62  	 * But first pinch a few for the stack/trampoline stuff
   15.63 @@ -790,8 +791,6 @@ void __init setup_arch(char **cmdline_p)
   15.64  
   15.65  	}
   15.66  
   15.67 -
   15.68 -
   15.69  	if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
   15.70  	{
   15.71  		acpi_disabled = 1;
   15.72 @@ -835,7 +834,7 @@ void __init setup_arch(char **cmdline_p)
   15.73  	 * and also for regions reported as reserved by the e820.
   15.74  	 */
   15.75  	probe_roms();
   15.76 -	e820_reserve_resources();
   15.77 +	e820_reserve_resources(); 
   15.78  #endif
   15.79  
   15.80  	request_resource(&iomem_resource, &video_ram_resource);
    16.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c	Tue Jan 10 15:21:00 2006 +0000
    16.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c	Tue Jan 24 17:54:34 2006 +0100
    16.3 @@ -33,6 +33,7 @@
    16.4  #ifdef CONFIG_XEN
    16.5  #include <asm/hypervisor.h>
    16.6  #endif
    16.7 +
    16.8  char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
    16.9  
   16.10  cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
   16.11 @@ -165,7 +166,6 @@ void __init cpu_gdt_init(struct desc_ptr
   16.12  }
   16.13  #endif
   16.14  
   16.15 -
   16.16  void pda_init(int cpu)
   16.17  { 
   16.18  	struct x8664_pda *pda = &cpu_pda[cpu];
   16.19 @@ -175,9 +175,10 @@ void pda_init(int cpu)
   16.20  #ifndef CONFIG_XEN
   16.21  	wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
   16.22  #else
   16.23 -        HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL, 
   16.24 -                                    (unsigned long)(cpu_pda + cpu));
   16.25 +	HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL, 
   16.26 +				    (unsigned long)(cpu_pda + cpu));
   16.27  #endif
   16.28 +
   16.29  	pda->me = pda;
   16.30  	pda->cpunumber = cpu; 
   16.31  	pda->irqcount = -1;
   16.32 @@ -201,6 +202,7 @@ void pda_init(int cpu)
   16.33  	}
   16.34  
   16.35  	switch_pt();
   16.36 +
   16.37  	pda->irqstackptr += IRQSTACKSIZE-64;
   16.38  } 
   16.39  
    17.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c	Tue Jan 10 15:21:00 2006 +0000
    17.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c	Tue Jan 24 17:54:34 2006 +0100
    17.3 @@ -30,8 +30,9 @@
    17.4  #include <asm/apicdef.h>
    17.5  #ifdef CONFIG_XEN
    17.6  #include <asm-xen/evtchn.h>
    17.7 +#endif
    17.8  
    17.9 -#else
   17.10 +#ifndef CONFIG_XEN
   17.11  /*
   17.12   *	Smarter SMP flushing macros. 
   17.13   *		c/o Linus Torvalds.
    18.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Tue Jan 10 15:21:00 2006 +0000
    18.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c	Tue Jan 24 17:54:34 2006 +0100
    18.3 @@ -559,9 +559,11 @@ static void mem_parity_error(unsigned ch
    18.4  	printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
    18.5  	printk("You probably have a hardware problem with your RAM chips\n");
    18.6  
    18.7 +#if 0 /* XEN */
    18.8  	/* Clear and disable the memory parity error line. */
    18.9  	reason = (reason & 0xf) | 4;
   18.10  	outb(reason, 0x61);
   18.11 +#endif /* XEN */
   18.12  }
   18.13  
   18.14  static void io_check_error(unsigned char reason, struct pt_regs * regs)
   18.15 @@ -569,12 +571,14 @@ static void io_check_error(unsigned char
   18.16  	printk("NMI: IOCK error (debug interrupt?)\n");
   18.17  	show_registers(regs);
   18.18  
   18.19 +#if 0 /* XEN */
   18.20  	/* Re-enable the IOCK line, wait for a few seconds */
   18.21  	reason = (reason & 0xf) | 8;
   18.22  	outb(reason, 0x61);
   18.23  	mdelay(2000);
   18.24  	reason &= ~8;
   18.25  	outb(reason, 0x61);
   18.26 +#endif /* XEN */
   18.27  }
   18.28  
   18.29  static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
   18.30 @@ -890,7 +894,6 @@ asmlinkage void __attribute__((weak)) sm
   18.31  asmlinkage void math_state_restore(void)
   18.32  {
   18.33  	struct task_struct *me = current;
   18.34 -        
   18.35          /* clts(); */ /* 'clts' is done for us by Xen during virtual trap. */
   18.36  
   18.37  	if (!used_math())
    19.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Tue Jan 10 15:21:00 2006 +0000
    19.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c	Tue Jan 24 17:54:34 2006 +0100
    19.3 @@ -153,7 +153,6 @@ void dump_pagetable(unsigned long addres
    19.4  	pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
    19.5  	preempt_enable();
    19.6  	pgd += pgd_index(address);
    19.7 -
    19.8  	printk("PGD %lx ", pgd_val(*pgd));
    19.9  	if (bad_address(pgd)) goto bad;
   19.10  	if (!pgd_present(*pgd)) goto ret; 
   19.11 @@ -258,7 +257,6 @@ static int vmalloc_fault(unsigned long a
   19.12  	pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
   19.13  	preempt_enable();
   19.14  	pgd += pgd_index(address);
   19.15 -
   19.16  	pgd_ref = pgd_offset_k(address);
   19.17  	if (pgd_none(*pgd_ref))
   19.18  		return -1;
    20.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Tue Jan 10 15:21:00 2006 +0000
    20.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c	Tue Jan 24 17:54:34 2006 +0100
    20.3 @@ -40,16 +40,16 @@
    20.4  #include <asm/proto.h>
    20.5  #include <asm/smp.h>
    20.6  
    20.7 +#ifndef Dprintk
    20.8 +#define Dprintk(x...)
    20.9 +#endif
   20.10 +
   20.11  extern unsigned long *contiguous_bitmap;
   20.12  
   20.13  #if defined(CONFIG_SWIOTLB)
   20.14  extern void swiotlb_init(void);
   20.15  #endif
   20.16  
   20.17 -#ifndef Dprintk
   20.18 -#define Dprintk(x...)
   20.19 -#endif
   20.20 -
   20.21  extern char _stext[];
   20.22  
   20.23  DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
   20.24 @@ -200,9 +200,9 @@ static void *spp_getpage(void)
   20.25  
   20.26  static inline pud_t *pud_offset_u(unsigned long address)
   20.27  {
   20.28 -        pud_t *pud = level3_user_pgt;
   20.29 +	pud_t *pud = level3_user_pgt;
   20.30  
   20.31 -        return pud + pud_index(address);
   20.32 +	return pud + pud_index(address);
   20.33  }
   20.34  
   20.35  static void set_pte_phys(unsigned long vaddr,
   20.36 @@ -215,34 +215,27 @@ static void set_pte_phys(unsigned long v
   20.37  
   20.38  	Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
   20.39  
   20.40 -        pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
   20.41 -
   20.42 +	pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
   20.43  	if (pgd_none(*pgd)) {
   20.44  		printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
   20.45  		return;
   20.46  	}
   20.47 -        
   20.48 -        pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
   20.49 -
   20.50 +	pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
   20.51  	if (pud_none(*pud)) {
   20.52  		pmd = (pmd_t *) spp_getpage(); 
   20.53 -
   20.54 -                make_page_readonly(pmd);
   20.55 -                xen_pmd_pin(__pa(pmd));
   20.56 +		make_page_readonly(pmd);
   20.57 +		xen_pmd_pin(__pa(pmd));
   20.58  		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
   20.59  		if (pmd != pmd_offset(pud, 0)) {
   20.60  			printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
   20.61  			return;
   20.62  		}
   20.63  	}
   20.64 -
   20.65  	pmd = pmd_offset(pud, vaddr);
   20.66 -
   20.67  	if (pmd_none(*pmd)) {
   20.68  		pte = (pte_t *) spp_getpage();
   20.69 -                make_page_readonly(pte);
   20.70 -
   20.71 -                xen_pte_pin(__pa(pte));
   20.72 +		make_page_readonly(pte);
   20.73 +		xen_pte_pin(__pa(pte));
   20.74  		set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
   20.75  		if (pte != pte_offset_kernel(pmd, 0)) {
   20.76  			printk("PAGETABLE BUG #02!\n");
   20.77 @@ -252,11 +245,10 @@ static void set_pte_phys(unsigned long v
   20.78  	new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
   20.79  
   20.80  	pte = pte_offset_kernel(pmd, vaddr);
   20.81 -
   20.82  	if (!pte_none(*pte) &&
   20.83  	    pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
   20.84  		pte_ERROR(*pte);
   20.85 -        set_pte(pte, new_pte);
   20.86 +	set_pte(pte, new_pte);
   20.87  
   20.88  	/*
   20.89  	 * It's enough to flush this one mapping.
   20.90 @@ -284,11 +276,11 @@ static void set_pte_phys_ma(unsigned lon
   20.91  	if (pud_none(*pud)) {
   20.92  
   20.93  		pmd = (pmd_t *) spp_getpage(); 
   20.94 -                make_page_readonly(pmd);
   20.95 -                xen_pmd_pin(__pa(pmd));
   20.96 +		make_page_readonly(pmd);
   20.97 +		xen_pmd_pin(__pa(pmd));
   20.98  
   20.99  		set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
  20.100 -         
  20.101 +
  20.102  		if (pmd != pmd_offset(pud, 0)) {
  20.103  			printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
  20.104  			return;
  20.105 @@ -298,8 +290,8 @@ static void set_pte_phys_ma(unsigned lon
  20.106  
  20.107  	if (pmd_none(*pmd)) {
  20.108  		pte = (pte_t *) spp_getpage();
  20.109 -                make_page_readonly(pte);  
  20.110 -                xen_pte_pin(__pa(pte));
  20.111 +		make_page_readonly(pte);  
  20.112 +		xen_pte_pin(__pa(pte));
  20.113  
  20.114  		set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
  20.115  		if (pte != pte_offset_kernel(pmd, 0)) {
  20.116 @@ -311,12 +303,12 @@ static void set_pte_phys_ma(unsigned lon
  20.117  	new_pte = pfn_pte_ma(phys >> PAGE_SHIFT, prot);
  20.118  	pte = pte_offset_kernel(pmd, vaddr);
  20.119  
  20.120 -        /* 
  20.121 -         * Note that the pte page is already RO, thus we want to use
  20.122 -         * xen_l1_entry_update(), not set_pte().
  20.123 -         */
  20.124 -        xen_l1_entry_update(pte, 
  20.125 -                            pfn_pte_ma(phys >> PAGE_SHIFT, prot));
  20.126 +	/* 
  20.127 +	 * Note that the pte page is already RO, thus we want to use
  20.128 +	 * xen_l1_entry_update(), not set_pte().
  20.129 +	 */
  20.130 +	xen_l1_entry_update(pte, 
  20.131 +			    pfn_pte_ma(phys >> PAGE_SHIFT, prot));
  20.132  
  20.133  	/*
  20.134  	 * It's enough to flush this one mapping.
  20.135 @@ -347,7 +339,6 @@ void __set_fixmap (enum fixed_addresses 
  20.136  	}
  20.137  }
  20.138  
  20.139 -
  20.140  /*
  20.141   * At this point it only supports vsyscall area.
  20.142   */
  20.143 @@ -360,18 +351,18 @@ void __set_fixmap_user (enum fixed_addre
  20.144  		return;
  20.145  	}
  20.146  
  20.147 -        set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
  20.148 +	set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
  20.149  }
  20.150  
  20.151  unsigned long __initdata table_start, tables_space; 
  20.152  
  20.153  unsigned long get_machine_pfn(unsigned long addr)
  20.154  {
  20.155 -        pud_t* pud = pud_offset_k(addr);
  20.156 -        pmd_t* pmd = pmd_offset(pud, addr);
  20.157 -        pte_t *pte = pte_offset_kernel(pmd, addr);
  20.158 -        
  20.159 -        return pte_mfn(*pte);
  20.160 +	pud_t* pud = pud_offset_k(addr);
  20.161 +	pmd_t* pmd = pmd_offset(pud, addr);
  20.162 +	pte_t *pte = pte_offset_kernel(pmd, addr);
  20.163 +
  20.164 +	return pte_mfn(*pte);
  20.165  } 
  20.166  
  20.167  static __init void *alloc_static_page(unsigned long *phys)
  20.168 @@ -411,12 +402,11 @@ static inline int make_readonly(unsigned
  20.169  
  20.170  static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
  20.171  { 
  20.172 -        long i, j, k; 
  20.173 -        unsigned long paddr;
  20.174 +	long i, j, k; 
  20.175 +	unsigned long paddr;
  20.176  
  20.177  	i = pud_index(address);
  20.178  	pud = pud + i;
  20.179 -
  20.180  	for (; i < PTRS_PER_PUD; pud++, i++) {
  20.181  		unsigned long pmd_phys;
  20.182  		pmd_t *pmd;
  20.183 @@ -429,38 +419,37 @@ static void __init phys_pud_init(pud_t *
  20.184  		} 
  20.185  
  20.186  		pmd = alloc_static_page(&pmd_phys);
  20.187 -                early_make_page_readonly(pmd);
  20.188 -                xen_pmd_pin(pmd_phys);
  20.189 +		early_make_page_readonly(pmd);
  20.190 +		xen_pmd_pin(pmd_phys);
  20.191  		set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
  20.192 -
  20.193        		for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
  20.194 -                        unsigned long pte_phys;
  20.195 -                        pte_t *pte, *pte_save;
  20.196 +			unsigned long pte_phys;
  20.197 +			pte_t *pte, *pte_save;
  20.198  
  20.199  			if (paddr >= end) { 
  20.200  				for (; j < PTRS_PER_PMD; j++, pmd++)
  20.201  					set_pmd(pmd,  __pmd(0)); 
  20.202  				break;
  20.203  			}
  20.204 -                        pte = alloc_static_page(&pte_phys);
  20.205 -                        pte_save = pte;
  20.206 -                        for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) {
  20.207 -                                if ((paddr >= end) ||
  20.208 -                                    ((paddr >> PAGE_SHIFT) >=
  20.209 -                                     xen_start_info->nr_pages)) { 
  20.210 -                                        __set_pte(pte, __pte(0)); 
  20.211 -                                        continue;
  20.212 -                                }
  20.213 -                                if (make_readonly(paddr)) {
  20.214 -                                        __set_pte(pte, 
  20.215 -                                                __pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW)));
  20.216 -                                        continue;
  20.217 -                                }
  20.218 -                                __set_pte(pte, __pte(paddr | _KERNPG_TABLE));
  20.219 -                        }
  20.220 -                        pte = pte_save;
  20.221 -                        early_make_page_readonly(pte);  
  20.222 -                        xen_pte_pin(pte_phys);
  20.223 +			pte = alloc_static_page(&pte_phys);
  20.224 +			pte_save = pte;
  20.225 +			for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) {
  20.226 +				if ((paddr >= end) ||
  20.227 +				    ((paddr >> PAGE_SHIFT) >=
  20.228 +				     xen_start_info->nr_pages)) { 
  20.229 +					__set_pte(pte, __pte(0)); 
  20.230 +					continue;
  20.231 +				}
  20.232 +				if (make_readonly(paddr)) {
  20.233 +					__set_pte(pte, 
  20.234 +						__pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW)));
  20.235 +					continue;
  20.236 +				}
  20.237 +				__set_pte(pte, __pte(paddr | _KERNPG_TABLE));
  20.238 +			}
  20.239 +			pte = pte_save;
  20.240 +			early_make_page_readonly(pte);  
  20.241 +			xen_pte_pin(pte_phys);
  20.242  			set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
  20.243  		}
  20.244  	}
  20.245 @@ -506,7 +495,7 @@ void __init xen_init_pt(void)
  20.246  	level3_kernel_pgt[pud_index(__START_KERNEL_map)] = 
  20.247  		__pud(__pa_symbol(level2_kernel_pgt) |
  20.248  		      _KERNPG_TABLE | _PAGE_USER);
  20.249 -        memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
  20.250 +	memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
  20.251  
  20.252  	early_make_page_readonly(init_level4_pgt);
  20.253  	early_make_page_readonly(init_level4_user_pgt);
  20.254 @@ -618,7 +607,7 @@ extern struct x8664_pda cpu_pda[NR_CPUS]
  20.255  
  20.256  void zap_low_mappings(void)
  20.257  {
  20.258 -        /* this is not required for Xen */
  20.259 +	/* this is not required for Xen */
  20.260  #if 0
  20.261  	swap_low_mappings();
  20.262  #endif
  20.263 @@ -629,11 +618,11 @@ void __init paging_init(void)
  20.264  {
  20.265  	{
  20.266  		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
  20.267 -                /*	unsigned int max_dma; */
  20.268 -                /* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; */
  20.269 -                /* if (end_pfn < max_dma) */
  20.270 +		/*	unsigned int max_dma; */
  20.271 +		/* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; */
  20.272 +		/* if (end_pfn < max_dma) */
  20.273  			zones_size[ZONE_DMA] = end_pfn;
  20.274 -#if 0                
  20.275 +#if 0
  20.276  		else {
  20.277  			zones_size[ZONE_DMA] = max_dma;
  20.278  			zones_size[ZONE_NORMAL] = end_pfn - max_dma;
  20.279 @@ -642,16 +631,16 @@ void __init paging_init(void)
  20.280  		free_area_init(zones_size);
  20.281  	}
  20.282  
  20.283 -        set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
  20.284 -        HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
  20.285 +	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
  20.286 +	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
  20.287  
  20.288 -        memset(empty_zero_page, 0, sizeof(empty_zero_page));
  20.289 +	memset(empty_zero_page, 0, sizeof(empty_zero_page));
  20.290  	init_mm.context.pinned = 1;
  20.291  
  20.292  #ifdef CONFIG_XEN_PHYSDEV_ACCESS
  20.293  	{
  20.294  		int i;
  20.295 -        /* Setup mapping of lower 1st MB */
  20.296 +		/* Setup mapping of lower 1st MB */
  20.297  		for (i = 0; i < NR_FIX_ISAMAPS; i++)
  20.298  			if (xen_start_info->flags & SIF_PRIVILEGED)
  20.299  				set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
  20.300 @@ -701,7 +690,7 @@ void __init clear_kernel_mapping(unsigne
  20.301  
  20.302  static inline int page_is_ram (unsigned long pagenr)
  20.303  {
  20.304 -        return 1;
  20.305 +	return 1;
  20.306  }
  20.307  
  20.308  static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
  20.309 @@ -790,10 +779,10 @@ extern char __initdata_begin[], __initda
  20.310  void free_initmem(void)
  20.311  {
  20.312  #ifdef __DO_LATER__
  20.313 -        /*
  20.314 -         * Some pages can be pinned, but some are not. Unpinning such pages 
  20.315 -         * triggers BUG(). 
  20.316 -         */
  20.317 +	/*
  20.318 +	 * Some pages can be pinned, but some are not. Unpinning such pages 
  20.319 +	 * triggers BUG(). 
  20.320 +	 */
  20.321  	unsigned long addr;
  20.322  
  20.323  	addr = (unsigned long)(&__init_begin);
  20.324 @@ -801,12 +790,12 @@ void free_initmem(void)
  20.325  		ClearPageReserved(virt_to_page(addr));
  20.326  		set_page_count(virt_to_page(addr), 1);
  20.327  		memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); 
  20.328 -                xen_pte_unpin(__pa(addr));
  20.329 -                make_page_writable(__va(__pa(addr)));
  20.330 -                /*
  20.331 -                 * Make pages from __PAGE_OFFSET address as well
  20.332 -                 */
  20.333 -                make_page_writable((void *)addr);
  20.334 +		xen_pte_unpin(__pa(addr));
  20.335 +		make_page_writable(__va(__pa(addr)));
  20.336 +		/*
  20.337 +		 * Make pages from __PAGE_OFFSET address as well
  20.338 +		 */
  20.339 +		make_page_writable((void *)addr);
  20.340  		free_page(addr);
  20.341  		totalram_pages++;
  20.342  	}
  20.343 @@ -856,7 +845,7 @@ int kern_addr_valid(unsigned long addr)
  20.344  	if (pgd_none(*pgd))
  20.345  		return 0;
  20.346  
  20.347 -        pud = pud_offset_k(addr);
  20.348 +	pud = pud_offset_k(addr);
  20.349  	if (pud_none(*pud))
  20.350  		return 0; 
  20.351  
    21.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Tue Jan 10 15:21:00 2006 +0000
    21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Tue Jan 24 17:54:34 2006 +0100
    21.3 @@ -544,7 +544,7 @@ static int __init blkif_init(void)
    21.4  		kfree(pending_grant_handles);
    21.5  		kfree(pending_vaddrs);
    21.6  		printk("%s: out of memory\n", __FUNCTION__);
    21.7 -		return -1;
    21.8 +		return -ENOMEM;
    21.9  	}
   21.10  
   21.11  	blkif_interface_init();
    22.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Jan 10 15:21:00 2006 +0000
    22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Jan 24 17:54:34 2006 +0100
    22.3 @@ -19,16 +19,8 @@
    22.4  #include <asm-xen/gnttab.h>
    22.5  #include <asm-xen/driver_util.h>
    22.6  
    22.7 -#if 0
    22.8 -#define ASSERT(_p) \
    22.9 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   22.10 -    __LINE__, __FILE__); *(int*)0=0; }
   22.11 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
   22.12 -                           __FILE__ , __LINE__ , ## _a )
   22.13 -#else
   22.14 -#define ASSERT(_p) ((void)0)
   22.15 -#define DPRINTK(_f, _a...) ((void)0)
   22.16 -#endif
   22.17 +#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
   22.18 +                                    __FILE__ , __LINE__ , ## _a )
   22.19  
   22.20  struct vbd {
   22.21  	blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Tue Jan 10 15:21:00 2006 +0000
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c	Tue Jan 24 17:54:34 2006 +0100
    23.3 @@ -11,7 +11,6 @@
    23.4  
    23.5  #define vbd_sz(_v)   ((_v)->bdev->bd_part ?				\
    23.6  	(_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
    23.7 -#define bdev_put(_b) blkdev_put(_b)
    23.8  
    23.9  unsigned long vbd_size(struct vbd *vbd)
   23.10  {
   23.11 @@ -69,7 +68,7 @@ int vbd_create(blkif_t *blkif, blkif_vde
   23.12  void vbd_free(struct vbd *vbd)
   23.13  {
   23.14  	if (vbd->bdev)
   23.15 -		bdev_put(vbd->bdev);
   23.16 +		blkdev_put(vbd->bdev);
   23.17  	vbd->bdev = NULL;
   23.18  }
   23.19  
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Jan 10 15:21:00 2006 +0000
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Jan 24 17:54:34 2006 +0100
    24.3 @@ -24,12 +24,9 @@
    24.4  #include <asm-xen/xenbus.h>
    24.5  #include "common.h"
    24.6  
    24.7 -
    24.8 -#if 0
    24.9  #undef DPRINTK
   24.10  #define DPRINTK(fmt, args...) \
   24.11 -    printk("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   24.12 -#endif
   24.13 +    pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   24.14  
   24.15  
   24.16  struct backend_info
   24.17 @@ -302,7 +299,7 @@ static void maybe_connect(struct backend
   24.18   */
   24.19  static void connect(struct backend_info *be)
   24.20  {
   24.21 -	struct xenbus_transaction *xbt;
   24.22 +	xenbus_transaction_t xbt;
   24.23  	int err;
   24.24  	struct xenbus_device *dev = be->dev;
   24.25  
   24.26 @@ -310,10 +307,9 @@ static void connect(struct backend_info 
   24.27  
   24.28  	/* Supply the information about the device the frontend needs */
   24.29  again:
   24.30 -	xbt = xenbus_transaction_start();
   24.31 +	err = xenbus_transaction_start(&xbt);
   24.32  
   24.33 -	if (IS_ERR(xbt)) {
   24.34 -		err = PTR_ERR(xbt);
   24.35 +	if (err) {
   24.36  		xenbus_dev_fatal(dev, err, "starting transaction");
   24.37  		return;
   24.38  	}
    25.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/Kconfig	Tue Jan 10 15:21:00 2006 +0000
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,6 +0,0 @@
    25.4 -
    25.5 -config XENBLOCK
    25.6 -	tristate "Block device driver"
    25.7 -	depends on ARCH_XEN
    25.8 -	help
    25.9 -	  Block device driver for Xen
    26.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jan 10 15:21:00 2006 +0000
    26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jan 24 17:54:34 2006 +0100
    26.3 @@ -35,14 +35,6 @@
    26.4   * IN THE SOFTWARE.
    26.5   */
    26.6  
    26.7 -#if 1
    26.8 -#define ASSERT(p)							   \
    26.9 -	if (!(p)) { printk("Assertion '%s' failed, line %d, file %s", #p , \
   26.10 -	__LINE__, __FILE__); *(int*)0=0; }
   26.11 -#else
   26.12 -#define ASSERT(_p)
   26.13 -#endif
   26.14 -
   26.15  #include <linux/version.h>
   26.16  #include "block.h"
   26.17  #include <linux/cdrom.h>
   26.18 @@ -161,7 +153,7 @@ static int talk_to_backend(struct xenbus
   26.19  			   struct blkfront_info *info)
   26.20  {
   26.21  	const char *message = NULL;
   26.22 -	struct xenbus_transaction *xbt;
   26.23 +	xenbus_transaction_t xbt;
   26.24  	int err;
   26.25  
   26.26  	/* Create shared ring, alloc event channel. */
   26.27 @@ -170,8 +162,8 @@ static int talk_to_backend(struct xenbus
   26.28  		goto out;
   26.29  
   26.30  again:
   26.31 -	xbt = xenbus_transaction_start();
   26.32 -	if (IS_ERR(xbt)) {
   26.33 +	err = xenbus_transaction_start(&xbt);
   26.34 +	if (err) {
   26.35  		xenbus_dev_fatal(dev, err, "starting transaction");
   26.36  		goto destroy_blkring;
   26.37  	}
   26.38 @@ -551,7 +543,7 @@ static int blkif_queue_request(struct re
   26.39  			lsect = fsect + (bvec->bv_len >> 9) - 1;
   26.40  			/* install a grant reference. */
   26.41  			ref = gnttab_claim_grant_reference(&gref_head);
   26.42 -			ASSERT(ref != -ENOSPC);
   26.43 +			BUG_ON(ref == -ENOSPC);
   26.44  
   26.45  			gnttab_grant_foreign_access_ref(
   26.46  				ref,
    27.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Tue Jan 10 15:21:00 2006 +0000
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Tue Jan 24 17:54:34 2006 +0100
    27.3 @@ -69,11 +69,7 @@
    27.4  #define WPRINTK(fmt, args...) ((void)0)
    27.5  #endif
    27.6   
    27.7 -#if 0
    27.8 -#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
    27.9 -#else
   27.10 -#define DPRINTK(_f, _a...) ((void)0)
   27.11 -#endif
   27.12 +#define DPRINTK(_f, _a...) pr_debug ( _f , ## _a )
   27.13  
   27.14  #if 0
   27.15  #define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
    28.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Tue Jan 10 15:21:00 2006 +0000
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Tue Jan 24 17:54:34 2006 +0100
    28.3 @@ -19,16 +19,8 @@
    28.4  #include <asm-xen/gnttab.h>
    28.5  #include <asm-xen/driver_util.h>
    28.6  
    28.7 -#if 0
    28.8 -#define ASSERT(_p) \
    28.9 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   28.10 -    __LINE__, __FILE__); *(int*)0=0; }
   28.11 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
   28.12 -                           __FILE__ , __LINE__ , ## _a )
   28.13 -#else
   28.14 -#define ASSERT(_p) ((void)0)
   28.15 -#define DPRINTK(_f, _a...) ((void)0)
   28.16 -#endif
   28.17 +#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
   28.18 +                                    __FILE__ , __LINE__ , ## _a )
   28.19  
   28.20  #define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
   28.21  
    29.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Tue Jan 10 15:21:00 2006 +0000
    29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Tue Jan 24 17:54:34 2006 +0100
    29.3 @@ -22,16 +22,8 @@
    29.4  #include <asm-xen/gnttab.h>
    29.5  #include <asm-xen/driver_util.h>
    29.6  
    29.7 -#if 0
    29.8 -#define ASSERT(_p) \
    29.9 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   29.10 -    __LINE__, __FILE__); *(int*)0=0; }
   29.11 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
   29.12 -                           __FILE__ , __LINE__ , ## _a )
   29.13 -#else
   29.14 -#define ASSERT(_p) ((void)0)
   29.15 -#define DPRINTK(_f, _a...) ((void)0)
   29.16 -#endif
   29.17 +#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
   29.18 +                                    __FILE__ , __LINE__ , ## _a )
   29.19  #define IPRINTK(fmt, args...) \
   29.20      printk(KERN_INFO "xen_net: " fmt, ##args)
   29.21  #define WPRINTK(fmt, args...) \
    30.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Tue Jan 10 15:21:00 2006 +0000
    30.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Tue Jan 24 17:54:34 2006 +0100
    30.3 @@ -27,6 +27,7 @@
    30.4  #include <linux/inetdevice.h>
    30.5  #include <linux/etherdevice.h>
    30.6  #include <linux/skbuff.h>
    30.7 +#include <linux/ethtool.h>
    30.8  #include <net/dst.h>
    30.9  
   30.10  static int nloopbacks = 8;
   30.11 @@ -122,6 +123,12 @@ static void loopback_construct(struct ne
   30.12  	/*dev->mtu             = 16*1024;*/
   30.13  }
   30.14  
   30.15 +static struct ethtool_ops network_ethtool_ops =
   30.16 +{
   30.17 +	.get_tx_csum = ethtool_op_get_tx_csum,
   30.18 +	.set_tx_csum = ethtool_op_set_tx_csum,
   30.19 +};
   30.20 +
   30.21  static int __init make_loopback(int i)
   30.22  {
   30.23  	struct net_device *dev1, *dev2;
   30.24 @@ -141,6 +148,8 @@ static int __init make_loopback(int i)
   30.25  	dev1->features |= NETIF_F_NO_CSUM;
   30.26  	dev2->features |= NETIF_F_IP_CSUM;
   30.27  
   30.28 +	SET_ETHTOOL_OPS(dev2, &network_ethtool_ops);
   30.29 +
   30.30  	/*
   30.31  	 * Initialise a dummy MAC address for the 'dummy backend' interface. We
   30.32  	 * choose the numerically largest non-broadcast address to prevent the
    31.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Jan 10 15:21:00 2006 +0000
    31.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Jan 24 17:54:34 2006 +0100
    31.3 @@ -120,7 +120,7 @@ int netif_be_start_xmit(struct sk_buff *
    31.4  {
    31.5  	netif_t *netif = netdev_priv(dev);
    31.6  
    31.7 -	ASSERT(skb->dev == dev);
    31.8 +	BUG_ON(skb->dev != dev);
    31.9  
   31.10  	/* Drop the packet if the target domain has no receive buffers. */
   31.11  	if (!netif->active || 
    32.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/Kconfig	Tue Jan 10 15:21:00 2006 +0000
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,6 +0,0 @@
    32.4 -
    32.5 -config XENNET
    32.6 -	tristate "Xen network driver"
    32.7 -	depends on NETDEVICES && ARCH_XEN
    32.8 -	help
    32.9 -	  Network driver for Xen
    33.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jan 10 15:21:00 2006 +0000
    33.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jan 24 17:54:34 2006 +0100
    33.3 @@ -154,13 +154,8 @@ static char *be_state_name[] = {
    33.4  };
    33.5  #endif
    33.6  
    33.7 -#ifdef DEBUG
    33.8 -#define DPRINTK(fmt, args...)						\
    33.9 -	printk(KERN_ALERT "netfront (%s:%d) " fmt, __FUNCTION__,	\
   33.10 -	       __LINE__, ##args)
   33.11 -#else
   33.12 -#define DPRINTK(fmt, args...) ((void)0)
   33.13 -#endif
   33.14 +#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \
   33.15 +                                       __FUNCTION__, __LINE__, ##args)
   33.16  #define IPRINTK(fmt, args...)				\
   33.17  	printk(KERN_INFO "netfront: " fmt, ##args)
   33.18  #define WPRINTK(fmt, args...)				\
   33.19 @@ -260,7 +255,7 @@ static int talk_to_backend(struct xenbus
   33.20  			   struct netfront_info *info)
   33.21  {
   33.22  	const char *message;
   33.23 -	struct xenbus_transaction *xbt;
   33.24 +	xenbus_transaction_t xbt;
   33.25  	int err;
   33.26  
   33.27  	err = xen_net_read_mac(dev, info->mac);
   33.28 @@ -275,8 +270,8 @@ static int talk_to_backend(struct xenbus
   33.29  		goto out;
   33.30  
   33.31  again:
   33.32 -	xbt = xenbus_transaction_start();
   33.33 -	if (IS_ERR(xbt)) {
   33.34 +	err = xenbus_transaction_start(&xbt);
   33.35 +	if (err) {
   33.36  		xenbus_dev_fatal(dev, err, "starting transaction");
   33.37  		goto destroy_ring;
   33.38  	}
    34.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Tue Jan 10 15:21:00 2006 +0000
    34.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Tue Jan 24 17:54:34 2006 +0100
    34.3 @@ -17,16 +17,8 @@
    34.4  #include <asm/io.h>
    34.5  #include <asm/pgalloc.h>
    34.6  
    34.7 -#if 0
    34.8 -#define ASSERT(_p) \
    34.9 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   34.10 -    __LINE__, __FILE__); *(int*)0=0; }
   34.11 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
   34.12 -                           __FILE__ , __LINE__ , ## _a )
   34.13 -#else
   34.14 -#define ASSERT(_p) ((void)0)
   34.15 -#define DPRINTK(_f, _a...) ((void)0)
   34.16 -#endif
   34.17 +#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
   34.18 +                                    __FILE__ , __LINE__ , ## _a )
   34.19  
   34.20  typedef struct tpmif_st {
   34.21  	struct list_head tpmif_list;
   34.22 @@ -84,11 +76,6 @@ extern int num_frontends;
   34.23  
   34.24  #define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
   34.25  
   34.26 -#ifndef TRUE
   34.27 -#define TRUE 1
   34.28 -#define FALSE 0
   34.29 -#endif
   34.30 -
   34.31  #endif /* __TPMIF__BACKEND__COMMON_H__ */
   34.32  
   34.33  /*
    35.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Tue Jan 10 15:21:00 2006 +0000
    35.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Tue Jan 24 17:54:34 2006 +0100
    35.3 @@ -78,7 +78,7 @@ static int tpmback_probe(struct xenbus_d
    35.4  
    35.5  	memset(be, 0, sizeof(*be));
    35.6  
    35.7 -	be->is_instance_set = FALSE;
    35.8 +	be->is_instance_set = 0;
    35.9  	be->dev = dev;
   35.10  	dev->data = be;
   35.11  
   35.12 @@ -89,7 +89,7 @@ static int tpmback_probe(struct xenbus_d
   35.13  		goto fail;
   35.14  	}
   35.15  
   35.16 -	err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
   35.17 +	err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
   35.18  	if (err) {
   35.19  		goto fail;
   35.20  	}
   35.21 @@ -109,7 +109,7 @@ static void backend_changed(struct xenbu
   35.22  		= container_of(watch, struct backend_info, backend_watch);
   35.23  	struct xenbus_device *dev = be->dev;
   35.24  
   35.25 -	err = xenbus_scanf(NULL, dev->nodename,
   35.26 +	err = xenbus_scanf(XBT_NULL, dev->nodename,
   35.27  	                   "instance","%li", &instance);
   35.28  	if (XENBUS_EXIST_ERR(err)) {
   35.29  		return;
   35.30 @@ -120,7 +120,7 @@ static void backend_changed(struct xenbu
   35.31  		return;
   35.32  	}
   35.33  
   35.34 -	if (be->is_instance_set != FALSE && be->instance != instance) {
   35.35 +	if (be->is_instance_set != 0 && be->instance != instance) {
   35.36  		printk(KERN_WARNING
   35.37  		       "tpmback: changing instance (from %ld to %ld) "
   35.38  		       "not allowed.\n",
   35.39 @@ -128,7 +128,7 @@ static void backend_changed(struct xenbu
   35.40  		return;
   35.41  	}
   35.42  
   35.43 -	if (be->is_instance_set == FALSE) {
   35.44 +	if (be->is_instance_set == 0) {
   35.45  		be->tpmif = tpmif_find(dev->otherend_id,
   35.46  		                       instance);
   35.47  		if (IS_ERR(be->tpmif)) {
   35.48 @@ -138,7 +138,7 @@ static void backend_changed(struct xenbu
   35.49  			return;
   35.50  		}
   35.51  		be->instance = instance;
   35.52 -		be->is_instance_set = TRUE;
   35.53 +		be->is_instance_set = 1;
   35.54  
   35.55  		/*
   35.56  		 * There's an unfortunate problem:
   35.57 @@ -177,7 +177,7 @@ static void frontend_changed(struct xenb
   35.58  		break;
   35.59  
   35.60  	case XenbusStateClosing:
   35.61 -		xenbus_switch_state(dev, NULL, XenbusStateClosing);
   35.62 +		xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
   35.63  		break;
   35.64  
   35.65  	case XenbusStateClosed:
   35.66 @@ -230,15 +230,14 @@ static void maybe_connect(struct backend
   35.67  
   35.68  static void connect(struct backend_info *be)
   35.69  {
   35.70 -	struct xenbus_transaction *xbt;
   35.71 +	xenbus_transaction_t xbt;
   35.72  	int err;
   35.73  	struct xenbus_device *dev = be->dev;
   35.74  	unsigned long ready = 1;
   35.75  
   35.76  again:
   35.77 -	xbt = xenbus_transaction_start();
   35.78 -	if (IS_ERR(xbt)) {
   35.79 -		err = PTR_ERR(xbt);
   35.80 +	err = xenbus_transaction_start(&xbt);
   35.81 +	if (err) {
   35.82  		xenbus_dev_fatal(be->dev, err, "starting transaction");
   35.83  		return;
   35.84  	}
    36.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Tue Jan 10 15:21:00 2006 +0000
    36.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Tue Jan 24 17:54:34 2006 +0100
    36.3 @@ -54,14 +54,6 @@
    36.4  
    36.5  #undef DEBUG
    36.6  
    36.7 -#if 1
    36.8 -#define ASSERT(_p) \
    36.9 -    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
   36.10 -        __LINE__, __FILE__); *(int*)0=0; }
   36.11 -#else
   36.12 -#define ASSERT(_p)
   36.13 -#endif
   36.14 -
   36.15  /* locally visible variables */
   36.16  static grant_ref_t gref_head;
   36.17  static struct tpm_private my_private;
   36.18 @@ -80,12 +72,8 @@ static int tpm_xmit(struct tpm_private *
   36.19                      const u8 * buf, size_t count, int userbuffer,
   36.20                      void *remember);
   36.21  
   36.22 -#if DEBUG
   36.23  #define DPRINTK(fmt, args...) \
   36.24 -    printk(KERN_ALERT "xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   36.25 -#else
   36.26 -#define DPRINTK(fmt, args...) ((void)0)
   36.27 -#endif
   36.28 +    pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   36.29  #define IPRINTK(fmt, args...) \
   36.30      printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
   36.31  #define WPRINTK(fmt, args...) \
   36.32 @@ -102,11 +90,8 @@ tx_buffer_copy(struct tx_buffer *txb, co
   36.33  		copied = txb->size;
   36.34  	}
   36.35  	if (isuserbuffer) {
   36.36 -		if (copy_from_user(txb->data,
   36.37 -		                   src,
   36.38 -		                   copied)) {
   36.39 +		if (copy_from_user(txb->data, src, copied))
   36.40  			return -EFAULT;
   36.41 -		}
   36.42  	} else {
   36.43  		memcpy(txb->data, src, copied);
   36.44  	}
   36.45 @@ -196,15 +181,12 @@ EXPORT_SYMBOL(tpm_fe_unregister_receiver
   36.46  static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
   36.47                                    const void *ptr)
   36.48  {
   36.49 -	int rc;
   36.50 +	int rc = 0;
   36.51  
   36.52  	down(&upperlayer_lock);
   36.53  
   36.54 -	if (upperlayer_tpmfe && upperlayer_tpmfe->receive) {
   36.55 +	if (upperlayer_tpmfe && upperlayer_tpmfe->receive)
   36.56  		rc = upperlayer_tpmfe->receive(buf, count, ptr);
   36.57 -	} else {
   36.58 -		rc = 0;
   36.59 -	}
   36.60  
   36.61  	up(&upperlayer_lock);
   36.62  	return rc;
   36.63 @@ -253,8 +235,8 @@ fail:
   36.64  
   36.65  static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
   36.66  {
   36.67 -	tpmif_set_connected_state(tp, FALSE);
   36.68 -	if ( tp->tx != NULL ) {
   36.69 +	tpmif_set_connected_state(tp, 0);
   36.70 +	if (tp->tx != NULL) {
   36.71  		gnttab_end_foreign_access(info->ring_ref, 0,
   36.72  					  (unsigned long)tp->tx);
   36.73  		tp->tx = NULL;
   36.74 @@ -271,7 +253,7 @@ static int talk_to_backend(struct xenbus
   36.75  {
   36.76  	const char *message = NULL;
   36.77  	int err;
   36.78 -	struct xenbus_transaction *xbt;
   36.79 +	xenbus_transaction_t xbt;
   36.80  
   36.81  	err = setup_tpmring(dev, info);
   36.82  	if (err) {
   36.83 @@ -280,8 +262,8 @@ static int talk_to_backend(struct xenbus
   36.84  	}
   36.85  
   36.86  again:
   36.87 -	xbt = xenbus_transaction_start();
   36.88 -	if (IS_ERR(xbt)) {
   36.89 +	err = xenbus_transaction_start(&xbt);
   36.90 +	if (err) {
   36.91  		xenbus_dev_fatal(dev, err, "starting transaction");
   36.92  		goto destroy_tpmring;
   36.93  	}
   36.94 @@ -341,15 +323,15 @@ static void backend_changed(struct xenbu
   36.95  		break;
   36.96  
   36.97  	case XenbusStateConnected:
   36.98 -		tpmif_set_connected_state(tp, TRUE);
   36.99 +		tpmif_set_connected_state(tp, 1);
  36.100  		break;
  36.101  
  36.102  	case XenbusStateClosing:
  36.103 -		tpmif_set_connected_state(tp, FALSE);
  36.104 +		tpmif_set_connected_state(tp, 0);
  36.105  		break;
  36.106  
  36.107  	case XenbusStateClosed:
  36.108 -        	if (tp->is_suspended == FALSE) {
  36.109 +        	if (tp->is_suspended == 0) {
  36.110          	        device_unregister(&dev->dev);
  36.111          	}
  36.112  	        break;
  36.113 @@ -364,7 +346,7 @@ static int tpmfront_probe(struct xenbus_
  36.114  	struct tpmfront_info *info;
  36.115  	int handle;
  36.116  
  36.117 -	err = xenbus_scanf(NULL, dev->nodename,
  36.118 +	err = xenbus_scanf(XBT_NULL, dev->nodename,
  36.119  	                   "handle", "%i", &handle);
  36.120  	if (XENBUS_EXIST_ERR(err))
  36.121  		return err;
  36.122 @@ -409,20 +391,19 @@ static int
  36.123  tpmfront_suspend(struct xenbus_device *dev)
  36.124  {
  36.125  	struct tpm_private *tp = &my_private;
  36.126 -	u32 ctr = 0;
  36.127 +	u32 ctr;
  36.128  
  36.129  	/* lock, so no app can send */
  36.130  	down(&suspend_lock);
  36.131 -	tp->is_suspended = TRUE;
  36.132 +	tp->is_suspended = 1;
  36.133  
  36.134 -	while (atomic_read(&tp->tx_busy) && ctr <= 25) {
  36.135 +	for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
  36.136  		if ((ctr % 10) == 0)
  36.137  			printk("TPM-FE [INFO]: Waiting for outstanding request.\n");
  36.138  		/*
  36.139  		 * Wait for a request to be responded to.
  36.140  		 */
  36.141  		interruptible_sleep_on_timeout(&tp->wait_q, 100);
  36.142 -		ctr++;
  36.143  	}
  36.144  
  36.145  	if (atomic_read(&tp->tx_busy)) {
  36.146 @@ -440,16 +421,13 @@ static int
  36.147  tpmfront_resume(struct xenbus_device *dev)
  36.148  {
  36.149  	struct tpmfront_info *info = dev->data;
  36.150 -	int err = talk_to_backend(dev, info);
  36.151 -
  36.152 -
  36.153 -	return err;
  36.154 +	return talk_to_backend(dev, info);
  36.155  }
  36.156  
  36.157  static void
  36.158  tpmif_connect(u16 evtchn, domid_t domid)
  36.159  {
  36.160 -	int err = 0;
  36.161 +	int err;
  36.162  	struct tpm_private *tp = &my_private;
  36.163  
  36.164  	tp->evtchn = evtchn;
  36.165 @@ -493,12 +471,8 @@ tpm_allocate_buffers(struct tpm_private 
  36.166  {
  36.167  	unsigned int i;
  36.168  
  36.169 -	i = 0;
  36.170 -	while (i < TPMIF_TX_RING_SIZE) {
  36.171 +	for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
  36.172  		tp->tx_buffers[i] = tx_buffer_alloc();
  36.173 -		i++;
  36.174 -	}
  36.175 -
  36.176  	return 1;
  36.177  }
  36.178  
  36.179 @@ -521,9 +495,7 @@ tpmif_rx_action(unsigned long unused)
  36.180  		goto exit;
  36.181  	}
  36.182  
  36.183 -	i = 0;
  36.184 -	while (i < TPMIF_TX_RING_SIZE &&
  36.185 -	       offset < received) {
  36.186 +	for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
  36.187  		struct tx_buffer *txb = tp->tx_buffers[i];
  36.188  		tpmif_tx_request_t *tx;
  36.189  		unsigned int tocopy;
  36.190 @@ -539,7 +511,6 @@ tpmif_rx_action(unsigned long unused)
  36.191  		gnttab_release_grant_reference(&gref_head, tx->ref);
  36.192  
  36.193  		offset += tocopy;
  36.194 -		i++;
  36.195  	}
  36.196  
  36.197  	tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
  36.198 @@ -583,19 +554,18 @@ tpm_xmit(struct tpm_private *tp,
  36.199  		return -EBUSY;
  36.200  	}
  36.201  
  36.202 -	if (tp->is_connected != TRUE) {
  36.203 +	if (tp->is_connected != 1) {
  36.204  		spin_unlock_irq(&tp->tx_lock);
  36.205  		return -EIO;
  36.206  	}
  36.207  
  36.208 -	i = 0;
  36.209 -	while (count > 0 && i < TPMIF_TX_RING_SIZE) {
  36.210 +	for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
  36.211  		struct tx_buffer *txb = tp->tx_buffers[i];
  36.212  		int copied;
  36.213  
  36.214  		if (NULL == txb) {
  36.215 -			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
  36.216 -			DPRINTK("Not transmitting anything!\n");
  36.217 +			DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
  36.218 +				"Not transmitting anything!\n", i);
  36.219  			spin_unlock_irq(&tp->tx_lock);
  36.220  			return -EFAULT;
  36.221  		}
  36.222 @@ -603,6 +573,7 @@ tpm_xmit(struct tpm_private *tp,
  36.223  		                        isuserbuffer);
  36.224  		if (copied < 0) {
  36.225  			/* An error occurred */
  36.226 +			spin_unlock_irq(&tp->tx_lock);
  36.227  			return copied;
  36.228  		}
  36.229  		count -= copied;
  36.230 @@ -618,9 +589,10 @@ tpm_xmit(struct tpm_private *tp,
  36.231  		        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
  36.232  
  36.233  		/* get the granttable reference for this page */
  36.234 -		tx->ref = gnttab_claim_grant_reference( &gref_head );
  36.235 +		tx->ref = gnttab_claim_grant_reference(&gref_head);
  36.236  
  36.237 -		if(-ENOSPC == tx->ref ) {
  36.238 +		if (-ENOSPC == tx->ref) {
  36.239 +			spin_unlock_irq(&tp->tx_lock);
  36.240  			DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
  36.241  			return -ENOSPC;
  36.242  		}
  36.243 @@ -628,7 +600,6 @@ tpm_xmit(struct tpm_private *tp,
  36.244  		                                 tp->backend_id,
  36.245  		                                 (tx->addr >> PAGE_SHIFT),
  36.246  		                                 0 /*RW*/);
  36.247 -		i++;
  36.248  		wmb();
  36.249  	}
  36.250  
  36.251 @@ -672,7 +643,7 @@ static void tpmif_set_connected_state(st
  36.252  	 * should disconnect - assumption is that we will resume
  36.253  	 * The semaphore keeps apps from sending.
  36.254  	 */
  36.255 -	if (is_connected == FALSE && tp->is_suspended == TRUE) {
  36.256 +	if (is_connected == 0 && tp->is_suspended == 1) {
  36.257  		return;
  36.258  	}
  36.259  
  36.260 @@ -681,8 +652,8 @@ static void tpmif_set_connected_state(st
  36.261  	 * after being suspended - now resuming.
  36.262  	 * This also removes the suspend state.
  36.263  	 */
  36.264 -	if (is_connected == TRUE && tp->is_suspended == TRUE) {
  36.265 -		tp->is_suspended = FALSE;
  36.266 +	if (is_connected == 1 && tp->is_suspended == 1) {
  36.267 +		tp->is_suspended = 0;
  36.268  		/* unlock, so apps can resume sending */
  36.269  		up(&suspend_lock);
  36.270  	}
    37.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Tue Jan 10 15:21:00 2006 +0000
    37.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Tue Jan 24 17:54:34 2006 +0100
    37.3 @@ -1,11 +1,6 @@
    37.4  #ifndef TPM_FRONT_H
    37.5  #define TPM_FRONT_H
    37.6  
    37.7 -#ifndef TRUE
    37.8 -#define TRUE 1
    37.9 -#define FALSE 0
   37.10 -#endif
   37.11 -
   37.12  struct tpm_private {
   37.13  	tpmif_tx_interface_t *tx;
   37.14  	unsigned int evtchn;
    38.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Tue Jan 10 15:21:00 2006 +0000
    38.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Tue Jan 24 17:54:34 2006 +0100
    38.3 @@ -34,13 +34,8 @@
    38.4  /* xenbus_probe.c */
    38.5  extern char *kasprintf(const char *fmt, ...);
    38.6  
    38.7 -#if 0
    38.8  #define DPRINTK(fmt, args...) \
    38.9 -    printk("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   38.10 -#else
   38.11 -#define DPRINTK(fmt, args...) ((void)0)
   38.12 -#endif
   38.13 -
   38.14 +    pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   38.15  
   38.16  int xenbus_watch_path(struct xenbus_device *dev, const char *path,
   38.17  		      struct xenbus_watch *watch, 
   38.18 @@ -87,7 +82,7 @@ EXPORT_SYMBOL(xenbus_watch_path2);
   38.19  
   38.20  
   38.21  int xenbus_switch_state(struct xenbus_device *dev,
   38.22 -			struct xenbus_transaction *xbt,
   38.23 +			xenbus_transaction_t xbt,
   38.24  			XenbusState state)
   38.25  {
   38.26  	/* We check whether the state is currently set to the given value, and
    39.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Tue Jan 10 15:21:00 2006 +0000
    39.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Tue Jan 24 17:54:34 2006 +0100
    39.3 @@ -47,7 +47,7 @@
    39.4  
    39.5  struct xenbus_dev_transaction {
    39.6  	struct list_head list;
    39.7 -	struct xenbus_transaction *handle;
    39.8 +	xenbus_transaction_t handle;
    39.9  };
   39.10  
   39.11  struct xenbus_dev_data {
   39.12 @@ -147,13 +147,11 @@ static ssize_t xenbus_dev_write(struct f
   39.13  		}
   39.14  
   39.15  		if (u->u.msg.type == XS_TRANSACTION_START) {
   39.16 -			trans->handle = (struct xenbus_transaction *)
   39.17 -				simple_strtoul(reply, NULL, 0);
   39.18 +			trans->handle = simple_strtoul(reply, NULL, 0);
   39.19  			list_add(&trans->list, &u->transactions);
   39.20  		} else if (u->u.msg.type == XS_TRANSACTION_END) {
   39.21  			list_for_each_entry(trans, &u->transactions, list)
   39.22 -				if ((unsigned long)trans->handle ==
   39.23 -				    (unsigned long)u->u.msg.tx_id)
   39.24 +				if (trans->handle == u->u.msg.tx_id)
   39.25  					break;
   39.26  			BUG_ON(&trans->list == &u->transactions);
   39.27  			list_del(&trans->list);
    40.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jan 10 15:21:00 2006 +0000
    40.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jan 24 17:54:34 2006 +0100
    40.3 @@ -27,12 +27,8 @@
    40.4   * IN THE SOFTWARE.
    40.5   */
    40.6  
    40.7 -#if 0
    40.8  #define DPRINTK(fmt, args...) \
    40.9 -    printk("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   40.10 -#else
   40.11 -#define DPRINTK(fmt, args...) ((void)0)
   40.12 -#endif
   40.13 +    pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   40.14  
   40.15  #include <linux/kernel.h>
   40.16  #include <linux/err.h>
   40.17 @@ -470,12 +466,17 @@ static int cleanup_dev(struct device *de
   40.18  
   40.19  	DPRINTK("%s", info->nodename);
   40.20  
   40.21 -	if (!strncmp(xendev->nodename, info->nodename, len)) {
   40.22 -		info->dev = xendev;
   40.23 -		get_device(dev);
   40.24 -		return 1;
   40.25 -	}
   40.26 -	return 0;
   40.27 +	/* Match the info->nodename path, or any subdirectory of that path. */
   40.28 +	if (strncmp(xendev->nodename, info->nodename, len))
   40.29 +		return 0;
   40.30 +
   40.31 +	/* If the node name is longer, ensure it really is a subdirectory. */
   40.32 +	if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
   40.33 +		return 0;
   40.34 +
   40.35 +	info->dev = xendev;
   40.36 +	get_device(dev);
   40.37 +	return 1;
   40.38  }
   40.39  
   40.40  static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
    41.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Jan 10 15:21:00 2006 +0000
    41.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Jan 24 17:54:34 2006 +0100
    41.3 @@ -190,7 +190,7 @@ void *xenbus_dev_request_and_reply(struc
    41.4  }
    41.5  
    41.6  /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
    41.7 -static void *xs_talkv(struct xenbus_transaction *t,
    41.8 +static void *xs_talkv(xenbus_transaction_t t,
    41.9  		      enum xsd_sockmsg_type type,
   41.10  		      const struct kvec *iovec,
   41.11  		      unsigned int num_vecs,
   41.12 @@ -201,7 +201,7 @@ static void *xs_talkv(struct xenbus_tran
   41.13  	unsigned int i;
   41.14  	int err;
   41.15  
   41.16 -	msg.tx_id = (u32)(unsigned long)t;
   41.17 +	msg.tx_id = t;
   41.18  	msg.req_id = 0;
   41.19  	msg.type = type;
   41.20  	msg.len = 0;
   41.21 @@ -242,7 +242,7 @@ static void *xs_talkv(struct xenbus_tran
   41.22  }
   41.23  
   41.24  /* Simplified version of xs_talkv: single message. */
   41.25 -static void *xs_single(struct xenbus_transaction *t,
   41.26 +static void *xs_single(xenbus_transaction_t t,
   41.27  		       enum xsd_sockmsg_type type,
   41.28  		       const char *string,
   41.29  		       unsigned int *len)
   41.30 @@ -309,7 +309,7 @@ static char **split(char *strings, unsig
   41.31  	return ret;
   41.32  }
   41.33  
   41.34 -char **xenbus_directory(struct xenbus_transaction *t,
   41.35 +char **xenbus_directory(xenbus_transaction_t t,
   41.36  			const char *dir, const char *node, unsigned int *num)
   41.37  {
   41.38  	char *strings, *path;
   41.39 @@ -329,7 +329,7 @@ char **xenbus_directory(struct xenbus_tr
   41.40  EXPORT_SYMBOL(xenbus_directory);
   41.41  
   41.42  /* Check if a path exists. Return 1 if it does. */
   41.43 -int xenbus_exists(struct xenbus_transaction *t,
   41.44 +int xenbus_exists(xenbus_transaction_t t,
   41.45  		  const char *dir, const char *node)
   41.46  {
   41.47  	char **d;
   41.48 @@ -347,7 +347,7 @@ EXPORT_SYMBOL(xenbus_exists);
   41.49   * Returns a kmalloced value: call free() on it after use.
   41.50   * len indicates length in bytes.
   41.51   */
   41.52 -void *xenbus_read(struct xenbus_transaction *t,
   41.53 +void *xenbus_read(xenbus_transaction_t t,
   41.54  		  const char *dir, const char *node, unsigned int *len)
   41.55  {
   41.56  	char *path;
   41.57 @@ -366,7 +366,7 @@ EXPORT_SYMBOL(xenbus_read);
   41.58  /* Write the value of a single file.
   41.59   * Returns -err on failure.
   41.60   */
   41.61 -int xenbus_write(struct xenbus_transaction *t,
   41.62 +int xenbus_write(xenbus_transaction_t t,
   41.63  		 const char *dir, const char *node, const char *string)
   41.64  {
   41.65  	const char *path;
   41.66 @@ -389,7 +389,7 @@ int xenbus_write(struct xenbus_transacti
   41.67  EXPORT_SYMBOL(xenbus_write);
   41.68  
   41.69  /* Create a new directory. */
   41.70 -int xenbus_mkdir(struct xenbus_transaction *t,
   41.71 +int xenbus_mkdir(xenbus_transaction_t t,
   41.72  		 const char *dir, const char *node)
   41.73  {
   41.74  	char *path;
   41.75 @@ -406,7 +406,7 @@ int xenbus_mkdir(struct xenbus_transacti
   41.76  EXPORT_SYMBOL(xenbus_mkdir);
   41.77  
   41.78  /* Destroy a file or directory (directories must be empty). */
   41.79 -int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
   41.80 +int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node)
   41.81  {
   41.82  	char *path;
   41.83  	int ret;
   41.84 @@ -424,30 +424,28 @@ EXPORT_SYMBOL(xenbus_rm);
   41.85  /* Start a transaction: changes by others will not be seen during this
   41.86   * transaction, and changes will not be visible to others until end.
   41.87   */
   41.88 -struct xenbus_transaction *xenbus_transaction_start(void)
   41.89 +int xenbus_transaction_start(xenbus_transaction_t *t)
   41.90  {
   41.91  	char *id_str;
   41.92 -	unsigned long id;
   41.93  
   41.94  	down_read(&xs_state.suspend_mutex);
   41.95  
   41.96  	id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL);
   41.97  	if (IS_ERR(id_str)) {
   41.98  		up_read(&xs_state.suspend_mutex);
   41.99 -		return (struct xenbus_transaction *)id_str;
  41.100 +		return PTR_ERR(id_str);
  41.101  	}
  41.102  
  41.103 -	id = simple_strtoul(id_str, NULL, 0);
  41.104 +	*t = simple_strtoul(id_str, NULL, 0);
  41.105  	kfree(id_str);
  41.106 -
  41.107 -	return (struct xenbus_transaction *)id;
  41.108 +	return 0;
  41.109  }
  41.110  EXPORT_SYMBOL(xenbus_transaction_start);
  41.111  
  41.112  /* End a transaction.
  41.113   * If abandon is true, transaction is discarded instead of committed.
  41.114   */
  41.115 -int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
  41.116 +int xenbus_transaction_end(xenbus_transaction_t t, int abort)
  41.117  {
  41.118  	char abortstr[2];
  41.119  	int err;
  41.120 @@ -466,7 +464,7 @@ int xenbus_transaction_end(struct xenbus
  41.121  EXPORT_SYMBOL(xenbus_transaction_end);
  41.122  
  41.123  /* Single read and scanf: returns -errno or num scanned. */
  41.124 -int xenbus_scanf(struct xenbus_transaction *t,
  41.125 +int xenbus_scanf(xenbus_transaction_t t,
  41.126  		 const char *dir, const char *node, const char *fmt, ...)
  41.127  {
  41.128  	va_list ap;
  41.129 @@ -489,7 +487,7 @@ int xenbus_scanf(struct xenbus_transacti
  41.130  EXPORT_SYMBOL(xenbus_scanf);
  41.131  
  41.132  /* Single printf and write: returns -errno or 0. */
  41.133 -int xenbus_printf(struct xenbus_transaction *t,
  41.134 +int xenbus_printf(xenbus_transaction_t t,
  41.135  		  const char *dir, const char *node, const char *fmt, ...)
  41.136  {
  41.137  	va_list ap;
  41.138 @@ -515,7 +513,7 @@ int xenbus_printf(struct xenbus_transact
  41.139  EXPORT_SYMBOL(xenbus_printf);
  41.140  
  41.141  /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
  41.142 -int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
  41.143 +int xenbus_gather(xenbus_transaction_t t, const char *dir, ...)
  41.144  {
  41.145  	va_list ap;
  41.146  	const char *name;
    42.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Tue Jan 10 15:21:00 2006 +0000
    42.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Tue Jan 24 17:54:34 2006 +0100
    42.3 @@ -32,6 +32,7 @@
    42.4  
    42.5  #include <asm-xen/xen-public/xen.h>
    42.6  #include <asm-xen/xen-public/sched.h>
    42.7 +#include <asm-xen/xen-public/nmi.h>
    42.8  
    42.9  #define _hypercall0(type, name)			\
   42.10  ({						\
   42.11 @@ -300,6 +301,14 @@ HYPERVISOR_suspend(
   42.12  			   SHUTDOWN_suspend, srec);
   42.13  }
   42.14  
   42.15 +static inline int
   42.16 +HYPERVISOR_nmi_op(
   42.17 +	unsigned long op,
   42.18 +	unsigned long arg)
   42.19 +{
   42.20 +	return _hypercall2(int, nmi_op, op, arg);
   42.21 +}
   42.22 +
   42.23  #endif /* __HYPERCALL_H__ */
   42.24  
   42.25  /*
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h	Tue Jan 24 17:54:34 2006 +0100
    43.3 @@ -0,0 +1,33 @@
    43.4 +/*
    43.5 + *  include/asm-xen/asm-i386/mach-xen/mach_traps.h
    43.6 + *
    43.7 + *  Machine specific NMI handling for Xen
    43.8 + */
    43.9 +#ifndef _MACH_TRAPS_H
   43.10 +#define _MACH_TRAPS_H
   43.11 +
   43.12 +#include <linux/bitops.h>
   43.13 +#include <asm-xen/xen-public/nmi.h>
   43.14 +
   43.15 +static inline void clear_mem_error(unsigned char reason) {}
   43.16 +static inline void clear_io_check_error(unsigned char reason) {}
   43.17 +
   43.18 +static inline unsigned char get_nmi_reason(void)
   43.19 +{
   43.20 +	shared_info_t *s = HYPERVISOR_shared_info;
   43.21 +	unsigned char reason = 0;
   43.22 +
   43.23 +	/* construct a value which looks like it came from
   43.24 +	 * port 0x61.
   43.25 +	 */
   43.26 +	if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
   43.27 +		reason |= 0x40;
   43.28 +	if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
   43.29 +		reason |= 0x80;
   43.30 +
   43.31 +        return reason;
   43.32 +}
   43.33 +
   43.34 +static inline void reassert_nmi(void) {}
   43.35 +
   43.36 +#endif /* !_MACH_TRAPS_H */
    44.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h	Tue Jan 10 15:21:00 2006 +0000
    44.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h	Tue Jan 24 17:54:34 2006 +0100
    44.3 @@ -29,6 +29,7 @@ void __init machine_specific_modify_cpu_
    44.4  
    44.5  extern void hypervisor_callback(void);
    44.6  extern void failsafe_callback(void);
    44.7 +extern void nmi(void);
    44.8  
    44.9  static void __init machine_specific_arch_setup(void)
   44.10  {
   44.11 @@ -36,5 +37,7 @@ static void __init machine_specific_arch
   44.12  	    __KERNEL_CS, (unsigned long)hypervisor_callback,
   44.13  	    __KERNEL_CS, (unsigned long)failsafe_callback);
   44.14  
   44.15 +	HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
   44.16 +
   44.17  	machine_specific_modify_cpu_capabilities(&boot_cpu_data);
   44.18  }
    45.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h	Tue Jan 10 15:21:00 2006 +0000
    45.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h	Tue Jan 24 17:54:34 2006 +0100
    45.3 @@ -287,9 +287,9 @@ HYPERVISOR_vcpu_op(
    45.4  }
    45.5  
    45.6  static inline int
    45.7 -HYPERVISOR_switch_to_user(void)
    45.8 +HYPERVISOR_iret(void)
    45.9  {
   45.10 -	return _hypercall0(int, switch_to_user);
   45.11 +	return _hypercall0(int, iret);
   45.12  }
   45.13  
   45.14  static inline int
   45.15 @@ -307,6 +307,14 @@ HYPERVISOR_suspend(
   45.16  			   SHUTDOWN_suspend, srec);
   45.17  }
   45.18  
   45.19 +static inline int
   45.20 +HYPERVISOR_nmi_op(
   45.21 +	unsigned long op,
   45.22 +	unsigned long arg)
   45.23 +{
   45.24 +	return _hypercall2(int, nmi_op, op, arg);
   45.25 +}
   45.26 +
   45.27  #endif /* __HYPERCALL_H__ */
   45.28  
   45.29  /*
    46.1 --- 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 +0000
    46.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h	Tue Jan 24 17:54:34 2006 +0100
    46.3 @@ -35,6 +35,7 @@ void __init machine_specific_modify_cpu_
    46.4  
    46.5  extern void hypervisor_callback(void);
    46.6  extern void failsafe_callback(void);
    46.7 +extern void nmi(void);
    46.8  
    46.9  static void __init machine_specific_arch_setup(void)
   46.10  {
   46.11 @@ -43,5 +44,9 @@ static void __init machine_specific_arch
   46.12                  (unsigned long) failsafe_callback,
   46.13                  (unsigned long) system_call);
   46.14  
   46.15 +#ifdef CONFIG_X86_LOCAL_APIC
   46.16 +	HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
   46.17 +#endif
   46.18 +
   46.19  	machine_specific_modify_cpu_capabilities(&boot_cpu_data);
   46.20  }
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/nmi.h	Tue Jan 24 17:54:34 2006 +0100
    47.3 @@ -0,0 +1,75 @@
    47.4 +/*
    47.5 + *  linux/include/asm-i386/nmi.h
    47.6 + */
    47.7 +#ifndef ASM_NMI_H
    47.8 +#define ASM_NMI_H
    47.9 +
   47.10 +#include <linux/pm.h>
   47.11 +
   47.12 +#include <asm-xen/xen-public/nmi.h>
   47.13 +
   47.14 +struct pt_regs;
   47.15 + 
   47.16 +typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
   47.17 + 
   47.18 +/** 
   47.19 + * set_nmi_callback
   47.20 + *
   47.21 + * Set a handler for an NMI. Only one handler may be
   47.22 + * set. Return 1 if the NMI was handled.
   47.23 + */
   47.24 +void set_nmi_callback(nmi_callback_t callback);
   47.25 + 
   47.26 +/** 
   47.27 + * unset_nmi_callback
   47.28 + *
   47.29 + * Remove the handler previously set.
   47.30 + */
   47.31 +void unset_nmi_callback(void);
   47.32 + 
   47.33 +#ifdef CONFIG_PM
   47.34 + 
   47.35 +/** Replace the PM callback routine for NMI. */
   47.36 +struct pm_dev * set_nmi_pm_callback(pm_callback callback);
   47.37 +
   47.38 +/** Unset the PM callback routine back to the default. */
   47.39 +void unset_nmi_pm_callback(struct pm_dev * dev);
   47.40 +
   47.41 +#else
   47.42 +
   47.43 +static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
   47.44 +{
   47.45 +	return 0;
   47.46 +} 
   47.47 + 
   47.48 +static inline void unset_nmi_pm_callback(struct pm_dev * dev)
   47.49 +{
   47.50 +}
   47.51 +
   47.52 +#endif /* CONFIG_PM */
   47.53 + 
   47.54 +extern void default_do_nmi(struct pt_regs *);
   47.55 +extern void die_nmi(char *str, struct pt_regs *regs);
   47.56 +
   47.57 +static inline unsigned char get_nmi_reason(void)
   47.58 +{
   47.59 +        shared_info_t *s = HYPERVISOR_shared_info;
   47.60 +        unsigned char reason = 0;
   47.61 +
   47.62 +        /* construct a value which looks like it came from
   47.63 +         * port 0x61.
   47.64 +         */
   47.65 +        if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
   47.66 +                reason |= 0x40;
   47.67 +        if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
   47.68 +                reason |= 0x80;
   47.69 +
   47.70 +        return reason;
   47.71 +}
   47.72 +
   47.73 +extern int panic_on_timeout;
   47.74 +extern int unknown_nmi_panic;
   47.75 +
   47.76 +extern int check_nmi_watchdog(void);
   47.77 + 
   47.78 +#endif /* ASM_NMI_H */
    48.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Tue Jan 10 15:21:00 2006 +0000
    48.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h	Tue Jan 24 17:54:34 2006 +0100
    48.3 @@ -417,12 +417,7 @@ static inline pud_t *__pud_offset_k(pud_
    48.4     Other CPUs get synced lazily via the page fault handler. */
    48.5  static inline pud_t *pud_offset_k(unsigned long address)
    48.6  {
    48.7 -	unsigned long addr;
    48.8 -
    48.9 -	addr = pgd_val(init_level4_pgt[pud_index(address)]);
   48.10 -	addr &= PHYSICAL_PAGE_MASK; /* machine physical */
   48.11 -        addr = machine_to_phys(addr);
   48.12 -	return __pud_offset_k((pud_t *)__va(addr), address);
   48.13 +	return pud_offset(pgd_offset_k(address), address);
   48.14  }
   48.15  
   48.16  /* PMD  - Level 2 access */
    49.1 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Tue Jan 10 15:21:00 2006 +0000
    49.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Tue Jan 24 17:54:34 2006 +0100
    49.3 @@ -37,7 +37,7 @@
    49.4  #include <asm-xen/xen-public/io/xenbus.h>
    49.5  #include <asm-xen/xen-public/io/xs_wire.h>
    49.6  
    49.7 -#define XBT_NULL NULL
    49.8 +#define XBT_NULL 0
    49.9  
   49.10  /* Register callback to watch this node. */
   49.11  struct xenbus_watch
   49.12 @@ -102,35 +102,35 @@ int xenbus_register_frontend(struct xenb
   49.13  int xenbus_register_backend(struct xenbus_driver *drv);
   49.14  void xenbus_unregister_driver(struct xenbus_driver *drv);
   49.15  
   49.16 -struct xenbus_transaction;
   49.17 +typedef u32 xenbus_transaction_t;
   49.18  
   49.19 -char **xenbus_directory(struct xenbus_transaction *t,
   49.20 +char **xenbus_directory(xenbus_transaction_t t,
   49.21  			const char *dir, const char *node, unsigned int *num);
   49.22 -void *xenbus_read(struct xenbus_transaction *t,
   49.23 +void *xenbus_read(xenbus_transaction_t t,
   49.24  		  const char *dir, const char *node, unsigned int *len);
   49.25 -int xenbus_write(struct xenbus_transaction *t,
   49.26 +int xenbus_write(xenbus_transaction_t t,
   49.27  		 const char *dir, const char *node, const char *string);
   49.28 -int xenbus_mkdir(struct xenbus_transaction *t,
   49.29 +int xenbus_mkdir(xenbus_transaction_t t,
   49.30  		 const char *dir, const char *node);
   49.31 -int xenbus_exists(struct xenbus_transaction *t,
   49.32 +int xenbus_exists(xenbus_transaction_t t,
   49.33  		  const char *dir, const char *node);
   49.34 -int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
   49.35 -struct xenbus_transaction *xenbus_transaction_start(void);
   49.36 -int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
   49.37 +int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node);
   49.38 +int xenbus_transaction_start(xenbus_transaction_t *t);
   49.39 +int xenbus_transaction_end(xenbus_transaction_t t, int abort);
   49.40  
   49.41  /* Single read and scanf: returns -errno or num scanned if > 0. */
   49.42 -int xenbus_scanf(struct xenbus_transaction *t,
   49.43 +int xenbus_scanf(xenbus_transaction_t t,
   49.44  		 const char *dir, const char *node, const char *fmt, ...)
   49.45  	__attribute__((format(scanf, 4, 5)));
   49.46  
   49.47  /* Single printf and write: returns -errno or 0. */
   49.48 -int xenbus_printf(struct xenbus_transaction *t,
   49.49 +int xenbus_printf(xenbus_transaction_t t,
   49.50  		  const char *dir, const char *node, const char *fmt, ...)
   49.51  	__attribute__((format(printf, 4, 5)));
   49.52  
   49.53  /* Generic read function: NULL-terminated triples of name,
   49.54   * sprintf-style type string, and pointer. Returns 0 or errno.*/
   49.55 -int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
   49.56 +int xenbus_gather(xenbus_transaction_t t, const char *dir, ...);
   49.57  
   49.58  /* notifer routines for when the xenstore comes up */
   49.59  int register_xenstore_notifier(struct notifier_block *nb);
   49.60 @@ -196,7 +196,7 @@ int xenbus_watch_path2(struct xenbus_dev
   49.61   * XenbusStateClosing, and the error will be saved in the store.
   49.62   */
   49.63  int xenbus_switch_state(struct xenbus_device *dev,
   49.64 -			struct xenbus_transaction *xbt,
   49.65 +			xenbus_transaction_t xbt,
   49.66  			XenbusState new_state);
   49.67  
   49.68  
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/patches/linux-2.6.12/i386-mach-io-check-nmi.patch	Tue Jan 24 17:54:34 2006 +0100
    50.3 @@ -0,0 +1,43 @@
    50.4 +--- ref-linux-2.6.12/arch/i386/kernel/traps.c	2005-12-19 09:23:44.000000000 +0000
    50.5 ++++ linux-2.6.12-xen0/arch/i386/kernel/traps.c	2006-01-05 15:51:52.000000000 +0000
    50.6 +@@ -521,18 +521,11 @@
    50.7 + 
    50.8 + static void io_check_error(unsigned char reason, struct pt_regs * regs)
    50.9 + {
   50.10 +-	unsigned long i;
   50.11 +-
   50.12 + 	printk("NMI: IOCK error (debug interrupt?)\n");
   50.13 + 	show_registers(regs);
   50.14 + 
   50.15 + 	/* Re-enable the IOCK line, wait for a few seconds */
   50.16 +-	reason = (reason & 0xf) | 8;
   50.17 +-	outb(reason, 0x61);
   50.18 +-	i = 2000;
   50.19 +-	while (--i) udelay(1000);
   50.20 +-	reason &= ~8;
   50.21 +-	outb(reason, 0x61);
   50.22 ++	clear_io_check_error(reason);
   50.23 + }
   50.24 + 
   50.25 + static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
   50.26 +--- ref-linux-2.6.12/include/asm-i386/mach-default/mach_traps.h	2005-06-17 20:48:29.000000000 +0100
   50.27 ++++ linux-2.6.12-xen0/include/asm-i386/mach-default/mach_traps.h	2006-01-05 15:52:33.000000000 +0000
   50.28 +@@ -15,6 +15,18 @@
   50.29 + 	outb(reason, 0x61);
   50.30 + }
   50.31 + 
   50.32 ++static inline void clear_io_check_error(unsigned char reason)
   50.33 ++{
   50.34 ++	unsigned long i;
   50.35 ++
   50.36 ++	reason = (reason & 0xf) | 8;
   50.37 ++	outb(reason, 0x61);
   50.38 ++	i = 2000;
   50.39 ++	while (--i) udelay(1000);
   50.40 ++	reason &= ~8;
   50.41 ++	outb(reason, 0x61);
   50.42 ++}
   50.43 ++
   50.44 + static inline unsigned char get_nmi_reason(void)
   50.45 + {
   50.46 + 	return inb(0x61);
    51.1 --- a/tools/examples/xmexample.vti	Tue Jan 10 15:21:00 2006 +0000
    51.2 +++ b/tools/examples/xmexample.vti	Tue Jan 24 17:54:34 2006 +0100
    51.3 @@ -21,7 +21,7 @@ builder='vmx'
    51.4  memory = 256
    51.5  
    51.6  # A name for your domain. All domains must have different names.
    51.7 -name = "ExampleVMXDomain"
    51.8 +name = "ExampleVTIDomain"
    51.9  
   51.10  # List of which CPUS this domain is allowed to use, default Xen picks
   51.11  #cpus = ""         # leave to Xen to pick
   51.12 @@ -30,7 +30,11 @@ name = "ExampleVMXDomain"
   51.13  
   51.14  # Optionally define mac and/or bridge for the network interfaces.
   51.15  # Random MACs are assigned if not given.
   51.16 -#vif = [ 'mac=00:16:3e:00:00:11, bridge=xen-br0' ]
   51.17 +#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
   51.18 +# type=ioemu specify the NIC is an ioemu device not netfront
   51.19 +vif = [ 'type=ioemu, bridge=xenbr0' ]
   51.20 +# for multiple NICs in device model, 3 in this example
   51.21 +#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
   51.22  
   51.23  #----------------------------------------------------------------------------
   51.24  # Define the disk devices you want the domain to have access to, and
   51.25 @@ -53,7 +57,7 @@ disk = [ 'file:/var/images/xenia64.img,i
   51.26  #============================================================================
   51.27  
   51.28  # New stuff
   51.29 -device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm.debug'
   51.30 +device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
   51.31  
   51.32  # Advanced users only. Don't touch if you don't know what you're doing
   51.33  memmap = '/usr/lib/xen/boot/mem-map.sxp'
    52.1 --- a/tools/firmware/vmxassist/acpi_madt.c	Tue Jan 10 15:21:00 2006 +0000
    52.2 +++ b/tools/firmware/vmxassist/acpi_madt.c	Tue Jan 24 17:54:34 2006 +0100
    52.3 @@ -55,7 +55,6 @@ static struct hvm_info_table *
    52.4  get_hvm_info_table(void)
    52.5  {
    52.6  	struct hvm_info_table *t;
    52.7 -	int i;
    52.8  
    52.9  	if (table != NULL)
   52.10  		return table;
    53.1 --- a/tools/ioemu/audio/audio.c	Tue Jan 10 15:21:00 2006 +0000
    53.2 +++ b/tools/ioemu/audio/audio.c	Tue Jan 24 17:54:34 2006 +0100
    53.3 @@ -257,11 +257,11 @@ void pcm_hw_clear (HWVoice *hw, void *bu
    53.4      switch (hw->fmt) {
    53.5      case AUD_FMT_S16:
    53.6      case AUD_FMT_S8:
    53.7 -        memset (buf, len << hw->shift, 0x00);
    53.8 +        memset (buf, 0x00, len << hw->shift);
    53.9          break;
   53.10  
   53.11      case AUD_FMT_U8:
   53.12 -        memset (buf, len << hw->shift, 0x80);
   53.13 +        memset (buf, 0x80, len << hw->shift);
   53.14          break;
   53.15  
   53.16      case AUD_FMT_U16:
    54.1 --- a/tools/ioemu/audio/noaudio.c	Tue Jan 10 15:21:00 2006 +0000
    54.2 +++ b/tools/ioemu/audio/noaudio.c	Tue Jan 24 17:54:34 2006 +0100
    54.3 @@ -41,7 +41,6 @@ static void no_hw_run (HWVoice *hw)
    54.4  {
    54.5      NoVoice *no = (NoVoice *) hw;
    54.6      int rpos, live, decr, samples;
    54.7 -    uint8_t *dst;
    54.8      st_sample_t *src;
    54.9      int64_t now = qemu_get_clock (vm_clock);
   54.10      int64_t ticks = now - no->old_ticks;
   54.11 @@ -82,7 +81,6 @@ static int no_hw_write (SWVoice *sw, voi
   54.12  
   54.13  static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
   54.14  {
   54.15 -    NoVoice *no = (NoVoice *) hw;
   54.16      hw->freq = freq;
   54.17      hw->nchannels = nchannels;
   54.18      hw->fmt = fmt;
    55.1 --- a/tools/ioemu/cpu.h	Tue Jan 10 15:21:00 2006 +0000
    55.2 +++ b/tools/ioemu/cpu.h	Tue Jan 24 17:54:34 2006 +0100
    55.3 @@ -63,6 +63,9 @@ int cpu_get_pic_interrupt(CPUX86State *s
    55.4  /* MSDOS compatibility mode FPU exception support */
    55.5  void cpu_set_ferr(CPUX86State *s);
    55.6  
    55.7 +/* helper2.c */
    55.8 +void cpu_x86_set_a20(CPUX86State *env, int a20_state);
    55.9 +
   55.10  #if defined(__i386__) || defined(__x86_64__)
   55.11  #define TARGET_PAGE_BITS 12
   55.12  #elif defined(__ia64__)
    56.1 --- a/tools/ioemu/hw/pc.c	Tue Jan 10 15:21:00 2006 +0000
    56.2 +++ b/tools/ioemu/hw/pc.c	Tue Jan 24 17:54:34 2006 +0100
    56.3 @@ -382,8 +382,6 @@ void pc_init(uint64_t ram_size, int vga_
    56.4  {
    56.5      char buf[1024];
    56.6      int ret, linux_boot, initrd_size, i, nb_nics1;
    56.7 -    unsigned long bios_offset, vga_bios_offset;
    56.8 -    int bios_size, isa_bios_size;
    56.9      PCIBus *pci_bus;
   56.10      extern void * shared_vram;
   56.11      
    57.1 --- a/tools/ioemu/vl.c	Tue Jan 10 15:21:00 2006 +0000
    57.2 +++ b/tools/ioemu/vl.c	Tue Jan 24 17:54:34 2006 +0100
    57.3 @@ -1204,7 +1204,7 @@ int store_console_dev(int domid, char *p
    57.4          return -1;
    57.5      }
    57.6      strcat(path, "/console/tty");
    57.7 -    if (!xs_write(xs, NULL, path, pts, strlen(pts))) {
    57.8 +    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
    57.9          fprintf(logfile, "xs_write for console fail");
   57.10          return -1;
   57.11      }
    58.1 --- a/tools/ioemu/vl.h	Tue Jan 10 15:21:00 2006 +0000
    58.2 +++ b/tools/ioemu/vl.h	Tue Jan 24 17:54:34 2006 +0100
    58.3 @@ -354,6 +354,9 @@ int register_savevm(const char *idstr,
    58.4  void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
    58.5  void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
    58.6  
    58.7 +/* port-e9.c */
    58.8 +void port_e9_init(void);
    58.9 +
   58.10  /* block.c */
   58.11  typedef struct BlockDriverState BlockDriverState;
   58.12  typedef struct BlockDriver BlockDriver;
    59.1 --- a/tools/libxc/xc_ia64_stubs.c	Tue Jan 10 15:21:00 2006 +0000
    59.2 +++ b/tools/libxc/xc_ia64_stubs.c	Tue Jan 24 17:54:34 2006 +0100
    59.3 @@ -23,7 +23,8 @@ unsigned long xc_ia64_fpsr_default(void)
    59.4  }
    59.5  
    59.6  int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 
    59.7 -                  uint32_t max_factor, uint32_t flags, int (*suspend)(void))
    59.8 +                  uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
    59.9 +                  int (*suspend)(int domid))
   59.10  {
   59.11      PERROR("xc_linux_save not implemented\n");
   59.12      return -1;
   59.13 @@ -664,15 +665,7 @@ int xc_vmx_build(int xc_handle,
   59.14          goto error_out;
   59.15      }
   59.16  
   59.17 -    if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ){
   59.18 -        PERROR("Could not get vcpu context");
   59.19 -        goto error_out;
   59.20 -    }
   59.21 -
   59.22 -    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) {
   59.23 -        ERROR("Domain is already constructed");
   59.24 -        goto error_out;
   59.25 -    }
   59.26 +    memset(ctxt, 0, sizeof(*ctxt));
   59.27  
   59.28      if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, image_size, 
   59.29                         control_evtchn, store_evtchn, store_mfn ) < 0 ){
    60.1 --- a/tools/libxc/xc_linux_build.c	Tue Jan 10 15:21:00 2006 +0000
    60.2 +++ b/tools/libxc/xc_linux_build.c	Tue Jan 24 17:54:34 2006 +0100
    60.3 @@ -33,10 +33,8 @@
    60.4  #endif
    60.5  
    60.6  #ifdef __ia64__
    60.7 -#define already_built(ctxt) (0)
    60.8  #define get_tot_pages xc_get_max_pages
    60.9  #else
   60.10 -#define already_built(ctxt) ((ctxt)->ctrlreg[3] != 0)
   60.11  #define get_tot_pages xc_get_tot_pages
   60.12  #endif
   60.13  
   60.14 @@ -800,17 +798,7 @@ int xc_linux_build(int xc_handle,
   60.15          goto error_out;
   60.16      }
   60.17  
   60.18 -    if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
   60.19 -    {
   60.20 -        PERROR("Could not get vcpu context");
   60.21 -        goto error_out;
   60.22 -    }
   60.23 -
   60.24 -    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) || already_built(ctxt) )
   60.25 -    {
   60.26 -        ERROR("Domain is already constructed");
   60.27 -        goto error_out;
   60.28 -    }
   60.29 +    memset(ctxt, 0, sizeof(*ctxt));
   60.30  
   60.31      if ( setup_guest(xc_handle, domid, image, image_size, 
   60.32                       initrd_gfd, initrd_size, nr_pages, 
   60.33 @@ -865,6 +853,8 @@ int xc_linux_build(int xc_handle,
   60.34      ctxt->user_regs.esi = vstartinfo_start;
   60.35      ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
   60.36  
   60.37 +    ctxt->flags = VGCF_IN_KERNEL;
   60.38 +
   60.39      /* FPU is set up to default initial state. */
   60.40      memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
   60.41  
    61.1 --- a/tools/libxc/xc_linux_restore.c	Tue Jan 10 15:21:00 2006 +0000
    61.2 +++ b/tools/libxc/xc_linux_restore.c	Tue Jan 24 17:54:34 2006 +0100
    61.3 @@ -170,13 +170,6 @@ int xc_linux_restore(int xc_handle, int 
    61.4      }
    61.5  
    61.6  
    61.7 -    /* Only have to worry about vcpu 0 even for SMP */
    61.8 -    if (xc_vcpu_getcontext( xc_handle, dom, 0, &ctxt)) {
    61.9 -        ERR("Could not get vcpu context");
   61.10 -        goto out;
   61.11 -    }
   61.12 -
   61.13 -    
   61.14      /* Read the saved P2M frame list */
   61.15      if(!(p2m_frame_list = malloc(P2M_FL_SIZE))) { 
   61.16          ERR("Couldn't allocate p2m_frame_list array");
    62.1 --- a/tools/libxc/xc_vmx_build.c	Tue Jan 10 15:21:00 2006 +0000
    62.2 +++ b/tools/libxc/xc_vmx_build.c	Tue Jan 24 17:54:34 2006 +0100
    62.3 @@ -651,18 +651,7 @@ int xc_vmx_build(int xc_handle,
    62.4          goto error_out;
    62.5      }
    62.6  
    62.7 -    if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
    62.8 -    {
    62.9 -        PERROR("Could not get vcpu context");
   62.10 -        goto error_out;
   62.11 -    }
   62.12 -
   62.13 -    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
   62.14 -         (ctxt->ctrlreg[3] != 0) )
   62.15 -    {
   62.16 -        ERROR("Domain is already constructed");
   62.17 -        goto error_out;
   62.18 -    }
   62.19 +    memset(ctxt, 0, sizeof(*ctxt));
   62.20  
   62.21      if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
   62.22                       ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
    63.1 --- a/tools/libxc/xenguest.h	Tue Jan 10 15:21:00 2006 +0000
    63.2 +++ b/tools/libxc/xenguest.h	Tue Jan 24 17:54:34 2006 +0100
    63.3 @@ -21,9 +21,9 @@
    63.4   * @parm dom the id of the domain
    63.5   * @return 0 on success, -1 on failure
    63.6   */
    63.7 -int xc_linux_save(int xc_handle, int fd, uint32_t dom, uint32_t max_iters, 
    63.8 +int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 
    63.9                    uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
   63.10 -                  int (*suspend)(int));
   63.11 +                  int (*suspend)(int domid));
   63.12  
   63.13  
   63.14  /**
    64.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Tue Jan 10 15:21:00 2006 +0000
    64.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Tue Jan 24 17:54:34 2006 +0100
    64.3 @@ -66,7 +66,7 @@ static PyObject *none(bool result);
    64.4  
    64.5  static int parse_transaction_path(XsHandle *self, PyObject *args,
    64.6                                    struct xs_handle **xh,
    64.7 -                                  struct xs_transaction_handle **th,
    64.8 +                                  xs_transaction_t *th,
    64.9                                    char **path);
   64.10  
   64.11  
   64.12 @@ -83,7 +83,7 @@ static int parse_transaction_path(XsHand
   64.13  static PyObject *xspy_read(XsHandle *self, PyObject *args)
   64.14  {
   64.15      struct xs_handle *xh;
   64.16 -    struct xs_transaction_handle *th;
   64.17 +    xs_transaction_t th;
   64.18      char *path;
   64.19  
   64.20      char *xsval;
   64.21 @@ -120,7 +120,7 @@ static PyObject *xspy_write(XsHandle *se
   64.22  {
   64.23      static char *arg_spec = "sss#";
   64.24      struct xs_handle *xh = xshandle(self);
   64.25 -    struct xs_transaction_handle *th;
   64.26 +    xs_transaction_t th;
   64.27      char *thstr;
   64.28      char *path;
   64.29      char *data;
   64.30 @@ -132,7 +132,7 @@ static PyObject *xspy_write(XsHandle *se
   64.31      if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path, &data, &data_n))
   64.32          return NULL;
   64.33  
   64.34 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
   64.35 +    th = strtoul(thstr, NULL, 16);
   64.36  
   64.37      Py_BEGIN_ALLOW_THREADS
   64.38      result = xs_write(xh, th, path, data, data_n);
   64.39 @@ -155,7 +155,7 @@ static PyObject *xspy_write(XsHandle *se
   64.40  static PyObject *xspy_ls(XsHandle *self, PyObject *args)
   64.41  {
   64.42      struct xs_handle *xh;
   64.43 -    struct xs_transaction_handle *th;
   64.44 +    xs_transaction_t th;
   64.45      char *path;
   64.46  
   64.47      char **xsval;
   64.48 @@ -193,7 +193,7 @@ static PyObject *xspy_ls(XsHandle *self,
   64.49  static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
   64.50  {
   64.51      struct xs_handle *xh;
   64.52 -    struct xs_transaction_handle *th;
   64.53 +    xs_transaction_t th;
   64.54      char *path;
   64.55  
   64.56      bool result;
   64.57 @@ -221,7 +221,7 @@ static PyObject *xspy_mkdir(XsHandle *se
   64.58  static PyObject *xspy_rm(XsHandle *self, PyObject *args)
   64.59  {
   64.60      struct xs_handle *xh;
   64.61 -    struct xs_transaction_handle *th;
   64.62 +    xs_transaction_t th;
   64.63      char *path;
   64.64  
   64.65      bool result;
   64.66 @@ -256,7 +256,7 @@ static PyObject *xspy_get_permissions(Xs
   64.67      unsigned int perms_n = 0;
   64.68      int i;
   64.69  
   64.70 -    struct xs_transaction_handle *th;
   64.71 +    xs_transaction_t th;
   64.72      char *thstr;
   64.73  
   64.74      if (!xh)
   64.75 @@ -264,7 +264,7 @@ static PyObject *xspy_get_permissions(Xs
   64.76      if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path))
   64.77          return NULL;
   64.78  
   64.79 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
   64.80 +    th = strtoul(thstr, NULL, 16);
   64.81  
   64.82      Py_BEGIN_ALLOW_THREADS
   64.83      perms = xs_get_permissions(xh, th, path, &perms_n);
   64.84 @@ -312,7 +312,7 @@ static PyObject *xspy_set_permissions(Xs
   64.85      int xsperms_n;
   64.86      PyObject *tuple0 = NULL;
   64.87  
   64.88 -    struct xs_transaction_handle *th;
   64.89 +    xs_transaction_t th;
   64.90      char *thstr;
   64.91  
   64.92      if (!xh)
   64.93 @@ -320,7 +320,7 @@ static PyObject *xspy_set_permissions(Xs
   64.94      if (!PyArg_ParseTuple(args, "ssO", &thstr, &path, &perms))
   64.95          goto exit;
   64.96  
   64.97 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
   64.98 +    th = strtoul(thstr, NULL, 16);
   64.99  
  64.100      if (!PyList_Check(perms)) {
  64.101          PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
  64.102 @@ -509,7 +509,7 @@ static PyObject *xspy_unwatch(XsHandle *
  64.103  static PyObject *xspy_transaction_start(XsHandle *self)
  64.104  {
  64.105      struct xs_handle *xh = xshandle(self);
  64.106 -    struct xs_transaction_handle *th;
  64.107 +    xs_transaction_t th;
  64.108      char thstr[MAX_STRLEN(unsigned long) + 1];
  64.109  
  64.110      if (!xh)
  64.111 @@ -519,7 +519,7 @@ static PyObject *xspy_transaction_start(
  64.112      th = xs_transaction_start(xh);
  64.113      Py_END_ALLOW_THREADS
  64.114  
  64.115 -    if (th == NULL) {
  64.116 +    if (th == XBT_NULL) {
  64.117          PyErr_SetFromErrno(PyExc_RuntimeError);
  64.118          return NULL;
  64.119      }
  64.120 @@ -547,7 +547,7 @@ static PyObject *xspy_transaction_end(Xs
  64.121      struct xs_handle *xh = xshandle(self);
  64.122      bool result;
  64.123  
  64.124 -    struct xs_transaction_handle *th;
  64.125 +    xs_transaction_t th;
  64.126      char *thstr;
  64.127  
  64.128      if (!xh)
  64.129 @@ -556,7 +556,7 @@ static PyObject *xspy_transaction_end(Xs
  64.130                                       &thstr, &abort))
  64.131          return NULL;
  64.132  
  64.133 -    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  64.134 +    th = strtoul(thstr, NULL, 16);
  64.135  
  64.136      Py_BEGIN_ALLOW_THREADS
  64.137      result = xs_transaction_end(xh, th, abort);
  64.138 @@ -727,7 +727,7 @@ static void remove_watch(XsHandle *self,
  64.139   */
  64.140  static int parse_transaction_path(XsHandle *self, PyObject *args,
  64.141                                    struct xs_handle **xh,
  64.142 -                                  struct xs_transaction_handle **th,
  64.143 +                                  xs_transaction_t *th,
  64.144                                    char **path)
  64.145  {
  64.146      char *thstr;
  64.147 @@ -740,7 +740,7 @@ static int parse_transaction_path(XsHand
  64.148      if (!PyArg_ParseTuple(args, "ss", &thstr, path))
  64.149          return 0;
  64.150  
  64.151 -    *th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
  64.152 +    *th = strtoul(thstr, NULL, 16);
  64.153  
  64.154      return 1;
  64.155  }
    65.1 --- a/tools/vtpm/Makefile	Tue Jan 10 15:21:00 2006 +0000
    65.2 +++ b/tools/vtpm/Makefile	Tue Jan 24 17:54:34 2006 +0100
    65.3 @@ -11,6 +11,8 @@ VTPM_DIR = vtpm
    65.4  # Emulator tarball name
    65.5  TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
    65.6  
    65.7 +GMP_HEADER = /usr/include/gmp.h
    65.8 +
    65.9  all: build
   65.10  
   65.11  build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) build_sub
   65.12 @@ -55,5 +57,12 @@ mrproper:
   65.13  	patch -p1 <../vtpm.patch
   65.14  
   65.15  build_sub:
   65.16 -	$(MAKE) -C $(TPM_EMULATOR_DIR)
   65.17 -	$(MAKE) -C $(VTPM_DIR)
   65.18 +	if [ -e $(GMP_HEADER) ]; then \
   65.19 +		$(MAKE) -C $(VTPM_DIR); \
   65.20 +		if [ "$(BUILD_EMULATOR)" = "y" ]; then \
   65.21 +			$(MAKE) -C $(TPM_EMULATOR_DIR); \
   65.22 +		fi \
   65.23 +	else \
   65.24 +		echo "*** Unable to build VTPMs. libgmp could not be found."; \
   65.25 +	fi
   65.26 +
    66.1 --- a/tools/vtpm/Rules.mk	Tue Jan 10 15:21:00 2006 +0000
    66.2 +++ b/tools/vtpm/Rules.mk	Tue Jan 24 17:54:34 2006 +0100
    66.3 @@ -33,5 +33,7 @@ OBJS	= $(patsubst %.c,%.o,$(SRCS))
    66.4  
    66.5  -include $(DEP_FILES)
    66.6  
    66.7 +BUILD_EMULATOR = n
    66.8 +
    66.9  # Make sure these are just rules
   66.10  .PHONY : all build install clean
    67.1 --- a/tools/vtpm_manager/Makefile	Tue Jan 10 15:21:00 2006 +0000
    67.2 +++ b/tools/vtpm_manager/Makefile	Tue Jan 24 17:54:34 2006 +0100
    67.3 @@ -4,13 +4,18 @@ XEN_ROOT = ../..
    67.4  include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
    67.5  
    67.6  SUBDIRS		= crypto tcs util manager
    67.7 +OPENSSL_HEADER	= /usr/include/openssl/crypto.h
    67.8  
    67.9  all: build
   67.10  
   67.11  build:
   67.12 -	@set -e; for subdir in $(SUBDIRS); do \
   67.13 -		$(MAKE) -C $$subdir $@; \
   67.14 -	done
   67.15 +	if [ -e $(OPENSSL_HEADER) ]; then \
   67.16 +		@set -e; for subdir in $(SUBDIRS); do \
   67.17 +			$(MAKE) -C $$subdir $@; \
   67.18 +		done; \
   67.19 +	else \
   67.20 +		echo "*** Cannot build vtpm_manager: OpenSSL developement files missing."; \
   67.21 +	fi
   67.22  
   67.23  install: build
   67.24  	@set -e; for subdir in $(SUBDIRS); do \
    68.1 --- a/tools/vtpm_manager/manager/vtpm_manager.c	Tue Jan 10 15:21:00 2006 +0000
    68.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.c	Tue Jan 24 17:54:34 2006 +0100
    68.3 @@ -151,9 +151,6 @@ TPM_RESULT VTPM_Create_Service(){
    68.4  				    &osap) );
    68.5    
    68.6    // Generate boot key's auth
    68.7 -  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
    68.8 -		     sizeof(TPM_AUTHDATA) );
    68.9 -  
   68.10    TPM_AUTHDATA bootKeyWrapAuth;
   68.11    memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
   68.12    
    69.1 --- a/tools/xenmon/Makefile	Tue Jan 10 15:21:00 2006 +0000
    69.2 +++ b/tools/xenmon/Makefile	Tue Jan 24 17:54:34 2006 +0100
    69.3 @@ -13,12 +13,9 @@
    69.4  INSTALL         = install
    69.5  INSTALL_PROG    = $(INSTALL) -m0755
    69.6  INSTALL_DIR     = $(INSTALL) -d -m0755
    69.7 -INSTALL_DATA    = $(INSTALL) -m064
    69.8 +INSTALL_DATA    = $(INSTALL) -m0644
    69.9  
   69.10 -prefix=/usr/local
   69.11 -mandir=$(prefix)/share/man
   69.12 -man1dir=$(mandir)/man1
   69.13 -sbindir=$(prefix)/sbin
   69.14 +sbindir=/usr/sbin
   69.15  
   69.16  XEN_ROOT=../..
   69.17  include $(XEN_ROOT)/tools/Rules.mk
    70.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Tue Jan 10 15:21:00 2006 +0000
    70.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Tue Jan 24 17:54:34 2006 +0100
    70.3 @@ -705,7 +705,7 @@ static char *xenstat_get_domain_name(xen
    70.4  
    70.5  	snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
    70.6  	
    70.7 -	name = xs_read(handle->xshandle, NULL, path, NULL);
    70.8 +	name = xs_read(handle->xshandle, XBT_NULL, path, NULL);
    70.9  	if (name == NULL)
   70.10  		name = strdup(" ");
   70.11  
    71.1 --- a/tools/xenstore/Makefile	Tue Jan 10 15:21:00 2006 +0000
    71.2 +++ b/tools/xenstore/Makefile	Tue Jan 24 17:54:34 2006 +0100
    71.3 @@ -27,7 +27,7 @@ CLIENTS := xenstore-exists xenstore-list
    71.4  CLIENTS += xenstore-write
    71.5  CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
    71.6  
    71.7 -all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xsls
    71.8 +all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xenstore-ls
    71.9  
   71.10  testcode: xs_test xenstored_test xs_random
   71.11  
   71.12 @@ -40,7 +40,7 @@ xenstored: xenstored_core.o xenstored_wa
   71.13  $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
   71.14  	$(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
   71.15  
   71.16 -xsls: xsls.o libxenstore.so
   71.17 +xenstore-ls: xsls.o libxenstore.so
   71.18  	$(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
   71.19  
   71.20  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
   71.21 @@ -77,7 +77,7 @@ libxenstore.so: xs.opic xs_lib.opic
   71.22  clean: testsuite-clean
   71.23  	rm -f *.o *.opic *.so
   71.24  	rm -f xenstored xs_random xs_stress xs_crashme
   71.25 -	rm -f xs_test xenstored_test xs_tdb_dump xsls $(CLIENTS)
   71.26 +	rm -f xs_test xenstored_test xs_tdb_dump xenstore-ls $(CLIENTS)
   71.27  	$(RM) $(PROG_DEP)
   71.28  
   71.29  print-dir:
   71.30 @@ -129,7 +129,7 @@ TAGS:
   71.31  tarball: clean
   71.32  	cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/
   71.33  
   71.34 -install: libxenstore.so xenstored xsls $(CLIENTS)
   71.35 +install: libxenstore.so xenstored xenstore-ls $(CLIENTS)
   71.36  	$(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
   71.37  	$(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
   71.38  	$(INSTALL_DIR) -p $(DESTDIR)/usr/bin
   71.39 @@ -137,7 +137,7 @@ install: libxenstore.so xenstored xsls $
   71.40  	$(INSTALL_DIR) -p $(DESTDIR)/usr/include
   71.41  	$(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
   71.42  	$(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin
   71.43 -	$(INSTALL_PROG) xsls $(DESTDIR)/usr/bin
   71.44 +	$(INSTALL_PROG) xenstore-ls $(DESTDIR)/usr/bin
   71.45  	$(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
   71.46  	$(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR)
   71.47  	$(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
    72.1 --- a/tools/xenstore/utils.c	Tue Jan 10 15:21:00 2006 +0000
    72.2 +++ b/tools/xenstore/utils.c	Tue Jan 24 17:54:34 2006 +0100
    72.3 @@ -92,23 +92,33 @@ void *grab_file(const char *filename, un
    72.4  	else
    72.5  		fd = open(filename, O_RDONLY, 0);
    72.6  
    72.7 -	if (fd < 0)
    72.8 +	if (fd == -1)
    72.9  		return NULL;
   72.10  
   72.11  	buffer = malloc(max+1);
   72.12 +	if (!buffer)
   72.13 +		goto error;
   72.14  	*size = 0;
   72.15  	while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
   72.16  		*size += ret;
   72.17 -		if (*size == max)
   72.18 -			buffer = realloc(buffer, max *= 2 + 1);
   72.19 +		if (*size == max) {
   72.20 +			void *nbuffer;
   72.21 +			max *= 2;
   72.22 +			nbuffer = realloc(buffer, max + 1);
   72.23 +			if (!nbuffer)
   72.24 +				goto error;
   72.25 +			buffer = nbuffer;
   72.26 +		}
   72.27  	}
   72.28 -	if (ret < 0) {
   72.29 -		free(buffer);
   72.30 -		buffer = NULL;
   72.31 -	} else
   72.32 -		((char *)buffer)[*size] = '\0';
   72.33 +	if (ret < 0)
   72.34 +		goto error;
   72.35 +	((char *)buffer)[*size] = '\0';
   72.36  	close(fd);
   72.37  	return buffer;
   72.38 +error:
   72.39 +	free(buffer);
   72.40 +	close(fd);
   72.41 +	return NULL;
   72.42  }
   72.43  
   72.44  void release_file(void *data, unsigned long size __attribute__((unused)))
    73.1 --- a/tools/xenstore/xenstore_client.c	Tue Jan 10 15:21:00 2006 +0000
    73.2 +++ b/tools/xenstore/xenstore_client.c	Tue Jan 24 17:54:34 2006 +0100
    73.3 @@ -66,7 +66,7 @@ usage(const char *progname)
    73.4  
    73.5  #if defined(CLIENT_rm)
    73.6  static int
    73.7 -do_rm(char *path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
    73.8 +do_rm(char *path, struct xs_handle *xsh, xs_transaction_t xth)
    73.9  {
   73.10      if (xs_rm(xsh, xth, path)) {
   73.11          return 0;
   73.12 @@ -81,7 +81,7 @@ do_rm(char *path, struct xs_handle *xsh,
   73.13  
   73.14  static int
   73.15  perform(int optind, int argc, char **argv, struct xs_handle *xsh,
   73.16 -        struct xs_transaction_handle *xth, int prefix, int tidy)
   73.17 +        xs_transaction_t xth, int prefix, int tidy)
   73.18  {
   73.19      while (optind < argc) {
   73.20  #if defined(CLIENT_read)
   73.21 @@ -179,7 +179,7 @@ int
   73.22  main(int argc, char **argv)
   73.23  {
   73.24      struct xs_handle *xsh;
   73.25 -    struct xs_transaction_handle *xth;
   73.26 +    xs_transaction_t xth;
   73.27      int ret = 0, socket = 0;
   73.28      int prefix = 0;
   73.29      int tidy = 0;
   73.30 @@ -243,7 +243,7 @@ main(int argc, char **argv)
   73.31  
   73.32    again:
   73.33      xth = xs_transaction_start(xsh);
   73.34 -    if (xth == NULL)
   73.35 +    if (xth == XBT_NULL)
   73.36  	errx(1, "couldn't start transaction");
   73.37  
   73.38      ret = perform(optind, argc, argv, xsh, xth, prefix, tidy);
    74.1 --- a/tools/xenstore/xenstored_core.c	Tue Jan 10 15:21:00 2006 +0000
    74.2 +++ b/tools/xenstore/xenstored_core.c	Tue Jan 24 17:54:34 2006 +0100
    74.3 @@ -174,11 +174,38 @@ static char *sockmsg_string(enum xsd_soc
    74.4  	}
    74.5  }
    74.6  
    74.7 +void trace(const char *fmt, ...)
    74.8 +{
    74.9 +	va_list arglist;
   74.10 +	char *str;
   74.11 +	char sbuf[1024];
   74.12 +	int ret;
   74.13 +
   74.14 +	if (tracefd < 0)
   74.15 +		return;
   74.16 +
   74.17 +	/* try to use a static buffer */
   74.18 +	va_start(arglist, fmt);
   74.19 +	ret = vsnprintf(sbuf, 1024, fmt, arglist);
   74.20 +	va_end(arglist);
   74.21 +
   74.22 +	if (ret <= 1024) {
   74.23 +		write(tracefd, sbuf, ret);
   74.24 +		return;
   74.25 +	}
   74.26 +
   74.27 +	/* fail back to dynamic allocation */
   74.28 +	va_start(arglist, fmt);
   74.29 +	str = talloc_vasprintf(NULL, fmt, arglist);
   74.30 +	va_end(arglist);
   74.31 +	write(tracefd, str, strlen(str));
   74.32 +	talloc_free(str);
   74.33 +}
   74.34 +
   74.35  static void trace_io(const struct connection *conn,
   74.36  		     const char *prefix,
   74.37  		     const struct buffered_data *data)
   74.38  {
   74.39 -	char string[64];
   74.40  	unsigned int i;
   74.41  	time_t now;
   74.42  	struct tm *tm;
   74.43 @@ -189,62 +216,25 @@ static void trace_io(const struct connec
   74.44  	now = time(NULL);
   74.45  	tm = localtime(&now);
   74.46  
   74.47 -	write(tracefd, prefix, strlen(prefix));
   74.48 -	sprintf(string, " %p %02d:%02d:%02d ", conn, tm->tm_hour, tm->tm_min,
   74.49 -		tm->tm_sec);
   74.50 -	write(tracefd, string, strlen(string));
   74.51 -	write(tracefd, sockmsg_string(data->hdr.msg.type),
   74.52 -	      strlen(sockmsg_string(data->hdr.msg.type)));
   74.53 -	write(tracefd, " (", 2);
   74.54 -	for (i = 0; i < data->hdr.msg.len; i++) {
   74.55 -		if (data->buffer[i] == '\0')
   74.56 -			write(tracefd, " ", 1);
   74.57 -		else
   74.58 -			write(tracefd, data->buffer + i, 1);
   74.59 -	}
   74.60 -	write(tracefd, ")\n", 2);
   74.61 +	trace("%s %p %02d:%02d:%02d %s (", prefix, conn,
   74.62 +	      tm->tm_hour, tm->tm_min, tm->tm_sec,
   74.63 +	      sockmsg_string(data->hdr.msg.type));
   74.64 +	
   74.65 +	for (i = 0; i < data->hdr.msg.len; i++)
   74.66 +		trace("%c", (data->buffer[i] != '\0') ? data->buffer[i] : ' ');
   74.67 +	trace(")\n");
   74.68  }
   74.69  
   74.70  void trace_create(const void *data, const char *type)
   74.71  {
   74.72 -	char string[64];
   74.73 -	if (tracefd < 0)
   74.74 -		return;
   74.75 -
   74.76 -	write(tracefd, "CREATE ", strlen("CREATE "));
   74.77 -	write(tracefd, type, strlen(type));
   74.78 -	sprintf(string, " %p\n", data);
   74.79 -	write(tracefd, string, strlen(string));
   74.80 +	trace("CREATE %s %p\n", type, data);
   74.81  }
   74.82  
   74.83  void trace_destroy(const void *data, const char *type)
   74.84  {
   74.85 -	char string[64];
   74.86 -	if (tracefd < 0)
   74.87 -		return;
   74.88 -
   74.89 -	write(tracefd, "DESTROY ", strlen("DESTROY "));
   74.90 -	write(tracefd, type, strlen(type));
   74.91 -	sprintf(string, " %p\n", data);
   74.92 -	write(tracefd, string, strlen(string));
   74.93 +	trace("DESTROY %s %p\n", type, data);
   74.94  }
   74.95  
   74.96 -void trace(const char *fmt, ...)
   74.97 -{
   74.98 -	va_list arglist;
   74.99 -	char *str;
  74.100 -
  74.101 -	if (tracefd < 0)
  74.102 -		return;
  74.103 -
  74.104 -	va_start(arglist, fmt);
  74.105 -	str = talloc_vasprintf(NULL, fmt, arglist);
  74.106 -	va_end(arglist);
  74.107 -	write(tracefd, str, strlen(str));
  74.108 -	talloc_free(str);
  74.109 -}
  74.110 -
  74.111 -
  74.112  /**
  74.113   * Signal handler for SIGHUP, which requests that the trace log is reopened
  74.114   * (in the main loop).  A single byte is written to reopen_log_pipe, to awaken
  74.115 @@ -268,7 +258,7 @@ static void reopen_log()
  74.116  		if (tracefd < 0)
  74.117  			perror("Could not open tracefile");
  74.118  		else
  74.119 -			write(tracefd, "\n***\n", strlen("\n***\n"));
  74.120 +			trace("\n***\n");
  74.121  	}
  74.122  }
  74.123  
  74.124 @@ -1311,11 +1301,10 @@ struct connection *new_connection(connwr
  74.125  {
  74.126  	struct connection *new;
  74.127  
  74.128 -	new = talloc(talloc_autofree_context(), struct connection);
  74.129 +	new = talloc_zero(talloc_autofree_context(), struct connection);
  74.130  	if (!new)
  74.131  		return NULL;
  74.132  
  74.133 -	memset(new, 0, sizeof(*new));
  74.134  	new->fd = -1;
  74.135  	new->write = write;
  74.136  	new->read = read;
    75.1 --- a/tools/xenstore/xenstored_domain.c	Tue Jan 10 15:21:00 2006 +0000
    75.2 +++ b/tools/xenstore/xenstored_domain.c	Tue Jan 24 17:54:34 2006 +0100
    75.3 @@ -278,12 +278,12 @@ static struct domain *new_domain(void *c
    75.4  	talloc_set_destructor(domain, destroy_domain);
    75.5  
    75.6  	/* Tell kernel we're interested in this event. */
    75.7 -        bind.remote_domain = domid;
    75.8 -        bind.remote_port   = port;
    75.9 -        rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
   75.10 -        if (rc == -1)
   75.11 -            return NULL;
   75.12 -        domain->port = rc;
   75.13 +	bind.remote_domain = domid;
   75.14 +	bind.remote_port   = port;
   75.15 +	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
   75.16 +	if (rc == -1)
   75.17 +	    return NULL;
   75.18 +	domain->port = rc;
   75.19  
   75.20  	domain->conn = new_connection(writechn, readchn);
   75.21  	domain->conn->domain = domain;
   75.22 @@ -426,10 +426,10 @@ void do_is_domain_introduced(struct conn
   75.23  	int result;
   75.24  	unsigned int domid;
   75.25  
   75.26 -        if (!domid_str) {
   75.27 -                send_error(conn, EINVAL);
   75.28 -                return;
   75.29 -        }
   75.30 +	if (!domid_str) {
   75.31 +		send_error(conn, EINVAL);
   75.32 +		return;
   75.33 +	}
   75.34  
   75.35  	domid = atoi(domid_str);
   75.36  	if (domid == DOMID_SELF)
   75.37 @@ -461,35 +461,45 @@ void restore_existing_connections(void)
   75.38  
   75.39  static int dom0_init(void) 
   75.40  { 
   75.41 -        int rc, fd;
   75.42 +	int rc, fd;
   75.43  	evtchn_port_t port; 
   75.44 -        unsigned long mfn; 
   75.45 -        char str[20]; 
   75.46 -        struct domain *dom0; 
   75.47 -        
   75.48 -        fd = open(XENSTORED_PROC_MFN, O_RDONLY); 
   75.49 -        
   75.50 -        rc = read(fd, str, sizeof(str)); 
   75.51 -        str[rc] = '\0'; 
   75.52 -        mfn = strtoul(str, NULL, 0); 
   75.53 -        
   75.54 -        close(fd); 
   75.55 -        
   75.56 -        fd = open(XENSTORED_PROC_PORT, O_RDONLY); 
   75.57 -        
   75.58 -        rc = read(fd, str, sizeof(str)); 
   75.59 -        str[rc] = '\0'; 
   75.60 -        port = strtoul(str, NULL, 0); 
   75.61 -        
   75.62 -        close(fd); 
   75.63 -        
   75.64 -        
   75.65 -        dom0 = new_domain(NULL, 0, mfn, port); 
   75.66 -        talloc_steal(dom0->conn, dom0); 
   75.67 +	unsigned long mfn; 
   75.68 +	char str[20]; 
   75.69 +	struct domain *dom0; 
   75.70 +
   75.71 +	fd = open(XENSTORED_PROC_MFN, O_RDONLY); 
   75.72 +	if (fd == -1)
   75.73 +		return -1;
   75.74 +
   75.75 +	rc = read(fd, str, sizeof(str)); 
   75.76 +	if (rc == -1)
   75.77 +		goto outfd;
   75.78 +	str[rc] = '\0'; 
   75.79 +	mfn = strtoul(str, NULL, 0); 
   75.80 +
   75.81 +	close(fd); 
   75.82  
   75.83 -        evtchn_notify(dom0->port); 
   75.84 +	fd = open(XENSTORED_PROC_PORT, O_RDONLY); 
   75.85 +	if (fd == -1)
   75.86 +		return -1;
   75.87 +
   75.88 +	rc = read(fd, str, sizeof(str)); 
   75.89 +	if (rc == -1)
   75.90 +		goto outfd;
   75.91 +	str[rc] = '\0'; 
   75.92 +	port = strtoul(str, NULL, 0); 
   75.93  
   75.94 -        return 0; 
   75.95 +	close(fd); 
   75.96 +
   75.97 +	dom0 = new_domain(NULL, 0, mfn, port); 
   75.98 +	talloc_steal(dom0->conn, dom0); 
   75.99 +
  75.100 +	evtchn_notify(dom0->port); 
  75.101 +
  75.102 +	return 0; 
  75.103 +outfd:
  75.104 +	close(fd);
  75.105 +	return -1;
  75.106  }
  75.107  
  75.108  
  75.109 @@ -539,9 +549,9 @@ int domain_init(void)
  75.110  	if (eventchn_fd < 0)
  75.111  		barf_perror("Failed to open evtchn device");
  75.112  
  75.113 -        if (dom0_init() != 0) 
  75.114 -                barf_perror("Failed to initialize dom0 state"); 
  75.115 -     
  75.116 +	if (dom0_init() != 0) 
  75.117 +		barf_perror("Failed to initialize dom0 state"); 
  75.118 +
  75.119  	bind.virq = VIRQ_DOM_EXC;
  75.120  	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
  75.121  	if (rc == -1)
    76.1 --- a/tools/xenstore/xs.c	Tue Jan 10 15:21:00 2006 +0000
    76.2 +++ b/tools/xenstore/xs.c	Tue Jan 24 17:54:34 2006 +0100
    76.3 @@ -292,7 +292,7 @@ static void *read_reply(
    76.4  }
    76.5  
    76.6  /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
    76.7 -static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t,
    76.8 +static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
    76.9  		      enum xsd_sockmsg_type type,
   76.10  		      const struct iovec *iovec,
   76.11  		      unsigned int num_vecs,
   76.12 @@ -304,7 +304,7 @@ static void *xs_talkv(struct xs_handle *
   76.13  	unsigned int i;
   76.14  	struct sigaction ignorepipe, oldact;
   76.15  
   76.16 -	msg.tx_id = (uint32_t)(unsigned long)t;
   76.17 +	msg.tx_id = t;
   76.18  	msg.req_id = 0;
   76.19  	msg.type = type;
   76.20  	msg.len = 0;
   76.21 @@ -368,7 +368,7 @@ static void free_no_errno(void *p)
   76.22  }
   76.23  
   76.24  /* Simplified version of xs_talkv: single message. */
   76.25 -static void *xs_single(struct xs_handle *h, struct xs_transaction_handle *t,
   76.26 +static void *xs_single(struct xs_handle *h, xs_transaction_t t,
   76.27  		       enum xsd_sockmsg_type type,
   76.28  		       const char *string,
   76.29  		       unsigned int *len)
   76.30 @@ -388,7 +388,7 @@ static bool xs_bool(char *reply)
   76.31  	return true;
   76.32  }
   76.33  
   76.34 -char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
   76.35 +char **xs_directory(struct xs_handle *h, xs_transaction_t t,
   76.36  		    const char *path, unsigned int *num)
   76.37  {
   76.38  	char *strings, *p, **ret;
   76.39 @@ -420,7 +420,7 @@ char **xs_directory(struct xs_handle *h,
   76.40   * Returns a malloced value: call free() on it after use.
   76.41   * len indicates length in bytes, not including the nul.
   76.42   */
   76.43 -void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
   76.44 +void *xs_read(struct xs_handle *h, xs_transaction_t t,
   76.45  	      const char *path, unsigned int *len)
   76.46  {
   76.47  	return xs_single(h, t, XS_READ, path, len);
   76.48 @@ -429,7 +429,7 @@ void *xs_read(struct xs_handle *h, struc
   76.49  /* Write the value of a single file.
   76.50   * Returns false on failure.
   76.51   */
   76.52 -bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
   76.53 +bool xs_write(struct xs_handle *h, xs_transaction_t t,
   76.54  	      const char *path, const void *data, unsigned int len)
   76.55  {
   76.56  	struct iovec iovec[2];
   76.57 @@ -446,7 +446,7 @@ bool xs_write(struct xs_handle *h, struc
   76.58  /* Create a new directory.
   76.59   * Returns false on failure, or success if it already exists.
   76.60   */
   76.61 -bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
   76.62 +bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
   76.63  	      const char *path)
   76.64  {
   76.65  	return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL));
   76.66 @@ -455,7 +455,7 @@ bool xs_mkdir(struct xs_handle *h, struc
   76.67  /* Destroy a file or directory (directories must be empty).
   76.68   * Returns false on failure, or success if it doesn't exist.
   76.69   */
   76.70 -bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
   76.71 +bool xs_rm(struct xs_handle *h, xs_transaction_t t,
   76.72  	   const char *path)
   76.73  {
   76.74  	return xs_bool(xs_single(h, t, XS_RM, path, NULL));
   76.75 @@ -465,7 +465,7 @@ bool xs_rm(struct xs_handle *h, struct x
   76.76   * Returns malloced array, or NULL: call free() after use.
   76.77   */
   76.78  struct xs_permissions *xs_get_permissions(struct xs_handle *h,
   76.79 -					  struct xs_transaction_handle *t,
   76.80 +					  xs_transaction_t t,
   76.81  					  const char *path, unsigned int *num)
   76.82  {
   76.83  	char *strings;
   76.84 @@ -499,7 +499,7 @@ struct xs_permissions *xs_get_permission
   76.85   * Returns false on failure.
   76.86   */
   76.87  bool xs_set_permissions(struct xs_handle *h,
   76.88 -			struct xs_transaction_handle *t,
   76.89 +			xs_transaction_t t,
   76.90  			const char *path,
   76.91  			struct xs_permissions *perms,
   76.92  			unsigned int num_perms)
   76.93 @@ -634,21 +634,21 @@ bool xs_unwatch(struct xs_handle *h, con
   76.94  /* Start a transaction: changes by others will not be seen during this
   76.95   * transaction, and changes will not be visible to others until end.
   76.96   * You can only have one transaction at any time.
   76.97 - * Returns NULL on failure.
   76.98 + * Returns XBT_NULL on failure.
   76.99   */
  76.100 -struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
  76.101 +xs_transaction_t xs_transaction_start(struct xs_handle *h)
  76.102  {
  76.103  	char *id_str;
  76.104 -	unsigned long id;
  76.105 +	xs_transaction_t id;
  76.106  
  76.107  	id_str = xs_single(h, XBT_NULL, XS_TRANSACTION_START, "", NULL);
  76.108  	if (id_str == NULL)
  76.109 -		return NULL;
  76.110 +		return XBT_NULL;
  76.111  
  76.112  	id = strtoul(id_str, NULL, 0);
  76.113  	free(id_str);
  76.114  
  76.115 -	return (struct xs_transaction_handle *)id;
  76.116 +	return id;
  76.117  }
  76.118  
  76.119  /* End a transaction.
  76.120 @@ -656,7 +656,7 @@ struct xs_transaction_handle *xs_transac
  76.121   * Returns false on failure, which indicates an error: transactions will
  76.122   * not fail spuriously.
  76.123   */
  76.124 -bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
  76.125 +bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
  76.126  			bool abort)
  76.127  {
  76.128  	char abortstr[2];
    77.1 --- a/tools/xenstore/xs.h	Tue Jan 10 15:21:00 2006 +0000
    77.2 +++ b/tools/xenstore/xs.h	Tue Jan 24 17:54:34 2006 +0100
    77.3 @@ -22,10 +22,10 @@
    77.4  
    77.5  #include <xs_lib.h>
    77.6  
    77.7 -#define XBT_NULL NULL
    77.8 +#define XBT_NULL 0
    77.9  
   77.10  struct xs_handle;
   77.11 -struct xs_transaction_handle;
   77.12 +typedef uint32_t xs_transaction_t;
   77.13  
   77.14  /* On failure, these routines set errno. */
   77.15  
   77.16 @@ -47,45 +47,45 @@ void xs_daemon_close(struct xs_handle *)
   77.17   * Returns a malloced array: call free() on it after use.
   77.18   * Num indicates size.
   77.19   */
   77.20 -char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
   77.21 +char **xs_directory(struct xs_handle *h, xs_transaction_t t,
   77.22  		    const char *path, unsigned int *num);
   77.23  
   77.24  /* Get the value of a single file, nul terminated.
   77.25   * Returns a malloced value: call free() on it after use.
   77.26   * len indicates length in bytes, not including terminator.
   77.27   */
   77.28 -void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
   77.29 +void *xs_read(struct xs_handle *h, xs_transaction_t t,
   77.30  	      const char *path, unsigned int *len);
   77.31  
   77.32  /* Write the value of a single file.
   77.33   * Returns false on failure.
   77.34   */
   77.35 -bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
   77.36 +bool xs_write(struct xs_handle *h, xs_transaction_t t,
   77.37  	      const char *path, const void *data, unsigned int len);
   77.38  
   77.39  /* Create a new directory.
   77.40   * Returns false on failure, or success if it already exists.
   77.41   */
   77.42 -bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
   77.43 +bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
   77.44  	      const char *path);
   77.45  
   77.46  /* Destroy a file or directory (and children).
   77.47   * Returns false on failure, or if it doesn't exist.
   77.48   */
   77.49 -bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
   77.50 +bool xs_rm(struct xs_handle *h, xs_transaction_t t,
   77.51  	   const char *path);
   77.52  
   77.53  /* Get permissions of node (first element is owner, first perms is "other").
   77.54   * Returns malloced array, or NULL: call free() after use.
   77.55   */
   77.56  struct xs_permissions *xs_get_permissions(struct xs_handle *h,
   77.57 -					  struct xs_transaction_handle *t,
   77.58 +					  xs_transaction_t t,
   77.59  					  const char *path, unsigned int *num);
   77.60  
   77.61  /* Set permissions of node (must be owner).
   77.62   * Returns false on failure.
   77.63   */
   77.64 -bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t,
   77.65 +bool xs_set_permissions(struct xs_handle *h, xs_transaction_t t,
   77.66  			const char *path, struct xs_permissions *perms,
   77.67  			unsigned int num_perms);
   77.68  
   77.69 @@ -115,14 +115,14 @@ bool xs_unwatch(struct xs_handle *h, con
   77.70   * You can only have one transaction at any time.
   77.71   * Returns NULL on failure.
   77.72   */
   77.73 -struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h);
   77.74 +xs_transaction_t xs_transaction_start(struct xs_handle *h);
   77.75  
   77.76  /* End a transaction.
   77.77   * If abandon is true, transaction is discarded instead of committed.
   77.78   * Returns false on failure: if errno == EAGAIN, you have to restart
   77.79   * transaction.
   77.80   */
   77.81 -bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
   77.82 +bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
   77.83  			bool abort);
   77.84  
   77.85  /* Introduce a new domain.
    78.1 --- a/tools/xenstore/xs_test.c	Tue Jan 10 15:21:00 2006 +0000
    78.2 +++ b/tools/xenstore/xs_test.c	Tue Jan 24 17:54:34 2006 +0100
    78.3 @@ -43,7 +43,7 @@
    78.4  #define XSTEST
    78.5  
    78.6  static struct xs_handle *handles[10] = { NULL };
    78.7 -static struct xs_transaction_handle *txh[10] = { XBT_NULL };
    78.8 +static xs_transaction_t txh[10] = { XBT_NULL };
    78.9  
   78.10  static unsigned int timeout_ms = 500;
   78.11  static bool timeout_suppressed = true;
   78.12 @@ -535,7 +535,7 @@ static void do_introduce(unsigned int ha
   78.13  	*(uint16_t *)((void *)interface + 36) = atoi(eventchn);
   78.14  
   78.15  	if (!xs_introduce_domain(handles[handle], atoi(domid),
   78.16 -				 atol(mfn), atoi(eventchn), path)) {
   78.17 +				 atol(mfn), atoi(eventchn))) {
   78.18  		failed(handle);
   78.19  		munmap(interface, getpagesize());
   78.20  		return;
    79.1 --- a/tools/xentrace/Makefile	Tue Jan 10 15:21:00 2006 +0000
    79.2 +++ b/tools/xentrace/Makefile	Tue Jan 24 17:54:34 2006 +0100
    79.3 @@ -33,14 +33,14 @@ build: $(BIN) $(LIBBIN)
    79.4  
    79.5  install: build
    79.6  	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
    79.7 -	[ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
    79.8 +	[ -z "$(LIBBIN)" ] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
    79.9  		$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
   79.10  	[ -d $(DESTDIR)/usr/share/man/man1 ] || \
   79.11  		$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1
   79.12  	[ -d $(DESTDIR)/usr/share/man/man8 ] || \
   79.13  		$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8
   79.14  	$(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
   79.15 -	[ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
   79.16 +	[ -z "$(LIBBIN)" ] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
   79.17  	$(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1
   79.18  	$(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8
   79.19  
    80.1 --- a/xen/arch/ia64/Makefile	Tue Jan 10 15:21:00 2006 +0000
    80.2 +++ b/xen/arch/ia64/Makefile	Tue Jan 24 17:54:34 2006 +0100
    80.3 @@ -23,6 +23,10 @@ OBJS +=	bitop.o clear_page.o flush.o cop
    80.4  	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o			\
    80.5  	__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
    80.6  
    80.7 +ifeq ($(crash_debug),y)
    80.8 +OBJS += gdbstub.o
    80.9 +endif
   80.10 +
   80.11  # xen stack unwinder
   80.12  # unwind_decoder.c is included in unwind.c
   80.13  OBJS += unwind.o
    81.1 --- a/xen/arch/ia64/Rules.mk	Tue Jan 10 15:21:00 2006 +0000
    81.2 +++ b/xen/arch/ia64/Rules.mk	Tue Jan 24 17:54:34 2006 +0100
    81.3 @@ -23,10 +23,10 @@ CFLAGS  += -I$(BASEDIR)/include/asm-ia64
    81.4             -I$(BASEDIR)/include/asm-ia64/linux-xen 			\
    81.5  	   -I$(BASEDIR)/include/asm-ia64/linux-null 			\
    81.6             -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
    81.7 -CFLAGS  += -Wno-pointer-arith -Wredundant-decls
    81.8 +#CFLAGS  += -Wno-pointer-arith -Wredundant-decls
    81.9  CFLAGS  += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
   81.10  CFLAGS	+= -ffixed-r13 -mfixed-range=f12-f15,f32-f127
   81.11 -CFLAGS	+= -w -g
   81.12 +CFLAGS	+= -g
   81.13  #CFLAGS  += -DVTI_DEBUG
   81.14  ifeq ($(VALIDATE_VT),y)
   81.15  CFLAGS  += -DVALIDATE_VT
    82.1 --- a/xen/arch/ia64/asm-offsets.c	Tue Jan 10 15:21:00 2006 +0000
    82.2 +++ b/xen/arch/ia64/asm-offsets.c	Tue Jan 24 17:54:34 2006 +0100
    82.3 @@ -15,7 +15,7 @@
    82.4  #define task_struct vcpu
    82.5  
    82.6  #define DEFINE(sym, val) \
    82.7 -        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
    82.8 +        asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
    82.9  
   82.10  #define BLANK() asm volatile("\n->" : : )
   82.11  
    83.1 --- a/xen/arch/ia64/asm-xsi-offsets.c	Tue Jan 10 15:21:00 2006 +0000
    83.2 +++ b/xen/arch/ia64/asm-xsi-offsets.c	Tue Jan 24 17:54:34 2006 +0100
    83.3 @@ -38,7 +38,7 @@
    83.4  #define task_struct vcpu
    83.5  
    83.6  #define DEFINE(sym, val) \
    83.7 -        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
    83.8 +        asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
    83.9  
   83.10  #define BLANK() asm volatile("\n->" : : )
   83.11  
    84.1 --- a/xen/arch/ia64/linux-xen/sal.c	Tue Jan 10 15:21:00 2006 +0000
    84.2 +++ b/xen/arch/ia64/linux-xen/sal.c	Tue Jan 24 17:54:34 2006 +0100
    84.3 @@ -16,6 +16,7 @@
    84.4  
    84.5  #ifdef XEN
    84.6  #include <linux/smp.h>
    84.7 +#include <xen/lib.h>
    84.8  #endif
    84.9  #include <asm/page.h>
   84.10  #include <asm/sal.h>
    85.1 --- a/xen/arch/ia64/linux-xen/smp.c	Tue Jan 10 15:21:00 2006 +0000
    85.2 +++ b/xen/arch/ia64/linux-xen/smp.c	Tue Jan 24 17:54:34 2006 +0100
    85.3 @@ -57,8 +57,21 @@
    85.4  void flush_tlb_mask(cpumask_t mask)
    85.5  {
    85.6  #ifdef CONFIG_SMP
    85.7 -    printf("flush_tlb_mask called, not implemented for SMP\n");
    85.8 -	dummy();
    85.9 +    int cpu;
   85.10 +
   85.11 +    cpu = smp_processor_id();
   85.12 +    if (cpu_isset (cpu, mask)) {
   85.13 +        cpu_clear(cpu, mask);
   85.14 +	local_flush_tlb_all ();
   85.15 +    }
   85.16 +
   85.17 +    if (cpus_empty(mask))
   85.18 +        return;
   85.19 +
   85.20 +    for (cpu = 0; cpu < NR_CPUS; ++cpu)
   85.21 +        if (cpu_isset(cpu, mask))
   85.22 +	   smp_call_function_single
   85.23 +	     (cpu, (void (*)(void *))local_flush_tlb_all, NULL, 1, 1);
   85.24  #endif
   85.25  }
   85.26  //#if CONFIG_SMP || IA64
    86.1 --- a/xen/arch/ia64/linux-xen/smpboot.c	Tue Jan 10 15:21:00 2006 +0000
    86.2 +++ b/xen/arch/ia64/linux-xen/smpboot.c	Tue Jan 24 17:54:34 2006 +0100
    86.3 @@ -64,6 +64,10 @@
    86.4  #ifdef XEN
    86.5  #include <asm/hw_irq.h>
    86.6  int ht_per_core = 1;
    86.7 +#ifndef CONFIG_SMP
    86.8 +cpumask_t cpu_online_map = CPU_MASK_CPU0;
    86.9 +EXPORT_SYMBOL(cpu_online_map);
   86.10 +#endif
   86.11  #endif
   86.12  
   86.13  #ifdef CONFIG_SMP /* ifdef XEN */
   86.14 @@ -482,9 +486,8 @@ do_rest:
   86.15  	struct vcpu *v;
   86.16  	void *stack;
   86.17  
   86.18 -	if ( (idle = do_createdomain(IDLE_DOMAIN_ID, cpu)) == NULL )
   86.19 -		panic("failed 'createdomain' for CPU %d", cpu);
   86.20 -	v = idle->vcpu[0];
   86.21 +	v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
   86.22 +	BUG_ON(v == NULL);
   86.23  
   86.24  	printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
   86.25  
    87.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Tue Jan 10 15:21:00 2006 +0000
    87.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Tue Jan 24 17:54:34 2006 +0100
    87.3 @@ -119,7 +119,7 @@ void vtm_init(VCPU *vcpu)
    87.4      itc_freq = local_cpu_data->itc_freq;
    87.5      vtm->cfg_max_jump=itc_freq*MAX_JUMP_STEP/1000;
    87.6      vtm->cfg_min_grun=itc_freq*MIN_GUEST_RUNNING_TIME/1000;
    87.7 -    init_ac_timer(&vtm->vtm_timer, vtm_timer_fn, vcpu, 0);
    87.8 +    init_timer(&vtm->vtm_timer, vtm_timer_fn, vcpu, 0);
    87.9      vtm_reset(vcpu);
   87.10  }
   87.11  
   87.12 @@ -163,20 +163,20 @@ void vtm_set_itv(VCPU *vcpu)
   87.13      local_irq_save(spsr);
   87.14      itv = VCPU(vcpu, itv);
   87.15      if ( ITV_IRQ_MASK(itv) )
   87.16 -        rem_ac_timer(&vtm->vtm_timer);
   87.17 +        stop_timer(&vtm->vtm_timer);
   87.18      vtm_interruption_update(vcpu, vtm);
   87.19      local_irq_restore(spsr);
   87.20  }
   87.21  
   87.22  
   87.23  /*
   87.24 - * Update interrupt or hook the vtm ac_timer for fire 
   87.25 + * Update interrupt or hook the vtm timer for fire 
   87.26   * At this point vtm_timer should be removed if itv is masked.
   87.27   */
   87.28  /* Interrupt must be disabled at this point */
   87.29  
   87.30  extern u64 cycle_to_ns(u64 cyle);
   87.31 -#define TIMER_SLOP (50*1000) /* ns */  /* copy from ac_timer.c */
   87.32 +#define TIMER_SLOP (50*1000) /* ns */  /* copy from timer.c */
   87.33  void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm)
   87.34  {
   87.35      uint64_t    cur_itc,vitm,vitv;
   87.36 @@ -198,7 +198,7 @@ void vtm_interruption_update(VCPU *vcpu,
   87.37      
   87.38      if ( diff_last >= 0 ) {
   87.39          // interrupt already fired.
   87.40 -        rem_ac_timer(&vtm->vtm_timer);
   87.41 +        stop_timer(&vtm->vtm_timer);
   87.42      }
   87.43      else if ( diff_now >= 0 ) {
   87.44          // ITV is fired.
   87.45 @@ -207,24 +207,24 @@ void vtm_interruption_update(VCPU *vcpu,
   87.46      /* Both last_itc & cur_itc < itm, wait for fire condition */
   87.47      else {
   87.48          expires = NOW() + cycle_to_ns(0-diff_now) + TIMER_SLOP;
   87.49 -        set_ac_timer(&vtm->vtm_timer, expires);
   87.50 +        set_timer(&vtm->vtm_timer, expires);
   87.51      }
   87.52      local_irq_restore(spsr);
   87.53  }
   87.54  
   87.55  /*
   87.56   * Action for vtm when the domain is scheduled out.
   87.57 - * Remove the ac_timer for vtm.
   87.58 + * Remove the timer for vtm.
   87.59   */
   87.60  void vtm_domain_out(VCPU *vcpu)
   87.61  {
   87.62      if(!is_idle_domain(vcpu->domain))
   87.63 -	rem_ac_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
   87.64 +	stop_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
   87.65  }
   87.66  
   87.67  /*
   87.68   * Action for vtm when the domain is scheduled in.
   87.69 - * Fire vtm IRQ or add the ac_timer for vtm.
   87.70 + * Fire vtm IRQ or add the timer for vtm.
   87.71   */
   87.72  void vtm_domain_in(VCPU *vcpu)
   87.73  {
    88.1 --- a/xen/arch/ia64/vmx/vmx_process.c	Tue Jan 10 15:21:00 2006 +0000
    88.2 +++ b/xen/arch/ia64/vmx/vmx_process.c	Tue Jan 24 17:54:34 2006 +0100
    88.3 @@ -41,6 +41,7 @@
    88.4  #include <asm/regionreg.h>
    88.5  #include <asm/privop.h>
    88.6  #include <asm/ia64_int.h>
    88.7 +#include <asm/debugger.h>
    88.8  //#include <asm/hpsim_ssc.h>
    88.9  #include <asm/dom_fw.h>
   88.10  #include <asm/vmx_vcpu.h>
   88.11 @@ -108,6 +109,14 @@ vmx_ia64_handle_break (unsigned long ifa
   88.12  		else do_ssc(vcpu_get_gr_nat(current,36), regs);
   88.13  	}
   88.14  #endif
   88.15 +#ifdef CRASH_DEBUG
   88.16 +	if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
   88.17 +        IS_VMM_ADDRESS(regs->cr_iip)) {
   88.18 +		if (iim == 0)
   88.19 +			show_registers(regs);
   88.20 +		debugger_trap_fatal(0 /* don't care */, regs);
   88.21 +	} else
   88.22 +#endif
   88.23  	if (iim == d->arch.breakimm) {
   88.24  		struct ia64_pal_retval y;
   88.25  		struct sal_ret_values x;
    89.1 --- a/xen/arch/ia64/xen/domain.c	Tue Jan 10 15:21:00 2006 +0000
    89.2 +++ b/xen/arch/ia64/xen/domain.c	Tue Jan 24 17:54:34 2006 +0100
    89.3 @@ -65,12 +65,14 @@ extern int readelfimage_base_and_size(ch
    89.4  
    89.5  unsigned long map_domain_page0(struct domain *);
    89.6  extern unsigned long dom_fw_setup(struct domain *, char *, int);
    89.7 +static void init_switch_stack(struct vcpu *v);
    89.8  
    89.9  /* this belongs in include/asm, but there doesn't seem to be a suitable place */
   89.10 -void free_perdomain_pt(struct domain *d)
   89.11 +void arch_domain_destroy(struct domain *d)
   89.12  {
   89.13 -	printf("free_perdomain_pt: not implemented\n");
   89.14 +	printf("arch_domain_destroy: not implemented\n");
   89.15  	//free_page((unsigned long)d->mm.perdomain_pt);
   89.16 +	free_xenheap_page(d->shared_info);
   89.17  }
   89.18  
   89.19  static void default_idle(void)
   89.20 @@ -87,7 +89,6 @@ static void continue_cpu_idle_loop(void)
   89.21  	int cpu = smp_processor_id();
   89.22  	for ( ; ; )
   89.23  	{
   89.24 -	printf ("idle%dD\n", cpu);
   89.25  #ifdef IA64
   89.26  //        __IRQ_STAT(cpu, idle_timestamp) = jiffies
   89.27  #else
   89.28 @@ -145,16 +146,45 @@ void startup_cpu_idle_loop(void)
   89.29  struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
   89.30  {
   89.31  	struct vcpu *v;
   89.32 +	struct thread_info *ti;
   89.33  
   89.34 -	if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
   89.35 +	/* Still keep idle vcpu0 static allocated at compilation, due
   89.36 +	 * to some code from Linux still requires it in early phase.
   89.37 +	 */
   89.38 +	if (is_idle_domain(d) && !vcpu_id)
   89.39 +	    v = idle_vcpu[0];
   89.40 +	else {
   89.41 +	    if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
   89.42  		return NULL;
   89.43 +	    memset(v, 0, sizeof(*v)); 
   89.44 +	}
   89.45 +
   89.46 +	ti = alloc_thread_info(v);
   89.47 +	/* Clear thread_info to clear some important fields, like
   89.48 +	 * preempt_count
   89.49 +	 */
   89.50 +	memset(ti, 0, sizeof(struct thread_info));
   89.51 +	init_switch_stack(v);
   89.52  
   89.53 -	memset(v, 0, sizeof(*v)); 
   89.54 -        memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch));
   89.55 -	v->arch.privregs = 
   89.56 +	if (!is_idle_domain(d)) {
   89.57 +	    v->arch.privregs = 
   89.58  		alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
   89.59 -	printf("arch_vcpu_info=%p\n", v->arch.privregs);
   89.60 -	memset(v->arch.privregs, 0, PAGE_SIZE);
   89.61 +	    BUG_ON(v->arch.privregs == NULL);
   89.62 +	    memset(v->arch.privregs, 0, PAGE_SIZE);
   89.63 +
   89.64 +	    if (!vcpu_id)
   89.65 +	    	memset(&d->shared_info->evtchn_mask[0], 0xff,
   89.66 +		    sizeof(d->shared_info->evtchn_mask));
   89.67 +
   89.68 +	    v->vcpu_info = &(d->shared_info->vcpu_info[0]);
   89.69 +	    v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
   89.70 +	    v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
   89.71 +	    v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
   89.72 +	    v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
   89.73 +	    v->arch.starting_rid = d->arch.starting_rid;
   89.74 +	    v->arch.ending_rid = d->arch.ending_rid;
   89.75 +	    v->arch.breakimm = d->arch.breakimm;
   89.76 +	}
   89.77  
   89.78  	return v;
   89.79  }
   89.80 @@ -182,34 +212,21 @@ static void init_switch_stack(struct vcp
   89.81  	memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
   89.82  }
   89.83  
   89.84 -int arch_do_createdomain(struct vcpu *v)
   89.85 +int arch_domain_create(struct domain *d)
   89.86  {
   89.87 -	struct domain *d = v->domain;
   89.88 -	struct thread_info *ti = alloc_thread_info(v);
   89.89 -
   89.90 -	/* Clear thread_info to clear some important fields, like preempt_count */
   89.91 -	memset(ti, 0, sizeof(struct thread_info));
   89.92 -	init_switch_stack(v);
   89.93 +	// the following will eventually need to be negotiated dynamically
   89.94 +	d->xen_vastart = XEN_START_ADDR;
   89.95 +	d->xen_vaend = XEN_END_ADDR;
   89.96 +	d->shared_info_va = SHAREDINFO_ADDR;
   89.97  
   89.98 -	d->shared_info = (void *)alloc_xenheap_page();
   89.99 -	if (!d->shared_info) {
  89.100 -   		printk("ERROR/HALTING: CAN'T ALLOC PAGE\n");
  89.101 -   		while (1);
  89.102 -	}
  89.103 +	if (is_idle_domain(d))
  89.104 +	    return 0;
  89.105 +
  89.106 +	if ((d->shared_info = (void *)alloc_xenheap_page()) == NULL)
  89.107 +	    goto fail_nomem;
  89.108  	memset(d->shared_info, 0, PAGE_SIZE);
  89.109 -	if (v == d->vcpu[0])
  89.110 -	    memset(&d->shared_info->evtchn_mask[0], 0xff,
  89.111 -		sizeof(d->shared_info->evtchn_mask));
  89.112 -#if 0
  89.113 -	d->vcpu[0].arch.privregs = 
  89.114 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
  89.115 -	printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
  89.116 -	memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
  89.117 -#endif
  89.118 -	v->vcpu_info = &(d->shared_info->vcpu_info[0]);
  89.119  
  89.120  	d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
  89.121 -
  89.122  	/* We may also need emulation rid for region4, though it's unlikely
  89.123  	 * to see guest issue uncacheable access in metaphysical mode. But
  89.124  	 * keep such info here may be more sane.
  89.125 @@ -217,41 +234,27 @@ int arch_do_createdomain(struct vcpu *v)
  89.126  	if (((d->arch.metaphysical_rr0 = allocate_metaphysical_rr()) == -1UL)
  89.127  	 || ((d->arch.metaphysical_rr4 = allocate_metaphysical_rr()) == -1UL))
  89.128  		BUG();
  89.129 -//	VCPU(v, metaphysical_mode) = 1;
  89.130 -	v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
  89.131 -	v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
  89.132 -	v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
  89.133 -	v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
  89.134  #define DOMAIN_RID_BITS_DEFAULT 18
  89.135  	if (!allocate_rid_range(d,DOMAIN_RID_BITS_DEFAULT)) // FIXME
  89.136  		BUG();
  89.137 -	v->arch.starting_rid = d->arch.starting_rid;
  89.138 -	v->arch.ending_rid = d->arch.ending_rid;
  89.139 -	// the following will eventually need to be negotiated dynamically
  89.140 -	d->xen_vastart = XEN_START_ADDR;
  89.141 -	d->xen_vaend = XEN_END_ADDR;
  89.142 -	d->shared_info_va = SHAREDINFO_ADDR;
  89.143  	d->arch.breakimm = 0x1000;
  89.144 -	v->arch.breakimm = d->arch.breakimm;
  89.145 -
  89.146  	d->arch.sys_pgnr = 0;
  89.147 -	if (d->domain_id != IDLE_DOMAIN_ID) {
  89.148 -		d->arch.mm = xmalloc(struct mm_struct);
  89.149 -		if (unlikely(!d->arch.mm)) {
  89.150 -			printk("Can't allocate mm_struct for domain %d\n",d->domain_id);
  89.151 -			return -ENOMEM;
  89.152 -		}
  89.153 -		memset(d->arch.mm, 0, sizeof(*d->arch.mm));
  89.154 -		d->arch.mm->pgd = pgd_alloc(d->arch.mm);
  89.155 -		if (unlikely(!d->arch.mm->pgd)) {
  89.156 -			printk("Can't allocate pgd for domain %d\n",d->domain_id);
  89.157 -			return -ENOMEM;
  89.158 -		}
  89.159 -	} else
  89.160 - 		d->arch.mm = NULL;
  89.161 -	printf ("arch_do_create_domain: domain=%p\n", d);
  89.162 +
  89.163 +	if ((d->arch.mm = xmalloc(struct mm_struct)) == NULL)
  89.164 +	    goto fail_nomem;
  89.165 +	memset(d->arch.mm, 0, sizeof(*d->arch.mm));
  89.166 +
  89.167 +	if ((d->arch.mm->pgd = pgd_alloc(d->arch.mm)) == NULL)
  89.168 +	    goto fail_nomem;
  89.169  
  89.170 +	printf ("arch_domain_create: domain=%p\n", d);
  89.171  	return 0;
  89.172 +
  89.173 +fail_nomem:
  89.174 +	free_xenheap_page(d->shared_info);
  89.175 +	xfree(d->arch.mm);
  89.176 +	pgd_free(d->arch.mm->pgd);
  89.177 +	return -ENOMEM;
  89.178  }
  89.179  
  89.180  void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/xen/arch/ia64/xen/gdbstub.c	Tue Jan 24 17:54:34 2006 +0100
    90.3 @@ -0,0 +1,811 @@
    90.4 +/*
    90.5 + * ia64-specific cdb routines
    90.6 + * cdb xen/ia64 by Isaku Yamahta <yamahata at valinux co jp>
    90.7 + *                 VA Linux Systems Japan K.K.
    90.8 + *  some routines are stolen from kgdb/ia64.
    90.9 + */
   90.10 +/*
   90.11 + *
   90.12 + * This program is free software; you can redistribute it and/or modify it
   90.13 + * under the terms of the GNU General Public License as published by the
   90.14 + * Free Software Foundation; either version 2, or (at your option) any
   90.15 + * later version.
   90.16 + *
   90.17 + * This program is distributed in the hope that it will be useful, but
   90.18 + * WITHOUT ANY WARRANTY; without even the implied warranty of
   90.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   90.20 + * General Public License for more details.
   90.21 + *
   90.22 + */
   90.23 +
   90.24 +/*
   90.25 + * Copyright (C) 2000-2001 VERITAS Software Corporation.
   90.26 + */
   90.27 +/*
   90.28 + *  Contributor:     Lake Stevens Instrument Division$
   90.29 + *  Written by:      Glenn Engel $
   90.30 + *  Updated by:	     Amit Kale<akale@veritas.com>
   90.31 + *  Modified for 386 by Jim Kingdon, Cygnus Support.
   90.32 + *  Origianl kgdb, compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
   90.33 + *
   90.34 + */
   90.35 +
   90.36 +
   90.37 +#include <xen/lib.h>
   90.38 +#include <asm/byteorder.h>
   90.39 +#include <asm/debugger.h>
   90.40 +#include <asm/uaccess.h>
   90.41 +
   90.42 +#define USE_UNWIND
   90.43 +
   90.44 +#ifdef USE_UNWIND
   90.45 +#include <asm/unwind.h>
   90.46 +#endif
   90.47 +
   90.48 +/* Printk isn't particularly safe just after we've trapped to the
   90.49 +   debugger. so avoid it. */
   90.50 +#define dbg_printk(...)
   90.51 +//#define dbg_printk(...)	printk(__VA_ARGS__)
   90.52 +
   90.53 +u16
   90.54 +gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
   90.55 +{
   90.56 +    /* XXX */
   90.57 +    return 1;
   90.58 +}
   90.59 +
   90.60 +void 
   90.61 +gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
   90.62 +{
   90.63 +    gdb_send_reply("", ctx);
   90.64 +}
   90.65 +
   90.66 +void 
   90.67 +gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
   90.68 +                         struct gdb_context *ctx)
   90.69 +{
   90.70 +    /* XXX TODO */
   90.71 +    gdb_send_reply("E02", ctx);
   90.72 +}
   90.73 +
   90.74 +/* Like copy_from_user, but safe to call with interrupts disabled.
   90.75 +   Trust me, and don't look behind the curtain. */
   90.76 +unsigned
   90.77 +gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
   90.78 +{
   90.79 +	int val;
   90.80 +	__asm__ __volatile__(
   90.81 +		"cmp4.eq p6, p0 = r0, %1\n"
   90.82 +		"(p6) br.cond.dptk 2f\n"
   90.83 +		"[1:]\n"
   90.84 +		".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
   90.85 +		"[99:] ld1 %0 = [%3], 1\n"
   90.86 +		";;\n"
   90.87 +		".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
   90.88 +		"[99:] st1 [%2] = %0, 1\n"
   90.89 +		"adds %1 = -1, %1\n"
   90.90 +		";;\n"
   90.91 +		"cmp4.eq p0, p6 = r0, %1\n"
   90.92 +		"(p6) br.cond.dptk 1b\n"
   90.93 +		"[2:]\n"
   90.94 +		: "=r"(val), "=r"(len), "=r"(dest), "=r"(src)
   90.95 +		:  "1"(len), "2"(dest), "3"(src)
   90.96 +		: "memory", "p6");
   90.97 +	return len;
   90.98 +}
   90.99 +
  90.100 +unsigned int 
  90.101 +gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
  90.102 +{
  90.103 +    /* XXX  */
  90.104 +    return len;
  90.105 +}
  90.106 +
  90.107 +#define NUM_REGS 590
  90.108 +#define REGISTER_BYTES (NUM_REGS*8+128*8)
  90.109 +#define REGISTER_BYTE(N) (((N) * 8)									\
  90.110 +	+ ((N) <= IA64_FR0_REGNUM ?                                     \
  90.111 +	0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
  90.112 +#define REGISTER_SIZE(N)                                               \
  90.113 +	(((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
  90.114 +#define IA64_GR0_REGNUM         0
  90.115 +#define IA64_FR0_REGNUM         128
  90.116 +#define IA64_FR127_REGNUM       (IA64_FR0_REGNUM+127)
  90.117 +#define IA64_PR0_REGNUM         256
  90.118 +#define IA64_BR0_REGNUM         320
  90.119 +#define IA64_VFP_REGNUM         328
  90.120 +#define IA64_PR_REGNUM          330
  90.121 +#define IA64_IP_REGNUM          331
  90.122 +#define IA64_PSR_REGNUM         332
  90.123 +#define IA64_CFM_REGNUM         333
  90.124 +#define IA64_AR0_REGNUM         334
  90.125 +#define IA64_NAT0_REGNUM        462
  90.126 +#define IA64_NAT31_REGNUM       (IA64_NAT0_REGNUM+31)
  90.127 +#define IA64_NAT32_REGNUM       (IA64_NAT0_REGNUM+32)
  90.128 +#define IA64_RSC_REGNUM			(IA64_AR0_REGNUM+16)
  90.129 +#define IA64_BSP_REGNUM			(IA64_AR0_REGNUM+17)
  90.130 +#define IA64_BSPSTORE_REGNUM	(IA64_AR0_REGNUM+18)
  90.131 +#define IA64_RNAT_REGNUM		(IA64_AR0_REGNUM+19)
  90.132 +#define IA64_FCR_REGNUM			(IA64_AR0_REGNUM+21)
  90.133 +#define IA64_EFLAG_REGNUM		(IA64_AR0_REGNUM+24)
  90.134 +#define IA64_CSD_REGNUM			(IA64_AR0_REGNUM+25)
  90.135 +#define IA64_SSD_REGNUM			(IA64_AR0_REGNUM+26)
  90.136 +#define IA64_CFLG_REGNUM		(IA64_AR0_REGNUM+27)
  90.137 +#define IA64_FSR_REGNUM			(IA64_AR0_REGNUM+28)
  90.138 +#define IA64_FIR_REGNUM			(IA64_AR0_REGNUM+29)
  90.139 +#define IA64_FDR_REGNUM			(IA64_AR0_REGNUM+30)
  90.140 +#define IA64_CCV_REGNUM			(IA64_AR0_REGNUM+32)
  90.141 +#define IA64_UNAT_REGNUM		(IA64_AR0_REGNUM+36)
  90.142 +#define IA64_FPSR_REGNUM		(IA64_AR0_REGNUM+40)
  90.143 +#define IA64_ITC_REGNUM			(IA64_AR0_REGNUM+44)
  90.144 +#define IA64_PFS_REGNUM			(IA64_AR0_REGNUM+64)
  90.145 +#define IA64_LC_REGNUM			(IA64_AR0_REGNUM+65)
  90.146 +#define IA64_EC_REGNUM			(IA64_AR0_REGNUM+66)
  90.147 +
  90.148 +#ifndef USE_UNWIND
  90.149 +struct regs_to_cpu_user_resgs_index {
  90.150 +	unsigned int reg;
  90.151 +	unsigned int ptregoff;
  90.152 +};
  90.153 +
  90.154 +#define ptoff(V)		((unsigned int)&((struct cpu_user_regs*)0x0)->V)
  90.155 +
  90.156 +// gr
  90.157 +static const struct regs_to_cpu_user_resgs_index
  90.158 +gr_reg_to_cpu_user_regs_index[] = {
  90.159 +	{IA64_GR0_REGNUM + 8,  ptoff(r8)},
  90.160 +	{IA64_GR0_REGNUM + 9,  ptoff(r9)},
  90.161 +	{IA64_GR0_REGNUM + 10, ptoff(r10)},
  90.162 +	{IA64_GR0_REGNUM + 11, ptoff(r11)},
  90.163 +	{IA64_GR0_REGNUM + 1,  ptoff(r1)},
  90.164 +	{IA64_GR0_REGNUM + 12, ptoff(r12)},
  90.165 +	{IA64_GR0_REGNUM + 13, ptoff(r13)},
  90.166 +	{IA64_GR0_REGNUM + 15, ptoff(r15)},
  90.167 +
  90.168 +	{IA64_GR0_REGNUM + 14, ptoff(r14)},
  90.169 +	{IA64_GR0_REGNUM + 2,  ptoff(r2)},
  90.170 +	{IA64_GR0_REGNUM + 3,  ptoff(r3)},
  90.171 +	{IA64_GR0_REGNUM + 16, ptoff(r16)},
  90.172 +	{IA64_GR0_REGNUM + 17, ptoff(r17)},
  90.173 +	{IA64_GR0_REGNUM + 18, ptoff(r18)},
  90.174 +	{IA64_GR0_REGNUM + 19, ptoff(r19)},
  90.175 +	{IA64_GR0_REGNUM + 20, ptoff(r20)},
  90.176 +	{IA64_GR0_REGNUM + 21, ptoff(r21)},
  90.177 +	{IA64_GR0_REGNUM + 22, ptoff(r22)},
  90.178 +	{IA64_GR0_REGNUM + 23, ptoff(r23)},
  90.179 +	{IA64_GR0_REGNUM + 24, ptoff(r24)},
  90.180 +	{IA64_GR0_REGNUM + 25, ptoff(r25)},
  90.181 +	{IA64_GR0_REGNUM + 26, ptoff(r26)},
  90.182 +	{IA64_GR0_REGNUM + 27, ptoff(r27)},
  90.183 +	{IA64_GR0_REGNUM + 28, ptoff(r28)},
  90.184 +	{IA64_GR0_REGNUM + 29, ptoff(r29)},
  90.185 +	{IA64_GR0_REGNUM + 30, ptoff(r30)},
  90.186 +	{IA64_GR0_REGNUM + 31, ptoff(r31)},
  90.187 +
  90.188 +	{IA64_GR0_REGNUM + 4,  ptoff(r4)},
  90.189 +	{IA64_GR0_REGNUM + 5,  ptoff(r5)},
  90.190 +	{IA64_GR0_REGNUM + 6,  ptoff(r6)},
  90.191 +	{IA64_GR0_REGNUM + 7,  ptoff(r7)},
  90.192 +};
  90.193 +static const int gr_reg_to_cpu_user_regs_index_max =
  90.194 +	sizeof(gr_reg_to_cpu_user_regs_index) /
  90.195 +	sizeof(gr_reg_to_cpu_user_regs_index[0]); 
  90.196 +
  90.197 +// br
  90.198 +static const struct regs_to_cpu_user_resgs_index
  90.199 +br_reg_to_cpu_user_regs_index[] = {
  90.200 +	{IA64_BR0_REGNUM + 0, ptoff(b0)},
  90.201 +	{IA64_BR0_REGNUM + 6, ptoff(b6)},
  90.202 +	{IA64_BR0_REGNUM + 7, ptoff(b7)},
  90.203 +};
  90.204 +static const int br_reg_to_cpu_user_regs_index_max =
  90.205 +	sizeof(br_reg_to_cpu_user_regs_index) /
  90.206 +	sizeof(br_reg_to_cpu_user_regs_index[0]); 
  90.207 +
  90.208 +// f
  90.209 +static const struct regs_to_cpu_user_resgs_index
  90.210 +fr_reg_to_cpu_user_regs_index[] = {
  90.211 +	{IA64_FR0_REGNUM + 6,  ptoff(f6)},
  90.212 +	{IA64_FR0_REGNUM + 7,  ptoff(f7)},
  90.213 +	{IA64_FR0_REGNUM + 8,  ptoff(f8)},
  90.214 +	{IA64_FR0_REGNUM + 9,  ptoff(f9)},
  90.215 +	{IA64_FR0_REGNUM + 10, ptoff(f10)},
  90.216 +	{IA64_FR0_REGNUM + 11, ptoff(f11)},
  90.217 +};
  90.218 +static const int fr_reg_to_cpu_user_regs_index_max =
  90.219 +	sizeof(fr_reg_to_cpu_user_regs_index) /
  90.220 +	sizeof(fr_reg_to_cpu_user_regs_index[0]); 
  90.221 +	
  90.222 +
  90.223 +void 
  90.224 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
  90.225 +                  struct gdb_context *ctx)
  90.226 +{
  90.227 +	unsigned long reg = IA64_IP_REGNUM;
  90.228 +	char buf[9];
  90.229 +	int i;
  90.230 +
  90.231 +	dbg_printk("Register read regnum = 0x%lx\n", regnum);
  90.232 +	if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) {
  90.233 +		for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) {
  90.234 +			if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) {
  90.235 +				reg = *(unsigned long*)(((char*)regs) + gr_reg_to_cpu_user_regs_index[i].ptregoff);
  90.236 +				break;
  90.237 +			}
  90.238 +		}
  90.239 +		if (i == gr_reg_to_cpu_user_regs_index_max) {
  90.240 +			goto out_err;
  90.241 +		}
  90.242 +	} else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) {
  90.243 +		for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) {
  90.244 +			if (br_reg_to_cpu_user_regs_index[i].reg == regnum) {
  90.245 +				reg = *(unsigned long*)(((char*)regs) + br_reg_to_cpu_user_regs_index[i].ptregoff);
  90.246 +				break;
  90.247 +			}
  90.248 +		}
  90.249 +		if (i == br_reg_to_cpu_user_regs_index_max) {
  90.250 +			goto out_err;
  90.251 +		}
  90.252 +	} else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM + 11) {
  90.253 +		for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) {
  90.254 +			if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) {
  90.255 +				reg = *(unsigned long*)(((char*)regs) + fr_reg_to_cpu_user_regs_index[i].ptregoff);
  90.256 +				break;
  90.257 +			}
  90.258 +		}
  90.259 +		if (i == fr_reg_to_cpu_user_regs_index_max) {
  90.260 +			goto out_err;
  90.261 +		}
  90.262 +	} else if (regnum == IA64_CSD_REGNUM) {
  90.263 +		reg = regs->ar_csd;
  90.264 +	} else if (regnum == IA64_SSD_REGNUM) {
  90.265 +		reg = regs->ar_ssd;
  90.266 +	} else if (regnum == IA64_PSR_REGNUM) {
  90.267 +		reg = regs->cr_ipsr;
  90.268 +	} else if (regnum == IA64_IP_REGNUM) {
  90.269 +		reg = regs->cr_iip;
  90.270 +	} else if (regnum == IA64_CFM_REGNUM) {
  90.271 +		reg = regs->cr_ifs;
  90.272 +	} else if (regnum == IA64_UNAT_REGNUM) {
  90.273 +		reg = regs->ar_unat;
  90.274 +	} else if (regnum == IA64_PFS_REGNUM) {
  90.275 +		reg = regs->ar_pfs;
  90.276 +	} else if (regnum == IA64_RSC_REGNUM) {
  90.277 +		reg = regs->ar_rsc;
  90.278 +	} else if (regnum == IA64_RNAT_REGNUM) {
  90.279 +		reg = regs->ar_rnat;
  90.280 +	} else if (regnum == IA64_BSPSTORE_REGNUM) {
  90.281 +		reg = regs->ar_bspstore;
  90.282 +	} else if (regnum == IA64_PR_REGNUM) {
  90.283 +		reg = regs->pr;
  90.284 +	} else if (regnum == IA64_FPSR_REGNUM) {
  90.285 +		reg = regs->ar_fpsr;
  90.286 +	} else if (regnum == IA64_CCV_REGNUM) {
  90.287 +		reg = regs->ar_ccv;
  90.288 +	} else {
  90.289 +		// emul_unat, rfi_pfs
  90.290 +		goto out_err;
  90.291 +	}
  90.292 +
  90.293 +	dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg);	
  90.294 +	sprintf(buf, "%.08lx", swab64(reg));
  90.295 +out:
  90.296 +	return gdb_send_reply(buf, ctx);
  90.297 +
  90.298 +out_err:
  90.299 +	dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
  90.300 +	sprintf(buf, "%s", "x");
  90.301 +	goto out;
  90.302 +}
  90.303 +#else
  90.304 +
  90.305 +#define	ptoff(V)	((unsigned int) &((struct pt_regs *)0x0)->V)
  90.306 +struct reg_to_ptreg_index {
  90.307 +	unsigned int reg;
  90.308 +	unsigned int ptregoff;
  90.309 +};
  90.310 +
  90.311 +static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
  90.312 +	{IA64_GR0_REGNUM + 1, ptoff(r1)},
  90.313 +	{IA64_GR0_REGNUM + 2, ptoff(r2)},
  90.314 +	{IA64_GR0_REGNUM + 3, ptoff(r3)},
  90.315 +	{IA64_GR0_REGNUM + 8, ptoff(r8)},
  90.316 +	{IA64_GR0_REGNUM + 9, ptoff(r9)},
  90.317 +	{IA64_GR0_REGNUM + 10, ptoff(r10)},
  90.318 +	{IA64_GR0_REGNUM + 11, ptoff(r11)},
  90.319 +	{IA64_GR0_REGNUM + 12, ptoff(r12)},
  90.320 +	{IA64_GR0_REGNUM + 13, ptoff(r13)},
  90.321 +	{IA64_GR0_REGNUM + 14, ptoff(r14)},
  90.322 +	{IA64_GR0_REGNUM + 15, ptoff(r15)},
  90.323 +	{IA64_GR0_REGNUM + 16, ptoff(r16)},
  90.324 +	{IA64_GR0_REGNUM + 17, ptoff(r17)},
  90.325 +	{IA64_GR0_REGNUM + 18, ptoff(r18)},
  90.326 +	{IA64_GR0_REGNUM + 19, ptoff(r19)},
  90.327 +	{IA64_GR0_REGNUM + 20, ptoff(r20)},
  90.328 +	{IA64_GR0_REGNUM + 21, ptoff(r21)},
  90.329 +	{IA64_GR0_REGNUM + 22, ptoff(r22)},
  90.330 +	{IA64_GR0_REGNUM + 23, ptoff(r23)},
  90.331 +	{IA64_GR0_REGNUM + 24, ptoff(r24)},
  90.332 +	{IA64_GR0_REGNUM + 25, ptoff(r25)},
  90.333 +	{IA64_GR0_REGNUM + 26, ptoff(r26)},
  90.334 +	{IA64_GR0_REGNUM + 27, ptoff(r27)},
  90.335 +	{IA64_GR0_REGNUM + 28, ptoff(r28)},
  90.336 +	{IA64_GR0_REGNUM + 29, ptoff(r29)},
  90.337 +	{IA64_GR0_REGNUM + 30, ptoff(r30)},
  90.338 +	{IA64_GR0_REGNUM + 31, ptoff(r31)},
  90.339 +};
  90.340 +
  90.341 +static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
  90.342 +	{IA64_BR0_REGNUM, ptoff(b0)},
  90.343 +	{IA64_BR0_REGNUM + 6, ptoff(b6)},
  90.344 +	{IA64_BR0_REGNUM + 7, ptoff(b7)},
  90.345 +};
  90.346 +
  90.347 +static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = {
  90.348 +	{IA64_PFS_REGNUM, ptoff(ar_pfs)},
  90.349 +	{IA64_UNAT_REGNUM, ptoff(ar_unat)},
  90.350 +	{IA64_RNAT_REGNUM, ptoff(ar_rnat)},
  90.351 +	{IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)},
  90.352 +	{IA64_RSC_REGNUM, ptoff(ar_rsc)},
  90.353 +	{IA64_CSD_REGNUM, ptoff(ar_csd)},
  90.354 +	{IA64_SSD_REGNUM, ptoff(ar_ssd)},
  90.355 +	{IA64_FPSR_REGNUM, ptoff(ar_fpsr)},
  90.356 +	{IA64_CCV_REGNUM, ptoff(ar_ccv)},
  90.357 +};
  90.358 +
  90.359 +#ifndef XEN
  90.360 +extern atomic_t cpu_doing_single_step;
  90.361 +#endif
  90.362 +
  90.363 +static int kgdb_gr_reg(int regnum, struct unw_frame_info *info,
  90.364 +	unsigned long *reg, int rw)
  90.365 +{
  90.366 +	char nat;
  90.367 +
  90.368 +	if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
  90.369 +		(regnum >= (IA64_GR0_REGNUM + 4) &&
  90.370 +		regnum <= (IA64_GR0_REGNUM + 7)))
  90.371 +		return !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
  90.372 +		reg, &nat, rw);
  90.373 +	else
  90.374 +		return 0;
  90.375 +}
  90.376 +static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs,
  90.377 +	struct unw_frame_info *info, unsigned long *reg, int rw)
  90.378 +{
  90.379 +	int i, result = 1;
  90.380 +	char nat;
  90.381 +
  90.382 +	if (!((regnum >= (IA64_GR0_REGNUM + 2) &&
  90.383 +		regnum <= (IA64_GR0_REGNUM + 3)) ||
  90.384 +		(regnum >= (IA64_GR0_REGNUM + 8) &&
  90.385 +		regnum <= (IA64_GR0_REGNUM + 15)) ||
  90.386 +		(regnum >= (IA64_GR0_REGNUM + 16) &&
  90.387 +		regnum <= (IA64_GR0_REGNUM + 31))))
  90.388 +		return 0;
  90.389 +	else if (rw && ptregs) {
  90.390 +		for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
  90.391 +			if (gr_reg_to_ptreg_index[i].reg == regnum) {
  90.392 +				*((unsigned long *)(((void *)ptregs) +
  90.393 +				gr_reg_to_ptreg_index[i].ptregoff)) = *reg;
  90.394 +				break;
  90.395 +			}
  90.396 +	} else if (!rw && ptregs) {
  90.397 +		for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
  90.398 +			if (gr_reg_to_ptreg_index[i].reg == regnum) {
  90.399 +				*reg = *((unsigned long *)
  90.400 +				(((void *)ptregs) +
  90.401 +				 gr_reg_to_ptreg_index[i].ptregoff));
  90.402 +				break;
  90.403 +			}
  90.404 +	} else
  90.405 +		result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
  90.406 +					reg, &nat, rw);
  90.407 +	return result;
  90.408 +}
  90.409 +
  90.410 +static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,
  90.411 +	struct unw_frame_info *info, unsigned long *reg, int rw)
  90.412 +{
  90.413 +	int i, result = 1;
  90.414 +
  90.415 +	if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))
  90.416 +		return 0;
  90.417 +
  90.418 +	switch (regnum) {
  90.419 +	case IA64_BR0_REGNUM:
  90.420 +	case IA64_BR0_REGNUM + 6:
  90.421 +	case IA64_BR0_REGNUM + 7:
  90.422 +		if (rw) {
  90.423 +			for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
  90.424 +				if (br_reg_to_ptreg_index[i].reg == regnum) {
  90.425 +					*((unsigned long *)
  90.426 +					(((void *)ptregs) +
  90.427 +					br_reg_to_ptreg_index[i].ptregoff)) =
  90.428 +					*reg;
  90.429 +					break;
  90.430 +				}
  90.431 +		} else
  90.432 +			for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
  90.433 +				if (br_reg_to_ptreg_index[i].reg == regnum) {
  90.434 +						*reg = *((unsigned long *)
  90.435 +						(((void *)ptregs) +
  90.436 +						br_reg_to_ptreg_index[i].
  90.437 +						ptregoff));
  90.438 +						break;
  90.439 +				}
  90.440 +		break;
  90.441 +	case IA64_BR0_REGNUM + 1:
  90.442 +	case IA64_BR0_REGNUM + 2:
  90.443 +	case IA64_BR0_REGNUM + 3:
  90.444 +	case IA64_BR0_REGNUM + 4:
  90.445 +	case IA64_BR0_REGNUM + 5:
  90.446 +		result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,
  90.447 +				reg, rw);
  90.448 +		break;
  90.449 +	}
  90.450 +
  90.451 +	return result;
  90.452 +}
  90.453 +
  90.454 +static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
  90.455 +	struct unw_frame_info *info, unsigned long *reg,
  90.456 +	struct ia64_fpreg *freg, int rw)
  90.457 +{
  90.458 +	int result = 1;
  90.459 +
  90.460 +	if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
  90.461 +		return 0;
  90.462 +
  90.463 +	switch (regnum) {
  90.464 +	case IA64_FR0_REGNUM + 6:
  90.465 +	case IA64_FR0_REGNUM + 7:
  90.466 +	case IA64_FR0_REGNUM + 8:
  90.467 +	case IA64_FR0_REGNUM + 9:
  90.468 +	case IA64_FR0_REGNUM + 10:
  90.469 +	case IA64_FR0_REGNUM + 11:
  90.470 +	case IA64_FR0_REGNUM + 12:
  90.471 +		if (rw) {
  90.472 +#ifndef XEN
  90.473 +			char *ptr = inbuffer;
  90.474 +
  90.475 +			freg->u.bits[0] = *reg;
  90.476 +			kgdb_hex2long(&ptr, &freg->u.bits[1]);
  90.477 +			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
  90.478 +				*freg;
  90.479 +#else
  90.480 +			printk("%s: %d: writing to fpreg is not supported.\n",
  90.481 +				   __func__, __LINE__);
  90.482 +#endif
  90.483 +			break;
  90.484 +		} else if (!ptregs)
  90.485 +			result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
  90.486 +				freg, rw);
  90.487 +		else
  90.488 +#ifndef XEN
  90.489 +			*freg =
  90.490 +			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
  90.491 +#else
  90.492 +		    //XXX struct ia64_fpreg and struct pt_fpreg are same.
  90.493 +			*freg = *((struct ia64_fpreg*)(&ptregs->f6 +
  90.494 +										   (regnum - (IA64_FR0_REGNUM + 6))));
  90.495 +#endif
  90.496 +		break;
  90.497 +	default:
  90.498 +		if (!rw)
  90.499 +			result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
  90.500 +				freg, rw);
  90.501 +		else
  90.502 +			result = 0;
  90.503 +		break;
  90.504 +	}
  90.505 +
  90.506 +	return result;
  90.507 +}
  90.508 +
  90.509 +static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
  90.510 +	struct unw_frame_info *info, unsigned long *reg, int rw)
  90.511 +{
  90.512 +	int result = 0, i;
  90.513 +
  90.514 +	if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
  90.515 +		return 0;
  90.516 +
  90.517 +	if (rw && ptregs) {
  90.518 +		for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
  90.519 +			if (ar_reg_to_ptreg_index[i].reg == regnum) {
  90.520 +				*((unsigned long *) (((void *)ptregs) +
  90.521 +				ar_reg_to_ptreg_index[i].ptregoff)) =
  90.522 +					*reg;
  90.523 +				result = 1;
  90.524 +				break;
  90.525 +			}
  90.526 +	} else if (ptregs) {
  90.527 +		for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
  90.528 +			if (ar_reg_to_ptreg_index[i].reg == regnum) {
  90.529 +				*reg = *((unsigned long *) (((void *)ptregs) +
  90.530 +					ar_reg_to_ptreg_index[i].ptregoff));
  90.531 +					result = 1;
  90.532 +				break;
  90.533 +			}
  90.534 +	}
  90.535 +
  90.536 +	if (result)
  90.537 +		return result;
  90.538 +
  90.539 +       result = 1;
  90.540 +
  90.541 +	switch (regnum) {
  90.542 +	case IA64_CSD_REGNUM:
  90.543 +		result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
  90.544 +		break;
  90.545 +	case IA64_SSD_REGNUM:
  90.546 +		result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
  90.547 +		break;
  90.548 +	case IA64_UNAT_REGNUM:
  90.549 +		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
  90.550 +		break;
  90.551 +		case IA64_RNAT_REGNUM:
  90.552 +		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
  90.553 +		break;
  90.554 +	case IA64_BSPSTORE_REGNUM:
  90.555 +		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
  90.556 +		break;
  90.557 +	case IA64_PFS_REGNUM:
  90.558 +		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
  90.559 +		break;
  90.560 +	case IA64_LC_REGNUM:
  90.561 +		result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
  90.562 +		break;
  90.563 +	case IA64_EC_REGNUM:
  90.564 +		result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
  90.565 +		break;
  90.566 +	case IA64_FPSR_REGNUM:
  90.567 +		result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
  90.568 +		break;
  90.569 +	case IA64_RSC_REGNUM:
  90.570 +		result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
  90.571 +		break;
  90.572 +	case IA64_CCV_REGNUM:
  90.573 +		result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
  90.574 +		break;
  90.575 +	default:
  90.576 +		result = 0;
  90.577 +	}
  90.578 +
  90.579 +	return result;
  90.580 +}
  90.581 +
  90.582 +#ifndef XEN
  90.583 +void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
  90.584 +	struct pt_regs *ptregs)
  90.585 +#else
  90.586 +static int
  90.587 +kgdb_get_reg(int regnum, struct unw_frame_info *info,
  90.588 +			 struct cpu_user_regs* ptregs,
  90.589 +			 unsigned long* __reg, struct ia64_fpreg* __freg)
  90.590 +#endif
  90.591 +{
  90.592 +	unsigned long reg, size = 0, *mem = &reg;
  90.593 +	struct ia64_fpreg freg;
  90.594 +
  90.595 +	if (kgdb_gr_reg(regnum, info, &reg, 0) ||
  90.596 +		kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||
  90.597 +		kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||
  90.598 +		kgdb_ar_reg(regnum, ptregs, info, &reg, 0))
  90.599 +			size = sizeof(reg);
  90.600 +	else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &freg, 0)) {
  90.601 +		size = sizeof(freg);
  90.602 +		mem = (unsigned long *)&freg;
  90.603 +	} else if (regnum == IA64_IP_REGNUM) {
  90.604 +		if (!ptregs) {
  90.605 +			unw_get_ip(info, &reg);
  90.606 +			size = sizeof(reg);
  90.607 +		} else {
  90.608 +			reg = ptregs->cr_iip;
  90.609 +			size = sizeof(reg);
  90.610 +		}
  90.611 +	} else if (regnum == IA64_CFM_REGNUM) {
  90.612 +		if (!ptregs)
  90.613 +			unw_get_cfm(info, &reg);
  90.614 +		else
  90.615 +			reg = ptregs->cr_ifs;
  90.616 +		size = sizeof(reg);
  90.617 +	} else if (regnum == IA64_PSR_REGNUM) {
  90.618 +#ifndef XEN
  90.619 +		if (!ptregs && kgdb_usethread)
  90.620 +			ptregs = (struct pt_regs *)
  90.621 +			((unsigned long)kgdb_usethread +
  90.622 +			IA64_STK_OFFSET) - 1;
  90.623 +#endif
  90.624 +		if (ptregs)
  90.625 +			reg = ptregs->cr_ipsr;
  90.626 +		size = sizeof(reg);
  90.627 +	} else if (regnum == IA64_PR_REGNUM) {
  90.628 +		if (ptregs)
  90.629 +			reg = ptregs->pr;
  90.630 +		else
  90.631 +			unw_access_pr(info, &reg, 0);
  90.632 +		size = sizeof(reg);
  90.633 +	} else if (regnum == IA64_BSP_REGNUM) {
  90.634 +		unw_get_bsp(info, &reg);
  90.635 +		size = sizeof(reg);
  90.636 +	}
  90.637 +
  90.638 +#ifndef XEN
  90.639 +	if (size) {
  90.640 +		kgdb_mem2hex((char *) mem, outbuffer, size);
  90.641 +		outbuffer[size*2] = 0;
  90.642 +	}
  90.643 +	else
  90.644 +		strcpy(outbuffer, "E0");
  90.645 +
  90.646 +	return;
  90.647 +#else
  90.648 +	if (size) {
  90.649 +		if (size == sizeof(reg)) {
  90.650 +			*__reg = reg;
  90.651 +		} else {
  90.652 +			BUG_ON(size != sizeof(freg));
  90.653 +			*__freg = freg;
  90.654 +		}
  90.655 +		return 0;
  90.656 +	}
  90.657 +
  90.658 +	return -1;
  90.659 +#endif
  90.660 +}
  90.661 +
  90.662 +#ifndef XEN
  90.663 +static int inline kgdb_get_blocked_state(struct task_struct *p,
  90.664 +					 struct unw_frame_info *unw)
  90.665 +#else
  90.666 +static int
  90.667 +kgdb_get_blocked_state(struct vcpu *p,
  90.668 +					   struct cpu_user_regs *regs,
  90.669 +					   struct unw_frame_info *unw)
  90.670 +#endif
  90.671 +{
  90.672 +	unsigned long ip;
  90.673 +	int count = 0;
  90.674 +
  90.675 +#ifndef XEN
  90.676 +	unw_init_from_blocked_task(unw, p);
  90.677 +#endif
  90.678 +	ip = 0UL;
  90.679 +	do {
  90.680 +		if (unw_unwind(unw) < 0)
  90.681 +			return -1;
  90.682 +		unw_get_ip(unw, &ip);
  90.683 +#ifndef XEN
  90.684 +		if (!in_sched_functions(ip))
  90.685 +			break;
  90.686 +#else
  90.687 +		dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip);
  90.688 +		if (ip == regs->cr_iip)
  90.689 +			break;
  90.690 +#endif
  90.691 +	} while (count++ < 16);
  90.692 +
  90.693 +	if (!ip)
  90.694 +		return -1;
  90.695 +	else
  90.696 +		return 0;
  90.697 +}
  90.698 +
  90.699 +struct gdb_callback_arg
  90.700 +{
  90.701 +	struct cpu_user_regs*		regs;
  90.702 +	unsigned long				regnum;
  90.703 +	unsigned long*				reg;
  90.704 +	struct pt_fpreg*			freg;
  90.705 +
  90.706 +	int							error;
  90.707 +	                            //  1: not supported
  90.708 +								//  0: success
  90.709 +								// -1: failure
  90.710 +};
  90.711 +
  90.712 +static void
  90.713 +gdb_get_reg_callback(struct unw_frame_info* info, void* __arg)
  90.714 +{
  90.715 +	struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg;
  90.716 +
  90.717 +	if (kgdb_get_blocked_state(current, arg->regs, info) < 0) {
  90.718 +		dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__);
  90.719 +		arg->error = -1;
  90.720 +		return;
  90.721 +	}
  90.722 +	//XXX struct ia64_fpreg and struct pt_fpreg are same.
  90.723 +	if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg, 
  90.724 +					 (struct ia64_fpreg*)arg->freg) < 0) {
  90.725 +		dbg_printk("%s: kgdb_get_reg failed\n", __func__);
  90.726 +		arg->error = 1;
  90.727 +		return;
  90.728 +	}
  90.729 +	arg->error = 0;
  90.730 +	return;
  90.731 +}
  90.732 +
  90.733 +void 
  90.734 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
  90.735 +                  struct gdb_context *ctx)
  90.736 +{
  90.737 +	struct gdb_callback_arg arg;
  90.738 +	unsigned long reg;
  90.739 +	struct pt_fpreg freg;
  90.740 +	char buf[16 * 2 + 1];
  90.741 +
  90.742 +	if (regnum >= NUM_REGS) {
  90.743 +		dbg_printk("%s: regnum %ld\n", __func__, regnum);
  90.744 +		goto out_err;
  90.745 +	}
  90.746 +
  90.747 +	arg.regs = regs;
  90.748 +	arg.regnum = regnum;
  90.749 +	arg.reg = &reg;
  90.750 +	arg.freg = &freg;
  90.751 +	arg.error = 0;
  90.752 +	unw_init_running(&gdb_get_reg_callback, (void*)&arg);
  90.753 +	if (arg.error < 0) {
  90.754 +		dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);
  90.755 +		goto out_err;
  90.756 +	}
  90.757 +
  90.758 +	if (arg.error > 0) {
  90.759 +		// notify gdb that this register is not supported.
  90.760 +		// see fetch_register_using_p() in gdb/remote.c.
  90.761 +		sprintf(buf, "%s", "x");
  90.762 +	} else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 127) {
  90.763 +		sprintf(buf, "%.016lx", swab64(freg.u.bits[0]));
  90.764 +		sprintf(buf + 16, "%.016lx", swab64(freg.u.bits[1]));
  90.765 +	} else {
  90.766 +		sprintf(buf, "%.016lx", swab64(reg));
  90.767 +	}
  90.768 +out:
  90.769 +	return gdb_send_reply(buf, ctx);
  90.770 +
  90.771 +out_err:
  90.772 +	dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
  90.773 +	sprintf(buf, "%s", "E0");
  90.774 +	goto out;
  90.775 +}
  90.776 +#endif
  90.777 +
  90.778 +void 
  90.779 +gdb_arch_resume(struct cpu_user_regs *regs,
  90.780 +                unsigned long addr, unsigned long type,
  90.781 +                struct gdb_context *ctx)
  90.782 +{
  90.783 +    /* XXX */
  90.784 +    if (type == GDB_STEP) {
  90.785 +        gdb_send_reply("S01", ctx);
  90.786 +    }
  90.787 +}
  90.788 +
  90.789 +void
  90.790 +gdb_arch_print_state(struct cpu_user_regs *regs)
  90.791 +{
  90.792 +    /* XXX */
  90.793 +}
  90.794 +
  90.795 +void
  90.796 +gdb_arch_enter(struct cpu_user_regs *regs)
  90.797 +{
  90.798 +    /* nothing */
  90.799 +}
  90.800 +
  90.801 +void
  90.802 +gdb_arch_exit(struct cpu_user_regs *regs)
  90.803 +{
  90.804 +    /* nothing */
  90.805 +}
  90.806 +
  90.807 +/*
  90.808 + * Local variables:
  90.809 + * mode: C
  90.810 + * c-set-style: "BSD"
  90.811 + * c-basic-offset: 4
  90.812 + * tab-width: 4
  90.813 + * End:
  90.814 + */
    91.1 --- a/xen/arch/ia64/xen/hyperprivop.S	Tue Jan 10 15:21:00 2006 +0000
    91.2 +++ b/xen/arch/ia64/xen/hyperprivop.S	Tue Jan 24 17:54:34 2006 +0100
    91.3 @@ -12,6 +12,7 @@
    91.4  #include <asm/offsets.h>
    91.5  #include <asm/processor.h>
    91.6  #include <asm/system.h>
    91.7 +#include <asm/debugger.h>
    91.8  #include <public/arch-ia64.h>
    91.9  
   91.10  
   91.11 @@ -549,7 +550,12 @@ GLOBAL_ENTRY(fast_break_reflect)
   91.12  (p7)    br.spnt.many 1f ;;
   91.13          cmp.eq p7,p0=r17,r0
   91.14  (p7)    br.spnt.few dispatch_break_fault ;;
   91.15 -1:
   91.16 +#ifdef CRASH_DEBUG
   91.17 +	movl r21=CDB_BREAK_NUM ;;
   91.18 +	cmp.eq p7,p0=r17,r21
   91.19 +(p7)	br.spnt.few dispatch_break_fault ;;
   91.20 +#endif	
   91.21 +1:	
   91.22  #if 1 /* special handling in case running on simulator */
   91.23  	movl r20=first_break;;
   91.24  	ld4 r23=[r20];;
    92.1 --- a/xen/arch/ia64/xen/idle0_task.c	Tue Jan 10 15:21:00 2006 +0000
    92.2 +++ b/xen/arch/ia64/xen/idle0_task.c	Tue Jan 24 17:54:34 2006 +0100
    92.3 @@ -11,30 +11,15 @@
    92.4  	.mmlist		= LIST_HEAD_INIT(name.mmlist),		\
    92.5  }
    92.6  
    92.7 -#define IDLE0_EXEC_DOMAIN(_ed,_d)    \
    92.8 +#define IDLE_VCPU(_v)    	     \
    92.9  {                                    \
   92.10      processor:   0,                  \
   92.11 -    mm:          0,                  \
   92.12 -    thread:      INIT_THREAD,        \
   92.13 -    domain:      (_d)                \
   92.14 -}
   92.15 -
   92.16 -#define IDLE0_DOMAIN(_t)             \
   92.17 -{                                    \
   92.18 -    domain_id:   IDLE_DOMAIN_ID,     \
   92.19 -    refcnt:      ATOMIC_INIT(1)      \
   92.20 +    domain:      0                   \
   92.21  }
   92.22  
   92.23  struct mm_struct init_mm = INIT_MM(init_mm);
   92.24  EXPORT_SYMBOL(init_mm);
   92.25  
   92.26 -struct domain idle0_domain = IDLE0_DOMAIN(idle0_domain);
   92.27 -#if 0
   92.28 -struct vcpu idle0_vcpu = IDLE0_EXEC_DOMAIN(idle0_vcpu,
   92.29 -                                                         &idle0_domain);
   92.30 -#endif
   92.31 -
   92.32 -
   92.33  /*
   92.34   * Initial task structure.
   92.35   *
   92.36 @@ -43,15 +28,12 @@ struct vcpu idle0_vcpu = IDLE0_EXEC_DOMA
   92.37   */
   92.38  union {
   92.39  	struct {
   92.40 -		struct domain task;
   92.41 +		struct vcpu task;
   92.42  	} s;
   92.43  	unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
   92.44 -} init_task_mem asm ("init_task") __attribute__((section(".data.init_task")));
   92.45 -// = {{
   92.46 -	;
   92.47 -//.task =		IDLE0_EXEC_DOMAIN(init_task_mem.s.task,&idle0_domain),
   92.48 -//};
   92.49 -//};
   92.50 +} init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) = {{
   92.51 +	.task = IDLE_VCPU(init_task_mem.s.task)
   92.52 +}};
   92.53  
   92.54  EXPORT_SYMBOL(init_task);
   92.55  
    93.1 --- a/xen/arch/ia64/xen/ivt.S	Tue Jan 10 15:21:00 2006 +0000
    93.2 +++ b/xen/arch/ia64/xen/ivt.S	Tue Jan 24 17:54:34 2006 +0100
    93.3 @@ -15,6 +15,7 @@
    93.4  #define sys_call_table 0
    93.5  #define sys_ni_syscall 0
    93.6  #include <asm/vhpt.h>
    93.7 +#include <asm/debugger.h>
    93.8  #endif
    93.9  /*
   93.10   * arch/ia64/kernel/ivt.S
   93.11 @@ -841,6 +842,13 @@ ENTRY(break_fault)
   93.12  	;;
   93.13  	cmp.eq p7,p0=r17,r0
   93.14  (p7)	br.spnt.few dispatch_break_fault ;;
   93.15 +#ifdef CRASH_DEBUG
   93.16 +        // panic can occur before domain0 is created.
   93.17 +        // in such case referencing XSI_PSR_IC causes nested_dtlb_miss
   93.18 +        movl r18=CDB_BREAK_NUM ;;
   93.19 +        cmp.eq p7,p0=r17,r18 ;; 
   93.20 +(p7)    br.spnt.few dispatch_break_fault ;;
   93.21 +#endif
   93.22  	movl r18=XSI_PSR_IC
   93.23  	;;
   93.24  	ld8 r19=[r18]
    94.1 --- a/xen/arch/ia64/xen/mm_init.c	Tue Jan 10 15:21:00 2006 +0000
    94.2 +++ b/xen/arch/ia64/xen/mm_init.c	Tue Jan 24 17:54:34 2006 +0100
    94.3 @@ -502,6 +502,7 @@ find_largest_hole (u64 start, u64 end, v
    94.4  }
    94.5  #endif /* CONFIG_VIRTUAL_MEM_MAP */
    94.6  
    94.7 +#ifndef XEN
    94.8  static int
    94.9  count_reserved_pages (u64 start, u64 end, void *arg)
   94.10  {
   94.11 @@ -514,6 +515,7 @@ count_reserved_pages (u64 start, u64 end
   94.12  	*count += num_reserved;
   94.13  	return 0;
   94.14  }
   94.15 +#endif
   94.16  
   94.17  /*
   94.18   * Boot command-line option "nolwsys" can be used to disable the use of any light-weight
    95.1 --- a/xen/arch/ia64/xen/process.c	Tue Jan 10 15:21:00 2006 +0000
    95.2 +++ b/xen/arch/ia64/xen/process.c	Tue Jan 24 17:54:34 2006 +0100
    95.3 @@ -31,6 +31,7 @@
    95.4  #include <asm/dom_fw.h>
    95.5  #include "hpsim_ssc.h"
    95.6  #include <xen/multicall.h>
    95.7 +#include <asm/debugger.h>
    95.8  
    95.9  extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64);
   95.10  extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
   95.11 @@ -652,7 +653,7 @@ void
   95.12  ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim)
   95.13  {
   95.14  	struct domain *d = (struct domain *) current->domain;
   95.15 -	struct vcpu *v = (struct domain *) current;
   95.16 +	struct vcpu *v = current;
   95.17  	extern unsigned long running_on_sim;
   95.18  
   95.19  	if (first_break) {
   95.20 @@ -663,7 +664,14 @@ ia64_handle_break (unsigned long ifa, st
   95.21  	if (iim == 0x80001 || iim == 0x80002) {	//FIXME: don't hardcode constant
   95.22  		if (running_on_sim) do_ssc(vcpu_get_gr(current,36), regs);
   95.23  		else do_ssc(vcpu_get_gr(current,36), regs);
   95.24 -	}
   95.25 +	} 
   95.26 +#ifdef CRASH_DEBUG
   95.27 +	else if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs)) {
   95.28 +		if (iim == 0)
   95.29 +			show_registers(regs);
   95.30 +		debugger_trap_fatal(0 /* don't care */, regs);
   95.31 +	} 
   95.32 +#endif
   95.33  	else if (iim == d->arch.breakimm) {
   95.34  		/* by default, do not continue */
   95.35  		v->arch.hypercall_continuation = 0;
    96.1 --- a/xen/arch/ia64/xen/sn_console.c	Tue Jan 10 15:21:00 2006 +0000
    96.2 +++ b/xen/arch/ia64/xen/sn_console.c	Tue Jan 24 17:54:34 2006 +0100
    96.3 @@ -4,6 +4,7 @@
    96.4   * Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
    96.5   */
    96.6  
    96.7 +#include <xen/lib.h>
    96.8  #include <asm/acpi.h>
    96.9  #include <asm/sn/sn_sal.h>
   96.10  #include <xen/serial.h>
    97.1 --- a/xen/arch/ia64/xen/xenmisc.c	Tue Jan 10 15:21:00 2006 +0000
    97.2 +++ b/xen/arch/ia64/xen/xenmisc.c	Tue Jan 24 17:54:34 2006 +0100
    97.3 @@ -18,6 +18,7 @@
    97.4  #include <xen/softirq.h>
    97.5  #include <public/sched.h>
    97.6  #include <asm/vhpt.h>
    97.7 +#include <asm/debugger.h>
    97.8  
    97.9  efi_memory_desc_t ia64_efi_io_md;
   97.10  EXPORT_SYMBOL(ia64_efi_io_md);
   97.11 @@ -75,7 +76,7 @@ struct pt_regs *guest_cpu_user_regs(void
   97.12  
   97.13  void raise_actimer_softirq(void)
   97.14  {
   97.15 -	raise_softirq(AC_TIMER_SOFTIRQ);
   97.16 +	raise_softirq(TIMER_SOFTIRQ);
   97.17  }
   97.18  
   97.19  unsigned long
   97.20 @@ -203,6 +204,8 @@ void dump_pageframe_info(struct domain *
   97.21  	printk("dump_pageframe_info not implemented\n");
   97.22  }
   97.23  
   97.24 +int nmi_count(int x) { return x; }
   97.25 +
   97.26  ///////////////////////////////
   97.27  // called from arch/ia64/head.S
   97.28  ///////////////////////////////
   97.29 @@ -354,6 +357,11 @@ loop:
   97.30  	va_end(args);
   97.31  	printf(buf);
   97.32  	if (regs) show_registers(regs);
   97.33 +	if (regs) {
   97.34 +		debugger_trap_fatal(0 /* don't care */, regs);
   97.35 +	} else {
   97.36 +		debugger_trap_immediate();
   97.37 +	}
   97.38  	domain_pause_by_systemcontroller(current->domain);
   97.39  	v->domain->shutdown_code = SHUTDOWN_crash;
   97.40  	set_bit(_DOMF_shutdown, v->domain->domain_flags);
    98.1 --- a/xen/arch/ia64/xen/xensetup.c	Tue Jan 10 15:21:00 2006 +0000
    98.2 +++ b/xen/arch/ia64/xen/xensetup.c	Tue Jan 24 17:54:34 2006 +0100
    98.3 @@ -21,12 +21,13 @@
    98.4  #include <asm/page.h>
    98.5  #include <asm/setup.h>
    98.6  #include <xen/string.h>
    98.7 +#include <asm/vmx.h>
    98.8  
    98.9  unsigned long xenheap_phys_end;
   98.10  
   98.11  char saved_command_line[COMMAND_LINE_SIZE];
   98.12  
   98.13 -struct vcpu *idle_vcpu[NR_CPUS] = { &idle0_vcpu };
   98.14 +struct vcpu *idle_vcpu[NR_CPUS];
   98.15  
   98.16  cpumask_t cpu_present_map;
   98.17  
   98.18 @@ -156,16 +157,12 @@ void start_kernel(void)
   98.19      unsigned long dom0_memory_start, dom0_memory_size;
   98.20      unsigned long dom0_initrd_start, dom0_initrd_size;
   98.21      unsigned long initial_images_start, initial_images_end;
   98.22 +    struct domain *idle_domain;
   98.23  
   98.24      running_on_sim = is_platform_hp_ski();
   98.25      /* Kernel may be relocated by EFI loader */
   98.26      xen_pstart = ia64_tpa(KERNEL_START);
   98.27  
   98.28 -    /* Must do this early -- e.g., spinlocks rely on get_current(). */
   98.29 -    //set_current(&idle0_vcpu);
   98.30 -    ia64_r13 = (void *)&idle0_vcpu;
   98.31 -    idle0_vcpu.domain = &idle0_domain;
   98.32 -
   98.33      early_setup_arch(&cmdline);
   98.34  
   98.35      /* We initialise the serial devices very early so we can get debugging. */
   98.36 @@ -281,18 +278,22 @@ void start_kernel(void)
   98.37  	(xenheap_phys_end-__pa(heap_start)) >> 20,
   98.38  	(xenheap_phys_end-__pa(heap_start)) >> 10);
   98.39  
   98.40 +printk("About to call scheduler_init()\n");
   98.41 +    scheduler_init();
   98.42 +    idle_vcpu[0] = (struct vcpu*) ia64_r13;
   98.43 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
   98.44 +    BUG_ON(idle_domain == NULL);
   98.45 +
   98.46      late_setup_arch(&cmdline);
   98.47      setup_per_cpu_areas();
   98.48      mem_init();
   98.49  
   98.50 -printk("About to call scheduler_init()\n");
   98.51 -    scheduler_init();
   98.52      local_irq_disable();
   98.53      init_IRQ ();
   98.54  printk("About to call init_xen_time()\n");
   98.55      init_xen_time(); /* initialise the time */
   98.56 -printk("About to call ac_timer_init()\n");
   98.57 -    ac_timer_init();
   98.58 +printk("About to call timer_init()\n");
   98.59 +    timer_init();
   98.60  
   98.61  #ifdef CONFIG_XEN_CONSOLE_INPUT	/* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
   98.62      initialize_keytable();
   98.63 @@ -308,14 +309,10 @@ printk("About to call ac_timer_init()\n"
   98.64      }
   98.65  
   98.66      smp_prepare_cpus(max_cpus);
   98.67 -
   98.68      /* We aren't hotplug-capable yet. */
   98.69 -    //BUG_ON(!cpus_empty(cpu_present_map));
   98.70      for_each_cpu ( i )
   98.71          cpu_set(i, cpu_present_map);
   98.72  
   98.73 -    //BUG_ON(!local_irq_is_enabled());
   98.74 -
   98.75      /*  Enable IRQ to receive IPI (needed for ITC sync).  */
   98.76      local_irq_enable();
   98.77  
   98.78 @@ -342,19 +339,14 @@ printk("About to call sort_main_extable(
   98.79  
   98.80  
   98.81      /* Create initial domain 0. */
   98.82 -printk("About to call do_createdomain()\n");
   98.83 -    dom0 = do_createdomain(0, 0);
   98.84 -    init_task.domain = &idle0_domain;
   98.85 -    init_task.processor = 0;
   98.86 -//    init_task.mm = &init_mm;
   98.87 -    init_task.domain->arch.mm = &init_mm;
   98.88 -//    init_task.thread = INIT_THREAD;
   98.89 -    //arch_do_createdomain(current);
   98.90 +printk("About to call domain_create()\n");
   98.91 +    dom0 = domain_create(0, 0);
   98.92 +
   98.93  #ifdef CLONE_DOMAIN0
   98.94      {
   98.95      int i;
   98.96      for (i = 0; i < CLONE_DOMAIN0; i++) {
   98.97 -	clones[i] = do_createdomain(i+1, 0);
   98.98 +	clones[i] = domain_create(i+1, 0);
   98.99          if ( clones[i] == NULL )
  98.100              panic("Error creating domain0 clone %d\n",i);
  98.101      }
  98.102 @@ -431,8 +423,8 @@ printk("About to call init_trace_bufs()\
  98.103  
  98.104      local_irq_enable();
  98.105  
  98.106 -    printf("About to call schedulers_start dom0=%p, idle0_dom=%p\n",
  98.107 -	   dom0, &idle0_domain);
  98.108 +    printf("About to call schedulers_start dom0=%p, idle_dom=%p\n",
  98.109 +	   dom0, &idle_domain);
  98.110      schedulers_start();
  98.111  
  98.112      domain_unpause_by_systemcontroller(dom0);
  98.113 @@ -445,9 +437,10 @@ void arch_get_xen_caps(xen_capabilities_
  98.114  {
  98.115      char *p=info;
  98.116  
  98.117 -    *p=0;
  98.118 +    p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
  98.119  
  98.120 -    p+=sprintf(p,"xen_%d.%d_ia64 ",XEN_VERSION,XEN_SUBVERSION);
  98.121 +    if (vmx_enabled)
  98.122 +        p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
  98.123  
  98.124      *(p-1) = 0;
  98.125  
    99.1 --- a/xen/arch/ia64/xen/xentime.c	Tue Jan 10 15:21:00 2006 +0000
    99.2 +++ b/xen/arch/ia64/xen/xentime.c	Tue Jan 24 17:54:34 2006 +0100
    99.3 @@ -196,7 +196,7 @@ xen_timer_interrupt (int irq, void *dev_
    99.4  //#endif
    99.5  		/* double check, in case we got hit by a (slow) PMI: */
    99.6  	} while (time_after_eq(ia64_get_itc(), new_itm));
    99.7 -	raise_softirq(AC_TIMER_SOFTIRQ);
    99.8 +	raise_softirq(TIMER_SOFTIRQ);
    99.9  
   99.10  	return IRQ_HANDLED;
   99.11  }
   99.12 @@ -235,7 +235,7 @@ int __init init_xen_time()
   99.13      return 0;
   99.14  }
   99.15  
   99.16 -int reprogram_ac_timer(s_time_t timeout)
   99.17 +int reprogram_timer(s_time_t timeout)
   99.18  {
   99.19  	struct vcpu *v = current;
   99.20  	s_time_t expire;
   100.1 --- a/xen/arch/x86/Makefile	Tue Jan 10 15:21:00 2006 +0000
   100.2 +++ b/xen/arch/x86/Makefile	Tue Jan 24 17:54:34 2006 +0100
   100.3 @@ -32,7 +32,7 @@ OBJS := $(subst $(TARGET_SUBARCH)/asm-of
   100.4  OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
   100.5  
   100.6  ifneq ($(crash_debug),y)
   100.7 -OBJS := $(patsubst cdb%.o,,$(OBJS))
   100.8 +OBJS := $(patsubst gdbstub%.o,,$(OBJS))
   100.9  endif
  100.10  
  100.11  default: $(TARGET)
   101.1 --- a/xen/arch/x86/apic.c	Tue Jan 10 15:21:00 2006 +0000
   101.2 +++ b/xen/arch/x86/apic.c	Tue Jan 24 17:54:34 2006 +0100
   101.3 @@ -870,7 +870,7 @@ void enable_APIC_timer(void)
   101.4   * returns 1 on success
   101.5   * returns 0 if the timeout value is too small or in the past.
   101.6   */
   101.7 -int reprogram_ac_timer(s_time_t timeout)
   101.8 +int reprogram_timer(s_time_t timeout)
   101.9  {
  101.10      s_time_t    now;
  101.11      s_time_t    expire;
  101.12 @@ -931,7 +931,7 @@ void smp_apic_timer_interrupt(struct cpu
  101.13  {
  101.14      ack_APIC_irq();
  101.15      perfc_incrc(apic_timer);
  101.16 -    raise_softirq(AC_TIMER_SOFTIRQ);
  101.17 +    raise_softirq(TIMER_SOFTIRQ);
  101.18  }
  101.19  
  101.20  /*
   102.1 --- a/xen/arch/x86/cdb.c	Tue Jan 10 15:21:00 2006 +0000
   102.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.3 @@ -1,414 +0,0 @@
   102.4 -/* Simple hacked-up version of pdb for use in post-mortem debugging of
   102.5 -   Xen and domain 0. This should be a little cleaner, hopefully.  Note
   102.6 -   that we can't share a serial line with PDB. */
   102.7 -/* We try to avoid assuming much about what the rest of the system is
   102.8 -   doing.  In particular, dynamic memory allocation is out of the
   102.9 -   question. */
  102.10 -/* Resuming after we've stopped used to work, but more through luck
  102.11 -   than any actual intention.  It doesn't at the moment. */
  102.12 -#include <xen/lib.h>
  102.13 -#include <asm/uaccess.h>
  102.14 -#include <xen/spinlock.h>
  102.15 -#include <xen/serial.h>
  102.16 -#include <xen/irq.h>
  102.17 -#include <asm/debugger.h>
  102.18 -#include <xen/init.h>
  102.19 -#include <xen/smp.h>
  102.20 -#include <xen/console.h>
  102.21 -#include <asm/apic.h>
  102.22 -
  102.23 -/* Printk isn't particularly safe just after we've trapped to the
  102.24 -   debugger. so avoid it. */
  102.25 -#define dbg_printk(...)
  102.26 -
  102.27 -static char opt_cdb[30] = "none";
  102.28 -string_param("cdb", opt_cdb);
  102.29 -
  102.30 -struct xendbg_context {
  102.31 -	int serhnd;
  102.32 -	u8 reply_csum;
  102.33 -	int currently_attached:1;
  102.34 -};
  102.35 -
  102.36 -/* Like copy_from_user, but safe to call with interrupts disabled.
  102.37 -
  102.38 -   Trust me, and don't look behind the curtain. */
  102.39 -static unsigned
  102.40 -dbg_copy_from_user(void *dest, const void *src, unsigned len)
  102.41 -{
  102.42 -	int __d0, __d1, __d2;
  102.43 -	ASSERT(!local_irq_is_enabled());
  102.44 -	__asm__ __volatile__(
  102.45 -		"1:	rep; movsb\n"
  102.46 -		"2:\n"
  102.47 -		".section .fixup,\"ax\"\n"
  102.48 -		"3:     addl $4, %%esp\n"
  102.49 -		"       jmp 2b\n"
  102.50 -		".previous\n"
  102.51 -		".section __pre_ex_table,\"a\"\n"
  102.52 -		"	.align 4\n"
  102.53 -		"	.long 1b,3b\n"
  102.54 -		".previous\n"
  102.55 -		".section __ex_table,\"a\"\n"
  102.56 -		"	.align 4\n"
  102.57 -		"	.long 1b,2b\n"
  102.58 -		".previous\n"
  102.59 -		: "=c"(__d2), "=D" (__d0), "=S" (__d1)
  102.60 -		: "0"(len), "1"(dest), "2"(src)
  102.61 -		: "memory");
  102.62 -	ASSERT(!local_irq_is_enabled());
  102.63 -	return __d2;
  102.64 -}
  102.65 -
  102.66 -static void
  102.67 -xendbg_put_char(u8 data, struct xendbg_context *ctx)
  102.68 -{
  102.69 -	ctx->reply_csum += data;
  102.70 -	serial_putc(ctx->serhnd, data);
  102.71 -}
  102.72 -
  102.73 -static int
  102.74 -hex_char_val(unsigned char c)
  102.75 -{
  102.76 -	if (c >= '0' && c <= '9')
  102.77 -		return c - '0';
  102.78 -	else if (c >= 'a' && c <= 'f')
  102.79 -		return c - 'a' + 10;
  102.80 -	else if (c >= 'A' && c <= 'F')
  102.81 -		return c - 'A' + 10;
  102.82 -	else
  102.83 -		BUG();
  102.84 -	return -1;
  102.85 -}
  102.86 -
  102.87 -/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
  102.88 -/* Does not acknowledge. */
  102.89 -static int
  102.90 -attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
  102.91 -{
  102.92 -	int count;
  102.93 -	u8 csum;
  102.94 -	u8 received_csum;
  102.95 -	u8 ch;
  102.96 -
  102.97 -	/* Skip over everything up to the first '$' */
  102.98 -	while ((ch = serial_getc(ctx->serhnd)) != '$')
  102.99 -		;
 102.100 -	csum = 0;
 102.101 -	for (count = 0; count < 4096; count++) {
 102.102 -		ch = serial_getc(ctx->serhnd);
 102.103 -		if (ch == '#')
 102.104 -			break;
 102.105 -		recv_buf[count] = ch;
 102.106 -		csum += ch;
 102.107 -	}
 102.108 -	if (count == 4096) {
 102.109 -		dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
 102.110 -		return -1;
 102.111 -	}
 102.112 -	recv_buf[count] = 0;
 102.113 -	received_csum = hex_char_val(serial_getc(ctx->serhnd)) * 16 +
 102.114 -		hex_char_val(serial_getc(ctx->serhnd));
 102.115 -	if (received_csum == csum) {
 102.116 -		return 0;
 102.117 -	} else {
 102.118 -		return -1;
 102.119 -	}
 102.120 -}
 102.121 -
 102.122 -/* Send a string of bytes to the debugger. */
 102.123 -static void
 102.124 -xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
 102.125 -{
 102.126 -	int x;
 102.127 -	for (x = 0; x < count; x++)
 102.128 -		xendbg_put_char(buf[x], ctx);
 102.129 -}
 102.130 -
 102.131 -/* Receive a command, discarding up to ten packets with csum
 102.132 - * errors.  Acknowledges all received packets. */
 102.133 -static int
 102.134 -receive_command(char *recv_buf, struct xendbg_context *ctx)
 102.135 -{
 102.136 -	int r;
 102.137 -	int count;
 102.138 -
 102.139 -	count = 0;
 102.140 -	do {
 102.141 -		r = attempt_receive_packet(recv_buf, ctx);
 102.142 -		if (r < 0)
 102.143 -			xendbg_put_char('-', ctx);
 102.144 -		else
 102.145 -			xendbg_put_char('+', ctx);
 102.146 -		count++;
 102.147 -	} while (r < 0 && count < 10);
 102.148 -	return r;
 102.149 -}
 102.150 -
 102.151 -static void
 102.152 -xendbg_start_reply(struct xendbg_context *ctx)
 102.153 -{
 102.154 -	xendbg_put_char('$', ctx);
 102.155 -	ctx->reply_csum = 0;
 102.156 -}
 102.157 -
 102.158 -/* Return 0 if the reply was successfully received, !0 otherwise. */
 102.159 -static int
 102.160 -xendbg_finish_reply(struct xendbg_context *ctx)
 102.161 -{
 102.162 -	char ch;
 102.163 -	char buf[3];
 102.164 -
 102.165 -	sprintf(buf, "%.02x\n", ctx->reply_csum);
 102.166 -
 102.167 -	xendbg_put_char('#', ctx);
 102.168 -	xendbg_send(buf, 2, ctx);
 102.169 -
 102.170 -	ch = serial_getc(ctx->serhnd);
 102.171 -	if (ch == '+')
 102.172 -		return 0;
 102.173 -	else
 102.174 -		return 1;
 102.175 -}
 102.176 -
 102.177 -/* Swap the order of the bytes in a work. */
 102.178 -static inline unsigned
 102.179 -bswab32(unsigned val)
 102.180 -{
 102.181 -	return (((val >> 0) & 0xff) << 24) |
 102.182 -		(((val >> 8) & 0xff) << 16) |
 102.183 -		(((val >> 16) & 0xff) << 8) |
 102.184 -		(((val >> 24) & 0xff) << 0);
 102.185 -}
 102.186 -
 102.187 -static int
 102.188 -handle_memory_read_command(unsigned long addr, unsigned long length,
 102.189 -			   struct xendbg_context *ctx)
 102.190 -{
 102.191 -	int x;
 102.192 -	unsigned char val;
 102.193 -	int r;
 102.194 -	char buf[2];
 102.195 -
 102.196 -	dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
 102.197 -		   length);
 102.198 -	xendbg_start_reply(ctx);
 102.199 -	for (x = 0; x < length; x++) {
 102.200 -		r = dbg_copy_from_user(&val, (void *)(addr + x), 1);
 102.201 -		if (r != 0) {
 102.202 -			dbg_printk("Error reading from %lx.\n", addr + x);
 102.203 -			break;
 102.204 -		}
 102.205 -		sprintf(buf, "%.02x", val);
 102.206 -		xendbg_send(buf, 2, ctx);
 102.207 -	}
 102.208 -	if (x == 0)
 102.209 -		xendbg_send("E05", 3, ctx);
 102.210 -	dbg_printk("Read done.\n");
 102.211 -	return xendbg_finish_reply(ctx);
 102.212 -}
 102.213 -
 102.214 -static int
 102.215 -xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
 102.216 -{
 102.217 -	xendbg_start_reply(ctx);
 102.218 -	xendbg_send(buf, strlen(buf), ctx);
 102.219 -	return xendbg_finish_reply(ctx);
 102.220 -}
 102.221 -
 102.222 -static int
 102.223 -handle_register_read_command(struct cpu_user_regs *regs, struct xendbg_context *ctx)
 102.224 -{
 102.225 -	char buf[121];
 102.226 -
 102.227 -	sprintf(buf,
 102.228 -		"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
 102.229 -		bswab32(regs->eax),
 102.230 -		bswab32(regs->ecx),
 102.231 -		bswab32(regs->edx),
 102.232 -		bswab32(regs->ebx),
 102.233 -		bswab32(regs->esp),
 102.234 -		bswab32(regs->ebp),
 102.235 -		bswab32(regs->esi),
 102.236 -		bswab32(regs->edi),
 102.237 -		bswab32(regs->eip),
 102.238 -		bswab32(regs->eflags),
 102.239 -		bswab32(regs->cs),
 102.240 -		bswab32(regs->ss),
 102.241 -		bswab32(regs->ds),
 102.242 -		bswab32(regs->es),
 102.243 -		bswab32(regs->fs),
 102.244 -		bswab32(regs->gs));
 102.245 -	return xendbg_send_reply(buf, ctx);
 102.246 -}
 102.247 -
 102.248 -static int
 102.249 -process_command(char *received_packet, struct cpu_user_regs *regs,
 102.250 -		struct xendbg_context *ctx)
 102.251 -{
 102.252 -	char *ptr;
 102.253 -	unsigned long addr, length;
 102.254 -	int retry;
 102.255 -	int counter;
 102.256 -	int resume = 0;
 102.257 -
 102.258 -	/* Repeat until gdb acks the reply */
 102.259 -	counter = 0;
 102.260 -	do {
 102.261 -		switch (received_packet[0]) {
 102.262 -		case 'g': /* Read registers */
 102.263 -			retry = handle_register_read_command(regs, ctx);
 102.264 -			ASSERT(!local_irq_is_enabled());
 102.265 -			break;
 102.266 -		case 'm': /* Read memory */
 102.267 -			addr = simple_strtoul(received_packet + 1, &ptr, 16);
 102.268 -			if (ptr == received_packet + 1 ||
 102.269 -			    ptr[0] != ',') {
 102.270 -				xendbg_send_reply("E03", ctx);
 102.271 -				return 0;
 102.272 -			}
 102.273 -			length = simple_strtoul(ptr + 1, &ptr, 16);
 102.274 -			if (ptr[0] != 0) {
 102.275 -				xendbg_send_reply("E04", ctx);
 102.276 -				return 0;
 102.277 -			}
 102.278 -			retry =
 102.279 -				handle_memory_read_command(addr,
 102.280 -							   length,
 102.281 -							   ctx);
 102.282 -			ASSERT(!local_irq_is_enabled());
 102.283 -			break;
 102.284 -		case 'G': /* Write registers */
 102.285 -		case 'M': /* Write memory */
 102.286 -			retry = xendbg_send_reply("E02", ctx);
 102.287 -			break;
 102.288 -		case 'D':
 102.289 -			resume = 1;
 102.290 -			ctx->currently_attached = 0;
 102.291 -			retry = xendbg_send_reply("", ctx);
 102.292 -			break;
 102.293 -		case 'c': /* Resume at current address */
 102.294 -			ctx->currently_attached = 1;
 102.295 -			resume = 1;
 102.296 -			retry = 0;
 102.297 -			break;
 102.298 -		case 'Z': /* We need to claim to support these or gdb
 102.299 -			     won't let you continue the process. */
 102.300 -		case 'z':
 102.301 -			retry = xendbg_send_reply("OK", ctx);
 102.302 -			break;
 102.303 -
 102.304 -		case 's': /* Single step */
 102.305 -		case '?':
 102.306 -			retry = xendbg_send_reply("S01", ctx);
 102.307 -			break;
 102.308 -		default:
 102.309 -			retry = xendbg_send_reply("", ctx);
 102.310 -			break;
 102.311 -		}
 102.312 -		counter++;
 102.313 -	} while (retry == 1 && counter < 10);
 102.314 -	if (retry) {
 102.315 -		dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
 102.316 -		return 1;
 102.317 -	}
 102.318 -	return resume;
 102.319 -}
 102.320 -
 102.321 -static struct xendbg_context
 102.322 -xdb_ctx = {
 102.323 -	serhnd : -1
 102.324 -};
 102.325 -
 102.326 -int
 102.327 -__trap_to_cdb(struct cpu_user_regs *regs)
 102.328 -{
 102.329 -	int resume = 0;
 102.330 -	int r;
 102.331 -	static atomic_t xendbg_running = ATOMIC_INIT(1);
 102.332 -	static char recv_buf[4096];
 102.333 -	unsigned flags;
 102.334 -
 102.335 -	if (xdb_ctx.serhnd < 0) {
 102.336 -		dbg_printk("Debugger not ready yet.\n");
 102.337 -		return 0;
 102.338 -	}
 102.339 -
 102.340 -	/* We rely on our caller to ensure we're only on one processor
 102.341 -	 * at a time... We should probably panic here, but given that
 102.342 -	 * we're a debugger we should probably be a little tolerant of
 102.343 -	 * things going wrong. */
 102.344 -	/* We don't want to use a spin lock here, because we're doing
 102.345 -	   two distinct things:
 102.346 -
 102.347 -	   1 -- we don't want to run on more than one processor at a time,
 102.348 -	        and
 102.349 -	   2 -- we want to do something sensible if we re-enter ourselves.
 102.350 -
 102.351 -	   Spin locks are good for 1, but useless for 2. */
 102.352 -	if (!atomic_dec_and_test(&xendbg_running)) {
 102.353 -		printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
 102.354 -		atomic_inc(&xendbg_running);
 102.355 -		return 0;
 102.356 -	}
 102.357 -
 102.358 -	smp_send_stop();
 102.359 -
 102.360 -	/* Try to make things a little more stable by disabling
 102.361 -	   interrupts while we're here. */
 102.362 -	local_irq_save(flags);
 102.363 -
 102.364 -	watchdog_disable();
 102.365 -	console_start_sync();
 102.366 -
 102.367 -	/* Shouldn't really do this, but otherwise we stop for no
 102.368 -	   obvious reason, which is Bad */
 102.369 -	printk("Waiting for GDB to attach to XenDBG\n");
 102.370 -
 102.371 -	/* If gdb is already attached, tell it we've stopped again. */
 102.372 -	if (xdb_ctx.currently_attached) {
 102.373 -		do {
 102.374 -			r = xendbg_send_reply("S01", &xdb_ctx);
 102.375 -		} while (r != 0);
 102.376 -	}
 102.377 -
 102.378 -	while (resume == 0) {
 102.379 -		ASSERT(!local_irq_is_enabled());
 102.380 -		r = receive_command(recv_buf, &xdb_ctx);
 102.381 -		ASSERT(!local_irq_is_enabled());
 102.382 -		if (r < 0) {
 102.383 -			dbg_printk("GDB disappeared, trying to resume Xen...\n");
 102.384 -			resume = 1;
 102.385 -		} else {
 102.386 -			ASSERT(!local_irq_is_enabled());
 102.387 -			resume = process_command(recv_buf, regs, &xdb_ctx);
 102.388 -			ASSERT(!local_irq_is_enabled());
 102.389 -		}
 102.390 -	}
 102.391 -
 102.392 -	console_end_sync();
 102.393 -	watchdog_enable();
 102.394 -	atomic_inc(&xendbg_running);
 102.395 -
 102.396 -	local_irq_restore(flags);
 102.397 -
 102.398 -	return 0;
 102.399 -}
 102.400 -
 102.401 -static int
 102.402 -initialize_xendbg(void)
 102.403 -{
 102.404 -	if (!strcmp(opt_cdb, "none"))
 102.405 -		return 0;
 102.406 -	xdb_ctx.serhnd = serial_parse_handle(opt_cdb);
 102.407 -	if (xdb_ctx.serhnd == -1)
 102.408 -		panic("Can't parse %s as CDB serial info.\n", opt_cdb);
 102.409 -
 102.410 -	/* Acknowledge any spurious GDB packets. */
 102.411 -	xendbg_put_char('+', &xdb_ctx);
 102.412 -
 102.413 -	printk("Xendbg initialised.\n");
 102.414 -	return 0;
 102.415 -}
 102.416 -
 102.417 -__initcall(initialize_xendbg);
   103.1 --- a/xen/arch/x86/domain.c	Tue Jan 10 15:21:00 2006 +0000
   103.2 +++ b/xen/arch/x86/domain.c	Tue Jan 24 17:54:34 2006 +0100
   103.3 @@ -110,6 +110,20 @@ static inline void kb_wait(void)
   103.4              break;
   103.5  }
   103.6  
   103.7 +void __attribute__((noreturn)) __machine_halt(void *unused)
   103.8 +{
   103.9 +    for ( ; ; )
  103.10 +        safe_halt();
  103.11 +}
  103.12 +
  103.13 +void machine_halt(void)
  103.14 +{
  103.15 +    watchdog_disable();
  103.16 +    console_start_sync();
  103.17 +    smp_call_function(__machine_halt, NULL, 1, 0);
  103.18 +    __machine_halt(NULL);
  103.19 +}
  103.20 +
  103.21  void machine_restart(char * __unused)
  103.22  {
  103.23      int i;
  103.24 @@ -117,8 +131,7 @@ void machine_restart(char * __unused)
  103.25      if ( opt_noreboot )
  103.26      {
  103.27          printk("Reboot disabled on cmdline: require manual reset\n");
  103.28 -        for ( ; ; )
  103.29 -            safe_halt();
  103.30 +        machine_halt();
  103.31      }
  103.32  
  103.33      watchdog_disable();
  103.34 @@ -164,20 +177,6 @@ void machine_restart(char * __unused)
  103.35  }
  103.36  
  103.37  
  103.38 -void __attribute__((noreturn)) __machine_halt(void *unused)
  103.39 -{
  103.40 -    for ( ; ; )
  103.41 -        safe_halt();
  103.42 -}
  103.43 -
  103.44 -void machine_halt(void)
  103.45 -{
  103.46 -    watchdog_disable();
  103.47 -    console_start_sync();
  103.48 -    smp_call_function(__machine_halt, NULL, 1, 0);
  103.49 -    __machine_halt(NULL);
  103.50 -}
  103.51 -
  103.52  void dump_pageframe_info(struct domain *d)
  103.53  {
  103.54      struct pfn_info *page;
  103.55 @@ -215,7 +214,6 @@ struct vcpu *alloc_vcpu_struct(struct do
  103.56  
  103.57      memset(v, 0, sizeof(*v));
  103.58  
  103.59 -    memcpy(&v->arch, &idle_vcpu[0]->arch, sizeof(v->arch));
  103.60      v->arch.flags = TF_kernel_mode;
  103.61  
  103.62      if ( is_idle_domain(d) )
  103.63 @@ -223,40 +221,31 @@ struct vcpu *alloc_vcpu_struct(struct do
  103.64          percpu_ctxt[vcpu_id].curr_vcpu = v;
  103.65          v->arch.schedule_tail = continue_idle_domain;
  103.66      }
  103.67 -
  103.68 -    if ( (v->vcpu_id = vcpu_id) != 0 )
  103.69 +    else
  103.70      {
  103.71 -        v->arch.schedule_tail  = d->vcpu[0]->arch.schedule_tail;
  103.72 -        v->arch.perdomain_ptes =
  103.73 -            d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
  103.74 +        v->arch.schedule_tail = continue_nonidle_domain;
  103.75      }
  103.76  
  103.77 +    v->arch.perdomain_ptes =
  103.78 +        d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
  103.79 +
  103.80 +    v->arch.guest_vtable  = __linear_l2_table;
  103.81 +    v->arch.shadow_vtable = __shadow_linear_l2_table;
  103.82 +#if defined(__x86_64__)
  103.83 +    v->arch.guest_vl3table = __linear_l3_table;
  103.84 +    v->arch.guest_vl4table = __linear_l4_table;
  103.85 +#endif
  103.86 +
  103.87      return v;
  103.88  }
  103.89  
  103.90  void free_vcpu_struct(struct vcpu *v)
  103.91  {
  103.92 -    BUG_ON(v->next_in_list != NULL);
  103.93 -    if ( v->vcpu_id != 0 )
  103.94 -        v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
  103.95      xfree(v);
  103.96  }
  103.97  
  103.98 -void free_perdomain_pt(struct domain *d)
  103.99 +int arch_domain_create(struct domain *d)
 103.100  {
 103.101 -    free_xenheap_pages(
 103.102 -        d->arch.mm_perdomain_pt,
 103.103 -        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
 103.104 -
 103.105 -#ifdef __x86_64__
 103.106 -    free_xenheap_page(d->arch.mm_perdomain_l2);
 103.107 -    free_xenheap_page(d->arch.mm_perdomain_l3);
 103.108 -#endif
 103.109 -}
 103.110 -
 103.111 -int arch_do_createdomain(struct vcpu *v)
 103.112 -{
 103.113 -    struct domain *d = v->domain;
 103.114      l1_pgentry_t gdt_l1e;
 103.115      int vcpuid, pdpt_order, rc;
 103.116  #ifdef __x86_64__
 103.117 @@ -267,9 +256,7 @@ int arch_do_createdomain(struct vcpu *v)
 103.118      d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
 103.119      if ( d->arch.mm_perdomain_pt == NULL )
 103.120          goto fail_nomem;
 103.121 -
 103.122      memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
 103.123 -    v->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
 103.124  
 103.125      /*
 103.126       * Map Xen segments into every VCPU's GDT, irrespective of whether every
 103.127 @@ -283,20 +270,12 @@ int arch_do_createdomain(struct vcpu *v)
 103.128          d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
 103.129                                   FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
 103.130  
 103.131 -    v->arch.guest_vtable  = __linear_l2_table;
 103.132 -    v->arch.shadow_vtable = __shadow_linear_l2_table;
 103.133 -
 103.134  #if defined(__i386__)
 103.135  
 103.136 -    d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
 103.137 -        (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
 103.138 -    spin_lock_init(&d->arch.mapcache.lock);
 103.139 +    mapcache_init(d);
 103.140  
 103.141  #else /* __x86_64__ */
 103.142  
 103.143 -    v->arch.guest_vl3table = __linear_l3_table;
 103.144 -    v->arch.guest_vl4table = __linear_l4_table;
 103.145 -
 103.146      d->arch.mm_perdomain_l2 = alloc_xenheap_page();
 103.147      d->arch.mm_perdomain_l3 = alloc_xenheap_page();
 103.148      if ( (d->arch.mm_perdomain_l2 == NULL) ||
 103.149 @@ -333,10 +312,7 @@ int arch_do_createdomain(struct vcpu *v)
 103.150              goto fail_nomem;
 103.151  
 103.152          memset(d->shared_info, 0, PAGE_SIZE);
 103.153 -        v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
 103.154          SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
 103.155 -
 103.156 -        v->arch.schedule_tail = continue_nonidle_domain;
 103.157      }
 103.158  
 103.159      return 0;
 103.160 @@ -351,6 +327,20 @@ int arch_do_createdomain(struct vcpu *v)
 103.161      return -ENOMEM;
 103.162  }
 103.163  
 103.164 +void arch_domain_destroy(struct domain *d)
 103.165 +{
 103.166 +    free_xenheap_pages(
 103.167 +        d->arch.mm_perdomain_pt,
 103.168 +        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
 103.169 +
 103.170 +#ifdef __x86_64__
 103.171 +    free_xenheap_page(d->arch.mm_perdomain_l2);
 103.172 +    free_xenheap_page(d->arch.mm_perdomain_l3);
 103.173 +#endif
 103.174 +
 103.175 +    free_xenheap_page(d->shared_info);
 103.176 +}
 103.177 +
 103.178  /* This is called by arch_final_setup_guest and do_boot_vcpu */
 103.179  int arch_set_info_guest(
 103.180      struct vcpu *v, struct vcpu_guest_context *c)
 103.181 @@ -482,14 +472,6 @@ void new_thread(struct vcpu *d,
 103.182  
 103.183  #ifdef __x86_64__
 103.184  
 103.185 -void toggle_guest_mode(struct vcpu *v)
 103.186 -{
 103.187 -    v->arch.flags ^= TF_kernel_mode;
 103.188 -    __asm__ __volatile__ ( "swapgs" );
 103.189 -    update_pagetables(v);
 103.190 -    write_ptbase(v);
 103.191 -}
 103.192 -
 103.193  #define loadsegment(seg,value) ({               \
 103.194      int __r = 1;                                \
 103.195      __asm__ __volatile__ (                      \
 103.196 @@ -659,35 +641,6 @@ static void save_segments(struct vcpu *v
 103.197      percpu_ctxt[smp_processor_id()].dirty_segment_mask = dirty_segment_mask;
 103.198  }
 103.199  
 103.200 -long do_switch_to_user(void)
 103.201 -{
 103.202 -    struct cpu_user_regs  *regs = guest_cpu_user_regs();
 103.203 -    struct switch_to_user  stu;
 103.204 -    struct vcpu    *v = current;
 103.205 -
 103.206 -    if ( unlikely(copy_from_user(&stu, (void *)regs->rsp, sizeof(stu))) ||
 103.207 -         unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
 103.208 -        return -EFAULT;
 103.209 -
 103.210 -    toggle_guest_mode(v);
 103.211 -
 103.212 -    regs->rip    = stu.rip;
 103.213 -    regs->cs     = stu.cs | 3; /* force guest privilege */
 103.214 -    regs->rflags = (stu.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
 103.215 -    regs->rsp    = stu.rsp;
 103.216 -    regs->ss     = stu.ss | 3; /* force guest privilege */
 103.217 -
 103.218 -    if ( !(stu.flags & VGCF_IN_SYSCALL) )
 103.219 -    {
 103.220 -        regs->entry_vector = 0;
 103.221 -        regs->r11 = stu.r11;
 103.222 -        regs->rcx = stu.rcx;
 103.223 -    }
 103.224 -
 103.225 -    /* Saved %rax gets written back to regs->rax in entry.S. */
 103.226 -    return stu.rax;
 103.227 -}
 103.228 -
 103.229  #define switch_kernel_stack(_n,_c) ((void)0)
 103.230  
 103.231  #elif defined(__i386__)
 103.232 @@ -785,7 +738,8 @@ void context_switch(struct vcpu *prev, s
 103.233      if ( unlikely(!cpu_isset(cpu, dirty_mask) && !cpus_empty(dirty_mask)) )
 103.234      {
 103.235          /* Other cpus call __sync_lazy_execstate from flush ipi handler. */
 103.236 -        flush_tlb_mask(dirty_mask);
 103.237 +        if ( !cpus_empty(next->vcpu_dirty_cpumask) )
 103.238 +            flush_tlb_mask(next->vcpu_dirty_cpumask);
 103.239      }
 103.240  
 103.241      local_irq_disable();
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/xen/arch/x86/gdbstub.c	Tue Jan 24 17:54:34 2006 +0100
   104.3 @@ -0,0 +1,146 @@
   104.4 +/*
   104.5 + * x86-specific gdb stub routines
   104.6 + * based on x86 cdb(xen/arch/x86/cdb.c), but Extensively modified.
   104.7 + * 
   104.8 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
   104.9 + *                    VA Linux Systems Japan. K.K.
  104.10 + *
  104.11 + * This program is free software; you can redistribute it and/or modify
  104.12 + * it under the terms of the GNU General Public License as published by
  104.13 + * the Free Software Foundation; either version 2 of the License, or
  104.14 + * (at your option) any later version.
  104.15 + * 
  104.16 + * This program is distributed in the hope that it will be useful,
  104.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  104.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  104.19 + * GNU General Public License for more details.
  104.20 + * 
  104.21 + * You should have received a copy of the GNU General Public License
  104.22 + * along with this program; if not, write to the Free Software
  104.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  104.24 + */
  104.25 +#include <asm/debugger.h>
  104.26 +
  104.27 +u16
  104.28 +gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
  104.29 +{
  104.30 +    /* XXX */
  104.31 +    return 1;
  104.32 +}
  104.33 +
  104.34 +void 
  104.35 +gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
  104.36 +{
  104.37 +#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
  104.38 +    GDB_REG(regs->eax);
  104.39 +    GDB_REG(regs->ecx);
  104.40 +    GDB_REG(regs->edx);
  104.41 +    GDB_REG(regs->ebx);
  104.42 +    GDB_REG(regs->esp);
  104.43 +    GDB_REG(regs->ebp);
  104.44 +    GDB_REG(regs->esi);
  104.45 +    GDB_REG(regs->edi);
  104.46 +    GDB_REG(regs->eip);
  104.47 +    GDB_REG(regs->eflags);
  104.48 +#undef GDB_REG
  104.49 +#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
  104.50 +    /* sizeof(segment) = 16bit */
  104.51 +    /* but gdb requires its return value as 32bit value */
  104.52 +    GDB_SEG_REG(regs->cs);
  104.53 +    GDB_SEG_REG(regs->ss);
  104.54 +    GDB_SEG_REG(regs->ds);
  104.55 +    GDB_SEG_REG(regs->es);
  104.56 +    GDB_SEG_REG(regs->fs);
  104.57 +    GDB_SEG_REG(regs->gs);
  104.58 +#undef GDB_SEG_REG
  104.59 +    gdb_send_packet(ctx);
  104.60 +}
  104.61 +
  104.62 +void 
  104.63 +gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
  104.64 +                         struct gdb_context *ctx)
  104.65 +{
  104.66 +    /* XXX TODO */
  104.67 +    gdb_send_reply("E02", ctx);
  104.68 +}
  104.69 +
  104.70 +void 
  104.71 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
  104.72 +                  struct gdb_context *ctx)
  104.73 +{
  104.74 +    gdb_send_reply("", ctx);
  104.75 +}
  104.76 +
  104.77 +/* Like copy_from_user, but safe to call with interrupts disabled.
  104.78 +   Trust me, and don't look behind the curtain. */
  104.79 +unsigned 
  104.80 +gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
  104.81 +{
  104.82 +    int __d0, __d1, __d2;
  104.83 +    ASSERT(!local_irq_is_enabled());
  104.84 +    __asm__ __volatile__(
  104.85 +        "1: rep; movsb\n"
  104.86 +        "2:\n"
  104.87 +        ".section .fixup,\"ax\"\n"
  104.88 +        "3:     addl $4, %%esp\n"
  104.89 +        "       jmp 2b\n"
  104.90 +        ".previous\n"
  104.91 +        ".section __pre_ex_table,\"a\"\n"
  104.92 +        "   "__FIXUP_ALIGN"\n"
  104.93 +        "   "__FIXUP_WORD" 1b,3b\n"
  104.94 +        ".previous\n"
  104.95 +        ".section __ex_table,\"a\"\n"
  104.96 +        "   "__FIXUP_ALIGN"\n"
  104.97 +        "   "__FIXUP_WORD" 1b,2b\n"
  104.98 +        ".previous\n"
  104.99 +        : "=c"(__d2), "=D" (__d0), "=S" (__d1)
 104.100 +        : "0"(len), "1"(dest), "2"(src)
 104.101 +        : "memory");
 104.102 +    ASSERT(!local_irq_is_enabled());
 104.103 +    return __d2;
 104.104 +}
 104.105 +
 104.106 +unsigned int 
 104.107 +gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
 104.108 +{
 104.109 +    /* XXX  */
 104.110 +    return len;
 104.111 +}
 104.112 +
 104.113 +void 
 104.114 +gdb_arch_resume(struct cpu_user_regs *regs,
 104.115 +                unsigned long addr, unsigned long type,
 104.116 +                struct gdb_context *ctx)
 104.117 +{
 104.118 +    /* XXX */
 104.119 +    if (type == GDB_STEP) {
 104.120 +        gdb_send_reply("S01", ctx);
 104.121 +    }
 104.122 +}
 104.123 +
 104.124 +void
 104.125 +gdb_arch_print_state(struct cpu_user_regs *regs)
 104.126 +{
 104.127 +    /* XXX */
 104.128 +}
 104.129 +
 104.130 +void
 104.131 +gdb_arch_enter(struct cpu_user_regs *regs)
 104.132 +{
 104.133 +    /* nothing */
 104.134 +}
 104.135 +
 104.136 +void
 104.137 +gdb_arch_exit(struct cpu_user_regs *regs)
 104.138 +{
 104.139 +    /* nothing */
 104.140 +}
 104.141 +
 104.142 +/*
 104.143 + * Local variables:
 104.144 + * mode: C
 104.145 + * c-set-style: "BSD"
 104.146 + * c-basic-offset: 4
 104.147 + * tab-width: 4
 104.148 + * End:
 104.149 + */
   105.1 --- a/xen/arch/x86/mm.c	Tue Jan 10 15:21:00 2006 +0000
   105.2 +++ b/xen/arch/x86/mm.c	Tue Jan 24 17:54:34 2006 +0100
   105.3 @@ -297,7 +297,6 @@ int map_ldt_shadow_page(unsigned int off
   105.4  
   105.5  #if defined(__x86_64__)
   105.6      /* If in user mode, switch to kernel mode just to read LDT mapping. */
   105.7 -    extern void toggle_guest_mode(struct vcpu *);
   105.8      int user_mode = !(v->arch.flags & TF_kernel_mode);
   105.9  #define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
  105.10  #elif defined(__i386__)
  105.11 @@ -2971,7 +2970,6 @@ void ptwr_flush(struct domain *d, const 
  105.12  
  105.13  #ifdef CONFIG_X86_64
  105.14      struct vcpu *v = current;
  105.15 -    extern void toggle_guest_mode(struct vcpu *);
  105.16      int user_mode = !(v->arch.flags & TF_kernel_mode);
  105.17  #endif
  105.18  
  105.19 @@ -3001,7 +2999,7 @@ void ptwr_flush(struct domain *d, const 
  105.20          BUG();
  105.21      }
  105.22      PTWR_PRINTK("[%c] disconnected_l1va at %p is %"PRIpte"\n",
  105.23 -                PTWR_PRINT_WHICH, ptep, pte.l1);
  105.24 +                PTWR_PRINT_WHICH, ptep, l1e_get_intpte(pte));
  105.25      l1e_remove_flags(pte, _PAGE_RW);
  105.26  
  105.27      /* Write-protect the p.t. page in the guest page table. */
  105.28 @@ -3019,18 +3017,31 @@ void ptwr_flush(struct domain *d, const 
  105.29      /* NB. INVLPG is a serialising instruction: flushes pending updates. */
  105.30      flush_tlb_one_mask(d->domain_dirty_cpumask, l1va);
  105.31      PTWR_PRINTK("[%c] disconnected_l1va at %p now %"PRIpte"\n",
  105.32 -                PTWR_PRINT_WHICH, ptep, pte.l1);
  105.33 +                PTWR_PRINT_WHICH, ptep, l1e_get_intpte(pte));
  105.34  
  105.35      /*
  105.36       * STEP 2. Validate any modified PTEs.
  105.37       */
  105.38  
  105.39 -    pl1e = d->arch.ptwr[which].pl1e;
  105.40 -    modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
  105.41 -    unmap_domain_page(pl1e);
  105.42 -    perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
  105.43 -    ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
  105.44 -    d->arch.ptwr[which].prev_nr_updates = modified;
  105.45 +    if ( likely(d == current->domain) )
  105.46 +    {
  105.47 +        pl1e = map_domain_page(l1e_get_pfn(pte));
  105.48 +        modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
  105.49 +        unmap_domain_page(pl1e);
  105.50 +        perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
  105.51 +        ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
  105.52 +        d->arch.ptwr[which].prev_nr_updates = modified;
  105.53 +    }
  105.54 +    else
  105.55 +    {
  105.56 +        /*
  105.57 +         * Must make a temporary global mapping, since we are running in the
  105.58 +         * wrong address space, so no access to our own mapcache.
  105.59 +         */
  105.60 +        pl1e = map_domain_page_global(l1e_get_pfn(pte));
  105.61 +        modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
  105.62 +        unmap_domain_page_global(pl1e);
  105.63 +    }
  105.64  
  105.65      /*
  105.66       * STEP 3. Reattach the L1 p.t. page into the current address space.
  105.67 @@ -3208,7 +3219,7 @@ int ptwr_do_page_fault(struct domain *d,
  105.68  {
  105.69      unsigned long    pfn;
  105.70      struct pfn_info *page;
  105.71 -    l1_pgentry_t     pte;
  105.72 +    l1_pgentry_t    *pl1e, pte;
  105.73      l2_pgentry_t    *pl2e, l2e;
  105.74      int              which, flags;
  105.75      unsigned long    l2_idx;
  105.76 @@ -3345,11 +3356,10 @@ int ptwr_do_page_fault(struct domain *d,
  105.77      }
  105.78      
  105.79      /* Temporarily map the L1 page, and make a copy of it. */
  105.80 -    d->arch.ptwr[which].pl1e = map_domain_page(pfn);
  105.81 -    memcpy(d->arch.ptwr[which].page,
  105.82 -           d->arch.ptwr[which].pl1e,
  105.83 -           L1_PAGETABLE_ENTRIES * sizeof(l1_pgentry_t));
  105.84 -    
  105.85 +    pl1e = map_domain_page(pfn);
  105.86 +    memcpy(d->arch.ptwr[which].page, pl1e, PAGE_SIZE);
  105.87 +    unmap_domain_page(pl1e);
  105.88 +
  105.89      /* Finally, make the p.t. page writable by the guest OS. */
  105.90      l1e_add_flags(pte, _PAGE_RW);
  105.91      if ( unlikely(__put_user(pte.l1,
  105.92 @@ -3358,7 +3368,6 @@ int ptwr_do_page_fault(struct domain *d,
  105.93          MEM_LOG("ptwr: Could not update pte at %p", (unsigned long *)
  105.94                  &linear_pg_table[l1_linear_offset(addr)]);
  105.95          /* Toss the writable pagetable state and crash. */
  105.96 -        unmap_domain_page(d->arch.ptwr[which].pl1e);
  105.97          d->arch.ptwr[which].l1va = 0;
  105.98          domain_crash(d);
  105.99          return 0;
   106.1 --- a/xen/arch/x86/nmi.c	Tue Jan 10 15:21:00 2006 +0000
   106.2 +++ b/xen/arch/x86/nmi.c	Tue Jan 24 17:54:34 2006 +0100
   106.3 @@ -23,18 +23,20 @@
   106.4  #include <xen/sched.h>
   106.5  #include <xen/console.h>
   106.6  #include <xen/smp.h>
   106.7 +#include <xen/keyhandler.h>
   106.8  #include <asm/current.h>
   106.9  #include <asm/mc146818rtc.h>
  106.10  #include <asm/msr.h>
  106.11  #include <asm/mpspec.h>
  106.12  #include <asm/debugger.h>
  106.13  #include <asm/div64.h>
  106.14 +#include <asm/apic.h>
  106.15  
  106.16  unsigned int nmi_watchdog = NMI_NONE;
  106.17  static unsigned int nmi_hz = HZ;
  106.18  static unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
  106.19  static unsigned int nmi_p4_cccr_val;
  106.20 -static struct ac_timer nmi_timer[NR_CPUS];
  106.21 +static struct timer nmi_timer[NR_CPUS];
  106.22  static unsigned int nmi_timer_ticks[NR_CPUS];
  106.23  
  106.24  /*
  106.25 @@ -132,7 +134,7 @@ static void nmi_timer_fn(void *unused)
  106.26  {
  106.27      int cpu = smp_processor_id();
  106.28      nmi_timer_ticks[cpu]++;
  106.29 -    set_ac_timer(&nmi_timer[cpu], NOW() + MILLISECS(1000));
  106.30 +    set_timer(&nmi_timer[cpu], NOW() + MILLISECS(1000));
  106.31  }
  106.32  
  106.33  static void disable_lapic_nmi_watchdog(void)
  106.34 @@ -308,8 +310,6 @@ static int __pminit setup_p4_watchdog(vo
  106.35  
  106.36  void __pminit setup_apic_nmi_watchdog(void)
  106.37  {
  106.38 -    int cpu = smp_processor_id();
  106.39 -
  106.40      if (!nmi_watchdog)
  106.41          return;
  106.42  
  106.43 @@ -344,49 +344,37 @@ void __pminit setup_apic_nmi_watchdog(vo
  106.44  
  106.45      lapic_nmi_owner = LAPIC_NMI_WATCHDOG;
  106.46      nmi_active = 1;
  106.47 -
  106.48 -    init_ac_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
  106.49  }
  106.50  
  106.51  static unsigned int
  106.52  last_irq_sums [NR_CPUS],
  106.53      alert_counter [NR_CPUS];
  106.54  
  106.55 -static spinlock_t   watchdog_lock = SPIN_LOCK_UNLOCKED;
  106.56 -static unsigned int watchdog_disable_count = 1;
  106.57 -static unsigned int watchdog_on;
  106.58 +static atomic_t watchdog_disable_count = ATOMIC_INIT(1);
  106.59  
  106.60  void watchdog_disable(void)
  106.61  {
  106.62 -    unsigned long flags;
  106.63 -
  106.64 -    spin_lock_irqsave(&watchdog_lock, flags);
  106.65 -
  106.66 -    if ( watchdog_disable_count++ == 0 )
  106.67 -        watchdog_on = 0;
  106.68 -
  106.69 -    spin_unlock_irqrestore(&watchdog_lock, flags);
  106.70 +    atomic_inc(&watchdog_disable_count);
  106.71  }
  106.72  
  106.73  void watchdog_enable(void)
  106.74  {
  106.75 -    unsigned int  cpu;
  106.76 -    unsigned long flags;
  106.77 +    static unsigned long heartbeat_initialised;
  106.78 +    unsigned int cpu;
  106.79  
  106.80 -    spin_lock_irqsave(&watchdog_lock, flags);
  106.81 +    if ( !atomic_dec_and_test(&watchdog_disable_count) ||
  106.82 +         test_and_set_bit(0, &heartbeat_initialised) )
  106.83 +        return;
  106.84  
  106.85 -    if ( --watchdog_disable_count == 0 )
  106.86 +    /*
  106.87 +     * Activate periodic heartbeats. We cannot do this earlier during 
  106.88 +     * setup because the timer infrastructure is not available.
  106.89 +     */
  106.90 +    for_each_online_cpu ( cpu )
  106.91      {
  106.92 -        watchdog_on = 1;
  106.93 -        /*
  106.94 -         * Ensure periodic heartbeats are active. We cannot do this earlier
  106.95 -         * during setup because the timer infrastructure is not available. 
  106.96 -         */
  106.97 -        for_each_online_cpu ( cpu )
  106.98 -            set_ac_timer(&nmi_timer[cpu], NOW());
  106.99 +        init_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
 106.100 +        set_timer(&nmi_timer[cpu], NOW());
 106.101      }
 106.102 -
 106.103 -    spin_unlock_irqrestore(&watchdog_lock, flags);
 106.104  }
 106.105  
 106.106  void nmi_watchdog_tick(struct cpu_user_regs * regs)
 106.107 @@ -395,7 +383,7 @@ void nmi_watchdog_tick(struct cpu_user_r
 106.108  
 106.109      sum = nmi_timer_ticks[cpu];
 106.110  
 106.111 -    if ( (last_irq_sums[cpu] == sum) && watchdog_on )
 106.112 +    if ( (last_irq_sums[cpu] == sum) && !atomic_read(&watchdog_disable_count) )
 106.113      {
 106.114          /*
 106.115           * Ayiee, looks like this CPU is stuck ... wait a few IRQs (5 seconds) 
 106.116 @@ -440,3 +428,51 @@ void nmi_watchdog_tick(struct cpu_user_r
 106.117          write_watchdog_counter(NULL);
 106.118      }
 106.119  }
 106.120 +
 106.121 +/*
 106.122 + * For some reason the destination shorthand for self is not valid
 106.123 + * when used with the NMI delivery mode. This is documented in Tables
 106.124 + * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to
 106.125 + * our own APIC ID explicitly which is valid.
 106.126 + */
 106.127 +static void do_nmi_trigger(unsigned char key)
 106.128 +{
 106.129 +    u32 id = apic_read(APIC_ID);
 106.130 +
 106.131 +    printk("Triggering NMI on APIC ID %x\n", id);
 106.132 +
 106.133 +    local_irq_disable();
 106.134 +    apic_wait_icr_idle();
 106.135 +    apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(id));
 106.136 +    apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_INT_ASSERT);
 106.137 +    local_irq_enable();
 106.138 +}
 106.139 +
 106.140 +static void do_nmi_stats(unsigned char key)
 106.141 +{
 106.142 +    int i;
 106.143 +    struct domain *d;
 106.144 +    struct vcpu *v;
 106.145 +    printk("CPU\tNMI\n");
 106.146 +    for_each_cpu(i)
 106.147 +        printk("%3d\t%3d\n", i, nmi_count(i));
 106.148 +
 106.149 +    if ((d = dom0) == NULL)
 106.150 +        return;
 106.151 +    if ((v = d->vcpu[0]) == NULL)
 106.152 +        return;
 106.153 +    if (v->vcpu_flags & (VCPUF_nmi_pending|VCPUF_nmi_masked))
 106.154 +        printk("dom0 vpu0: NMI %s%s\n",
 106.155 +               v->vcpu_flags & VCPUF_nmi_pending ? "pending " : "",
 106.156 +               v->vcpu_flags & VCPUF_nmi_masked ? "masked " : "");
 106.157 +    else
 106.158 +        printk("dom0 vcpu0: NMI neither pending nor masked\n");
 106.159 +}
 106.160 +
 106.161 +static __init int register_nmi_trigger(void)
 106.162 +{
 106.163 +    register_keyhandler('n', do_nmi_trigger, "trigger an NMI");
 106.164 +    register_keyhandler('N', do_nmi_stats,   "NMI statistics");
 106.165 +    return 0;
 106.166 +}
 106.167 +__initcall(register_nmi_trigger);
   107.1 --- a/xen/arch/x86/setup.c	Tue Jan 10 15:21:00 2006 +0000
   107.2 +++ b/xen/arch/x86/setup.c	Tue Jan 24 17:54:34 2006 +0100
   107.3 @@ -385,7 +385,7 @@ void __init __start_xen(multiboot_info_t
   107.4  
   107.5      scheduler_init();
   107.6  
   107.7 -    idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
   107.8 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
   107.9      BUG_ON(idle_domain == NULL);
  107.10  
  107.11      set_current(idle_domain->vcpu[0]);
  107.12 @@ -423,7 +423,7 @@ void __init __start_xen(multiboot_info_t
  107.13  
  107.14      trap_init();
  107.15  
  107.16 -    ac_timer_init();
  107.17 +    timer_init();
  107.18  
  107.19      early_time_init();
  107.20  
  107.21 @@ -478,7 +478,8 @@ void __init __start_xen(multiboot_info_t
  107.22  
  107.23      schedulers_start();
  107.24  
  107.25 -    watchdog_enable();
  107.26 +    if ( opt_watchdog ) 
  107.27 +        watchdog_enable();
  107.28  
  107.29      shadow_mode_init();
  107.30  
  107.31 @@ -486,7 +487,7 @@ void __init __start_xen(multiboot_info_t
  107.32      acm_init(&initrdidx, mbi, initial_images_start);
  107.33  
  107.34      /* Create initial domain 0. */
  107.35 -    dom0 = do_createdomain(0, 0);
  107.36 +    dom0 = domain_create(0, 0);
  107.37      if ( dom0 == NULL )
  107.38          panic("Error creating domain 0\n");
  107.39  
   108.1 --- a/xen/arch/x86/shadow.c	Tue Jan 10 15:21:00 2006 +0000
   108.2 +++ b/xen/arch/x86/shadow.c	Tue Jan 24 17:54:34 2006 +0100
   108.3 @@ -469,6 +469,7 @@ static unsigned long shadow_l2_table(
   108.4  {
   108.5      unsigned long smfn;
   108.6      l2_pgentry_t *spl2e;
   108.7 +    int i;
   108.8  
   108.9      SH_VVLOG("shadow_l2_table(gpfn=%lx, gmfn=%lx)", gpfn, gmfn);
  108.10  
  108.11 @@ -503,9 +504,11 @@ static unsigned long shadow_l2_table(
  108.12          spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
  108.13              l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
  108.14  
  108.15 -        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
  108.16 -            l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
  108.17 -                            __PAGE_HYPERVISOR);
  108.18 +        for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
  108.19 +            spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
  108.20 +                l2e_from_page(virt_to_page(page_get_owner(pfn_to_page(gmfn))->
  108.21 +                                           arch.mm_perdomain_pt) + i,
  108.22 +                              __PAGE_HYPERVISOR);
  108.23  
  108.24          if ( shadow_mode_translate(d) ) // NB: not external
  108.25          {
  108.26 @@ -2135,6 +2138,7 @@ static void shadow_update_pagetables(str
  108.27  #if CONFIG_PAGING_LEVELS == 2
  108.28      unsigned long hl2mfn;
  108.29  #endif
  108.30 +    int need_sync = 0;
  108.31  
  108.32      int max_mode = ( shadow_mode_external(d) ? SHM_external
  108.33                       : shadow_mode_translate(d) ? SHM_translate
  108.34 @@ -2150,8 +2154,8 @@ static void shadow_update_pagetables(str
  108.35      if ( max_mode & (SHM_enable | SHM_external) )
  108.36      {
  108.37          if ( likely(v->arch.guest_vtable != NULL) )
  108.38 -            unmap_domain_page(v->arch.guest_vtable);
  108.39 -        v->arch.guest_vtable = map_domain_page(gmfn);
  108.40 +            unmap_domain_page_global(v->arch.guest_vtable);
  108.41 +        v->arch.guest_vtable = map_domain_page_global(gmfn);
  108.42      }
  108.43  
  108.44      /*
  108.45 @@ -2166,8 +2170,17 @@ static void shadow_update_pagetables(str
  108.46  #elif CONFIG_PAGING_LEVELS == 4
  108.47          smfn = shadow_l4_table(d, gpfn, gmfn);
  108.48  #endif
  108.49 -    }else
  108.50 -        shadow_sync_all(d);
  108.51 +    }
  108.52 +    else
  108.53 +    {
  108.54 +        /*
  108.55 +         *  move sync later in order to avoid this smfn been 
  108.56 +         *  unshadowed occasionally
  108.57 +         */
  108.58 +        need_sync = 1;
  108.59 +    }
  108.60 +
  108.61 +
  108.62      if ( !get_shadow_ref(smfn) )
  108.63          BUG();
  108.64      old_smfn = pagetable_get_pfn(v->arch.shadow_table);
  108.65 @@ -2187,8 +2200,8 @@ static void shadow_update_pagetables(str
  108.66          )
  108.67      {
  108.68          if ( v->arch.shadow_vtable )
  108.69 -            unmap_domain_page(v->arch.shadow_vtable);
  108.70 -        v->arch.shadow_vtable = map_domain_page(smfn);
  108.71 +            unmap_domain_page_global(v->arch.shadow_vtable);
  108.72 +        v->arch.shadow_vtable = map_domain_page_global(smfn);
  108.73      }
  108.74  
  108.75  #if CONFIG_PAGING_LEVELS == 2
  108.76 @@ -2204,8 +2217,8 @@ static void shadow_update_pagetables(str
  108.77          if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
  108.78              hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
  108.79          if ( v->arch.hl2_vtable )
  108.80 -            unmap_domain_page(v->arch.hl2_vtable);
  108.81 -        v->arch.hl2_vtable = map_domain_page(hl2mfn);
  108.82 +            unmap_domain_page_global(v->arch.hl2_vtable);
  108.83 +        v->arch.hl2_vtable = map_domain_page_global(hl2mfn);
  108.84      }
  108.85  
  108.86      /*
  108.87 @@ -2238,6 +2251,9 @@ static void shadow_update_pagetables(str
  108.88      }
  108.89  #endif /* CONFIG_PAGING_LEVELS == 2 */
  108.90  
  108.91 +    if(likely(need_sync))
  108.92 +        shadow_sync_all(d);
  108.93 +
  108.94  #if CONFIG_PAGING_LEVELS == 3
  108.95      /* FIXME: PAE code to be written */
  108.96  #endif
   109.1 --- a/xen/arch/x86/shadow32.c	Tue Jan 10 15:21:00 2006 +0000
   109.2 +++ b/xen/arch/x86/shadow32.c	Tue Jan 24 17:54:34 2006 +0100
   109.3 @@ -726,6 +726,7 @@ static void alloc_monitor_pagetable(stru
   109.4      l2_pgentry_t *mpl2e;
   109.5      struct pfn_info *mmfn_info;
   109.6      struct domain *d = v->domain;
   109.7 +    int i;
   109.8  
   109.9      ASSERT(pagetable_get_paddr(v->arch.monitor_table) == 0);
  109.10  
  109.11 @@ -733,16 +734,17 @@ static void alloc_monitor_pagetable(stru
  109.12      ASSERT(mmfn_info != NULL);
  109.13  
  109.14      mmfn = page_to_pfn(mmfn_info);
  109.15 -    mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
  109.16 +    mpl2e = (l2_pgentry_t *)map_domain_page_global(mmfn);
  109.17      memset(mpl2e, 0, PAGE_SIZE);
  109.18  
  109.19      memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
  109.20             &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
  109.21             HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
  109.22  
  109.23 -    mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
  109.24 -        l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
  109.25 -                        __PAGE_HYPERVISOR);
  109.26 +    for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
  109.27 +        mpl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
  109.28 +            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
  109.29 +                          __PAGE_HYPERVISOR);
  109.30  
  109.31      // map the phys_to_machine map into the Read-Only MPT space for this domain
  109.32      mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
  109.33 @@ -794,7 +796,7 @@ void free_monitor_pagetable(struct vcpu 
  109.34       * Then free monitor_table.
  109.35       */
  109.36      mfn = pagetable_get_pfn(v->arch.monitor_table);
  109.37 -    unmap_domain_page(v->arch.monitor_vtable);
  109.38 +    unmap_domain_page_global(v->arch.monitor_vtable);
  109.39      free_domheap_page(pfn_to_page(mfn));
  109.40  
  109.41      v->arch.monitor_table = mk_pagetable(0);
  109.42 @@ -929,7 +931,7 @@ int __shadow_mode_enable(struct domain *
  109.43          if ( v->arch.guest_vtable &&
  109.44               (v->arch.guest_vtable != __linear_l2_table) )
  109.45          {
  109.46 -            unmap_domain_page(v->arch.guest_vtable);
  109.47 +            unmap_domain_page_global(v->arch.guest_vtable);
  109.48          }
  109.49          if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
  109.50              v->arch.guest_vtable = __linear_l2_table;
  109.51 @@ -942,7 +944,7 @@ int __shadow_mode_enable(struct domain *
  109.52          if ( v->arch.shadow_vtable &&
  109.53               (v->arch.shadow_vtable != __shadow_linear_l2_table) )
  109.54          {
  109.55 -            unmap_domain_page(v->arch.shadow_vtable);
  109.56 +            unmap_domain_page_global(v->arch.shadow_vtable);
  109.57          }
  109.58          if ( !(mode & SHM_external) )
  109.59              v->arch.shadow_vtable = __shadow_linear_l2_table;
  109.60 @@ -955,7 +957,7 @@ int __shadow_mode_enable(struct domain *
  109.61          if ( v->arch.hl2_vtable &&
  109.62               (v->arch.hl2_vtable != __linear_hl2_table) )
  109.63          {
  109.64 -            unmap_domain_page(v->arch.hl2_vtable);
  109.65 +            unmap_domain_page_global(v->arch.hl2_vtable);
  109.66          }
  109.67          if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
  109.68              v->arch.hl2_vtable = __linear_hl2_table;
  109.69 @@ -1508,6 +1510,7 @@ static unsigned long shadow_l2_table(
  109.70  {
  109.71      unsigned long smfn;
  109.72      l2_pgentry_t *spl2e;
  109.73 +    int i;
  109.74  
  109.75      SH_VVLOG("shadow_l2_table(gpfn=%lx, gmfn=%lx)", gpfn, gmfn);
  109.76  
  109.77 @@ -1542,9 +1545,11 @@ static unsigned long shadow_l2_table(
  109.78          spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
  109.79              l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
  109.80  
  109.81 -        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
  109.82 -            l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
  109.83 -                            __PAGE_HYPERVISOR);
  109.84 +        for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
  109.85 +            spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
  109.86 +            l2e_from_page(virt_to_page(page_get_owner(pfn_to_page(gmfn))->
  109.87 +                                       arch.mm_perdomain_pt) + i,
  109.88 +                          __PAGE_HYPERVISOR);
  109.89  
  109.90          if ( shadow_mode_translate(d) ) // NB: not external
  109.91          {
  109.92 @@ -2891,6 +2896,7 @@ void __update_pagetables(struct vcpu *v)
  109.93      unsigned long gmfn = pagetable_get_pfn(v->arch.guest_table);
  109.94      unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
  109.95      unsigned long smfn, hl2mfn, old_smfn;
  109.96 +    int need_sync = 0;
  109.97  
  109.98      int max_mode = ( shadow_mode_external(d) ? SHM_external
  109.99                       : shadow_mode_translate(d) ? SHM_translate
 109.100 @@ -2906,8 +2912,8 @@ void __update_pagetables(struct vcpu *v)
 109.101      if ( max_mode & (SHM_enable | SHM_external) )
 109.102      {
 109.103          if ( likely(v->arch.guest_vtable != NULL) )
 109.104 -            unmap_domain_page(v->arch.guest_vtable);
 109.105 -        v->arch.guest_vtable = map_domain_page(gmfn);
 109.106 +            unmap_domain_page_global(v->arch.guest_vtable);
 109.107 +        v->arch.guest_vtable = map_domain_page_global(gmfn);
 109.108      }
 109.109  
 109.110      /*
 109.111 @@ -2916,7 +2922,13 @@ void __update_pagetables(struct vcpu *v)
 109.112      if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_base_page_table))) )
 109.113          smfn = shadow_l2_table(d, gpfn, gmfn);
 109.114      else
 109.115 -        shadow_sync_all(d);
 109.116 +    {
 109.117 +        /*
 109.118 +         *  move sync later in order to avoid this smfn been 
 109.119 +         *  unshadowed occasionally
 109.120 +         */
 109.121 +        need_sync = 1;
 109.122 +    }
 109.123      if ( !get_shadow_ref(smfn) )
 109.124          BUG();
 109.125      old_smfn = pagetable_get_pfn(v->arch.shadow_table);
 109.126 @@ -2932,8 +2944,8 @@ void __update_pagetables(struct vcpu *v)
 109.127      if ( max_mode == SHM_external )
 109.128      {
 109.129          if ( v->arch.shadow_vtable )
 109.130 -            unmap_domain_page(v->arch.shadow_vtable);
 109.131 -        v->arch.shadow_vtable = map_domain_page(smfn);
 109.132 +            unmap_domain_page_global(v->arch.shadow_vtable);
 109.133 +        v->arch.shadow_vtable = map_domain_page_global(smfn);
 109.134      }
 109.135  
 109.136      /*
 109.137 @@ -2948,8 +2960,8 @@ void __update_pagetables(struct vcpu *v)
 109.138          if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
 109.139              hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
 109.140          if ( v->arch.hl2_vtable )
 109.141 -            unmap_domain_page(v->arch.hl2_vtable);
 109.142 -        v->arch.hl2_vtable = map_domain_page(hl2mfn);
 109.143 +            unmap_domain_page_global(v->arch.hl2_vtable);
 109.144 +        v->arch.hl2_vtable = map_domain_page_global(hl2mfn);
 109.145      }
 109.146  
 109.147      /*
 109.148 @@ -2980,6 +2992,9 @@ void __update_pagetables(struct vcpu *v)
 109.149          // XXX - maybe this can be optimized somewhat??
 109.150          local_flush_tlb();
 109.151      }
 109.152 +
 109.153 +    if(likely(need_sync))
 109.154 +        shadow_sync_all(d);
 109.155  }
 109.156  
 109.157  void clear_all_shadow_status(struct domain *d)
   110.1 --- a/xen/arch/x86/shadow_public.c	Tue Jan 10 15:21:00 2006 +0000
   110.2 +++ b/xen/arch/x86/shadow_public.c	Tue Jan 24 17:54:34 2006 +0100
   110.3 @@ -151,6 +151,8 @@ free_shadow_fl1_table(struct domain *d, 
   110.4  
   110.5      for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
   110.6          put_page_from_l1e(pl1e[i], d);
   110.7 +
   110.8 +    unmap_domain_page(pl1e);
   110.9  }
  110.10  
  110.11  /*
  110.12 @@ -254,6 +256,7 @@ static pagetable_t page_table_convert(st
  110.13      pae_l3 = map_domain_page(pagetable_get_pfn(d->arch.phys_table));
  110.14      for (i = 0; i < PDP_ENTRIES; i++)
  110.15          l3[i] = l3e_from_pfn(l3e_get_pfn(pae_l3[i]), __PAGE_HYPERVISOR);
  110.16 +    unmap_domain_page(pae_l3);
  110.17  
  110.18      unmap_domain_page(l4);
  110.19      unmap_domain_page(l3);
  110.20 @@ -275,7 +278,7 @@ static void alloc_monitor_pagetable(stru
  110.21      ASSERT( mmfn_info );
  110.22  
  110.23      mmfn = page_to_pfn(mmfn_info);
  110.24 -    mpl4e = (l4_pgentry_t *) map_domain_page(mmfn);
  110.25 +    mpl4e = (l4_pgentry_t *) map_domain_page_global(mmfn);
  110.26      memcpy(mpl4e, &idle_pg_table[0], PAGE_SIZE);
  110.27      mpl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
  110.28          l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
  110.29 @@ -298,7 +301,7 @@ void free_monitor_pagetable(struct vcpu 
  110.30       * free monitor_table.
  110.31       */
  110.32      mfn = pagetable_get_pfn(v->arch.monitor_table);
  110.33 -    unmap_domain_page(v->arch.monitor_vtable);
  110.34 +    unmap_domain_page_global(v->arch.monitor_vtable);
  110.35      free_domheap_page(pfn_to_page(mfn));
  110.36  
  110.37      v->arch.monitor_table = mk_pagetable(0);
  110.38 @@ -325,6 +328,7 @@ static void alloc_monitor_pagetable(stru
  110.39      l2_pgentry_t *mpl2e;
  110.40      struct pfn_info *mmfn_info;
  110.41      struct domain *d = v->domain;
  110.42 +    int i;
  110.43  
  110.44      ASSERT(pagetable_get_paddr(v->arch.monitor_table) == 0);
  110.45  
  110.46 @@ -332,16 +336,17 @@ static void alloc_monitor_pagetable(stru
  110.47      ASSERT(mmfn_info != NULL);
  110.48  
  110.49      mmfn = page_to_pfn(mmfn_info);
  110.50 -    mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
  110.51 +    mpl2e = (l2_pgentry_t *)map_domain_page_global(mmfn);
  110.52      memset(mpl2e, 0, PAGE_SIZE);
  110.53  
  110.54      memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
  110.55             &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
  110.56             HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
  110.57  
  110.58 -    mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
  110.59 -        l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
  110.60 -                       __PAGE_HYPERVISOR);
  110.61 +    for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
  110.62 +        mpl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
  110.63 +            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
  110.64 +                          __PAGE_HYPERVISOR);
  110.65  
  110.66      // map the phys_to_machine map into the Read-Only MPT space for this domain
  110.67      mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
  110.68 @@ -393,7 +398,7 @@ void free_monitor_pagetable(struct vcpu 
  110.69       * Then free monitor_table.
  110.70       */
  110.71      mfn = pagetable_get_pfn(v->arch.monitor_table);
  110.72 -    unmap_domain_page(v->arch.monitor_vtable);
  110.73 +    unmap_domain_page_global(v->arch.monitor_vtable);
  110.74      free_domheap_page(pfn_to_page(mfn));
  110.75  
  110.76      v->arch.monitor_table = mk_pagetable(0);
  110.77 @@ -977,7 +982,7 @@ int __shadow_mode_enable(struct domain *
  110.78          if ( v->arch.guest_vtable &&
  110.79               (v->arch.guest_vtable != __linear_l2_table) )
  110.80          {
  110.81 -            unmap_domain_page(v->arch.guest_vtable);
  110.82 +            unmap_domain_page_global(v->arch.guest_vtable);
  110.83          }
  110.84          if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
  110.85              v->arch.guest_vtable = __linear_l2_table;
  110.86 @@ -990,7 +995,7 @@ int __shadow_mode_enable(struct domain *
  110.87          if ( v->arch.shadow_vtable &&
  110.88               (v->arch.shadow_vtable != __shadow_linear_l2_table) )
  110.89          {
  110.90 -            unmap_domain_page(v->arch.shadow_vtable);
  110.91 +            unmap_domain_page_global(v->arch.shadow_vtable);
  110.92          }
  110.93          if ( !(mode & SHM_external) && d->arch.ops->guest_paging_levels == 2)
  110.94              v->arch.shadow_vtable = __shadow_linear_l2_table;
  110.95 @@ -1004,7 +1009,7 @@ int __shadow_mode_enable(struct domain *
  110.96          if ( v->arch.hl2_vtable &&
  110.97               (v->arch.hl2_vtable != __linear_hl2_table) )
  110.98          {
  110.99 -            unmap_domain_page(v->arch.hl2_vtable);
 110.100 +            unmap_domain_page_global(v->arch.hl2_vtable);
 110.101          }
 110.102          if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
 110.103              v->arch.hl2_vtable = __linear_hl2_table;
   111.1 --- a/xen/arch/x86/time.c	Tue Jan 10 15:21:00 2006 +0000
   111.2 +++ b/xen/arch/x86/time.c	Tue Jan 24 17:54:34 2006 +0100
   111.3 @@ -17,7 +17,7 @@
   111.4  #include <xen/config.h>
   111.5  #include <xen/init.h>
   111.6  #include <xen/time.h>
   111.7 -#include <xen/ac_timer.h>
   111.8 +#include <xen/timer.h>
   111.9  #include <xen/smp.h>
  111.10  #include <xen/irq.h>
  111.11  #include <xen/softirq.h>
  111.12 @@ -56,7 +56,7 @@ struct cpu_time {
  111.13      s_time_t stime_local_stamp;
  111.14      s_time_t stime_master_stamp;
  111.15      struct time_scale tsc_scale;
  111.16 -    struct ac_timer calibration_timer;
  111.17 +    struct timer calibration_timer;
  111.18  } __cacheline_aligned;
  111.19  
  111.20  static struct cpu_time cpu_time[NR_CPUS];
  111.21 @@ -163,7 +163,7 @@ void timer_interrupt(int irq, void *dev_
  111.22  
  111.23      /* Rough hack to allow accurate timers to sort-of-work with no APIC. */
  111.24      if ( !cpu_has_apic )
  111.25 -        raise_softirq(AC_TIMER_SOFTIRQ);
  111.26 +        raise_softirq(TIMER_SOFTIRQ);
  111.27  
  111.28      if ( using_pit )
  111.29          pit_overflow();
  111.30 @@ -342,7 +342,7 @@ static void init_pit(void)
  111.31  /* Protected by platform_timer_lock. */
  111.32  static u64 hpet_counter64, hpet_overflow_period;
  111.33  static u32 hpet_stamp;
  111.34 -static struct ac_timer hpet_overflow_timer;
  111.35 +static struct timer hpet_overflow_timer;
  111.36  
  111.37  static void hpet_overflow(void *unused)
  111.38  {
  111.39 @@ -354,7 +354,7 @@ static void hpet_overflow(void *unused)
  111.40      hpet_stamp = counter;
  111.41      spin_unlock_irq(&platform_timer_lock);
  111.42  
  111.43 -    set_ac_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period);
  111.44 +    set_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period);
  111.45  }
  111.46  
  111.47  static u64 read_hpet_count(void)
  111.48 @@ -430,7 +430,7 @@ static int init_hpet(void)
  111.49          (void)do_div(hpet_overflow_period, (u32)hpet_rate);
  111.50      }
  111.51  
  111.52 -    init_ac_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0);
  111.53 +    init_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0);
  111.54      hpet_overflow(NULL);
  111.55      platform_timer_stamp = hpet_counter64;
  111.56  
  111.57 @@ -459,7 +459,7 @@ int use_cyclone;
  111.58  /* Protected by platform_timer_lock. */
  111.59  static u64 cyclone_counter64;
  111.60  static u32 cyclone_stamp;
  111.61 -static struct ac_timer cyclone_overflow_timer;
  111.62 +static struct timer cyclone_overflow_timer;
  111.63  static volatile u32 *cyclone_timer; /* Cyclone MPMC0 register */
  111.64  
  111.65  static void cyclone_overflow(void *unused)
  111.66 @@ -472,7 +472,7 @@ static void cyclone_overflow(void *unuse
  111.67      cyclone_stamp = counter;
  111.68      spin_unlock_irq(&platform_timer_lock);
  111.69  
  111.70 -    set_ac_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
  111.71 +    set_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
  111.72  }
  111.73  
  111.74  static u64 read_cyclone_count(void)
  111.75 @@ -510,7 +510,7 @@ static int init_cyclone(void)
  111.76  
  111.77      read_platform_count = read_cyclone_count;
  111.78  
  111.79 -    init_ac_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
  111.80 +    init_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
  111.81      cyclone_overflow(NULL);
  111.82      platform_timer_stamp = cyclone_counter64;
  111.83      set_time_scale(&platform_timer_scale, CYCLONE_TIMER_FREQ);
  111.84 @@ -876,7 +876,7 @@ static void local_time_calibration(void 
  111.85      cpu_time[cpu].stime_master_stamp = curr_master_stime;
  111.86  
  111.87   out:
  111.88 -    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
  111.89 +    set_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
  111.90  
  111.91      if ( cpu == 0 )
  111.92          platform_time_calibration();
  111.93 @@ -896,9 +896,9 @@ void init_percpu_time(void)
  111.94      cpu_time[cpu].stime_master_stamp = now;
  111.95      cpu_time[cpu].stime_local_stamp  = now;
  111.96  
  111.97 -    init_ac_timer(&cpu_time[cpu].calibration_timer,
  111.98 +    init_timer(&cpu_time[cpu].calibration_timer,
  111.99                    local_time_calibration, NULL, cpu);
 111.100 -    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
 111.101 +    set_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
 111.102  }
 111.103  
 111.104  /* Late init function (after all CPUs are booted). */
   112.1 --- a/xen/arch/x86/traps.c	Tue Jan 10 15:21:00 2006 +0000
   112.2 +++ b/xen/arch/x86/traps.c	Tue Jan 24 17:54:34 2006 +0100
   112.3 @@ -130,9 +130,19 @@ unsigned long kernel_text_end(void)
   112.4  static void show_guest_stack(struct cpu_user_regs *regs)
   112.5  {
   112.6      int i;
   112.7 -    unsigned long *stack = (unsigned long *)regs->esp, addr;
   112.8 +    unsigned long *stack, addr;
   112.9  
  112.10 -    printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
  112.11 +    if ( VM86_MODE(regs) )
  112.12 +    {
  112.13 +        stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
  112.14 +        printk("Guest stack trace from ss:sp = %04x:%04x (VM86)\n   ",
  112.15 +               regs->ss, (uint16_t)(regs->esp & 0xffff));
  112.16 +    }
  112.17 +    else
  112.18 +    {
  112.19 +        stack = (unsigned long *)regs->esp;
  112.20 +        printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
  112.21 +    }
  112.22  
  112.23      for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
  112.24      {
  112.25 @@ -596,7 +606,6 @@ static inline int guest_io_okay(
  112.26      u16 x;
  112.27  #if defined(__x86_64__)
  112.28      /* If in user mode, switch to kernel mode just to read I/O bitmap. */
  112.29 -    extern void toggle_guest_mode(struct vcpu *);
  112.30      int user_mode = !(v->arch.flags & TF_kernel_mode);
  112.31  #define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
  112.32  #elif defined(__i386__)
  112.33 @@ -964,16 +973,26 @@ static int emulate_privileged_op(struct 
  112.34      case 0x30: /* WRMSR */
  112.35          /* Ignore the instruction if unprivileged. */
  112.36          if ( !IS_PRIV(v->domain) )
  112.37 -            DPRINTK("Non-priv domain attempted WRMSR(%p,%08lx,%08lx).\n",
  112.38 -                    _p(regs->ecx), (long)regs->eax, (long)regs->edx);
  112.39 +        {
  112.40 +            u32 l, h;
  112.41 +            if ( (rdmsr_user(regs->ecx, l, h) != 0) ||
  112.42 +                 (regs->ecx != MSR_EFER) ||
  112.43 +                 (regs->eax != l) || (regs->edx != h) )
  112.44 +                DPRINTK("Non-priv domain attempted WRMSR %p from "
  112.45 +                        "%08x:%08x to %08lx:%08lx.\n",
  112.46 +                        _p(regs->ecx), h, l, (long)regs->edx, (long)regs->eax);
  112.47 +        }
  112.48          else if ( wrmsr_user(regs->ecx, regs->eax, regs->edx) )
  112.49              goto fail;
  112.50          break;
  112.51  
  112.52      case 0x32: /* RDMSR */
  112.53          if ( !IS_PRIV(v->domain) )
  112.54 -            DPRINTK("Non-priv domain attempted RDMSR(%p,%08lx,%08lx).\n",
  112.55 -                    _p(regs->ecx), (long)regs->eax, (long)regs->edx);
  112.56 +        {
  112.57 +            if ( regs->ecx != MSR_EFER )
  112.58 +                DPRINTK("Non-priv domain attempted RDMSR %p.\n",
  112.59 +                        _p(regs->ecx));
  112.60 +        }
  112.61          /* Everyone can read the MSR space. */
  112.62          if ( rdmsr_user(regs->ecx, regs->eax, regs->edx) )
  112.63              goto fail;
  112.64 @@ -1080,26 +1099,23 @@ asmlinkage int do_general_protection(str
  112.65      return 0;
  112.66  }
  112.67  
  112.68 +static void nmi_softirq(void)
  112.69 +{
  112.70 +    /* Only used to defer wakeup of dom0,vcpu0 to a safe (non-NMI) context. */
  112.71 +    evtchn_notify(dom0->vcpu[0]);
  112.72 +}
  112.73  
  112.74 -/* Defer dom0 notification to softirq context (unsafe in NMI context). */
  112.75 -static unsigned long nmi_dom0_softirq_reason;
  112.76 -#define NMI_DOM0_PARITY_ERR 0
  112.77 -#define NMI_DOM0_IO_ERR     1
  112.78 -#define NMI_DOM0_UNKNOWN    2
  112.79 +static void nmi_dom0_report(unsigned int reason_idx)
  112.80 +{
  112.81 +    struct domain *d;
  112.82  
  112.83 -static void nmi_dom0_softirq(void)
  112.84 -{
  112.85 -    if ( dom0 == NULL )
  112.86 +    if ( (d = dom0) == NULL )
  112.87          return;
  112.88  
  112.89 -    if ( test_and_clear_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason) )
  112.90 -        send_guest_virq(dom0->vcpu[0], VIRQ_PARITY_ERR);
  112.91 +    set_bit(reason_idx, &d->shared_info->arch.nmi_reason);
  112.92  
  112.93 -    if ( test_and_clear_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason) )
  112.94 -        send_guest_virq(dom0->vcpu[0], VIRQ_IO_ERR);
  112.95 -
  112.96 -    if ( test_and_clear_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason) )
  112.97 -        send_guest_virq(dom0->vcpu[0], VIRQ_NMI);
  112.98 +    if ( test_and_set_bit(_VCPUF_nmi_pending, &d->vcpu[0]->vcpu_flags) )
  112.99 +        raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */
 112.100  }
 112.101  
 112.102  asmlinkage void mem_parity_error(struct cpu_user_regs *regs)
 112.103 @@ -1107,8 +1123,7 @@ asmlinkage void mem_parity_error(struct 
 112.104      switch ( opt_nmi[0] )
 112.105      {
 112.106      case 'd': /* 'dom0' */
 112.107 -        set_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason);
 112.108 -        raise_softirq(NMI_DOM0_SOFTIRQ);
 112.109 +        nmi_dom0_report(_XEN_NMIREASON_parity_error);
 112.110      case 'i': /* 'ignore' */
 112.111          break;
 112.112      default:  /* 'fatal' */
 112.113 @@ -1127,8 +1142,7 @@ asmlinkage void io_check_error(struct cp
 112.114      switch ( opt_nmi[0] )
 112.115      {
 112.116      case 'd': /* 'dom0' */
 112.117 -        set_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason);
 112.118 -        raise_softirq(NMI_DOM0_SOFTIRQ);
 112.119 +        nmi_dom0_report(_XEN_NMIREASON_io_error);
 112.120      case 'i': /* 'ignore' */
 112.121          break;
 112.122      default:  /* 'fatal' */
 112.123 @@ -1147,8 +1161,7 @@ static void unknown_nmi_error(unsigned c
 112.124      switch ( opt_nmi[0] )
 112.125      {
 112.126      case 'd': /* 'dom0' */
 112.127 -        set_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason);
 112.128 -        raise_softirq(NMI_DOM0_SOFTIRQ);
 112.129 +        nmi_dom0_report(_XEN_NMIREASON_unknown);
 112.130      case 'i': /* 'ignore' */
 112.131          break;
 112.132      default:  /* 'fatal' */
 112.133 @@ -1347,7 +1360,7 @@ void __init trap_init(void)
 112.134  
 112.135      cpu_init();
 112.136  
 112.137 -    open_softirq(NMI_DOM0_SOFTIRQ, nmi_dom0_softirq);
 112.138 +    open_softirq(NMI_SOFTIRQ, nmi_softirq);
 112.139  }
 112.140  
 112.141  
   113.1 --- a/xen/arch/x86/vmx.c	Tue Jan 10 15:21:00 2006 +0000
   113.2 +++ b/xen/arch/x86/vmx.c	Tue Jan 24 17:54:34 2006 +0100
   113.3 @@ -98,19 +98,18 @@ void vmx_relinquish_resources(struct vcp
   113.4          /* unmap IO shared page */
   113.5          struct domain *d = v->domain;
   113.6          if ( d->arch.vmx_platform.shared_page_va )
   113.7 -            unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
   113.8 +            unmap_domain_page_global(
   113.9 +                (void *)d->arch.vmx_platform.shared_page_va);
  113.10      }
  113.11  
  113.12      destroy_vmcs(&v->arch.arch_vmx);
  113.13      free_monitor_pagetable(v);
  113.14      vpit = &v->domain->arch.vmx_platform.vmx_pit;
  113.15 -    if ( active_ac_timer(&(vpit->pit_timer)) )
  113.16 -        rem_ac_timer(&vpit->pit_timer);
  113.17 -    if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) )
  113.18 -        rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
  113.19 +    kill_timer(&vpit->pit_timer);
  113.20 +    kill_timer(&v->arch.arch_vmx.hlt_timer);
  113.21      if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
  113.22      {
  113.23 -        rem_ac_timer(&VLAPIC(v)->vlapic_timer);
  113.24 +        kill_timer(&VLAPIC(v)->vlapic_timer);
  113.25          xfree(VLAPIC(v));
  113.26      }
  113.27  }
  113.28 @@ -1599,7 +1598,7 @@ void vmx_vmexit_do_hlt(void)
  113.29          next_wakeup = next_pit;
  113.30      }
  113.31      if ( next_wakeup != - 1 ) 
  113.32 -        set_ac_timer(&current->arch.arch_vmx.hlt_timer, next_wakeup);
  113.33 +        set_timer(&current->arch.arch_vmx.hlt_timer, next_wakeup);
  113.34      do_block();
  113.35  }
  113.36  
   114.1 --- a/xen/arch/x86/vmx_intercept.c	Tue Jan 10 15:21:00 2006 +0000
   114.2 +++ b/xen/arch/x86/vmx_intercept.c	Tue Jan 24 17:54:34 2006 +0100
   114.3 @@ -356,19 +356,19 @@ static void pit_timer_fn(void *data)
   114.4      vpit->pending_intr_nr++;
   114.5      if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
   114.6          vpit->scheduled += vpit->period;
   114.7 -        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
   114.8 +        set_timer(&vpit->pit_timer, vpit->scheduled);
   114.9      }
  114.10  }
  114.11  
  114.12  void pickup_deactive_ticks(struct vmx_virpit *vpit)
  114.13  {
  114.14  
  114.15 -    if ( !active_ac_timer(&(vpit->pit_timer)) ) {
  114.16 +    if ( !active_timer(&(vpit->pit_timer)) ) {
  114.17          /* pick up missed timer tick */
  114.18          missed_ticks(vpit);
  114.19      
  114.20          vpit->scheduled += vpit->period;
  114.21 -        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
  114.22 +        set_timer(&vpit->pit_timer, vpit->scheduled);
  114.23      }
  114.24  }
  114.25  
  114.26 @@ -385,14 +385,14 @@ void vmx_hooks_assist(struct vcpu *v)
  114.27      /* load init count*/
  114.28      if (p->state == STATE_IORESP_HOOK) {
  114.29          /* set up actimer, handle re-init */
  114.30 -        if ( active_ac_timer(&(vpit->pit_timer)) ) {
  114.31 +        if ( active_timer(&(vpit->pit_timer)) ) {
  114.32              VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel %lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) );
  114.33 -            rem_ac_timer(&(vpit->pit_timer));
  114.34 +            stop_timer(&(vpit->pit_timer));
  114.35              reinit = 1;
  114.36   
  114.37          }
  114.38          else {
  114.39 -            init_ac_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
  114.40 +            init_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
  114.41          }
  114.42  
  114.43          /* init count for this channel */
  114.44 @@ -431,7 +431,7 @@ void vmx_hooks_assist(struct vcpu *v)
  114.45          }
  114.46  
  114.47          vpit->scheduled = NOW() + vpit->period;
  114.48 -        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
  114.49 +        set_timer(&vpit->pit_timer, vpit->scheduled);
  114.50  
  114.51          /*restore the state*/
  114.52          p->state = STATE_IORESP_READY;
   115.1 --- a/xen/arch/x86/vmx_io.c	Tue Jan 10 15:21:00 2006 +0000
   115.2 +++ b/xen/arch/x86/vmx_io.c	Tue Jan 24 17:54:34 2006 +0100
   115.3 @@ -819,7 +819,7 @@ interrupt_post_injection(struct vcpu * v
   115.4          if ( !vpit->first_injected ) {
   115.5              vpit->pending_intr_nr = 0;
   115.6              vpit->scheduled = NOW() + vpit->period;
   115.7 -            set_ac_timer(&vpit->pit_timer, vpit->scheduled);
   115.8 +            set_timer(&vpit->pit_timer, vpit->scheduled);
   115.9              vpit->first_injected = 1;
  115.10          } else {
  115.11              vpit->pending_intr_nr--;
   116.1 --- a/xen/arch/x86/vmx_vlapic.c	Tue Jan 10 15:21:00 2006 +0000
   116.2 +++ b/xen/arch/x86/vmx_vlapic.c	Tue Jan 24 17:54:34 2006 +0100
   116.3 @@ -391,7 +391,7 @@ static void vlapic_begin_timer(struct vl
   116.4        (262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter;
   116.5      vlapic->vlapic_timer.expires = cur + offset;
   116.6  
   116.7 -    set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
   116.8 +    set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
   116.9  
  116.10      VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: "
  116.11                  "bus_scale %x now %08x%08x expire %08x%08x "
  116.12 @@ -739,7 +739,7 @@ static void vlapic_write(struct vcpu *v,
  116.13  
  116.14      case APIC_TMICT:
  116.15          if (vlapic_timer_active(vlapic))
  116.16 -            rem_ac_timer(&(vlapic->vlapic_timer));
  116.17 +            stop_timer(&(vlapic->vlapic_timer));
  116.18  
  116.19          vlapic->timer_initial = val;
  116.20          vlapic->timer_current = val;
  116.21 @@ -846,7 +846,7 @@ void vlapic_timer_fn(void *data)
  116.22          vlapic->timer_current = vlapic->timer_initial;
  116.23          offset = vlapic->timer_current * (262144/get_apic_bus_scale()) * vlapic->timer_divide_counter;
  116.24          vlapic->vlapic_timer.expires = NOW() + offset;
  116.25 -        set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
  116.26 +        set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
  116.27      }else {
  116.28          vlapic->timer_current = 0;
  116.29      }
  116.30 @@ -986,7 +986,7 @@ static int vlapic_reset(struct vlapic *v
  116.31  
  116.32      vmx_vioapic_add_lapic(vlapic, v);
  116.33  
  116.34 -    init_ac_timer(&vlapic->vlapic_timer,
  116.35 +    init_timer(&vlapic->vlapic_timer,
  116.36                    vlapic_timer_fn, vlapic, v->processor);
  116.37  
  116.38  #ifdef VLAPIC_NO_BIOS
   117.1 --- a/xen/arch/x86/vmx_vmcs.c	Tue Jan 10 15:21:00 2006 +0000
   117.2 +++ b/xen/arch/x86/vmx_vmcs.c	Tue Jan 24 17:54:34 2006 +0100
   117.3 @@ -193,7 +193,7 @@ static void vmx_map_io_shared_page(struc
   117.4          domain_crash_synchronous();
   117.5      }
   117.6  
   117.7 -    p = map_domain_page(mpfn);
   117.8 +    p = map_domain_page_global(mpfn);
   117.9      if (p == NULL) {
  117.10          printk("Can not map io request shared page for VMX domain.\n");
  117.11          domain_crash_synchronous();
  117.12 @@ -341,7 +341,7 @@ static void vmx_do_launch(struct vcpu *v
  117.13          vlapic_init(v);
  117.14  
  117.15      vmx_set_host_env(v);
  117.16 -    init_ac_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
  117.17 +    init_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
  117.18  
  117.19      error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
  117.20      error |= __vmwrite(GUEST_LDTR_BASE, 0);
   118.1 --- a/xen/arch/x86/x86_32/asm-offsets.c	Tue Jan 10 15:21:00 2006 +0000
   118.2 +++ b/xen/arch/x86/x86_32/asm-offsets.c	Tue Jan 24 17:54:34 2006 +0100
   118.3 @@ -65,6 +65,10 @@ void __dummy__(void)
   118.4             arch.guest_context.kernel_ss);
   118.5      OFFSET(VCPU_kernel_sp, struct vcpu,
   118.6             arch.guest_context.kernel_sp);
   118.7 +    OFFSET(VCPU_flags, struct vcpu, vcpu_flags);
   118.8 +    OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
   118.9 +    DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending);
  118.10 +    DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked);
  118.11      BLANK();
  118.12  
  118.13      OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
   119.1 --- a/xen/arch/x86/x86_32/domain_page.c	Tue Jan 10 15:21:00 2006 +0000
   119.2 +++ b/xen/arch/x86/x86_32/domain_page.c	Tue Jan 24 17:54:34 2006 +0100
   119.3 @@ -1,14 +1,9 @@
   119.4  /******************************************************************************
   119.5   * domain_page.h
   119.6   * 
   119.7 - * Allow temporary mapping of domain pages. Based on ideas from the
   119.8 - * Linux PKMAP code -- the copyrights and credits are retained below.
   119.9 - */
  119.10 -
  119.11 -/*
  119.12 - * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de
  119.13 - *          Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de *
  119.14 - * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
  119.15 + * Allow temporary mapping of domain pages.
  119.16 + * 
  119.17 + * Copyright (c) 2003-2006, Keir Fraser <keir@xensource.com>
  119.18   */
  119.19  
  119.20  #include <xen/config.h>
  119.21 @@ -20,84 +15,203 @@
  119.22  #include <asm/flushtlb.h>
  119.23  #include <asm/hardirq.h>
  119.24  
  119.25 -#define MAPCACHE_ORDER    10
  119.26 -#define MAPCACHE_ENTRIES  (1 << MAPCACHE_ORDER)
  119.27 -
  119.28 -/* Use a spare PTE bit to mark entries ready for recycling. */
  119.29 -#define READY_FOR_TLB_FLUSH (1<<10)
  119.30 -
  119.31 -static void flush_all_ready_maps(void)
  119.32 -{
  119.33 -    struct mapcache *cache = &current->domain->arch.mapcache;
  119.34 -    unsigned int i;
  119.35 -
  119.36 -    for ( i = 0; i < MAPCACHE_ENTRIES; i++ )
  119.37 -        if ( (l1e_get_flags(cache->l1tab[i]) & READY_FOR_TLB_FLUSH) )
  119.38 -            cache->l1tab[i] = l1e_empty();
  119.39 -}
  119.40 -
  119.41 -void *map_domain_pages(unsigned long pfn, unsigned int order)
  119.42 +void *map_domain_page(unsigned long pfn)
  119.43  {
  119.44      unsigned long va;
  119.45 -    unsigned int idx, i, flags, vcpu = current->vcpu_id;
  119.46 -    struct mapcache *cache = &current->domain->arch.mapcache;
  119.47 -#ifndef NDEBUG
  119.48 -    unsigned int flush_count = 0;
  119.49 -#endif
  119.50 +    unsigned int idx, i, vcpu = current->vcpu_id;
  119.51 +    struct domain *d;
  119.52 +    struct mapcache *cache;
  119.53 +    struct vcpu_maphash_entry *hashent;
  119.54  
  119.55      ASSERT(!in_irq());
  119.56 +
  119.57      perfc_incrc(map_domain_page_count);
  119.58  
  119.59      /* If we are the idle domain, ensure that we run on our own page tables. */
  119.60 -    if ( unlikely(is_idle_vcpu(current)) )
  119.61 +    d = current->domain;
  119.62 +    if ( unlikely(is_idle_domain(d)) )
  119.63          __sync_lazy_execstate();
  119.64  
  119.65 +    cache = &d->arch.mapcache;
  119.66 +
  119.67 +    hashent = &cache->vcpu_maphash[vcpu].hash[MAPHASH_HASHFN(pfn)];
  119.68 +    if ( hashent->pfn == pfn )
  119.69 +    {
  119.70 +        idx = hashent->idx;
  119.71 +        hashent->refcnt++;
  119.72 +        ASSERT(hashent->refcnt != 0);
  119.73 +        ASSERT(l1e_get_pfn(cache->l1tab[idx]) == pfn);
  119.74 +        goto out;
  119.75 +    }
  119.76 +
  119.77      spin_lock(&cache->lock);
  119.78  
  119.79      /* Has some other CPU caused a wrap? We must flush if so. */
  119.80 -    if ( cache->epoch != cache->shadow_epoch[vcpu] )
  119.81 +    if ( unlikely(cache->epoch != cache->shadow_epoch[vcpu]) )
  119.82      {
  119.83 -        perfc_incrc(domain_page_tlb_flush);
  119.84 -        local_flush_tlb();
  119.85          cache->shadow_epoch[vcpu] = cache->epoch;
  119.86 +        if ( NEED_FLUSH(tlbflush_time[smp_processor_id()],
  119.87 +                        cache->tlbflush_timestamp) )
  119.88 +        {
  119.89 +            perfc_incrc(domain_page_tlb_flush);
  119.90 +            local_flush_tlb();
  119.91 +        }
  119.92      }
  119.93  
  119.94 -    do {
  119.95 -        idx = cache->cursor = (cache->cursor + 1) & (MAPCACHE_ENTRIES - 1);
  119.96 -        if ( unlikely(idx == 0) )
  119.97 +    idx = find_next_zero_bit(cache->inuse, MAPCACHE_ENTRIES, cache->cursor);
  119.98 +    if ( unlikely(idx >= MAPCACHE_ENTRIES) )
  119.99 +    {
 119.100 +        /* /First/, clean the garbage map and update the inuse list. */
 119.101 +        for ( i = 0; i < ARRAY_SIZE(cache->garbage); i++ )
 119.102          {
 119.103 -            ASSERT(flush_count++ == 0);
 119.104 -            flush_all_ready_maps();
 119.105 -            perfc_incrc(domain_page_tlb_flush);
 119.106 -            local_flush_tlb();
 119.107 -            cache->shadow_epoch[vcpu] = ++cache->epoch;
 119.108 +            unsigned long x = xchg(&cache->garbage[i], 0);
 119.109 +            cache->inuse[i] &= ~x;
 119.110          }
 119.111  
 119.112 -        flags = 0;
 119.113 -        for ( i = 0; i < (1U << order); i++ )
 119.114 -            flags |= l1e_get_flags(cache->l1tab[idx+i]);
 119.115 +        /* /Second/, flush TLBs. */
 119.116 +        perfc_incrc(domain_page_tlb_flush);
 119.117 +        local_flush_tlb();
 119.118 +        cache->shadow_epoch[vcpu] = ++cache->epoch;
 119.119 +        cache->tlbflush_timestamp = tlbflush_current_time();
 119.120 +
 119.121 +        idx = find_first_zero_bit(cache->inuse, MAPCACHE_ENTRIES);
 119.122 +        ASSERT(idx < MAPCACHE_ENTRIES);
 119.123      }
 119.124 -    while ( flags & _PAGE_PRESENT );
 119.125  
 119.126 -    for ( i = 0; i < (1U << order); i++ )
 119.127 -        cache->l1tab[idx+i] = l1e_from_pfn(pfn+i, __PAGE_HYPERVISOR);
 119.128 +    set_bit(idx, cache->inuse);
 119.129 +    cache->cursor = idx + 1;
 119.130  
 119.131      spin_unlock(&cache->lock);
 119.132  
 119.133 +    cache->l1tab[idx] = l1e_from_pfn(pfn, __PAGE_HYPERVISOR);
 119.134 +
 119.135 + out:
 119.136      va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT);
 119.137      return (void *)va;
 119.138  }
 119.139  
 119.140 -void unmap_domain_pages(void *va, unsigned int order)
 119.141 +void unmap_domain_page(void *va)
 119.142  {
 119.143 -    unsigned int idx, i;
 119.144 +    unsigned int idx;
 119.145      struct mapcache *cache = &current->domain->arch.mapcache;
 119.146 +    unsigned long pfn;
 119.147 +    struct vcpu_maphash_entry *hashent;
 119.148 +
 119.149 +    ASSERT(!in_irq());
 119.150  
 119.151      ASSERT((void *)MAPCACHE_VIRT_START <= va);
 119.152      ASSERT(va < (void *)MAPCACHE_VIRT_END);
 119.153  
 119.154      idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
 119.155 +    pfn = l1e_get_pfn(cache->l1tab[idx]);
 119.156 +    hashent = &cache->vcpu_maphash[current->vcpu_id].hash[MAPHASH_HASHFN(pfn)];
 119.157  
 119.158 -    for ( i = 0; i < (1U << order); i++ )
 119.159 -        l1e_add_flags(cache->l1tab[idx+i], READY_FOR_TLB_FLUSH);
 119.160 +    if ( hashent->idx == idx )
 119.161 +    {
 119.162 +        ASSERT(hashent->pfn == pfn);
 119.163 +        ASSERT(hashent->refcnt != 0);
 119.164 +        hashent->refcnt--;
 119.165 +    }
 119.166 +    else if ( hashent->refcnt == 0 )
 119.167 +    {
 119.168 +        if ( hashent->idx != MAPHASHENT_NOTINUSE )
 119.169 +        {
 119.170 +            /* /First/, zap the PTE. */
 119.171 +            ASSERT(l1e_get_pfn(cache->l1tab[hashent->idx]) == hashent->pfn);
 119.172 +            cache->l1tab[hashent->idx] = l1e_empty();
 119.173 +            /* /Second/, mark as garbage. */
 119.174 +            set_bit(hashent->idx, cache->garbage);
 119.175 +        }
 119.176 +
 119.177 +        /* Add newly-freed mapping to the maphash. */
 119.178 +        hashent->pfn = pfn;
 119.179 +        hashent->idx = idx;
 119.180 +    }
 119.181 +    else
 119.182 +    {
 119.183 +        /* /First/, zap the PTE. */
 119.184 +        cache->l1tab[idx] = l1e_empty();
 119.185 +        /* /Second/, mark as garbage. */
 119.186 +        set_bit(idx, cache->garbage);
 119.187 +    }
 119.188 +}
 119.189 +
 119.190 +void mapcache_init(struct domain *d)
 119.191 +{
 119.192 +    unsigned int i, j;
 119.193 +
 119.194 +    d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
 119.195 +        (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
 119.196 +    spin_lock_init(&d->arch.mapcache.lock);
 119.197 +
 119.198 +    /* Mark all maphash entries as not in use. */
 119.199 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
 119.200 +        for ( j = 0; j < MAPHASH_ENTRIES; j++ )
 119.201 +            d->arch.mapcache.vcpu_maphash[i].hash[j].idx =
 119.202 +                MAPHASHENT_NOTINUSE;
 119.203  }
 119.204 +
 119.205 +#define GLOBALMAP_BITS (IOREMAP_MBYTES << (20 - PAGE_SHIFT))
 119.206 +static unsigned long inuse[BITS_TO_LONGS(GLOBALMAP_BITS)];
 119.207 +static unsigned long garbage[BITS_TO_LONGS(GLOBALMAP_BITS)];
 119.208 +static unsigned int inuse_cursor;
 119.209 +static spinlock_t globalmap_lock = SPIN_LOCK_UNLOCKED;
 119.210 +
 119.211 +void *map_domain_page_global(unsigned long pfn)
 119.212 +{
 119.213 +    l2_pgentry_t *pl2e;
 119.214 +    l1_pgentry_t *pl1e;
 119.215 +    unsigned int idx, i;
 119.216 +    unsigned long va;
 119.217 +
 119.218 +    ASSERT(!in_irq() && local_irq_is_enabled());
 119.219 +
 119.220 +    spin_lock(&globalmap_lock);
 119.221 +
 119.222 +    idx = find_next_zero_bit(inuse, GLOBALMAP_BITS, inuse_cursor);
 119.223 +    va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
 119.224 +    if ( unlikely(va >= FIXADDR_START) )
 119.225 +    {
 119.226 +        /* /First/, clean the garbage map and update the inuse list. */
 119.227 +        for ( i = 0; i < ARRAY_SIZE(garbage); i++ )
 119.228 +        {
 119.229 +            unsigned long x = xchg(&garbage[i], 0);
 119.230 +            inuse[i] &= ~x;
 119.231 +        }
 119.232 +
 119.233 +        /* /Second/, flush all TLBs to get rid of stale garbage mappings. */
 119.234 +        flush_tlb_all();
 119.235 +
 119.236 +        idx = find_first_zero_bit(inuse, GLOBALMAP_BITS);
 119.237 +        va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
 119.238 +        ASSERT(va < FIXADDR_START);
 119.239 +    }
 119.240 +
 119.241 +    set_bit(idx, inuse);
 119.242 +    inuse_cursor = idx + 1;
 119.243 +
 119.244 +    spin_unlock(&globalmap_lock);
 119.245 +
 119.246 +    pl2e = virt_to_xen_l2e(va);
 119.247 +    pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(va);
 119.248 +    *pl1e = l1e_from_pfn(pfn, __PAGE_HYPERVISOR);
 119.249 +
 119.250 +    return (void *)va;
 119.251 +}
 119.252 +
 119.253 +void unmap_domain_page_global(void *va)
 119.254 +{
 119.255 +    unsigned long __va = (unsigned long)va;
 119.256 +    l2_pgentry_t *pl2e;
 119.257 +    l1_pgentry_t *pl1e;
 119.258 +    unsigned int idx;
 119.259 +
 119.260 +    /* /First/, we zap the PTE. */
 119.261 +    pl2e = virt_to_xen_l2e(__va);
 119.262 +    pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(__va);
 119.263 +    *pl1e = l1e_empty();
 119.264 +
 119.265 +    /* /Second/, we add to the garbage map. */
 119.266 +    idx = (__va - IOREMAP_VIRT_START) >> PAGE_SHIFT;
 119.267 +    set_bit(idx, garbage);
 119.268 +}
   120.1 --- a/xen/arch/x86/x86_32/entry.S	Tue Jan 10 15:21:00 2006 +0000
   120.2 +++ b/xen/arch/x86/x86_32/entry.S	Tue Jan 24 17:54:34 2006 +0100
   120.3 @@ -326,7 +326,9 @@ test_all_events:
   120.4          shl  $IRQSTAT_shift,%eax
   120.5          test %ecx,irq_stat(%eax,1)
   120.6          jnz  process_softirqs
   120.7 -/*test_guest_events:*/
   120.8 +        btr  $_VCPUF_nmi_pending,VCPU_flags(%ebx)
   120.9 +        jc   process_nmi
  120.10 +test_guest_events:
  120.11          movl VCPU_vcpu_info(%ebx),%eax
  120.12          testb $0xFF,VCPUINFO_upcall_mask(%eax)
  120.13          jnz  restore_all_guest
  120.14 @@ -348,7 +350,24 @@ process_softirqs:
  120.15          sti       
  120.16          call do_softirq
  120.17          jmp  test_all_events
  120.18 -                
  120.19 +	
  120.20 +	ALIGN
  120.21 +process_nmi:
  120.22 +        movl VCPU_nmi_addr(%ebx),%eax
  120.23 +        test %eax,%eax
  120.24 +        jz   test_all_events
  120.25 +        bts  $_VCPUF_nmi_masked,VCPU_flags(%ebx)
  120.26 +        jc   1f
  120.27 +        sti
  120.28 +        leal VCPU_trap_bounce(%ebx),%edx
  120.29 +        movl %eax,TRAPBOUNCE_eip(%edx)
  120.30 +        movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
  120.31 +        movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
  120.32 +        call create_bounce_frame
  120.33 +        jmp  test_all_events
  120.34 +1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%ebx)
  120.35 +        jmp  test_guest_events
  120.36 +
  120.37  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
  120.38  /*   {EIP, CS, EFLAGS, [ESP, SS]}                                        */
  120.39  /* %edx == trap_bounce, %ebx == struct vcpu                       */
  120.40 @@ -620,9 +639,7 @@ ENTRY(nmi)
  120.41          jne   defer_nmi
  120.42  
  120.43  continue_nmi:
  120.44 -        movl  $(__HYPERVISOR_DS),%edx
  120.45 -        movl  %edx,%ds
  120.46 -        movl  %edx,%es
  120.47 +        SET_XEN_SEGMENTS(d)
  120.48          movl  %esp,%edx
  120.49          pushl %edx
  120.50          call  do_nmi
  120.51 @@ -660,42 +677,6 @@ do_arch_sched_op:
  120.52          movl %eax,UREGS_eax(%ecx)
  120.53          jmp  do_sched_op
  120.54  
  120.55 -do_switch_vm86:
  120.56 -        # Reset the stack pointer
  120.57 -        GET_GUEST_REGS(%ecx)
  120.58 -        movl %ecx,%esp
  120.59 -
  120.60 -        # GS:ESI == Ring-1 stack activation
  120.61 -        movl UREGS_esp(%esp),%esi
  120.62 -VFLT1:  mov  UREGS_ss(%esp),%gs
  120.63 -
  120.64 -        # ES:EDI == Ring-0 stack activation
  120.65 -        leal UREGS_eip(%esp),%edi
  120.66 -
  120.67 -        # Restore the hypercall-number-clobbered EAX on our stack frame
  120.68 -VFLT2:  movl %gs:(%esi),%eax
  120.69 -        movl %eax,UREGS_eax(%esp)
  120.70 -        addl $4,%esi
  120.71 -        	
  120.72 -      	# Copy the VM86 activation from the ring-1 stack to the ring-0 stack
  120.73 -        movl $(UREGS_user_sizeof-UREGS_eip)/4,%ecx
  120.74 -VFLT3:  movl %gs:(%esi),%eax
  120.75 -        stosl
  120.76 -        addl $4,%esi
  120.77 -        loop VFLT3
  120.78 -
  120.79 -        # Fix up EFLAGS: IOPL=0, IF=1, VM=1
  120.80 -        andl $~X86_EFLAGS_IOPL,UREGS_eflags(%esp)
  120.81 -        orl  $X86_EFLAGS_IF|X86_EFLAGS_VM,UREGS_eflags(%esp)
  120.82 -        
  120.83 -        jmp test_all_events
  120.84 -
  120.85 -.section __ex_table,"a"
  120.86 -        .long VFLT1,domain_crash_synchronous
  120.87 -        .long VFLT2,domain_crash_synchronous
  120.88 -        .long VFLT3,domain_crash_synchronous
  120.89 -.previous
  120.90 -
  120.91  .data
  120.92  
  120.93  ENTRY(exception_table)
  120.94 @@ -744,11 +725,12 @@ ENTRY(hypercall_table)
  120.95          .long do_grant_table_op     /* 20 */
  120.96          .long do_vm_assist
  120.97          .long do_update_va_mapping_otherdomain
  120.98 -        .long do_switch_vm86
  120.99 +        .long do_iret
 120.100          .long do_vcpu_op
 120.101          .long do_ni_hypercall       /* 25 */
 120.102          .long do_mmuext_op
 120.103 -        .long do_acm_op             /* 27 */
 120.104 +        .long do_acm_op
 120.105 +        .long do_nmi_op
 120.106          .rept NR_hypercalls-((.-hypercall_table)/4)
 120.107          .long do_ni_hypercall
 120.108          .endr
 120.109 @@ -777,11 +759,12 @@ ENTRY(hypercall_args_table)
 120.110          .byte 3 /* do_grant_table_op    */  /* 20 */
 120.111          .byte 2 /* do_vm_assist         */
 120.112          .byte 5 /* do_update_va_mapping_otherdomain */
 120.113 -        .byte 0 /* do_switch_vm86       */
 120.114 +        .byte 0 /* do_iret              */
 120.115          .byte 3 /* do_vcpu_op           */
 120.116          .byte 0 /* do_ni_hypercall      */  /* 25 */
 120.117          .byte 4 /* do_mmuext_op         */
 120.118          .byte 1 /* do_acm_op            */
 120.119 +        .byte 2 /* do_nmi_op            */
 120.120          .rept NR_hypercalls-(.-hypercall_args_table)
 120.121          .byte 0 /* do_ni_hypercall      */
 120.122          .endr
   121.1 --- a/xen/arch/x86/x86_32/traps.c	Tue Jan 10 15:21:00 2006 +0000
   121.2 +++ b/xen/arch/x86/x86_32/traps.c	Tue Jan 24 17:54:34 2006 +0100
   121.3 @@ -157,6 +157,64 @@ asmlinkage void do_double_fault(void)
   121.4          __asm__ __volatile__ ( "hlt" );
   121.5  }
   121.6  
   121.7 +asmlinkage unsigned long do_iret(void)
   121.8 +{
   121.9 +    struct cpu_user_regs *regs = guest_cpu_user_regs();
  121.10 +    u32 eflags;
  121.11 +
  121.12 +    /* Check worst-case stack frame for overlap with Xen protected area. */
  121.13 +    if ( unlikely(!access_ok(regs->esp, 40)) )
  121.14 +        domain_crash_synchronous();
  121.15 +
  121.16 +    /* Pop and restore EAX (clobbered by hypercall). */
  121.17 +    if ( unlikely(__copy_from_user(&regs->eax, (void __user *)regs->esp, 4)) )
  121.18 +        domain_crash_synchronous();
  121.19 +    regs->esp += 4;
  121.20 +
  121.21 +    /* Pop and restore CS and EIP. */
  121.22 +    if ( unlikely(__copy_from_user(&regs->eip, (void __user *)regs->esp, 8)) )
  121.23 +        domain_crash_synchronous();
  121.24 +    regs->esp += 8;
  121.25 +
  121.26 +    /*
  121.27 +     * Pop, fix up and restore EFLAGS. We fix up in a local staging area
  121.28 +     * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
  121.29 +     */
  121.30 +    if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
  121.31 +        domain_crash_synchronous();
  121.32 +    regs->esp += 4;
  121.33 +    regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
  121.34 +
  121.35 +    if ( VM86_MODE(regs) )
  121.36 +    {
  121.37 +        /* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
  121.38 +        if ( __copy_from_user(&regs->esp, (void __user *)regs->esp, 24) )
  121.39 +            domain_crash_synchronous();
  121.40 +    }
  121.41 +    else if ( unlikely(RING_0(regs)) )
  121.42 +    {
  121.43 +        domain_crash_synchronous();
  121.44 +    }
  121.45 +    else if ( !RING_1(regs) )
  121.46 +    {
  121.47 +        /* Return to ring 2/3: pop and restore ESP and SS. */
  121.48 +        if ( __copy_from_user(&regs->esp, (void __user *)regs->esp, 8) )
  121.49 +            domain_crash_synchronous();
  121.50 +    }
  121.51 +
  121.52 +    /* No longer in NMI context. */
  121.53 +    clear_bit(_VCPUF_nmi_masked, &current->vcpu_flags);
  121.54 +
  121.55 +    /* Restore upcall mask from saved value. */
  121.56 +    current->vcpu_info->evtchn_upcall_mask = regs->saved_upcall_mask;
  121.57 +
  121.58 +    /*
  121.59 +     * The hypercall exit path will overwrite EAX with this return
  121.60 +     * value.
  121.61 +     */
  121.62 +    return regs->eax;
  121.63 +}
  121.64 +
  121.65  BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
  121.66  asmlinkage void smp_deferred_nmi(struct cpu_user_regs regs)
  121.67  {
   122.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Tue Jan 10 15:21:00 2006 +0000
   122.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Tue Jan 24 17:54:34 2006 +0100
   122.3 @@ -65,6 +65,10 @@ void __dummy__(void)
   122.4             arch.guest_context.syscall_callback_eip);
   122.5      OFFSET(VCPU_kernel_sp, struct vcpu,
   122.6             arch.guest_context.kernel_sp);
   122.7 +    OFFSET(VCPU_flags, struct vcpu, vcpu_flags);
   122.8 +    OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
   122.9 +    DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending);
  122.10 +    DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked);
  122.11      BLANK();
  122.12  
  122.13      OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
   123.1 --- a/xen/arch/x86/x86_64/entry.S	Tue Jan 10 15:21:00 2006 +0000
   123.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Jan 24 17:54:34 2006 +0100
   123.3 @@ -171,7 +171,9 @@ test_all_events:
   123.4          leaq  irq_stat(%rip),%rcx
   123.5          testl $~0,(%rcx,%rax,1)
   123.6          jnz   process_softirqs
   123.7 -/*test_guest_events:*/
   123.8 +        btr   $_VCPUF_nmi_pending,VCPU_flags(%rbx)
   123.9 +        jc    process_nmi
  123.10 +test_guest_events:
  123.11          movq  VCPU_vcpu_info(%rbx),%rax
  123.12          testb $0xFF,VCPUINFO_upcall_mask(%rax)
  123.13          jnz   restore_all_guest
  123.14 @@ -322,6 +324,23 @@ process_softirqs:
  123.15          call do_softirq
  123.16          jmp  test_all_events
  123.17  
  123.18 +	ALIGN
  123.19 +/* %rbx: struct vcpu */
  123.20 +process_nmi:
  123.21 +        movq VCPU_nmi_addr(%rbx),%rax
  123.22 +        test %rax,%rax
  123.23 +        jz   test_all_events
  123.24 +        bts  $_VCPUF_nmi_masked,VCPU_flags(%rbx)
  123.25 +        jc   1f
  123.26 +        sti
  123.27 +        leaq VCPU_trap_bounce(%rbx),%rdx
  123.28 +        movq %rax,TRAPBOUNCE_eip(%rdx)
  123.29 +        movw $(TBF_INTERRUPT|TBF_SLOW_IRET),TRAPBOUNCE_flags(%rdx)
  123.30 +        call create_bounce_frame
  123.31 +        jmp  test_all_events
  123.32 +1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%rbx)
  123.33 +        jmp  test_guest_events
  123.34 +	
  123.35  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK:                     */
  123.36  /*   { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS }   */
  123.37  /* %rdx: trap_bounce, %rbx: struct vcpu                           */
  123.38 @@ -339,6 +358,9 @@ create_bounce_frame:
  123.39  1:      /* In kernel context already: push new frame at existing %rsp. */
  123.40          movq  UREGS_rsp+8(%rsp),%rsi
  123.41          andb  $0xfc,UREGS_cs+8(%rsp)    # Indicate kernel context to guest.
  123.42 +	testw $(TBF_SLOW_IRET),TRAPBOUNCE_flags(%rdx)
  123.43 +	jz    2f
  123.44 +	orb   $0x01,UREGS_cs+8(%rsp)
  123.45  2:      andq  $~0xf,%rsi                # Stack frames are 16-byte aligned.
  123.46          movq  $HYPERVISOR_VIRT_START,%rax
  123.47          cmpq  %rax,%rsi
  123.48 @@ -569,7 +591,7 @@ ENTRY(nmi)
  123.49          SAVE_ALL
  123.50          movq  %rsp,%rdi
  123.51          call  do_nmi
  123.52 -	jmp   restore_all_xen
  123.53 +        jmp   ret_from_intr
  123.54  
  123.55  do_arch_sched_op:
  123.56          # Ensure we return success even if we return via schedule_tail()
  123.57 @@ -626,11 +648,12 @@ ENTRY(hypercall_table)
  123.58          .quad do_grant_table_op     /* 20 */
  123.59          .quad do_vm_assist
  123.60          .quad do_update_va_mapping_otherdomain
  123.61 -        .quad do_switch_to_user
  123.62 +        .quad do_iret
  123.63          .quad do_vcpu_op
  123.64          .quad do_set_segment_base   /* 25 */
  123.65          .quad do_mmuext_op
  123.66          .quad do_acm_op
  123.67 +        .quad do_nmi_op
  123.68          .rept NR_hypercalls-((.-hypercall_table)/4)
  123.69          .quad do_ni_hypercall
  123.70          .endr
  123.71 @@ -659,11 +682,12 @@ ENTRY(hypercall_args_table)
  123.72          .byte 3 /* do_grant_table_op    */  /* 20 */
  123.73          .byte 2 /* do_vm_assist         */
  123.74          .byte 4 /* do_update_va_mapping_otherdomain */
  123.75 -        .byte 0 /* do_switch_to_user    */
  123.76 +        .byte 0 /* do_iret              */
  123.77          .byte 3 /* do_vcpu_op           */
  123.78          .byte 2 /* do_set_segment_base  */  /* 25 */
  123.79          .byte 4 /* do_mmuext_op         */
  123.80          .byte 1 /* do_acm_op            */
  123.81 +        .byte 2 /* do_nmi_op            */
  123.82          .rept NR_hypercalls-(.-hypercall_args_table)
  123.83          .byte 0 /* do_ni_hypercall      */
  123.84          .endr
   124.1 --- a/xen/arch/x86/x86_64/traps.c	Tue Jan 10 15:21:00 2006 +0000
   124.2 +++ b/xen/arch/x86/x86_64/traps.c	Tue Jan 24 17:54:34 2006 +0100
   124.3 @@ -12,6 +12,7 @@
   124.4  #include <asm/current.h>
   124.5  #include <asm/flushtlb.h>
   124.6  #include <asm/msr.h>
   124.7 +#include <asm/shadow.h>
   124.8  #include <asm/vmx.h>
   124.9  
  124.10  void show_registers(struct cpu_user_regs *regs)
  124.11 @@ -113,6 +114,52 @@ asmlinkage void do_double_fault(struct c
  124.12          __asm__ __volatile__ ( "hlt" );
  124.13  }
  124.14  
  124.15 +void toggle_guest_mode(struct vcpu *v)
  124.16 +{
  124.17 +    v->arch.flags ^= TF_kernel_mode;
  124.18 +    __asm__ __volatile__ ( "swapgs" );
  124.19 +    update_pagetables(v);
  124.20 +    write_ptbase(v);
  124.21 +}
  124.22 +
  124.23 +long do_iret(void)
  124.24 +{
  124.25 +    struct cpu_user_regs *regs = guest_cpu_user_regs();
  124.26 +    struct iret_context iret_saved;
  124.27 +    struct vcpu *v = current;
  124.28 +
  124.29 +    if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp,
  124.30 +                                 sizeof(iret_saved))) )
  124.31 +        domain_crash_synchronous();
  124.32 +
  124.33 +    /* Returning to user mode? */
  124.34 +    if ( (iret_saved.cs & 3) == 3 )
  124.35 +    {
  124.36 +        if ( unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
  124.37 +            return -EFAULT;
  124.38 +        toggle_guest_mode(v);
  124.39 +    }
  124.40 +
  124.41 +    regs->rip    = iret_saved.rip;
  124.42 +    regs->cs     = iret_saved.cs | 3; /* force guest privilege */
  124.43 +    regs->rflags = (iret_saved.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
  124.44 +    regs->rsp    = iret_saved.rsp;
  124.45 +    regs->ss     = iret_saved.ss | 3; /* force guest privilege */
  124.46 +
  124.47 +    if ( !(iret_saved.flags & VGCF_IN_SYSCALL) )
  124.48 +    {
  124.49 +        regs->entry_vector = 0;
  124.50 +        regs->r11 = iret_saved.r11;
  124.51 +        regs->rcx = iret_saved.rcx;
  124.52 +    }
  124.53 +
  124.54 +    /* No longer in NMI context. */
  124.55 +    clear_bit(_VCPUF_nmi_masked, &current->vcpu_flags);
  124.56 +
  124.57 +    /* Saved %rax gets written back to regs->rax in entry.S. */
  124.58 +    return iret_saved.rax;
  124.59 +}
  124.60 +
  124.61  asmlinkage void syscall_enter(void);
  124.62  void __init percpu_traps_init(void)
  124.63  {
   125.1 --- a/xen/common/Makefile	Tue Jan 10 15:21:00 2006 +0000
   125.2 +++ b/xen/common/Makefile	Tue Jan 24 17:54:34 2006 +0100
   125.3 @@ -4,6 +4,9 @@ include $(BASEDIR)/Rules.mk
   125.4  ifneq ($(perfc),y)
   125.5  OBJS := $(subst perfc.o,,$(OBJS))
   125.6  endif
   125.7 +ifneq ($(crash_debug),y)
   125.8 +OBJS := $(patsubst gdbstub.o,,$(OBJS))
   125.9 +endif
  125.10  
  125.11  default: common.o
  125.12  common.o: $(OBJS)
   126.1 --- a/xen/common/ac_timer.c	Tue Jan 10 15:21:00 2006 +0000
   126.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.3 @@ -1,286 +0,0 @@
   126.4 -/******************************************************************************
   126.5 - * ac_timer.c
   126.6 - * 
   126.7 - * Copyright (c) 2002-2003 Rolf Neugebauer
   126.8 - * Copyright (c) 2002-2005 K A Fraser
   126.9 - */
  126.10 -
  126.11 -#include <xen/config.h>
  126.12 -#include <xen/init.h>
  126.13 -#include <xen/types.h>
  126.14 -#include <xen/errno.h>
  126.15 -#include <xen/sched.h>
  126.16 -#include <xen/lib.h>
  126.17 -#include <xen/smp.h>
  126.18 -#include <xen/perfc.h>
  126.19 -#include <xen/time.h>
  126.20 -#include <xen/softirq.h>
  126.21 -#include <xen/ac_timer.h>
  126.22 -#include <xen/keyhandler.h>
  126.23 -#include <asm/system.h>
  126.24 -#include <asm/desc.h>
  126.25 -
  126.26 -/*
  126.27 - * We pull handlers off the timer list this far in future,
  126.28 - * rather than reprogramming the time hardware.
  126.29 - */
  126.30 -#define TIMER_SLOP (50*1000) /* ns */
  126.31 -
  126.32 -struct ac_timers {
  126.33 -    spinlock_t        lock;
  126.34 -    struct ac_timer **heap;
  126.35 -    unsigned int      softirqs;
  126.36 -} __cacheline_aligned;
  126.37 -
  126.38 -struct ac_timers ac_timers[NR_CPUS];
  126.39 -
  126.40 -extern int reprogram_ac_timer(s_time_t timeout);
  126.41 -
  126.42 -/****************************************************************************
  126.43 - * HEAP OPERATIONS.
  126.44 - */
  126.45 -
  126.46 -#define GET_HEAP_SIZE(_h)     ((int)(((u16 *)(_h))[0]))
  126.47 -#define SET_HEAP_SIZE(_h,_v)  (((u16 *)(_h))[0] = (u16)(_v))
  126.48 -
  126.49 -#define GET_HEAP_LIMIT(_h)    ((int)(((u16 *)(_h))[1]))
  126.50 -#define SET_HEAP_LIMIT(_h,_v) (((u16 *)(_h))[1] = (u16)(_v))
  126.51 -
  126.52 -/* Sink down element @pos of @heap. */
  126.53 -static void down_heap(struct ac_timer **heap, int pos)
  126.54 -{
  126.55 -    int sz = GET_HEAP_SIZE(heap), nxt;
  126.56 -    struct ac_timer *t = heap[pos];
  126.57 -
  126.58 -    while ( (nxt = (pos << 1)) <= sz )
  126.59 -    {
  126.60 -        if ( ((nxt+1) <= sz) && (heap[nxt+1]->expires < heap[nxt]->expires) )
  126.61 -            nxt++;
  126.62 -        if ( heap[nxt]->expires > t->expires )
  126.63 -            break;
  126.64 -        heap[pos] = heap[nxt];
  126.65 -        heap[pos]->heap_offset = pos;
  126.66 -        pos = nxt;
  126.67 -    }
  126.68 -
  126.69 -    heap[pos] = t;
  126.70 -    t->heap_offset = pos;
  126.71 -}
  126.72 -
  126.73 -/* Float element @pos up @heap. */
  126.74 -static void up_heap(struct ac_timer **heap, int pos)
  126.75 -{
  126.76 -    struct ac_timer *t = heap[pos];
  126.77 -
  126.78 -    while ( (pos > 1) && (t->expires < heap[pos>>1]->expires) )
  126.79 -    {
  126.80 -        heap[pos] = heap[pos>>1];
  126.81 -        heap[pos]->heap_offset = pos;
  126.82 -        pos >>= 1;
  126.83 -    }
  126.84 -
  126.85 -    heap[pos] = t;
  126.86 -    t->heap_offset = pos;
  126.87 -}
  126.88 -
  126.89 -
  126.90 -/* Delete @t from @heap. Return TRUE if new top of heap. */
  126.91 -static int remove_entry(struct ac_timer **heap, struct ac_timer *t)
  126.92 -{
  126.93 -    int sz = GET_HEAP_SIZE(heap);
  126.94 -    int pos = t->heap_offset;
  126.95 -
  126.96 -    t->heap_offset = 0;
  126.97 -
  126.98 -    if ( unlikely(pos == sz) )
  126.99 -    {
 126.100 -        SET_HEAP_SIZE(heap, sz-1);
 126.101 -        goto out;
 126.102 -    }
 126.103 -
 126.104 -    heap[pos] = heap[sz];
 126.105 -    heap[pos]->heap_offset = pos;
 126.106 -
 126.107 -    SET_HEAP_SIZE(heap, --sz);
 126.108 -
 126.109 -    if ( (pos > 1) && (heap[pos]->expires < heap[pos>>1]->expires) )
 126.110 -        up_heap(heap, pos);
 126.111 -    else
 126.112 -        down_heap(heap, pos);
 126.113 -
 126.114 - out:
 126.115 -    return (pos == 1);
 126.116 -}
 126.117 -
 126.118 -
 126.119 -/* Add new entry @t to @heap. Return TRUE if new top of heap. */
 126.120 -static int add_entry(struct ac_timer ***pheap, struct ac_timer *t)
 126.121 -{
 126.122 -    struct ac_timer **heap = *pheap;
 126.123 -    int sz = GET_HEAP_SIZE(heap);
 126.124 -
 126.125 -    /* Copy the heap if it is full. */
 126.126 -    if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
 126.127 -    {
 126.128 -        /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
 126.129 -        int old_limit = GET_HEAP_LIMIT(heap);
 126.130 -        int new_limit = ((old_limit + 1) << 4) - 1;
 126.131 -        heap = xmalloc_array(struct ac_timer *, new_limit + 1);
 126.132 -        BUG_ON(heap == NULL);
 126.133 -        memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
 126.134 -        SET_HEAP_LIMIT(heap, new_limit);
 126.135 -        if ( old_limit != 0 )
 126.136 -            xfree(*pheap);
 126.137 -        *pheap = heap;
 126.138 -    }
 126.139 -
 126.140 -    SET_HEAP_SIZE(heap, ++sz);
 126.141 -    heap[sz] = t;
 126.142 -    t->heap_offset = sz;
 126.143 -    up_heap(heap, sz);
 126.144 -    return (t->heap_offset == 1);
 126.145 -}
 126.146 -
 126.147 -
 126.148 -/****************************************************************************
 126.149 - * TIMER OPERATIONS.
 126.150 - */
 126.151 -
 126.152 -static inline void __add_ac_timer(struct ac_timer *timer)
 126.153 -{
 126.154 -    int cpu = timer->cpu;
 126.155 -    if ( add_entry(&ac_timers[cpu].heap, timer) )
 126.156 -        cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
 126.157 -}
 126.158 -
 126.159 -
 126.160 -static inline void __rem_ac_timer(struct ac_timer *timer)
 126.161 -{
 126.162 -    int cpu = timer->cpu;
 126.163 -    if ( remove_entry(ac_timers[cpu].heap, timer) )
 126.164 -        cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
 126.165 -}
 126.166 -
 126.167 -
 126.168 -void set_ac_timer(struct ac_timer *timer, s_time_t expires)
 126.169 -{
 126.170 -    int           cpu = timer->cpu;
 126.171 -    unsigned long flags;
 126.172 -
 126.173 -    spin_lock_irqsave(&ac_timers[cpu].lock, flags);
 126.174 -    ASSERT(timer != NULL);
 126.175 -    if ( active_ac_timer(timer) )
 126.176 -        __rem_ac_timer(timer);
 126.177 -    timer->expires = expires;
 126.178 -    __add_ac_timer(timer);
 126.179 -    spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
 126.180 -}
 126.181 -
 126.182 -
 126.183 -void rem_ac_timer(struct ac_timer *timer)
 126.184 -{
 126.185 -    int           cpu = timer->cpu;
 126.186 -    unsigned long flags;
 126.187 -
 126.188 -    spin_lock_irqsave(&ac_timers[cpu].lock, flags);
 126.189 -    ASSERT(timer != NULL);
 126.190 -    if ( active_ac_timer(timer) )
 126.191 -        __rem_ac_timer(timer);
 126.192 -    spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
 126.193 -}
 126.194 -
 126.195 -
 126.196 -static void ac_timer_softirq_action(void)
 126.197 -{
 126.198 -    int              cpu = smp_processor_id();
 126.199 -    struct ac_timer *t, **heap;
 126.200 -    s_time_t         now;
 126.201 -    void             (*fn)(void *);
 126.202 -
 126.203 -    spin_lock_irq(&ac_timers[cpu].lock);
 126.204 -    
 126.205 -    do {
 126.206 -        heap = ac_timers[cpu].heap;
 126.207 -        now  = NOW();
 126.208 -
 126.209 -        while ( (GET_HEAP_SIZE(heap) != 0) &&
 126.210 -                ((t = heap[1])->expires < (now + TIMER_SLOP)) )
 126.211 -        {
 126.212 -            remove_entry(heap, t);
 126.213 -
 126.214 -            if ( (fn = t->function) != NULL )
 126.215 -            {
 126.216 -                void *data = t->data;
 126.217 -                spin_unlock_irq(&ac_timers[cpu].lock);
 126.218 -                (*fn)(data);
 126.219 -                spin_lock_irq(&ac_timers[cpu].lock);
 126.220 -            }
 126.221 -
 126.222 -            /* Heap may have grown while the lock was released. */
 126.223 -            heap = ac_timers[cpu].heap;
 126.224 -        }
 126.225 -    }
 126.226 -    while ( !reprogram_ac_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
 126.227 -
 126.228 -    spin_unlock_irq(&ac_timers[cpu].lock);
 126.229 -}
 126.230 -
 126.231 -
 126.232 -static void dump_timerq(unsigned char key)
 126.233 -{
 126.234 -    struct ac_timer *t;
 126.235 -    unsigned long    flags; 
 126.236 -    s_time_t         now = NOW();
 126.237 -    int              i, j;
 126.238 -
 126.239 -    printk("Dumping ac_timer queues: NOW=0x%08X%08X\n",
 126.240 -           (u32)(now>>32), (u32)now); 
 126.241 -
 126.242 -    for_each_online_cpu( i )
 126.243 -    {
 126.244 -        printk("CPU[%02d] ", i);
 126.245 -        spin_lock_irqsave(&ac_timers[i].lock, flags);
 126.246 -        for ( j = 1; j <= GET_HEAP_SIZE(ac_timers[i].heap); j++ )
 126.247 -        {
 126.248 -            t = ac_timers[i].heap[j];
 126.249 -            printk ("  %d : %p ex=0x%08X%08X %p\n",
 126.250 -                    j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
 126.251 -        }
 126.252 -        spin_unlock_irqrestore(&ac_timers[i].lock, flags);
 126.253 -        printk("\n");
 126.254 -    }
 126.255 -}
 126.256 -
 126.257 -
 126.258 -void __init ac_timer_init(void)
 126.259 -{
 126.260 -    static struct ac_timer *dummy_heap;
 126.261 -    int i;
 126.262 -
 126.263 -    open_softirq(AC_TIMER_SOFTIRQ, ac_timer_softirq_action);
 126.264 -
 126.265 -    /*
 126.266 -     * All CPUs initially share an empty dummy heap. Only those CPUs that
 126.267 -     * are brought online will be dynamically allocated their own heap.
 126.268 -     */
 126.269 -    SET_HEAP_SIZE(&dummy_heap, 0);
 126.270 -    SET_HEAP_LIMIT(&dummy_heap, 0);
 126.271 -
 126.272 -    for ( i = 0; i < NR_CPUS; i++ )
 126.273 -    {
 126.274 -        spin_lock_init(&ac_timers[i].lock);
 126.275 -        ac_timers[i].heap = &dummy_heap;
 126.276 -    }
 126.277 -
 126.278 -    register_keyhandler('a', dump_timerq, "dump ac_timer queues");
 126.279 -}
 126.280 -
 126.281 -/*
 126.282 - * Local variables:
 126.283 - * mode: C
 126.284 - * c-set-style: "BSD"
 126.285 - * c-basic-offset: 4
 126.286 - * tab-width: 4
 126.287 - * indent-tabs-mode: nil
 126.288 - * End:
 126.289 - */
   127.1 --- a/xen/common/dom0_ops.c	Tue Jan 10 15:21:00 2006 +0000
   127.2 +++ b/xen/common/dom0_ops.c	Tue Jan 24 17:54:34 2006 +0100
   127.3 @@ -208,7 +208,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   127.4                  pro = i;
   127.5  
   127.6          ret = -ENOMEM;
   127.7 -        if ( (d = do_createdomain(dom, pro)) == NULL )
   127.8 +        if ( (d = domain_create(dom, pro)) == NULL )
   127.9              break;
  127.10  
  127.11          memcpy(d->handle, op->u.createdomain.handle,
  127.12 @@ -323,7 +323,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
  127.13          new_affinity = v->cpu_affinity;
  127.14          memcpy(cpus_addr(new_affinity),
  127.15                 &op->u.setvcpuaffinity.cpumap,
  127.16 -               min((int)BITS_TO_LONGS(NR_CPUS),
  127.17 +               min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)),
  127.18                     (int)sizeof(op->u.setvcpuaffinity.cpumap)));
  127.19  
  127.20          ret = vcpu_set_affinity(v, &new_affinity);
  127.21 @@ -450,6 +450,10 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
  127.22          if ( (v = d->vcpu[op->u.getvcpucontext.vcpu]) == NULL )
  127.23              goto getvcpucontext_out;
  127.24  
  127.25 +        ret = -ENODATA;
  127.26 +        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  127.27 +            goto getvcpucontext_out;
  127.28 +
  127.29          ret = -ENOMEM;
  127.30          if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
  127.31              goto getvcpucontext_out;
  127.32 @@ -501,7 +505,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
  127.33          op->u.getvcpuinfo.cpumap   = 0;
  127.34          memcpy(&op->u.getvcpuinfo.cpumap,
  127.35                 cpus_addr(v->cpu_affinity),
  127.36 -               min((int)BITS_TO_LONGS(NR_CPUS),
  127.37 +               min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)),
  127.38                     (int)sizeof(op->u.getvcpuinfo.cpumap)));
  127.39          ret = 0;
  127.40  
   128.1 --- a/xen/common/domain.c	Tue Jan 10 15:21:00 2006 +0000
   128.2 +++ b/xen/common/domain.c	Tue Jan 24 17:54:34 2006 +0100
   128.3 @@ -29,7 +29,7 @@ struct domain *domain_list;
   128.4  
   128.5  struct domain *dom0;
   128.6  
   128.7 -struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
   128.8 +struct domain *domain_create(domid_t dom_id, unsigned int cpu)
   128.9  {
  128.10      struct domain *d, **pd;
  128.11      struct vcpu *v;
  128.12 @@ -46,25 +46,27 @@ struct domain *do_createdomain(domid_t d
  128.13      INIT_LIST_HEAD(&d->page_list);
  128.14      INIT_LIST_HEAD(&d->xenpage_list);
  128.15  
  128.16 -    if ( !is_idle_domain(d) )
  128.17 -        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
  128.18 +    rangeset_domain_initialise(d);
  128.19  
  128.20 -    if ( !is_idle_domain(d) &&
  128.21 -         ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
  128.22 -        goto fail1;
  128.23 -    
  128.24 +    if ( !is_idle_domain(d) )
  128.25 +    {
  128.26 +        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
  128.27 +        if ( evtchn_init(d) != 0 )
  128.28 +            goto fail1;
  128.29 +        if ( grant_table_create(d) != 0 )
  128.30 +            goto fail2;
  128.31 +    }
  128.32 +
  128.33 +    if ( arch_domain_create(d) != 0 )
  128.34 +        goto fail3;
  128.35 +
  128.36      if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
  128.37 -        goto fail2;
  128.38 -
  128.39 -    rangeset_domain_initialise(d);
  128.40 +        goto fail4;
  128.41  
  128.42      d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
  128.43      d->irq_caps   = rangeset_new(d, "Interrupts", 0);
  128.44 -
  128.45 -    if ( (d->iomem_caps == NULL) ||
  128.46 -         (d->irq_caps == NULL) ||
  128.47 -         (arch_do_createdomain(v) != 0) )
  128.48 -        goto fail3;
  128.49 +    if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
  128.50 +        goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */
  128.51  
  128.52      if ( !is_idle_domain(d) )
  128.53      {
  128.54 @@ -82,12 +84,16 @@ struct domain *do_createdomain(domid_t d
  128.55  
  128.56      return d;
  128.57  
  128.58 + fail4:
  128.59 +    arch_domain_destroy(d);
  128.60   fail3:
  128.61 -    rangeset_domain_destroy(d);
  128.62 +    if ( !is_idle_domain(d) )
  128.63 +        grant_table_destroy(d);
  128.64   fail2:
  128.65 -    grant_table_destroy(d);
  128.66 +    if ( !is_idle_domain(d) )
  128.67 +        evtchn_destroy(d);
  128.68   fail1:
  128.69 -    evtchn_destroy(d);
  128.70 +    rangeset_domain_destroy(d);
  128.71      free_domain(d);
  128.72      return NULL;
  128.73  }
  128.74 @@ -256,16 +262,16 @@ void domain_pause_for_debugger(void)
  128.75  
  128.76  
  128.77  /* Release resources belonging to task @p. */
  128.78 -void domain_destruct(struct domain *d)
  128.79 +void domain_destroy(struct domain *d)
  128.80  {
  128.81      struct domain **pd;
  128.82      atomic_t      old, new;
  128.83  
  128.84      BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
  128.85  
  128.86 -    /* May be already destructed, or get_domain() can race us. */
  128.87 +    /* May be already destroyed, or get_domain() can race us. */
  128.88      _atomic_set(old, 0);
  128.89 -    _atomic_set(new, DOMAIN_DESTRUCTED);
  128.90 +    _atomic_set(new, DOMAIN_DESTROYED);
  128.91      old = atomic_compareandswap(old, new, &d->refcnt);
  128.92      if ( _atomic_read(old) != 0 )
  128.93          return;
  128.94 @@ -287,8 +293,7 @@ void domain_destruct(struct domain *d)
  128.95      evtchn_destroy(d);
  128.96      grant_table_destroy(d);
  128.97  
  128.98 -    free_perdomain_pt(d);
  128.99 -    free_xenheap_page(d->shared_info);
 128.100 +    arch_domain_destroy(d);
 128.101  
 128.102      free_domain(d);
 128.103  
 128.104 @@ -369,16 +374,17 @@ int set_info_guest(struct domain *d, dom
 128.105      if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
 128.106          return -EINVAL;
 128.107      
 128.108 -    if ( !test_bit(_DOMF_ctrl_pause, &d->domain_flags) )
 128.109 -        return -EINVAL;
 128.110 -
 128.111      if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
 128.112          return -ENOMEM;
 128.113  
 128.114 +    domain_pause(d);
 128.115 +
 128.116      rc = -EFAULT;
 128.117      if ( copy_from_user(c, setvcpucontext->ctxt, sizeof(*c)) == 0 )
 128.118          rc = arch_set_info_guest(v, c);
 128.119  
 128.120 +    domain_unpause(d);
 128.121 +
 128.122      xfree(c);
 128.123      return rc;
 128.124  }
   129.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   129.2 +++ b/xen/common/gdbstub.c	Tue Jan 24 17:54:34 2006 +0100
   129.3 @@ -0,0 +1,593 @@
   129.4 +/*
   129.5 + * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
   129.6 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
   129.7 + *                    VA Linux Systems Japan. K.K.
   129.8 + * 
   129.9 + * gdbstub arch neutral part
  129.10 + * Based on x86 cdb (xen/arch/x86/cdb.c) and ppc gdbstub(xen/common/gdbstub.c)
  129.11 + * But extensively modified.
  129.12 + *
  129.13 + * This program is free software; you can redistribute it and/or modify
  129.14 + * it under the terms of the GNU General Public License as published by
  129.15 + * the Free Software Foundation; either version 2 of the License, or
  129.16 + * (at your option) any later version.
  129.17 + * 
  129.18 + * This program is distributed in the hope that it will be useful,
  129.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  129.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  129.21 + * GNU General Public License for more details.
  129.22 + * 
  129.23 + * You should have received a copy of the GNU General Public License
  129.24 + * along with this program; if not, write to the Free Software
  129.25 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  129.26 + */
  129.27 +
  129.28 +/*
  129.29 + * gdbstub: implements the architecture independant parts of the
  129.30 + * gdb remote protocol.
  129.31 + */
  129.32 +
  129.33 +/* We try to avoid assuming much about what the rest of the system is
  129.34 +   doing.  In particular, dynamic memory allocation is out of the
  129.35 +   question. */
  129.36 +
  129.37 +/* Resuming after we've stopped used to work, but more through luck
  129.38 +   than any actual intention.  It doesn't at the moment. */
  129.39 +
  129.40 +#include <xen/lib.h>
  129.41 +#include <asm/uaccess.h>
  129.42 +#include <xen/spinlock.h>
  129.43 +#include <xen/serial.h>
  129.44 +#include <xen/irq.h>
  129.45 +#include <asm/debugger.h>
  129.46 +#include <xen/init.h>
  129.47 +#include <xen/smp.h>
  129.48 +#include <xen/console.h>
  129.49 +
  129.50 +/* Printk isn't particularly safe just after we've trapped to the
  129.51 +   debugger. so avoid it. */
  129.52 +#define dbg_printk(...)
  129.53 +/*#define dbg_printk(...)   printk(__VA_ARGS__)*/
  129.54 +
  129.55 +#define GDB_RETRY_MAX   10
  129.56 +
  129.57 +static char opt_gdb[30] = "none";
  129.58 +string_param("gdb", opt_gdb);
  129.59 +
  129.60 +/* value <-> char (de)serialzers */
  129.61 +char
  129.62 +hex2char(unsigned long x)
  129.63 +{
  129.64 +    const char array[] = "0123456789abcdef";
  129.65 +
  129.66 +    return array[x & 15];
  129.67 +}
  129.68 +
  129.69 +int
  129.70 +char2hex(unsigned char c)
  129.71 +{
  129.72 +    if ( (c >= '0') && (c <= '9') )
  129.73 +        return c - '0';
  129.74 +    else if ( (c >= 'a') && (c <= 'f') )
  129.75 +        return c - 'a' + 10;
  129.76 +    else if ( (c >= 'A') && (c <= 'F') )
  129.77 +        return c - 'A' + 10;
  129.78 +    else
  129.79 +        BUG();
  129.80 +    return -1;
  129.81 +}
  129.82 +
  129.83 +char
  129.84 +str2hex(const char *str)
  129.85 +{
  129.86 +    return (char2hex(str[0]) << 4) | char2hex(str[1]);
  129.87 +}
  129.88 +
  129.89 +unsigned long
  129.90 +str2ulong(const char *str, unsigned long bytes)
  129.91 +{
  129.92 +    unsigned long x = 0;
  129.93 +    unsigned long i = 0;
  129.94 +
  129.95 +    while ( *str && (i < (bytes * 2)) )
  129.96 +    {
  129.97 +        x <<= 4;
  129.98 +        x += char2hex(*str);
  129.99 +        ++str;
 129.100 +        ++i;
 129.101 +    }
 129.102 +
 129.103 +    return x;
 129.104 +}
 129.105 +
 129.106 +/* gdb io wrappers */
 129.107 +static signed long
 129.108 +gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
 129.109 +{
 129.110 +    int i;
 129.111 +    for ( i = 0; i < len; i++ )
 129.112 +        serial_putc(ctx->serhnd, buf[i]);
 129.113 +    return i;
 129.114 +}
 129.115 +
 129.116 +static int
 129.117 +gdb_io_write_char(u8 data, struct gdb_context *ctx)
 129.118 +{
 129.119 +    return gdb_io_write((char*)&data, 1, ctx);
 129.120 +}
 129.121 +
 129.122 +static unsigned char
 129.123 +gdb_io_read(struct gdb_context *ctx)
 129.124 +{
 129.125 +    return serial_getc(ctx->serhnd);
 129.126 +}
 129.127 +
 129.128 +/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
 129.129 +/* Does not acknowledge. */
 129.130 +static int 
 129.131 +attempt_receive_packet(struct gdb_context *ctx)
 129.132 +{
 129.133 +    u8 csum;
 129.134 +    u8 received_csum;
 129.135 +    u8 ch;
 129.136 +
 129.137 +    /* Skip over everything up to the first '$' */
 129.138 +    while ( (ch = gdb_io_read(ctx)) != '$' )
 129.139 +        continue;
 129.140 +
 129.141 +    csum = 0;
 129.142 +    for ( ctx->in_bytes = 0;
 129.143 +          ctx->in_bytes < sizeof(ctx->in_buf);
 129.144 +          ctx->in_bytes++ )
 129.145 +    {
 129.146 +        ch = gdb_io_read(ctx);
 129.147 +        if ( ch == '#' )
 129.148 +            break;
 129.149 +        ctx->in_buf[ctx->in_bytes] = ch;
 129.150 +        csum += ch;
 129.151 +    }
 129.152 +
 129.153 +    if ( ctx->in_bytes == sizeof(ctx->in_buf) )
 129.154 +    {
 129.155 +        dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
 129.156 +        return -1;
 129.157 +    }
 129.158 +
 129.159 +    ctx->in_buf[ctx->in_bytes] = '\0';
 129.160 +    received_csum = char2hex(gdb_io_read(ctx)) * 16 +
 129.161 +        char2hex(gdb_io_read(ctx));
 129.162 +
 129.163 +    return (received_csum == csum) ? 0 : -1;
 129.164 +}
 129.165 +
 129.166 +/* Receive a command, discarding up to ten packets with csum
 129.167 + * errors.  Acknowledges all received packets. */
 129.168 +static int 
 129.169 +receive_command(struct gdb_context *ctx)
 129.170 +{
 129.171 +    int r, count = 0;
 129.172 +
 129.173 +    count = 0;
 129.174 +    do {
 129.175 +        r = attempt_receive_packet(ctx);
 129.176 +        gdb_io_write_char((r < 0) ? '-' : '+', ctx);
 129.177 +        count++;
 129.178 +    } while ( (r < 0) && (count < GDB_RETRY_MAX) );
 129.179 +
 129.180 +    return r;
 129.181 +}
 129.182 +
 129.183 +/* routines to send reply packets */
 129.184 +
 129.185 +static void 
 129.186 +gdb_start_packet(struct gdb_context *ctx)
 129.187 +{
 129.188 +    ctx->out_buf[0] = '$';
 129.189 +    ctx->out_offset = 1;
 129.190 +    ctx->out_csum = 0;
 129.191 +}
 129.192 +
 129.193 +static void 
 129.194 +gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
 129.195 +{
 129.196 +    ctx->out_csum += data;
 129.197 +    ctx->out_buf[ctx->out_offset] = data;
 129.198 +    ctx->out_offset++;
 129.199 +}
 129.200 +
 129.201 +void 
 129.202 +gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
 129.203 +{
 129.204 +    int x;
 129.205 +    for ( x = 0; x < count; x++ )
 129.206 +        gdb_write_to_packet_char(buf[x], ctx);
 129.207 +}
 129.208 +
 129.209 +void 
 129.210 +gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
 129.211 +{
 129.212 +    gdb_write_to_packet(buf, strlen(buf), ctx);
 129.213 +}
 129.214 +
 129.215 +void
 129.216 +gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
 129.217 +{
 129.218 +    char buf[sizeof(unsigned long) * 2 + 1];
 129.219 +    int i = sizeof(unsigned long) * 2;
 129.220 +    int width = int_size * 2;
 129.221 +
 129.222 +    buf[sizeof(unsigned long) * 2] = 0;
 129.223 +
 129.224 +    switch ( int_size )
 129.225 +    {
 129.226 +    case sizeof(u8):
 129.227 +    case sizeof(u16):
 129.228 +    case sizeof(u32):
 129.229 +    case sizeof(u64):
 129.230 +        break;
 129.231 +    default:
 129.232 +        dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
 129.233 +                   __func__, x, int_size);
 129.234 +        break;
 129.235 +    }
 129.236 +
 129.237 +    do {
 129.238 +        buf[--i] = hex2char(x & 15);
 129.239 +        x >>= 4;
 129.240 +    } while ( x );
 129.241 +
 129.242 +    while ( (i + width) > (sizeof(unsigned long) * 2) )
 129.243 +        buf[--i] = '0';
 129.244 +
 129.245 +    gdb_write_to_packet(&buf[i], width, ctx);
 129.246 +}
 129.247 +
 129.248 +static int
 129.249 +gdb_check_ack(struct gdb_context *ctx)
 129.250 +{
 129.251 +    u8 c = gdb_io_read(ctx);
 129.252 +
 129.253 +    switch ( c )
 129.254 +    {
 129.255 +    case '+':
 129.256 +        return 1;
 129.257 +    case '-':
 129.258 +        return 0;
 129.259 +    default:
 129.260 +        printk("Bad ack: %c\n", c);
 129.261 +        return 0;
 129.262 +    }
 129.263 +}
 129.264 +
 129.265 +/* Return 0 if the reply was successfully received, !0 otherwise. */
 129.266 +void 
 129.267 +gdb_send_packet(struct gdb_context *ctx)
 129.268 +{
 129.269 +    char buf[3];
 129.270 +    int count;
 129.271 +
 129.272 +    sprintf(buf, "%.02x\n", ctx->out_csum);
 129.273 +
 129.274 +    gdb_write_to_packet_char('#', ctx);
 129.275 +    gdb_write_to_packet(buf, 2, ctx);
 129.276 +
 129.277 +    count = 0;
 129.278 +    do {
 129.279 +        gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
 129.280 +    } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
 129.281 +
 129.282 +    if ( count == GDB_RETRY_MAX )
 129.283 +        dbg_printk("WARNING: %s reached max retry %d\n",
 129.284 +                   __func__, GDB_RETRY_MAX);
 129.285 +}
 129.286 +
 129.287 +void 
 129.288 +gdb_send_reply(const char *buf, struct gdb_context *ctx)
 129.289 +{
 129.290 +    gdb_start_packet(ctx);
 129.291 +    gdb_write_to_packet_str(buf, ctx);
 129.292 +    gdb_send_packet(ctx);
 129.293 +}
 129.294 +
 129.295 +/* arch neutral command handlers */
 129.296 +
 129.297 +static void 
 129.298 +gdb_cmd_signum(struct gdb_context *ctx)
 129.299 +{
 129.300 +    gdb_write_to_packet_char('S', ctx);
 129.301 +    gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
 129.302 +    gdb_send_packet(ctx);
 129.303 +}
 129.304 +
 129.305 +static void 
 129.306 +gdb_cmd_read_mem(unsigned long addr, unsigned long length,
 129.307 +                 struct gdb_context *ctx)
 129.308 +{
 129.309 +    int x, r;
 129.310 +    unsigned char val;
 129.311 +
 129.312 +    dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
 129.313 +               length);
 129.314 +
 129.315 +    for ( x = 0; x < length; x++ )
 129.316 +    {
 129.317 +        r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
 129.318 +        if ( r != 0 )
 129.319 +        {
 129.320 +            dbg_printk("Error reading from %lx.\n", addr + x);
 129.321 +            break;
 129.322 +        }
 129.323 +        gdb_write_to_packet_hex(val, sizeof(val), ctx);
 129.324 +    }
 129.325 +
 129.326 +    if ( x == 0 )
 129.327 +        gdb_write_to_packet_str("E05", ctx);
 129.328 +
 129.329 +    dbg_printk("Read done.\n");
 129.330 +
 129.331 +    gdb_send_packet(ctx);
 129.332 +}
 129.333 +
 129.334 +static void 
 129.335 +gdb_cmd_write_mem(unsigned long addr, unsigned long length,
 129.336 +                  const char *buf, struct gdb_context *ctx)
 129.337 +{
 129.338 +    int x, r;
 129.339 +    unsigned char val;
 129.340 +
 129.341 +    dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
 129.342 +
 129.343 +    for ( x = 0; x < length; x++, addr++, buf += 2 )
 129.344 +    {
 129.345 +        val = str2ulong(buf, sizeof(val));
 129.346 +        r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
 129.347 +        if ( r != 0 )
 129.348 +        {
 129.349 +            dbg_printk("Error writing to %lx.\n", addr);
 129.350 +            break;
 129.351 +        }
 129.352 +    }
 129.353 +
 129.354 +    gdb_write_to_packet_str((x != length) ? "OK" : "E11", ctx);
 129.355 +
 129.356 +    dbg_printk("Write done.\n");
 129.357 +
 129.358 +    gdb_send_packet(ctx);
 129.359 +}
 129.360 +
 129.361 +/* command dispatcher */
 129.362 +static int 
 129.363 +process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
 129.364 +{
 129.365 +    char *ptr;
 129.366 +    unsigned long addr, length;
 129.367 +    int resume = 0;
 129.368 +
 129.369 +    /* XXX check ctx->in_bytes >= 2 or similar. */
 129.370 +
 129.371 +    gdb_start_packet(ctx);
 129.372 +    switch ( ctx->in_buf[0] )
 129.373 +    {
 129.374 +    case '?':    /* query signal number */
 129.375 +        gdb_cmd_signum(ctx);
 129.376 +        break;
 129.377 +    case 'H':    /* thread operations */
 129.378 +        gdb_send_reply("OK", ctx);
 129.379 +        break;
 129.380 +    case 'g': /* Read registers */
 129.381 +        gdb_arch_read_reg_array(regs, ctx);
 129.382 +        ASSERT(!local_irq_is_enabled());
 129.383 +        break;
 129.384 +    case 'G': /* Write registers */
 129.385 +        gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
 129.386 +        break;
 129.387 +    case 'm': /* Read memory */
 129.388 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
 129.389 +        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
 129.390 +        {
 129.391 +            gdb_send_reply("E03", ctx);
 129.392 +            return 0;
 129.393 +        }
 129.394 +        length = simple_strtoul(ptr + 1, &ptr, 16);
 129.395 +        if ( ptr[0] != 0 )
 129.396 +        {
 129.397 +            gdb_send_reply("E04", ctx);
 129.398 +            return 0;
 129.399 +        }
 129.400 +        gdb_cmd_read_mem(addr, length, ctx);
 129.401 +        ASSERT(!local_irq_is_enabled());
 129.402 +        break;
 129.403 +    case 'M': /* Write memory */
 129.404 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
 129.405 +        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ':') )
 129.406 +        {
 129.407 +            gdb_send_reply("E03", ctx);
 129.408 +            return 0;
 129.409 +        }
 129.410 +        length = simple_strtoul(ptr + 1, &ptr, 16);
 129.411 +        gdb_cmd_write_mem(addr, length, ptr, ctx);
 129.412 +        break;
 129.413 +    case 'p': /* read register */
 129.414 +        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
 129.415 +        if ( ptr == (ctx->in_buf + 1) )
 129.416 +        {
 129.417 +            gdb_send_reply("E03", ctx);
 129.418 +            return 0;
 129.419 +        }
 129.420 +        if ( ptr[0] != 0 )
 129.421 +        {
 129.422 +            gdb_send_reply("E04", ctx);
 129.423 +            return 0;
 129.424 +        }
 129.425 +        gdb_arch_read_reg(addr, regs, ctx);
 129.426 +        break;
 129.427 +    case 'Z': /* We need to claim to support these or gdb
 129.428 +                 won't let you continue the process. */
 129.429 +    case 'z':
 129.430 +        gdb_send_reply("OK", ctx);
 129.431 +        break;
 129.432 +
 129.433 +    case 'D':
 129.434 +        ctx->currently_attached = 0;
 129.435 +        gdb_send_reply("OK", ctx);
 129.436 +        /* fall through */
 129.437 +    case 'k':
 129.438 +        ctx->connected = 0;
 129.439 +        /* fall through */
 129.440 +    case 's': /* Single step */
 129.441 +    case 'c': /* Resume at current address */
 129.442 +    {
 129.443 +        unsigned long addr = ~((unsigned long)0);
 129.444 +        unsigned long type = GDB_CONTINUE;
 129.445 +        if ( ctx->in_buf[0] == 's' )
 129.446 +            type = GDB_STEP;
 129.447 +        if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
 129.448 +             ctx->in_buf[1] )
 129.449 +            addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
 129.450 +        if ( ctx->in_buf[0] != 'D' )
 129.451 +            ctx->currently_attached = 1;
 129.452 +        resume = 1;
 129.453 +        gdb_arch_resume(regs, addr, type, ctx);
 129.454 +        break;
 129.455 +    }
 129.456 +
 129.457 +    default:
 129.458 +        gdb_send_reply("", ctx);
 129.459 +        break;
 129.460 +    }
 129.461 +    return resume;
 129.462 +}
 129.463 +
 129.464 +static struct gdb_context
 129.465 +__gdb_ctx = {
 129.466 +    .serhnd             = -1,
 129.467 +    .currently_attached = 0,
 129.468 +    .running            = ATOMIC_INIT(1),
 129.469 +    .connected          = 0,
 129.470 +    .signum             = 1,
 129.471 +    .in_bytes           = 0,
 129.472 +    .out_offset         = 0,
 129.473 +    .out_csum           = 0,
 129.474 +};
 129.475 +static struct gdb_context *gdb_ctx = &__gdb_ctx;
 129.476 +
 129.477 +/* trap handler: main entry point */
 129.478 +int 
 129.479 +__trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
 129.480 +{
 129.481 +    int resume = 0;
 129.482 +    int r;
 129.483 +    unsigned flags;
 129.484 +
 129.485 +    if ( gdb_ctx->serhnd < 0 )
 129.486 +    {
 129.487 +        dbg_printk("Debugger not ready yet.\n");
 129.488 +        return 0;
 129.489 +    }
 129.490 +
 129.491 +    /* We rely on our caller to ensure we're only on one processor
 129.492 +     * at a time... We should probably panic here, but given that
 129.493 +     * we're a debugger we should probably be a little tolerant of
 129.494 +     * things going wrong. */
 129.495 +    /* We don't want to use a spin lock here, because we're doing
 129.496 +       two distinct things:
 129.497 +
 129.498 +       1 -- we don't want to run on more than one processor at a time,
 129.499 +            and
 129.500 +       2 -- we want to do something sensible if we re-enter ourselves.
 129.501 +
 129.502 +       Spin locks are good for 1, but useless for 2. */
 129.503 +    if ( !atomic_dec_and_test(&gdb_ctx->running) )
 129.504 +    {
 129.505 +        printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
 129.506 +        atomic_inc(&gdb_ctx->running);
 129.507 +        return 0;
 129.508 +    }
 129.509 +
 129.510 +    if ( !gdb_ctx->connected )
 129.511 +    {
 129.512 +        printk("GDB connection activated\n");
 129.513 +        gdb_arch_print_state(regs);
 129.514 +        gdb_ctx->connected = 1;
 129.515 +    }
 129.516 +
 129.517 +    smp_send_stop();
 129.518 +
 129.519 +    /* Try to make things a little more stable by disabling
 129.520 +       interrupts while we're here. */
 129.521 +    local_irq_save(flags);
 129.522 +
 129.523 +    watchdog_disable();
 129.524 +    console_start_sync();
 129.525 +
 129.526 +    /* Shouldn't really do this, but otherwise we stop for no
 129.527 +       obvious reason, which is Bad */
 129.528 +    printk("Waiting for GDB to attach to Gdb\n");
 129.529 +
 129.530 +    gdb_arch_enter(regs);
 129.531 +    gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
 129.532 +    /* If gdb is already attached, tell it we've stopped again. */
 129.533 +    if ( gdb_ctx->currently_attached )
 129.534 +    {
 129.535 +        gdb_start_packet(gdb_ctx);
 129.536 +        gdb_cmd_signum(gdb_ctx);
 129.537 +    }
 129.538 +
 129.539 +    while ( resume == 0 )
 129.540 +    {
 129.541 +        ASSERT(!local_irq_is_enabled());
 129.542 +        r = receive_command(gdb_ctx);
 129.543 +        ASSERT(!local_irq_is_enabled());
 129.544 +        if ( r < 0 )
 129.545 +        {
 129.546 +            dbg_printk("GDB disappeared, trying to resume Xen...\n");
 129.547 +            resume = 1;
 129.548 +        }
 129.549 +        else
 129.550 +        {
 129.551 +            ASSERT(!local_irq_is_enabled());
 129.552 +            resume = process_command(regs, gdb_ctx);
 129.553 +            ASSERT(!local_irq_is_enabled());
 129.554 +        }
 129.555 +    }
 129.556 +
 129.557 +    gdb_arch_exit(regs);
 129.558 +    console_end_sync();
 129.559 +    watchdog_enable();
 129.560 +    atomic_inc(&gdb_ctx->running);
 129.561 +
 129.562 +    local_irq_restore(flags);
 129.563 +
 129.564 +    return 0;
 129.565 +}
 129.566 +
 129.567 +/*
 129.568 + * initialization
 129.569 + * XXX TODO
 129.570 + *     This should be an explicit call from architecture code.               
 129.571 + *     initcall is far too late for some early debugging, and only the 
 129.572 + *     architecture code knows when this call can be made.          
 129.573 + */
 129.574 +static int
 129.575 +initialize_gdb(void)
 129.576 +{
 129.577 +    if ( !strcmp(opt_gdb, "none") )
 129.578 +        return 0;
 129.579 +    gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
 129.580 +    if ( gdb_ctx->serhnd == -1 )
 129.581 +        panic("Can't parse %s as GDB serial info.\n", opt_gdb);
 129.582 +
 129.583 +    printk("Gdb initialised.\n");
 129.584 +    return 0;
 129.585 +}
 129.586 +
 129.587 +__initcall(initialize_gdb);
 129.588 +
 129.589 +/*
 129.590 + * Local variables:
 129.591 + * mode: C
 129.592 + * c-set-style: "BSD"
 129.593 + * c-basic-offset: 4
 129.594 + * tab-width: 4
 129.595 + * End:
 129.596 + */
   130.1 --- a/xen/common/kernel.c	Tue Jan 10 15:21:00 2006 +0000
   130.2 +++ b/xen/common/kernel.c	Tue Jan 24 17:54:34 2006 +0100
   130.3 @@ -11,6 +11,7 @@
   130.4  #include <xen/compile.h>
   130.5  #include <xen/sched.h>
   130.6  #include <asm/current.h>
   130.7 +#include <public/nmi.h>
   130.8  #include <public/version.h>
   130.9  
  130.10  void cmdline_parse(char *cmdline)
  130.11 @@ -148,6 +149,43 @@ long do_xen_version(int cmd, void *arg)
  130.12      return -ENOSYS;
  130.13  }
  130.14  
  130.15 +long do_nmi_op(unsigned int cmd, void *arg)
  130.16 +{
  130.17 +    struct vcpu *v = current;
  130.18 +    struct domain *d = current->domain;
  130.19 +    long rc = 0;
  130.20 +
  130.21 +    switch ( cmd )
  130.22 +    {
  130.23 +    case XENNMI_register_callback:
  130.24 +        if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
  130.25 +        { 
  130.26 +           rc = -EINVAL;
  130.27 +        }
  130.28 +        else
  130.29 +        {
  130.30 +            v->nmi_addr = (unsigned long)arg;
  130.31 +#ifdef CONFIG_X86
  130.32 +            /*
  130.33 +             * If no handler was registered we can 'lose the NMI edge'.
  130.34 +             * Re-assert it now.
  130.35 +             */
  130.36 +            if ( d->shared_info->arch.nmi_reason != 0 )
  130.37 +                set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
  130.38 +#endif
  130.39 +        }
  130.40 +        break;
  130.41 +    case XENNMI_unregister_callback:
  130.42 +        v->nmi_addr = 0;
  130.43 +        break;
  130.44 +    default:
  130.45 +        rc = -ENOSYS;
  130.46 +        break;
  130.47 +    }
  130.48 +
  130.49 +    return rc;
  130.50 +}
  130.51 +
  130.52  long do_vm_assist(unsigned int cmd, unsigned int type)
  130.53  {
  130.54      return vm_assist(current->domain, cmd, type);
   131.1 --- a/xen/common/memory.c	Tue Jan 10 15:21:00 2006 +0000
   131.2 +++ b/xen/common/memory.c	Tue Jan 24 17:54:34 2006 +0100
   131.3 @@ -38,10 +38,7 @@ increase_reservation(
   131.4  
   131.5      if ( (extent_order != 0) &&
   131.6           !multipage_allocation_permitted(current->domain) )
   131.7 -    {
   131.8 -        DPRINTK("Only I/O-capable domains may allocate multi-page extents.\n");
   131.9          return 0;
  131.10 -    }
  131.11  
  131.12      for ( i = 0; i < nr_extents; i++ )
  131.13      {
   132.1 --- a/xen/common/sched_bvt.c	Tue Jan 10 15:21:00 2006 +0000
   132.2 +++ b/xen/common/sched_bvt.c	Tue Jan 24 17:54:34 2006 +0100
   132.3 @@ -20,7 +20,7 @@
   132.4  #include <xen/delay.h>
   132.5  #include <xen/event.h>
   132.6  #include <xen/time.h>
   132.7 -#include <xen/ac_timer.h>
   132.8 +#include <xen/timer.h>
   132.9  #include <xen/perfc.h>
  132.10  #include <xen/sched-if.h>
  132.11  #include <xen/softirq.h>
  132.12 @@ -45,9 +45,9 @@ struct bvt_dom_info
  132.13                                               limits*/
  132.14      s32                 warp_value;       /* virtual time warp */
  132.15      s_time_t            warpl;            /* warp limit */
  132.16 -    struct ac_timer     warp_timer;       /* deals with warpl */
  132.17 +    struct timer        warp_timer;       /* deals with warpl */
  132.18      s_time_t            warpu;            /* unwarp time requirement */
  132.19 -    struct ac_timer     unwarp_timer;     /* deals with warpu */
  132.20 +    struct timer        unwarp_timer;     /* deals with warpu */
  132.21  
  132.22      struct bvt_vcpu_info vcpu_inf[MAX_VIRT_CPUS];
  132.23  };
  132.24 @@ -98,9 +98,9 @@ static inline int __task_on_runqueue(str
  132.25  static void warp_timer_fn(void *data)
  132.26  {
  132.27      struct bvt_dom_info *inf = data;
  132.28 -    unsigned int cpu = inf->domain->vcpu[0]->processor;
  132.29 -    
  132.30 -    spin_lock_irq(&schedule_data[cpu].schedule_lock);
  132.31 +    struct vcpu *v = inf->domain->vcpu[0];
  132.32 +
  132.33 +    vcpu_schedule_lock_irq(v);
  132.34  
  132.35      inf->warp = 0;
  132.36  
  132.37 @@ -108,28 +108,28 @@ static void warp_timer_fn(void *data)
  132.38      if ( inf->warpu == 0 )
  132.39      {
  132.40          inf->warpback = 0;
  132.41 -        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);   
  132.42 +        cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);   
  132.43      }
  132.44      
  132.45 -    set_ac_timer(&inf->unwarp_timer, NOW() + inf->warpu);
  132.46 +    set_timer(&inf->unwarp_timer, NOW() + inf->warpu);
  132.47  
  132.48 -    spin_unlock_irq(&schedule_data[cpu].schedule_lock);
  132.49 +    vcpu_schedule_unlock_irq(v);
  132.50  }
  132.51  
  132.52  static void unwarp_timer_fn(void *data)
  132.53  {
  132.54      struct bvt_dom_info *inf = data;
  132.55 -    unsigned int cpu = inf->domain->vcpu[0]->processor;
  132.56 +    struct vcpu *v = inf->domain->vcpu[0];
  132.57  
  132.58 -    spin_lock_irq(&schedule_data[cpu].schedule_lock);
  132.59 +    vcpu_schedule_lock_irq(v);
  132.60  
  132.61      if ( inf->warpback )
  132.62      {
  132.63          inf->warp = 1;
  132.64 -        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);   
  132.65 +        cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);   
  132.66      }
  132.67       
  132.68 -    spin_unlock_irq(&schedule_data[cpu].schedule_lock);
  132.69 +    vcpu_schedule_unlock_irq(v);
  132.70  }
  132.71  
  132.72  static inline u32 calc_avt(struct vcpu *d, s_time_t now)
  132.73 @@ -168,6 +168,7 @@ static inline u32 calc_evt(struct vcpu *
  132.74  static int bvt_alloc_task(struct vcpu *v)
  132.75  {
  132.76      struct domain *d = v->domain;
  132.77 +    struct bvt_dom_info *inf;
  132.78  
  132.79      if ( (d->sched_priv == NULL) )
  132.80      {
  132.81 @@ -176,32 +177,12 @@ static int bvt_alloc_task(struct vcpu *v
  132.82          memset(d->sched_priv, 0, sizeof(struct bvt_dom_info));
  132.83      }
  132.84  
  132.85 -    v->sched_priv = &BVT_INFO(d)->vcpu_inf[v->vcpu_id];
  132.86 -
  132.87 -    BVT_INFO(d)->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
  132.88 -    BVT_INFO(d)->vcpu_inf[v->vcpu_id].vcpu = v;
  132.89 -
  132.90 -    return 0;
  132.91 -}
  132.92 +    inf = BVT_INFO(d);
  132.93  
  132.94 -/*
  132.95 - * Add and remove a domain
  132.96 - */
  132.97 -static void bvt_add_task(struct vcpu *v) 
  132.98 -{
  132.99 -    struct bvt_dom_info *inf = BVT_INFO(v->domain);
 132.100 -    struct bvt_vcpu_info *einf = EBVT_INFO(v);
 132.101 -    ASSERT(inf != NULL);
 132.102 -    ASSERT(v   != NULL);
 132.103 +    v->sched_priv = &inf->vcpu_inf[v->vcpu_id];
 132.104  
 132.105 -    /* Allocate per-CPU context if this is the first domain to be added. */
 132.106 -    if ( CPU_INFO(v->processor) == NULL )
 132.107 -    {
 132.108 -        schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
 132.109 -        BUG_ON(CPU_INFO(v->processor) == NULL);
 132.110 -        INIT_LIST_HEAD(RUNQUEUE(v->processor));
 132.111 -        CPU_SVT(v->processor) = 0;
 132.112 -    }
 132.113 +    inf->vcpu_inf[v->vcpu_id].inf  = BVT_INFO(d);
 132.114 +    inf->vcpu_inf[v->vcpu_id].vcpu = v;
 132.115  
 132.116      if ( v->vcpu_id == 0 )
 132.117      {
 132.118 @@ -214,11 +195,28 @@ static void bvt_add_task(struct vcpu *v)
 132.119          inf->warpl       = MILLISECS(2000);
 132.120          inf->warpu       = MILLISECS(1000);
 132.121          /* Initialise the warp timers. */
 132.122 -        init_ac_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
 132.123 -        init_ac_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
 132.124 +        init_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
 132.125 +        init_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
 132.126      }
 132.127  
 132.128 -    einf->vcpu = v;
 132.129 +    return 0;
 132.130 +}
 132.131 +
 132.132 +/*
 132.133 + * Add and remove a domain
 132.134 + */
 132.135 +static void bvt_add_task(struct vcpu *v) 
 132.136 +{
 132.137 +    struct bvt_vcpu_info *einf = EBVT_INFO(v);
 132.138 +
 132.139 +    /* Allocate per-CPU context if this is the first domain to be added. */
 132.140 +    if ( CPU_INFO(v->processor) == NULL )
 132.141 +    {
 132.142 +        schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
 132.143 +        BUG_ON(CPU_INFO(v->processor) == NULL);
 132.144 +        INIT_LIST_HEAD(RUNQUEUE(v->processor));
 132.145 +        CPU_SVT(v->processor) = 0;
 132.146 +    }
 132.147  
 132.148      if ( is_idle_vcpu(v) )
 132.149      {
 132.150 @@ -271,7 +269,7 @@ static void bvt_wake(struct vcpu *v)
 132.151      if ( is_idle_vcpu(curr) || (einf->evt <= curr_evt) )
 132.152          cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
 132.153      else if ( schedule_data[cpu].s_timer.expires > r_time )
 132.154 -        set_ac_timer(&schedule_data[cpu].s_timer, r_time);
 132.155 +        set_timer(&schedule_data[cpu].s_timer, r_time);
 132.156  }
 132.157  
 132.158  
 132.159 @@ -305,8 +303,14 @@ static int bvt_set_affinity(struct vcpu 
 132.160   */
 132.161  static void bvt_free_task(struct domain *d)
 132.162  {
 132.163 -    ASSERT(d->sched_priv != NULL);
 132.164 -    xfree(d->sched_priv);
 132.165 +    struct bvt_dom_info *inf = BVT_INFO(d);
 132.166 +
 132.167 +    ASSERT(inf != NULL);
 132.168 +
 132.169 +    kill_timer(&inf->warp_timer);
 132.170 +    kill_timer(&inf->unwarp_timer);
 132.171 +
 132.172 +    xfree(inf);
 132.173  }
 132.174  
 132.175  /* Control the scheduler. */
 132.176 @@ -355,10 +359,10 @@ static int bvt_adjdom(
 132.177          inf->warpu = MILLISECS(warpu);
 132.178          
 132.179          /* If the unwarp timer set up it needs to be removed */
 132.180 -        rem_ac_timer(&inf->unwarp_timer);
 132.181 +        stop_timer(&inf->unwarp_timer);
 132.182          /* If we stop warping the warp timer needs to be removed */
 132.183          if ( !warpback )
 132.184 -            rem_ac_timer(&inf->warp_timer);
 132.185 +            stop_timer(&inf->warp_timer);
 132.186      }
 132.187      else if ( cmd->direction == SCHED_INFO_GET )
 132.188      {
 132.189 @@ -405,7 +409,7 @@ static struct task_slice bvt_do_schedule
 132.190          prev_einf->evt = calc_evt(prev, prev_einf->avt);
 132.191         
 132.192          if(prev_inf->warpback && prev_inf->warpl > 0)
 132.193 -            rem_ac_timer(&prev_inf->warp_timer);
 132.194 +            stop_timer(&prev_inf->warp_timer);
 132.195          
 132.196          __del_from_runqueue(prev);
 132.197          
 132.198 @@ -455,7 +459,7 @@ static struct task_slice bvt_do_schedule
 132.199      }
 132.200      
 132.201      if ( next_einf->inf->warp && next_einf->inf->warpl > 0 )
 132.202 -        set_ac_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
 132.203 +        set_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
 132.204     
 132.205      /* Extract the domain pointers from the dom infos */
 132.206      next        = next_einf->vcpu;
   133.1 --- a/xen/common/sched_sedf.c	Tue Jan 10 15:21:00 2006 +0000
   133.2 +++ b/xen/common/sched_sedf.c	Tue Jan 24 17:54:34 2006 +0100
   133.3 @@ -9,7 +9,7 @@
   133.4  #include <xen/sched.h>
   133.5  #include <xen/sched-if.h>
   133.6  #include <public/sched_ctl.h>
   133.7 -#include <xen/ac_timer.h>
   133.8 +#include <xen/timer.h>
   133.9  #include <xen/softirq.h>
  133.10  #include <xen/time.h>
  133.11  
   134.1 --- a/xen/common/schedule.c	Tue Jan 10 15:21:00 2006 +0000
   134.2 +++ b/xen/common/schedule.c	Tue Jan 24 17:54:34 2006 +0100
   134.3 @@ -21,7 +21,7 @@
   134.4  #include <xen/delay.h>
   134.5  #include <xen/event.h>
   134.6  #include <xen/time.h>
   134.7 -#include <xen/ac_timer.h>
   134.8 +#include <xen/timer.h>
   134.9  #include <xen/perfc.h>
  134.10  #include <xen/sched-if.h>
  134.11  #include <xen/softirq.h>
  134.12 @@ -71,17 +71,31 @@ static struct scheduler ops;
  134.13            : (typeof(ops.fn(__VA_ARGS__)))0 )
  134.14  
  134.15  /* Per-CPU periodic timer sends an event to the currently-executing domain. */
  134.16 -static struct ac_timer t_timer[NR_CPUS]; 
  134.17 +static struct timer t_timer[NR_CPUS]; 
  134.18 +
  134.19 +struct domain *alloc_domain(void)
  134.20 +{
  134.21 +    struct domain *d;
  134.22 +
  134.23 +    if ( (d = xmalloc(struct domain)) != NULL )
  134.24 +        memset(d, 0, sizeof(*d));
  134.25 +
  134.26 +    return d;
  134.27 +}
  134.28  
  134.29  void free_domain(struct domain *d)
  134.30  {
  134.31 +    struct vcpu *v;
  134.32      int i;
  134.33  
  134.34 +    for_each_vcpu ( d, v )
  134.35 +        sched_rem_domain(v);
  134.36 +
  134.37      SCHED_OP(free_task, d);
  134.38  
  134.39      for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
  134.40 -        if ( d->vcpu[i] != NULL )
  134.41 -            free_vcpu_struct(d->vcpu[i]);
  134.42 +        if ( (v = d->vcpu[i]) != NULL )
  134.43 +            free_vcpu_struct(v);
  134.44  
  134.45      xfree(d);
  134.46  }
  134.47 @@ -100,48 +114,33 @@ struct vcpu *alloc_vcpu(
  134.48      v->vcpu_id = vcpu_id;
  134.49      v->processor = cpu_id;
  134.50      atomic_set(&v->pausecnt, 0);
  134.51 +    v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
  134.52  
  134.53      v->cpu_affinity = is_idle_domain(d) ?
  134.54          cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
  134.55  
  134.56 -    d->vcpu[vcpu_id] = v;
  134.57 +    if ( (vcpu_id != 0) && !is_idle_domain(d) )
  134.58 +        set_bit(_VCPUF_down, &v->vcpu_flags);
  134.59  
  134.60      if ( SCHED_OP(alloc_task, v) < 0 )
  134.61      {
  134.62 -        d->vcpu[vcpu_id] = NULL;
  134.63          free_vcpu_struct(v);
  134.64          return NULL;
  134.65      }
  134.66  
  134.67 -    sched_add_domain(v);
  134.68 -
  134.69 +    d->vcpu[vcpu_id] = v;
  134.70      if ( vcpu_id != 0 )
  134.71 -    {
  134.72 -        v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
  134.73          d->vcpu[v->vcpu_id-1]->next_in_list = v;
  134.74 -        set_bit(_VCPUF_down, &v->vcpu_flags);
  134.75 -    }
  134.76 +
  134.77 +    sched_add_domain(v);
  134.78  
  134.79      return v;
  134.80  }
  134.81  
  134.82 -struct domain *alloc_domain(void)
  134.83 -{
  134.84 -    struct domain *d;
  134.85 -
  134.86 -    if ( (d = xmalloc(struct domain)) != NULL )
  134.87 -        memset(d, 0, sizeof(*d));
  134.88 -
  134.89 -    return d;
  134.90 -}
  134.91 -
  134.92 -/*
  134.93 - * Add and remove a domain
  134.94 - */
  134.95  void sched_add_domain(struct vcpu *v) 
  134.96  {
  134.97      /* Initialise the per-domain timer. */
  134.98 -    init_ac_timer(&v->timer, dom_timer_fn, v, v->processor);
  134.99 +    init_timer(&v->timer, dom_timer_fn, v, v->processor);
 134.100  
 134.101      if ( is_idle_vcpu(v) )
 134.102      {
 134.103 @@ -156,7 +155,7 @@ void sched_add_domain(struct vcpu *v)
 134.104  
 134.105  void sched_rem_domain(struct vcpu *v) 
 134.106  {
 134.107 -    rem_ac_timer(&v->timer);
 134.108 +    kill_timer(&v->timer);
 134.109      SCHED_OP(rem_task, v);
 134.110      TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
 134.111  }
 134.112 @@ -165,26 +164,19 @@ void vcpu_sleep_nosync(struct vcpu *v)
 134.113  {
 134.114      unsigned long flags;
 134.115  
 134.116 -    spin_lock_irqsave(&schedule_data[v->processor].schedule_lock, flags);
 134.117 +    vcpu_schedule_lock_irqsave(v, flags);
 134.118      if ( likely(!vcpu_runnable(v)) )
 134.119          SCHED_OP(sleep, v);
 134.120 -    spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
 134.121 +    vcpu_schedule_unlock_irqrestore(v, flags);
 134.122  
 134.123      TRACE_2D(TRC_SCHED_SLEEP, v->domain->domain_id, v->vcpu_id);
 134.124 -} 
 134.125 +}
 134.126  
 134.127  void vcpu_sleep_sync(struct vcpu *v)
 134.128  {
 134.129      vcpu_sleep_nosync(v);
 134.130  
 134.131 -    /*
 134.132 -     * We can be sure that the VCPU is finally descheduled after the running
 134.133 -     * flag is cleared and the scheduler lock is released. We also check that
 134.134 -     * the domain continues to be unrunnable, in case someone else wakes it.
 134.135 -     */
 134.136 -    while ( !vcpu_runnable(v) &&
 134.137 -            (test_bit(_VCPUF_running, &v->vcpu_flags) ||
 134.138 -             spin_is_locked(&schedule_data[v->processor].schedule_lock)) )
 134.139 +    while ( !vcpu_runnable(v) && test_bit(_VCPUF_running, &v->vcpu_flags) )
 134.140          cpu_relax();
 134.141  
 134.142      sync_vcpu_execstate(v);
 134.143 @@ -194,20 +186,23 @@ void vcpu_wake(struct vcpu *v)
 134.144  {
 134.145      unsigned long flags;
 134.146  
 134.147 -    spin_lock_irqsave(&schedule_data[v->processor].schedule_lock, flags);
 134.148 +    vcpu_schedule_lock_irqsave(v, flags);
 134.149      if ( likely(vcpu_runnable(v)) )
 134.150      {
 134.151          SCHED_OP(wake, v);
 134.152          v->wokenup = NOW();
 134.153      }
 134.154 -    spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
 134.155 +    vcpu_schedule_unlock_irqrestore(v, flags);
 134.156  
 134.157      TRACE_2D(TRC_SCHED_WAKE, v->domain->domain_id, v->vcpu_id);
 134.158  }
 134.159  
 134.160  int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
 134.161  {
 134.162 -    if ( cpus_empty(*affinity) )
 134.163 +    cpumask_t online_affinity;
 134.164 +
 134.165 +    cpus_and(online_affinity, *affinity, cpu_online_map);
 134.166 +    if ( cpus_empty(online_affinity) )
 134.167          return -EINVAL;
 134.168  
 134.169      return SCHED_OP(set_affinity, v, affinity);
 134.170 @@ -282,9 +277,9 @@ long do_set_timer_op(s_time_t timeout)
 134.171      struct vcpu *v = current;
 134.172  
 134.173      if ( timeout == 0 )
 134.174 -        rem_ac_timer(&v->timer);
 134.175 +        stop_timer(&v->timer);
 134.176      else
 134.177 -        set_ac_timer(&v->timer, timeout);
 134.178 +        set_timer(&v->timer, timeout);
 134.179  
 134.180      return 0;
 134.181  }
 134.182 @@ -311,68 +306,42 @@ long sched_adjdom(struct sched_adjdom_cm
 134.183  {
 134.184      struct domain *d;
 134.185      struct vcpu *v;
 134.186 -    int cpu;
 134.187 -#if NR_CPUS <=32
 134.188 -    unsigned long have_lock;
 134.189 - #else
 134.190 -    unsigned long long have_lock;
 134.191 -#endif
 134.192 -    int succ;
 134.193 -
 134.194 -    #define __set_cpu_bit(cpu, data) data |= ((typeof(data))1)<<cpu
 134.195 -    #define __get_cpu_bit(cpu, data) (data & ((typeof(data))1)<<cpu)
 134.196 -    #define __clear_cpu_bits(data) data = ((typeof(data))0)
 134.197      
 134.198 -    if ( cmd->sched_id != ops.sched_id )
 134.199 -        return -EINVAL;
 134.200 -    
 134.201 -    if ( cmd->direction != SCHED_INFO_PUT && cmd->direction != SCHED_INFO_GET )
 134.202 +    if ( (cmd->sched_id != ops.sched_id) ||
 134.203 +         ((cmd->direction != SCHED_INFO_PUT) &&
 134.204 +          (cmd->direction != SCHED_INFO_GET)) )
 134.205          return -EINVAL;
 134.206  
 134.207      d = find_domain_by_id(cmd->domain);
 134.208      if ( d == NULL )
 134.209          return -ESRCH;
 134.210  
 134.211 -    /* acquire locks on all CPUs on which vcpus of this domain run */
 134.212 -    do {
 134.213 -        succ = 0;
 134.214 -        __clear_cpu_bits(have_lock);
 134.215 -        for_each_vcpu ( d, v )
 134.216 -        {
 134.217 -            cpu = v->processor;
 134.218 -            if ( !__get_cpu_bit(cpu, have_lock) )
 134.219 -            {
 134.220 -                /* if we don't have a lock on this CPU: acquire it*/
 134.221 -                if ( spin_trylock(&schedule_data[cpu].schedule_lock) )
 134.222 -                {
 134.223 -                    /*we have this lock!*/
 134.224 -                    __set_cpu_bit(cpu, have_lock);
 134.225 -                    succ = 1;
 134.226 -                }
 134.227 -                else
 134.228 -                {
 134.229 -                    /*we didn,t get this lock -> free all other locks too!*/
 134.230 -                    for ( cpu = 0; cpu < NR_CPUS; cpu++ )
 134.231 -                        if ( __get_cpu_bit(cpu, have_lock) )
 134.232 -                            spin_unlock(&schedule_data[cpu].schedule_lock);
 134.233 -                    /* and start from the beginning! */
 134.234 -                    succ = 0;
 134.235 -                    /* leave the "for_each_domain_loop" */
 134.236 -                    break;
 134.237 -                }
 134.238 -            }
 134.239 -        }
 134.240 -    } while ( !succ );
 134.241 +    /*
 134.242 +     * Most VCPUs we can simply pause. If we are adjusting this VCPU then
 134.243 +     * we acquire the local schedule_lock to guard against concurrent updates.
 134.244 +     */
 134.245 +    for_each_vcpu ( d, v )
 134.246 +    {
 134.247 +        if ( v == current )
 134.248 +            vcpu_schedule_lock_irq(v);
 134.249 +        else
 134.250 +            vcpu_pause(v);
 134.251 +    }
 134.252  
 134.253      SCHED_OP(adjdom, d, cmd);
 134.254  
 134.255 -    for ( cpu = 0; cpu < NR_CPUS; cpu++ )
 134.256 -        if ( __get_cpu_bit(cpu, have_lock) )
 134.257 -            spin_unlock(&schedule_data[cpu].schedule_lock);
 134.258 -    __clear_cpu_bits(have_lock);
 134.259 +    TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
 134.260  
 134.261 -    TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
 134.262 +    for_each_vcpu ( d, v )
 134.263 +    {
 134.264 +        if ( v == current )
 134.265 +            vcpu_schedule_unlock_irq(v);
 134.266 +        else
 134.267 +            vcpu_unpause(v);
 134.268 +    }
 134.269 +
 134.270      put_domain(d);
 134.271 +
 134.272      return 0;
 134.273  }
 134.274  
 134.275 @@ -395,7 +364,7 @@ static void __enter_scheduler(void)
 134.276  
 134.277      spin_lock_irq(&schedule_data[cpu].schedule_lock);
 134.278  
 134.279 -    rem_ac_timer(&schedule_data[cpu].s_timer);
 134.280 +    stop_timer(&schedule_data[cpu].s_timer);
 134.281      
 134.282      prev->cpu_time += now - prev->lastschd;
 134.283  
 134.284 @@ -409,7 +378,7 @@ static void __enter_scheduler(void)
 134.285      
 134.286      next->lastschd = now;
 134.287  
 134.288 -    set_ac_timer(&schedule_data[cpu].s_timer, now + r_time);
 134.289 +    set_timer(&schedule_data[cpu].s_timer, now + r_time);
 134.290  
 134.291      if ( unlikely(prev == next) )
 134.292      {
 134.293 @@ -451,6 +420,7 @@ static void __enter_scheduler(void)
 134.294      }
 134.295  #endif
 134.296  
 134.297 +    ASSERT(!test_bit(_VCPUF_running, &next->vcpu_flags));
 134.298      set_bit(_VCPUF_running, &next->vcpu_flags);
 134.299  
 134.300      spin_unlock_irq(&schedule_data[cpu].schedule_lock);
 134.301 @@ -492,7 +462,7 @@ static void s_timer_fn(void *unused)
 134.302  /* Periodic tick timer: send timer event to current domain */
 134.303  static void t_timer_fn(void *unused)
 134.304  {
 134.305 -    struct vcpu  *v  = current;
 134.306 +    struct vcpu  *v   = current;
 134.307      unsigned int  cpu = smp_processor_id();
 134.308  
 134.309      schedule_data[cpu].tick++;
 134.310 @@ -505,7 +475,7 @@ static void t_timer_fn(void *unused)
 134.311  
 134.312      page_scrub_schedule_work();
 134.313  
 134.314 -    set_ac_timer(&t_timer[cpu], NOW() + MILLISECS(10));
 134.315 +    set_timer(&t_timer[cpu], NOW() + MILLISECS(10));
 134.316  }
 134.317  
 134.318  /* Domain timer function, sends a virtual timer interrupt to domain */
 134.319 @@ -527,8 +497,8 @@ void __init scheduler_init(void)
 134.320      for ( i = 0; i < NR_CPUS; i++ )
 134.321      {
 134.322          spin_lock_init(&schedule_data[i].schedule_lock);
 134.323 -        init_ac_timer(&schedule_data[i].s_timer, s_timer_fn, NULL, i);
 134.324 -        init_ac_timer(&t_timer[i], t_timer_fn, NULL, i);
 134.325 +        init_timer(&schedule_data[i].s_timer, s_timer_fn, NULL, i);
 134.326 +        init_timer(&t_timer[i], t_timer_fn, NULL, i);
 134.327      }
 134.328  
 134.329      for ( i = 0; schedulers[i] != NULL; i++ )
   135.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   135.2 +++ b/xen/common/timer.c	Tue Jan 24 17:54:34 2006 +0100
   135.3 @@ -0,0 +1,308 @@
   135.4 +/******************************************************************************
   135.5 + * timer.c
   135.6 + * 
   135.7 + * Copyright (c) 2002-2003 Rolf Neugebauer
   135.8 + * Copyright (c) 2002-2005 K A Fraser
   135.9 + */
  135.10 +
  135.11 +#include <xen/config.h>
  135.12 +#include <xen/init.h>
  135.13 +#include <xen/types.h>
  135.14 +#include <xen/errno.h>
  135.15 +#include <xen/sched.h>
  135.16 +#include <xen/lib.h>
  135.17 +#include <xen/smp.h>
  135.18 +#include <xen/perfc.h>
  135.19 +#include <xen/time.h>
  135.20 +#include <xen/softirq.h>
  135.21 +#include <xen/timer.h>
  135.22 +#include <xen/keyhandler.h>
  135.23 +#include <asm/system.h>
  135.24 +#include <asm/desc.h>
  135.25 +
  135.26 +/*
  135.27 + * We pull handlers off the timer list this far in future,
  135.28 + * rather than reprogramming the time hardware.
  135.29 + */
  135.30 +#define TIMER_SLOP (50*1000) /* ns */
  135.31 +
  135.32 +struct timers {
  135.33 +    spinlock_t     lock;
  135.34 +    struct timer **heap;
  135.35 +    struct timer  *running;
  135.36 +} __cacheline_aligned;
  135.37 +
  135.38 +struct timers timers[NR_CPUS];
  135.39 +
  135.40 +extern int reprogram_timer(s_time_t timeout);
  135.41 +
  135.42 +/****************************************************************************
  135.43 + * HEAP OPERATIONS.
  135.44 + */
  135.45 +
  135.46 +#define GET_HEAP_SIZE(_h)     ((int)(((u16 *)(_h))[0]))
  135.47 +#define SET_HEAP_SIZE(_h,_v)  (((u16 *)(_h))[0] = (u16)(_v))
  135.48 +
  135.49 +#define GET_HEAP_LIMIT(_h)    ((int)(((u16 *)(_h))[1]))
  135.50 +#define SET_HEAP_LIMIT(_h,_v) (((u16 *)(_h))[1] = (u16)(_v))
  135.51 +
  135.52 +/* Sink down element @pos of @heap. */
  135.53 +static void down_heap(struct timer **heap, int pos)
  135.54 +{
  135.55 +    int sz = GET_HEAP_SIZE(heap), nxt;
  135.56 +    struct timer *t = heap[pos];
  135.57 +
  135.58 +    while ( (nxt = (pos << 1)) <= sz )
  135.59 +    {
  135.60 +        if ( ((nxt+1) <= sz) && (heap[nxt+1]->expires < heap[nxt]->expires) )
  135.61 +            nxt++;
  135.62 +        if ( heap[nxt]->expires > t->expires )
  135.63 +            break;
  135.64 +        heap[pos] = heap[nxt];
  135.65 +        heap[pos]->heap_offset = pos;
  135.66 +        pos = nxt;
  135.67 +    }
  135.68 +
  135.69 +    heap[pos] = t;
  135.70 +    t->heap_offset = pos;
  135.71 +}
  135.72 +
  135.73 +/* Float element @pos up @heap. */
  135.74 +static void up_heap(struct timer **heap, int pos)
  135.75 +{
  135.76 +    struct timer *t = heap[pos];
  135.77 +
  135.78 +    while ( (pos > 1) && (t->expires < heap[pos>>1]->expires) )
  135.79 +    {
  135.80 +        heap[pos] = heap[pos>>1];
  135.81 +        heap[pos]->heap_offset = pos;
  135.82 +        pos >>= 1;
  135.83 +    }
  135.84 +
  135.85 +    heap[pos] = t;
  135.86 +    t->heap_offset = pos;
  135.87 +}
  135.88 +
  135.89 +
  135.90 +/* Delete @t from @heap. Return TRUE if new top of heap. */
  135.91 +static int remove_entry(struct timer **heap, struct timer *t)
  135.92 +{
  135.93 +    int sz = GET_HEAP_SIZE(heap);
  135.94 +    int pos = t->heap_offset;
  135.95 +
  135.96 +    t->heap_offset = 0;
  135.97 +
  135.98 +    if ( unlikely(pos == sz) )
  135.99 +    {
 135.100 +        SET_HEAP_SIZE(heap, sz-1);
 135.101 +        goto out;
 135.102 +    }
 135.103 +
 135.104 +    heap[pos] = heap[sz];
 135.105 +    heap[pos]->heap_offset = pos;
 135.106 +
 135.107 +    SET_HEAP_SIZE(heap, --sz);
 135.108 +
 135.109 +    if ( (pos > 1) && (heap[pos]->expires < heap[pos>>1]->expires) )
 135.110 +        up_heap(heap, pos);
 135.111 +    else
 135.112 +        down_heap(heap, pos);
 135.113 +
 135.114 + out:
 135.115 +    return (pos == 1);
 135.116 +}
 135.117 +
 135.118 +
 135.119 +/* Add new entry @t to @heap. Return TRUE if new top of heap. */
 135.120 +static int add_entry(struct timer ***pheap, struct timer *t)
 135.121 +{
 135.122 +    struct timer **heap = *pheap;
 135.123 +    int sz = GET_HEAP_SIZE(heap);
 135.124 +
 135.125 +    /* Copy the heap if it is full. */
 135.126 +    if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
 135.127 +    {
 135.128 +        /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
 135.129 +        int old_limit = GET_HEAP_LIMIT(heap);
 135.130 +        int new_limit = ((old_limit + 1) << 4) - 1;
 135.131 +        heap = xmalloc_array(struct timer *, new_limit + 1);
 135.132 +        BUG_ON(heap == NULL);
 135.133 +        memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
 135.134 +        SET_HEAP_LIMIT(heap, new_limit);
 135.135 +        if ( old_limit != 0 )
 135.136 +            xfree(*pheap);
 135.137 +        *pheap = heap;
 135.138 +    }
 135.139 +
 135.140 +    SET_HEAP_SIZE(heap, ++sz);
 135.141 +    heap[sz] = t;
 135.142 +    t->heap_offset = sz;
 135.143 +    up_heap(heap, sz);
 135.144 +    return (t->heap_offset == 1);
 135.145 +}
 135.146 +
 135.147 +
 135.148 +/****************************************************************************
 135.149 + * TIMER OPERATIONS.
 135.150 + */
 135.151 +
 135.152 +static inline void __add_timer(struct timer *timer)
 135.153 +{
 135.154 +    int cpu = timer->cpu;
 135.155 +    if ( add_entry(&timers[cpu].heap, timer) )
 135.156 +        cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
 135.157 +}
 135.158 +
 135.159 +
 135.160 +static inline void __stop_timer(struct timer *timer)
 135.161 +{
 135.162 +    int cpu = timer->cpu;
 135.163 +    if ( remove_entry(timers[cpu].heap, timer) )
 135.164 +        cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
 135.165 +}
 135.166 +
 135.167 +
 135.168 +void set_timer(struct timer *timer, s_time_t expires)
 135.169 +{
 135.170 +    int           cpu = timer->cpu;
 135.171 +    unsigned long flags;
 135.172 +
 135.173 +    spin_lock_irqsave(&timers[cpu].lock, flags);
 135.174 +    if ( active_timer(timer) )
 135.175 +        __stop_timer(timer);
 135.176 +    timer->expires = expires;
 135.177 +    if ( likely(!timer->killed) )
 135.178 +        __add_timer(timer);
 135.179 +    spin_unlock_irqrestore(&timers[cpu].lock, flags);
 135.180 +}
 135.181 +
 135.182 +
 135.183 +void stop_timer(struct timer *timer)
 135.184 +{
 135.185 +    int           cpu = timer->cpu;
 135.186 +    unsigned long flags;
 135.187 +
 135.188 +    spin_lock_irqsave(&timers[cpu].lock, flags);
 135.189 +    if ( active_timer(timer) )
 135.190 +        __stop_timer(timer);
 135.191 +    spin_unlock_irqrestore(&timers[cpu].lock, flags);
 135.192 +}
 135.193 +
 135.194 +
 135.195 +void kill_timer(struct timer *timer)
 135.196 +{
 135.197 +    int           cpu = timer->cpu;
 135.198 +    unsigned long flags;
 135.199 +
 135.200 +    BUG_ON(timers[cpu].running == timer);
 135.201 +
 135.202 +    spin_lock_irqsave(&timers[cpu].lock, flags);
 135.203 +    if ( active_timer(timer) )
 135.204 +        __stop_timer(timer);
 135.205 +    timer->killed = 1;
 135.206 +    spin_unlock_irqrestore(&timers[cpu].lock, flags);
 135.207 +
 135.208 +    for_each_online_cpu ( cpu )
 135.209 +        while ( timers[cpu].running == timer )
 135.210 +            cpu_relax();
 135.211 +}
 135.212 +
 135.213 +
 135.214 +static void timer_softirq_action(void)
 135.215 +{
 135.216 +    int           cpu = smp_processor_id();
 135.217 +    struct timer *t, **heap;
 135.218 +    s_time_t      now;
 135.219 +    void        (*fn)(void *);
 135.220 +    void         *data;
 135.221 +
 135.222 +    spin_lock_irq(&timers[cpu].lock);
 135.223 +    
 135.224 +    do {
 135.225 +        heap = timers[cpu].heap;
 135.226 +        now  = NOW();
 135.227 +
 135.228 +        while ( (GET_HEAP_SIZE(heap) != 0) &&
 135.229 +                ((t = heap[1])->expires < (now + TIMER_SLOP)) )
 135.230 +        {
 135.231 +            remove_entry(heap, t);
 135.232 +
 135.233 +            timers[cpu].running = t;
 135.234 +
 135.235 +            fn   = t->function;
 135.236 +            data = t->data;
 135.237 +
 135.238 +            spin_unlock_irq(&timers[cpu].lock);
 135.239 +            (*fn)(data);
 135.240 +            spin_lock_irq(&timers[cpu].lock);
 135.241 +
 135.242 +            /* Heap may have grown while the lock was released. */
 135.243 +            heap = timers[cpu].heap;
 135.244 +        }
 135.245 +
 135.246 +        timers[cpu].running = NULL;
 135.247 +    }
 135.248 +    while ( !reprogram_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
 135.249 +
 135.250 +    spin_unlock_irq(&timers[cpu].lock);
 135.251 +}
 135.252 +
 135.253 +
 135.254 +static void dump_timerq(unsigned char key)
 135.255 +{
 135.256 +    struct timer *t;
 135.257 +    unsigned long flags; 
 135.258 +    s_time_t      now = NOW();
 135.259 +    int           i, j;
 135.260 +
 135.261 +    printk("Dumping timer queues: NOW=0x%08X%08X\n",
 135.262 +           (u32)(now>>32), (u32)now); 
 135.263 +
 135.264 +    for_each_online_cpu( i )
 135.265 +    {
 135.266 +        printk("CPU[%02d] ", i);
 135.267 +        spin_lock_irqsave(&timers[i].lock, flags);
 135.268 +        for ( j = 1; j <= GET_HEAP_SIZE(timers[i].heap); j++ )
 135.269 +        {
 135.270 +            t = timers[i].heap[j];
 135.271 +            printk ("  %d : %p ex=0x%08X%08X %p\n",
 135.272 +                    j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
 135.273 +        }
 135.274 +        spin_unlock_irqrestore(&timers[i].lock, flags);
 135.275 +        printk("\n");
 135.276 +    }
 135.277 +}
 135.278 +
 135.279 +
 135.280 +void __init timer_init(void)
 135.281 +{
 135.282 +    static struct timer *dummy_heap;
 135.283 +    int i;
 135.284 +
 135.285 +    open_softirq(TIMER_SOFTIRQ, timer_softirq_action);
 135.286 +
 135.287 +    /*
 135.288 +     * All CPUs initially share an empty dummy heap. Only those CPUs that
 135.289 +     * are brought online will be dynamically allocated their own heap.
 135.290 +     */
 135.291 +    SET_HEAP_SIZE(&dummy_heap, 0);
 135.292 +    SET_HEAP_LIMIT(&dummy_heap, 0);
 135.293 +
 135.294 +    for ( i = 0; i < NR_CPUS; i++ )
 135.295 +    {
 135.296 +        spin_lock_init(&timers[i].lock);
 135.297 +        timers[i].heap = &dummy_heap;
 135.298 +    }
 135.299 +
 135.300 +    register_keyhandler('a', dump_timerq, "dump timer queues");
 135.301 +}
 135.302 +
 135.303 +/*
 135.304 + * Local variables:
 135.305 + * mode: C
 135.306 + * c-set-style: "BSD"
 135.307 + * c-basic-offset: 4
 135.308 + * tab-width: 4
 135.309 + * indent-tabs-mode: nil
 135.310 + * End:
 135.311 + */
   136.1 --- a/xen/common/xmalloc.c	Tue Jan 10 15:21:00 2006 +0000
   136.2 +++ b/xen/common/xmalloc.c	Tue Jan 24 17:54:34 2006 +0100
   136.3 @@ -30,7 +30,7 @@
   136.4  #include <xen/config.h>
   136.5  #include <xen/mm.h>
   136.6  #include <xen/spinlock.h>
   136.7 -#include <xen/ac_timer.h>
   136.8 +#include <xen/timer.h>
   136.9  #include <xen/cache.h>
  136.10  #include <xen/prefetch.h>
  136.11  
   137.1 --- a/xen/drivers/char/ns16550.c	Tue Jan 10 15:21:00 2006 +0000
   137.2 +++ b/xen/drivers/char/ns16550.c	Tue Jan 24 17:54:34 2006 +0100
   137.3 @@ -33,7 +33,7 @@ static struct ns16550 {
   137.4      /* UART with IRQ line: interrupt-driven I/O. */
   137.5      struct irqaction irqaction;
   137.6      /* UART with no IRQ line: periodically-polled I/O. */
   137.7 -    struct ac_timer timer;
   137.8 +    struct timer timer;
   137.9      unsigned int timeout_ms;
  137.10  } ns16550_com[2] = { { 0 } };
  137.11  
  137.12 @@ -138,7 +138,7 @@ static void ns16550_poll(void *data)
  137.13      if ( ns_read_reg(uart, LSR) & LSR_THRE )
  137.14          serial_tx_interrupt(port, regs);
  137.15  
  137.16 -    set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
  137.17 +    set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
  137.18  }
  137.19  
  137.20  static int ns16550_tx_empty(struct serial_port *port)
  137.21 @@ -214,8 +214,8 @@ static void ns16550_init_postirq(struct 
  137.22          bits = uart->data_bits + uart->stop_bits + !!uart->parity;
  137.23          uart->timeout_ms = max_t(
  137.24              unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
  137.25 -        init_ac_timer(&uart->timer, ns16550_poll, port, 0);
  137.26 -        set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
  137.27 +        init_timer(&uart->timer, ns16550_poll, port, 0);
  137.28 +        set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
  137.29      }
  137.30      else
  137.31      {
   138.1 --- a/xen/include/asm-ia64/config.h	Tue Jan 10 15:21:00 2006 +0000
   138.2 +++ b/xen/include/asm-ia64/config.h	Tue Jan 24 17:54:34 2006 +0100
   138.3 @@ -92,7 +92,7 @@ extern char _end[]; /* standard ELF symb
   138.4  //#define __acquire(x) (void)0
   138.5  //#define __release(x) (void)0
   138.6  //#define __cond_lock(x) (x)
   138.7 -#define __must_check
   138.8 +//#define __must_check
   138.9  #define __deprecated
  138.10  #ifndef RELOC_HIDE
  138.11  # define RELOC_HIDE(ptr, off)					\
  138.12 @@ -121,7 +121,7 @@ extern char _end[]; /* standard ELF symb
  138.13  
  138.14  // from include/asm-ia64/smp.h
  138.15  #ifdef CONFIG_SMP
  138.16 -#warning "Lots of things to fix to enable CONFIG_SMP!"
  138.17 +//#warning "Lots of things to fix to enable CONFIG_SMP!"
  138.18  #endif
  138.19  #define	get_cpu()	smp_processor_id()
  138.20  #define put_cpu()	do {} while(0)
  138.21 @@ -141,10 +141,6 @@ struct page;
  138.22  #undef alloc_task_struct
  138.23  #define get_thread_info(v) alloc_thread_info(v)
  138.24  
  138.25 -// initial task has a different name in Xen
  138.26 -//#define	idle0_task	init_task
  138.27 -#define	idle0_vcpu	init_task
  138.28 -
  138.29  // avoid redefining task_t in asm/thread_info.h
  138.30  #define task_t	struct domain
  138.31  
  138.32 @@ -160,7 +156,7 @@ struct page;
  138.33  #define platform_outl	__ia64_outl
  138.34  
  138.35  // FIXME: This just overrides a use in a typedef (not allowed in ia64,
  138.36 -//  or maybe just in older gcc's?) used in ac_timer.c but should be OK
  138.37 +//  or maybe just in older gcc's?) used in timer.c but should be OK
  138.38  //  (and indeed is probably required!) elsewhere
  138.39  #undef __cacheline_aligned
  138.40  #undef ____cacheline_aligned
  138.41 @@ -187,7 +183,9 @@ void sort_extable(struct exception_table
  138.42  		  struct exception_table_entry *finish);
  138.43  void sort_main_extable(void);
  138.44  
  138.45 +#if 0 /* Already defined in xen/lib.h */
  138.46  #define printk printf
  138.47 +#endif
  138.48  
  138.49  #undef  __ARCH_IRQ_STAT
  138.50  
  138.51 @@ -205,7 +203,6 @@ void sort_main_extable(void);
  138.52  #define	OPT_CONSOLE_STR "com2"
  138.53  #endif
  138.54  
  138.55 -#define __attribute_used__	__attribute__ ((unused))
  138.56  #define __nocast
  138.57  
  138.58  // see include/asm-x86/atomic.h (different from standard linux)
  138.59 @@ -255,9 +252,6 @@ struct screen_info { };
  138.60  #define seq_printf(a,b...) printf(b)
  138.61  #define CONFIG_BLK_DEV_INITRD // needed to reserve memory for domain0
  138.62  
  138.63 -// needed for newer ACPI code
  138.64 -#define asmlinkage
  138.65 -
  138.66  #define FORCE_CRASH()	asm("break 0;;");
  138.67  
  138.68  void dummy_called(char *function);
  138.69 @@ -306,13 +300,8 @@ extern int ht_per_core;
  138.70  #endif
  138.71  
  138.72  
  138.73 -// FOLLOWING ADDED FOR XEN POST-NGIO and/or LINUX 2.6.7
  138.74 +#ifndef __ASSEMBLY__
  138.75 +#include <linux/linkage.h>
  138.76 +#endif
  138.77  
  138.78 -// following derived from linux/include/linux/compiler-gcc3.h
  138.79 -// problem because xen (over?)simplifies include/xen/compiler.h
  138.80 -#if __GNUC_MAJOR < 3 || __GNUC_MINOR__ >= 3
  138.81 -# define __attribute_used__	__attribute__((__used__))
  138.82 -#else
  138.83 -# define __attribute_used__	__attribute__((__unused__))
  138.84 -#endif
  138.85  #endif	/* _IA64_CONFIG_H_ */
   139.1 --- a/xen/include/asm-ia64/debugger.h	Tue Jan 10 15:21:00 2006 +0000
   139.2 +++ b/xen/include/asm-ia64/debugger.h	Tue Jan 24 17:54:34 2006 +0100
   139.3 @@ -24,6 +24,54 @@
   139.4  
   139.5  #include <xen/softirq.h>
   139.6  
   139.7 +// this number is an arbitary number which is not used for any other purpose
   139.8 +// __builtin_trap(), FORCE_CRASH() 0x0
   139.9 +// ski  0x80001, 0x80002
  139.10 +// kdb  0x80100, 0x80101
  139.11 +// kprobe 0x80200, jprobe 0x80300
  139.12 +// kgdb 0x6665
  139.13 +// gdb 0x99998 (#define IA64_BREAKPOINT 0x00003333300LL)
  139.14 +
  139.15 +// cdb should handle 0 and CDB_BREAK_NUM.
  139.16 +#define CDB_BREAK_NUM	0x80800
  139.17 +
  139.18 +
  139.19 +#ifndef __ASSEMBLY__
  139.20 +
  139.21 +#include <xen/gdbstub.h>
  139.22 +
  139.23 +// NOTE: on xen struct pt_regs = struct cpu_user_regs
  139.24 +//       see include/asm-ia64/linux-xen/asm/ptrace.h
  139.25 +#ifdef CRASH_DEBUG
  139.26 +// crash_debug=y
  139.27 +
  139.28 +/* The main trap handlers use these helper macros which include early bail. */
  139.29 +static inline int debugger_trap_entry(
  139.30 +    unsigned int vector, struct cpu_user_regs *regs)
  139.31 +{
  139.32 +    return 0;
  139.33 +}
  139.34 +
  139.35 +extern int __trap_to_cdb(struct cpu_user_regs *r);
  139.36 +static inline int debugger_trap_fatal(
  139.37 +    unsigned int vector, struct cpu_user_regs *regs)
  139.38 +{
  139.39 +	(void)__trap_to_gdb(regs, vector);
  139.40 +    return 0;
  139.41 +}
  139.42 +
  139.43 +#define ____debugger_trap_immediate(b) __asm__ __volatile__ ("break.m "#b"\n")
  139.44 +#define __debugger_trap_immediate(b) ____debugger_trap_immediate(b)
  139.45 +#define debugger_trap_immediate() __debugger_trap_immediate(CDB_BREAK_NUM)
  139.46 +
  139.47 +//XXX temporal work around
  139.48 +#ifndef CONFIG_SMP
  139.49 +#define smp_send_stop()	/* nothing */
  139.50 +#endif
  139.51 +
  139.52 +#elif defined DOMU_DEBUG
  139.53 +// domu_debug=y
  139.54 +#warning "domu_debug is not implemented yet."
  139.55  /* The main trap handlers use these helper macros which include early bail. */
  139.56  static inline int debugger_trap_entry(
  139.57      unsigned int vector, struct cpu_user_regs *regs)
  139.58 @@ -37,6 +85,23 @@ static inline int debugger_trap_fatal(
  139.59      return 0;
  139.60  }
  139.61  
  139.62 -#define debugger_trap_immediate() do {} while(0)
  139.63 +#define debugger_trap_immediate()		((void)0)
  139.64 +#else
  139.65 +/* The main trap handlers use these helper macros which include early bail. */
  139.66 +static inline int debugger_trap_entry(
  139.67 +    unsigned int vector, struct cpu_user_regs *regs)
  139.68 +{
  139.69 +    return 0;
  139.70 +}
  139.71 +
  139.72 +static inline int debugger_trap_fatal(
  139.73 +    unsigned int vector, struct cpu_user_regs *regs)
  139.74 +{
  139.75 +    return 0;
  139.76 +}
  139.77 +
  139.78 +#define debugger_trap_immediate()		((void)0)
  139.79 +#endif
  139.80 +#endif // __ASSEMBLLY__
  139.81  
  139.82  #endif /* __ASM_DEBUGGER_H__ */
   140.1 --- a/xen/include/asm-ia64/domain.h	Tue Jan 10 15:21:00 2006 +0000
   140.2 +++ b/xen/include/asm-ia64/domain.h	Tue Jan 24 17:54:34 2006 +0100
   140.3 @@ -10,8 +10,6 @@
   140.4  #include <asm/vmx_platform.h>
   140.5  #include <xen/list.h>
   140.6  
   140.7 -extern int arch_do_createdomain(struct vcpu *);
   140.8 -
   140.9  extern void domain_relinquish_resources(struct domain *);
  140.10  
  140.11  struct arch_domain {
   141.1 --- a/xen/include/asm-ia64/linux-xen/asm/ptrace.h	Tue Jan 10 15:21:00 2006 +0000
   141.2 +++ b/xen/include/asm-ia64/linux-xen/asm/ptrace.h	Tue Jan 24 17:54:34 2006 +0100
   141.3 @@ -110,6 +110,7 @@ vcpu_regs (struct vcpu *v)
   141.4    return (struct cpu_user_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
   141.5  }
   141.6  
   141.7 +struct pt_regs *guest_cpu_user_regs(void);
   141.8  
   141.9  #else
  141.10  struct pt_regs {
   142.1 --- a/xen/include/asm-ia64/linux-xen/linux/interrupt.h	Tue Jan 10 15:21:00 2006 +0000
   142.2 +++ b/xen/include/asm-ia64/linux-xen/linux/interrupt.h	Tue Jan 24 17:54:34 2006 +0100
   142.3 @@ -104,6 +104,7 @@ extern void local_bh_enable(void);
   142.4     al. should be converted to tasklets, not to softirqs.
   142.5   */
   142.6  
   142.7 +#ifndef XEN
   142.8  enum
   142.9  {
  142.10  	HI_SOFTIRQ=0,
  142.11 @@ -113,6 +114,7 @@ enum
  142.12  	SCSI_SOFTIRQ,
  142.13  	TASKLET_SOFTIRQ
  142.14  };
  142.15 +#endif
  142.16  
  142.17  /* softirq mask and active fields moved to irq_cpustat_t in
  142.18   * asm/hardirq.h to get better cache usage.  KAO
   143.1 --- a/xen/include/asm-ia64/mm.h	Tue Jan 10 15:21:00 2006 +0000
   143.2 +++ b/xen/include/asm-ia64/mm.h	Tue Jan 24 17:54:34 2006 +0100
   143.3 @@ -67,10 +67,12 @@ struct page
   143.4          } free;
   143.5  
   143.6      } u;
   143.7 +#if 0
   143.8  // following added for Linux compiling
   143.9      page_flags_t flags;
  143.10      atomic_t _count;
  143.11      struct list_head lru;	// is this the same as above "list"?
  143.12 +#endif
  143.13  };
  143.14  
  143.15  #define set_page_count(p,v) 	atomic_set(&(p)->_count, v - 1)
   144.1 --- a/xen/include/asm-ia64/vmmu.h	Tue Jan 10 15:21:00 2006 +0000
   144.2 +++ b/xen/include/asm-ia64/vmmu.h	Tue Jan 24 17:54:34 2006 +0100
   144.3 @@ -151,8 +151,8 @@ typedef union thash_cch_mem {
   144.4  typedef u64 *(THASH_FN)(PTA pta, u64 va);
   144.5  typedef u64 *(TTAG_FN)(PTA pta, u64 va);
   144.6  typedef u64 *(GET_MFN_FN)(domid_t d, u64 gpfn, u64 pages);
   144.7 -typedef void *(REM_NOTIFIER_FN)(struct hash_cb *hcb, thash_data_t *entry);
   144.8 -typedef void (RECYCLE_FN)(struct hash_cb *hc, u64 para);
   144.9 +typedef void *(REM_NOTIFIER_FN)(struct thash_cb *hcb, thash_data_t *entry);
  144.10 +typedef void (RECYCLE_FN)(struct thash_cb *hc, u64 para);
  144.11  typedef ia64_rr (GET_RR_FN)(struct vcpu *vcpu, u64 reg);
  144.12  typedef thash_data_t *(FIND_OVERLAP_FN)(struct thash_cb *hcb, 
  144.13          u64 va, u64 ps, int rid, char cl, search_section_t s_sect);
   145.1 --- a/xen/include/asm-ia64/vtm.h	Tue Jan 10 15:21:00 2006 +0000
   145.2 +++ b/xen/include/asm-ia64/vtm.h	Tue Jan 24 17:54:34 2006 +0100
   145.3 @@ -23,7 +23,7 @@
   145.4  #ifndef _VTM_H_
   145.5  #define _VTM_H_
   145.6  
   145.7 -#include <xen/ac_timer.h>
   145.8 +#include <xen/timer.h>
   145.9  #include <xen/types.h>
  145.10  
  145.11  #define MAX_JUMP_STEP       (5000)   /* 500ms, max jump step */
  145.12 @@ -46,7 +46,7 @@ typedef struct vtime {
  145.13      	uint64_t    cfg_max_jump;   // max jump within one time suspendsion
  145.14      	uint64_t    cfg_min_grun;   // min guest running time since last jump
  145.15  //    	uint64_t    latest_read_itc;    // latest guest read ITC
  145.16 -    	struct ac_timer	vtm_timer;
  145.17 +    	struct timer	vtm_timer;
  145.18  //	int        triggered;
  145.19      	
  145.20  
   146.1 --- a/xen/include/asm-x86/debugger.h	Tue Jan 10 15:21:00 2006 +0000
   146.2 +++ b/xen/include/asm-x86/debugger.h	Tue Jan 24 17:54:34 2006 +0100
   146.3 @@ -42,19 +42,19 @@
   146.4  
   146.5  #if defined(CRASH_DEBUG)
   146.6  
   146.7 -extern int __trap_to_cdb(struct cpu_user_regs *r);
   146.8 +#include <xen/gdbstub.h>
   146.9  
  146.10  #define __debugger_trap_entry(_v, _r) (0)
  146.11  
  146.12  static inline int __debugger_trap_fatal(
  146.13      unsigned int vector, struct cpu_user_regs *regs)
  146.14  {
  146.15 -    (void)__trap_to_cdb(regs);
  146.16 +    (void)__trap_to_gdb(regs, vector);
  146.17      return (vector == TRAP_int3); /* int3 is harmless */
  146.18  }
  146.19  
  146.20  /* Int3 is a trivial way to gather cpu_user_regs context. */
  146.21 -#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
  146.22 +#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
  146.23  
  146.24  #elif 0
  146.25  
  146.26 @@ -73,7 +73,7 @@ static inline int __debugger_trap_fatal(
  146.27  }
  146.28  
  146.29  /* Int3 is a trivial way to gather cpu_user_regs context. */
  146.30 -#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
  146.31 +#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
  146.32  
  146.33  #else
  146.34  
  146.35 @@ -100,6 +100,8 @@ static inline int debugger_trap_entry(
  146.36  }
  146.37  
  146.38  #define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
  146.39 +#ifndef debugger_trap_immediate
  146.40  #define debugger_trap_immediate() (__debugger_trap_immediate())
  146.41 +#endif
  146.42  
  146.43  #endif /* __X86_DEBUGGER_H__ */
   147.1 --- a/xen/include/asm-x86/domain.h	Tue Jan 10 15:21:00 2006 +0000
   147.2 +++ b/xen/include/asm-x86/domain.h	Tue Jan 24 17:54:34 2006 +0100
   147.3 @@ -13,13 +13,44 @@ struct trap_bounce {
   147.4      unsigned long  eip;
   147.5  };
   147.6  
   147.7 +#define MAPHASH_ENTRIES 8
   147.8 +#define MAPHASH_HASHFN(pfn) ((pfn) & (MAPHASH_ENTRIES-1))
   147.9 +#define MAPHASHENT_NOTINUSE ((u16)~0U)
  147.10 +struct vcpu_maphash {
  147.11 +    struct vcpu_maphash_entry {
  147.12 +        unsigned long pfn;
  147.13 +        uint16_t      idx;
  147.14 +        uint16_t      refcnt;
  147.15 +    } hash[MAPHASH_ENTRIES];
  147.16 +} __cacheline_aligned;
  147.17 +
  147.18 +#define MAPCACHE_ORDER   10
  147.19 +#define MAPCACHE_ENTRIES (1 << MAPCACHE_ORDER)
  147.20  struct mapcache {
  147.21 +    /* The PTEs that provide the mappings, and a cursor into the array. */
  147.22      l1_pgentry_t *l1tab;
  147.23      unsigned int cursor;
  147.24 -    unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS];
  147.25 +
  147.26 +    /* Protects map_domain_page(). */
  147.27      spinlock_t lock;
  147.28 +
  147.29 +    /* Garbage mappings are flushed from TLBs in batches called 'epochs'. */
  147.30 +    unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS];
  147.31 +    u32 tlbflush_timestamp;
  147.32 +
  147.33 +    /* Which mappings are in use, and which are garbage to reap next epoch? */
  147.34 +    unsigned long inuse[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
  147.35 +    unsigned long garbage[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
  147.36 +
  147.37 +    /* Lock-free per-VCPU hash of recently-used mappings. */
  147.38 +    struct vcpu_maphash vcpu_maphash[MAX_VIRT_CPUS];
  147.39  };
  147.40  
  147.41 +extern void mapcache_init(struct domain *);
  147.42 +
  147.43 +/* x86/64: toggle guest between kernel and user modes. */
  147.44 +extern void toggle_guest_mode(struct vcpu *);
  147.45 +
  147.46  struct arch_domain
  147.47  {
  147.48      l1_pgentry_t *mm_perdomain_pt;
   148.1 --- a/xen/include/asm-x86/mm.h	Tue Jan 10 15:21:00 2006 +0000
   148.2 +++ b/xen/include/asm-x86/mm.h	Tue Jan 24 17:54:34 2006 +0100
   148.3 @@ -309,16 +309,13 @@ struct ptwr_info {
   148.4      unsigned long l1va;
   148.5      /* Copy of the p.t. page, taken before guest is given write access. */
   148.6      l1_pgentry_t *page;
   148.7 -    /* A temporary Xen mapping of the actual p.t. page. */
   148.8 -    l1_pgentry_t *pl1e;
   148.9      /* Index in L2 page table where this L1 p.t. is always hooked. */
  148.10      unsigned int l2_idx; /* NB. Only used for PTWR_PT_ACTIVE. */
  148.11      /* Info about last ptwr update batch. */
  148.12      unsigned int prev_nr_updates;
  148.13 -    /* Exec domain which created writable mapping. */
  148.14 +    /* VCPU which created writable mapping. */
  148.15      struct vcpu *vcpu;
  148.16 -    /* EIP of the address which took the original write fault
  148.17 -       used for stats collection only */
  148.18 +    /* EIP of the original write fault (stats collection only). */
  148.19      unsigned long eip;
  148.20  };
  148.21  
   149.1 --- a/xen/include/asm-x86/nmi.h	Tue Jan 10 15:21:00 2006 +0000
   149.2 +++ b/xen/include/asm-x86/nmi.h	Tue Jan 24 17:54:34 2006 +0100
   149.3 @@ -2,6 +2,8 @@
   149.4  #ifndef ASM_NMI_H
   149.5  #define ASM_NMI_H
   149.6  
   149.7 +#include <public/nmi.h>
   149.8 +
   149.9  struct cpu_user_regs;
  149.10   
  149.11  typedef int (*nmi_callback_t)(struct cpu_user_regs *regs, int cpu);
   150.1 --- a/xen/include/asm-x86/processor.h	Tue Jan 10 15:21:00 2006 +0000
   150.2 +++ b/xen/include/asm-x86/processor.h	Tue Jan 24 17:54:34 2006 +0100
   150.3 @@ -123,6 +123,7 @@
   150.4  #define TBF_EXCEPTION_ERRCODE  2
   150.5  #define TBF_INTERRUPT          8
   150.6  #define TBF_FAILSAFE          16
   150.7 +#define TBF_SLOW_IRET         32
   150.8  
   150.9  /* 'arch_vcpu' flags values */
  150.10  #define _TF_kernel_mode        0
   151.1 --- a/xen/include/asm-x86/vmx_vlapic.h	Tue Jan 10 15:21:00 2006 +0000
   151.2 +++ b/xen/include/asm-x86/vmx_vlapic.h	Tue Jan 24 17:54:34 2006 +0100
   151.3 @@ -187,7 +187,7 @@ struct vlapic
   151.4      uint32_t           timer_current;
   151.5      uint32_t           timer_divconf;
   151.6      uint32_t           timer_divide_counter;
   151.7 -    struct ac_timer    vlapic_timer;
   151.8 +    struct timer    vlapic_timer;
   151.9      int                intr_pending_count[MAX_VECTOR];
  151.10      s_time_t           timer_current_update;
  151.11      uint32_t           icr_high;
  151.12 @@ -216,7 +216,7 @@ static inline int vlapic_set_irq(struct 
  151.13  
  151.14  static inline int  vlapic_timer_active(struct vlapic *vlapic)
  151.15  {
  151.16 -    return  active_ac_timer(&(vlapic->vlapic_timer));
  151.17 +    return  active_timer(&(vlapic->vlapic_timer));
  151.18  }
  151.19  
  151.20  int vlapic_find_highest_irr(struct vlapic *vlapic);
   152.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Tue Jan 10 15:21:00 2006 +0000
   152.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Tue Jan 24 17:54:34 2006 +0100
   152.3 @@ -100,7 +100,7 @@ struct arch_vmx_struct {
   152.4      void                    *io_bitmap_a, *io_bitmap_b;
   152.5      struct vlapic           *vlapic;
   152.6      u64                     tsc_offset;
   152.7 -    struct ac_timer         hlt_timer;  /* hlt ins emulation wakeup timer */
   152.8 +    struct timer         hlt_timer;  /* hlt ins emulation wakeup timer */
   152.9  };
  152.10  
  152.11  #define vmx_schedule_tail(next)         \
   153.1 --- a/xen/include/asm-x86/vmx_vpit.h	Tue Jan 10 15:21:00 2006 +0000
   153.2 +++ b/xen/include/asm-x86/vmx_vpit.h	Tue Jan 24 17:54:34 2006 +0100
   153.3 @@ -6,7 +6,7 @@
   153.4  #include <xen/lib.h>
   153.5  #include <xen/time.h>
   153.6  #include <xen/errno.h>
   153.7 -#include <xen/ac_timer.h>
   153.8 +#include <xen/timer.h>
   153.9  #include <asm/vmx_vmcs.h>
  153.10  #include <asm/vmx_vpic.h>
  153.11  
  153.12 @@ -23,7 +23,7 @@ struct vmx_virpit {
  153.13      u64 inject_point; /* the time inject virt intr */
  153.14      u64 shift;  /* save the value of offset - drift */
  153.15      s_time_t scheduled;                 /* scheduled timer interrupt */
  153.16 -    struct ac_timer pit_timer;  /* periodic timer for mode 2*/
  153.17 +    struct timer pit_timer;  /* periodic timer for mode 2*/
  153.18      unsigned int channel;  /* the pit channel, counter 0~2 */
  153.19      unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
  153.20      u32 period;		/* pit frequency in ns */
   154.1 --- a/xen/include/public/arch-ia64.h	Tue Jan 10 15:21:00 2006 +0000
   154.2 +++ b/xen/include/public/arch-ia64.h	Tue Jan 24 17:54:34 2006 +0100
   154.3 @@ -9,7 +9,7 @@
   154.4  
   154.5  /* Maximum number of virtual CPUs in multi-processor guests. */
   154.6  /* WARNING: before changing this, check that shared_info fits on a page */
   154.7 -#define MAX_VIRT_CPUS 1
   154.8 +#define MAX_VIRT_CPUS 4
   154.9  
  154.10  #ifndef __ASSEMBLY__
  154.11  
   155.1 --- a/xen/include/public/arch-x86_32.h	Tue Jan 10 15:21:00 2006 +0000
   155.2 +++ b/xen/include/public/arch-x86_32.h	Tue Jan 24 17:54:34 2006 +0100
   155.3 @@ -135,6 +135,7 @@ typedef struct arch_shared_info {
   155.4      unsigned long max_pfn;                  /* max pfn that appears in table */
   155.5      /* Frame containing list of mfns containing list of mfns containing p2m. */
   155.6      unsigned long pfn_to_mfn_frame_list_list; 
   155.7 +    unsigned long nmi_reason;
   155.8  } arch_shared_info_t;
   155.9  
  155.10  typedef struct {
   156.1 --- a/xen/include/public/arch-x86_64.h	Tue Jan 10 15:21:00 2006 +0000
   156.2 +++ b/xen/include/public/arch-x86_64.h	Tue Jan 24 17:54:34 2006 +0100
   156.3 @@ -88,11 +88,20 @@
   156.4  #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
   156.5  
   156.6  /*
   156.7 - * int HYPERVISOR_switch_to_user(void)
   156.8 + * int HYPERVISOR_iret(void)
   156.9   * All arguments are on the kernel stack, in the following format.
  156.10   * Never returns if successful. Current kernel context is lost.
  156.11 + * The saved CS is mapped as follows:
  156.12 + *   RING0 -> RING3 kernel mode.
  156.13 + *   RING1 -> RING3 kernel mode.
  156.14 + *   RING2 -> RING3 kernel mode.
  156.15 + *   RING3 -> RING3 user mode.
  156.16 + * However RING0 indicates that the guest kernel should return to iteself
  156.17 + * directly with
  156.18 + *      orb   $3,1*8(%rsp)
  156.19 + *      iretq
  156.20   * If flags contains VGCF_IN_SYSCALL:
  156.21 - *   Restore RAX, RIP, RFLAGS, RSP. 
  156.22 + *   Restore RAX, RIP, RFLAGS, RSP.
  156.23   *   Discard R11, RCX, CS, SS.
  156.24   * Otherwise:
  156.25   *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
  156.26 @@ -100,10 +109,19 @@
  156.27   */
  156.28  /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
  156.29  #define VGCF_IN_SYSCALL (1<<8)
  156.30 +struct iret_context {
  156.31 +    /* Top of stack (%rsp at point of hypercall). */
  156.32 +    uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
  156.33 +    /* Bottom of iret stack frame. */
  156.34 +};
  156.35 +/*
  156.36 + * For compatibility with HYPERVISOR_switch_to_user which is the old
  156.37 + * name for HYPERVISOR_iret.
  156.38 + */
  156.39  struct switch_to_user {
  156.40      /* Top of stack (%rsp at point of hypercall). */
  156.41      uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
  156.42 -    /* Bottom of switch_to_user stack frame. */
  156.43 +    /* Bottom of iret stack frame. */
  156.44  };
  156.45  
  156.46  /*
  156.47 @@ -202,6 +220,7 @@ typedef struct arch_shared_info {
  156.48      unsigned long max_pfn;                  /* max pfn that appears in table */
  156.49      /* Frame containing list of mfns containing list of mfns containing p2m. */
  156.50      unsigned long pfn_to_mfn_frame_list_list; 
  156.51 +    unsigned long nmi_reason;
  156.52  } arch_shared_info_t;
  156.53  
  156.54  typedef struct {
   157.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.2 +++ b/xen/include/public/nmi.h	Tue Jan 24 17:54:34 2006 +0100
   157.3 @@ -0,0 +1,54 @@
   157.4 +/******************************************************************************
   157.5 + * nmi.h
   157.6 + * 
   157.7 + * NMI callback registration and reason codes.
   157.8 + * 
   157.9 + * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
  157.10 + */
  157.11 +
  157.12 +#ifndef __XEN_PUBLIC_NMI_H__
  157.13 +#define __XEN_PUBLIC_NMI_H__
  157.14 +
  157.15 +/*
  157.16 + * NMI reason codes:
  157.17 + * Currently these are x86-specific, stored in arch_shared_info.nmi_reason.
  157.18 + */
  157.19 + /* I/O-check error reported via ISA port 0x61, bit 6. */
  157.20 +#define _XEN_NMIREASON_io_error     0
  157.21 +#define XEN_NMIREASON_io_error      (1UL << _XEN_NMIREASON_io_error)
  157.22 + /* Parity error reported via ISA port 0x61, bit 7. */
  157.23 +#define _XEN_NMIREASON_parity_error 1
  157.24 +#define XEN_NMIREASON_parity_error  (1UL << _XEN_NMIREASON_parity_error)
  157.25 + /* Unknown hardware-generated NMI. */
  157.26 +#define _XEN_NMIREASON_unknown      2
  157.27 +#define XEN_NMIREASON_unknown       (1UL << _XEN_NMIREASON_unknown)
  157.28 +
  157.29 +/*
  157.30 + * long nmi_op(unsigned int cmd, void *arg)
  157.31 + * NB. All ops return zero on success, else a negative error code.
  157.32 + */
  157.33 +
  157.34 +/*
  157.35 + * Register NMI callback for this (calling) VCPU. Currently this only makes
  157.36 + * sense for domain 0, vcpu 0. All other callers will be returned EINVAL.
  157.37 + * arg == address of callback function.
  157.38 + */
  157.39 +#define XENNMI_register_callback   0
  157.40 +
  157.41 +/*
  157.42 + * Deregister NMI callback for this (calling) VCPU.
  157.43 + * arg == NULL.
  157.44 + */
  157.45 +#define XENNMI_unregister_callback 1
  157.46 +
  157.47 +#endif /* __XEN_PUBLIC_NMI_H__ */
  157.48 +
  157.49 +/*
  157.50 + * Local variables:
  157.51 + * mode: C
  157.52 + * c-set-style: "BSD"
  157.53 + * c-basic-offset: 4
  157.54 + * tab-width: 4
  157.55 + * indent-tabs-mode: nil
  157.56 + * End:
  157.57 + */
   158.1 --- a/xen/include/public/xen.h	Tue Jan 10 15:21:00 2006 +0000
   158.2 +++ b/xen/include/public/xen.h	Tue Jan 24 17:54:34 2006 +0100
   158.3 @@ -53,12 +53,14 @@
   158.4  #define __HYPERVISOR_grant_table_op       20
   158.5  #define __HYPERVISOR_vm_assist            21
   158.6  #define __HYPERVISOR_update_va_mapping_otherdomain 22
   158.7 -#define __HYPERVISOR_switch_vm86          23 /* x86/32 only */
   158.8 -#define __HYPERVISOR_switch_to_user       23 /* x86/64 only */
   158.9 +#define __HYPERVISOR_iret                 23 /* x86 only */
  158.10 +#define __HYPERVISOR_switch_vm86          23 /* x86/32 only (obsolete name) */
  158.11 +#define __HYPERVISOR_switch_to_user       23 /* x86/64 only (obsolete name) */
  158.12  #define __HYPERVISOR_vcpu_op              24
  158.13  #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
  158.14  #define __HYPERVISOR_mmuext_op            26
  158.15  #define __HYPERVISOR_acm_op               27
  158.16 +#define __HYPERVISOR_nmi_op               28
  158.17  
  158.18  /* 
  158.19   * VIRTUAL INTERRUPTS
  158.20 @@ -69,10 +71,7 @@
  158.21  #define VIRQ_DEBUG      1  /* Request guest to dump debug info.           */
  158.22  #define VIRQ_CONSOLE    2  /* (DOM0) Bytes received on emergency console. */
  158.23  #define VIRQ_DOM_EXC    3  /* (DOM0) Exceptional event for some domain.   */
  158.24 -#define VIRQ_PARITY_ERR 4  /* (DOM0) NMI parity error (port 0x61, bit 7). */
  158.25 -#define VIRQ_IO_ERR     5  /* (DOM0) NMI I/O error    (port 0x61, bit 6). */
  158.26  #define VIRQ_DEBUGGER   6  /* (DOM0) A domain has paused for debugging.   */
  158.27 -#define VIRQ_NMI        7  /* (DOM0) Unknown NMI (not from ISA port 0x61).*/
  158.28  #define NR_VIRQS        8
  158.29  
  158.30  /*
   159.1 --- a/xen/include/xen/ac_timer.h	Tue Jan 10 15:21:00 2006 +0000
   159.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   159.3 @@ -1,81 +0,0 @@
   159.4 -/******************************************************************************
   159.5 - * ac_timer.h
   159.6 - * 
   159.7 - * Copyright (c) 2002-2003 Rolf Neugebauer
   159.8 - * Copyright (c) 2002-2005 K A Fraser
   159.9 - */
  159.10 -
  159.11 -#ifndef _AC_TIMER_H_
  159.12 -#define _AC_TIMER_H_
  159.13 -
  159.14 -#include <xen/spinlock.h>
  159.15 -#include <xen/time.h>
  159.16 -#include <xen/string.h>
  159.17 -
  159.18 -struct ac_timer {
  159.19 -    /* System time expiry value (nanoseconds since boot). */
  159.20 -    s_time_t      expires;
  159.21 -    /* CPU on which this timer will be installed and executed. */
  159.22 -    unsigned int  cpu;
  159.23 -    /* On expiry, '(*function)(data)' will be executed in softirq context. */
  159.24 -    void        (*function)(void *);
  159.25 -    void         *data;
  159.26 -    /* Timer-heap offset. */
  159.27 -    unsigned int  heap_offset;
  159.28 -};
  159.29 -
  159.30 -/*
  159.31 - * All functions below can be called for any CPU from any CPU in any context.
  159.32 - */
  159.33 -
  159.34 -/* Returns TRUE if the given timer is on a timer list. */
  159.35 -static __inline__ int active_ac_timer(struct ac_timer *timer)
  159.36 -{
  159.37 -    return (timer->heap_offset != 0);
  159.38 -}
  159.39 -
  159.40 -/*
  159.41 - * It initialises the static fields of the ac_timer structure.
  159.42 - * It can be called multiple times to reinitialise a single (inactive) timer.
  159.43 - */
  159.44 -static __inline__ void init_ac_timer(
  159.45 -    struct ac_timer *timer,
  159.46 -    void           (*function)(void *),
  159.47 -    void            *data,
  159.48 -    unsigned int     cpu)
  159.49 -{
  159.50 -    memset(timer, 0, sizeof(*timer));
  159.51 -    timer->function = function;
  159.52 -    timer->data     = data;
  159.53 -    timer->cpu      = cpu;
  159.54 -}
  159.55 -
  159.56 -/*
  159.57 - * Set the expiry time and activate a timer (which must previously have been
  159.58 - * initialised by init_ac_timer).
  159.59 - */
  159.60 -extern void set_ac_timer(struct ac_timer *timer, s_time_t expires);
  159.61 -
  159.62 -/*
  159.63 - * Deactivate a timer (which must previously have been initialised by
  159.64 - * init_ac_timer). This function has no effect if the timer is not currently
  159.65 - * active.
  159.66 - */
  159.67 -extern void rem_ac_timer(struct ac_timer *timer);
  159.68 -
  159.69 -/*
  159.70 - * Initialisation. Must be called before any other ac_timer function.
  159.71 - */
  159.72 -extern void ac_timer_init(void);
  159.73 -
  159.74 -#endif /* _AC_TIMER_H_ */
  159.75 -
  159.76 -/*
  159.77 - * Local variables:
  159.78 - * mode: C
  159.79 - * c-set-style: "BSD"
  159.80 - * c-basic-offset: 4
  159.81 - * tab-width: 4
  159.82 - * indent-tabs-mode: nil
  159.83 - * End:
  159.84 - */
   160.1 --- a/xen/include/xen/domain.h	Tue Jan 10 15:21:00 2006 +0000
   160.2 +++ b/xen/include/xen/domain.h	Tue Jan 24 17:54:34 2006 +0100
   160.3 @@ -13,13 +13,13 @@ struct vcpu *alloc_vcpu_struct(struct do
   160.4  
   160.5  extern void free_vcpu_struct(struct vcpu *v);
   160.6  
   160.7 -extern int arch_do_createdomain(struct vcpu *v);
   160.8 +extern int arch_domain_create(struct domain *d);
   160.9 +
  160.10 +extern void arch_domain_destroy(struct domain *d);
  160.11  
  160.12  extern int arch_set_info_guest(
  160.13      struct vcpu *v, struct vcpu_guest_context *c);
  160.14  
  160.15 -extern void free_perdomain_pt(struct domain *d);
  160.16 -
  160.17  extern void domain_relinquish_resources(struct domain *d);
  160.18  
  160.19  extern void dump_pageframe_info(struct domain *d);
   161.1 --- a/xen/include/xen/domain_page.h	Tue Jan 10 15:21:00 2006 +0000
   161.2 +++ b/xen/include/xen/domain_page.h	Tue Jan 24 17:54:34 2006 +0100
   161.3 @@ -2,6 +2,8 @@
   161.4   * domain_page.h
   161.5   * 
   161.6   * Allow temporary mapping of domain page frames into Xen space.
   161.7 + * 
   161.8 + * Copyright (c) 2003-2006, Keir Fraser <keir@xensource.com>
   161.9   */
  161.10  
  161.11  #ifndef __XEN_DOMAIN_PAGE_H__
  161.12 @@ -10,22 +12,27 @@
  161.13  #include <xen/config.h>
  161.14  #include <xen/mm.h>
  161.15  
  161.16 -#define map_domain_page(pfn)   map_domain_pages(pfn,0)
  161.17 -#define unmap_domain_page(va)  unmap_domain_pages(va,0)
  161.18 -
  161.19  #ifdef CONFIG_DOMAIN_PAGE
  161.20  
  161.21  /*
  161.22 - * Maps a given range of page frames, returning the mapped virtual address. The
  161.23 - * pages are now accessible until a corresponding call to unmap_domain_page().
  161.24 + * Map a given page frame, returning the mapped virtual address. The page is
  161.25 + * then accessible within the current VCPU until a corresponding unmap call.
  161.26   */
  161.27 -extern void *map_domain_pages(unsigned long pfn, unsigned int order);
  161.28 +extern void *map_domain_page(unsigned long pfn);
  161.29  
  161.30  /*
  161.31 - * Pass a VA within the first page of a range previously mapped with
  161.32 - * map_omain_pages(). Those pages will then be removed from the mapping lists.
  161.33 + * Pass a VA within a page previously mapped in the context of the
  161.34 + * currently-executing VCPU via a call to map_domain_pages().
  161.35   */
  161.36 -extern void unmap_domain_pages(void *va, unsigned int order);
  161.37 +extern void unmap_domain_page(void *va);
  161.38 +
  161.39 +/*
  161.40 + * Similar to the above calls, except the mapping is accessible in all
  161.41 + * address spaces (not just within the VCPU that created the mapping). Global
  161.42 + * mappings can also be unmapped from any context.
  161.43 + */
  161.44 +extern void *map_domain_page_global(unsigned long pfn);
  161.45 +extern void unmap_domain_page_global(void *va);
  161.46  
  161.47  #define DMCACHE_ENTRY_VALID 1U
  161.48  #define DMCACHE_ENTRY_HELD  2U
  161.49 @@ -87,8 +94,11 @@ domain_mmap_cache_destroy(struct domain_
  161.50  
  161.51  #else /* !CONFIG_DOMAIN_PAGE */
  161.52  
  161.53 -#define map_domain_pages(pfn,order)         phys_to_virt((pfn)<<PAGE_SHIFT)
  161.54 -#define unmap_domain_pages(va,order)        ((void)((void)(va),(void)(order)))
  161.55 +#define map_domain_page(pfn)                phys_to_virt((pfn)<<PAGE_SHIFT)
  161.56 +#define unmap_domain_page(va)               ((void)(va))
  161.57 +
  161.58 +#define map_domain_page_global(pfn)         phys_to_virt((pfn)<<PAGE_SHIFT)
  161.59 +#define unmap_domain_page_global(va)        ((void)(va))
  161.60  
  161.61  struct domain_mmap_cache { 
  161.62  };
   162.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   162.2 +++ b/xen/include/xen/gdbstub.h	Tue Jan 24 17:54:34 2006 +0100
   162.3 @@ -0,0 +1,96 @@
   162.4 +/*
   162.5 + * Copyright (C) 2005 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
   162.6 + * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
   162.7 + *                    VA Linux Systems Japan. K.K.
   162.8 + *
   162.9 + * This program is free software; you can redistribute it and/or modify
  162.10 + * it under the terms of the GNU General Public License as published by
  162.11 + * the Free Software Foundation; either version 2 of the License, or
  162.12 + * (at your option) any later version.
  162.13 + * 
  162.14 + * This program is distributed in the hope that it will be useful,
  162.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  162.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  162.17 + * GNU General Public License for more details.
  162.18 + * 
  162.19 + * You should have received a copy of the GNU General Public License
  162.20 + * along with this program; if not, write to the Free Software
  162.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  162.22 + */
  162.23 +
  162.24 +#ifndef __XEN_GDBSTUB_H__
  162.25 +#define __XEN_GDBSTUB_H__
  162.26 +
  162.27 +/* value <-> char (de)serialzers for arch specific gdb backends */
  162.28 +char hex2char(unsigned long x); 
  162.29 +int char2hex(unsigned char c); 
  162.30 +char str2hex(const char *str); 
  162.31 +unsigned long str2ulong(const char *str, unsigned long bytes); 
  162.32 +
  162.33 +struct gdb_context {
  162.34 +    int                 serhnd;
  162.35 +    int                 currently_attached:1;
  162.36 +    atomic_t            running;
  162.37 +    unsigned long       connected;
  162.38 +    u8                  signum;
  162.39 +
  162.40 +    char                in_buf[PAGE_SIZE];
  162.41 +    unsigned long       in_bytes;
  162.42 +
  162.43 +    char                out_buf[PAGE_SIZE];
  162.44 +    unsigned long       out_offset;
  162.45 +    u8                  out_csum;
  162.46 +};
  162.47 +
  162.48 +/* interface to arch specific routines */
  162.49 +void gdb_write_to_packet(
  162.50 +    const char *buf, int count, struct gdb_context *ctx);
  162.51 +void gdb_write_to_packet_hex(
  162.52 +    unsigned long x, int int_size, struct gdb_context *ctx);
  162.53 +void gdb_send_packet(struct gdb_context *ctx); 
  162.54 +void gdb_send_reply(const char *buf, struct gdb_context *ctx);
  162.55 +
  162.56 +/* gdb stub trap handler: entry point */
  162.57 +int __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie);
  162.58 +
  162.59 +/* arch specific routines */
  162.60 +u16 gdb_arch_signal_num(
  162.61 +    struct cpu_user_regs *regs, unsigned long cookie);
  162.62 +void gdb_arch_read_reg_array(
  162.63 +    struct cpu_user_regs *regs, struct gdb_context *ctx);
  162.64 +void gdb_arch_write_reg_array(
  162.65 +    struct cpu_user_regs *regs, const char* buf, struct gdb_context *ctx);
  162.66 +void gdb_arch_read_reg(
  162.67 +    unsigned long regnum, struct cpu_user_regs *regs, struct gdb_context *ctx);
  162.68 +unsigned int gdb_arch_copy_from_user(
  162.69 +    void *dest, const void *src, unsigned len);
  162.70 +unsigned int gdb_arch_copy_to_user(
  162.71 +    void *dest, const void *src, unsigned len);
  162.72 +void gdb_arch_resume(
  162.73 +    struct cpu_user_regs *regs, unsigned long addr,
  162.74 +    unsigned long type, struct gdb_context *ctx);
  162.75 +void gdb_arch_print_state(struct cpu_user_regs *regs);
  162.76 +void gdb_arch_enter(struct cpu_user_regs *regs);
  162.77 +void gdb_arch_exit(struct cpu_user_regs *regs);
  162.78 +
  162.79 +#define GDB_CONTINUE     0
  162.80 +#define GDB_STEP         1
  162.81 +
  162.82 +#define SIGILL           4
  162.83 +#define SIGTRAP          5
  162.84 +#define SIGBUS           7
  162.85 +#define SIGFPE           8
  162.86 +#define SIGSEGV         11
  162.87 +#define SIGALRM         14
  162.88 +#define SIGTERM         15
  162.89 +
  162.90 +#endif /* __XEN_GDBSTUB_H__ */
  162.91 +
  162.92 +/*
  162.93 + * Local variables:
  162.94 + * mode: C
  162.95 + * c-set-style: "BSD"
  162.96 + * c-basic-offset: 4
  162.97 + * tab-width: 4
  162.98 + * End:
  162.99 + */
   163.1 --- a/xen/include/xen/perfc_defn.h	Tue Jan 10 15:21:00 2006 +0000
   163.2 +++ b/xen/include/xen/perfc_defn.h	Tue Jan 24 17:54:34 2006 +0100
   163.3 @@ -32,7 +32,7 @@ PERFCOUNTER_CPU(ipis,                   
   163.4  PERFCOUNTER_CPU(irq_time,               "cycles spent in irq handler")
   163.5  
   163.6  PERFCOUNTER_CPU(apic_timer,             "apic timer interrupts")
   163.7 -PERFCOUNTER_CPU(ac_timer_max,           "ac_timer max error (ns)")
   163.8 +PERFCOUNTER_CPU(timer_max,           "timer max error (ns)")
   163.9  PERFCOUNTER_CPU(sched_irq,              "sched: timer")
  163.10  PERFCOUNTER_CPU(sched_run,              "sched: runs through scheduler")
  163.11  PERFCOUNTER_CPU(sched_ctx,              "sched: context switches")
   164.1 --- a/xen/include/xen/sched-if.h	Tue Jan 10 15:21:00 2006 +0000
   164.2 +++ b/xen/include/xen/sched-if.h	Tue Jan 24 17:54:34 2006 +0100
   164.3 @@ -16,16 +16,47 @@ struct schedule_data {
   164.4      struct vcpu        *curr;           /* current task                    */
   164.5      struct vcpu        *idle;           /* idle task for this cpu          */
   164.6      void               *sched_priv;
   164.7 -    struct ac_timer     s_timer;        /* scheduling timer                */
   164.8 +    struct timer        s_timer;        /* scheduling timer                */
   164.9      unsigned long       tick;           /* current periodic 'tick'         */
  164.10  #ifdef BUCKETS
  164.11      u32                 hist[BUCKETS];  /* for scheduler latency histogram */
  164.12  #endif
  164.13  } __cacheline_aligned;
  164.14  
  164.15 +extern struct schedule_data schedule_data[];
  164.16 +
  164.17 +static inline void vcpu_schedule_lock(struct vcpu *v)
  164.18 +{
  164.19 +    unsigned int cpu;
  164.20 +
  164.21 +    for ( ; ; )
  164.22 +    {
  164.23 +        cpu = v->processor;
  164.24 +        spin_lock(&schedule_data[cpu].schedule_lock);
  164.25 +        if ( likely(v->processor == cpu) )
  164.26 +            break;
  164.27 +        spin_unlock(&schedule_data[cpu].schedule_lock);
  164.28 +    }
  164.29 +}
  164.30 +
  164.31 +#define vcpu_schedule_lock_irq(v) \
  164.32 +    do { local_irq_disable(); vcpu_schedule_lock(v); } while ( 0 )
  164.33 +#define vcpu_schedule_lock_irqsave(v, flags) \
  164.34 +    do { local_irq_save(flags); vcpu_schedule_lock(v); } while ( 0 )
  164.35 +
  164.36 +static inline void vcpu_schedule_unlock(struct vcpu *v)
  164.37 +{
  164.38 +    spin_unlock(&schedule_data[v->processor].schedule_lock);
  164.39 +}
  164.40 +
  164.41 +#define vcpu_schedule_unlock_irq(v) \
  164.42 +    do { vcpu_schedule_unlock(v); local_irq_enable(); } while ( 0 )
  164.43 +#define vcpu_schedule_unlock_irqrestore(v, flags) \
  164.44 +    do { vcpu_schedule_unlock(v); local_irq_restore(flags); } while ( 0 )
  164.45 +
  164.46  struct task_slice {
  164.47      struct vcpu *task;
  164.48 -    s_time_t            time;
  164.49 +    s_time_t     time;
  164.50  };
  164.51  
  164.52  struct scheduler {
  164.53 @@ -48,6 +79,4 @@ struct scheduler {
  164.54      void         (*dump_cpu_state) (int);
  164.55  };
  164.56  
  164.57 -extern struct schedule_data schedule_data[];
  164.58 -
  164.59  #endif /* __XEN_SCHED_IF_H__ */
   165.1 --- a/xen/include/xen/sched.h	Tue Jan 10 15:21:00 2006 +0000
   165.2 +++ b/xen/include/xen/sched.h	Tue Jan 24 17:54:34 2006 +0100
   165.3 @@ -9,7 +9,7 @@
   165.4  #include <public/xen.h>
   165.5  #include <public/dom0_ops.h>
   165.6  #include <xen/time.h>
   165.7 -#include <xen/ac_timer.h>
   165.8 +#include <xen/timer.h>
   165.9  #include <xen/grant_table.h>
  165.10  #include <xen/rangeset.h>
  165.11  #include <asm/domain.h>
  165.12 @@ -63,7 +63,7 @@ struct vcpu
  165.13  
  165.14      struct vcpu     *next_in_list;
  165.15  
  165.16 -    struct ac_timer  timer;         /* one-shot timer for timeout values */
  165.17 +    struct timer  timer;         /* one-shot timer for timeout values */
  165.18      unsigned long    sleep_tick;    /* tick at which this vcpu started sleep */
  165.19  
  165.20      s_time_t         lastschd;      /* time this domain was last scheduled */
  165.21 @@ -81,6 +81,8 @@ struct vcpu
  165.22      /* Bitmask of CPUs on which this VCPU may run. */
  165.23      cpumask_t        cpu_affinity;
  165.24  
  165.25 +    unsigned long    nmi_addr;      /* NMI callback address. */
  165.26 +
  165.27      /* Bitmask of CPUs which are holding onto this VCPU's state. */
  165.28      cpumask_t        vcpu_dirty_cpumask;
  165.29  
  165.30 @@ -183,13 +185,13 @@ struct vcpu *alloc_vcpu(
  165.31  struct domain *alloc_domain(void);
  165.32  void free_domain(struct domain *d);
  165.33  
  165.34 -#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
  165.35 +#define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
  165.36  #define put_domain(_d) \
  165.37 -  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
  165.38 +  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
  165.39  
  165.40  /*
  165.41   * Use this when you don't have an existing reference to @d. It returns
  165.42 - * FALSE if @d is being destructed.
  165.43 + * FALSE if @d is being destroyed.
  165.44   */
  165.45  static always_inline int get_domain(struct domain *d)
  165.46  {
  165.47 @@ -197,7 +199,7 @@ static always_inline int get_domain(stru
  165.48      do
  165.49      {
  165.50          old = seen;
  165.51 -        if ( unlikely(_atomic_read(old) & DOMAIN_DESTRUCTED) )
  165.52 +        if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
  165.53              return 0;
  165.54          _atomic_set(new, _atomic_read(old) + 1);
  165.55          seen = atomic_compareandswap(old, new, &d->refcnt);
  165.56 @@ -208,15 +210,15 @@ static always_inline int get_domain(stru
  165.57  
  165.58  /*
  165.59   * Use this when you already have, or are borrowing, a reference to @d.
  165.60 - * In this case we know that @d cannot be destructed under our feet.
  165.61 + * In this case we know that @d cannot be destroyed under our feet.
  165.62   */
  165.63  static inline void get_knownalive_domain(struct domain *d)
  165.64  {
  165.65      atomic_inc(&d->refcnt);
  165.66 -    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
  165.67 +    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
  165.68  }
  165.69  
  165.70 -extern struct domain *do_createdomain(
  165.71 +extern struct domain *domain_create(
  165.72      domid_t dom_id, unsigned int cpu);
  165.73  extern int construct_dom0(
  165.74      struct domain *d,
  165.75 @@ -226,7 +228,7 @@ extern int construct_dom0(
  165.76  extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *);
  165.77  
  165.78  struct domain *find_domain_by_id(domid_t dom);
  165.79 -extern void domain_destruct(struct domain *d);
  165.80 +extern void domain_destroy(struct domain *d);
  165.81  extern void domain_kill(struct domain *d);
  165.82  extern void domain_shutdown(struct domain *d, u8 reason);
  165.83  extern void domain_pause_for_debugger(void);
  165.84 @@ -361,6 +363,12 @@ extern struct domain *domain_list;
  165.85   /* VCPU is not-runnable */
  165.86  #define _VCPUF_down            5
  165.87  #define VCPUF_down             (1UL<<_VCPUF_down)
  165.88 + /* NMI callback pending for this VCPU? */
  165.89 +#define _VCPUF_nmi_pending     8
  165.90 +#define VCPUF_nmi_pending      (1UL<<_VCPUF_nmi_pending)
  165.91 + /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
  165.92 +#define _VCPUF_nmi_masked      9
  165.93 +#define VCPUF_nmi_masked       (1UL<<_VCPUF_nmi_masked)
  165.94  
  165.95  /*
  165.96   * Per-domain flags (domain_flags).
   166.1 --- a/xen/include/xen/softirq.h	Tue Jan 10 15:21:00 2006 +0000
   166.2 +++ b/xen/include/xen/softirq.h	Tue Jan 24 17:54:34 2006 +0100
   166.3 @@ -2,11 +2,11 @@
   166.4  #define __XEN_SOFTIRQ_H__
   166.5  
   166.6  /* Common softirqs come first in the following list. */
   166.7 -#define AC_TIMER_SOFTIRQ                  0
   166.8 +#define TIMER_SOFTIRQ                     0
   166.9  #define SCHEDULE_SOFTIRQ                  1
  166.10  #define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
  166.11  #define KEYPRESS_SOFTIRQ                  3
  166.12 -#define NMI_DOM0_SOFTIRQ                  4
  166.13 +#define NMI_SOFTIRQ                       4
  166.14  #define PAGE_SCRUB_SOFTIRQ                5
  166.15  #define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ  6
  166.16  #define NR_SOFTIRQS                       7
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/xen/include/xen/timer.h	Tue Jan 24 17:54:34 2006 +0100
   167.3 @@ -0,0 +1,90 @@
   167.4 +/******************************************************************************
   167.5 + * timer.h
   167.6 + * 
   167.7 + * Copyright (c) 2002-2003 Rolf Neugebauer
   167.8 + * Copyright (c) 2002-2005 K A Fraser
   167.9 + */
  167.10 +
  167.11 +#ifndef _TIMER_H_
  167.12 +#define _TIMER_H_
  167.13 +
  167.14 +#include <xen/spinlock.h>
  167.15 +#include <xen/time.h>
  167.16 +#include <xen/string.h>
  167.17 +
  167.18 +struct timer {
  167.19 +    /* System time expiry value (nanoseconds since boot). */
  167.20 +    s_time_t      expires;
  167.21 +    /* CPU on which this timer will be installed and executed. */
  167.22 +    unsigned int  cpu;
  167.23 +    /* On expiry, '(*function)(data)' will be executed in softirq context. */
  167.24 +    void        (*function)(void *);
  167.25 +    void         *data;
  167.26 +    /* Timer-heap offset. */
  167.27 +    unsigned int  heap_offset;
  167.28 +    /* Has this timer been killed (cannot be activated)? */
  167.29 +    int           killed;
  167.30 +};
  167.31 +
  167.32 +/*
  167.33 + * All functions below can be called for any CPU from any CPU in any context.
  167.34 + */
  167.35 +
  167.36 +/* Returns TRUE if the given timer is on a timer list. */
  167.37 +static __inline__ int active_timer(struct timer *timer)
  167.38 +{
  167.39 +    return (timer->heap_offset != 0);
  167.40 +}
  167.41 +
  167.42 +/*
  167.43 + * It initialises the static fields of the timer structure.
  167.44 + * It can be called multiple times to reinitialise a single (inactive) timer.
  167.45 + */
  167.46 +static __inline__ void init_timer(
  167.47 +    struct timer *timer,
  167.48 +    void           (*function)(void *),
  167.49 +    void            *data,
  167.50 +    unsigned int     cpu)
  167.51 +{
  167.52 +    memset(timer, 0, sizeof(*timer));
  167.53 +    timer->function = function;
  167.54 +    timer->data     = data;
  167.55 +    timer->cpu      = cpu;
  167.56 +}
  167.57 +
  167.58 +/*
  167.59 + * Set the expiry time and activate a timer (which must previously have been
  167.60 + * initialised by init_timer).
  167.61 + */
  167.62 +extern void set_timer(struct timer *timer, s_time_t expires);
  167.63 +
  167.64 +/*
  167.65 + * Deactivate a timer (which must previously have been initialised by
  167.66 + * init_timer). This function has no effect if the timer is not currently
  167.67 + * active.
  167.68 + */
  167.69 +extern void stop_timer(struct timer *timer);
  167.70 +
  167.71 +/*
  167.72 + * Deactivate a timer and prevent it from being re-set (future calls to
  167.73 + * set_timer will silently fail). When this function returns it is guaranteed
  167.74 + * that the timer callback handler is not running on any CPU.
  167.75 + */
  167.76 +extern void kill_timer(struct timer *timer);
  167.77 +
  167.78 +/*
  167.79 + * Initialisation. Must be called before any other timer function.
  167.80 + */
  167.81 +extern void timer_init(void);
  167.82 +
  167.83 +#endif /* _TIMER_H_ */
  167.84 +
  167.85 +/*
  167.86 + * Local variables:
  167.87 + * mode: C
  167.88 + * c-set-style: "BSD"
  167.89 + * c-basic-offset: 4
  167.90 + * tab-width: 4
  167.91 + * indent-tabs-mode: nil
  167.92 + * End:
  167.93 + */