ia64/xen-unstable

changeset 9337:cf89e8f0831b

Merged.
author emellor@leeni.uk.xensource.com
date Mon Mar 20 09:56:54 2006 +0100 (2006-03-20)
parents 516cf6553011 1ecb7f1ddc79
children 056e571ce462
files xen/include/asm-x86/hvm/domain.h
line diff
     1.1 --- a/buildconfigs/mk.linux-2.6-xen	Mon Mar 20 09:56:46 2006 +0100
     1.2 +++ b/buildconfigs/mk.linux-2.6-xen	Mon Mar 20 09:56:54 2006 +0100
     1.3 @@ -2,8 +2,8 @@
     1.4  OS           = linux
     1.5  
     1.6  LINUX_SERIES = 2.6
     1.7 -LINUX_VER    = 2.6.16-rc5
     1.8 -LINUX_SRCS = linux-2.6.15.tar.bz2 patch-2.6.16-rc5.bz2
     1.9 +LINUX_VER    = 2.6.16-rc6
    1.10 +LINUX_SRCS = linux-2.6.15.tar.bz2 patch-2.6.16-rc6.bz2
    1.11  LINUX_PDIR = linux-$(LINUX_VER)
    1.12  
    1.13  EXTRAVERSION ?= xen
    1.14 @@ -34,7 +34,7 @@ pristine-$(LINUX_PDIR)/.valid-srcs: $(LI
    1.15  	touch $(@D)/.hgskip
    1.16  	touch $@
    1.17  
    1.18 -pristine-linux-%.16-rc5/.valid-pristine: pristine-$(LINUX_PDIR)/.valid-srcs
    1.19 +pristine-linux-%.16-rc6/.valid-pristine: pristine-$(LINUX_PDIR)/.valid-srcs
    1.20  	touch $@ # update timestamp to avoid rebuild
    1.21  
    1.22  $(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
     2.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile	Mon Mar 20 09:56:46 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile	Mon Mar 20 09:56:54 2006 +0100
     2.3 @@ -11,7 +11,7 @@ obj-y	:= process.o semaphore.o signal.o 
     2.4  
     2.5  obj-y				+= cpu/
     2.6  obj-y				+= timers/
     2.7 -obj-$(CONFIG_ACPI)		+= acpi/
     2.8 +obj-y				+= acpi/
     2.9  obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
    2.10  obj-$(CONFIG_MCA)		+= mca.o
    2.11  obj-$(CONFIG_X86_MSR)		+= msr.o
     3.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/acpi/Makefile	Mon Mar 20 09:56:46 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/acpi/Makefile	Mon Mar 20 09:56:54 2006 +0100
     3.3 @@ -1,4 +1,4 @@
     3.4 -obj-y				:= boot.o
     3.5 +obj-$(CONFIG_ACPI)		+= boot.o
     3.6  obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk.o
     3.7  obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
     3.8  
     4.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c	Mon Mar 20 09:56:46 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c	Mon Mar 20 09:56:54 2006 +0100
     4.3 @@ -44,6 +44,9 @@ extern void __init clustered_apic_check(
     4.4  extern int gsi_irq_sharing(int gsi);
     4.5  #include <asm/proto.h>
     4.6  
     4.7 +static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; }
     4.8 +
     4.9 +
    4.10  #else				/* X86 */
    4.11  
    4.12  #ifdef	CONFIG_X86_LOCAL_APIC
    4.13 @@ -1111,9 +1114,6 @@ int __init acpi_boot_table_init(void)
    4.14  		disable_acpi();
    4.15  		return error;
    4.16  	}
    4.17 -#ifdef __i386__
    4.18 -	check_acpi_pci();
    4.19 -#endif
    4.20  
    4.21  	acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
    4.22  
     5.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c	Mon Mar 20 09:56:46 2006 +0100
     5.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c	Mon Mar 20 09:56:54 2006 +0100
     5.3 @@ -283,10 +283,10 @@ void __devinit generic_identify(struct c
     5.4  			c->x86_capability[4] = excap;
     5.5  			c->x86 = (tfms >> 8) & 15;
     5.6  			c->x86_model = (tfms >> 4) & 15;
     5.7 -			if (c->x86 == 0xf) {
     5.8 +			if (c->x86 == 0xf)
     5.9  				c->x86 += (tfms >> 20) & 0xff;
    5.10 +			if (c->x86 >= 0x6)
    5.11  				c->x86_model += ((tfms >> 16) & 0xF) << 4;
    5.12 -			} 
    5.13  			c->x86_mask = tfms & 15;
    5.14  		} else {
    5.15  			/* Have CPUID level 0 only - unheard of */
     6.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c	Mon Mar 20 09:56:46 2006 +0100
     6.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c	Mon Mar 20 09:56:54 2006 +0100
     6.3 @@ -93,6 +93,8 @@ static struct { int pin, apic; } ioapic_
     6.4  
     6.5  static DEFINE_SPINLOCK(ioapic_lock);
     6.6  
     6.7 +int timer_over_8254 __initdata = 1;
     6.8 +
     6.9  /*
    6.10   *	Is the SiS APIC rmw bug present ?
    6.11   *	-1 = don't know, 0 = no, 1 = yes
    6.12 @@ -2329,7 +2331,8 @@ static inline void check_timer(void)
    6.13  	apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
    6.14  	init_8259A(1);
    6.15  	timer_ack = 1;
    6.16 -	enable_8259A_irq(0);
    6.17 +	if (timer_over_8254 > 0)
    6.18 +		enable_8259A_irq(0);
    6.19  
    6.20  	pin1  = find_isa_irq_pin(0, mp_INT);
    6.21  	apic1 = find_isa_irq_apic(0, mp_INT);
    6.22 @@ -2459,6 +2462,20 @@ void __init setup_IO_APIC(void)
    6.23  		print_IO_APIC();
    6.24  }
    6.25  
    6.26 +static int __init setup_disable_8254_timer(char *s)
    6.27 +{
    6.28 +	timer_over_8254 = -1;
    6.29 +	return 1;
    6.30 +}
    6.31 +static int __init setup_enable_8254_timer(char *s)
    6.32 +{
    6.33 +	timer_over_8254 = 2;
    6.34 +	return 1;
    6.35 +}
    6.36 +
    6.37 +__setup("disable_8254_timer", setup_disable_8254_timer);
    6.38 +__setup("enable_8254_timer", setup_enable_8254_timer);
    6.39 +
    6.40  /*
    6.41   *	Called after all the initialization is done. If we didnt find any
    6.42   *	APIC bugs then we can allow the modify fast path
     7.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Mon Mar 20 09:56:46 2006 +0100
     7.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Mon Mar 20 09:56:54 2006 +0100
     7.3 @@ -25,6 +25,7 @@
     7.4  #include <linux/kernel.h>
     7.5  #include <linux/init.h>
     7.6  #include <linux/sched.h>
     7.7 +#include <linux/cpumask.h>
     7.8  #include <linux/module.h>
     7.9  #include <linux/slab.h>
    7.10  #include <linux/vmalloc.h>
     8.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon Mar 20 09:56:46 2006 +0100
     8.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Mon Mar 20 09:56:54 2006 +0100
     8.3 @@ -1819,6 +1819,10 @@ void __init setup_arch(char **cmdline_p)
     8.4  	op.u.set_iopl.iopl = 1;
     8.5  	HYPERVISOR_physdev_op(&op);
     8.6  
     8.7 +#ifdef CONFIG_X86_IO_APIC
     8.8 +	check_acpi_pci();	/* Checks more than just ACPI actually */
     8.9 +#endif
    8.10 +
    8.11  #ifdef CONFIG_ACPI
    8.12  	if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
    8.13  		printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
     9.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Mon Mar 20 09:56:46 2006 +0100
     9.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Mon Mar 20 09:56:54 2006 +0100
     9.3 @@ -840,9 +840,9 @@ static int timer_resume(struct sys_devic
     9.4  	write_seqlock_irqsave(&xtime_lock, flags);
     9.5  	xtime.tv_sec = sec;
     9.6  	xtime.tv_nsec = 0;
     9.7 +	jiffies_64 += sleep_length;
     9.8 +	wall_jiffies += sleep_length;
     9.9  	write_sequnlock_irqrestore(&xtime_lock, flags);
    9.10 -	jiffies += sleep_length;
    9.11 -	wall_jiffies += sleep_length;
    9.12  	if (last_timer->resume)
    9.13  		last_timer->resume();
    9.14  	cur_timer = last_timer;
    10.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Mon Mar 20 09:56:46 2006 +0100
    10.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Mon Mar 20 09:56:54 2006 +0100
    10.3 @@ -254,7 +254,6 @@ 1:	movl r11=XSI_PSR_IC
    10.4  	st8 [r11]=r10
    10.5  	;;
    10.6  	br.ret.sptk.many rp
    10.7 -	;;
    10.8  END(xen_set_rr)
    10.9  
   10.10  GLOBAL_ENTRY(xen_fc)
   10.11 @@ -264,7 +263,16 @@ GLOBAL_ENTRY(xen_fc)
   10.12  (p7)	fc r32;;
   10.13  (p7)	br.ret.sptk.many rp
   10.14  	;;
   10.15 -	ptc.e r96		// this is a "privified" fc r32
   10.16 +	movl r9=XSI_PSR_IC
   10.17 +	mov r8=r32
   10.18 +	;;
   10.19 +	ld8 r10=[r9]
   10.20 +	;;
   10.21 +	st8 [r9]=r0
   10.22 +	;;
   10.23 +	XEN_HYPER_FC
   10.24 +	;;
   10.25 +	st8 [r9]=r10
   10.26  	;;
   10.27  	br.ret.sptk.many rp
   10.28  END(xen_fc)
   10.29 @@ -276,7 +284,16 @@ GLOBAL_ENTRY(xen_get_cpuid)
   10.30  (p7)	mov r8=cpuid[r32];;
   10.31  (p7)	br.ret.sptk.many rp
   10.32  	;;
   10.33 -	mov r72=rr[r32]		// this is a "privified" mov r8=cpuid[r32]
   10.34 +	movl r9=XSI_PSR_IC
   10.35 +	mov r8=r32
   10.36 +	;;
   10.37 +	ld8 r10=[r9]
   10.38 +	;;
   10.39 +	st8 [r9]=r0
   10.40 +	;;
   10.41 +	XEN_HYPER_GET_CPUID
   10.42 +	;;
   10.43 +	st8 [r9]=r10
   10.44  	;;
   10.45  	br.ret.sptk.many rp
   10.46  END(xen_get_cpuid)
   10.47 @@ -288,7 +305,16 @@ GLOBAL_ENTRY(xen_get_pmd)
   10.48  (p7)	mov r8=pmd[r32];;
   10.49  (p7)	br.ret.sptk.many rp
   10.50  	;;
   10.51 -	mov r72=pmc[r32] 	// this is a "privified" mov r8=pmd[r32]
   10.52 +	movl r9=XSI_PSR_IC
   10.53 +	mov r8=r32
   10.54 +	;;
   10.55 +	ld8 r10=[r9]
   10.56 +	;;
   10.57 +	st8 [r9]=r0
   10.58 +	;;
   10.59 +	XEN_HYPER_GET_PMD
   10.60 +	;;
   10.61 +	st8 [r9]=r10
   10.62  	;;
   10.63  	br.ret.sptk.many rp
   10.64  END(xen_get_pmd)
   10.65 @@ -301,10 +327,20 @@ GLOBAL_ENTRY(xen_get_eflag)
   10.66  (p7)	mov r8=ar24;;
   10.67  (p7)	br.ret.sptk.many rp
   10.68  	;;
   10.69 -	mov ar24=r72		// this is a "privified" mov r8=ar.eflg
   10.70 +	movl r9=XSI_PSR_IC
   10.71 +	mov r8=r32
   10.72 +	;;
   10.73 +	ld8 r10=[r9]
   10.74 +	;;
   10.75 +	st8 [r9]=r0
   10.76 +	;;
   10.77 +	XEN_HYPER_GET_EFLAG
   10.78 +	;;
   10.79 +	st8 [r9]=r10
   10.80  	;;
   10.81  	br.ret.sptk.many rp
   10.82  END(xen_get_eflag)
   10.83 +	
   10.84  // some bits aren't set if pl!=0, see SDM vol1 3.1.8
   10.85  GLOBAL_ENTRY(xen_set_eflag)
   10.86  	movl r8=running_on_xen;;
   10.87 @@ -313,11 +349,17 @@ GLOBAL_ENTRY(xen_set_eflag)
   10.88  (p7)	mov ar24=r32
   10.89  (p7)	br.ret.sptk.many rp
   10.90  	;;
   10.91 -	// FIXME: this remains no-op'd because it generates
   10.92 -	// a privileged register (general exception) trap rather than
   10.93 -	// a privileged operation fault
   10.94 -	//mov ar24=r32
   10.95 +	movl r9=XSI_PSR_IC
   10.96 +	mov r8=r32
   10.97 +	;;
   10.98 +	ld8 r10=[r9]
   10.99 +	;;
  10.100 +	st8 [r9]=r0
  10.101 +	;;
  10.102 +	XEN_HYPER_SET_EFLAG
  10.103 +	;;
  10.104 +	st8 [r9]=r10
  10.105  	;;
  10.106  	br.ret.sptk.many rp
  10.107 -END(xen_get_eflag)
  10.108 +END(xen_set_eflag)
  10.109  #endif
    11.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S	Mon Mar 20 09:56:46 2006 +0100
    11.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S	Mon Mar 20 09:56:54 2006 +0100
    11.3 @@ -723,16 +723,12 @@ ENTRY(dirty_bit)
    11.4  	movl r30=1f				// load continuation point in case of nested fault
    11.5  	;;
    11.6  #ifdef CONFIG_XEN
    11.7 -#if 1
    11.8  	mov r18=r8;
    11.9  	mov r8=r16;
   11.10  	XEN_HYPER_THASH;;
   11.11  	mov r17=r8;
   11.12  	mov r8=r18;;
   11.13  #else
   11.14 -	tak r17=r80				// "privified" thash
   11.15 -#endif
   11.16 -#else
   11.17  	thash r17=r16				// compute virtual address of L3 PTE
   11.18  #endif
   11.19  	mov r29=b0				// save b0 in case of nested fault
   11.20 @@ -812,16 +808,12 @@ ENTRY(iaccess_bit)
   11.21  #endif /* CONFIG_ITANIUM */
   11.22  	;;
   11.23  #ifdef CONFIG_XEN
   11.24 -#if 1
   11.25  	mov r18=r8;
   11.26  	mov r8=r16;
   11.27  	XEN_HYPER_THASH;;
   11.28  	mov r17=r8;
   11.29  	mov r8=r18;;
   11.30  #else
   11.31 -	tak r17=r80				// "privified" thash
   11.32 -#endif
   11.33 -#else
   11.34  	thash r17=r16				// compute virtual address of L3 PTE
   11.35  #endif
   11.36  	mov r29=b0				// save b0 in case of nested fault)
   11.37 @@ -898,16 +890,12 @@ ENTRY(daccess_bit)
   11.38  	movl r30=1f				// load continuation point in case of nested fault
   11.39  	;;
   11.40  #ifdef CONFIG_XEN
   11.41 -#if 1
   11.42  	mov r18=r8;
   11.43  	mov r8=r16;
   11.44  	XEN_HYPER_THASH;;
   11.45  	mov r17=r8;
   11.46  	mov r8=r18;;
   11.47  #else
   11.48 -	tak r17=r80				// "privified" thash
   11.49 -#endif
   11.50 -#else
   11.51  	thash r17=r16				// compute virtual address of L3 PTE
   11.52  #endif
   11.53  	mov r31=pr
    12.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Mon Mar 20 09:56:46 2006 +0100
    12.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Mon Mar 20 09:56:54 2006 +0100
    12.3 @@ -818,7 +818,7 @@ 11:	movb $0, EVENT_MASK(%rdi)
    12.4  	jmp  error_exit
    12.5  
    12.6  #ifdef CONFIG_X86_LOCAL_APIC
    12.7 -ENTRY(nmi)
    12.8 +KPROBE_ENTRY(nmi)
    12.9  	zeroentry do_nmi_callback
   12.10  ENTRY(do_nmi_callback)
   12.11          addq $8, %rsp
   12.12 @@ -828,6 +828,7 @@ ENTRY(do_nmi_callback)
   12.13          XEN_BLOCK_EVENTS(%rsi)
   12.14          GET_THREAD_INFO(%rcx)
   12.15          jmp  retint_restore_args
   12.16 +	.previous .text
   12.17  #endif
   12.18  
   12.19          ALIGN
    13.1 --- a/linux-2.6-xen-sparse/drivers/char/tty_io.c	Mon Mar 20 09:56:46 2006 +0100
    13.2 +++ b/linux-2.6-xen-sparse/drivers/char/tty_io.c	Mon Mar 20 09:56:54 2006 +0100
    13.3 @@ -305,7 +305,7 @@ static struct tty_buffer *tty_buffer_fin
    13.4  			t->commit = 0;
    13.5  			t->read = 0;
    13.6  			/* DEBUG ONLY */
    13.7 -			memset(t->data, '*', size);
    13.8 +/*			memset(t->data, '*', size); */
    13.9  /* 			printk("Flip recycle %p\n", t); */
   13.10  			return t;
   13.11  		}
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon Mar 20 09:56:46 2006 +0100
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon Mar 20 09:56:54 2006 +0100
    14.3 @@ -1049,6 +1049,8 @@ static int __init xenbus_probe_init(void
    14.4  		if (xsd_port_intf)
    14.5  			xsd_port_intf->read_proc = xsd_port_read;
    14.6  	}
    14.7 +	else
    14.8 +		xenstored_ready = 1;
    14.9  
   14.10  	/* Initialize the interface to xenstore. */
   14.11  	err = xs_init();
   14.12 @@ -1058,10 +1060,8 @@ static int __init xenbus_probe_init(void
   14.13  		return err;
   14.14  	}
   14.15  
   14.16 -	if (!dom0) {
   14.17 -		xenstored_ready = 1;
   14.18 +	if (!dom0)
   14.19  		xenbus_probe(NULL);
   14.20 -	}
   14.21  
   14.22  	return 0;
   14.23  }
    15.1 --- a/linux-2.6-xen-sparse/include/asm-i386/apic.h	Mon Mar 20 09:56:46 2006 +0100
    15.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/apic.h	Mon Mar 20 09:56:54 2006 +0100
    15.3 @@ -139,6 +139,8 @@ void switch_ipi_to_APIC_timer(void *cpum
    15.4  #define ARCH_APICTIMER_STOPS_ON_C3	1
    15.5  #endif
    15.6  
    15.7 +extern int timer_over_8254;
    15.8 +
    15.9  #else /* !CONFIG_X86_LOCAL_APIC */
   15.10  static inline void lapic_shutdown(void) { }
   15.11  
    16.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon Mar 20 09:56:46 2006 +0100
    16.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Mon Mar 20 09:56:54 2006 +0100
    16.3 @@ -32,6 +32,7 @@
    16.4  
    16.5  #include <xen/interface/xen.h>
    16.6  #include <xen/interface/sched.h>
    16.7 +#include <xen/interface/dom0_ops.h>
    16.8  #include <linux/errno.h>
    16.9  
   16.10  /* FIXME: temp place to hold these page related macros */
    17.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Mon Mar 20 09:56:46 2006 +0100
    17.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Mon Mar 20 09:56:54 2006 +0100
    17.3 @@ -44,6 +44,8 @@ extern start_info_t *xen_start_info;
    17.4  
    17.5  void force_evtchn_callback(void);
    17.6  
    17.7 +int xen_init(void);
    17.8 +
    17.9  /* Turn jiffies into Xen system time. XXX Implement me. */
   17.10  #define jiffies_to_st(j)	0
   17.11  
    18.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h	Mon Mar 20 09:56:46 2006 +0100
    18.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h	Mon Mar 20 09:56:54 2006 +0100
    18.3 @@ -33,6 +33,11 @@
    18.4  #define	XEN_HYPER_GET_RR		break 0x10
    18.5  #define	XEN_HYPER_SET_RR		break 0x11
    18.6  #define	XEN_HYPER_SET_KR		break 0x12
    18.7 +#define	XEN_HYPER_FC			break 0x13
    18.8 +#define	XEN_HYPER_GET_CPUID		break 0x14
    18.9 +#define	XEN_HYPER_GET_PMD		break 0x15
   18.10 +#define	XEN_HYPER_GET_EFLAG		break 0x16
   18.11 +#define	XEN_HYPER_SET_EFLAG		break 0x17
   18.12  #endif
   18.13  
   18.14  #ifndef __ASSEMBLY__
    19.1 --- a/linux-2.6-xen-sparse/include/linux/gfp.h	Mon Mar 20 09:56:46 2006 +0100
    19.2 +++ b/linux-2.6-xen-sparse/include/linux/gfp.h	Mon Mar 20 09:56:54 2006 +0100
    19.3 @@ -161,9 +161,9 @@ extern void FASTCALL(free_cold_page(stru
    19.4  
    19.5  void page_alloc_init(void);
    19.6  #ifdef CONFIG_NUMA
    19.7 -void drain_remote_pages(void);
    19.8 +void drain_node_pages(int node);
    19.9  #else
   19.10 -static inline void drain_remote_pages(void) { };
   19.11 +static inline void drain_node_pages(int node) { };
   19.12  #endif
   19.13  
   19.14  #endif /* __LINUX_GFP_H */
    20.1 --- a/linux-2.6-xen-sparse/mm/page_alloc.c	Mon Mar 20 09:56:46 2006 +0100
    20.2 +++ b/linux-2.6-xen-sparse/mm/page_alloc.c	Mon Mar 20 09:56:54 2006 +0100
    20.3 @@ -591,21 +591,20 @@ static int rmqueue_bulk(struct zone *zon
    20.4  }
    20.5  
    20.6  #ifdef CONFIG_NUMA
    20.7 -/* Called from the slab reaper to drain remote pagesets */
    20.8 -void drain_remote_pages(void)
    20.9 +/*
   20.10 + * Called from the slab reaper to drain pagesets on a particular node that
   20.11 + * belong to the currently executing processor.
   20.12 + */
   20.13 +void drain_node_pages(int nodeid)
   20.14  {
   20.15 -	struct zone *zone;
   20.16 -	int i;
   20.17 +	int i, z;
   20.18  	unsigned long flags;
   20.19  
   20.20  	local_irq_save(flags);
   20.21 -	for_each_zone(zone) {
   20.22 +	for (z = 0; z < MAX_NR_ZONES; z++) {
   20.23 +		struct zone *zone = NODE_DATA(nodeid)->node_zones + z;
   20.24  		struct per_cpu_pageset *pset;
   20.25  
   20.26 -		/* Do not drain local pagesets */
   20.27 -		if (zone->zone_pgdat->node_id == numa_node_id())
   20.28 -			continue;
   20.29 -
   20.30  		pset = zone_pcp(zone, smp_processor_id());
   20.31  		for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
   20.32  			struct per_cpu_pages *pcp;
    21.1 --- a/patches/linux-2.6.16-rc5/i386-mach-io-check-nmi.patch	Mon Mar 20 09:56:46 2006 +0100
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,45 +0,0 @@
    21.4 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
    21.5 ---- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/traps.c	2006-02-27 15:46:58.000000000 +0000
    21.6 -+++ ./arch/i386/kernel/traps.c	2006-02-27 15:55:23.000000000 +0000
    21.7 -@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
    21.8 - 
    21.9 - static void io_check_error(unsigned char reason, struct pt_regs * regs)
   21.10 - {
   21.11 --	unsigned long i;
   21.12 --
   21.13 - 	printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
   21.14 - 	show_registers(regs);
   21.15 - 
   21.16 - 	/* Re-enable the IOCK line, wait for a few seconds */
   21.17 --	reason = (reason & 0xf) | 8;
   21.18 --	outb(reason, 0x61);
   21.19 --	i = 2000;
   21.20 --	while (--i) udelay(1000);
   21.21 --	reason &= ~8;
   21.22 --	outb(reason, 0x61);
   21.23 -+	clear_io_check_error(reason);
   21.24 - }
   21.25 - 
   21.26 - static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
   21.27 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
   21.28 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/mach-default/mach_traps.h	2006-01-03 03:21:10.000000000 +0000
   21.29 -+++ ./include/asm-i386/mach-default/mach_traps.h	2006-02-27 15:55:23.000000000 +0000
   21.30 -@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
   21.31 - 	outb(reason, 0x61);
   21.32 - }
   21.33 - 
   21.34 -+static inline void clear_io_check_error(unsigned char reason)
   21.35 -+{
   21.36 -+	unsigned long i;
   21.37 -+
   21.38 -+	reason = (reason & 0xf) | 8;
   21.39 -+	outb(reason, 0x61);
   21.40 -+	i = 2000;
   21.41 -+	while (--i) udelay(1000);
   21.42 -+	reason &= ~8;
   21.43 -+	outb(reason, 0x61);
   21.44 -+}
   21.45 -+
   21.46 - static inline unsigned char get_nmi_reason(void)
   21.47 - {
   21.48 - 	return inb(0x61);
    22.1 --- a/patches/linux-2.6.16-rc5/net-csum.patch	Mon Mar 20 09:56:46 2006 +0100
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,41 +0,0 @@
    22.4 -diff -pruN ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
    22.5 ---- ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-02-27 15:47:38.000000000 +0000
    22.6 -+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-02-27 15:55:25.000000000 +0000
    22.7 -@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
    22.8 - 	if (hdrsize < sizeof(*hdr))
    22.9 - 		return 1;
   22.10 - 
   22.11 --	hdr->check = ip_nat_cheat_check(~oldip, newip,
   22.12 -+	if ((*pskb)->proto_csum_blank) {
   22.13 -+		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   22.14 -+	} else {
   22.15 -+		hdr->check = ip_nat_cheat_check(~oldip, newip,
   22.16 - 					ip_nat_cheat_check(oldport ^ 0xFFFF,
   22.17 - 							   newport,
   22.18 - 							   hdr->check));
   22.19 -+	}
   22.20 - 	return 1;
   22.21 - }
   22.22 - 
   22.23 -diff -pruN ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
   22.24 ---- ../pristine-linux-2.6.16-rc5/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-02-27 15:47:38.000000000 +0000
   22.25 -+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c	2006-02-27 15:55:25.000000000 +0000
   22.26 -@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
   22.27 - 		newport = tuple->dst.u.udp.port;
   22.28 - 		portptr = &hdr->dest;
   22.29 - 	}
   22.30 --	if (hdr->check) /* 0 is a special case meaning no checksum */
   22.31 --		hdr->check = ip_nat_cheat_check(~oldip, newip,
   22.32 -+	if (hdr->check) { /* 0 is a special case meaning no checksum */
   22.33 -+		if ((*pskb)->proto_csum_blank) {
   22.34 -+			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   22.35 -+		} else {
   22.36 -+			hdr->check = ip_nat_cheat_check(~oldip, newip,
   22.37 - 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
   22.38 - 							   newport,
   22.39 - 							   hdr->check));
   22.40 -+		}
   22.41 -+	}
   22.42 - 	*portptr = newport;
   22.43 - 	return 1;
   22.44 - }
    23.1 --- a/patches/linux-2.6.16-rc5/pmd-shared.patch	Mon Mar 20 09:56:46 2006 +0100
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,111 +0,0 @@
    23.4 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
    23.5 ---- ../pristine-linux-2.6.16-rc5/arch/i386/mm/pageattr.c	2006-02-27 15:46:58.000000000 +0000
    23.6 -+++ ./arch/i386/mm/pageattr.c	2006-02-27 15:55:31.000000000 +0000
    23.7 -@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
    23.8 - 	unsigned long flags;
    23.9 - 
   23.10 - 	set_pte_atomic(kpte, pte); 	/* change init_mm */
   23.11 --	if (PTRS_PER_PMD > 1)
   23.12 -+	if (HAVE_SHARED_KERNEL_PMD)
   23.13 - 		return;
   23.14 - 
   23.15 - 	spin_lock_irqsave(&pgd_lock, flags);
   23.16 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
   23.17 ---- ../pristine-linux-2.6.16-rc5/arch/i386/mm/pgtable.c	2006-01-03 03:21:10.000000000 +0000
   23.18 -+++ ./arch/i386/mm/pgtable.c	2006-02-27 15:55:31.000000000 +0000
   23.19 -@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
   23.20 - 		spin_lock_irqsave(&pgd_lock, flags);
   23.21 - 	}
   23.22 - 
   23.23 --	clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
   23.24 --			swapper_pg_dir + USER_PTRS_PER_PGD,
   23.25 --			KERNEL_PGD_PTRS);
   23.26 -+	if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
   23.27 -+		clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
   23.28 -+				swapper_pg_dir + USER_PTRS_PER_PGD,
   23.29 -+				KERNEL_PGD_PTRS);
   23.30 - 	if (PTRS_PER_PMD > 1)
   23.31 - 		return;
   23.32 - 
   23.33 -@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
   23.34 - 			goto out_oom;
   23.35 - 		set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
   23.36 - 	}
   23.37 -+
   23.38 -+	if (!HAVE_SHARED_KERNEL_PMD) {
   23.39 -+		unsigned long flags;
   23.40 -+
   23.41 -+		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   23.42 -+			pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
   23.43 -+			if (!pmd)
   23.44 -+				goto out_oom;
   23.45 -+			set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
   23.46 -+		}
   23.47 -+
   23.48 -+		spin_lock_irqsave(&pgd_lock, flags);
   23.49 -+		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   23.50 -+			unsigned long v = (unsigned long)i << PGDIR_SHIFT;
   23.51 -+			pgd_t *kpgd = pgd_offset_k(v);
   23.52 -+			pud_t *kpud = pud_offset(kpgd, v);
   23.53 -+			pmd_t *kpmd = pmd_offset(kpud, v);
   23.54 -+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   23.55 -+			memcpy(pmd, kpmd, PAGE_SIZE);
   23.56 -+		}
   23.57 -+		pgd_list_add(pgd);
   23.58 -+		spin_unlock_irqrestore(&pgd_lock, flags);
   23.59 -+	}
   23.60 -+
   23.61 - 	return pgd;
   23.62 - 
   23.63 - out_oom:
   23.64 -@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
   23.65 - 	int i;
   23.66 - 
   23.67 - 	/* in the PAE case user pgd entries are overwritten before usage */
   23.68 --	if (PTRS_PER_PMD > 1)
   23.69 --		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
   23.70 --			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
   23.71 -+	if (PTRS_PER_PMD > 1) {
   23.72 -+		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
   23.73 -+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   23.74 -+			kmem_cache_free(pmd_cache, pmd);
   23.75 -+		}
   23.76 -+		if (!HAVE_SHARED_KERNEL_PMD) {
   23.77 -+			unsigned long flags;
   23.78 -+			spin_lock_irqsave(&pgd_lock, flags);
   23.79 -+			pgd_list_del(pgd);
   23.80 -+			spin_unlock_irqrestore(&pgd_lock, flags);
   23.81 -+			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   23.82 -+				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   23.83 -+				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
   23.84 -+				kmem_cache_free(pmd_cache, pmd);
   23.85 -+			}
   23.86 -+		}
   23.87 -+	}
   23.88 - 	/* in the non-PAE case, free_pgtables() clears user pgd entries */
   23.89 - 	kmem_cache_free(pgd_cache, pgd);
   23.90 - }
   23.91 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
   23.92 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-2level-defs.h	2006-01-03 03:21:10.000000000 +0000
   23.93 -+++ ./include/asm-i386/pgtable-2level-defs.h	2006-02-27 15:55:31.000000000 +0000
   23.94 -@@ -1,6 +1,8 @@
   23.95 - #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
   23.96 - #define _I386_PGTABLE_2LEVEL_DEFS_H
   23.97 - 
   23.98 -+#define HAVE_SHARED_KERNEL_PMD 0
   23.99 -+
  23.100 - /*
  23.101 -  * traditional i386 two-level paging structure:
  23.102 -  */
  23.103 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
  23.104 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/pgtable-3level-defs.h	2006-01-03 03:21:10.000000000 +0000
  23.105 -+++ ./include/asm-i386/pgtable-3level-defs.h	2006-02-27 15:55:31.000000000 +0000
  23.106 -@@ -1,6 +1,8 @@
  23.107 - #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
  23.108 - #define _I386_PGTABLE_3LEVEL_DEFS_H
  23.109 - 
  23.110 -+#define HAVE_SHARED_KERNEL_PMD 1
  23.111 -+
  23.112 - /*
  23.113 -  * PGDIR_SHIFT determines what a top-level page table entry can map
  23.114 -  */
    24.1 --- a/patches/linux-2.6.16-rc5/smp-alts.patch	Mon Mar 20 09:56:46 2006 +0100
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,591 +0,0 @@
    24.4 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/Kconfig ./arch/i386/Kconfig
    24.5 ---- ../pristine-linux-2.6.16-rc5/arch/i386/Kconfig	2006-02-27 15:46:58.000000000 +0000
    24.6 -+++ ./arch/i386/Kconfig	2006-02-27 15:55:34.000000000 +0000
    24.7 -@@ -202,6 +202,19 @@ config SMP
    24.8 - 
    24.9 - 	  If you don't know what to do here, say N.
   24.10 - 
   24.11 -+config SMP_ALTERNATIVES
   24.12 -+	bool "SMP alternatives support (EXPERIMENTAL)"
   24.13 -+	depends on SMP && EXPERIMENTAL
   24.14 -+	help
   24.15 -+	  Try to reduce the overhead of running an SMP kernel on a uniprocessor
   24.16 -+	  host slightly by replacing certain key instruction sequences
   24.17 -+	  according to whether we currently have more than one CPU available.
   24.18 -+	  This should provide a noticeable boost to performance when
   24.19 -+	  running SMP kernels on UP machines, and have negligible impact
   24.20 -+	  when running on an true SMP host.
   24.21 -+
   24.22 -+          If unsure, say N.
   24.23 -+	  
   24.24 - config NR_CPUS
   24.25 - 	int "Maximum number of CPUs (2-255)"
   24.26 - 	range 2 255
   24.27 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
   24.28 ---- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/Makefile	2006-02-27 15:46:58.000000000 +0000
   24.29 -+++ ./arch/i386/kernel/Makefile	2006-02-27 15:55:34.000000000 +0000
   24.30 -@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
   24.31 - obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
   24.32 - obj-$(CONFIG_VM86)		+= vm86.o
   24.33 - obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
   24.34 -+obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
   24.35 - 
   24.36 - EXTRA_AFLAGS   := -traditional
   24.37 - 
   24.38 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
   24.39 ---- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpalts.c	1970-01-01 01:00:00.000000000 +0100
   24.40 -+++ ./arch/i386/kernel/smpalts.c	2006-02-27 15:55:34.000000000 +0000
   24.41 -@@ -0,0 +1,85 @@
   24.42 -+#include <linux/kernel.h>
   24.43 -+#include <asm/system.h>
   24.44 -+#include <asm/smp_alt.h>
   24.45 -+#include <asm/processor.h>
   24.46 -+#include <asm/string.h>
   24.47 -+
   24.48 -+struct smp_replacement_record {
   24.49 -+	unsigned char targ_size;
   24.50 -+	unsigned char smp1_size;
   24.51 -+	unsigned char smp2_size;
   24.52 -+	unsigned char up_size;
   24.53 -+	unsigned char feature;
   24.54 -+	unsigned char data[0];
   24.55 -+};
   24.56 -+
   24.57 -+struct smp_alternative_record {
   24.58 -+	void *targ_start;
   24.59 -+	struct smp_replacement_record *repl;
   24.60 -+};
   24.61 -+
   24.62 -+extern struct smp_alternative_record __start_smp_alternatives_table,
   24.63 -+  __stop_smp_alternatives_table;
   24.64 -+extern unsigned long __init_begin, __init_end;
   24.65 -+
   24.66 -+void prepare_for_smp(void)
   24.67 -+{
   24.68 -+	struct smp_alternative_record *r;
   24.69 -+	printk(KERN_INFO "Enabling SMP...\n");
   24.70 -+	for (r = &__start_smp_alternatives_table;
   24.71 -+	     r != &__stop_smp_alternatives_table;
   24.72 -+	     r++) {
   24.73 -+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
   24.74 -+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
   24.75 -+		BUG_ON(r->repl->targ_size < r->repl->up_size);
   24.76 -+               if (system_state == SYSTEM_RUNNING &&
   24.77 -+                   r->targ_start >= (void *)&__init_begin &&
   24.78 -+                   r->targ_start < (void *)&__init_end)
   24.79 -+                       continue;
   24.80 -+		if (r->repl->feature != (unsigned char)-1 &&
   24.81 -+		    boot_cpu_has(r->repl->feature)) {
   24.82 -+			memcpy(r->targ_start,
   24.83 -+			       r->repl->data + r->repl->smp1_size,
   24.84 -+			       r->repl->smp2_size);
   24.85 -+			memset(r->targ_start + r->repl->smp2_size,
   24.86 -+			       0x90,
   24.87 -+			       r->repl->targ_size - r->repl->smp2_size);
   24.88 -+		} else {
   24.89 -+			memcpy(r->targ_start,
   24.90 -+			       r->repl->data,
   24.91 -+			       r->repl->smp1_size);
   24.92 -+			memset(r->targ_start + r->repl->smp1_size,
   24.93 -+			       0x90,
   24.94 -+			       r->repl->targ_size - r->repl->smp1_size);
   24.95 -+		}
   24.96 -+	}
   24.97 -+	/* Paranoia */
   24.98 -+	asm volatile ("jmp 1f\n1:");
   24.99 -+	mb();
  24.100 -+}
  24.101 -+
  24.102 -+void unprepare_for_smp(void)
  24.103 -+{
  24.104 -+	struct smp_alternative_record *r;
  24.105 -+	printk(KERN_INFO "Disabling SMP...\n");
  24.106 -+	for (r = &__start_smp_alternatives_table;
  24.107 -+	     r != &__stop_smp_alternatives_table;
  24.108 -+	     r++) {
  24.109 -+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
  24.110 -+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
  24.111 -+		BUG_ON(r->repl->targ_size < r->repl->up_size);
  24.112 -+               if (system_state == SYSTEM_RUNNING &&
  24.113 -+                   r->targ_start >= (void *)&__init_begin &&
  24.114 -+                   r->targ_start < (void *)&__init_end)
  24.115 -+                       continue;
  24.116 -+		memcpy(r->targ_start,
  24.117 -+		       r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
  24.118 -+		       r->repl->up_size);
  24.119 -+		memset(r->targ_start + r->repl->up_size,
  24.120 -+		       0x90,
  24.121 -+		       r->repl->targ_size - r->repl->up_size);
  24.122 -+	}
  24.123 -+	/* Paranoia */
  24.124 -+	asm volatile ("jmp 1f\n1:");
  24.125 -+	mb();
  24.126 -+}
  24.127 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
  24.128 ---- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/smpboot.c	2006-02-27 15:46:58.000000000 +0000
  24.129 -+++ ./arch/i386/kernel/smpboot.c	2006-02-27 15:55:34.000000000 +0000
  24.130 -@@ -1208,6 +1208,11 @@ static void __init smp_boot_cpus(unsigne
  24.131 - 		if (max_cpus <= cpucount+1)
  24.132 - 			continue;
  24.133 - 
  24.134 -+#ifdef CONFIG_SMP_ALTERNATIVES
  24.135 -+		if (kicked == 1)
  24.136 -+			prepare_for_smp();
  24.137 -+#endif
  24.138 -+
  24.139 - 		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
  24.140 - 			printk("CPU #%d not responding - cannot use it.\n",
  24.141 - 								apicid);
  24.142 -@@ -1386,6 +1391,11 @@ int __devinit __cpu_up(unsigned int cpu)
  24.143 - 		return -EIO;
  24.144 - 	}
  24.145 - 
  24.146 -+#ifdef CONFIG_SMP_ALTERNATIVES
  24.147 -+	if (num_online_cpus() == 1)
  24.148 -+		prepare_for_smp();
  24.149 -+#endif
  24.150 -+
  24.151 - 	local_irq_enable();
  24.152 - 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
  24.153 - 	/* Unleash the CPU! */
  24.154 -diff -pruN ../pristine-linux-2.6.16-rc5/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
  24.155 ---- ../pristine-linux-2.6.16-rc5/arch/i386/kernel/vmlinux.lds.S	2006-01-03 03:21:10.000000000 +0000
  24.156 -+++ ./arch/i386/kernel/vmlinux.lds.S	2006-02-27 15:55:34.000000000 +0000
  24.157 -@@ -34,6 +34,13 @@ SECTIONS
  24.158 -   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
  24.159 -   __stop___ex_table = .;
  24.160 - 
  24.161 -+  . = ALIGN(16);
  24.162 -+  __start_smp_alternatives_table = .;
  24.163 -+  __smp_alternatives : { *(__smp_alternatives) }
  24.164 -+  __stop_smp_alternatives_table = .;
  24.165 -+
  24.166 -+  __smp_replacements : { *(__smp_replacements) }
  24.167 -+
  24.168 -   RODATA
  24.169 - 
  24.170 -   /* writeable */
  24.171 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
  24.172 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/atomic.h	2006-02-27 15:47:25.000000000 +0000
  24.173 -+++ ./include/asm-i386/atomic.h	2006-02-27 15:55:34.000000000 +0000
  24.174 -@@ -4,18 +4,13 @@
  24.175 - #include <linux/config.h>
  24.176 - #include <linux/compiler.h>
  24.177 - #include <asm/processor.h>
  24.178 -+#include <asm/smp_alt.h>
  24.179 - 
  24.180 - /*
  24.181 -  * Atomic operations that C can't guarantee us.  Useful for
  24.182 -  * resource counting etc..
  24.183 -  */
  24.184 - 
  24.185 --#ifdef CONFIG_SMP
  24.186 --#define LOCK "lock ; "
  24.187 --#else
  24.188 --#define LOCK ""
  24.189 --#endif
  24.190 --
  24.191 - /*
  24.192 -  * Make sure gcc doesn't try to be clever and move things around
  24.193 -  * on us. We need to use _exactly_ the address the user gave us,
  24.194 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
  24.195 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/bitops.h	2006-02-27 15:47:25.000000000 +0000
  24.196 -+++ ./include/asm-i386/bitops.h	2006-02-27 15:55:34.000000000 +0000
  24.197 -@@ -7,6 +7,7 @@
  24.198 - 
  24.199 - #include <linux/config.h>
  24.200 - #include <linux/compiler.h>
  24.201 -+#include <asm/smp_alt.h>
  24.202 - 
  24.203 - /*
  24.204 -  * These have to be done with inline assembly: that way the bit-setting
  24.205 -@@ -16,12 +17,6 @@
  24.206 -  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  24.207 -  */
  24.208 - 
  24.209 --#ifdef CONFIG_SMP
  24.210 --#define LOCK_PREFIX "lock ; "
  24.211 --#else
  24.212 --#define LOCK_PREFIX ""
  24.213 --#endif
  24.214 --
  24.215 - #define ADDR (*(volatile long *) addr)
  24.216 - 
  24.217 - /**
  24.218 -@@ -41,7 +36,7 @@
  24.219 -  */
  24.220 - static inline void set_bit(int nr, volatile unsigned long * addr)
  24.221 - {
  24.222 --	__asm__ __volatile__( LOCK_PREFIX
  24.223 -+	__asm__ __volatile__( LOCK
  24.224 - 		"btsl %1,%0"
  24.225 - 		:"+m" (ADDR)
  24.226 - 		:"Ir" (nr));
  24.227 -@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
  24.228 -  */
  24.229 - static inline void clear_bit(int nr, volatile unsigned long * addr)
  24.230 - {
  24.231 --	__asm__ __volatile__( LOCK_PREFIX
  24.232 -+	__asm__ __volatile__( LOCK
  24.233 - 		"btrl %1,%0"
  24.234 - 		:"+m" (ADDR)
  24.235 - 		:"Ir" (nr));
  24.236 -@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 
  24.237 -  */
  24.238 - static inline void change_bit(int nr, volatile unsigned long * addr)
  24.239 - {
  24.240 --	__asm__ __volatile__( LOCK_PREFIX
  24.241 -+	__asm__ __volatile__( LOCK
  24.242 - 		"btcl %1,%0"
  24.243 - 		:"+m" (ADDR)
  24.244 - 		:"Ir" (nr));
  24.245 -@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
  24.246 - {
  24.247 - 	int oldbit;
  24.248 - 
  24.249 --	__asm__ __volatile__( LOCK_PREFIX
  24.250 -+	__asm__ __volatile__( LOCK
  24.251 - 		"btsl %2,%1\n\tsbbl %0,%0"
  24.252 - 		:"=r" (oldbit),"+m" (ADDR)
  24.253 - 		:"Ir" (nr) : "memory");
  24.254 -@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
  24.255 - {
  24.256 - 	int oldbit;
  24.257 - 
  24.258 --	__asm__ __volatile__( LOCK_PREFIX
  24.259 -+	__asm__ __volatile__( LOCK
  24.260 - 		"btrl %2,%1\n\tsbbl %0,%0"
  24.261 - 		:"=r" (oldbit),"+m" (ADDR)
  24.262 - 		:"Ir" (nr) : "memory");
  24.263 -@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
  24.264 - {
  24.265 - 	int oldbit;
  24.266 - 
  24.267 --	__asm__ __volatile__( LOCK_PREFIX
  24.268 -+	__asm__ __volatile__( LOCK
  24.269 - 		"btcl %2,%1\n\tsbbl %0,%0"
  24.270 - 		:"=r" (oldbit),"+m" (ADDR)
  24.271 - 		:"Ir" (nr) : "memory");
  24.272 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/futex.h ./include/asm-i386/futex.h
  24.273 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/futex.h	2006-02-27 15:47:25.000000000 +0000
  24.274 -+++ ./include/asm-i386/futex.h	2006-02-27 15:55:34.000000000 +0000
  24.275 -@@ -28,7 +28,7 @@
  24.276 - "1:	movl	%2, %0\n\
  24.277 - 	movl	%0, %3\n"					\
  24.278 - 	insn "\n"						\
  24.279 --"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
  24.280 -+"2:	" LOCK "cmpxchgl %3, %2\n\
  24.281 - 	jnz	1b\n\
  24.282 - 3:	.section .fixup,\"ax\"\n\
  24.283 - 4:	mov	%5, %1\n\
  24.284 -@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 
  24.285 - #endif
  24.286 - 		switch (op) {
  24.287 - 		case FUTEX_OP_ADD:
  24.288 --			__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
  24.289 -+			__futex_atomic_op1(LOCK "xaddl %0, %2", ret,
  24.290 - 					   oldval, uaddr, oparg);
  24.291 - 			break;
  24.292 - 		case FUTEX_OP_OR:
  24.293 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
  24.294 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/rwsem.h	2006-01-03 03:21:10.000000000 +0000
  24.295 -+++ ./include/asm-i386/rwsem.h	2006-02-27 15:55:34.000000000 +0000
  24.296 -@@ -40,6 +40,7 @@
  24.297 - 
  24.298 - #include <linux/list.h>
  24.299 - #include <linux/spinlock.h>
  24.300 -+#include <asm/smp_alt.h>
  24.301 - 
  24.302 - struct rwsem_waiter;
  24.303 - 
  24.304 -@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
  24.305 - {
  24.306 - 	__asm__ __volatile__(
  24.307 - 		"# beginning down_read\n\t"
  24.308 --LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
  24.309 -+LOCK	        "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
  24.310 - 		"  js        2f\n\t" /* jump if we weren't granted the lock */
  24.311 - 		"1:\n\t"
  24.312 - 		LOCK_SECTION_START("")
  24.313 -@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
  24.314 - 		"  movl	     %1,%2\n\t"
  24.315 - 		"  addl      %3,%2\n\t"
  24.316 - 		"  jle	     2f\n\t"
  24.317 --LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
  24.318 -+LOCK	        "  cmpxchgl  %2,%0\n\t"
  24.319 - 		"  jnz	     1b\n\t"
  24.320 - 		"2:\n\t"
  24.321 - 		"# ending __down_read_trylock\n\t"
  24.322 -@@ -150,7 +151,7 @@ static inline void __down_write(struct r
  24.323 - 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
  24.324 - 	__asm__ __volatile__(
  24.325 - 		"# beginning down_write\n\t"
  24.326 --LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
  24.327 -+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
  24.328 - 		"  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
  24.329 - 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
  24.330 - 		"1:\n\t"
  24.331 -@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
  24.332 - 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
  24.333 - 	__asm__ __volatile__(
  24.334 - 		"# beginning __up_read\n\t"
  24.335 --LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
  24.336 -+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
  24.337 - 		"  js        2f\n\t" /* jump if the lock is being waited upon */
  24.338 - 		"1:\n\t"
  24.339 - 		LOCK_SECTION_START("")
  24.340 -@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
  24.341 - 	__asm__ __volatile__(
  24.342 - 		"# beginning __up_write\n\t"
  24.343 - 		"  movl      %2,%%edx\n\t"
  24.344 --LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
  24.345 -+LOCK	        "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
  24.346 - 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
  24.347 - 		"1:\n\t"
  24.348 - 		LOCK_SECTION_START("")
  24.349 -@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
  24.350 - {
  24.351 - 	__asm__ __volatile__(
  24.352 - 		"# beginning __downgrade_write\n\t"
  24.353 --LOCK_PREFIX	"  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
  24.354 -+LOCK	        "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
  24.355 - 		"  js        2f\n\t" /* jump if the lock is being waited upon */
  24.356 - 		"1:\n\t"
  24.357 - 		LOCK_SECTION_START("")
  24.358 -@@ -263,7 +264,7 @@ LOCK_PREFIX	"  addl      %2,(%%eax)\n\t"
  24.359 - static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
  24.360 - {
  24.361 - 	__asm__ __volatile__(
  24.362 --LOCK_PREFIX	"addl %1,%0"
  24.363 -+LOCK	          "addl %1,%0"
  24.364 - 		: "=m"(sem->count)
  24.365 - 		: "ir"(delta), "m"(sem->count));
  24.366 - }
  24.367 -@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
  24.368 - 	int tmp = delta;
  24.369 - 
  24.370 - 	__asm__ __volatile__(
  24.371 --LOCK_PREFIX	"xadd %0,(%2)"
  24.372 -+LOCK  	          "xadd %0,(%2)"
  24.373 - 		: "+r"(tmp), "=m"(sem->count)
  24.374 - 		: "r"(sem), "m"(sem->count)
  24.375 - 		: "memory");
  24.376 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
  24.377 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/smp_alt.h	1970-01-01 01:00:00.000000000 +0100
  24.378 -+++ ./include/asm-i386/smp_alt.h	2006-02-27 15:55:34.000000000 +0000
  24.379 -@@ -0,0 +1,32 @@
  24.380 -+#ifndef __ASM_SMP_ALT_H__
  24.381 -+#define __ASM_SMP_ALT_H__
  24.382 -+
  24.383 -+#include <linux/config.h>
  24.384 -+
  24.385 -+#ifdef CONFIG_SMP
  24.386 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
  24.387 -+#define LOCK \
  24.388 -+        "6677: nop\n" \
  24.389 -+	".section __smp_alternatives,\"a\"\n" \
  24.390 -+	".long 6677b\n" \
  24.391 -+	".long 6678f\n" \
  24.392 -+	".previous\n" \
  24.393 -+	".section __smp_replacements,\"a\"\n" \
  24.394 -+	"6678: .byte 1\n" \
  24.395 -+	".byte 1\n" \
  24.396 -+	".byte 0\n" \
  24.397 -+        ".byte 1\n" \
  24.398 -+	".byte -1\n" \
  24.399 -+	"lock\n" \
  24.400 -+	"nop\n" \
  24.401 -+	".previous\n"
  24.402 -+void prepare_for_smp(void);
  24.403 -+void unprepare_for_smp(void);
  24.404 -+#else
  24.405 -+#define LOCK "lock ; "
  24.406 -+#endif
  24.407 -+#else
  24.408 -+#define LOCK ""
  24.409 -+#endif
  24.410 -+
  24.411 -+#endif /* __ASM_SMP_ALT_H__ */
  24.412 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
  24.413 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/spinlock.h	2006-01-03 03:21:10.000000000 +0000
  24.414 -+++ ./include/asm-i386/spinlock.h	2006-02-27 15:55:34.000000000 +0000
  24.415 -@@ -6,6 +6,7 @@
  24.416 - #include <asm/page.h>
  24.417 - #include <linux/config.h>
  24.418 - #include <linux/compiler.h>
  24.419 -+#include <asm/smp_alt.h>
  24.420 - 
  24.421 - /*
  24.422 -  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  24.423 -@@ -23,7 +24,8 @@
  24.424 - 
  24.425 - #define __raw_spin_lock_string \
  24.426 - 	"\n1:\t" \
  24.427 --	"lock ; decb %0\n\t" \
  24.428 -+	LOCK \
  24.429 -+	"decb %0\n\t" \
  24.430 - 	"jns 3f\n" \
  24.431 - 	"2:\t" \
  24.432 - 	"rep;nop\n\t" \
  24.433 -@@ -34,7 +36,8 @@
  24.434 - 
  24.435 - #define __raw_spin_lock_string_flags \
  24.436 - 	"\n1:\t" \
  24.437 --	"lock ; decb %0\n\t" \
  24.438 -+	LOCK \
  24.439 -+	"decb %0\n\t" \
  24.440 - 	"jns 4f\n\t" \
  24.441 - 	"2:\t" \
  24.442 - 	"testl $0x200, %1\n\t" \
  24.443 -@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
  24.444 - static inline int __raw_spin_trylock(raw_spinlock_t *lock)
  24.445 - {
  24.446 - 	char oldval;
  24.447 -+#ifdef CONFIG_SMP_ALTERNATIVES
  24.448 - 	__asm__ __volatile__(
  24.449 --		"xchgb %b0,%1"
  24.450 -+		"1:movb %1,%b0\n"
  24.451 -+		"movb $0,%1\n"
  24.452 -+		"2:"
  24.453 -+		".section __smp_alternatives,\"a\"\n"
  24.454 -+		".long 1b\n"
  24.455 -+		".long 3f\n"
  24.456 -+		".previous\n"
  24.457 -+		".section __smp_replacements,\"a\"\n"
  24.458 -+		"3: .byte 2b - 1b\n"
  24.459 -+		".byte 5f-4f\n"
  24.460 -+		".byte 0\n"
  24.461 -+		".byte 6f-5f\n"
  24.462 -+		".byte -1\n"
  24.463 -+		"4: xchgb %b0,%1\n"
  24.464 -+		"5: movb %1,%b0\n"
  24.465 -+		"movb $0,%1\n"
  24.466 -+		"6:\n"
  24.467 -+		".previous\n"
  24.468 - 		:"=q" (oldval), "=m" (lock->slock)
  24.469 - 		:"0" (0) : "memory");
  24.470 -+#else
  24.471 -+	__asm__ __volatile__(
  24.472 -+		"xchgb %b0,%1\n"
  24.473 -+		:"=q" (oldval), "=m" (lock->slock)
  24.474 -+		:"0" (0) : "memory");
  24.475 -+#endif
  24.476 - 	return oldval > 0;
  24.477 - }
  24.478 - 
  24.479 -@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
  24.480 - 
  24.481 - static inline void __raw_read_unlock(raw_rwlock_t *rw)
  24.482 - {
  24.483 --	asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
  24.484 -+	asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
  24.485 - }
  24.486 - 
  24.487 - static inline void __raw_write_unlock(raw_rwlock_t *rw)
  24.488 - {
  24.489 --	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
  24.490 -+	asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
  24.491 - 				 : "=m" (rw->lock) : : "memory");
  24.492 - }
  24.493 - 
  24.494 -diff -pruN ../pristine-linux-2.6.16-rc5/include/asm-i386/system.h ./include/asm-i386/system.h
  24.495 ---- ../pristine-linux-2.6.16-rc5/include/asm-i386/system.h	2006-02-27 15:47:25.000000000 +0000
  24.496 -+++ ./include/asm-i386/system.h	2006-02-27 15:55:34.000000000 +0000
  24.497 -@@ -5,7 +5,7 @@
  24.498 - #include <linux/kernel.h>
  24.499 - #include <asm/segment.h>
  24.500 - #include <asm/cpufeature.h>
  24.501 --#include <linux/bitops.h> /* for LOCK_PREFIX */
  24.502 -+#include <asm/smp_alt.h>
  24.503 - 
  24.504 - #ifdef __KERNEL__
  24.505 - 
  24.506 -@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
  24.507 - 	unsigned long prev;
  24.508 - 	switch (size) {
  24.509 - 	case 1:
  24.510 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
  24.511 -+		__asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
  24.512 - 				     : "=a"(prev)
  24.513 - 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
  24.514 - 				     : "memory");
  24.515 - 		return prev;
  24.516 - 	case 2:
  24.517 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
  24.518 -+		__asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
  24.519 - 				     : "=a"(prev)
  24.520 - 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
  24.521 - 				     : "memory");
  24.522 - 		return prev;
  24.523 - 	case 4:
  24.524 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
  24.525 -+		__asm__ __volatile__(LOCK "cmpxchgl %1,%2"
  24.526 - 				     : "=a"(prev)
  24.527 - 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
  24.528 - 				     : "memory");
  24.529 -@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
  24.530 - 				      unsigned long long new)
  24.531 - {
  24.532 - 	unsigned long long prev;
  24.533 --	__asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
  24.534 -+	__asm__ __volatile__(LOCK "cmpxchg8b %3"
  24.535 - 			     : "=A"(prev)
  24.536 - 			     : "b"((unsigned long)new),
  24.537 - 			       "c"((unsigned long)(new >> 32)),
  24.538 -@@ -503,11 +503,55 @@ struct alt_instr { 
  24.539 - #endif
  24.540 - 
  24.541 - #ifdef CONFIG_SMP
  24.542 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
  24.543 -+#define smp_alt_mb(instr)                                           \
  24.544 -+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
  24.545 -+		     ".section __smp_alternatives,\"a\"\n"          \
  24.546 -+		     ".long 6667b\n"                                \
  24.547 -+                     ".long 6673f\n"                                \
  24.548 -+		     ".previous\n"                                  \
  24.549 -+		     ".section __smp_replacements,\"a\"\n"          \
  24.550 -+		     "6673:.byte 6668b-6667b\n"                     \
  24.551 -+		     ".byte 6670f-6669f\n"                          \
  24.552 -+		     ".byte 6671f-6670f\n"                          \
  24.553 -+                     ".byte 0\n"                                    \
  24.554 -+		     ".byte %c0\n"                                  \
  24.555 -+		     "6669:lock;addl $0,0(%%esp)\n"                 \
  24.556 -+		     "6670:" instr "\n"                             \
  24.557 -+		     "6671:\n"                                      \
  24.558 -+		     ".previous\n"                                  \
  24.559 -+		     :                                              \
  24.560 -+		     : "i" (X86_FEATURE_XMM2)                       \
  24.561 -+		     : "memory")
  24.562 -+#define smp_rmb() smp_alt_mb("lfence")
  24.563 -+#define smp_mb()  smp_alt_mb("mfence")
  24.564 -+#define set_mb(var, value) do {                                     \
  24.565 -+unsigned long __set_mb_temp;                                        \
  24.566 -+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
  24.567 -+		     ".section __smp_alternatives,\"a\"\n"          \
  24.568 -+		     ".long 6667b\n"                                \
  24.569 -+		     ".long 6673f\n"                                \
  24.570 -+		     ".previous\n"                                  \
  24.571 -+		     ".section __smp_replacements,\"a\"\n"          \
  24.572 -+		     "6673: .byte 6668b-6667b\n"                    \
  24.573 -+		     ".byte 6670f-6669f\n"                          \
  24.574 -+		     ".byte 0\n"                                    \
  24.575 -+		     ".byte 6671f-6670f\n"                          \
  24.576 -+		     ".byte -1\n"                                   \
  24.577 -+		     "6669: xchg %1, %0\n"                          \
  24.578 -+		     "6670:movl %1, %0\n"                           \
  24.579 -+		     "6671:\n"                                      \
  24.580 -+		     ".previous\n"                                  \
  24.581 -+		     : "=m" (var), "=r" (__set_mb_temp)             \
  24.582 -+		     : "1" (value)                                  \
  24.583 -+		     : "memory"); } while (0)
  24.584 -+#else
  24.585 - #define smp_mb()	mb()
  24.586 - #define smp_rmb()	rmb()
  24.587 -+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  24.588 -+#endif
  24.589 - #define smp_wmb()	wmb()
  24.590 - #define smp_read_barrier_depends()	read_barrier_depends()
  24.591 --#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  24.592 - #else
  24.593 - #define smp_mb()	barrier()
  24.594 - #define smp_rmb()	barrier()
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/patches/linux-2.6.16-rc6/i386-mach-io-check-nmi.patch	Mon Mar 20 09:56:54 2006 +0100
    25.3 @@ -0,0 +1,45 @@
    25.4 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
    25.5 +--- ../pristine-linux-2.6.16-rc6/arch/i386/kernel/traps.c	2006-03-17 22:59:01.000000000 +0000
    25.6 ++++ ./arch/i386/kernel/traps.c	2006-03-17 23:04:16.000000000 +0000
    25.7 +@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
    25.8 + 
    25.9 + static void io_check_error(unsigned char reason, struct pt_regs * regs)
   25.10 + {
   25.11 +-	unsigned long i;
   25.12 +-
   25.13 + 	printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
   25.14 + 	show_registers(regs);
   25.15 + 
   25.16 + 	/* Re-enable the IOCK line, wait for a few seconds */
   25.17 +-	reason = (reason & 0xf) | 8;
   25.18 +-	outb(reason, 0x61);
   25.19 +-	i = 2000;
   25.20 +-	while (--i) udelay(1000);
   25.21 +-	reason &= ~8;
   25.22 +-	outb(reason, 0x61);
   25.23 ++	clear_io_check_error(reason);
   25.24 + }
   25.25 + 
   25.26 + static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
   25.27 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
   25.28 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/mach-default/mach_traps.h	2006-01-03 03:21:10.000000000 +0000
   25.29 ++++ ./include/asm-i386/mach-default/mach_traps.h	2006-03-17 23:04:16.000000000 +0000
   25.30 +@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
   25.31 + 	outb(reason, 0x61);
   25.32 + }
   25.33 + 
   25.34 ++static inline void clear_io_check_error(unsigned char reason)
   25.35 ++{
   25.36 ++	unsigned long i;
   25.37 ++
   25.38 ++	reason = (reason & 0xf) | 8;
   25.39 ++	outb(reason, 0x61);
   25.40 ++	i = 2000;
   25.41 ++	while (--i) udelay(1000);
   25.42 ++	reason &= ~8;
   25.43 ++	outb(reason, 0x61);
   25.44 ++}
   25.45 ++
   25.46 + static inline unsigned char get_nmi_reason(void)
   25.47 + {
   25.48 + 	return inb(0x61);
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/patches/linux-2.6.16-rc6/net-csum.patch	Mon Mar 20 09:56:54 2006 +0100
    26.3 @@ -0,0 +1,41 @@
    26.4 +diff -pruN ../pristine-linux-2.6.16-rc6/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
    26.5 +--- ../pristine-linux-2.6.16-rc6/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-03-17 22:59:16.000000000 +0000
    26.6 ++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-03-17 23:04:19.000000000 +0000
    26.7 +@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
    26.8 + 	if (hdrsize < sizeof(*hdr))
    26.9 + 		return 1;
   26.10 + 
   26.11 +-	hdr->check = ip_nat_cheat_check(~oldip, newip,
   26.12 ++	if ((*pskb)->proto_csum_blank) {
   26.13 ++		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   26.14 ++	} else {
   26.15 ++		hdr->check = ip_nat_cheat_check(~oldip, newip,
   26.16 + 					ip_nat_cheat_check(oldport ^ 0xFFFF,
   26.17 + 							   newport,
   26.18 + 							   hdr->check));
   26.19 ++	}
   26.20 + 	return 1;
   26.21 + }
   26.22 + 
   26.23 +diff -pruN ../pristine-linux-2.6.16-rc6/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
   26.24 +--- ../pristine-linux-2.6.16-rc6/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-03-17 22:59:16.000000000 +0000
   26.25 ++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c	2006-03-17 23:04:19.000000000 +0000
   26.26 +@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
   26.27 + 		newport = tuple->dst.u.udp.port;
   26.28 + 		portptr = &hdr->dest;
   26.29 + 	}
   26.30 +-	if (hdr->check) /* 0 is a special case meaning no checksum */
   26.31 +-		hdr->check = ip_nat_cheat_check(~oldip, newip,
   26.32 ++	if (hdr->check) { /* 0 is a special case meaning no checksum */
   26.33 ++		if ((*pskb)->proto_csum_blank) {
   26.34 ++			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   26.35 ++		} else {
   26.36 ++			hdr->check = ip_nat_cheat_check(~oldip, newip,
   26.37 + 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
   26.38 + 							   newport,
   26.39 + 							   hdr->check));
   26.40 ++		}
   26.41 ++	}
   26.42 + 	*portptr = newport;
   26.43 + 	return 1;
   26.44 + }
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/patches/linux-2.6.16-rc6/pmd-shared.patch	Mon Mar 20 09:56:54 2006 +0100
    27.3 @@ -0,0 +1,111 @@
    27.4 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
    27.5 +--- ../pristine-linux-2.6.16-rc6/arch/i386/mm/pageattr.c	2006-03-17 22:59:01.000000000 +0000
    27.6 ++++ ./arch/i386/mm/pageattr.c	2006-03-17 23:04:21.000000000 +0000
    27.7 +@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
    27.8 + 	unsigned long flags;
    27.9 + 
   27.10 + 	set_pte_atomic(kpte, pte); 	/* change init_mm */
   27.11 +-	if (PTRS_PER_PMD > 1)
   27.12 ++	if (HAVE_SHARED_KERNEL_PMD)
   27.13 + 		return;
   27.14 + 
   27.15 + 	spin_lock_irqsave(&pgd_lock, flags);
   27.16 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
   27.17 +--- ../pristine-linux-2.6.16-rc6/arch/i386/mm/pgtable.c	2006-01-03 03:21:10.000000000 +0000
   27.18 ++++ ./arch/i386/mm/pgtable.c	2006-03-17 23:04:21.000000000 +0000
   27.19 +@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
   27.20 + 		spin_lock_irqsave(&pgd_lock, flags);
   27.21 + 	}
   27.22 + 
   27.23 +-	clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
   27.24 +-			swapper_pg_dir + USER_PTRS_PER_PGD,
   27.25 +-			KERNEL_PGD_PTRS);
   27.26 ++	if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
   27.27 ++		clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
   27.28 ++				swapper_pg_dir + USER_PTRS_PER_PGD,
   27.29 ++				KERNEL_PGD_PTRS);
   27.30 + 	if (PTRS_PER_PMD > 1)
   27.31 + 		return;
   27.32 + 
   27.33 +@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
   27.34 + 			goto out_oom;
   27.35 + 		set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
   27.36 + 	}
   27.37 ++
   27.38 ++	if (!HAVE_SHARED_KERNEL_PMD) {
   27.39 ++		unsigned long flags;
   27.40 ++
   27.41 ++		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   27.42 ++			pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
   27.43 ++			if (!pmd)
   27.44 ++				goto out_oom;
   27.45 ++			set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
   27.46 ++		}
   27.47 ++
   27.48 ++		spin_lock_irqsave(&pgd_lock, flags);
   27.49 ++		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   27.50 ++			unsigned long v = (unsigned long)i << PGDIR_SHIFT;
   27.51 ++			pgd_t *kpgd = pgd_offset_k(v);
   27.52 ++			pud_t *kpud = pud_offset(kpgd, v);
   27.53 ++			pmd_t *kpmd = pmd_offset(kpud, v);
   27.54 ++			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   27.55 ++			memcpy(pmd, kpmd, PAGE_SIZE);
   27.56 ++		}
   27.57 ++		pgd_list_add(pgd);
   27.58 ++		spin_unlock_irqrestore(&pgd_lock, flags);
   27.59 ++	}
   27.60 ++
   27.61 + 	return pgd;
   27.62 + 
   27.63 + out_oom:
   27.64 +@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
   27.65 + 	int i;
   27.66 + 
   27.67 + 	/* in the PAE case user pgd entries are overwritten before usage */
   27.68 +-	if (PTRS_PER_PMD > 1)
   27.69 +-		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
   27.70 +-			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
   27.71 ++	if (PTRS_PER_PMD > 1) {
   27.72 ++		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
   27.73 ++			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   27.74 ++			kmem_cache_free(pmd_cache, pmd);
   27.75 ++		}
   27.76 ++		if (!HAVE_SHARED_KERNEL_PMD) {
   27.77 ++			unsigned long flags;
   27.78 ++			spin_lock_irqsave(&pgd_lock, flags);
   27.79 ++			pgd_list_del(pgd);
   27.80 ++			spin_unlock_irqrestore(&pgd_lock, flags);
   27.81 ++			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   27.82 ++				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   27.83 ++				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
   27.84 ++				kmem_cache_free(pmd_cache, pmd);
   27.85 ++			}
   27.86 ++		}
   27.87 ++	}
   27.88 + 	/* in the non-PAE case, free_pgtables() clears user pgd entries */
   27.89 + 	kmem_cache_free(pgd_cache, pgd);
   27.90 + }
   27.91 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
   27.92 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/pgtable-2level-defs.h	2006-01-03 03:21:10.000000000 +0000
   27.93 ++++ ./include/asm-i386/pgtable-2level-defs.h	2006-03-17 23:04:21.000000000 +0000
   27.94 +@@ -1,6 +1,8 @@
   27.95 + #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
   27.96 + #define _I386_PGTABLE_2LEVEL_DEFS_H
   27.97 + 
   27.98 ++#define HAVE_SHARED_KERNEL_PMD 0
   27.99 ++
  27.100 + /*
  27.101 +  * traditional i386 two-level paging structure:
  27.102 +  */
  27.103 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
  27.104 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/pgtable-3level-defs.h	2006-01-03 03:21:10.000000000 +0000
  27.105 ++++ ./include/asm-i386/pgtable-3level-defs.h	2006-03-17 23:04:21.000000000 +0000
  27.106 +@@ -1,6 +1,8 @@
  27.107 + #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
  27.108 + #define _I386_PGTABLE_3LEVEL_DEFS_H
  27.109 + 
  27.110 ++#define HAVE_SHARED_KERNEL_PMD 1
  27.111 ++
  27.112 + /*
  27.113 +  * PGDIR_SHIFT determines what a top-level page table entry can map
  27.114 +  */
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/patches/linux-2.6.16-rc6/smp-alts.patch	Mon Mar 20 09:56:54 2006 +0100
    28.3 @@ -0,0 +1,591 @@
    28.4 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/Kconfig ./arch/i386/Kconfig
    28.5 +--- ../pristine-linux-2.6.16-rc6/arch/i386/Kconfig	2006-03-17 22:59:01.000000000 +0000
    28.6 ++++ ./arch/i386/Kconfig	2006-03-17 23:04:23.000000000 +0000
    28.7 +@@ -202,6 +202,19 @@ config SMP
    28.8 + 
    28.9 + 	  If you don't know what to do here, say N.
   28.10 + 
   28.11 ++config SMP_ALTERNATIVES
   28.12 ++	bool "SMP alternatives support (EXPERIMENTAL)"
   28.13 ++	depends on SMP && EXPERIMENTAL
   28.14 ++	help
   28.15 ++	  Try to reduce the overhead of running an SMP kernel on a uniprocessor
   28.16 ++	  host slightly by replacing certain key instruction sequences
   28.17 ++	  according to whether we currently have more than one CPU available.
   28.18 ++	  This should provide a noticeable boost to performance when
   28.19 ++	  running SMP kernels on UP machines, and have negligible impact
   28.20 ++	  when running on an true SMP host.
   28.21 ++
   28.22 ++          If unsure, say N.
   28.23 ++	  
   28.24 + config NR_CPUS
   28.25 + 	int "Maximum number of CPUs (2-255)"
   28.26 + 	range 2 255
   28.27 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
   28.28 +--- ../pristine-linux-2.6.16-rc6/arch/i386/kernel/Makefile	2006-03-17 22:59:01.000000000 +0000
   28.29 ++++ ./arch/i386/kernel/Makefile	2006-03-17 23:04:23.000000000 +0000
   28.30 +@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
   28.31 + obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
   28.32 + obj-$(CONFIG_VM86)		+= vm86.o
   28.33 + obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
   28.34 ++obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
   28.35 + 
   28.36 + EXTRA_AFLAGS   := -traditional
   28.37 + 
   28.38 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
   28.39 +--- ../pristine-linux-2.6.16-rc6/arch/i386/kernel/smpalts.c	1970-01-01 01:00:00.000000000 +0100
   28.40 ++++ ./arch/i386/kernel/smpalts.c	2006-03-17 23:04:23.000000000 +0000
   28.41 +@@ -0,0 +1,85 @@
   28.42 ++#include <linux/kernel.h>
   28.43 ++#include <asm/system.h>
   28.44 ++#include <asm/smp_alt.h>
   28.45 ++#include <asm/processor.h>
   28.46 ++#include <asm/string.h>
   28.47 ++
   28.48 ++struct smp_replacement_record {
   28.49 ++	unsigned char targ_size;
   28.50 ++	unsigned char smp1_size;
   28.51 ++	unsigned char smp2_size;
   28.52 ++	unsigned char up_size;
   28.53 ++	unsigned char feature;
   28.54 ++	unsigned char data[0];
   28.55 ++};
   28.56 ++
   28.57 ++struct smp_alternative_record {
   28.58 ++	void *targ_start;
   28.59 ++	struct smp_replacement_record *repl;
   28.60 ++};
   28.61 ++
   28.62 ++extern struct smp_alternative_record __start_smp_alternatives_table,
   28.63 ++  __stop_smp_alternatives_table;
   28.64 ++extern unsigned long __init_begin, __init_end;
   28.65 ++
   28.66 ++void prepare_for_smp(void)
   28.67 ++{
   28.68 ++	struct smp_alternative_record *r;
   28.69 ++	printk(KERN_INFO "Enabling SMP...\n");
   28.70 ++	for (r = &__start_smp_alternatives_table;
   28.71 ++	     r != &__stop_smp_alternatives_table;
   28.72 ++	     r++) {
   28.73 ++		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
   28.74 ++		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
   28.75 ++		BUG_ON(r->repl->targ_size < r->repl->up_size);
   28.76 ++               if (system_state == SYSTEM_RUNNING &&
   28.77 ++                   r->targ_start >= (void *)&__init_begin &&
   28.78 ++                   r->targ_start < (void *)&__init_end)
   28.79 ++                       continue;
   28.80 ++		if (r->repl->feature != (unsigned char)-1 &&
   28.81 ++		    boot_cpu_has(r->repl->feature)) {
   28.82 ++			memcpy(r->targ_start,
   28.83 ++			       r->repl->data + r->repl->smp1_size,
   28.84 ++			       r->repl->smp2_size);
   28.85 ++			memset(r->targ_start + r->repl->smp2_size,
   28.86 ++			       0x90,
   28.87 ++			       r->repl->targ_size - r->repl->smp2_size);
   28.88 ++		} else {
   28.89 ++			memcpy(r->targ_start,
   28.90 ++			       r->repl->data,
   28.91 ++			       r->repl->smp1_size);
   28.92 ++			memset(r->targ_start + r->repl->smp1_size,
   28.93 ++			       0x90,
   28.94 ++			       r->repl->targ_size - r->repl->smp1_size);
   28.95 ++		}
   28.96 ++	}
   28.97 ++	/* Paranoia */
   28.98 ++	asm volatile ("jmp 1f\n1:");
   28.99 ++	mb();
  28.100 ++}
  28.101 ++
  28.102 ++void unprepare_for_smp(void)
  28.103 ++{
  28.104 ++	struct smp_alternative_record *r;
  28.105 ++	printk(KERN_INFO "Disabling SMP...\n");
  28.106 ++	for (r = &__start_smp_alternatives_table;
  28.107 ++	     r != &__stop_smp_alternatives_table;
  28.108 ++	     r++) {
  28.109 ++		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
  28.110 ++		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
  28.111 ++		BUG_ON(r->repl->targ_size < r->repl->up_size);
  28.112 ++               if (system_state == SYSTEM_RUNNING &&
  28.113 ++                   r->targ_start >= (void *)&__init_begin &&
  28.114 ++                   r->targ_start < (void *)&__init_end)
  28.115 ++                       continue;
  28.116 ++		memcpy(r->targ_start,
  28.117 ++		       r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
  28.118 ++		       r->repl->up_size);
  28.119 ++		memset(r->targ_start + r->repl->up_size,
  28.120 ++		       0x90,
  28.121 ++		       r->repl->targ_size - r->repl->up_size);
  28.122 ++	}
  28.123 ++	/* Paranoia */
  28.124 ++	asm volatile ("jmp 1f\n1:");
  28.125 ++	mb();
  28.126 ++}
  28.127 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
  28.128 +--- ../pristine-linux-2.6.16-rc6/arch/i386/kernel/smpboot.c	2006-03-17 22:59:01.000000000 +0000
  28.129 ++++ ./arch/i386/kernel/smpboot.c	2006-03-17 23:04:23.000000000 +0000
  28.130 +@@ -1208,6 +1208,11 @@ static void __init smp_boot_cpus(unsigne
  28.131 + 		if (max_cpus <= cpucount+1)
  28.132 + 			continue;
  28.133 + 
  28.134 ++#ifdef CONFIG_SMP_ALTERNATIVES
  28.135 ++		if (kicked == 1)
  28.136 ++			prepare_for_smp();
  28.137 ++#endif
  28.138 ++
  28.139 + 		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
  28.140 + 			printk("CPU #%d not responding - cannot use it.\n",
  28.141 + 								apicid);
  28.142 +@@ -1386,6 +1391,11 @@ int __devinit __cpu_up(unsigned int cpu)
  28.143 + 		return -EIO;
  28.144 + 	}
  28.145 + 
  28.146 ++#ifdef CONFIG_SMP_ALTERNATIVES
  28.147 ++	if (num_online_cpus() == 1)
  28.148 ++		prepare_for_smp();
  28.149 ++#endif
  28.150 ++
  28.151 + 	local_irq_enable();
  28.152 + 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
  28.153 + 	/* Unleash the CPU! */
  28.154 +diff -pruN ../pristine-linux-2.6.16-rc6/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
  28.155 +--- ../pristine-linux-2.6.16-rc6/arch/i386/kernel/vmlinux.lds.S	2006-01-03 03:21:10.000000000 +0000
  28.156 ++++ ./arch/i386/kernel/vmlinux.lds.S	2006-03-17 23:04:23.000000000 +0000
  28.157 +@@ -34,6 +34,13 @@ SECTIONS
  28.158 +   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
  28.159 +   __stop___ex_table = .;
  28.160 + 
  28.161 ++  . = ALIGN(16);
  28.162 ++  __start_smp_alternatives_table = .;
  28.163 ++  __smp_alternatives : { *(__smp_alternatives) }
  28.164 ++  __stop_smp_alternatives_table = .;
  28.165 ++
  28.166 ++  __smp_replacements : { *(__smp_replacements) }
  28.167 ++
  28.168 +   RODATA
  28.169 + 
  28.170 +   /* writeable */
  28.171 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
  28.172 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/atomic.h	2006-03-17 22:59:05.000000000 +0000
  28.173 ++++ ./include/asm-i386/atomic.h	2006-03-17 23:04:23.000000000 +0000
  28.174 +@@ -4,18 +4,13 @@
  28.175 + #include <linux/config.h>
  28.176 + #include <linux/compiler.h>
  28.177 + #include <asm/processor.h>
  28.178 ++#include <asm/smp_alt.h>
  28.179 + 
  28.180 + /*
  28.181 +  * Atomic operations that C can't guarantee us.  Useful for
  28.182 +  * resource counting etc..
  28.183 +  */
  28.184 + 
  28.185 +-#ifdef CONFIG_SMP
  28.186 +-#define LOCK "lock ; "
  28.187 +-#else
  28.188 +-#define LOCK ""
  28.189 +-#endif
  28.190 +-
  28.191 + /*
  28.192 +  * Make sure gcc doesn't try to be clever and move things around
  28.193 +  * on us. We need to use _exactly_ the address the user gave us,
  28.194 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
  28.195 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/bitops.h	2006-03-17 22:59:05.000000000 +0000
  28.196 ++++ ./include/asm-i386/bitops.h	2006-03-17 23:04:23.000000000 +0000
  28.197 +@@ -7,6 +7,7 @@
  28.198 + 
  28.199 + #include <linux/config.h>
  28.200 + #include <linux/compiler.h>
  28.201 ++#include <asm/smp_alt.h>
  28.202 + 
  28.203 + /*
  28.204 +  * These have to be done with inline assembly: that way the bit-setting
  28.205 +@@ -16,12 +17,6 @@
  28.206 +  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  28.207 +  */
  28.208 + 
  28.209 +-#ifdef CONFIG_SMP
  28.210 +-#define LOCK_PREFIX "lock ; "
  28.211 +-#else
  28.212 +-#define LOCK_PREFIX ""
  28.213 +-#endif
  28.214 +-
  28.215 + #define ADDR (*(volatile long *) addr)
  28.216 + 
  28.217 + /**
  28.218 +@@ -41,7 +36,7 @@
  28.219 +  */
  28.220 + static inline void set_bit(int nr, volatile unsigned long * addr)
  28.221 + {
  28.222 +-	__asm__ __volatile__( LOCK_PREFIX
  28.223 ++	__asm__ __volatile__( LOCK
  28.224 + 		"btsl %1,%0"
  28.225 + 		:"+m" (ADDR)
  28.226 + 		:"Ir" (nr));
  28.227 +@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
  28.228 +  */
  28.229 + static inline void clear_bit(int nr, volatile unsigned long * addr)
  28.230 + {
  28.231 +-	__asm__ __volatile__( LOCK_PREFIX
  28.232 ++	__asm__ __volatile__( LOCK
  28.233 + 		"btrl %1,%0"
  28.234 + 		:"+m" (ADDR)
  28.235 + 		:"Ir" (nr));
  28.236 +@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 
  28.237 +  */
  28.238 + static inline void change_bit(int nr, volatile unsigned long * addr)
  28.239 + {
  28.240 +-	__asm__ __volatile__( LOCK_PREFIX
  28.241 ++	__asm__ __volatile__( LOCK
  28.242 + 		"btcl %1,%0"
  28.243 + 		:"+m" (ADDR)
  28.244 + 		:"Ir" (nr));
  28.245 +@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
  28.246 + {
  28.247 + 	int oldbit;
  28.248 + 
  28.249 +-	__asm__ __volatile__( LOCK_PREFIX
  28.250 ++	__asm__ __volatile__( LOCK
  28.251 + 		"btsl %2,%1\n\tsbbl %0,%0"
  28.252 + 		:"=r" (oldbit),"+m" (ADDR)
  28.253 + 		:"Ir" (nr) : "memory");
  28.254 +@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
  28.255 + {
  28.256 + 	int oldbit;
  28.257 + 
  28.258 +-	__asm__ __volatile__( LOCK_PREFIX
  28.259 ++	__asm__ __volatile__( LOCK
  28.260 + 		"btrl %2,%1\n\tsbbl %0,%0"
  28.261 + 		:"=r" (oldbit),"+m" (ADDR)
  28.262 + 		:"Ir" (nr) : "memory");
  28.263 +@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
  28.264 + {
  28.265 + 	int oldbit;
  28.266 + 
  28.267 +-	__asm__ __volatile__( LOCK_PREFIX
  28.268 ++	__asm__ __volatile__( LOCK
  28.269 + 		"btcl %2,%1\n\tsbbl %0,%0"
  28.270 + 		:"=r" (oldbit),"+m" (ADDR)
  28.271 + 		:"Ir" (nr) : "memory");
  28.272 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/futex.h ./include/asm-i386/futex.h
  28.273 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/futex.h	2006-03-17 22:59:05.000000000 +0000
  28.274 ++++ ./include/asm-i386/futex.h	2006-03-17 23:04:23.000000000 +0000
  28.275 +@@ -28,7 +28,7 @@
  28.276 + "1:	movl	%2, %0\n\
  28.277 + 	movl	%0, %3\n"					\
  28.278 + 	insn "\n"						\
  28.279 +-"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
  28.280 ++"2:	" LOCK "cmpxchgl %3, %2\n\
  28.281 + 	jnz	1b\n\
  28.282 + 3:	.section .fixup,\"ax\"\n\
  28.283 + 4:	mov	%5, %1\n\
  28.284 +@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 
  28.285 + #endif
  28.286 + 		switch (op) {
  28.287 + 		case FUTEX_OP_ADD:
  28.288 +-			__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
  28.289 ++			__futex_atomic_op1(LOCK "xaddl %0, %2", ret,
  28.290 + 					   oldval, uaddr, oparg);
  28.291 + 			break;
  28.292 + 		case FUTEX_OP_OR:
  28.293 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
  28.294 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/rwsem.h	2006-01-03 03:21:10.000000000 +0000
  28.295 ++++ ./include/asm-i386/rwsem.h	2006-03-17 23:04:23.000000000 +0000
  28.296 +@@ -40,6 +40,7 @@
  28.297 + 
  28.298 + #include <linux/list.h>
  28.299 + #include <linux/spinlock.h>
  28.300 ++#include <asm/smp_alt.h>
  28.301 + 
  28.302 + struct rwsem_waiter;
  28.303 + 
  28.304 +@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
  28.305 + {
  28.306 + 	__asm__ __volatile__(
  28.307 + 		"# beginning down_read\n\t"
  28.308 +-LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
  28.309 ++LOCK	        "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
  28.310 + 		"  js        2f\n\t" /* jump if we weren't granted the lock */
  28.311 + 		"1:\n\t"
  28.312 + 		LOCK_SECTION_START("")
  28.313 +@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
  28.314 + 		"  movl	     %1,%2\n\t"
  28.315 + 		"  addl      %3,%2\n\t"
  28.316 + 		"  jle	     2f\n\t"
  28.317 +-LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
  28.318 ++LOCK	        "  cmpxchgl  %2,%0\n\t"
  28.319 + 		"  jnz	     1b\n\t"
  28.320 + 		"2:\n\t"
  28.321 + 		"# ending __down_read_trylock\n\t"
  28.322 +@@ -150,7 +151,7 @@ static inline void __down_write(struct r
  28.323 + 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
  28.324 + 	__asm__ __volatile__(
  28.325 + 		"# beginning down_write\n\t"
  28.326 +-LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
  28.327 ++LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
  28.328 + 		"  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
  28.329 + 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
  28.330 + 		"1:\n\t"
  28.331 +@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
  28.332 + 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
  28.333 + 	__asm__ __volatile__(
  28.334 + 		"# beginning __up_read\n\t"
  28.335 +-LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
  28.336 ++LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
  28.337 + 		"  js        2f\n\t" /* jump if the lock is being waited upon */
  28.338 + 		"1:\n\t"
  28.339 + 		LOCK_SECTION_START("")
  28.340 +@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
  28.341 + 	__asm__ __volatile__(
  28.342 + 		"# beginning __up_write\n\t"
  28.343 + 		"  movl      %2,%%edx\n\t"
  28.344 +-LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
  28.345 ++LOCK	        "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
  28.346 + 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
  28.347 + 		"1:\n\t"
  28.348 + 		LOCK_SECTION_START("")
  28.349 +@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
  28.350 + {
  28.351 + 	__asm__ __volatile__(
  28.352 + 		"# beginning __downgrade_write\n\t"
  28.353 +-LOCK_PREFIX	"  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
  28.354 ++LOCK	        "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
  28.355 + 		"  js        2f\n\t" /* jump if the lock is being waited upon */
  28.356 + 		"1:\n\t"
  28.357 + 		LOCK_SECTION_START("")
  28.358 +@@ -263,7 +264,7 @@ LOCK_PREFIX	"  addl      %2,(%%eax)\n\t"
  28.359 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
  28.360 + {
  28.361 + 	__asm__ __volatile__(
  28.362 +-LOCK_PREFIX	"addl %1,%0"
  28.363 ++LOCK	          "addl %1,%0"
  28.364 + 		: "=m"(sem->count)
  28.365 + 		: "ir"(delta), "m"(sem->count));
  28.366 + }
  28.367 +@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
  28.368 + 	int tmp = delta;
  28.369 + 
  28.370 + 	__asm__ __volatile__(
  28.371 +-LOCK_PREFIX	"xadd %0,(%2)"
  28.372 ++LOCK  	          "xadd %0,(%2)"
  28.373 + 		: "+r"(tmp), "=m"(sem->count)
  28.374 + 		: "r"(sem), "m"(sem->count)
  28.375 + 		: "memory");
  28.376 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
  28.377 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/smp_alt.h	1970-01-01 01:00:00.000000000 +0100
  28.378 ++++ ./include/asm-i386/smp_alt.h	2006-03-17 23:04:23.000000000 +0000
  28.379 +@@ -0,0 +1,32 @@
  28.380 ++#ifndef __ASM_SMP_ALT_H__
  28.381 ++#define __ASM_SMP_ALT_H__
  28.382 ++
  28.383 ++#include <linux/config.h>
  28.384 ++
  28.385 ++#ifdef CONFIG_SMP
  28.386 ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
  28.387 ++#define LOCK \
  28.388 ++        "6677: nop\n" \
  28.389 ++	".section __smp_alternatives,\"a\"\n" \
  28.390 ++	".long 6677b\n" \
  28.391 ++	".long 6678f\n" \
  28.392 ++	".previous\n" \
  28.393 ++	".section __smp_replacements,\"a\"\n" \
  28.394 ++	"6678: .byte 1\n" \
  28.395 ++	".byte 1\n" \
  28.396 ++	".byte 0\n" \
  28.397 ++        ".byte 1\n" \
  28.398 ++	".byte -1\n" \
  28.399 ++	"lock\n" \
  28.400 ++	"nop\n" \
  28.401 ++	".previous\n"
  28.402 ++void prepare_for_smp(void);
  28.403 ++void unprepare_for_smp(void);
  28.404 ++#else
  28.405 ++#define LOCK "lock ; "
  28.406 ++#endif
  28.407 ++#else
  28.408 ++#define LOCK ""
  28.409 ++#endif
  28.410 ++
  28.411 ++#endif /* __ASM_SMP_ALT_H__ */
  28.412 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
  28.413 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/spinlock.h	2006-01-03 03:21:10.000000000 +0000
  28.414 ++++ ./include/asm-i386/spinlock.h	2006-03-17 23:04:23.000000000 +0000
  28.415 +@@ -6,6 +6,7 @@
  28.416 + #include <asm/page.h>
  28.417 + #include <linux/config.h>
  28.418 + #include <linux/compiler.h>
  28.419 ++#include <asm/smp_alt.h>
  28.420 + 
  28.421 + /*
  28.422 +  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  28.423 +@@ -23,7 +24,8 @@
  28.424 + 
  28.425 + #define __raw_spin_lock_string \
  28.426 + 	"\n1:\t" \
  28.427 +-	"lock ; decb %0\n\t" \
  28.428 ++	LOCK \
  28.429 ++	"decb %0\n\t" \
  28.430 + 	"jns 3f\n" \
  28.431 + 	"2:\t" \
  28.432 + 	"rep;nop\n\t" \
  28.433 +@@ -34,7 +36,8 @@
  28.434 + 
  28.435 + #define __raw_spin_lock_string_flags \
  28.436 + 	"\n1:\t" \
  28.437 +-	"lock ; decb %0\n\t" \
  28.438 ++	LOCK \
  28.439 ++	"decb %0\n\t" \
  28.440 + 	"jns 4f\n\t" \
  28.441 + 	"2:\t" \
  28.442 + 	"testl $0x200, %1\n\t" \
  28.443 +@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
  28.444 + static inline int __raw_spin_trylock(raw_spinlock_t *lock)
  28.445 + {
  28.446 + 	char oldval;
  28.447 ++#ifdef CONFIG_SMP_ALTERNATIVES
  28.448 + 	__asm__ __volatile__(
  28.449 +-		"xchgb %b0,%1"
  28.450 ++		"1:movb %1,%b0\n"
  28.451 ++		"movb $0,%1\n"
  28.452 ++		"2:"
  28.453 ++		".section __smp_alternatives,\"a\"\n"
  28.454 ++		".long 1b\n"
  28.455 ++		".long 3f\n"
  28.456 ++		".previous\n"
  28.457 ++		".section __smp_replacements,\"a\"\n"
  28.458 ++		"3: .byte 2b - 1b\n"
  28.459 ++		".byte 5f-4f\n"
  28.460 ++		".byte 0\n"
  28.461 ++		".byte 6f-5f\n"
  28.462 ++		".byte -1\n"
  28.463 ++		"4: xchgb %b0,%1\n"
  28.464 ++		"5: movb %1,%b0\n"
  28.465 ++		"movb $0,%1\n"
  28.466 ++		"6:\n"
  28.467 ++		".previous\n"
  28.468 + 		:"=q" (oldval), "=m" (lock->slock)
  28.469 + 		:"0" (0) : "memory");
  28.470 ++#else
  28.471 ++	__asm__ __volatile__(
  28.472 ++		"xchgb %b0,%1\n"
  28.473 ++		:"=q" (oldval), "=m" (lock->slock)
  28.474 ++		:"0" (0) : "memory");
  28.475 ++#endif
  28.476 + 	return oldval > 0;
  28.477 + }
  28.478 + 
  28.479 +@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
  28.480 + 
  28.481 + static inline void __raw_read_unlock(raw_rwlock_t *rw)
  28.482 + {
  28.483 +-	asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
  28.484 ++	asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
  28.485 + }
  28.486 + 
  28.487 + static inline void __raw_write_unlock(raw_rwlock_t *rw)
  28.488 + {
  28.489 +-	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
  28.490 ++	asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
  28.491 + 				 : "=m" (rw->lock) : : "memory");
  28.492 + }
  28.493 + 
  28.494 +diff -pruN ../pristine-linux-2.6.16-rc6/include/asm-i386/system.h ./include/asm-i386/system.h
  28.495 +--- ../pristine-linux-2.6.16-rc6/include/asm-i386/system.h	2006-03-17 22:59:05.000000000 +0000
  28.496 ++++ ./include/asm-i386/system.h	2006-03-17 23:04:23.000000000 +0000
  28.497 +@@ -5,7 +5,7 @@
  28.498 + #include <linux/kernel.h>
  28.499 + #include <asm/segment.h>
  28.500 + #include <asm/cpufeature.h>
  28.501 +-#include <linux/bitops.h> /* for LOCK_PREFIX */
  28.502 ++#include <asm/smp_alt.h>
  28.503 + 
  28.504 + #ifdef __KERNEL__
  28.505 + 
  28.506 +@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
  28.507 + 	unsigned long prev;
  28.508 + 	switch (size) {
  28.509 + 	case 1:
  28.510 +-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
  28.511 ++		__asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
  28.512 + 				     : "=a"(prev)
  28.513 + 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
  28.514 + 				     : "memory");
  28.515 + 		return prev;
  28.516 + 	case 2:
  28.517 +-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
  28.518 ++		__asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
  28.519 + 				     : "=a"(prev)
  28.520 + 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
  28.521 + 				     : "memory");
  28.522 + 		return prev;
  28.523 + 	case 4:
  28.524 +-		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
  28.525 ++		__asm__ __volatile__(LOCK "cmpxchgl %1,%2"
  28.526 + 				     : "=a"(prev)
  28.527 + 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
  28.528 + 				     : "memory");
  28.529 +@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
  28.530 + 				      unsigned long long new)
  28.531 + {
  28.532 + 	unsigned long long prev;
  28.533 +-	__asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
  28.534 ++	__asm__ __volatile__(LOCK "cmpxchg8b %3"
  28.535 + 			     : "=A"(prev)
  28.536 + 			     : "b"((unsigned long)new),
  28.537 + 			       "c"((unsigned long)(new >> 32)),
  28.538 +@@ -503,11 +503,55 @@ struct alt_instr { 
  28.539 + #endif
  28.540 + 
  28.541 + #ifdef CONFIG_SMP
  28.542 ++#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
  28.543 ++#define smp_alt_mb(instr)                                           \
  28.544 ++__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
  28.545 ++		     ".section __smp_alternatives,\"a\"\n"          \
  28.546 ++		     ".long 6667b\n"                                \
  28.547 ++                     ".long 6673f\n"                                \
  28.548 ++		     ".previous\n"                                  \
  28.549 ++		     ".section __smp_replacements,\"a\"\n"          \
  28.550 ++		     "6673:.byte 6668b-6667b\n"                     \
  28.551 ++		     ".byte 6670f-6669f\n"                          \
  28.552 ++		     ".byte 6671f-6670f\n"                          \
  28.553 ++                     ".byte 0\n"                                    \
  28.554 ++		     ".byte %c0\n"                                  \
  28.555 ++		     "6669:lock;addl $0,0(%%esp)\n"                 \
  28.556 ++		     "6670:" instr "\n"                             \
  28.557 ++		     "6671:\n"                                      \
  28.558 ++		     ".previous\n"                                  \
  28.559 ++		     :                                              \
  28.560 ++		     : "i" (X86_FEATURE_XMM2)                       \
  28.561 ++		     : "memory")
  28.562 ++#define smp_rmb() smp_alt_mb("lfence")
  28.563 ++#define smp_mb()  smp_alt_mb("mfence")
  28.564 ++#define set_mb(var, value) do {                                     \
  28.565 ++unsigned long __set_mb_temp;                                        \
  28.566 ++__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
  28.567 ++		     ".section __smp_alternatives,\"a\"\n"          \
  28.568 ++		     ".long 6667b\n"                                \
  28.569 ++		     ".long 6673f\n"                                \
  28.570 ++		     ".previous\n"                                  \
  28.571 ++		     ".section __smp_replacements,\"a\"\n"          \
  28.572 ++		     "6673: .byte 6668b-6667b\n"                    \
  28.573 ++		     ".byte 6670f-6669f\n"                          \
  28.574 ++		     ".byte 0\n"                                    \
  28.575 ++		     ".byte 6671f-6670f\n"                          \
  28.576 ++		     ".byte -1\n"                                   \
  28.577 ++		     "6669: xchg %1, %0\n"                          \
  28.578 ++		     "6670:movl %1, %0\n"                           \
  28.579 ++		     "6671:\n"                                      \
  28.580 ++		     ".previous\n"                                  \
  28.581 ++		     : "=m" (var), "=r" (__set_mb_temp)             \
  28.582 ++		     : "1" (value)                                  \
  28.583 ++		     : "memory"); } while (0)
  28.584 ++#else
  28.585 + #define smp_mb()	mb()
  28.586 + #define smp_rmb()	rmb()
  28.587 ++#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  28.588 ++#endif
  28.589 + #define smp_wmb()	wmb()
  28.590 + #define smp_read_barrier_depends()	read_barrier_depends()
  28.591 +-#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  28.592 + #else
  28.593 + #define smp_mb()	barrier()
  28.594 + #define smp_rmb()	barrier()
    29.1 --- a/tools/examples/xmexample.vti	Mon Mar 20 09:56:46 2006 +0100
    29.2 +++ b/tools/examples/xmexample.vti	Mon Mar 20 09:56:54 2006 +0100
    29.3 @@ -14,8 +14,8 @@ arch_libdir = 'lib'
    29.4  # Kernel image file.
    29.5  kernel = "/boot/Flash.fd"
    29.6  
    29.7 -# The domain build function. VMX domain uses 'vmx'.
    29.8 -builder='vmx'
    29.9 +# The domain build function. VTI domain uses 'hvm'.
   29.10 +builder='hvm'
   29.11  
   29.12  # Initial memory allocation (in megabytes) for the new domain.
   29.13  memory = 256
    30.1 --- a/tools/firmware/rombios/apmbios.S	Mon Mar 20 09:56:46 2006 +0100
    30.2 +++ b/tools/firmware/rombios/apmbios.S	Mon Mar 20 09:56:54 2006 +0100
    30.3 @@ -217,14 +217,22 @@ APMSYM(03):
    30.4  ; APM interface disconnect
    30.5  APMSYM(04):
    30.6    cmp al, #0x04
    30.7 +  jne APMSYM(05)
    30.8 +  jmp APMSYM(ok)
    30.9 +
   30.10 +;-----------------
   30.11 +; APM cpu idle
   30.12 +APMSYM(05):
   30.13 +  cmp al, #0x05
   30.14    jne APMSYM(07)
   30.15 +  hlt
   30.16    jmp APMSYM(ok)
   30.17  
   30.18  ;-----------------
   30.19  ; APM Set Power State
   30.20  APMSYM(07):
   30.21    cmp al, #0x07
   30.22 -  jne APMSYM(0a)
   30.23 +  jne APMSYM(08)
   30.24    
   30.25    cmp bx, #1
   30.26    jne APMSYM(ok)
   30.27 @@ -268,6 +276,14 @@ APMSYM(07_standby):
   30.28    jmp APMSYM(ok)
   30.29  
   30.30  ;-----------------
   30.31 +; APM Enable / Disable
   30.32 +APMSYM(08):
   30.33 +  cmp al, #0x08
   30.34 +  jne APMSYM(0a)
   30.35 +
   30.36 +  jmp APMSYM(ok)
   30.37 +
   30.38 +;-----------------
   30.39  ; Get Power Status
   30.40  APMSYM(0a):
   30.41    cmp al, #0x0a
   30.42 @@ -297,7 +313,7 @@ APMSYM(0b):
   30.43  ; APM Driver Version
   30.44  APMSYM(0e):
   30.45    cmp al, #0x0e
   30.46 -  jne APMSYM(unimplemented)
   30.47 +  jne APMSYM(0f)
   30.48    
   30.49    mov ah, #1
   30.50    mov al, #2
   30.51 @@ -305,6 +321,25 @@ APMSYM(0e):
   30.52    jmp APMSYM(ok)
   30.53  
   30.54  ;-----------------
   30.55 +; APM Engage / Disengage
   30.56 +APMSYM(0f):
   30.57 +  cmp al, #0x0f
   30.58 +  jne APMSYM(10)
   30.59 +
   30.60 +  jmp APMSYM(ok)
   30.61 +
   30.62 +;-----------------
   30.63 +; APM Get Capabilities
   30.64 +APMSYM(10):
   30.65 +  cmp al, #0x10
   30.66 +  jne APMSYM(unimplemented)
   30.67 +
   30.68 +  mov bl, #0
   30.69 +  mov cx, #0
   30.70 +
   30.71 +  jmp APMSYM(ok)
   30.72 +
   30.73 +;-----------------
   30.74  APMSYM(ok):
   30.75    popf
   30.76    clc
    31.1 --- a/tools/firmware/rombios/rombios.c	Mon Mar 20 09:56:46 2006 +0100
    31.2 +++ b/tools/firmware/rombios/rombios.c	Mon Mar 20 09:56:54 2006 +0100
    31.3 @@ -149,7 +149,7 @@
    31.4  #define BX_SUPPORT_FLOPPY 1
    31.5  #define BX_FLOPPY_ON_CNT 37   /* 2 seconds */
    31.6  #define BX_PCIBIOS       1
    31.7 -#define BX_APM           0
    31.8 +#define BX_APM           1
    31.9  
   31.10  #define BX_USE_ATADRV    1
   31.11  #define BX_ELTORITO_BOOT 1
    32.1 --- a/tools/libxc/xc_hvm_build.c	Mon Mar 20 09:56:46 2006 +0100
    32.2 +++ b/tools/libxc/xc_hvm_build.c	Mon Mar 20 09:56:54 2006 +0100
    32.3 @@ -51,7 +51,7 @@ loadelfimage(
    32.4      char *elfbase, int xch, uint32_t dom, unsigned long *parray,
    32.5      struct domain_setup_info *dsi);
    32.6  
    32.7 -static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
    32.8 +static unsigned char build_e820map(void *e820_page, unsigned long long mem_size)
    32.9  {
   32.10      struct e820entry *e820entry =
   32.11          (struct e820entry *)(((unsigned char *)e820_page) + E820_MAP_OFFSET);
   32.12 @@ -81,24 +81,24 @@ static unsigned char build_e820map(void 
   32.13  #define STATIC_PAGES    2       /* for ioreq_t and store_mfn */
   32.14      /* Most of the ram goes here */
   32.15      e820entry[nr_map].addr = 0x100000;
   32.16 -    e820entry[nr_map].size = mem_size - 0x100000 - STATIC_PAGES*PAGE_SIZE;
   32.17 +    e820entry[nr_map].size = mem_size - 0x100000 - STATIC_PAGES * PAGE_SIZE;
   32.18      e820entry[nr_map].type = E820_RAM;
   32.19      nr_map++;
   32.20  
   32.21      /* Statically allocated special pages */
   32.22  
   32.23 +    /* For xenstore */
   32.24 +    e820entry[nr_map].addr = mem_size - 2 * PAGE_SIZE;
   32.25 +    e820entry[nr_map].size = PAGE_SIZE;
   32.26 +    e820entry[nr_map].type = E820_XENSTORE;
   32.27 +    nr_map++;
   32.28 +
   32.29      /* Shared ioreq_t page */
   32.30      e820entry[nr_map].addr = mem_size - PAGE_SIZE;
   32.31      e820entry[nr_map].size = PAGE_SIZE;
   32.32      e820entry[nr_map].type = E820_SHARED_PAGE;
   32.33      nr_map++;
   32.34  
   32.35 -    /* For xenstore */
   32.36 -    e820entry[nr_map].addr = mem_size - 2*PAGE_SIZE;
   32.37 -    e820entry[nr_map].size = PAGE_SIZE;
   32.38 -    e820entry[nr_map].type = E820_XENSTORE;
   32.39 -    nr_map++;
   32.40 -
   32.41      e820entry[nr_map].addr = mem_size;
   32.42      e820entry[nr_map].size = 0x3 * PAGE_SIZE;
   32.43      e820entry[nr_map].type = E820_NVS;
   32.44 @@ -117,8 +117,7 @@ static unsigned char build_e820map(void 
   32.45      return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
   32.46  }
   32.47  
   32.48 -static void
   32.49 -set_hvm_info_checksum(struct hvm_info_table *t)
   32.50 +static void set_hvm_info_checksum(struct hvm_info_table *t)
   32.51  {
   32.52      uint8_t *ptr = (uint8_t *)t, sum = 0;
   32.53      unsigned int i;
   32.54 @@ -142,19 +141,16 @@ static int set_hvm_info(int xc_handle, u
   32.55      char *va_map;
   32.56      struct hvm_info_table *va_hvm;
   32.57  
   32.58 -
   32.59 -    va_map = xc_map_foreign_range(
   32.60 -        xc_handle,
   32.61 -        dom,
   32.62 -        PAGE_SIZE,
   32.63 -        PROT_READ|PROT_WRITE,
   32.64 -        pfn_list[HVM_INFO_PFN]);
   32.65 +    va_map = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   32.66 +                                  PROT_READ | PROT_WRITE,
   32.67 +                                  pfn_list[HVM_INFO_PFN]);
   32.68  
   32.69      if ( va_map == NULL )
   32.70          return -1;
   32.71  
   32.72      va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
   32.73      memset(va_hvm, 0, sizeof(*va_hvm));
   32.74 +
   32.75      strncpy(va_hvm->signature, "HVM INFO", 8);
   32.76      va_hvm->length       = sizeof(struct hvm_info_table);
   32.77      va_hvm->acpi_enabled = acpi;
   32.78 @@ -183,58 +179,59 @@ static int setup_guest(int xc_handle,
   32.79                         unsigned long *store_mfn)
   32.80  {
   32.81      unsigned long *page_array = NULL;
   32.82 +    unsigned long count, i;
   32.83 +    unsigned long long ptr;
   32.84 +    xc_mmu_t *mmu = NULL;
   32.85  
   32.86 -    unsigned long count, i;
   32.87      shared_info_t *shared_info;
   32.88      void *e820_page;
   32.89      unsigned char e820_map_nr;
   32.90 -    xc_mmu_t *mmu = NULL;
   32.91 -    int rc;
   32.92  
   32.93      struct domain_setup_info dsi;
   32.94 -    unsigned long v_end;
   32.95 +    unsigned long long v_end;
   32.96  
   32.97      unsigned long shared_page_frame = 0;
   32.98      shared_iopage_t *sp;
   32.99  
  32.100      memset(&dsi, 0, sizeof(struct domain_setup_info));
  32.101  
  32.102 -    if ( (rc = parseelfimage(image, image_size, &dsi)) != 0 )
  32.103 +    if ( (parseelfimage(image, image_size, &dsi)) != 0 )
  32.104          goto error_out;
  32.105  
  32.106 -    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
  32.107 +    if ( (dsi.v_kernstart & (PAGE_SIZE - 1)) != 0 )
  32.108      {
  32.109          PERROR("Guest OS must load to a page boundary.\n");
  32.110          goto error_out;
  32.111      }
  32.112  
  32.113      /* memsize is in megabytes */
  32.114 -    v_end              = (unsigned long)memsize << 20;
  32.115 +    v_end = (unsigned long long)memsize << 20;
  32.116  
  32.117      printf("VIRTUAL MEMORY ARRANGEMENT:\n"
  32.118 -           " Loaded HVM loader: %08lx->%08lx\n"
  32.119 -           " TOTAL:         %08lx->%08lx\n",
  32.120 +           "  Loaded HVM loader:    %08lx->%08lx\n"
  32.121 +           "  TOTAL:                %08lx->%016llx\n",
  32.122             dsi.v_kernstart, dsi.v_kernend,
  32.123             dsi.v_start, v_end);
  32.124 -    printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
  32.125 +    printf("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
  32.126  
  32.127 -    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
  32.128 +    if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
  32.129      {
  32.130 -        ERROR("Initial guest OS requires too much space\n"
  32.131 -               "(%luMB is greater than %luMB limit)\n",
  32.132 -               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
  32.133 +        PERROR("Initial guest OS requires too much space: "
  32.134 +               "(%lluMB is greater than %lluMB limit)\n",
  32.135 +               (unsigned long long)(v_end - dsi.v_start) >> 20,
  32.136 +               ((unsigned long long)nr_pages << PAGE_SHIFT) >> 20);
  32.137          goto error_out;
  32.138      }
  32.139  
  32.140      if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
  32.141      {
  32.142 -        PERROR("Could not allocate memory");
  32.143 +        PERROR("Could not allocate memory.\n");
  32.144          goto error_out;
  32.145      }
  32.146  
  32.147      if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
  32.148      {
  32.149 -        PERROR("Could not get the page frame list");
  32.150 +        PERROR("Could not get the page frame list.\n");
  32.151          goto error_out;
  32.152      }
  32.153  
  32.154 @@ -246,20 +243,21 @@ static int setup_guest(int xc_handle,
  32.155      /* Write the machine->phys table entries. */
  32.156      for ( count = 0; count < nr_pages; count++ )
  32.157      {
  32.158 +        ptr = (unsigned long long)page_array[count] << PAGE_SHIFT;
  32.159          if ( xc_add_mmu_update(xc_handle, mmu,
  32.160 -                               (page_array[count] << PAGE_SHIFT) |
  32.161 -                               MMU_MACHPHYS_UPDATE, count) )
  32.162 +                               ptr | MMU_MACHPHYS_UPDATE, count) )
  32.163              goto error_out;
  32.164      }
  32.165  
  32.166 -    if ( set_hvm_info(xc_handle, dom, page_array, vcpus, pae, acpi, apic) ) {
  32.167 -        fprintf(stderr, "Couldn't set hvm info for HVM guest.\n");
  32.168 +    if ( set_hvm_info(xc_handle, dom, page_array, vcpus, pae, acpi, apic) )
  32.169 +    {
  32.170 +        ERROR("Couldn't set hvm info for HVM guest.\n");
  32.171          goto error_out;
  32.172      }
  32.173  
  32.174      if ( (e820_page = xc_map_foreign_range(
  32.175 -         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  32.176 -         page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 )
  32.177 +              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
  32.178 +              page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 )
  32.179          goto error_out;
  32.180      memset(e820_page, 0, PAGE_SIZE);
  32.181      e820_map_nr = build_e820map(e820_page, v_end);
  32.182 @@ -267,8 +265,8 @@ static int setup_guest(int xc_handle,
  32.183  
  32.184      /* shared_info page starts its life empty. */
  32.185      if ( (shared_info = xc_map_foreign_range(
  32.186 -         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  32.187 -         shared_info_frame)) == 0 )
  32.188 +              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
  32.189 +              shared_info_frame)) == 0 )
  32.190          goto error_out;
  32.191      memset(shared_info, 0, sizeof(shared_info_t));
  32.192      /* Mask all upcalls... */
  32.193 @@ -279,8 +277,8 @@ static int setup_guest(int xc_handle,
  32.194      /* Populate the event channel port in the shared page */
  32.195      shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
  32.196      if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
  32.197 -         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  32.198 -         shared_page_frame)) == 0 )
  32.199 +              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
  32.200 +              shared_page_frame)) == 0 )
  32.201          goto error_out;
  32.202      memset(sp, 0, PAGE_SIZE);
  32.203  
  32.204 @@ -290,7 +288,7 @@ static int setup_guest(int xc_handle,
  32.205  
  32.206          vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
  32.207          if ( vp_eport < 0 ) {
  32.208 -            fprintf(stderr, "Couldn't get unbound port from VMX guest.\n");
  32.209 +            PERROR("Couldn't get unbound port from VMX guest.\n");
  32.210              goto error_out;
  32.211          }
  32.212          sp->vcpu_iodata[i].vp_eport = vp_eport;
    33.1 --- a/tools/libxc/xc_linux_build.c	Mon Mar 20 09:56:46 2006 +0100
    33.2 +++ b/tools/libxc/xc_linux_build.c	Mon Mar 20 09:56:54 2006 +0100
    33.3 @@ -536,8 +536,12 @@ static int setup_guest(int xc_handle,
    33.4  
    33.5      *store_mfn = page_array[1];
    33.6      *console_mfn = page_array[2];
    33.7 -    printf("store_mfn: 0x%lx, console_mfn: 0x%lx\n",
    33.8 -           (uint64_t)store_mfn, (uint64_t)console_mfn);
    33.9 +    printf("start_info: 0x%lx at 0x%lx, "
   33.10 +           "store_mfn: 0x%lx at 0x%lx, "
   33.11 +           "console_mfn: 0x%lx at 0x%lx\n",
   33.12 +           page_array[0], nr_pages,
   33.13 +           *store_mfn,    nr_pages - 2,
   33.14 +           *console_mfn,  nr_pages - 1);
   33.15  
   33.16      start_info = xc_map_foreign_range(
   33.17          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]);
    34.1 --- a/xen/Makefile	Mon Mar 20 09:56:46 2006 +0100
    34.2 +++ b/xen/Makefile	Mon Mar 20 09:56:54 2006 +0100
    34.3 @@ -61,6 +61,7 @@ ifeq ($(ACM_SECURITY),y)
    34.4  	$(MAKE) -C acm
    34.5  endif
    34.6  	$(MAKE) -C arch/$(TARGET_ARCH)
    34.7 +	$(MAKE) -C arch/$(TARGET_ARCH) $(TARGET)
    34.8  
    34.9  # drivers/char/console.o contains static banner/compile info. Blow it away.
   34.10  # Don't refresh these files during e.g., 'sudo make install'
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/xen/Post.mk	Mon Mar 20 09:56:54 2006 +0100
    35.3 @@ -0,0 +1,18 @@
    35.4 +
    35.5 +subdirs-all := $(subdirs-y) $(subdirs-n)
    35.6 +
    35.7 +obj-y += $(patsubst %,%/built_in.o,$(subdirs-y))
    35.8 +
    35.9 +built_in.o: $(obj-y)
   35.10 +	$(LD) $(LDFLAGS) -r -o $@ $^
   35.11 +
   35.12 +.PHONY: FORCE
   35.13 +FORCE:
   35.14 +
   35.15 +%/built_in.o: FORCE
   35.16 +	$(MAKE) -C $*
   35.17 +
   35.18 +clean:: $(addprefix _clean_, $(subdirs-all)) FORCE
   35.19 +	rm -f *.o *~ core
   35.20 +_clean_%/: FORCE
   35.21 +	$(MAKE) -C $* clean
    36.1 --- a/xen/Rules.mk	Mon Mar 20 09:56:46 2006 +0100
    36.2 +++ b/xen/Rules.mk	Mon Mar 20 09:56:54 2006 +0100
    36.3 @@ -8,6 +8,15 @@ perfc       ?= n
    36.4  perfc_arrays?= n
    36.5  crash_debug ?= n
    36.6  
    36.7 +# Hardcoded configuration implications and dependencies.
    36.8 +# Do this is a neater way if it becomes unwieldy.
    36.9 +ifeq ($(debug),y)
   36.10 +verbose := y
   36.11 +endif
   36.12 +ifeq ($(perfc_arrays),y)
   36.13 +perfc := y
   36.14 +endif
   36.15 +
   36.16  XEN_ROOT=$(BASEDIR)/..
   36.17  include $(XEN_ROOT)/Config.mk
   36.18  
   36.19 @@ -27,41 +36,23 @@ HDRS    := $(subst $(BASEDIR)/include/as
   36.20  HDRS    := $(subst $(BASEDIR)/include/xen/banner.h,,$(HDRS))
   36.21  HDRS    := $(subst $(BASEDIR)/include/xen/compile.h,,$(HDRS))
   36.22  
   36.23 -C_SRCS  := $(wildcard *.c)
   36.24 -S_SRCS  := $(wildcard *.S)
   36.25 -OBJS    := $(patsubst %.S,%.o,$(S_SRCS))
   36.26 -OBJS    += $(patsubst %.c,%.o,$(C_SRCS))
   36.27 -
   36.28 -# Note that link order matters!
   36.29 -ALL_OBJS := $(BASEDIR)/common/common.o
   36.30 -ALL_OBJS += $(BASEDIR)/drivers/char/driver.o
   36.31 -ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o
   36.32 -ifeq ($(ACM_SECURITY),y)
   36.33 -ALL_OBJS += $(BASEDIR)/acm/acm.o
   36.34 -CFLAGS += -DACM_SECURITY
   36.35 -endif
   36.36 -ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o
   36.37 -
   36.38  include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk
   36.39  
   36.40 -CFLAGS += -g -D__XEN__
   36.41 -
   36.42 -ifneq ($(debug)$(verbose),nn)
   36.43 -CFLAGS += -DVERBOSE
   36.44 -endif
   36.45 +# Note that link order matters!
   36.46 +ALL_OBJS-y               += $(BASEDIR)/common/built_in.o
   36.47 +ALL_OBJS-y               += $(BASEDIR)/drivers/built_in.o
   36.48 +ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o
   36.49 +ALL_OBJS-y               += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o
   36.50  
   36.51 -ifeq ($(crash_debug),y)
   36.52 -CFLAGS += -DCRASH_DEBUG
   36.53 -endif
   36.54 +CFLAGS-y               += -g -D__XEN__
   36.55 +CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY
   36.56 +CFLAGS-$(verbose)      += -DVERBOSE
   36.57 +CFLAGS-$(crash_debug)  += -DCRASH_DEBUG
   36.58 +CFLAGS-$(perfc)        += -DPERF_COUNTERS
   36.59 +CFLAGS-$(perfc_arrays) += -DPERF_ARRAYS
   36.60  
   36.61 -ifeq ($(perfc),y)
   36.62 -CFLAGS += -DPERF_COUNTERS
   36.63 -ifeq ($(perfc_arrays),y)
   36.64 -CFLAGS += -DPERF_ARRAYS
   36.65 -endif
   36.66 -endif
   36.67 -
   36.68 -CFLAGS := $(strip $(CFLAGS))
   36.69 +ALL_OBJS := $(ALL_OBJS-y)
   36.70 +CFLAGS   := $(strip $(CFLAGS) $(CFLAGS-y))
   36.71  
   36.72  %.o: %.c $(HDRS) Makefile
   36.73  	$(CC) $(CFLAGS) -c $< -o $@
    37.1 --- a/xen/acm/Makefile	Mon Mar 20 09:56:46 2006 +0100
    37.2 +++ b/xen/acm/Makefile	Mon Mar 20 09:56:54 2006 +0100
    37.3 @@ -1,15 +1,9 @@
    37.4 -
    37.5  include $(BASEDIR)/Rules.mk
    37.6 -OBJS =  acm_core.o 
    37.7 -OBJS += acm_policy.o
    37.8 -OBJS += acm_simple_type_enforcement_hooks.o
    37.9 -OBJS += acm_chinesewall_hooks.o
   37.10 -OBJS += acm_null_hooks.o
   37.11  
   37.12 -default: acm.o
   37.13 +obj-y += acm_core.o 
   37.14 +obj-y += acm_policy.o
   37.15 +obj-y += acm_simple_type_enforcement_hooks.o
   37.16 +obj-y += acm_chinesewall_hooks.o
   37.17 +obj-y += acm_null_hooks.o
   37.18  
   37.19 -acm.o: $(OBJS)
   37.20 -	$(LD) $(LDFLAGS) -r -o acm.o $(OBJS)
   37.21 -
   37.22 -clean:
   37.23 -	rm -f *.o *~ core
   37.24 +include $(BASEDIR)/Post.mk
    38.1 --- a/xen/arch/ia64/Rules.mk	Mon Mar 20 09:56:46 2006 +0100
    38.2 +++ b/xen/arch/ia64/Rules.mk	Mon Mar 20 09:56:54 2006 +0100
    38.3 @@ -1,11 +1,13 @@
    38.4  ########################################
    38.5  # ia64-specific definitions
    38.6  
    38.7 +HAS_ACPI := y
    38.8  VALIDATE_VT	?= n
    38.9  ifneq ($(COMPILE_ARCH),$(TARGET_ARCH))
   38.10  CROSS_COMPILE ?= /usr/local/sp_env/v2.2.5/i686/bin/ia64-unknown-linux-
   38.11  endif
   38.12 -AFLAGS  += -D__ASSEMBLY__
   38.13 +AFLAGS  += -D__ASSEMBLY__ -nostdinc $(CPPFLAGS)
   38.14 +AFLAGS  += -mconstant-gp
   38.15  CPPFLAGS  += -I$(BASEDIR)/include -I$(BASEDIR)/include/asm-ia64 	\
   38.16               -I$(BASEDIR)/include/asm-ia64/linux 			\
   38.17  	     -I$(BASEDIR)/include/asm-ia64/linux-xen 			\
   38.18 @@ -13,6 +15,7 @@ CPPFLAGS  += -I$(BASEDIR)/include -I$(BA
   38.19               -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
   38.20  
   38.21  CFLAGS  += -nostdinc -fno-builtin -fno-common -fno-strict-aliasing
   38.22 +CFLAGS  += -mconstant-gp
   38.23  #CFLAGS  += -O3		# -O3 over-inlines making debugging tough!
   38.24  CFLAGS  += -O2		# but no optimization causes compile errors!
   38.25  #CFLAGS  += -iwithprefix include -Wall -DMONITOR_BASE=$(MONITOR_BASE)
    39.1 --- a/xen/arch/ia64/asm-offsets.c	Mon Mar 20 09:56:46 2006 +0100
    39.2 +++ b/xen/arch/ia64/asm-offsets.c	Mon Mar 20 09:56:54 2006 +0100
    39.3 @@ -84,7 +84,6 @@ void foo(void)
    39.4  	//DEFINE(IA64_TASK_SIGHAND_OFFSET,offsetof (struct task_struct, sighand));
    39.5  	//DEFINE(IA64_TASK_SIGNAL_OFFSET,offsetof (struct task_struct, signal));
    39.6  	//DEFINE(IA64_TASK_TGID_OFFSET, offsetof (struct task_struct, tgid));
    39.7 -	DEFINE(IA64_PGD, offsetof(struct domain, arch.mm));
    39.8  	DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct vcpu, arch._thread.ksp));
    39.9  	DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, arch._thread.on_ustack));
   39.10  
    40.1 --- a/xen/arch/ia64/linux-xen/efi.c	Mon Mar 20 09:56:46 2006 +0100
    40.2 +++ b/xen/arch/ia64/linux-xen/efi.c	Mon Mar 20 09:56:54 2006 +0100
    40.3 @@ -37,11 +37,17 @@
    40.4  #define EFI_DEBUG	0
    40.5  
    40.6  extern efi_status_t efi_call_phys (void *, ...);
    40.7 +extern unsigned long long memparse (char *ptr, char **retptr);
    40.8  
    40.9  struct efi efi;
   40.10  EXPORT_SYMBOL(efi);
   40.11  static efi_runtime_services_t *runtime;
   40.12 +#ifdef XEN
   40.13 +// this is a temporary hack to avoid CONFIG_VIRTUAL_MEM_MAP
   40.14 +static unsigned long mem_limit = ~0UL, max_addr = 0x100000000;
   40.15 +#else
   40.16  static unsigned long mem_limit = ~0UL, max_addr = ~0UL;
   40.17 +#endif
   40.18  
   40.19  #define efi_call_virt(f, args...)	(*(f))(args)
   40.20  
   40.21 @@ -328,8 +334,6 @@ efi_memmap_walk (efi_freemem_callback_t 
   40.22  		if (running_on_sim && md->type != EFI_CONVENTIONAL_MEMORY)
   40.23  			continue;
   40.24  }
   40.25 -// this is a temporary hack to avoid CONFIG_VIRTUAL_MEM_MAP
   40.26 -		if (md->phys_addr >= 0x100000000) continue;
   40.27  #endif
   40.28  		/*
   40.29  		 * granule_addr is the base of md's first granule.
    41.1 --- a/xen/arch/ia64/linux-xen/setup.c	Mon Mar 20 09:56:46 2006 +0100
    41.2 +++ b/xen/arch/ia64/linux-xen/setup.c	Mon Mar 20 09:56:54 2006 +0100
    41.3 @@ -384,6 +384,9 @@ setup_arch (char **cmdline_p)
    41.4  	*cmdline_p = __va(ia64_boot_param->command_line);
    41.5  #ifndef XEN
    41.6  	strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
    41.7 +#else
    41.8 +	early_cmdline_parse(cmdline_p);
    41.9 +	cmdline_parse(*cmdline_p);
   41.10  #endif
   41.11  
   41.12  	efi_init();
   41.13 @@ -414,10 +417,6 @@ setup_arch (char **cmdline_p)
   41.14  	}
   41.15  #endif
   41.16  
   41.17 -#ifdef XEN
   41.18 -	early_cmdline_parse(cmdline_p);
   41.19 -	cmdline_parse(*cmdline_p);
   41.20 -#endif
   41.21  	if (early_console_setup(*cmdline_p) == 0)
   41.22  		mark_bsp_online();
   41.23  
   41.24 @@ -842,7 +841,9 @@ cpu_init (void)
   41.25  					| IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
   41.26  #endif
   41.27  	atomic_inc(&init_mm.mm_count);
   41.28 +#ifndef XEN
   41.29  	current->active_mm = &init_mm;
   41.30 +#endif
   41.31  #ifdef XEN
   41.32  	if (current->domain->arch.mm)
   41.33  #else
    42.1 --- a/xen/arch/ia64/linux-xen/smp.c	Mon Mar 20 09:56:46 2006 +0100
    42.2 +++ b/xen/arch/ia64/linux-xen/smp.c	Mon Mar 20 09:56:54 2006 +0100
    42.3 @@ -296,7 +296,12 @@ smp_flush_tlb_mm (struct mm_struct *mm)
    42.4  {
    42.5  	preempt_disable();
    42.6  	/* this happens for the common case of a single-threaded fork():  */
    42.7 +#ifdef XEN
    42.8 +	if (likely(mm == current->domain->arch.mm
    42.9 +		   && atomic_read(&mm->mm_users) == 1))
   42.10 +#else
   42.11  	if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
   42.12 +#endif
   42.13  	{
   42.14  		local_finish_flush_tlb_mm(mm);
   42.15  		preempt_enable();
    43.1 --- a/xen/arch/ia64/linux-xen/smpboot.c	Mon Mar 20 09:56:46 2006 +0100
    43.2 +++ b/xen/arch/ia64/linux-xen/smpboot.c	Mon Mar 20 09:56:54 2006 +0100
    43.3 @@ -72,8 +72,7 @@ EXPORT_SYMBOL(cpu_online_map);
    43.4  
    43.5  #ifdef CONFIG_SMP /* ifdef XEN */
    43.6  
    43.7 -//#define SMP_DEBUG 0
    43.8 -#define SMP_DEBUG 1
    43.9 +#define SMP_DEBUG 0
   43.10  
   43.11  #if SMP_DEBUG
   43.12  #define Dprintk(x...)  printk(x)
   43.13 @@ -482,16 +481,14 @@ do_boot_cpu (int sapicid, int cpu)
   43.14  do_rest:
   43.15  	task_for_booting_cpu = c_idle.idle;
   43.16  #else
   43.17 -	struct domain *idle;
   43.18  	struct vcpu *v;
   43.19 -	void *stack;
   43.20  
   43.21  	v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
   43.22  	BUG_ON(v == NULL);
   43.23  
   43.24 -	printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
   43.25 +	//printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
   43.26  
   43.27 -	task_for_booting_cpu = v;
   43.28 +	task_for_booting_cpu = (task_t *)v;
   43.29  
   43.30  	/* Set cpu number.  */
   43.31  	get_thread_info(v)->cpu = cpu;
   43.32 @@ -522,6 +519,7 @@ do_rest:
   43.33  	return 0;
   43.34  }
   43.35  
   43.36 +#ifndef XEN
   43.37  static int __init
   43.38  decay (char *str)
   43.39  {
   43.40 @@ -531,6 +529,7 @@ decay (char *str)
   43.41  }
   43.42  
   43.43  __setup("decay=", decay);
   43.44 +#endif
   43.45  
   43.46  /*
   43.47   * Initialize the logical CPU number to SAPICID mapping
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/xen/arch/ia64/tools/privop/Makefile	Mon Mar 20 09:56:54 2006 +0100
    44.3 @@ -0,0 +1,11 @@
    44.4 +CC=gcc
    44.5 +CFLAGS=-O -Wall
    44.6 +
    44.7 +all: postat
    44.8 +
    44.9 +postat: postat.c pohcalls.o
   44.10 +
   44.11 +clean:
   44.12 +	$(RM) -f *.o postat *.s *~
   44.13 +
   44.14 +
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/xen/arch/ia64/tools/privop/pohcalls.S	Mon Mar 20 09:56:54 2006 +0100
    45.3 @@ -0,0 +1,30 @@
    45.4 +	.file	"hypercall.S"
    45.5 +	.pred.safe_across_calls p1-p5,p16-p63
    45.6 +	.text
    45.7 +	.align 16
    45.8 +	.global dump_privop_counts#
    45.9 +	.proc dump_privop_counts#
   45.10 +dump_privop_counts:
   45.11 +	.prologue
   45.12 +	.body
   45.13 +	mov r2 = 0xffff
   45.14 +	;;
   45.15 +	break 0x1000
   45.16 +	;; 
   45.17 +	br.ret.sptk.many b0
   45.18 +	;;
   45.19 +	.endp dump_privop_counts#
   45.20 +	.align 16
   45.21 +	.global zero_privop_counts#
   45.22 +	.proc zero_privop_counts#
   45.23 +zero_privop_counts:
   45.24 +	.prologue
   45.25 +	.body
   45.26 +	mov r2 = 0xfffe
   45.27 +	;;
   45.28 +	break 0x1000
   45.29 +	;; 
   45.30 +	br.ret.sptk.many b0
   45.31 +	;;
   45.32 +	.endp zero_privop_counts#
   45.33 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/xen/arch/ia64/tools/privop/postat.c	Mon Mar 20 09:56:54 2006 +0100
    46.3 @@ -0,0 +1,27 @@
    46.4 +#include <stdio.h>
    46.5 +#include <string.h>
    46.6 +
    46.7 +extern int dump_privop_counts (char *buf, int len);
    46.8 +
    46.9 +extern int zero_privop_counts (char *buf, int len);
   46.10 +
   46.11 +int
   46.12 +main (int argc, char *argv[])
   46.13 +{
   46.14 +  static char buf[8192];
   46.15 +  int res;
   46.16 +
   46.17 +  if (argc == 1)
   46.18 +    res = dump_privop_counts (buf, sizeof (buf));
   46.19 +  else if (argc == 2 && strcmp (argv[1], "--clear") == 0)
   46.20 +    res = zero_privop_counts (buf, sizeof (buf));
   46.21 +  else
   46.22 +    {
   46.23 +      printf ("usage: %s [--clear]\n", argv[0]);
   46.24 +      return 1;
   46.25 +    }
   46.26 +  printf ("res=%d\n", res);
   46.27 +  fputs (buf, stdout);
   46.28 +
   46.29 +  return 0;
   46.30 +}
    47.1 --- a/xen/arch/ia64/vmx/mmio.c	Mon Mar 20 09:56:46 2006 +0100
    47.2 +++ b/xen/arch/ia64/vmx/mmio.c	Mon Mar 20 09:56:54 2006 +0100
    47.3 @@ -33,6 +33,7 @@
    47.4  #include <asm/mm.h>
    47.5  #include <asm/vmx.h>
    47.6  #include <public/event_channel.h>
    47.7 +#include <linux/event.h>
    47.8  
    47.9  /*
   47.10  struct mmio_list *lookup_mmio(u64 gpa, struct mmio_list *mio_base)
    48.1 --- a/xen/arch/ia64/vmx/pal_emul.c	Mon Mar 20 09:56:46 2006 +0100
    48.2 +++ b/xen/arch/ia64/vmx/pal_emul.c	Mon Mar 20 09:56:54 2006 +0100
    48.3 @@ -20,6 +20,7 @@
    48.4  
    48.5  #include <asm/vmx_vcpu.h>
    48.6  #include <asm/pal.h>
    48.7 +#include <asm/sal.h>
    48.8  
    48.9  static void
   48.10  get_pal_parameters (VCPU *vcpu, UINT64 *gr29,
   48.11 @@ -68,7 +69,6 @@ pal_cache_flush (VCPU *vcpu) {
   48.12  
   48.13  static struct ia64_pal_retval
   48.14  pal_vm_tr_read (VCPU *vcpu ) {
   48.15 -#warning pal_vm_tr_read: to be implemented
   48.16  	struct ia64_pal_retval result;
   48.17  
   48.18  	result.status= -1; //unimplemented
   48.19 @@ -101,7 +101,6 @@ pal_platform_addr(VCPU *vcpu) {
   48.20  
   48.21  static struct ia64_pal_retval
   48.22  pal_halt (VCPU *vcpu) {
   48.23 -#warning pal_halt: to be implemented
   48.24  	//bugbug: to be implement. 
   48.25  	struct ia64_pal_retval result;
   48.26  
   48.27 @@ -140,12 +139,18 @@ pal_cache_write (VCPU *vcpu) {
   48.28  
   48.29  static struct ia64_pal_retval
   48.30  pal_bus_get_features(VCPU *vcpu){
   48.31 -	
   48.32 +	struct ia64_pal_retval result;
   48.33 +
   48.34 +	result.status= -1; //unimplemented
   48.35 +	return result;
   48.36  }
   48.37  
   48.38  static struct ia64_pal_retval
   48.39  pal_cache_summary(VCPU *vcpu){
   48.40 -	
   48.41 +	struct ia64_pal_retval result;
   48.42 +
   48.43 +	result.status= -1; //unimplemented
   48.44 +	return result;
   48.45  }
   48.46  
   48.47  static struct ia64_pal_retval
   48.48 @@ -157,22 +162,34 @@ pal_cache_init(VCPU *vcpu){
   48.49  
   48.50  static struct ia64_pal_retval
   48.51  pal_cache_info(VCPU *vcpu){
   48.52 +	struct ia64_pal_retval result;
   48.53 +
   48.54 +	result.status= -1; //unimplemented
   48.55 +	return result;
   48.56  }
   48.57  
   48.58  static struct ia64_pal_retval
   48.59  pal_cache_prot_info(VCPU *vcpu){
   48.60 -}
   48.61 +	struct ia64_pal_retval result;
   48.62  
   48.63 -static struct ia64_pal_retval
   48.64 -pal_cache_shared_info(VCPU *vcpu){
   48.65 +	result.status= -1; //unimplemented
   48.66 +	return result;
   48.67  }
   48.68  
   48.69  static struct ia64_pal_retval
   48.70  pal_mem_attrib(VCPU *vcpu){
   48.71 +	struct ia64_pal_retval result;
   48.72 +
   48.73 +	result.status= -1; //unimplemented
   48.74 +	return result;
   48.75  }
   48.76  
   48.77  static struct ia64_pal_retval
   48.78  pal_debug_info(VCPU *vcpu){
   48.79 +	struct ia64_pal_retval result;
   48.80 +
   48.81 +	result.status= -1; //unimplemented
   48.82 +	return result;
   48.83  }
   48.84  
   48.85  static struct ia64_pal_retval
   48.86 @@ -182,8 +199,16 @@ pal_fixed_addr(VCPU *vcpu){
   48.87  static struct ia64_pal_retval
   48.88  pal_freq_base(VCPU *vcpu){
   48.89      struct ia64_pal_retval result;
   48.90 +    struct ia64_sal_retval isrv;
   48.91  
   48.92      PAL_CALL(result,PAL_FREQ_BASE, 0, 0, 0);
   48.93 +    if(result.v0 == 0){ //PAL_FREQ_BASE may not be implemented in some platforms, call SAL instead.
   48.94 +        SAL_CALL(isrv, SAL_FREQ_BASE, 
   48.95 +                SAL_FREQ_BASE_PLATFORM, 0, 0, 0, 0, 0, 0);
   48.96 +        result.status = isrv.status;
   48.97 +        result.v0 = isrv.v0;
   48.98 +        result.v1 = result.v2 =0;
   48.99 +    }
  48.100      return result;
  48.101  }
  48.102  
  48.103 @@ -197,46 +222,89 @@ pal_freq_ratios(VCPU *vcpu){
  48.104  
  48.105  static struct ia64_pal_retval
  48.106  pal_halt_info(VCPU *vcpu){
  48.107 +	struct ia64_pal_retval result;
  48.108 +
  48.109 +	result.status= -1; //unimplemented
  48.110 +	return result;
  48.111  }
  48.112  
  48.113  static struct ia64_pal_retval
  48.114  pal_logical_to_physica(VCPU *vcpu){
  48.115 +	struct ia64_pal_retval result;
  48.116 +
  48.117 +	result.status= -1; //unimplemented
  48.118 +	return result;
  48.119  }
  48.120  
  48.121  static struct ia64_pal_retval
  48.122  pal_perf_mon_info(VCPU *vcpu){
  48.123 +	struct ia64_pal_retval result;
  48.124 +
  48.125 +	result.status= -1; //unimplemented
  48.126 +	return result;
  48.127  }
  48.128  
  48.129  static struct ia64_pal_retval
  48.130  pal_proc_get_features(VCPU *vcpu){
  48.131 +	struct ia64_pal_retval result;
  48.132 +
  48.133 +	result.status= -1; //unimplemented
  48.134 +	return result;
  48.135  }
  48.136  
  48.137  static struct ia64_pal_retval
  48.138  pal_ptce_info(VCPU *vcpu){
  48.139 +	struct ia64_pal_retval result;
  48.140 +
  48.141 +	result.status= -1; //unimplemented
  48.142 +	return result;
  48.143  }
  48.144  
  48.145  static struct ia64_pal_retval
  48.146  pal_register_info(VCPU *vcpu){
  48.147 +	struct ia64_pal_retval result;
  48.148 +
  48.149 +	result.status= -1; //unimplemented
  48.150 +	return result;
  48.151  }
  48.152  
  48.153  static struct ia64_pal_retval
  48.154  pal_rse_info(VCPU *vcpu){
  48.155 +	struct ia64_pal_retval result;
  48.156 +
  48.157 +	result.status= -1; //unimplemented
  48.158 +	return result;
  48.159  }
  48.160 -
  48.161  static struct ia64_pal_retval
  48.162  pal_test_info(VCPU *vcpu){
  48.163 +	struct ia64_pal_retval result;
  48.164 +
  48.165 +	result.status= -1; //unimplemented
  48.166 +	return result;
  48.167  }
  48.168  
  48.169  static struct ia64_pal_retval
  48.170  pal_vm_summary(VCPU *vcpu){
  48.171 +	struct ia64_pal_retval result;
  48.172 +
  48.173 +	result.status= -1; //unimplemented
  48.174 +	return result;
  48.175  }
  48.176  
  48.177  static struct ia64_pal_retval
  48.178  pal_vm_info(VCPU *vcpu){
  48.179 +	struct ia64_pal_retval result;
  48.180 +
  48.181 +	result.status= -1; //unimplemented
  48.182 +	return result;
  48.183  }
  48.184  
  48.185  static struct ia64_pal_retval
  48.186  pal_vm_page_size(VCPU *vcpu){
  48.187 +	struct ia64_pal_retval result;
  48.188 +
  48.189 +	result.status= -1; //unimplemented
  48.190 +	return result;
  48.191  }
  48.192  void
  48.193  pal_emul( VCPU *vcpu) {
  48.194 @@ -287,6 +355,82 @@ pal_emul( VCPU *vcpu) {
  48.195  			result = pal_freq_base (vcpu);
  48.196  			break;
  48.197  
  48.198 +		case PAL_BUS_GET_FEATURES :
  48.199 +			result = pal_bus_get_features (vcpu);
  48.200 +			break;
  48.201 +
  48.202 +		case PAL_CACHE_SUMMARY :
  48.203 +			result = pal_cache_summary (vcpu);
  48.204 +			break;
  48.205 +
  48.206 +		case PAL_CACHE_INIT :
  48.207 +			result = pal_cache_init(vcpu);
  48.208 +			break;
  48.209 +
  48.210 +		case PAL_CACHE_INFO :
  48.211 +			result = pal_cache_info(vcpu);
  48.212 +			break;
  48.213 +
  48.214 +		case PAL_CACHE_PROT_INFO :
  48.215 +			result = pal_cache_prot_info(vcpu);
  48.216 +			break;
  48.217 +
  48.218 +		case PAL_MEM_ATTRIB :
  48.219 +			result = pal_mem_attrib(vcpu);
  48.220 +			break;
  48.221 +
  48.222 +		case PAL_DEBUG_INFO :
  48.223 +			result = pal_debug_info(vcpu);
  48.224 +			break;
  48.225 +
  48.226 +		case PAL_FIXED_ADDR :
  48.227 +			result = pal_fixed_addr(vcpu);
  48.228 +			break;
  48.229 +
  48.230 +		case PAL_HALT_INFO :
  48.231 +			result = pal_halt_info(vcpu);
  48.232 +			break;
  48.233 +
  48.234 +		case PAL_LOGICAL_TO_PHYSICAL :
  48.235 +			result = pal_logical_to_physica(vcpu);
  48.236 +			break;
  48.237 +
  48.238 +		case PAL_PERF_MON_INFO :
  48.239 +			result = pal_perf_mon_info(vcpu);
  48.240 +			break;
  48.241 +
  48.242 +		case  PAL_PROC_GET_FEATURES:
  48.243 +			result = pal_proc_get_features(vcpu);
  48.244 +			break;
  48.245 +
  48.246 +		case PAL_PTCE_INFO :
  48.247 +			result = pal_ptce_info(vcpu);
  48.248 +			break;
  48.249 +
  48.250 +		case PAL_REGISTER_INFO :
  48.251 +			result = pal_register_info(vcpu);
  48.252 +			break;
  48.253 +
  48.254 +		case PAL_RSE_INFO :
  48.255 +			result = pal_rse_info(vcpu);
  48.256 +			break;
  48.257 +
  48.258 +		case PAL_TEST_PROC :
  48.259 +			result = pal_test_info(vcpu);
  48.260 +			break;
  48.261 +
  48.262 +		case PAL_VM_SUMMARY :
  48.263 +			result = pal_vm_summary(vcpu);
  48.264 +			break;
  48.265 +
  48.266 +		case PAL_VM_INFO :
  48.267 +			result = pal_vm_info(vcpu);
  48.268 +			break;
  48.269 +
  48.270 +		case PAL_VM_PAGE_SIZE :
  48.271 +			result = pal_vm_page_size(vcpu);
  48.272 +			break;
  48.273 +
  48.274  		default:
  48.275  			panic("pal_emul(): guest call unsupported pal" );
  48.276    }
    49.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Mon Mar 20 09:56:46 2006 +0100
    49.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Mon Mar 20 09:56:54 2006 +0100
    49.3 @@ -97,16 +97,15 @@ static void vtm_timer_fn(void *data)
    49.4  {
    49.5      vtime_t *vtm;
    49.6      VCPU    *vcpu = data;
    49.7 -    u64	    cur_itc,vitm;
    49.8 +    u64	    cur_itc,vitv;
    49.9  
   49.10 -    UINT64  vec;
   49.11 -    
   49.12 -    vec = VCPU(vcpu, itv) & 0xff;
   49.13 -    vmx_vcpu_pend_interrupt(vcpu, vec);
   49.14 -
   49.15 +    vitv = VCPU(vcpu, itv);
   49.16 +    if ( !ITV_IRQ_MASK(vitv) ){
   49.17 +        vmx_vcpu_pend_interrupt(vcpu, vitv & 0xff);
   49.18 +    }
   49.19      vtm=&(vcpu->arch.arch_vmx.vtm);
   49.20      cur_itc = now_itc(vtm);
   49.21 -    vitm =VCPU(vcpu, itm);
   49.22 + //    vitm =VCPU(vcpu, itm);
   49.23   //fire_itc2 = cur_itc;
   49.24   //fire_itm2 = vitm;
   49.25      update_last_itc(vtm,cur_itc);  // pseudo read to update vITC
   49.26 @@ -131,55 +130,76 @@ void vtm_init(VCPU *vcpu)
   49.27   */
   49.28  uint64_t vtm_get_itc(VCPU *vcpu)
   49.29  {
   49.30 -    uint64_t    guest_itc, spsr;
   49.31 +    uint64_t    guest_itc;
   49.32      vtime_t    *vtm;
   49.33  
   49.34      vtm=&(vcpu->arch.arch_vmx.vtm);
   49.35 -    // FIXME: should use local_irq_disable & local_irq_enable ??
   49.36 -    local_irq_save(spsr);
   49.37      guest_itc = now_itc(vtm);
   49.38 -//    update_last_itc(vtm, guest_itc);
   49.39 -
   49.40 -    local_irq_restore(spsr);
   49.41      return guest_itc;
   49.42  }
   49.43  
   49.44 +
   49.45 +
   49.46 +
   49.47  void vtm_set_itc(VCPU *vcpu, uint64_t new_itc)
   49.48  {
   49.49 -    uint64_t    spsr;
   49.50 +    uint64_t    vitm, vitv;
   49.51      vtime_t     *vtm;
   49.52 -
   49.53 +    vitm = VCPU(vcpu,itm);
   49.54 +    vitv = VCPU(vcpu,itv);
   49.55      vtm=&(vcpu->arch.arch_vmx.vtm);
   49.56 -    local_irq_save(spsr);
   49.57      vtm->vtm_offset = new_itc - ia64_get_itc();
   49.58      vtm->last_itc = new_itc;
   49.59 -    vtm_interruption_update(vcpu, vtm);
   49.60 -    local_irq_restore(spsr);
   49.61 +    if(vitm < new_itc){
   49.62 +        clear_bit(ITV_VECTOR(vitv), &VCPU(vcpu, irr[0]));
   49.63 +        stop_timer(&vtm->vtm_timer);
   49.64 +    }
   49.65  }
   49.66  
   49.67 -void vtm_set_itv(VCPU *vcpu)
   49.68 +
   49.69 +#define TIMER_SLOP (50*1000) /* ns */  /* copy from timer.c */
   49.70 +extern u64 cycle_to_ns(u64 cyle);
   49.71 +
   49.72 +
   49.73 +void vtm_set_itm(VCPU *vcpu, uint64_t val)
   49.74  {
   49.75 -    uint64_t    spsr,itv;
   49.76 -    vtime_t     *vtm;
   49.77 -
   49.78 +    vtime_t *vtm;
   49.79 +    uint64_t   vitv, cur_itc, expires;
   49.80 +    vitv = VCPU(vcpu, itv);
   49.81      vtm=&(vcpu->arch.arch_vmx.vtm);
   49.82 -    local_irq_save(spsr);
   49.83 -    itv = VCPU(vcpu, itv);
   49.84 -    if ( ITV_IRQ_MASK(itv) )
   49.85 +    // TODO; need to handle VHPI in future
   49.86 +    clear_bit(ITV_VECTOR(vitv), &VCPU(vcpu, irr[0]));
   49.87 +    VCPU(vcpu,itm)=val;
   49.88 +    cur_itc =now_itc(vtm);
   49.89 +    if(val >  vtm->last_itc){
   49.90 +        expires = NOW() + cycle_to_ns(val-cur_itc) + TIMER_SLOP;
   49.91 +        set_timer(&vtm->vtm_timer, expires);
   49.92 +    }else{
   49.93          stop_timer(&vtm->vtm_timer);
   49.94 -    vtm_interruption_update(vcpu, vtm);
   49.95 -    local_irq_restore(spsr);
   49.96 +    }
   49.97 +}
   49.98 +
   49.99 +
  49.100 +void vtm_set_itv(VCPU *vcpu, uint64_t val)
  49.101 +{
  49.102 +    uint64_t    olditv;
  49.103 +    olditv = VCPU(vcpu, itv);
  49.104 +    VCPU(vcpu, itv) = val;
  49.105 +    if(ITV_IRQ_MASK(val)){
  49.106 +        clear_bit(ITV_VECTOR(olditv), &VCPU(vcpu, irr[0]));
  49.107 +    }else if(ITV_VECTOR(olditv)!=ITV_VECTOR(val)){
  49.108 +        if(test_and_clear_bit(ITV_VECTOR(olditv), &VCPU(vcpu, irr[0])))
  49.109 +            set_bit(ITV_VECTOR(val), &VCPU(vcpu, irr[0]));
  49.110 +    }
  49.111  }
  49.112  
  49.113  
  49.114  /*
  49.115 - * Update interrupt or hook the vtm timer for fire 
  49.116 + * Update interrupt or hook the vtm timer for fire
  49.117   * At this point vtm_timer should be removed if itv is masked.
  49.118   */
  49.119  /* Interrupt must be disabled at this point */
  49.120 -
  49.121 -extern u64 cycle_to_ns(u64 cyle);
  49.122 -#define TIMER_SLOP (50*1000) /* ns */  /* copy from timer.c */
  49.123 +/*
  49.124  void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm)
  49.125  {
  49.126      uint64_t    cur_itc,vitm,vitv;
  49.127 @@ -197,8 +217,7 @@ void vtm_interruption_update(VCPU *vcpu,
  49.128      cur_itc =now_itc(vtm);
  49.129      diff_last = vtm->last_itc - vitm;
  49.130      diff_now = cur_itc - vitm;
  49.131 -    update_last_itc (vtm,cur_itc);
  49.132 -    
  49.133 +
  49.134      if ( diff_last >= 0 ) {
  49.135          // interrupt already fired.
  49.136          stop_timer(&vtm->vtm_timer);
  49.137 @@ -207,28 +226,32 @@ void vtm_interruption_update(VCPU *vcpu,
  49.138          // ITV is fired.
  49.139          vmx_vcpu_pend_interrupt(vcpu, vitv&0xff);
  49.140      }
  49.141 +*/
  49.142      /* Both last_itc & cur_itc < itm, wait for fire condition */
  49.143 -    else {
  49.144 +/*    else {
  49.145          expires = NOW() + cycle_to_ns(0-diff_now) + TIMER_SLOP;
  49.146          set_timer(&vtm->vtm_timer, expires);
  49.147      }
  49.148      local_irq_restore(spsr);
  49.149  }
  49.150 + */
  49.151  
  49.152  /*
  49.153   * Action for vtm when the domain is scheduled out.
  49.154   * Remove the timer for vtm.
  49.155   */
  49.156 +/*
  49.157  void vtm_domain_out(VCPU *vcpu)
  49.158  {
  49.159      if(!is_idle_domain(vcpu->domain))
  49.160  	stop_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
  49.161  }
  49.162 -
  49.163 + */
  49.164  /*
  49.165   * Action for vtm when the domain is scheduled in.
  49.166   * Fire vtm IRQ or add the timer for vtm.
  49.167   */
  49.168 +/*
  49.169  void vtm_domain_in(VCPU *vcpu)
  49.170  {
  49.171      vtime_t     *vtm;
  49.172 @@ -238,6 +261,7 @@ void vtm_domain_in(VCPU *vcpu)
  49.173  	vtm_interruption_update(vcpu, vtm);
  49.174      }
  49.175  }
  49.176 + */
  49.177  
  49.178  /*
  49.179   * Next for vLSapic
  49.180 @@ -413,11 +437,12 @@ static int is_higher_class(int pending, 
  49.181  {
  49.182      return ( (pending >> 4) > mic );
  49.183  }
  49.184 -
  49.185 +#if 0
  49.186  static int is_invalid_irq(int vec)
  49.187  {
  49.188      return (vec == 1 || ((vec <= 14 && vec >= 3)));
  49.189  }
  49.190 +#endif //shadow it due to no use currently
  49.191  
  49.192  #define   IRQ_NO_MASKED         0
  49.193  #define   IRQ_MASKED_BY_VTPR    1
    50.1 --- a/xen/arch/ia64/vmx/vmmu.c	Mon Mar 20 09:56:46 2006 +0100
    50.2 +++ b/xen/arch/ia64/vmx/vmmu.c	Mon Mar 20 09:56:54 2006 +0100
    50.3 @@ -31,6 +31,7 @@
    50.4  #include <asm/hw_irq.h>
    50.5  #include <asm/vmx_pal_vsa.h>
    50.6  #include <asm/kregs.h>
    50.7 +#include <asm/vcpu.h>
    50.8  #include <xen/irq.h>
    50.9  
   50.10  /*
   50.11 @@ -68,14 +69,14 @@ u64 get_mfn(struct domain *d, u64 gpfn)
   50.12  /*
   50.13   * The VRN bits of va stand for which rr to get.
   50.14   */
   50.15 -ia64_rr vmmu_get_rr(VCPU *vcpu, u64 va)
   50.16 -{
   50.17 -    ia64_rr   vrr;
   50.18 -    vmx_vcpu_get_rr(vcpu, va, &vrr.rrval);
   50.19 -    return vrr;
   50.20 -}
   50.21 +//ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va)
   50.22 +//{
   50.23 +//    ia64_rr   vrr;
   50.24 +//    vcpu_get_rr(vcpu, va, &vrr.rrval);
   50.25 +//    return vrr;
   50.26 +//}
   50.27  
   50.28 -
   50.29 +/*
   50.30  void recycle_message(thash_cb_t *hcb, u64 para)
   50.31  {
   50.32      if(hcb->ht == THASH_VHPT)
   50.33 @@ -84,7 +85,7 @@ void recycle_message(thash_cb_t *hcb, u6
   50.34      }
   50.35      printk("hcb=%p recycled with %lx\n",hcb,para);
   50.36  }
   50.37 -
   50.38 + */
   50.39  
   50.40  /*
   50.41   * Purge all guest TCs in logical processor.
   50.42 @@ -102,7 +103,6 @@ purge_machine_tc_by_domid(domid_t domid)
   50.43      u32 stride1,stride2;
   50.44      u32 i,j;
   50.45      u64 psr;
   50.46 -    
   50.47  
   50.48      result = ia64_pal_call_static(PAL_PTCE_INFO,0,0,0, 0);
   50.49      if ( result.status != 0 ) {
   50.50 @@ -113,7 +113,7 @@ purge_machine_tc_by_domid(domid_t domid)
   50.51      count2 = LOW_32BITS (result.v1);
   50.52      stride1 = HIGH_32BITS(result.v2);
   50.53      stride2 = LOW_32BITS (result.v2);
   50.54 -    
   50.55 +
   50.56      local_irq_save(psr);
   50.57      for (i=0; i<count1; i++) {
   50.58          for (j=0; j<count2; j++) {
   50.59 @@ -133,24 +133,10 @@ static thash_cb_t *init_domain_vhpt(stru
   50.60  //    struct page_info *page;
   50.61      thash_cb_t  *vhpt;
   50.62      PTA pta_value;
   50.63 -/*
   50.64 -    page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
   50.65 -    if ( page == NULL ) {
   50.66 -        panic("No enough contiguous memory for init_domain_mm\n");
   50.67 -    }
   50.68 -    vbase = page_to_virt(page);
   50.69 -    printk("Allocate domain vhpt at 0x%lx\n", (u64)vbase);
   50.70 -    memset(vbase, 0, VCPU_VHPT_SIZE);
   50.71 - */
   50.72 -//    vcur = (void*)((u64)vbase + VCPU_VHPT_SIZE);
   50.73      vcur -= sizeof (thash_cb_t);
   50.74      vhpt = vcur;
   50.75      vhpt->ht = THASH_VHPT;
   50.76      vhpt->vcpu = d;
   50.77 -//    vhpt->hash_func = machine_thash;
   50.78 -//    vcur -= sizeof (vhpt_special);
   50.79 -//    vs = vcur;
   50.80 -
   50.81      /* Setup guest pta */
   50.82      pta_value.val = 0;
   50.83      pta_value.ve = 1;
   50.84 @@ -159,14 +145,10 @@ static thash_cb_t *init_domain_vhpt(stru
   50.85      pta_value.base = ((u64)vbase) >> PTA_BASE_SHIFT;
   50.86      d->arch.arch_vmx.mpta = pta_value.val;
   50.87  
   50.88 -//    vhpt->vs = vs;
   50.89 -//    vhpt->vs->get_mfn = __gpfn_to_mfn_foreign;
   50.90 -//    vhpt->vs->tag_func = machine_ttag;
   50.91      vhpt->hash = vbase;
   50.92      vhpt->hash_sz = VCPU_VHPT_SIZE/2;
   50.93      vhpt->cch_buf = (void *)(vbase + vhpt->hash_sz);
   50.94      vhpt->cch_sz = (u64)vcur - (u64)vhpt->cch_buf;
   50.95 -//    vhpt->recycle_notifier = recycle_message;
   50.96      thash_init(vhpt,VCPU_VHPT_SHIFT-1);
   50.97      return vhpt;
   50.98  }
   50.99 @@ -177,9 +159,8 @@ thash_cb_t *init_domain_tlb(struct vcpu 
  50.100  {
  50.101      struct page_info *page;
  50.102      void    *vbase, *vhptbase, *vcur;
  50.103 -    tlb_special_t  *ts;
  50.104      thash_cb_t  *tlb;
  50.105 -    
  50.106 +
  50.107      page = alloc_domheap_pages (NULL, VCPU_VHPT_ORDER, 0);
  50.108      if ( page == NULL ) {
  50.109          panic("No enough contiguous memory for init_domain_mm\n");
  50.110 @@ -193,10 +174,7 @@ thash_cb_t *init_domain_tlb(struct vcpu 
  50.111      tlb = vcur;
  50.112      tlb->ht = THASH_TLB;
  50.113      tlb->vcpu = d;
  50.114 -    vcur -= sizeof (tlb_special_t);
  50.115 -    ts = vcur;
  50.116 -    tlb->ts = ts;
  50.117 -    tlb->ts->vhpt = init_domain_vhpt(d,vhptbase,vbase);
  50.118 +    tlb->vhpt = init_domain_vhpt(d,vhptbase,vbase);
  50.119  //    tlb->hash_func = machine_thash;
  50.120      tlb->hash = vbase;
  50.121      tlb->hash_sz = VCPU_VTLB_SIZE/2;
  50.122 @@ -207,27 +185,6 @@ thash_cb_t *init_domain_tlb(struct vcpu 
  50.123      return tlb;
  50.124  }
  50.125  
  50.126 -/* Allocate physical to machine mapping table for domN
  50.127 - * FIXME: Later this interface may be removed, if that table is provided
  50.128 - * by control panel. Dom0 has gpfn identical to mfn, which doesn't need
  50.129 - * this interface at all.
  50.130 - */
  50.131 -#if 0
  50.132 -void
  50.133 -alloc_pmt(struct domain *d)
  50.134 -{
  50.135 -    struct page_info *page;
  50.136 -
  50.137 -    /* Only called once */
  50.138 -    ASSERT(d->arch.pmt);
  50.139 -
  50.140 -    page = alloc_domheap_pages(NULL, get_order(d->max_pages), 0);
  50.141 -    ASSERT(page);
  50.142 -
  50.143 -    d->arch.pmt = page_to_virt(page);
  50.144 -    memset(d->arch.pmt, 0x55, d->max_pages * 8);
  50.145 -}
  50.146 -#endif
  50.147  /*
  50.148   * Insert guest TLB to machine TLB.
  50.149   *  data:   In TLB format
  50.150 @@ -240,7 +197,6 @@ void machine_tlb_insert(struct vcpu *d, 
  50.151      unsigned long mtlb_ppn;
  50.152      mtlb.ifa = tlb->vadr;
  50.153      mtlb.itir = tlb->itir & ~ITIR_RV_MASK;
  50.154 -    //vmx_vcpu_get_rr(d, mtlb.ifa, &vrr.value);
  50.155      mtlb.page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
  50.156      mtlb.ppn = get_mfn(d->domain,tlb->ppn);
  50.157      mtlb_ppn=mtlb.ppn;
  50.158 @@ -311,7 +267,7 @@ int vhpt_enabled(VCPU *vcpu, uint64_t va
  50.159      IA64_PSR  vpsr; 
  50.160  
  50.161      vpsr.val = vmx_vcpu_get_psr(vcpu);
  50.162 -    vrr = vmx_vcpu_rr(vcpu, vadr);
  50.163 +    vcpu_get_rr(vcpu, vadr, &vrr.rrval);
  50.164      vmx_vcpu_get_pta(vcpu,&vpta.val);
  50.165  
  50.166      if ( vrr.ve & vpta.ve ) {
  50.167 @@ -355,21 +311,18 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
  50.168      u64     *vpa;
  50.169      thash_data_t    *tlb;
  50.170      thash_cb_t *hcb;
  50.171 -    ia64_rr vrr;
  50.172      u64     mfn;
  50.173  
  50.174      if ( !(VCPU(vcpu, vpsr) & IA64_PSR_IT) ) {   // I-side physical mode
  50.175          gpip = gip;
  50.176      }
  50.177      else {
  50.178 -        vmx_vcpu_get_rr(vcpu, gip, &vrr.rrval);
  50.179 -	hcb = vmx_vcpu_get_vtlb(vcpu);
  50.180 -        tlb = vtlb_lookup_ex (hcb, vrr.rid, gip, ISIDE_TLB );
  50.181 -        if( tlb == NULL )
  50.182 -             tlb = vtlb_lookup_ex (hcb,
  50.183 -                vrr.rid, gip, DSIDE_TLB );
  50.184 -        if (tlb) 
  50.185 -	        gpip = (tlb->ppn << 12) | ( gip & (PSIZE(tlb->ps)-1) );
  50.186 +	    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.187 +        tlb = vtlb_lookup(hcb, gip, ISIDE_TLB);
  50.188 +//        if( tlb == NULL )
  50.189 +//             tlb = vtlb_lookup(hcb, gip, DSIDE_TLB );
  50.190 +        if (tlb)
  50.191 +	        gpip = (tlb->ppn >>(tlb->ps-12)<<tlb->ps) | ( gip & (PSIZE(tlb->ps)-1) );
  50.192      }
  50.193      if( gpip){
  50.194  	 mfn = gmfn_to_mfn(vcpu->domain, gpip >>PAGE_SHIFT);
  50.195 @@ -388,236 +341,146 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
  50.196  
  50.197  IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
  50.198  {
  50.199 -
  50.200 -    thash_data_t data, *ovl;
  50.201 +    int slot;
  50.202 +    u64 ps, va;
  50.203      thash_cb_t  *hcb;
  50.204 -    search_section_t sections;
  50.205 -    ia64_rr vrr;
  50.206  
  50.207 -    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.208 -    data.page_flags=pte & ~PAGE_FLAGS_RV_MASK;
  50.209 -    data.itir=itir;
  50.210 -    data.vadr=PAGEALIGN(ifa,data.ps);
  50.211 -    data.tc = 1;
  50.212 -    data.cl=ISIDE_TLB;
  50.213 -    vmx_vcpu_get_rr(vcpu, ifa, (UINT64 *)&vrr);
  50.214 -    data.rid = vrr.rid;
  50.215 -    
  50.216 -    sections.tr = 1;
  50.217 -    sections.tc = 0;
  50.218 -
  50.219 -    ovl = vtr_find_overlap(hcb, &data, ISIDE_TLB);
  50.220 -    while (ovl) {
  50.221 +    ps = itir_ps(itir);
  50.222 +    va = PAGEALIGN(ifa, ps);
  50.223 +    slot = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
  50.224 +    if (slot >=0) {
  50.225          // generate MCA.
  50.226          panic("Tlb conflict!!");
  50.227          return IA64_FAULT;
  50.228      }
  50.229 -    thash_purge_and_insert(hcb, &data, ifa);
  50.230 +    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.231 +    thash_purge_and_insert(hcb, pte, itir, ifa);
  50.232      return IA64_NO_FAULT;
  50.233  }
  50.234  
  50.235 +IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
  50.236 +{
  50.237 +    int slot;
  50.238 +    u64 ps, va, gpfn;
  50.239 +    thash_cb_t  *hcb;
  50.240 +
  50.241 +    ps = itir_ps(itir);
  50.242 +    va = PAGEALIGN(ifa, ps);
  50.243 +    slot = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
  50.244 +    if (slot >=0) {
  50.245 +        // generate MCA.
  50.246 +        panic("Tlb conflict!!");
  50.247 +        return IA64_FAULT;
  50.248 +    }
  50.249 +    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.250 +    gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
  50.251 +    if(__gpfn_is_io(vcpu->domain,gpfn))
  50.252 +        pte |= VTLB_PTE_IO;
  50.253 +    thash_purge_and_insert(hcb, pte, itir, ifa);
  50.254 +    return IA64_NO_FAULT;
  50.255 +
  50.256 +}
  50.257 +
  50.258  
  50.259  
  50.260  
  50.261 -IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
  50.262 +IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
  50.263  {
  50.264 -
  50.265 -    thash_data_t data, *ovl;
  50.266 +    int index;
  50.267 +    u64 ps, va, rid;
  50.268      thash_cb_t  *hcb;
  50.269 -    search_section_t sections;
  50.270 -    ia64_rr vrr;
  50.271 -
  50.272 -    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.273 -    data.page_flags=pte & ~PAGE_FLAGS_RV_MASK;
  50.274 -    data.itir=itir;
  50.275 -    data.vadr=PAGEALIGN(ifa,data.ps);
  50.276 -    data.tc = 1;
  50.277 -    data.cl=DSIDE_TLB;
  50.278 -    vmx_vcpu_get_rr(vcpu, ifa,(UINT64 *)&vrr);
  50.279 -    data.rid = vrr.rid;
  50.280 -    sections.tr = 1;
  50.281 -    sections.tc = 0;
  50.282 -
  50.283 -    ovl = vtr_find_overlap(hcb, &data, DSIDE_TLB);
  50.284 -    if (ovl) {
  50.285 -          // generate MCA.
  50.286 -        panic("Tlb conflict!!");
  50.287 -        return IA64_FAULT;
  50.288 -    }
  50.289 -    thash_purge_and_insert(hcb, &data, ifa);
  50.290 -    return IA64_NO_FAULT;
  50.291 -}
  50.292 -
  50.293 -/*
  50.294 - * Return TRUE/FALSE for success of lock operation
  50.295 - */
  50.296 -
  50.297 -/*
  50.298 -int vmx_lock_guest_dtc (VCPU *vcpu, UINT64 va, int lock)
  50.299 -{
  50.300  
  50.301 -    thash_cb_t  *hcb;
  50.302 -    ia64_rr vrr;
  50.303 -    u64	  preferred_size;
  50.304 -
  50.305 -    vmx_vcpu_get_rr(vcpu, va, &vrr);
  50.306 -    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.307 -    va = PAGEALIGN(va,vrr.ps);
  50.308 -    preferred_size = PSIZE(vrr.ps);
  50.309 -    return thash_lock_tc(hcb, va, preferred_size, vrr.rid, DSIDE_TLB, lock);
  50.310 -}
  50.311 - */
  50.312 -
  50.313 -
  50.314 -
  50.315 -IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa, UINT64 idx)
  50.316 -{
  50.317 -
  50.318 -    thash_data_t data, *ovl;
  50.319 -    thash_cb_t  *hcb;
  50.320 -    search_section_t sections;
  50.321 -    ia64_rr vrr;
  50.322 -    /* u64 mfn,psr; */
  50.323 -
  50.324 -    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.325 -    data.page_flags=pte & ~PAGE_FLAGS_RV_MASK;
  50.326 -    data.itir=itir;
  50.327 -    data.vadr=PAGEALIGN(ifa,data.ps);
  50.328 -    data.tc = 0;
  50.329 -    data.cl=ISIDE_TLB;
  50.330 -    vmx_vcpu_get_rr(vcpu, ifa, (UINT64 *)&vrr);
  50.331 -    data.rid = vrr.rid;
  50.332 -    sections.tr = 1;
  50.333 -    sections.tc = 0;
  50.334 -
  50.335 -
  50.336 -    ovl = vtr_find_overlap(hcb, &data, ISIDE_TLB);
  50.337 -    if (ovl) {
  50.338 +    ps = itir_ps(itir);
  50.339 +    va = PAGEALIGN(ifa, ps);
  50.340 +    index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
  50.341 +    if (index >=0) {
  50.342          // generate MCA.
  50.343          panic("Tlb conflict!!");
  50.344          return IA64_FAULT;
  50.345      }
  50.346 -    sections.tr = 0;
  50.347 -    sections.tc = 1;
  50.348 -    thash_purge_entries(hcb, &data, sections);
  50.349 -/*    if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
  50.350 -        data.contiguous=1;
  50.351 -    }
  50.352 - */
  50.353 -    thash_tr_insert(hcb, &data, ifa, idx);
  50.354 -/*
  50.355 -    if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
  50.356 -        mfn = __gpfn_to_mfn_foreign(vcpu->domain,arch_to_xen_ppn(data.ppn));
  50.357 -        data.page_flags=pte&~PAGE_FLAGS_RV_MASK;
  50.358 -        data.ppn = xen_to_arch_ppn(mfn);
  50.359 -        psr = ia64_clear_ic();
  50.360 -        ia64_itr(0x1, IA64_ITR_GUEST_KERNEL, data.vadr, data.page_flags, data.ps);
  50.361 -        ia64_set_psr(psr);      // restore psr
  50.362 -        ia64_srlz_i();
  50.363 -//        return IA64_NO_FAULT;
  50.364 -    }
  50.365 -*/
  50.366 +    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.367 +    thash_purge_entries(hcb, va, ps);
  50.368 +    vcpu_get_rr(vcpu, va, &rid);
  50.369 +    rid = rid& RR_RID_MASK;
  50.370 +    vmx_vcpu_set_tr((thash_data_t *)&vcpu->arch.itrs[slot], pte, itir, va, rid);
  50.371 +    vcpu_quick_region_set(PSCBX(vcpu,itr_regions),va);
  50.372      return IA64_NO_FAULT;
  50.373  }
  50.374  
  50.375 -IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa, UINT64 idx)
  50.376 -{
  50.377 -
  50.378 -    thash_data_t data, *ovl;
  50.379 -    thash_cb_t  *hcb;
  50.380 -    search_section_t sections;
  50.381 -    ia64_rr    vrr;
  50.382 -    /* u64 mfn,psr; */
  50.383  
  50.384 -    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.385 -    data.page_flags=pte & ~PAGE_FLAGS_RV_MASK;
  50.386 -    data.itir=itir;
  50.387 -    data.vadr=PAGEALIGN(ifa,data.ps);
  50.388 -    data.tc = 0;
  50.389 -    data.cl=DSIDE_TLB;
  50.390 -    vmx_vcpu_get_rr(vcpu, ifa,(UINT64 *)&vrr);
  50.391 -    data.rid = vrr.rid;
  50.392 -    sections.tr = 1;
  50.393 -    sections.tc = 0;
  50.394 +IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
  50.395 +{
  50.396 +    int index;
  50.397 +    u64 ps, va, gpfn, rid;
  50.398 +    thash_cb_t  *hcb;
  50.399  
  50.400 -    ovl = vtr_find_overlap(hcb, &data, DSIDE_TLB);
  50.401 -    while (ovl) {
  50.402 +    ps = itir_ps(itir);
  50.403 +    va = PAGEALIGN(ifa, ps);
  50.404 +    index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
  50.405 +    if (index>=0) {
  50.406          // generate MCA.
  50.407          panic("Tlb conflict!!");
  50.408          return IA64_FAULT;
  50.409      }
  50.410 -    sections.tr = 0;
  50.411 -    sections.tc = 1;
  50.412 -    thash_purge_entries(hcb, &data, sections);
  50.413 -/*
  50.414 -    if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
  50.415 -        data.contiguous=1;
  50.416 -    }
  50.417 - */
  50.418 -    thash_tr_insert(hcb, &data, ifa, idx);
  50.419 -/*
  50.420 -    if((idx==IA64_TR_KERNEL)&&(data.ps == KERNEL_TR_PAGE_SHIFT)){
  50.421 -        mfn = __gpfn_to_mfn_foreign(vcpu->domain,arch_to_xen_ppn(data.ppn));
  50.422 -        data.page_flags=pte&~PAGE_FLAGS_RV_MASK;
  50.423 -        data.ppn = xen_to_arch_ppn(mfn);
  50.424 -        psr = ia64_clear_ic();
  50.425 -        ia64_itr(0x2,IA64_DTR_GUEST_KERNEL , data.vadr, data.page_flags, data.ps);
  50.426 -        ia64_set_psr(psr);      // restore psr
  50.427 -        ia64_srlz_i();
  50.428 -//        return IA64_NO_FAULT;
  50.429 -    }
  50.430 -*/
  50.431 -
  50.432 +    hcb = vmx_vcpu_get_vtlb(vcpu);
  50.433 +    thash_purge_entries(hcb, va, ps);
  50.434 +    gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
  50.435 +    if(__gpfn_is_io(vcpu->domain,gpfn))
  50.436 +        pte |= VTLB_PTE_IO;
  50.437 +    vcpu_get_rr(vcpu, va, &rid);
  50.438 +    rid = rid& RR_RID_MASK;
  50.439 +    vmx_vcpu_set_tr((thash_data_t *)&vcpu->arch.dtrs[slot], pte, itir, va, rid);
  50.440 +    vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),va);
  50.441      return IA64_NO_FAULT;
  50.442  }
  50.443  
  50.444  
  50.445  
  50.446 -IA64FAULT vmx_vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 ps)
  50.447 +IA64FAULT vmx_vcpu_ptr_d(VCPU *vcpu,UINT64 ifa,UINT64 ps)
  50.448  {
  50.449 +    int index;
  50.450 +    u64 va;
  50.451      thash_cb_t  *hcb;
  50.452 -    ia64_rr rr;
  50.453 -    search_section_t sections;
  50.454  
  50.455 +    va = PAGEALIGN(ifa, ps);
  50.456 +    index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
  50.457 +    if (index>=0) {
  50.458 +        vcpu->arch.dtrs[index].p=0;
  50.459 +        index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
  50.460 +    }
  50.461      hcb = vmx_vcpu_get_vtlb(vcpu);
  50.462 -    rr=vmx_vcpu_rr(vcpu,vadr);
  50.463 -    sections.tr = 1;
  50.464 -    sections.tc = 1;
  50.465 -    thash_purge_entries_ex(hcb,rr.rid,vadr,ps,sections,DSIDE_TLB);
  50.466 +    thash_purge_entries(hcb, va, ps);
  50.467      return IA64_NO_FAULT;
  50.468  }
  50.469  
  50.470 -IA64FAULT vmx_vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 ps)
  50.471 +IA64FAULT vmx_vcpu_ptr_i(VCPU *vcpu,UINT64 ifa,UINT64 ps)
  50.472  {
  50.473 +    int index;
  50.474 +    u64 va;
  50.475      thash_cb_t  *hcb;
  50.476 -    ia64_rr rr;
  50.477 -    search_section_t sections;
  50.478 +
  50.479 +    va = PAGEALIGN(ifa, ps);
  50.480 +    index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
  50.481 +    if (index>=0) {
  50.482 +        vcpu->arch.itrs[index].p=0;
  50.483 +        index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
  50.484 +    }
  50.485      hcb = vmx_vcpu_get_vtlb(vcpu);
  50.486 -    rr=vmx_vcpu_rr(vcpu,vadr);
  50.487 -    sections.tr = 1;
  50.488 -    sections.tc = 1;
  50.489 -    thash_purge_entries_ex(hcb,rr.rid,vadr,ps,sections,ISIDE_TLB);
  50.490 +    thash_purge_entries(hcb, va, ps);
  50.491      return IA64_NO_FAULT;
  50.492  }
  50.493  
  50.494 -IA64FAULT vmx_vcpu_ptc_l(VCPU *vcpu, UINT64 vadr, UINT64 ps)
  50.495 +IA64FAULT vmx_vcpu_ptc_l(VCPU *vcpu, UINT64 va, UINT64 ps)
  50.496  {
  50.497      thash_cb_t  *hcb;
  50.498 -    ia64_rr vrr;
  50.499 -    search_section_t sections;
  50.500 +    va = PAGEALIGN(va, ps);
  50.501      hcb = vmx_vcpu_get_vtlb(vcpu);
  50.502 -    vrr=vmx_vcpu_rr(vcpu,vadr);
  50.503 -    sections.tr = 0;
  50.504 -    sections.tc = 1;
  50.505 -    vadr = PAGEALIGN(vadr, ps);
  50.506 -
  50.507 -    thash_purge_entries_ex(hcb,vrr.rid,vadr,ps,sections,DSIDE_TLB);
  50.508 -    thash_purge_entries_ex(hcb,vrr.rid,vadr,ps,sections,ISIDE_TLB);
  50.509 +    thash_purge_entries(hcb, va, ps);
  50.510      return IA64_NO_FAULT;
  50.511  }
  50.512  
  50.513  
  50.514 -IA64FAULT vmx_vcpu_ptc_e(VCPU *vcpu, UINT64 vadr)
  50.515 +IA64FAULT vmx_vcpu_ptc_e(VCPU *vcpu, UINT64 va)
  50.516  {
  50.517      thash_cb_t  *hcb;
  50.518      hcb = vmx_vcpu_get_vtlb(vcpu);
  50.519 @@ -625,15 +488,15 @@ IA64FAULT vmx_vcpu_ptc_e(VCPU *vcpu, UIN
  50.520      return IA64_NO_FAULT;
  50.521  }
  50.522  
  50.523 -IA64FAULT vmx_vcpu_ptc_g(VCPU *vcpu, UINT64 vadr, UINT64 ps)
  50.524 +IA64FAULT vmx_vcpu_ptc_g(VCPU *vcpu, UINT64 va, UINT64 ps)
  50.525  {
  50.526 -    vmx_vcpu_ptc_l(vcpu, vadr, ps);
  50.527 +    vmx_vcpu_ptc_l(vcpu, va, ps);
  50.528      return IA64_ILLOP_FAULT;
  50.529  }
  50.530  
  50.531 -IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu,UINT64 vadr,UINT64 ps)
  50.532 +IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu,UINT64 va,UINT64 ps)
  50.533  {
  50.534 -    vmx_vcpu_ptc_l(vcpu, vadr, ps);
  50.535 +    vmx_vcpu_ptc_l(vcpu, va, ps);
  50.536      return IA64_NO_FAULT;
  50.537  }
  50.538  
  50.539 @@ -644,7 +507,7 @@ IA64FAULT vmx_vcpu_thash(VCPU *vcpu, UIN
  50.540      ia64_rr vrr;
  50.541      u64 vhpt_offset;
  50.542      vmx_vcpu_get_pta(vcpu, &vpta.val);
  50.543 -    vrr=vmx_vcpu_rr(vcpu, vadr);
  50.544 +    vcpu_get_rr(vcpu, vadr, &vrr.rrval);
  50.545      if(vpta.vf){
  50.546          panic("THASH,Don't support long format VHPT");
  50.547          *pval = ia64_call_vsa(PAL_VPS_THASH,vadr,vrr.rrval,vpta.val,0,0,0,0);
  50.548 @@ -663,7 +526,7 @@ IA64FAULT vmx_vcpu_ttag(VCPU *vcpu, UINT
  50.549      ia64_rr vrr;
  50.550      PTA vpta;
  50.551      vmx_vcpu_get_pta(vcpu, &vpta.val);
  50.552 -    vrr=vmx_vcpu_rr(vcpu, vadr);
  50.553 +    vcpu_get_rr(vcpu, vadr, &vrr.rrval);
  50.554      if(vpta.vf){
  50.555          panic("THASH,Don't support long format VHPT");
  50.556          *pval = ia64_call_vsa(PAL_VPS_TTAG,vadr,vrr.rrval,0,0,0,0,0);
  50.557 @@ -679,13 +542,11 @@ IA64FAULT vmx_vcpu_tpa(VCPU *vcpu, UINT6
  50.558  {
  50.559      thash_data_t *data;
  50.560      thash_cb_t  *hcb;
  50.561 -    ia64_rr vrr;
  50.562      ISR visr,pt_isr;
  50.563      REGS *regs;
  50.564      u64 vhpt_adr;
  50.565      IA64_PSR vpsr;
  50.566      hcb = vmx_vcpu_get_vtlb(vcpu);
  50.567 -    vrr=vmx_vcpu_rr(vcpu,vadr);
  50.568      regs=vcpu_regs(vcpu);
  50.569      pt_isr.val=VMX(vcpu,cr_isr);
  50.570      visr.val=0;
  50.571 @@ -696,7 +557,7 @@ IA64FAULT vmx_vcpu_tpa(VCPU *vcpu, UINT6
  50.572           visr.ni=1;
  50.573      }
  50.574      visr.na=1;
  50.575 -    data = vtlb_lookup_ex(hcb, vrr.rid, vadr, DSIDE_TLB);
  50.576 +    data = vtlb_lookup(hcb, vadr, DSIDE_TLB);
  50.577      if(data){
  50.578          if(data->p==0){
  50.579              visr.na=1;
  50.580 @@ -744,8 +605,7 @@ IA64FAULT vmx_vcpu_tpa(VCPU *vcpu, UINT6
  50.581          }
  50.582          else{
  50.583              vmx_vcpu_thash(vcpu, vadr, &vhpt_adr);
  50.584 -            vrr=vmx_vcpu_rr(vcpu,vhpt_adr);
  50.585 -            data = vtlb_lookup_ex(hcb, vrr.rid, vhpt_adr, DSIDE_TLB);
  50.586 +            data = vtlb_lookup(hcb, vhpt_adr, DSIDE_TLB);
  50.587              if(data){
  50.588                  if(vpsr.ic){
  50.589                      vcpu_set_isr(vcpu, visr.val);
  50.590 @@ -776,7 +636,6 @@ IA64FAULT vmx_vcpu_tak(VCPU *vcpu, UINT6
  50.591  {
  50.592      thash_data_t *data;
  50.593      thash_cb_t  *hcb;
  50.594 -    ia64_rr rr;
  50.595      PTA vpta;
  50.596      vmx_vcpu_get_pta(vcpu, &vpta.val);
  50.597      if(vpta.vf==0 || unimplemented_gva(vcpu, vadr)){
  50.598 @@ -784,8 +643,7 @@ IA64FAULT vmx_vcpu_tak(VCPU *vcpu, UINT6
  50.599          return IA64_NO_FAULT;
  50.600      }
  50.601      hcb = vmx_vcpu_get_vtlb(vcpu);
  50.602 -    rr=vmx_vcpu_rr(vcpu,vadr);
  50.603 -    data = vtlb_lookup_ex(hcb, rr.rid, vadr, DSIDE_TLB);
  50.604 +    data = vtlb_lookup(hcb, vadr, DSIDE_TLB);
  50.605      if(!data||!data->p){
  50.606          *key=1;
  50.607      }else{
  50.608 @@ -821,11 +679,9 @@ long
  50.609      unsigned long	end;	/* end of the area mapped by current entry */
  50.610      thash_data_t	*entry;
  50.611      struct vcpu *v = current;
  50.612 -    ia64_rr	vrr;
  50.613  
  50.614      vtlb = vmx_vcpu_get_vtlb(v); 
  50.615 -    vrr = vmx_vcpu_rr(v, va);
  50.616 -    entry = vtlb_lookup_ex(vtlb, vrr.rid, va, DSIDE_TLB);
  50.617 +    entry = vtlb_lookup(vtlb, va, DSIDE_TLB);
  50.618      if (entry == NULL)
  50.619  	return -EFAULT;
  50.620  
    51.1 --- a/xen/arch/ia64/vmx/vmx_hypercall.c	Mon Mar 20 09:56:46 2006 +0100
    51.2 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c	Mon Mar 20 09:56:54 2006 +0100
    51.3 @@ -35,6 +35,9 @@
    51.4  #include <asm/dom_fw.h>
    51.5  #include <xen/domain.h>
    51.6  
    51.7 +extern long do_sched_op(int cmd, unsigned long arg);
    51.8 +extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
    51.9 +
   51.10  void hyper_not_support(void)
   51.11  {
   51.12      VCPU *vcpu=current;
   51.13 @@ -123,7 +126,7 @@ void hyper_xen_version(void)
   51.14      vcpu_set_gr(vcpu, 8, ret, 0);
   51.15      vmx_vcpu_increment_iip(vcpu);
   51.16  }
   51.17 -
   51.18 +/*
   51.19  static int do_lock_page(VCPU *vcpu, u64 va, u64 lock)
   51.20  {
   51.21      ia64_rr rr;
   51.22 @@ -132,7 +135,7 @@ static int do_lock_page(VCPU *vcpu, u64 
   51.23      rr = vmx_vcpu_rr(vcpu, va);
   51.24      return thash_lock_tc(hcb, va ,1U<<rr.ps, rr.rid, DSIDE_TLB, lock);
   51.25  }
   51.26 -
   51.27 + */
   51.28  /*
   51.29   * Lock guest page in vTLB, so that it's not relinquished by recycle
   51.30   * session when HV is servicing that hypercall.
    52.1 --- a/xen/arch/ia64/vmx/vmx_init.c	Mon Mar 20 09:56:46 2006 +0100
    52.2 +++ b/xen/arch/ia64/vmx/vmx_init.c	Mon Mar 20 09:56:54 2006 +0100
    52.3 @@ -50,6 +50,8 @@
    52.4  #include <public/arch-ia64.h>
    52.5  #include <asm/hvm/vioapic.h>
    52.6  #include <public/event_channel.h>
    52.7 +#include <xen/event.h>
    52.8 +#include <asm/vlsapic.h>
    52.9  
   52.10  /* Global flag to identify whether Intel vmx feature is on */
   52.11  u32 vmx_enabled = 0;
   52.12 @@ -96,7 +98,7 @@ identify_vmx_feature(void)
   52.13  	if (!(vp_env_info & VP_OPCODE))
   52.14  		printk("WARNING: no opcode provided from hardware(%lx)!!!\n", vp_env_info);
   52.15  	vm_order = get_order(buffer_size);
   52.16 -	printk("vm buffer size: %ld, order: %ld\n", buffer_size, vm_order);
   52.17 +	printk("vm buffer size: %ld, order: %d\n", buffer_size, vm_order);
   52.18  
   52.19  	vmx_enabled = 1;
   52.20  no_vti:
   52.21 @@ -161,7 +163,7 @@ static vpd_t *alloc_vpd(void)
   52.22  		return NULL;
   52.23  	}
   52.24  
   52.25 -	printk("vpd base: 0x%lx, vpd size:%d\n", vpd, sizeof(vpd_t));
   52.26 +	printk("vpd base: 0x%p, vpd size:%ld\n", vpd, sizeof(vpd_t));
   52.27  	memset(vpd, 0, VPD_SIZE);
   52.28  	/* CPUID init */
   52.29  	for (i = 0; i < 5; i++)
   52.30 @@ -234,7 +236,7 @@ vmx_load_state(struct vcpu *v)
   52.31  {
   52.32  	u64 status;
   52.33  
   52.34 -	status = ia64_pal_vp_restore(v->arch.privregs, 0);
   52.35 +	status = ia64_pal_vp_restore((u64 *)v->arch.privregs, 0);
   52.36  	if (status != PAL_STATUS_SUCCESS)
   52.37  		panic("Restore vp status failed\n");
   52.38  
   52.39 @@ -307,7 +309,6 @@ io_range_t io_ranges[] = {
   52.40  
   52.41  int vmx_alloc_contig_pages(struct domain *d)
   52.42  {
   52.43 -	unsigned int order;
   52.44  	unsigned long i, j, start,tmp, end, pgnr, conf_nr;
   52.45  	struct page_info *page;
   52.46  	struct vcpu *v = d->vcpu[0];
    53.1 --- a/xen/arch/ia64/vmx/vmx_interrupt.c	Mon Mar 20 09:56:46 2006 +0100
    53.2 +++ b/xen/arch/ia64/vmx/vmx_interrupt.c	Mon Mar 20 09:56:54 2006 +0100
    53.3 @@ -334,12 +334,13 @@ static void
    53.4   *  @ Nat Consumption Vector
    53.5   * Refer to SDM Vol2 Table 5-6 & 8-1
    53.6   */
    53.7 -
    53.8 +#if 0
    53.9  static void
   53.10  ir_nat_page_consumption (VCPU *vcpu, u64 vadr)
   53.11  {
   53.12      _nat_consumption_fault(vcpu, vadr, DATA);
   53.13  }
   53.14 +#endif //shadow it due to no use currently 
   53.15  
   53.16  /*
   53.17   * Instruction Nat Page Consumption Fault
    54.1 --- a/xen/arch/ia64/vmx/vmx_irq_ia64.c	Mon Mar 20 09:56:46 2006 +0100
    54.2 +++ b/xen/arch/ia64/vmx/vmx_irq_ia64.c	Mon Mar 20 09:56:54 2006 +0100
    54.3 @@ -128,6 +128,6 @@ vmx_ia64_handle_irq (ia64_vector vector,
    54.4  	 * come through until ia64_eoi() has been done.
    54.5  	 */
    54.6  	vmx_irq_exit();
    54.7 -	if (current && wake_dom0 != dom0 ) 
    54.8 +	if (wake_dom0 && current->domain != dom0 ) 
    54.9  		vcpu_wake(dom0->vcpu[0]);
   54.10  }
    55.1 --- a/xen/arch/ia64/vmx/vmx_phy_mode.c	Mon Mar 20 09:56:46 2006 +0100
    55.2 +++ b/xen/arch/ia64/vmx/vmx_phy_mode.c	Mon Mar 20 09:56:54 2006 +0100
    55.3 @@ -104,57 +104,51 @@ physical_mode_init(VCPU *vcpu)
    55.4      vcpu->arch.mode_flags = GUEST_IN_PHY;
    55.5  }
    55.6  
    55.7 -extern u64 get_mfn(struct domain *d, u64 gpfn);
    55.8  extern void vmx_switch_rr7(unsigned long ,shared_info_t*,void *,void *,void *);
    55.9 -void
   55.10 -physical_itlb_miss_dom0(VCPU *vcpu, u64 vadr)
   55.11 +/*void
   55.12 +physical_itlb_miss(VCPU *vcpu, u64 vadr)
   55.13  {
   55.14      u64 psr;
   55.15      IA64_PSR vpsr;
   55.16 -    u64 mppn,gppn;
   55.17 +    u64 xen_mppn,xen_gppn;
   55.18      vpsr.val=vmx_vcpu_get_psr(vcpu);
   55.19 -    gppn=(vadr<<1)>>13;
   55.20 -    mppn = get_mfn(vcpu->domain,gppn);
   55.21 -    mppn=(mppn<<12)|(vpsr.cpl<<7); 
   55.22 -//    if(vadr>>63)
   55.23 -//       mppn |= PHY_PAGE_UC;
   55.24 -//    else
   55.25 -    mppn |= PHY_PAGE_WB;
   55.26 +    xen_gppn=(vadr<<1)>>(PAGE_SHIFT+1);
   55.27 +    xen_mppn = gmfn_to_mfn(vcpu->domain, xen_gppn);
   55.28 +    xen_mppn=(xen_mppn<<PAGE_SHIFT)|(vpsr.cpl<<7);
   55.29 +    if(vadr>>63)
   55.30 +        xen_mppn |= PHY_PAGE_UC;
   55.31 +    else
   55.32 +        xen_mppn |= PHY_PAGE_WB;
   55.33  
   55.34      psr=ia64_clear_ic();
   55.35 -    ia64_itc(1,vadr&(~0xfff),mppn,EMUL_PHY_PAGE_SHIFT);
   55.36 +    ia64_itc(1,vadr&PAGE_MASK,xen_mppn,PAGE_SHIFT);
   55.37      ia64_set_psr(psr);
   55.38      ia64_srlz_i();
   55.39      return;
   55.40  }
   55.41  
   55.42 -
   55.43 +*/
   55.44 +/* 
   55.45 + *      vec=1, itlb miss
   55.46 + *      vec=2, dtlb miss
   55.47 + */
   55.48  void
   55.49 -physical_itlb_miss(VCPU *vcpu, u64 vadr)
   55.50 -{
   55.51 -        physical_itlb_miss_dom0(vcpu, vadr);
   55.52 -}
   55.53 -
   55.54 -
   55.55 -void
   55.56 -physical_dtlb_miss(VCPU *vcpu, u64 vadr)
   55.57 +physical_tlb_miss(VCPU *vcpu, u64 vadr, u64 vec)
   55.58  {
   55.59      u64 psr;
   55.60      IA64_PSR vpsr;
   55.61 -    u64 mppn,gppn;
   55.62 -//    if(vcpu->domain!=dom0)
   55.63 -//        panic("dom n physical dtlb miss happen\n");
   55.64 +    u64 xen_mppn,xen_gppn;
   55.65      vpsr.val=vmx_vcpu_get_psr(vcpu);
   55.66 -    gppn=(vadr<<1)>>13;
   55.67 -    mppn = get_mfn(vcpu->domain, gppn);
   55.68 -    mppn=(mppn<<12)|(vpsr.cpl<<7);
   55.69 +    xen_gppn=(vadr<<1)>>(PAGE_SHIFT+1);
   55.70 +    xen_mppn = gmfn_to_mfn(vcpu->domain, xen_gppn);
   55.71 +    xen_mppn=(xen_mppn<<PAGE_SHIFT)|(vpsr.cpl<<7);
   55.72      if(vadr>>63)
   55.73 -        mppn |= PHY_PAGE_UC;
   55.74 +        xen_mppn |= PHY_PAGE_UC;
   55.75      else
   55.76 -        mppn |= PHY_PAGE_WB;
   55.77 +        xen_mppn |= PHY_PAGE_WB;
   55.78  
   55.79      psr=ia64_clear_ic();
   55.80 -    ia64_itc(2,vadr&(~0xfff),mppn,EMUL_PHY_PAGE_SHIFT);
   55.81 +    ia64_itc(vec,vadr&PAGE_MASK,xen_mppn,PAGE_SHIFT);
   55.82      ia64_set_psr(psr);
   55.83      ia64_srlz_i();
   55.84      return;
   55.85 @@ -193,13 +187,13 @@ vmx_load_all_rr(VCPU *vcpu)
   55.86  	if (is_physical_mode(vcpu)) {
   55.87  		if (vcpu->arch.mode_flags & GUEST_PHY_EMUL)
   55.88  			panic("Unexpected domain switch in phy emul\n");
   55.89 -		phy_rr.rrval = vcpu->domain->arch.metaphysical_rr0;
   55.90 -    	phy_rr.ps = EMUL_PHY_PAGE_SHIFT;
   55.91 +		phy_rr.rrval = vcpu->arch.metaphysical_rr0;
   55.92 + //   	phy_rr.ps = PAGE_SHIFT;
   55.93      	phy_rr.ve = 1;
   55.94  
   55.95  		ia64_set_rr((VRN0 << VRN_SHIFT), phy_rr.rrval);
   55.96 -		phy_rr.rrval = vcpu->domain->arch.metaphysical_rr4;
   55.97 -    	phy_rr.ps = EMUL_PHY_PAGE_SHIFT;
   55.98 +		phy_rr.rrval = vcpu->arch.metaphysical_rr4;
   55.99 +//    	phy_rr.ps = PAGE_SHIFT;
  55.100  	    phy_rr.ve = 1;
  55.101  
  55.102  		ia64_set_rr((VRN4 << VRN_SHIFT), phy_rr.rrval);
  55.103 @@ -224,7 +218,7 @@ vmx_load_all_rr(VCPU *vcpu)
  55.104      extern void * pal_vaddr;
  55.105      vmx_switch_rr7(vmx_vrrtomrr(vcpu,VMX(vcpu, vrr[VRN7])),(void *)vcpu->domain->shared_info,
  55.106                  (void *)vcpu->arch.privregs,
  55.107 -                ( void *)vcpu->arch.vtlb->ts->vhpt->hash, pal_vaddr );
  55.108 +                (void *)vcpu->arch.vtlb->vhpt->hash, pal_vaddr );
  55.109      ia64_set_pta(vcpu->arch.arch_vmx.mpta);
  55.110  
  55.111  	ia64_srlz_d();
  55.112 @@ -242,12 +236,12 @@ switch_to_physical_rid(VCPU *vcpu)
  55.113      /* Save original virtual mode rr[0] and rr[4] */
  55.114      psr=ia64_clear_ic();
  55.115      phy_rr.rrval = vcpu->domain->arch.metaphysical_rr0;
  55.116 -    phy_rr.ps = EMUL_PHY_PAGE_SHIFT;
  55.117 +//    phy_rr.ps = EMUL_PHY_PAGE_SHIFT;
  55.118      phy_rr.ve = 1;
  55.119      ia64_set_rr(VRN0<<VRN_SHIFT, phy_rr.rrval);
  55.120      ia64_srlz_d();
  55.121      phy_rr.rrval = vcpu->domain->arch.metaphysical_rr4;
  55.122 -    phy_rr.ps = EMUL_PHY_PAGE_SHIFT;
  55.123 +//    phy_rr.ps = EMUL_PHY_PAGE_SHIFT;
  55.124      phy_rr.ve = 1;
  55.125      ia64_set_rr(VRN4<<VRN_SHIFT, phy_rr.rrval);
  55.126      ia64_srlz_d();
  55.127 @@ -266,10 +260,10 @@ switch_to_virtual_rid(VCPU *vcpu)
  55.128  
  55.129      psr=ia64_clear_ic();
  55.130  
  55.131 -    mrr=vmx_vcpu_rr(vcpu,VRN0<<VRN_SHIFT);
  55.132 +    vcpu_get_rr(vcpu,VRN0<<VRN_SHIFT,&mrr.rrval);
  55.133      ia64_set_rr(VRN0<<VRN_SHIFT, vmx_vrrtomrr(vcpu, mrr.rrval));
  55.134      ia64_srlz_d();
  55.135 -    mrr=vmx_vcpu_rr(vcpu,VRN4<<VRN_SHIFT);
  55.136 +    vcpu_get_rr(vcpu,VRN4<<VRN_SHIFT,&mrr.rrval);
  55.137      ia64_set_rr(VRN4<<VRN_SHIFT, vmx_vrrtomrr(vcpu, mrr.rrval));
  55.138      ia64_srlz_d();
  55.139      ia64_set_psr(psr);
    56.1 --- a/xen/arch/ia64/vmx/vmx_process.c	Mon Mar 20 09:56:46 2006 +0100
    56.2 +++ b/xen/arch/ia64/vmx/vmx_process.c	Mon Mar 20 09:56:54 2006 +0100
    56.3 @@ -58,6 +58,11 @@
    56.4  
    56.5  extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
    56.6  extern void rnat_consumption (VCPU *vcpu);
    56.7 +extern unsigned long translate_domain_mpaddr(unsigned long mpaddr);
    56.8 +extern void alt_itlb (VCPU *vcpu, u64 vadr);
    56.9 +extern void itlb_fault (VCPU *vcpu, u64 vadr);
   56.10 +extern void ivhpt_fault (VCPU *vcpu, u64 vadr);
   56.11 +
   56.12  #define DOMN_PAL_REQUEST    0x110000
   56.13  
   56.14  static UINT64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000, 0x1400,0x1800,
   56.15 @@ -292,10 +297,9 @@ IA64FAULT
   56.16  vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs)
   56.17  {
   56.18      IA64_PSR vpsr;
   56.19 -    CACHE_LINE_TYPE type=ISIDE_TLB;
   56.20 +    int type=ISIDE_TLB;
   56.21      u64 vhpt_adr, gppa;
   56.22      ISR misr;
   56.23 -    ia64_rr vrr;
   56.24  //    REGS *regs;
   56.25      thash_cb_t *vtlb;
   56.26      thash_data_t *data;
   56.27 @@ -315,34 +319,32 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
   56.28          return;
   56.29      }
   56.30  */
   56.31 -    if(vadr == 0x1ea18c00 ){
   56.32 +/*    if(vadr == 0x1ea18c00 ){
   56.33          ia64_clear_ic();
   56.34          while(1);
   56.35      }
   56.36 + */
   56.37      if(is_physical_mode(v)&&(!(vadr<<1>>62))){
   56.38 -        if(vec==1){
   56.39 -            physical_itlb_miss(v, vadr);
   56.40 -            return IA64_FAULT;
   56.41 -        }
   56.42          if(vec==2){
   56.43              if(v->domain!=dom0&&__gpfn_is_io(v->domain,(vadr<<1)>>(PAGE_SHIFT+1))){
   56.44                  emulate_io_inst(v,((vadr<<1)>>1),4);   //  UC
   56.45 -            }else{
   56.46 -                physical_dtlb_miss(v, vadr);
   56.47 +                return IA64_FAULT;
   56.48              }
   56.49 -            return IA64_FAULT;
   56.50          }
   56.51 +        physical_tlb_miss(v, vadr, vec);
   56.52 +        return IA64_FAULT;
   56.53      }
   56.54 -    vrr = vmx_vcpu_rr(v, vadr);
   56.55      if(vec == 1) type = ISIDE_TLB;
   56.56      else if(vec == 2) type = DSIDE_TLB;
   56.57      else panic("wrong vec\n");
   56.58  
   56.59  //    prepare_if_physical_mode(v);
   56.60  
   56.61 -    if((data=vtlb_lookup_ex(vtlb, vrr.rid, vadr,type))!=0){
   56.62 -	gppa = (vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
   56.63 -        if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){
   56.64 +    if((data=vtlb_lookup(vtlb, vadr,type))!=0){
   56.65 +//	gppa = (vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
   56.66 +//        if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){
   56.67 +        if(v->domain!=dom0 && data->io && type==DSIDE_TLB ){
   56.68 +        	gppa = (vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
   56.69              emulate_io_inst(v, gppa, data->ma);
   56.70              return IA64_FAULT;
   56.71          }
   56.72 @@ -356,7 +358,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
   56.73          }
   56.74          else{
   56.75   */
   56.76 -            thash_vhpt_insert(vtlb->ts->vhpt,data,vadr);
   56.77 +            thash_vhpt_insert(vtlb->vhpt,data->page_flags, data->itir ,vadr);
   56.78  //        }
   56.79  //	    }
   56.80      }else if(type == DSIDE_TLB){
   56.81 @@ -377,8 +379,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
   56.82              }
   56.83          } else{
   56.84              vmx_vcpu_thash(v, vadr, &vhpt_adr);
   56.85 -            vrr=vmx_vcpu_rr(v,vhpt_adr);
   56.86 -            if(vhpt_lookup(vhpt_adr) ||  vtlb_lookup_ex(vtlb, vrr.rid, vhpt_adr, DSIDE_TLB)){
   56.87 +            if(vhpt_lookup(vhpt_adr) ||  vtlb_lookup(vtlb, vhpt_adr, DSIDE_TLB)){
   56.88                  if(vpsr.ic){
   56.89                      vcpu_set_isr(v, misr.val);
   56.90                      dtlb_fault(v, vadr);
   56.91 @@ -420,8 +421,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
   56.92              return IA64_FAULT;
   56.93          } else{
   56.94              vmx_vcpu_thash(v, vadr, &vhpt_adr);
   56.95 -            vrr=vmx_vcpu_rr(v,vhpt_adr);
   56.96 -            if(vhpt_lookup(vhpt_adr) || vtlb_lookup_ex(vtlb, vrr.rid, vhpt_adr, DSIDE_TLB)){
   56.97 +            if(vhpt_lookup(vhpt_adr) || vtlb_lookup(vtlb, vhpt_adr, DSIDE_TLB)){
   56.98                  if(!vpsr.ic){
   56.99                      misr.ni=1;
  56.100                  }
    57.1 --- a/xen/arch/ia64/vmx/vmx_vcpu.c	Mon Mar 20 09:56:46 2006 +0100
    57.2 +++ b/xen/arch/ia64/vmx/vmx_vcpu.c	Mon Mar 20 09:56:54 2006 +0100
    57.3 @@ -204,32 +204,24 @@ vmx_vcpu_get_plat(VCPU *vcpu)
    57.4  }
    57.5  
    57.6  
    57.7 -ia64_rr vmx_vcpu_rr(VCPU *vcpu,UINT64 vadr)
    57.8 -{
    57.9 -        return (ia64_rr)VMX(vcpu,vrr[vadr>>61]);
   57.10 -}
   57.11 -
   57.12  
   57.13  IA64FAULT vmx_vcpu_set_rr(VCPU *vcpu, UINT64 reg, UINT64 val)
   57.14  {
   57.15      ia64_rr oldrr,newrr;
   57.16      thash_cb_t *hcb;
   57.17      extern void * pal_vaddr;
   57.18 -    oldrr=vmx_vcpu_rr(vcpu,reg);
   57.19 +    vcpu_get_rr(vcpu, reg, &oldrr.rrval);
   57.20      newrr.rrval=val;
   57.21 -#if 1
   57.22      if(oldrr.ps!=newrr.ps){
   57.23          hcb = vmx_vcpu_get_vtlb(vcpu);
   57.24          thash_purge_all(hcb);
   57.25      }
   57.26 -#endif
   57.27      VMX(vcpu,vrr[reg>>61]) = val;
   57.28 -
   57.29      switch((u64)(reg>>61)) {
   57.30      case VRN7:
   57.31 -       vmx_switch_rr7(vmx_vrrtomrr(vcpu,val),vcpu->domain->shared_info,
   57.32 +        vmx_switch_rr7(vmx_vrrtomrr(vcpu,val),vcpu->domain->shared_info,
   57.33          (void *)vcpu->arch.privregs,
   57.34 -       ( void *)vcpu->arch.vtlb->ts->vhpt->hash, pal_vaddr );
   57.35 +        (void *)vcpu->arch.vtlb->vhpt->hash, pal_vaddr );
   57.36         break;
   57.37      default:
   57.38          ia64_set_rr(reg,vmx_vrrtomrr(vcpu,val));
   57.39 @@ -275,7 +267,7 @@ check_entry(u64 va, u64 ps, char *str)
   57.40  u64 vmx_vcpu_get_itir_on_fault(VCPU *vcpu, u64 ifa)
   57.41  {
   57.42      ia64_rr rr,rr1;
   57.43 -    rr=vmx_vcpu_rr(vcpu,ifa);
   57.44 +    vcpu_get_rr(vcpu,ifa,&rr.rrval);
   57.45      rr1.rrval=0;
   57.46      rr1.ps=rr.ps;
   57.47      rr1.rid=rr.rid;
    58.1 --- a/xen/arch/ia64/vmx/vmx_virt.c	Mon Mar 20 09:56:46 2006 +0100
    58.2 +++ b/xen/arch/ia64/vmx/vmx_virt.c	Mon Mar 20 09:56:54 2006 +0100
    58.3 @@ -34,6 +34,7 @@
    58.4  #include <asm/virt_event.h>
    58.5  #include <asm/vmx_phy_mode.h>
    58.6  extern UINT64 privop_trace;
    58.7 +extern void vhpi_detection(VCPU *vcpu);//temporarily place here,need a header file.
    58.8  
    58.9  void
   58.10  ia64_priv_decoder(IA64_SLOT_TYPE slot_type, INST64 inst, UINT64  * cause)
   58.11 @@ -572,7 +573,7 @@ IA64FAULT vmx_emul_itr_d(VCPU *vcpu, INS
   58.12     }
   58.13  #endif // VMAL_NO_FAULT_CHECK
   58.14  
   58.15 -    return (vmx_vcpu_itr_d(vcpu,pte,itir,ifa,slot));
   58.16 +    return (vmx_vcpu_itr_d(vcpu,slot,pte,itir,ifa));
   58.17  }
   58.18  
   58.19  IA64FAULT vmx_emul_itr_i(VCPU *vcpu, INST64 inst)
   58.20 @@ -631,7 +632,7 @@ IA64FAULT vmx_emul_itr_i(VCPU *vcpu, INS
   58.21     }
   58.22  #endif // VMAL_NO_FAULT_CHECK
   58.23  
   58.24 -   return (vmx_vcpu_itr_i(vcpu,pte,itir,ifa,slot));
   58.25 +   return (vmx_vcpu_itr_i(vcpu,slot,pte,itir,ifa));
   58.26  }
   58.27  
   58.28  IA64FAULT itc_fault_check(VCPU *vcpu, INST64 inst, u64 *itir, u64 *ifa,u64 *pte)
   58.29 @@ -972,7 +973,7 @@ IA64FAULT vmx_emul_mov_from_rr(VCPU *vcp
   58.30          rsv_reg_field(vcpu);
   58.31      }
   58.32  #endif  //CHECK_FAULT
   58.33 -    vmx_vcpu_get_rr(vcpu,r3,&r1);
   58.34 +    vcpu_get_rr(vcpu,r3,&r1);
   58.35      return vcpu_set_gr(vcpu, inst.M43.r1, r1,0);
   58.36  }
   58.37  
    59.1 --- a/xen/arch/ia64/vmx/vtlb.c	Mon Mar 20 09:56:46 2006 +0100
    59.2 +++ b/xen/arch/ia64/vmx/vtlb.c	Mon Mar 20 09:56:54 2006 +0100
    59.3 @@ -32,7 +32,7 @@
    59.4  #include <asm/tlbflush.h>
    59.5  #define  MAX_CCH_LENGTH     40
    59.6  
    59.7 -thash_data_t *__alloc_chain(thash_cb_t *, thash_data_t *);
    59.8 +thash_data_t *__alloc_chain(thash_cb_t *);
    59.9  
   59.10  static void cch_mem_init(thash_cb_t *hcb)
   59.11  {
   59.12 @@ -71,36 +71,25 @@ static void cch_free(thash_cb_t *hcb, th
   59.13   * Check to see if the address rid:va is translated by the TLB
   59.14   */
   59.15  
   59.16 -static int __is_tr_translated(thash_data_t *tlb, u64 rid, u64 va, CACHE_LINE_TYPE cl)
   59.17 +static inline int __is_tr_translated(thash_data_t *trp, u64 rid, u64 va)
   59.18  {
   59.19 -    u64  size;
   59.20 -    size = PSIZE(tlb->ps);
   59.21 -    if(tlb->vadr&(size-1))
   59.22 -        while(1);
   59.23 -    if ((tlb->rid == rid) && ((va-tlb->vadr)<size))
   59.24 -        return 1;
   59.25 -    else
   59.26 -        return 0;
   59.27 +    return ((trp->p) && (trp->rid == rid) && ((va-trp->vadr)<PSIZE(trp->ps)));
   59.28  }
   59.29  
   59.30  /*
   59.31   * Only for GUEST TR format.
   59.32   */
   59.33  static int
   59.34 -__is_tr_overlap(thash_cb_t *hcb,thash_data_t *entry,int rid, char cl, u64 sva, u64 eva)
   59.35 +__is_tr_overlap(thash_data_t *trp, u64 rid, u64 sva, u64 eva)
   59.36  {
   59.37 -    uint64_t size, sa1, ea1;
   59.38 +    uint64_t sa1, ea1;
   59.39  
   59.40 -//    if ( entry->invalid || entry->rid != rid || (entry->cl != cl ) ) {
   59.41 -    if ( entry->invalid || entry->rid != rid ) {
   59.42 +    if (!trp->p || trp->rid != rid ) {
   59.43          return 0;
   59.44      }
   59.45 -    size = PSIZE(entry->ps);
   59.46 -    sa1 = entry->vadr;
   59.47 -    ea1 = sa1 + size -1;
   59.48 +    sa1 = trp->vadr;
   59.49 +    ea1 = sa1 + PSIZE(trp->ps) -1;
   59.50      eva -= 1;
   59.51 -    if(sa1&(size-1))
   59.52 -        while(1);
   59.53      if ( (sva>ea1) || (sa1>eva) )
   59.54          return 0;
   59.55      else
   59.56 @@ -108,90 +97,6 @@ static int
   59.57  
   59.58  }
   59.59  
   59.60 -static void __rem_tr (thash_cb_t *hcb, thash_data_t *tr)
   59.61 -{
   59.62 -/*
   59.63 -    if ( hcb->remove_notifier ) {
   59.64 -        (hcb->remove_notifier)(hcb,tr);
   59.65 -    }
   59.66 -*/
   59.67 -    tr->invalid = 1;
   59.68 -}
   59.69 -
   59.70 -static inline void __set_tr (thash_data_t *tr, thash_data_t *data, int idx)
   59.71 -{
   59.72 -    *tr = *data;
   59.73 -    tr->tr_idx = idx;
   59.74 -}
   59.75 -
   59.76 -
   59.77 -static void __init_tr(thash_cb_t *hcb)
   59.78 -{
   59.79 -    int i;
   59.80 -    thash_data_t *tr;
   59.81 -
   59.82 -    for ( i=0, tr = &ITR(hcb,0); i<NITRS; i++ ) {
   59.83 -        tr[i].invalid = 1;
   59.84 -    }
   59.85 -    for ( i=0, tr = &DTR(hcb,0); i<NDTRS; i++ ) {
   59.86 -        tr[i].invalid = 1;
   59.87 -    }
   59.88 -}
   59.89 -
   59.90 -/*
   59.91 - * Replace TR entry.
   59.92 - */
   59.93 -static void rep_tr(thash_cb_t *hcb,thash_data_t *insert, int idx)
   59.94 -{
   59.95 -    thash_data_t *tr;
   59.96 -
   59.97 -    if ( insert->cl == ISIDE_TLB ) {
   59.98 -        tr = &ITR(hcb,idx);
   59.99 -    }
  59.100 -    else {
  59.101 -        tr = &DTR(hcb,idx);
  59.102 -    }
  59.103 -    if ( !INVALID_TR(tr) ) {
  59.104 -        __rem_tr(hcb, tr);
  59.105 -    }
  59.106 -    __set_tr (tr, insert, idx);
  59.107 -}
  59.108 -
  59.109 -/*
  59.110 - * remove TR entry.
  59.111 - */
  59.112 -/*
  59.113 -static void rem_tr(thash_cb_t *hcb,CACHE_LINE_TYPE cl, int idx)
  59.114 -{
  59.115 -    thash_data_t *tr;
  59.116 -
  59.117 -    if ( cl == ISIDE_TLB ) {
  59.118 -        tr = &ITR(hcb,idx);
  59.119 -    }
  59.120 -    else {
  59.121 -        tr = &DTR(hcb,idx);
  59.122 -    }
  59.123 -    if ( !INVALID_TR(tr) ) {
  59.124 -        __rem_tr(hcb, tr);
  59.125 -    }
  59.126 -}
  59.127 - */
  59.128 -/*
  59.129 - * Delete an thash entry in collision chain.
  59.130 - *  prev: the previous entry.
  59.131 - *  rem: the removed entry.
  59.132 - */
  59.133 -/*
  59.134 -static void __rem_chain(thash_cb_t *hcb, thash_data_t *prev, thash_data_t *rem)
  59.135 -{
  59.136 -    //prev->next = rem->next;
  59.137 -    if ( hcb->remove_notifier ) {
  59.138 -         (hcb->remove_notifier)(hcb,rem);
  59.139 -    }
  59.140 -    cch_free (hcb, rem);
  59.141 -}
  59.142 - */
  59.143 -
  59.144  /*
  59.145   * Delete an thash entry leading collision chain.
  59.146   */
  59.147 @@ -212,71 +117,37 @@ static void __rem_hash_head(thash_cb_t *
  59.148      }
  59.149  }
  59.150  
  59.151 -thash_data_t *__vtr_lookup(thash_cb_t *hcb,
  59.152 -            u64 rid, u64 va,
  59.153 -            CACHE_LINE_TYPE cl)
  59.154 +thash_data_t *__vtr_lookup(VCPU *vcpu, u64 va, int is_data)
  59.155  {
  59.156 -    thash_data_t    *tr;
  59.157 -    int   num,i;
  59.158  
  59.159 -    if ( cl == ISIDE_TLB ) {
  59.160 -        tr = &ITR(hcb,0);
  59.161 -        num = NITRS;
  59.162 +    thash_data_t  *trp;
  59.163 +    int  i;
  59.164 +    u64 rid;
  59.165 +    vcpu_get_rr(vcpu, va, &rid);
  59.166 +    rid = rid&RR_RID_MASK;;
  59.167 +    if (is_data) {
  59.168 +        if (vcpu_quick_region_check(vcpu->arch.dtr_regions,va)) {
  59.169 +            for (trp =(thash_data_t *) vcpu->arch.dtrs,i=0; i<NDTRS; i++, trp++) {
  59.170 +                if (__is_tr_translated(trp, rid, va)) {
  59.171 +                    return trp;
  59.172 +                }
  59.173 +            }
  59.174 +        }
  59.175      }
  59.176      else {
  59.177 -        tr = &DTR(hcb,0);
  59.178 -        num = NDTRS;
  59.179 -    }
  59.180 -    for ( i=0; i<num; i++ ) {
  59.181 -        if ( !INVALID_TR(&tr[i]) &&
  59.182 -            __is_tr_translated(&tr[i], rid, va, cl) )
  59.183 -            return &tr[i];
  59.184 +        if (vcpu_quick_region_check(vcpu->arch.itr_regions,va)) {
  59.185 +            for (trp =(thash_data_t *) vcpu->arch.itrs,i=0; i<NITRS; i++, trp++) {
  59.186 +                if (__is_tr_translated(trp, rid, va)) {
  59.187 +                    return trp;
  59.188 +                }
  59.189 +            }
  59.190 +        }
  59.191      }
  59.192      return NULL;
  59.193  }
  59.194  
  59.195  
  59.196  /*
  59.197 - * Find overlap VHPT entry within current collision chain
  59.198 - * base on internal priv info.
  59.199 - */
  59.200 -/*
  59.201 -static inline thash_data_t* _vhpt_next_overlap_in_chain(thash_cb_t *hcb)
  59.202 -{
  59.203 -    thash_data_t    *cch;
  59.204 -    thash_internal_t *priv = &hcb->priv;
  59.205 -
  59.206 -
  59.207 -    for (cch=priv->cur_cch; cch; cch = cch->next) {
  59.208 -        if ( priv->tag == cch->etag  ) {
  59.209 -            return cch;
  59.210 -        }
  59.211 -    }
  59.212 -    return NULL;
  59.213 -}
  59.214 -*/
  59.215 -/*
  59.216 - * Find overlap TLB/VHPT entry within current collision chain
  59.217 - * base on internal priv info.
  59.218 - */
  59.219 -/*
  59.220 -static thash_data_t *_vtlb_next_overlap_in_chain(thash_cb_t *hcb)
  59.221 -{
  59.222 -    thash_data_t    *cch;
  59.223 -    thash_internal_t *priv = &hcb->priv;
  59.224 -
  59.225 -    // Find overlap TLB entry
  59.226 -    for (cch=priv->cur_cch; cch; cch = cch->next) {
  59.227 -        if ( ( cch->tc ? priv->s_sect.tc : priv->s_sect.tr )  &&
  59.228 -            __is_translated( cch, priv->rid, priv->_curva, priv->cl)) {
  59.229 -            return cch;
  59.230 -        }
  59.231 -    }
  59.232 -    return NULL;
  59.233 -}
  59.234 - */
  59.235 -
  59.236 -/*
  59.237   * Get the machine format of VHPT entry.
  59.238   *    PARAS:
  59.239   *  1: tlb: means the tlb format hash entry converting to VHPT.
  59.240 @@ -292,24 +163,16 @@ static thash_data_t *_vtlb_next_overlap_
  59.241   *  0/1: means successful or fail.
  59.242   *
  59.243   */
  59.244 -int __tlb_to_vhpt(thash_cb_t *hcb,
  59.245 -            thash_data_t *tlb, u64 va,
  59.246 -            thash_data_t *vhpt)
  59.247 +int __tlb_to_vhpt(thash_cb_t *hcb, thash_data_t *vhpt, u64 va)
  59.248  {
  59.249      u64 padr,pte;
  59.250 -//    ia64_rr vrr;
  59.251      ASSERT ( hcb->ht == THASH_VHPT );
  59.252 -//    vrr = (hcb->get_rr_fn)(hcb->vcpu,va);
  59.253 -    padr = tlb->ppn >>(tlb->ps-ARCH_PAGE_SHIFT)<<tlb->ps;
  59.254 -    padr += va&((1UL<<tlb->ps)-1);
  59.255 +    padr = vhpt->ppn >>(vhpt->ps-ARCH_PAGE_SHIFT)<<vhpt->ps;
  59.256 +    padr += va&((1UL<<vhpt->ps)-1);
  59.257      pte=lookup_domain_mpa(current->domain,padr);
  59.258      if((pte>>56))
  59.259          return 0;
  59.260 -    // TODO with machine discontinuous address space issue.
  59.261      vhpt->etag = ia64_ttag(va);
  59.262 -    //vhpt->ti = 0;
  59.263 -    vhpt->itir = tlb->itir & ~ITIR_RV_MASK;
  59.264 -    vhpt->page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
  59.265      vhpt->ps = PAGE_SHIFT;
  59.266      vhpt->ppn = (pte&((1UL<<IA64_MAX_PHYS_BITS)-(1UL<<PAGE_SHIFT)))>>ARCH_PAGE_SHIFT;
  59.267      vhpt->next = 0;
  59.268 @@ -331,17 +194,20 @@ static void thash_remove_cch(thash_cb_t 
  59.269  
  59.270  /*  vhpt only has entries with PAGE_SIZE page size */
  59.271  
  59.272 -void thash_vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
  59.273 +void thash_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
  59.274  {
  59.275      thash_data_t   vhpt_entry, *hash_table, *cch;
  59.276 +    vhpt_entry.page_flags = pte & ~PAGE_FLAGS_RV_MASK;
  59.277 +    vhpt_entry.itir=itir;
  59.278 +
  59.279  //    ia64_rr vrr;
  59.280  
  59.281 -    if ( !__tlb_to_vhpt(hcb, entry, va, &vhpt_entry) ) {
  59.282 +    if ( !__tlb_to_vhpt(hcb, &vhpt_entry, ifa) ) {
  59.283          return;
  59.284      //panic("Can't convert to machine VHPT entry\n");
  59.285      }
  59.286  
  59.287 -    hash_table = (thash_data_t *)ia64_thash(va);
  59.288 +    hash_table = (thash_data_t *)ia64_thash(ifa);
  59.289      if( INVALID_VHPT(hash_table) ) {
  59.290          *hash_table = vhpt_entry;
  59.291          hash_table->next = 0;
  59.292 @@ -358,6 +224,7 @@ void thash_vhpt_insert(thash_cb_t *hcb, 
  59.293          }
  59.294          cch = cch->next;
  59.295      }
  59.296 +
  59.297      if(hash_table->len>=MAX_CCN_DEPTH){
  59.298      	thash_remove_cch(hcb, hash_table);
  59.299      	cch = cch_alloc(hcb);
  59.300 @@ -367,9 +234,9 @@ void thash_vhpt_insert(thash_cb_t *hcb, 
  59.301          hash_table->next = cch;
  59.302      	return;
  59.303      }
  59.304 -	
  59.305 +
  59.306      // TODO: Add collision chain length limitation.
  59.307 -     cch = __alloc_chain(hcb,entry);
  59.308 +     cch = __alloc_chain(hcb);
  59.309       if(cch == NULL){
  59.310             *hash_table = vhpt_entry;
  59.311              hash_table->next = 0;
  59.312 @@ -377,10 +244,8 @@ void thash_vhpt_insert(thash_cb_t *hcb, 
  59.313              *cch = *hash_table;
  59.314              *hash_table = vhpt_entry;
  59.315              hash_table->next = cch;
  59.316 -	    hash_table->len = cch->len + 1;
  59.317 -	    cch->len = 0;	
  59.318 -//            if(hash_table->tag==hash_table->next->tag)
  59.319 -//                while(1);
  59.320 +    	    hash_table->len = cch->len + 1;
  59.321 +    	    cch->len = 0;
  59.322  
  59.323      }
  59.324      return /*hash_table*/;
  59.325 @@ -414,7 +279,7 @@ static void vtlb_purge(thash_cb_t *hcb, 
  59.326      thash_data_t *hash_table, *prev, *next;
  59.327      u64 start, end, size, tag, rid;
  59.328      ia64_rr vrr;
  59.329 -    vrr=vmx_vcpu_rr(current, va);
  59.330 +    vcpu_get_rr(current, va, &vrr.rrval);
  59.331      rid = vrr.rid;
  59.332      size = PSIZE(ps);
  59.333      start = va & (-size);
  59.334 @@ -480,36 +345,6 @@ static void vhpt_purge(thash_cb_t *hcb, 
  59.335      }
  59.336      machine_tlb_purge(va, ps);
  59.337  }
  59.338 -/*
  59.339 - * Insert an entry to hash table. 
  59.340 - *    NOTES:
  59.341 - *  1: TLB entry may be TR, TC or Foreign Map. For TR entry,
  59.342 - *     itr[]/dtr[] need to be updated too.
  59.343 - *  2: Inserting to collision chain may trigger recycling if 
  59.344 - *     the buffer for collision chain is empty.
  59.345 - *  3: The new entry is inserted at the next of hash table.
  59.346 - *     (I.e. head of the collision chain)
  59.347 - *  4: The buffer holding the entry is allocated internally
  59.348 - *     from cch_buf or just in the hash table.
  59.349 - *  5: Return the entry in hash table or collision chain.
  59.350 - *  6: Input parameter, entry, should be in TLB format.
  59.351 - *      I.e. Has va, rid, ps...
  59.352 - *  7: This API is invoked by emulating ITC/ITR and tlb_miss.
  59.353 - *
  59.354 - */
  59.355 -
  59.356 -void thash_tr_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va, int idx)
  59.357 -{
  59.358 -    if ( hcb->ht != THASH_TLB || entry->tc ) {
  59.359 -        panic("wrong parameter\n");
  59.360 -    }
  59.361 -    entry->vadr = PAGEALIGN(entry->vadr,entry->ps);
  59.362 -    entry->ppn = PAGEALIGN(entry->ppn, entry->ps-12);
  59.363 -    rep_tr(hcb, entry, idx);
  59.364 -//    thash_vhpt_insert(hcb->ts->vhpt, entry, va);
  59.365 -    return ;
  59.366 -}
  59.367 -
  59.368  
  59.369  /*
  59.370   * Recycle all collisions chain in VTLB or VHPT.
  59.371 @@ -525,8 +360,8 @@ void thash_recycle_cch(thash_cb_t *hcb)
  59.372          thash_remove_cch(hcb,hash_table);
  59.373      }
  59.374  }
  59.375 -/*
  59.376 -thash_data_t *vtlb_alloc_chain(thash_cb_t *hcb,thash_data_t *entry)
  59.377 +
  59.378 +thash_data_t *__alloc_chain(thash_cb_t *hcb)
  59.379  {
  59.380      thash_data_t *cch;
  59.381  
  59.382 @@ -537,23 +372,6 @@ thash_data_t *vtlb_alloc_chain(thash_cb_
  59.383      }
  59.384      return cch;
  59.385  }
  59.386 -*/
  59.387 -
  59.388 -thash_data_t *__alloc_chain(thash_cb_t *hcb,thash_data_t *entry)
  59.389 -{
  59.390 -    thash_data_t *cch;
  59.391 -
  59.392 -    cch = cch_alloc(hcb);
  59.393 -    if(cch == NULL){
  59.394 -        // recycle
  59.395 -//        if ( hcb->recycle_notifier ) {
  59.396 -//                hcb->recycle_notifier(hcb,(u64)entry);
  59.397 -//        }
  59.398 -        thash_recycle_cch(hcb);
  59.399 -        cch = cch_alloc(hcb);
  59.400 -    }
  59.401 -    return cch;
  59.402 -}
  59.403  
  59.404  /*
  59.405   * Insert an entry into hash TLB or VHPT.
  59.406 @@ -564,474 +382,117 @@ thash_data_t *__alloc_chain(thash_cb_t *
  59.407   *  3: The caller need to make sure the new entry will not overlap
  59.408   *     with any existed entry.
  59.409   */
  59.410 -void vtlb_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
  59.411 +void vtlb_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 va)
  59.412  {
  59.413      thash_data_t    *hash_table, *cch;
  59.414      /* int flag; */
  59.415      ia64_rr vrr;
  59.416      /* u64 gppn, ppns, ppne; */
  59.417 -    u64 tag;
  59.418 -    vrr=vmx_vcpu_rr(current, va);
  59.419 -    if (vrr.ps != entry->ps) {
  59.420 +    u64 tag, ps;
  59.421 +    ps = itir_ps(itir);
  59.422 +    vcpu_get_rr(current, va, &vrr.rrval);
  59.423 +    if (vrr.ps != ps) {
  59.424  //        machine_tlb_insert(hcb->vcpu, entry);
  59.425      	panic("not preferred ps with va: 0x%lx\n", va);
  59.426      	return;
  59.427      }
  59.428 -    entry->vadr = PAGEALIGN(entry->vadr,entry->ps);
  59.429 -    entry->ppn = PAGEALIGN(entry->ppn, entry->ps-12);
  59.430      hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
  59.431 -    entry->etag = tag;
  59.432      if( INVALID_TLB(hash_table) ) {
  59.433 -        *hash_table = *entry;
  59.434 +        hash_table->page_flags = pte;
  59.435 +        hash_table->itir=itir;
  59.436 +        hash_table->etag=tag;
  59.437          hash_table->next = 0;
  59.438      }
  59.439      else if (hash_table->len>=MAX_CCN_DEPTH){
  59.440          thash_remove_cch(hcb, hash_table);
  59.441          cch = cch_alloc(hcb);
  59.442          *cch = *hash_table;
  59.443 -        *hash_table = *entry;
  59.444 +        hash_table->page_flags = pte;
  59.445 +        hash_table->itir=itir;
  59.446 +        hash_table->etag=tag;
  59.447          hash_table->len = 1;
  59.448          hash_table->next = cch;
  59.449      }
  59.450 +
  59.451      else {
  59.452          // TODO: Add collision chain length limitation.
  59.453 -        cch = __alloc_chain(hcb,entry);
  59.454 +        cch = __alloc_chain(hcb);
  59.455          if(cch == NULL){
  59.456 -            *hash_table = *entry;
  59.457 +            hash_table->page_flags = pte;
  59.458 +            hash_table->itir=itir;
  59.459 +            hash_table->etag=tag;
  59.460              hash_table->next = 0;
  59.461          }else{
  59.462              *cch = *hash_table;
  59.463 -            *hash_table = *entry;
  59.464 +            hash_table->page_flags = pte;
  59.465 +            hash_table->itir=itir;
  59.466 +            hash_table->etag=tag;
  59.467              hash_table->next = cch;
  59.468              hash_table->len = cch->len + 1;
  59.469              cch->len = 0;
  59.470          }
  59.471      }
  59.472 -#if 0
  59.473 -    if(hcb->vcpu->domain->domain_id==0){
  59.474 -       thash_insert(hcb->ts->vhpt, entry, va);
  59.475 -        return;
  59.476 -    }
  59.477 -#endif
  59.478 -/*
  59.479 -    flag = 1;
  59.480 -    gppn = (POFFSET(va,entry->ps)|PAGEALIGN((entry->ppn<<12),entry->ps))>>PAGE_SHIFT;
  59.481 -    ppns = PAGEALIGN((entry->ppn<<12),entry->ps);
  59.482 -    ppne = ppns + PSIZE(entry->ps);
  59.483 -    if(((ppns<=0xa0000)&&(ppne>0xa0000))||((ppne>0xc0000)&&(ppns<=0xc0000)))
  59.484 -        flag = 0;
  59.485 -    if((__gpfn_is_mem(hcb->vcpu->domain, gppn)&&flag))
  59.486 -       thash_insert(hcb->ts->vhpt, entry, va);
  59.487 -*/
  59.488      return ;
  59.489  }
  59.490  
  59.491  
  59.492 -/*
  59.493 -void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va)
  59.494 -{
  59.495 -    thash_data_t    *hash_table;
  59.496 -    ia64_rr vrr;
  59.497 -    
  59.498 -    vrr = vmx_vcpu_rr(hcb->vcpu,entry->vadr);
  59.499 -    if ( entry->ps != vrr.ps && entry->tc ) {
  59.500 -        panic("Not support for multiple page size now\n");
  59.501 -    }
  59.502 -    entry->vadr = PAGEALIGN(entry->vadr,entry->ps);
  59.503 -    entry->ppn = PAGEALIGN(entry->ppn, entry->ps-12);
  59.504 -    (hcb->ins_hash)(hcb, entry, va);
  59.505 -    
  59.506 -}
  59.507 -*/
  59.508 -/*
  59.509 -static void rem_thash(thash_cb_t *hcb, thash_data_t *entry)
  59.510 +int vtr_find_overlap(VCPU *vcpu, u64 va, u64 ps, int is_data)
  59.511  {
  59.512 -    thash_data_t    *hash_table, *p, *q;
  59.513 -    thash_internal_t *priv = &hcb->priv;
  59.514 -    int idx;
  59.515 -
  59.516 -    hash_table = priv->hash_base;
  59.517 -    if ( hash_table == entry ) {
  59.518 -//        if ( PURGABLE_ENTRY(hcb, entry) ) {
  59.519 -            __rem_hash_head (hcb, entry);
  59.520 -//        }
  59.521 -        return ;
  59.522 -    }
  59.523 -    // remove from collision chain
  59.524 -    p = hash_table;
  59.525 -    for ( q=p->next; q; q = p->next ) {
  59.526 -        if ( q == entry ){
  59.527 -//            if ( PURGABLE_ENTRY(hcb,q ) ) {
  59.528 -                p->next = q->next;
  59.529 -                __rem_chain(hcb, entry);
  59.530 -                hash_table->len--;
  59.531 -//            }
  59.532 -            return ;
  59.533 +    thash_data_t  *trp;
  59.534 +    int  i;
  59.535 +    u64 end, rid;
  59.536 +    vcpu_get_rr(vcpu, va, &rid);
  59.537 +    rid = rid&RR_RID_MASK;;
  59.538 +    end = va + PSIZE(ps);
  59.539 +    if (is_data) {
  59.540 +        if (vcpu_quick_region_check(vcpu->arch.dtr_regions,va)) {
  59.541 +            for (trp =(thash_data_t *) vcpu->arch.dtrs,i=0; i<NDTRS; i++, trp++) {
  59.542 +                if (__is_tr_overlap(trp, rid, va, end )) {
  59.543 +                    return i;
  59.544 +                }
  59.545 +            }
  59.546          }
  59.547 -        p = q;
  59.548 -    }
  59.549 -    panic("Entry not existed or bad sequence\n");
  59.550 -}
  59.551 -*/
  59.552 -/*
  59.553 -static void rem_vtlb(thash_cb_t *hcb, thash_data_t *entry)
  59.554 -{
  59.555 -    thash_data_t    *hash_table, *p, *q;
  59.556 -    thash_internal_t *priv = &hcb->priv;
  59.557 -    int idx;
  59.558 -    
  59.559 -    if ( !entry->tc ) {
  59.560 -        return rem_tr(hcb, entry->cl, entry->tr_idx);
  59.561 -    }
  59.562 -    rem_thash(hcb, entry);
  59.563 -}    
  59.564 -*/
  59.565 -int   cch_depth=0;
  59.566 -/*
  59.567 - * Purge the collision chain starting from cch.
  59.568 - * NOTE:
  59.569 - *     For those UN-Purgable entries(FM), this function will return
  59.570 - * the head of left collision chain.
  59.571 - */
  59.572 -/*
  59.573 -static thash_data_t *thash_rem_cch(thash_cb_t *hcb, thash_data_t *cch)
  59.574 -{
  59.575 -    thash_data_t *next;
  59.576 -
  59.577 -//    if ( ++cch_depth > MAX_CCH_LENGTH ) {
  59.578 -//        printf ("cch length > MAX_CCH_LENGTH, exceed the expected length\n");
  59.579 -//        while(1);
  59.580 -//   }
  59.581 -    if ( cch -> next ) {
  59.582 -        next = thash_rem_cch(hcb, cch->next);
  59.583      }
  59.584      else {
  59.585 -        next = NULL;
  59.586 -    }
  59.587 -    if ( PURGABLE_ENTRY(hcb, cch) ) {
  59.588 -        __rem_chain(hcb, cch);
  59.589 -        return next;
  59.590 -    }
  59.591 -    else {
  59.592 -        cch->next = next;
  59.593 -        return cch;
  59.594 +        if (vcpu_quick_region_check(vcpu->arch.itr_regions,va)) {
  59.595 +            for (trp =(thash_data_t *) vcpu->arch.itrs,i=0; i<NITRS; i++, trp++) {
  59.596 +                if (__is_tr_overlap(trp, rid, va, end )) {
  59.597 +                    return i;
  59.598 +                }
  59.599 +            }
  59.600 +        }
  59.601      }
  59.602 -}
  59.603 - */
  59.604 -
  59.605 -/*
  59.606 - * Purge one hash line (include the entry in hash table).
  59.607 - * Can only be called by thash_purge_all.
  59.608 - * Input:
  59.609 - *  hash: The head of collision chain (hash table)
  59.610 - *
  59.611 - */
  59.612 -/*
  59.613 -static void thash_rem_line(thash_cb_t *hcb, thash_data_t *hash)
  59.614 -{
  59.615 -    if ( INVALID_ENTRY(hcb, hash) ) return;
  59.616 -
  59.617 -    if ( hash->next ) {
  59.618 -        cch_depth = 0;
  59.619 -        hash->next = thash_rem_cch(hcb, hash->next);
  59.620 -    }
  59.621 -    // Then hash table itself.
  59.622 -    if ( PURGABLE_ENTRY(hcb, hash) ) {
  59.623 -        __rem_hash_head(hcb, hash);
  59.624 -    }
  59.625 +    return -1;
  59.626  }
  59.627 - */
  59.628 -
  59.629 -/*
  59.630 - * Find an overlap entry in hash table and its collision chain.
  59.631 - * Refer to SDM2 4.1.1.4 for overlap definition.
  59.632 - *    PARAS:
  59.633 - *  1: in: TLB format entry, rid:ps must be same with vrr[].
  59.634 - *         va & ps identify the address space for overlap lookup
  59.635 - *  2: section can be combination of TR, TC and FM. (THASH_SECTION_XX)
  59.636 - *  3: cl means I side or D side.
  59.637 - *    RETURNS:
  59.638 - *  NULL to indicate the end of findings.
  59.639 - *    NOTES:
  59.640 - *
  59.641 - */
  59.642 -
  59.643 -/*
  59.644 -thash_data_t *thash_find_overlap(thash_cb_t *hcb,
  59.645 -            thash_data_t *in, search_section_t s_sect)
  59.646 -{
  59.647 -    return (hcb->find_overlap)(hcb, in->vadr,
  59.648 -            PSIZE(in->ps), in->rid, in->cl, s_sect);
  59.649 -}
  59.650 -*/
  59.651 -
  59.652 -/*
  59.653 -static thash_data_t *vtlb_find_overlap(thash_cb_t *hcb,
  59.654 -        u64 va, u64 size, int rid, char cl, search_section_t s_sect)
  59.655 -{
  59.656 -    thash_data_t    *hash_table;
  59.657 -    thash_internal_t *priv = &hcb->priv;
  59.658 -    u64     tag;
  59.659 -    ia64_rr vrr;
  59.660 -
  59.661 -    priv->_curva = va & ~(size-1);
  59.662 -    priv->_eva = priv->_curva + size;
  59.663 -    priv->rid = rid;
  59.664 -    vrr = vmx_vcpu_rr(hcb->vcpu,va);
  59.665 -    priv->ps = vrr.ps;
  59.666 -    hash_table = vsa_thash(hcb->pta, priv->_curva, vrr.rrval, &tag);
  59.667 -    priv->s_sect = s_sect;
  59.668 -    priv->cl = cl;
  59.669 -    priv->_tr_idx = 0;
  59.670 -    priv->hash_base = hash_table;
  59.671 -    priv->cur_cch = hash_table;
  59.672 -    return (hcb->next_overlap)(hcb);
  59.673 -}
  59.674 -*/
  59.675  
  59.676  /*
  59.677 -static thash_data_t *vhpt_find_overlap(thash_cb_t *hcb,
  59.678 -        u64 va, u64 size, int rid, char cl, search_section_t s_sect)
  59.679 + * Purge entries in VTLB and VHPT
  59.680 + */
  59.681 +void thash_purge_entries(thash_cb_t *hcb, u64 va, u64 ps)
  59.682  {
  59.683 -    thash_data_t    *hash_table;
  59.684 -    thash_internal_t *priv = &hcb->priv;
  59.685 -    u64     tag;
  59.686 -    ia64_rr vrr;
  59.687 -
  59.688 -    priv->_curva = va & ~(size-1);
  59.689 -    priv->_eva = priv->_curva + size;
  59.690 -    priv->rid = rid;
  59.691 -    vrr = vmx_vcpu_rr(hcb->vcpu,va);
  59.692 -    priv->ps = vrr.ps;
  59.693 -    hash_table = ia64_thash(priv->_curva);
  59.694 -    tag = ia64_ttag(priv->_curva);
  59.695 -    priv->tag = tag;
  59.696 -    priv->hash_base = hash_table;
  59.697 -    priv->cur_cch = hash_table;
  59.698 -    return (hcb->next_overlap)(hcb);
  59.699 -}
  59.700 -*/
  59.701 -
  59.702 -
  59.703 -thash_data_t *vtr_find_overlap(thash_cb_t *hcb, thash_data_t *data, char cl)
  59.704 -{
  59.705 -    thash_data_t    *tr;
  59.706 -    int  i,num;
  59.707 -    u64 end;
  59.708 -
  59.709 -    if (cl == ISIDE_TLB ) {
  59.710 -        num = NITRS;
  59.711 -        tr = &ITR(hcb,0);
  59.712 -    }
  59.713 -    else {
  59.714 -        num = NDTRS;
  59.715 -        tr = &DTR(hcb,0);
  59.716 -    }
  59.717 -    end=data->vadr + PSIZE(data->ps);
  59.718 -    for (i=0; i<num; i++ ) {
  59.719 -        if ( __is_tr_overlap(hcb, &tr[i], data->rid, cl, data->vadr, end )) {
  59.720 -            return &tr[i];
  59.721 -        }
  59.722 -    }
  59.723 -    return NULL;
  59.724 +    vtlb_purge(hcb, va, ps);
  59.725 +    vhpt_purge(hcb->vhpt, va, ps);
  59.726  }
  59.727  
  59.728  
  59.729  /*
  59.730 -static thash_data_t *vtr_find_next_overlap(thash_cb_t *hcb)
  59.731 -{
  59.732 -    thash_data_t    *tr;
  59.733 -    thash_internal_t *priv = &hcb->priv;
  59.734 -    int   num;
  59.735 -
  59.736 -    if ( priv->cl == ISIDE_TLB ) {
  59.737 -        num = NITRS;
  59.738 -        tr = &ITR(hcb,0);
  59.739 -    }
  59.740 -    else {
  59.741 -        num = NDTRS;
  59.742 -        tr = &DTR(hcb,0);
  59.743 -    }
  59.744 -    for (; priv->_tr_idx < num; priv->_tr_idx ++ ) {
  59.745 -        if ( __is_tr_overlap(hcb, &tr[priv->_tr_idx],
  59.746 -                priv->rid, priv->cl,
  59.747 -                priv->_curva, priv->_eva) ) {
  59.748 -            return &tr[priv->_tr_idx++];
  59.749 -        }
  59.750 -    }
  59.751 -    return NULL;
  59.752 -}
  59.753 -*/
  59.754 -
  59.755 -/*
  59.756 - * Similar with vtlb_next_overlap but find next entry.
  59.757 - *    NOTES:
  59.758 - *  Intermediate position information is stored in hcb->priv.
  59.759 - */
  59.760 -/*
  59.761 -static thash_data_t *vtlb_next_overlap(thash_cb_t *hcb)
  59.762 -{
  59.763 -    thash_data_t    *ovl;
  59.764 -    thash_internal_t *priv = &hcb->priv;
  59.765 -    u64 addr,rr_psize,tag;
  59.766 -    ia64_rr vrr;
  59.767 -
  59.768 -    if ( priv->s_sect.tr ) {
  59.769 -        ovl = vtr_find_next_overlap (hcb);
  59.770 -        if ( ovl ) return ovl;
  59.771 -        priv->s_sect.tr = 0;
  59.772 -    }
  59.773 -    if ( priv->s_sect.v == 0 ) return NULL;
  59.774 -    vrr = vmx_vcpu_rr(hcb->vcpu,priv->_curva);
  59.775 -    rr_psize = PSIZE(vrr.ps);
  59.776 -
  59.777 -    while ( priv->_curva < priv->_eva ) {
  59.778 -        if ( !INVALID_ENTRY(hcb, priv->hash_base) ) {
  59.779 -            ovl = _vtlb_next_overlap_in_chain(hcb);
  59.780 -            if ( ovl ) {
  59.781 -                priv->cur_cch = ovl->next;
  59.782 -                return ovl;
  59.783 -            }
  59.784 -        }
  59.785 -        priv->_curva += rr_psize;
  59.786 -        priv->hash_base = vsa_thash( hcb->pta, priv->_curva, vrr.rrval, &tag);
  59.787 -        priv->cur_cch = priv->hash_base;
  59.788 -    }
  59.789 -    return NULL;
  59.790 -}
  59.791 - */
  59.792 -
  59.793 -
  59.794 -/*
  59.795 -static thash_data_t *vhpt_next_overlap(thash_cb_t *hcb)
  59.796 -{
  59.797 -    thash_data_t    *ovl;
  59.798 -    thash_internal_t *priv = &hcb->priv;
  59.799 -    u64 addr,rr_psize;
  59.800 -    ia64_rr vrr;
  59.801 -
  59.802 -    vrr = vmx_vcpu_rr(hcb->vcpu,priv->_curva);
  59.803 -    rr_psize = PSIZE(vrr.ps);
  59.804 -
  59.805 -    while ( priv->_curva < priv->_eva ) {
  59.806 -        if ( !INVALID_ENTRY(hcb, priv->hash_base) ) {
  59.807 -            ovl = _vhpt_next_overlap_in_chain(hcb);
  59.808 -            if ( ovl ) {
  59.809 -                priv->cur_cch = ovl->next;
  59.810 -                return ovl;
  59.811 -            }
  59.812 -        }
  59.813 -        priv->_curva += rr_psize;
  59.814 -        priv->hash_base = ia64_thash(priv->_curva);
  59.815 -        priv->tag = ia64_ttag(priv->_curva);
  59.816 -        priv->cur_cch = priv->hash_base;
  59.817 -    }
  59.818 -    return NULL;
  59.819 -}
  59.820 -*/
  59.821 -
  59.822 -/*
  59.823 - * Find and purge overlap entries in hash table and its collision chain.
  59.824 - *    PARAS:
  59.825 - *  1: in: TLB format entry, rid:ps must be same with vrr[].
  59.826 - *         rid, va & ps identify the address space for purge
  59.827 - *  2: section can be combination of TR, TC and FM. (thash_SECTION_XX)
  59.828 - *  3: cl means I side or D side.
  59.829 - *    NOTES:
  59.830 - *
  59.831 - */
  59.832 -void thash_purge_entries(thash_cb_t *hcb,
  59.833 -            thash_data_t *in, search_section_t p_sect)
  59.834 -{
  59.835 -    return thash_purge_entries_ex(hcb, in->rid, in->vadr,
  59.836 -            in->ps, p_sect, in->cl);
  59.837 -}
  59.838 -
  59.839 -void thash_purge_entries_ex(thash_cb_t *hcb,
  59.840 -            u64 rid, u64 va, u64 ps,
  59.841 -            search_section_t p_sect,
  59.842 -            CACHE_LINE_TYPE cl)
  59.843 -{
  59.844 -/*
  59.845 -    thash_data_t    *ovl;
  59.846 -
  59.847 -    ovl = (hcb->find_overlap)(hcb, va, PSIZE(ps), rid, cl, p_sect);
  59.848 -    while ( ovl != NULL ) {
  59.849 -        (hcb->rem_hash)(hcb, ovl);
  59.850 -        ovl = (hcb->next_overlap)(hcb);
  59.851 -    };
  59.852 - */
  59.853 -    vtlb_purge(hcb, va, ps);
  59.854 -    vhpt_purge(hcb->ts->vhpt, va, ps);
  59.855 -}
  59.856 -
  59.857 -/*
  59.858   * Purge overlap TCs and then insert the new entry to emulate itc ops.
  59.859   *    Notes: Only TC entry can purge and insert.
  59.860   */
  59.861 -void thash_purge_and_insert(thash_cb_t *hcb, thash_data_t *in, u64 va)
  59.862 +void thash_purge_and_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
  59.863  {
  59.864 -    /* thash_data_t    *ovl; */
  59.865 -    search_section_t sections;
  59.866 -
  59.867 -#ifdef   XEN_DEBUGGER
  59.868 -    vrr = vmx_vcpu_rr(hcb->vcpu,in->vadr);
  59.869 -	if ( in->ps != vrr.ps || hcb->ht != THASH_TLB || !in->tc ) {
  59.870 -		panic ("Oops, wrong call for purge_and_insert\n");
  59.871 -		return;
  59.872 -	}
  59.873 -#endif
  59.874 -    in->vadr = PAGEALIGN(in->vadr,in->ps);
  59.875 -    in->ppn = PAGEALIGN(in->ppn, in->ps-12);
  59.876 -    sections.tr = 0;
  59.877 -    sections.tc = 1;
  59.878 -/*
  59.879 -    ovl = (hcb->find_overlap)(hcb, in->vadr, PSIZE(in->ps),
  59.880 -    				 in->rid, in->cl, sections);
  59.881 -    if(ovl)
  59.882 -        (hcb->rem_hash)(hcb, ovl);
  59.883 - */
  59.884 -    vtlb_purge(hcb, va, in->ps);
  59.885 -    vhpt_purge(hcb->ts->vhpt, va, in->ps);
  59.886 -#ifdef   XEN_DEBUGGER
  59.887 -    ovl = (hcb->next_overlap)(hcb);
  59.888 -    if ( ovl ) {
  59.889 -		panic ("Oops, 2+ overlaps for purge_and_insert\n");
  59.890 -		return;
  59.891 +    u64 ps, va;
  59.892 +    ps = itir_ps(itir);
  59.893 +    va = PAGEALIGN(ifa,ps);
  59.894 +    vtlb_purge(hcb, va, ps);
  59.895 +    vhpt_purge(hcb->vhpt, va, ps);
  59.896 +    if((ps!=PAGE_SHIFT)||(pte&VTLB_PTE_IO))
  59.897 +        vtlb_insert(hcb, pte, itir, va);
  59.898 +    if(!(pte&VTLB_PTE_IO)){
  59.899 +        va = PAGEALIGN(ifa,PAGE_SHIFT);
  59.900 +        thash_vhpt_insert(hcb->vhpt, pte, itir, va);
  59.901      }
  59.902 -#endif
  59.903 -    if(in->ps!=PAGE_SHIFT)
  59.904 -        vtlb_insert(hcb, in, va);
  59.905 -    thash_vhpt_insert(hcb->ts->vhpt, in, va);
  59.906  }
  59.907 -/*
  59.908 - * Purge one hash line (include the entry in hash table).
  59.909 - * Can only be called by thash_purge_all.
  59.910 - * Input:
  59.911 - *  hash: The head of collision chain (hash table)
  59.912 - *
  59.913 - */
  59.914 -/*
  59.915 -static void thash_purge_line(thash_cb_t *hcb, thash_data_t *hash)
  59.916 -{
  59.917 -    if ( INVALID_ENTRY(hcb, hash) ) return;
  59.918 -    thash_data_t *prev, *next;
  59.919 -    next=hash->next;
  59.920 -    while ( next ) {
  59.921 -        prev=next;
  59.922 -        next=next->next;
  59.923 -        cch_free(hcb, prev);
  59.924 -    }
  59.925 -    // Then hash table itself.
  59.926 -    INVALIDATE_HASH(hcb, hash);
  59.927 -}
  59.928 -*/
  59.929 -
  59.930 -
  59.931 -
  59.932 -
  59.933 -
  59.934 -
  59.935  
  59.936  
  59.937  
  59.938 @@ -1064,27 +525,12 @@ void thash_purge_all(thash_cb_t *hcb)
  59.939      }
  59.940      cch_mem_init (hcb);
  59.941  
  59.942 -    vhpt = hcb->ts->vhpt;
  59.943 +    vhpt = hcb->vhpt;
  59.944      hash_table = (thash_data_t*)((u64)vhpt->hash + vhpt->hash_sz);
  59.945      for (--hash_table;(u64)hash_table >= (u64)vhpt->hash;hash_table--) {
  59.946          INVALIDATE_VHPT_HEADER(hash_table);
  59.947      }
  59.948      cch_mem_init (vhpt);
  59.949 -    
  59.950 -/*
  59.951 -    entry = &hcb->ts->itr[0];
  59.952 -    for(i=0; i< (NITRS+NDTRS); i++){
  59.953 -        if(!INVALID_TLB(entry)){
  59.954 -            start=entry->vadr & (-PSIZE(entry->ps));
  59.955 -            end = start + PSIZE(entry->ps);
  59.956 -            while(start<end){
  59.957 -                thash_vhpt_insert(vhpt, entry, start);
  59.958 -                start += PAGE_SIZE;
  59.959 -            }
  59.960 -        }
  59.961 -        entry++;
  59.962 -    }
  59.963 -*/
  59.964      local_flush_tlb_all();
  59.965  }
  59.966  
  59.967 @@ -1096,100 +542,32 @@ void thash_purge_all(thash_cb_t *hcb)
  59.968   * INPUT:
  59.969   *  in: TLB format for both VHPT & TLB.
  59.970   */
  59.971 -thash_data_t *vtlb_lookup(thash_cb_t *hcb, 
  59.972 -            thash_data_t *in)
  59.973 -{
  59.974 -    return vtlb_lookup_ex(hcb, in->rid, in->vadr, in->cl);
  59.975 -}
  59.976  
  59.977 -thash_data_t *vtlb_lookup_ex(thash_cb_t *hcb, 
  59.978 -            u64 rid, u64 va,
  59.979 -            CACHE_LINE_TYPE cl)
  59.980 +thash_data_t *vtlb_lookup(thash_cb_t *hcb, u64 va,int is_data)
  59.981  {
  59.982      thash_data_t    *hash_table, *cch;
  59.983      u64     tag;
  59.984      ia64_rr vrr;
  59.985 -   
  59.986 +
  59.987      ASSERT ( hcb->ht == THASH_TLB );
  59.988 -    
  59.989 -    cch = __vtr_lookup(hcb, rid, va, cl);;
  59.990 +
  59.991 +    cch = __vtr_lookup(hcb->vcpu, va, is_data);;
  59.992      if ( cch ) return cch;
  59.993  
  59.994 -    vrr = vmx_vcpu_rr(hcb->vcpu,va);
  59.995 +    vcpu_get_rr(hcb->vcpu,va,&vrr.rrval);
  59.996      hash_table = vsa_thash( hcb->pta, va, vrr.rrval, &tag);
  59.997  
  59.998      if ( INVALID_ENTRY(hcb, hash_table ) )
  59.999          return NULL;
 59.1000  
 59.1001 -        
 59.1002 +
 59.1003      for (cch=hash_table; cch; cch = cch->next) {
 59.1004 -//        if ( __is_translated(cch, rid, va, cl) )
 59.1005          if(cch->etag == tag)
 59.1006              return cch;
 59.1007      }
 59.1008      return NULL;
 59.1009  }
 59.1010  
 59.1011 -/*
 59.1012 - * Lock/Unlock TC if found.
 59.1013 - *     NOTES: Only the page in prefered size can be handled.
 59.1014 - *   return:
 59.1015 - *          1: failure
 59.1016 - *          0: success
 59.1017 - */
 59.1018 -/*
 59.1019 -int thash_lock_tc(thash_cb_t *hcb, u64 va, u64 size, int rid, char cl, int lock)
 59.1020 -{
 59.1021 -	thash_data_t	*ovl;
 59.1022 -	search_section_t	sections;
 59.1023 -
 59.1024 -    sections.tr = 1;
 59.1025 -    sections.tc = 1;
 59.1026 -	ovl = (hcb->find_overlap)(hcb, va, size, rid, cl, sections);
 59.1027 -	if ( ovl ) {
 59.1028 -		if ( !ovl->tc ) {
 59.1029 -//			panic("Oops, TR for lock\n");
 59.1030 -			return 0;
 59.1031 -		}
 59.1032 -		else if ( lock ) {
 59.1033 -			if ( ovl->locked ) {
 59.1034 -				DPRINTK("Oops, already locked entry\n");
 59.1035 -			}
 59.1036 -			ovl->locked = 1;
 59.1037 -		}
 59.1038 -		else if ( !lock ) {
 59.1039 -			if ( !ovl->locked ) {
 59.1040 -				DPRINTK("Oops, already unlocked entry\n");
 59.1041 -			}
 59.1042 -			ovl->locked = 0;
 59.1043 -		}
 59.1044 -		return 0;
 59.1045 -	}
 59.1046 -	return 1;
 59.1047 -}
 59.1048 -*/
 59.1049 -
 59.1050 -/*
 59.1051 - * Notifier when TLB is deleted from hash table and its collision chain.
 59.1052 - * NOTES:
 59.1053 - *  The typical situation is that TLB remove needs to inform
 59.1054 - * VHPT to remove too.
 59.1055 - * PARAS:
 59.1056 - *  1: hcb is TLB object.
 59.1057 - *  2: The format of entry is always in TLB.
 59.1058 - *
 59.1059 - */
 59.1060 -//void tlb_remove_notifier(thash_cb_t *hcb, thash_data_t *entry)
 59.1061 -//{
 59.1062 -//    vhpt_purge(hcb->ts->vhpt,entry->vadr,entry->ps);
 59.1063 -//    thash_cb_t  *vhpt;
 59.1064 -    
 59.1065 -//    search_section_t    s_sect;
 59.1066 -    
 59.1067 -//    s_sect.v = 0;
 59.1068 -//    thash_purge_entries(hcb->ts->vhpt, entry, s_sect);
 59.1069 -//    machine_tlb_purge(entry->vadr, entry->ps);
 59.1070 -//}
 59.1071  
 59.1072  /*
 59.1073   * Initialize internal control data before service.
 59.1074 @@ -1206,28 +584,15 @@ void thash_init(thash_cb_t *hcb, u64 sz)
 59.1075      hcb->pta.size = sz;
 59.1076  //    hcb->get_rr_fn = vmmu_get_rr;
 59.1077      ASSERT ( hcb->hash_sz % sizeof(thash_data_t) == 0 );
 59.1078 -    if ( hcb->ht == THASH_TLB ) {
 59.1079 -//        hcb->remove_notifier =  NULL;	//tlb_remove_notifier;
 59.1080 -//        hcb->find_overlap = vtlb_find_overlap;
 59.1081 -//        hcb->next_overlap = vtlb_next_overlap;
 59.1082 -//        hcb->rem_hash = rem_vtlb;
 59.1083 -//        hcb->ins_hash = vtlb_insert;
 59.1084 -        __init_tr(hcb);
 59.1085 -    }
 59.1086 -    else {
 59.1087 -//        hcb->remove_notifier =  NULL;
 59.1088 -//        hcb->find_overlap = vhpt_find_overlap;
 59.1089 -//        hcb->next_overlap = vhpt_next_overlap;
 59.1090 -//        hcb->rem_hash = rem_thash;
 59.1091 -//        hcb->ins_hash = thash_vhpt_insert;
 59.1092 -    }
 59.1093      hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
 59.1094  
 59.1095      for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
 59.1096          INVALIDATE_HASH_HEADER(hcb,hash_table);
 59.1097      }
 59.1098  }
 59.1099 +
 59.1100  #ifdef  VTLB_DEBUG
 59.1101 +/*
 59.1102  static  u64 cch_length_statistics[MAX_CCH_LENGTH+1];
 59.1103  u64  sanity_check=0;
 59.1104  u64 vtlb_chain_sanity(thash_cb_t *vtlb, thash_cb_t *vhpt, thash_data_t *hash)
 59.1105 @@ -1264,7 +629,7 @@ void check_vtlb_sanity(thash_cb_t *vtlb)
 59.1106      thash_data_t  *hash, *cch;
 59.1107      thash_data_t    *ovl;
 59.1108      search_section_t s_sect;
 59.1109 -    thash_cb_t *vhpt = vtlb->ts->vhpt;
 59.1110 +    thash_cb_t *vhpt = vtlb->vhpt;
 59.1111      u64   invalid_ratio;
 59.1112   
 59.1113      if ( sanity_check == 0 ) return;
 59.1114 @@ -1403,4 +768,5 @@ void dump_vtlb(thash_cb_t *vtlb)
 59.1115      }
 59.1116      printf("End of vTLB dump\n");
 59.1117  }
 59.1118 +*/
 59.1119  #endif
    60.1 --- a/xen/arch/ia64/xen/dom_fw.c	Mon Mar 20 09:56:46 2006 +0100
    60.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Mon Mar 20 09:56:54 2006 +0100
    60.3 @@ -47,7 +47,7 @@ unsigned long dom_pa(unsigned long imva)
    60.4  }
    60.5  
    60.6  // builds a hypercall bundle at domain physical address
    60.7 -void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall)
    60.8 +static void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall)
    60.9  {
   60.10  	unsigned long *imva;
   60.11  
   60.12 @@ -96,122 +96,13 @@ unsigned long dom_fw_setup(struct domain
   60.13  # define NUM_MEM_DESCS	5
   60.14  
   60.15  
   60.16 -#define SECS_PER_HOUR   (60 * 60)
   60.17 -#define SECS_PER_DAY    (SECS_PER_HOUR * 24)
   60.18 -
   60.19 -/* Compute the `struct tm' representation of *T,
   60.20 -   offset OFFSET seconds east of UTC,
   60.21 -   and store year, yday, mon, mday, wday, hour, min, sec into *TP.
   60.22 -   Return nonzero if successful.  */
   60.23 -int
   60.24 -offtime (unsigned long t, efi_time_t *tp)
   60.25 -{
   60.26 -	const unsigned short int __mon_yday[2][13] =
   60.27 -	{
   60.28 -		/* Normal years.  */
   60.29 -		{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
   60.30 -		/* Leap years.  */
   60.31 -		{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
   60.32 -	};
   60.33 -	long int days, rem, y;
   60.34 -	const unsigned short int *ip;
   60.35 -
   60.36 -	days = t / SECS_PER_DAY;
   60.37 -	rem = t % SECS_PER_DAY;
   60.38 -	while (rem < 0) {
   60.39 -		rem += SECS_PER_DAY;
   60.40 -		--days;
   60.41 -	}
   60.42 -	while (rem >= SECS_PER_DAY) {
   60.43 -		rem -= SECS_PER_DAY;
   60.44 -		++days;
   60.45 -	}
   60.46 -	tp->hour = rem / SECS_PER_HOUR;
   60.47 -	rem %= SECS_PER_HOUR;
   60.48 -	tp->minute = rem / 60;
   60.49 -	tp->second = rem % 60;
   60.50 -	/* January 1, 1970 was a Thursday.  */
   60.51 -	y = 1970;
   60.52 -
   60.53 -#	define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
   60.54 -#	define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
   60.55 -#	define __isleap(year) \
   60.56 -	  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
   60.57 -
   60.58 -	while (days < 0 || days >= (__isleap (y) ? 366 : 365)) {
   60.59 -		/* Guess a corrected year, assuming 365 days per year.  */
   60.60 -		long int yg = y + days / 365 - (days % 365 < 0);
   60.61 -
   60.62 -		/* Adjust DAYS and Y to match the guessed year.  */
   60.63 -		days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)
   60.64 -			 - LEAPS_THRU_END_OF (y - 1));
   60.65 -		y = yg;
   60.66 -	}
   60.67 -	tp->year = y;
   60.68 -	ip = __mon_yday[__isleap(y)];
   60.69 -	for (y = 11; days < (long int) ip[y]; --y)
   60.70 -		continue;
   60.71 -	days -= ip[y];
   60.72 -	tp->month = y + 1;
   60.73 -	tp->day = days + 1;
   60.74 -	return 1;
   60.75 -}
   60.76 -
   60.77 -/* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
   60.78 -
   60.79 -#define BUILD_CMD(addr)		((0x80000000 | (addr)) & ~3)
   60.80 -
   60.81 -#define REG_OFFSET(addr)	(0x00000000000000FF & (addr))
   60.82 -#define DEVICE_FUNCTION(addr)	(0x000000000000FF00 & (addr))
   60.83 -#define BUS_NUMBER(addr)	(0x0000000000FF0000 & (addr))
   60.84 -
   60.85 -#ifndef XEN
   60.86 -static efi_status_t
   60.87 -fw_efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
   60.88 -{
   60.89 -#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
   60.90 -	struct {
   60.91 -		int tv_sec;	/* must be 32bits to work */
   60.92 -		int tv_usec;
   60.93 -	} tv32bits;
   60.94 -
   60.95 -	ssc((unsigned long) &tv32bits, 0, 0, 0, SSC_GET_TOD);
   60.96 -
   60.97 -	memset(tm, 0, sizeof(*tm));
   60.98 -	offtime(tv32bits.tv_sec, tm);
   60.99 -
  60.100 -	if (tc)
  60.101 -		memset(tc, 0, sizeof(*tc));
  60.102 -#else
  60.103 -#	error Not implemented yet...
  60.104 -#endif
  60.105 -	return EFI_SUCCESS;
  60.106 -}
  60.107 -
  60.108 -static void
  60.109 -efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
  60.110 -{
  60.111 -#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
  60.112 -	ssc(status, 0, 0, 0, SSC_EXIT);
  60.113 -#else
  60.114 -#	error Not implemented yet...
  60.115 -#endif
  60.116 -}
  60.117 -
  60.118 -static efi_status_t
  60.119 -efi_unimplemented (void)
  60.120 -{
  60.121 -	return EFI_UNSUPPORTED;
  60.122 -}
  60.123 -#endif /* !XEN */
  60.124 -
  60.125  struct sal_ret_values
  60.126  sal_emulator (long index, unsigned long in1, unsigned long in2,
  60.127  	      unsigned long in3, unsigned long in4, unsigned long in5,
  60.128  	      unsigned long in6, unsigned long in7)
  60.129  {
  60.130 -	long r9  = 0;
  60.131 -	long r10 = 0;
  60.132 +	unsigned long r9  = 0;
  60.133 +	unsigned long r10 = 0;
  60.134  	long r11 = 0;
  60.135  	long status;
  60.136  
  60.137 @@ -285,12 +176,11 @@ sal_emulator (long index, unsigned long 
  60.138  }
  60.139  
  60.140  struct ia64_pal_retval
  60.141 -xen_pal_emulator(unsigned long index, unsigned long in1,
  60.142 -	unsigned long in2, unsigned long in3)
  60.143 +xen_pal_emulator(unsigned long index, u64 in1, u64 in2, u64 in3)
  60.144  {
  60.145 -	long r9  = 0;
  60.146 -	long r10 = 0;
  60.147 -	long r11 = 0;
  60.148 +	unsigned long r9  = 0;
  60.149 +	unsigned long r10 = 0;
  60.150 +	unsigned long r11 = 0;
  60.151  	long status = -1;
  60.152  
  60.153  	if (running_on_sim) return pal_emulator_static(index);
  60.154 @@ -364,7 +254,7 @@ xen_pal_emulator(unsigned long index, un
  60.155  				&r10);
  60.156  		break;
  60.157  	    case PAL_REGISTER_INFO:
  60.158 -		status = ia64_pal_register_info(in1,&r9,&r10);
  60.159 +		status = ia64_pal_register_info(in1, &r9, &r10);
  60.160  		break;
  60.161  	    case PAL_CACHE_FLUSH:
  60.162  		/* FIXME */
  60.163 @@ -434,7 +324,7 @@ xen_pal_emulator(unsigned long index, un
  60.164  
  60.165  #define NFUNCPTRS 20
  60.166  
  60.167 -void print_md(efi_memory_desc_t *md)
  60.168 +static void print_md(efi_memory_desc_t *md)
  60.169  {
  60.170  #if 1
  60.171  	printk("domain mem: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
  60.172 @@ -496,7 +386,7 @@ acpi_update_madt_checksum (unsigned long
  60.173  }
  60.174  
  60.175  /* base is physical address of acpi table */
  60.176 -void touch_acpi_table(void)
  60.177 +static void touch_acpi_table(void)
  60.178  {
  60.179  	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0)
  60.180  		printk("Error parsing MADT - no LAPIC entires\n");
  60.181 @@ -514,15 +404,15 @@ struct fake_acpi_tables {
  60.182  	struct acpi_table_header dsdt;
  60.183  	u8 aml[16];
  60.184  	struct acpi_table_madt madt;
  60.185 -	struct acpi_table_lsapic lsapic;
  60.186 +	struct acpi_table_lsapic lsapic[MAX_VIRT_CPUS];
  60.187  	u8 pm1a_evt_blk[4];
  60.188  	u8 pm1a_cnt_blk[1];
  60.189  	u8 pm_tmr_blk[4];
  60.190  };
  60.191  
  60.192  /* Create enough of an ACPI structure to make the guest OS ACPI happy. */
  60.193 -void
  60.194 -dom_fw_fake_acpi(struct fake_acpi_tables *tables)
  60.195 +static void
  60.196 +dom_fw_fake_acpi(struct domain *d, struct fake_acpi_tables *tables)
  60.197  {
  60.198  	struct acpi20_table_rsdp *rsdp = &tables->rsdp;
  60.199  	struct xsdt_descriptor_rev2 *xsdt = &tables->xsdt;
  60.200 @@ -530,7 +420,8 @@ dom_fw_fake_acpi(struct fake_acpi_tables
  60.201  	struct facs_descriptor_rev2 *facs = &tables->facs;
  60.202  	struct acpi_table_header *dsdt = &tables->dsdt;
  60.203  	struct acpi_table_madt *madt = &tables->madt;
  60.204 -	struct acpi_table_lsapic *lsapic = &tables->lsapic;
  60.205 +	struct acpi_table_lsapic *lsapic = tables->lsapic;
  60.206 +	int i;
  60.207  
  60.208  	memset(tables, 0, sizeof(struct fake_acpi_tables));
  60.209  
  60.210 @@ -608,13 +499,13 @@ dom_fw_fake_acpi(struct fake_acpi_tables
  60.211  	/* Trivial namespace, avoids ACPI CA complaints */
  60.212  	tables->aml[0] = 0x10; /* Scope */
  60.213  	tables->aml[1] = 0x12; /* length/offset to next object */
  60.214 -	strncpy(&tables->aml[2], "_SB_", 4);
  60.215 +	strncpy((char *)&tables->aml[2], "_SB_", 4);
  60.216  
  60.217  	/* The processor object isn't absolutely necessary, revist for SMP */
  60.218  	tables->aml[6] = 0x5b; /* processor object */
  60.219  	tables->aml[7] = 0x83;
  60.220  	tables->aml[8] = 0x0b; /* next */
  60.221 -	strncpy(&tables->aml[9], "CPU0", 4);
  60.222 +	strncpy((char *)&tables->aml[9], "CPU0", 4);
  60.223  
  60.224  	dsdt->checksum = generate_acpi_checksum(dsdt, dsdt->length);
  60.225  
  60.226 @@ -622,16 +513,20 @@ dom_fw_fake_acpi(struct fake_acpi_tables
  60.227  	strncpy(madt->header.signature, APIC_SIG, 4);
  60.228  	madt->header.revision = 2;
  60.229  	madt->header.length = sizeof(struct acpi_table_madt) +
  60.230 -	                      sizeof(struct acpi_table_lsapic);
  60.231 +		MAX_VIRT_CPUS * sizeof(struct acpi_table_lsapic);
  60.232  	strcpy(madt->header.oem_id, "XEN");
  60.233  	strcpy(madt->header.oem_table_id, "Xen/ia64");
  60.234  	strcpy(madt->header.asl_compiler_id, "XEN");
  60.235  	madt->header.asl_compiler_revision = (XEN_VERSION<<16)|(XEN_SUBVERSION);
  60.236  
  60.237 -	/* A single LSAPIC entry describes the CPU.  Revisit for SMP guests */
  60.238 -	lsapic->header.type = ACPI_MADT_LSAPIC;
  60.239 -	lsapic->header.length = sizeof(struct acpi_table_lsapic);
  60.240 -	lsapic->flags.enabled = 1;
  60.241 +	/* An LSAPIC entry describes a CPU.  */
  60.242 +	for (i = 0; i < MAX_VIRT_CPUS; i++) {
  60.243 +		lsapic[i].header.type = ACPI_MADT_LSAPIC;
  60.244 +		lsapic[i].header.length = sizeof(struct acpi_table_lsapic);
  60.245 +		lsapic[i].id = i;
  60.246 +		lsapic[i].eid = 0;
  60.247 +		lsapic[i].flags.enabled = (d->vcpu[i] != NULL);
  60.248 +	}
  60.249  
  60.250  	madt->header.checksum = generate_acpi_checksum(madt,
  60.251  	                                               madt->header.length);
  60.252 @@ -785,7 +680,7 @@ dom_fw_init (struct domain *d, char *arg
  60.253  
  60.254  			acpi_tables = (void *)cp;
  60.255  			cp += sizeof(struct fake_acpi_tables);
  60.256 -			dom_fw_fake_acpi(acpi_tables);
  60.257 +			dom_fw_fake_acpi(d, acpi_tables);
  60.258  
  60.259  			efi_tables[i].guid = ACPI_20_TABLE_GUID;
  60.260  			efi_tables[i].table = dom_pa((unsigned long) acpi_tables);
  60.261 @@ -801,8 +696,8 @@ dom_fw_init (struct domain *d, char *arg
  60.262  	sal_systab->sal_rev_major = 0;
  60.263  	sal_systab->entry_count = 1;
  60.264  
  60.265 -	strcpy(sal_systab->oem_id, "Xen/ia64");
  60.266 -	strcpy(sal_systab->product_id, "Xen/ia64");
  60.267 +	strcpy((char *)sal_systab->oem_id, "Xen/ia64");
  60.268 +	strcpy((char *)sal_systab->product_id, "Xen/ia64");
  60.269  
  60.270  	/* fill in an entry point: */
  60.271  	sal_ed->type = SAL_DESC_ENTRY_POINT;
  60.272 @@ -861,7 +756,10 @@ dom_fw_init (struct domain *d, char *arg
  60.273  		/* hypercall patches live here, masquerade as reserved PAL memory */
  60.274  		MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB,HYPERCALL_START,HYPERCALL_END, 1);
  60.275  		MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
  60.276 -		MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
  60.277 +		/* Create a dummy entry for IO ports, so that IO accesses are
  60.278 +		   trapped by Xen.  */
  60.279 +		MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE,EFI_MEMORY_UC,
  60.280 +			0x00000ffffc000000, 0x00000fffffffffff, 1);
  60.281  		MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
  60.282  	}
  60.283  
    61.1 --- a/xen/arch/ia64/xen/domain.c	Mon Mar 20 09:56:46 2006 +0100
    61.2 +++ b/xen/arch/ia64/xen/domain.c	Mon Mar 20 09:56:54 2006 +0100
    61.3 @@ -26,6 +26,7 @@
    61.4  #include <asm/processor.h>
    61.5  #include <asm/desc.h>
    61.6  #include <asm/hw_irq.h>
    61.7 +#include <asm/setup.h>
    61.8  //#include <asm/mpspec.h>
    61.9  #include <xen/irq.h>
   61.10  #include <xen/event.h>
   61.11 @@ -36,7 +37,6 @@
   61.12  #include <xen/elf.h>
   61.13  //#include <asm/page.h>
   61.14  #include <asm/pgalloc.h>
   61.15 -#include <asm/dma.h>	/* for MAX_DMA_ADDRESS */
   61.16  
   61.17  #include <asm/asm-offsets.h>  /* for IA64_THREAD_INFO_SIZE */
   61.18  
   61.19 @@ -49,6 +49,9 @@
   61.20  #include <asm/pal.h>
   61.21  #include <asm/vhpt.h>
   61.22  #include <public/hvm/ioreq.h>
   61.23 +#include <public/arch-ia64.h>
   61.24 +#include <asm/tlbflush.h>
   61.25 +#include <asm/regionreg.h>
   61.26  
   61.27  #define CONFIG_DOMAIN0_CONTIGUOUS
   61.28  unsigned long dom0_start = -1L;
   61.29 @@ -69,10 +72,7 @@ extern unsigned long dom_fw_setup(struct
   61.30  /* FIXME: where these declarations should be there ? */
   61.31  extern void domain_pend_keyboard_interrupt(int);
   61.32  extern long platform_is_hp_ski(void);
   61.33 -extern unsigned long allocate_metaphysical_rr(void);
   61.34 -extern int allocate_rid_range(struct domain *, unsigned long);
   61.35  extern void sync_split_caches(void);
   61.36 -extern void init_all_rr(struct vcpu *);
   61.37  extern void serial_input_init(void);
   61.38  
   61.39  static void init_switch_stack(struct vcpu *v);
   61.40 @@ -80,9 +80,33 @@ static void init_switch_stack(struct vcp
   61.41  /* this belongs in include/asm, but there doesn't seem to be a suitable place */
   61.42  void arch_domain_destroy(struct domain *d)
   61.43  {
   61.44 -	printf("arch_domain_destroy: not implemented\n");
   61.45 -	//free_page((unsigned long)d->mm.perdomain_pt);
   61.46 -	free_xenheap_page(d->shared_info);
   61.47 +	struct page_info *page;
   61.48 +	struct list_head *ent, *prev;
   61.49 +
   61.50 +	if (d->arch.mm->pgd != NULL)
   61.51 +	{
   61.52 +		list_for_each ( ent, &d->arch.mm->pt_list )
   61.53 +		{
   61.54 +			page = list_entry(ent, struct page_info, list);
   61.55 +			prev = ent->prev;
   61.56 +			list_del(ent);
   61.57 +			free_xenheap_page(page_to_virt(page));
   61.58 +			ent = prev;
   61.59 +		}
   61.60 +		pgd_free(d->arch.mm->pgd);
   61.61 +	}
   61.62 +	if (d->arch.mm != NULL)
   61.63 +		xfree(d->arch.mm);
   61.64 +	if (d->shared_info != NULL)
   61.65 +		free_xenheap_page(d->shared_info);
   61.66 +
   61.67 +	deallocate_rid_range(d);
   61.68 +
   61.69 +	/* It is really good in this? */
   61.70 +	flush_tlb_all();
   61.71 +
   61.72 +	/* It is really good in this? */
   61.73 +	vhpt_flush();
   61.74  }
   61.75  
   61.76  static void default_idle(void)
   61.77 @@ -115,23 +139,9 @@ static void continue_cpu_idle_loop(void)
   61.78  
   61.79  void startup_cpu_idle_loop(void)
   61.80  {
   61.81 -	int cpu = smp_processor_id ();
   61.82  	/* Just some sanity to ensure that the scheduler is set up okay. */
   61.83  	ASSERT(current->domain == IDLE_DOMAIN_ID);
   61.84 -	printf ("idle%dA\n", cpu);
   61.85  	raise_softirq(SCHEDULE_SOFTIRQ);
   61.86 -#if 0   /* All this work is done within continue_cpu_idle_loop  */
   61.87 -	printf ("idle%dB\n", cpu);
   61.88 -	asm volatile ("mov ar.k2=r0");
   61.89 -	do_softirq();
   61.90 -	printf ("idle%dC\n", cpu);
   61.91 -
   61.92 -	/*
   61.93 -	 * Declares CPU setup done to the boot processor.
   61.94 -	 * Therefore memory barrier to ensure state is visible.
   61.95 -	 */
   61.96 -	smp_mb();
   61.97 -#endif
   61.98  #if 0
   61.99  //do we have to ensure the idle task has a shared page so that, for example,
  61.100  //region registers can be loaded from it.  Apparently not...
  61.101 @@ -201,6 +211,8 @@ struct vcpu *alloc_vcpu_struct(struct do
  61.102  
  61.103  void free_vcpu_struct(struct vcpu *v)
  61.104  {
  61.105 +	if (v->arch.privregs != NULL)
  61.106 +		free_xenheap_pages(v->arch.privregs, get_order(sizeof(mapped_regs_t)));
  61.107  	free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
  61.108  }
  61.109  
  61.110 @@ -253,6 +265,7 @@ int arch_domain_create(struct domain *d)
  61.111  	if ((d->arch.mm = xmalloc(struct mm_struct)) == NULL)
  61.112  	    goto fail_nomem;
  61.113  	memset(d->arch.mm, 0, sizeof(*d->arch.mm));
  61.114 +	INIT_LIST_HEAD(&d->arch.mm->pt_list);
  61.115  
  61.116  	if ((d->arch.mm->pgd = pgd_alloc(d->arch.mm)) == NULL)
  61.117  	    goto fail_nomem;
  61.118 @@ -324,10 +337,74 @@ int arch_set_info_guest(struct vcpu *v, 
  61.119  	return 0;
  61.120  }
  61.121  
  61.122 +static void relinquish_memory(struct domain *d, struct list_head *list)
  61.123 +{
  61.124 +    struct list_head *ent;
  61.125 +    struct page_info *page;
  61.126 +#ifndef __ia64__
  61.127 +    unsigned long     x, y;
  61.128 +#endif
  61.129 +
  61.130 +    /* Use a recursive lock, as we may enter 'free_domheap_page'. */
  61.131 +    spin_lock_recursive(&d->page_alloc_lock);
  61.132 +    ent = list->next;
  61.133 +    while ( ent != list )
  61.134 +    {
  61.135 +        page = list_entry(ent, struct page_info, list);
  61.136 +        /* Grab a reference to the page so it won't disappear from under us. */
  61.137 +        if ( unlikely(!get_page(page, d)) )
  61.138 +        {
  61.139 +            /* Couldn't get a reference -- someone is freeing this page. */
  61.140 +            ent = ent->next;
  61.141 +            continue;
  61.142 +        }
  61.143 +
  61.144 +        if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
  61.145 +            put_page_and_type(page);
  61.146 +
  61.147 +        if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
  61.148 +            put_page(page);
  61.149 +
  61.150 +#ifndef __ia64__
  61.151 +        /*
  61.152 +         * Forcibly invalidate base page tables at this point to break circular
  61.153 +         * 'linear page table' references. This is okay because MMU structures
  61.154 +         * are not shared across domains and this domain is now dead. Thus base
  61.155 +         * tables are not in use so a non-zero count means circular reference.
  61.156 +         */
  61.157 +        y = page->u.inuse.type_info;
  61.158 +        for ( ; ; )
  61.159 +        {
  61.160 +            x = y;
  61.161 +            if ( likely((x & (PGT_type_mask|PGT_validated)) !=
  61.162 +                        (PGT_base_page_table|PGT_validated)) )
  61.163 +                break;
  61.164 +
  61.165 +            y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated);
  61.166 +            if ( likely(y == x) )
  61.167 +            {
  61.168 +                free_page_type(page, PGT_base_page_table);
  61.169 +                break;
  61.170 +            }
  61.171 +        }
  61.172 +#endif
  61.173 +
  61.174 +        /* Follow the list chain and /then/ potentially free the page. */
  61.175 +        ent = ent->next;
  61.176 +        put_page(page);
  61.177 +    }
  61.178 +
  61.179 +    spin_unlock_recursive(&d->page_alloc_lock);
  61.180 +}
  61.181 +
  61.182  void domain_relinquish_resources(struct domain *d)
  61.183  {
  61.184 -	/* FIXME */
  61.185 -	printf("domain_relinquish_resources: not implemented\n");
  61.186 +    /* Relinquish every page of memory. */
  61.187 +
  61.188 +    /* xenheap_list is not used in ia64. */
  61.189 +    BUG_ON(!list_empty(&d->xenpage_list));
  61.190 +
  61.191 +    relinquish_memory(d, &d->page_list);
  61.192  }
  61.193  
  61.194  // heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread()
  61.195 @@ -339,7 +416,7 @@ void new_thread(struct vcpu *v,
  61.196  {
  61.197  	struct domain *d = v->domain;
  61.198  	struct pt_regs *regs;
  61.199 -	extern char saved_command_line[];
  61.200 +	extern char dom0_command_line[];
  61.201  
  61.202  #ifdef CONFIG_DOMAIN0_CONTIGUOUS
  61.203  	if (d == dom0) start_pc += dom0_start;
  61.204 @@ -351,8 +428,9 @@ void new_thread(struct vcpu *v,
  61.205  		regs->cr_ipsr = 0x501008826008; /* Need to be expanded as macro */
  61.206  	} else {
  61.207  		regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
  61.208 -			| IA64_PSR_BITS_TO_SET | IA64_PSR_BN
  61.209 -			& ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS);
  61.210 +		  | IA64_PSR_BITS_TO_SET | IA64_PSR_BN;
  61.211 +		regs->cr_ipsr &= ~(IA64_PSR_BITS_TO_CLEAR
  61.212 +				   | IA64_PSR_RI | IA64_PSR_IS);
  61.213  		regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; // domain runs at PL2
  61.214  	}
  61.215  	regs->cr_iip = start_pc;
  61.216 @@ -362,24 +440,27 @@ void new_thread(struct vcpu *v,
  61.217  	if (VMX_DOMAIN(v)) {
  61.218  		vmx_init_all_rr(v);
  61.219  		if (d == dom0)
  61.220 -//		    VCPU(v,vgr[12]) = dom_fw_setup(d,saved_command_line,256L);
  61.221 -		    regs->r28 = dom_fw_setup(d,saved_command_line,256L);
  61.222 +		    regs->r28 = dom_fw_setup(d,dom0_command_line,
  61.223 +					     COMMAND_LINE_SIZE);
  61.224  		/* Virtual processor context setup */
  61.225  		VCPU(v, vpsr) = IA64_PSR_BN;
  61.226  		VCPU(v, dcr) = 0;
  61.227  	} else {
  61.228  		init_all_rr(v);
  61.229  		if (d == dom0) 
  61.230 -		    regs->r28 = dom_fw_setup(d,saved_command_line,256L);
  61.231 +		    regs->r28 = dom_fw_setup(d,dom0_command_line,
  61.232 +					     COMMAND_LINE_SIZE);
  61.233  		else {
  61.234  		    regs->ar_rsc |= (2 << 2); /* force PL2/3 */
  61.235  		    if (*d->arch.cmdline == '\0') {
  61.236  #define DEFAULT_CMDLINE "nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1"
  61.237 -			regs->r28 = dom_fw_setup(d,DEFAULT_CMDLINE,256L);
  61.238 +			regs->r28 = dom_fw_setup(d,DEFAULT_CMDLINE,
  61.239 +						 sizeof (DEFAULT_CMDLINE));
  61.240  			printf("domU command line defaulted to"
  61.241  				DEFAULT_CMDLINE "\n");
  61.242  		    }
  61.243 -		    else regs->r28 = dom_fw_setup(d,d->arch.cmdline,256L);
  61.244 +		    else regs->r28 = dom_fw_setup(d,d->arch.cmdline, 
  61.245 +						  IA64_COMMAND_LINE_SIZE);
  61.246  		}
  61.247  		VCPU(v, banknum) = 1;
  61.248  		VCPU(v, metaphysical_mode) = 1;
  61.249 @@ -387,7 +468,7 @@ void new_thread(struct vcpu *v,
  61.250  	}
  61.251  }
  61.252  
  61.253 -static struct page * assign_new_domain0_page(unsigned long mpaddr)
  61.254 +static struct page_info * assign_new_domain0_page(unsigned long mpaddr)
  61.255  {
  61.256  	if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
  61.257  		printk("assign_new_domain0_page: bad domain0 mpaddr 0x%lx!\n",mpaddr);
  61.258 @@ -399,10 +480,10 @@ static struct page * assign_new_domain0_
  61.259  }
  61.260  
  61.261  /* allocate new page for domain and map it to the specified metaphysical addr */
  61.262 -struct page * assign_new_domain_page(struct domain *d, unsigned long mpaddr)
  61.263 +struct page_info * assign_new_domain_page(struct domain *d, unsigned long mpaddr)
  61.264  {
  61.265  	struct mm_struct *mm = d->arch.mm;
  61.266 -	struct page *p = (struct page *)0;
  61.267 +	struct page_info *pt, *p = (struct page_info *)0;
  61.268  	pgd_t *pgd;
  61.269  	pud_t *pud;
  61.270  	pmd_t *pmd;
  61.271 @@ -414,16 +495,28 @@ struct page * assign_new_domain_page(str
  61.272  	}
  61.273  	pgd = pgd_offset(mm,mpaddr);
  61.274  	if (pgd_none(*pgd))
  61.275 +	{
  61.276  		pgd_populate(mm, pgd, pud_alloc_one(mm,mpaddr));
  61.277 +		pt = maddr_to_page(pgd_val(*pgd));
  61.278 +		list_add_tail(&pt->list, &d->arch.mm->pt_list);
  61.279 +	}
  61.280  
  61.281  	pud = pud_offset(pgd, mpaddr);
  61.282  	if (pud_none(*pud))
  61.283 +	{
  61.284  		pud_populate(mm, pud, pmd_alloc_one(mm,mpaddr));
  61.285 +		pt = maddr_to_page(pud_val(*pud));
  61.286 +		list_add_tail(&pt->list, &d->arch.mm->pt_list);
  61.287 +	}
  61.288  
  61.289  	pmd = pmd_offset(pud, mpaddr);
  61.290  	if (pmd_none(*pmd))
  61.291 +	{
  61.292  		pmd_populate_kernel(mm, pmd, pte_alloc_one_kernel(mm,mpaddr));
  61.293  //		pmd_populate(mm, pmd, pte_alloc_one(mm,mpaddr));
  61.294 +		pt = maddr_to_page(pmd_val(*pmd));
  61.295 +		list_add_tail(&pt->list, &d->arch.mm->pt_list);
  61.296 +	}
  61.297  
  61.298  	pte = pte_offset_map(pmd, mpaddr);
  61.299  	if (pte_none(*pte)) {
  61.300 @@ -456,6 +549,7 @@ struct page * assign_new_domain_page(str
  61.301  void assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr)
  61.302  {
  61.303  	struct mm_struct *mm = d->arch.mm;
  61.304 +	struct page_info *pt;
  61.305  	pgd_t *pgd;
  61.306  	pud_t *pud;
  61.307  	pmd_t *pmd;
  61.308 @@ -467,16 +561,28 @@ void assign_domain_page(struct domain *d
  61.309  	}
  61.310  	pgd = pgd_offset(mm,mpaddr);
  61.311  	if (pgd_none(*pgd))
  61.312 +	{
  61.313  		pgd_populate(mm, pgd, pud_alloc_one(mm,mpaddr));
  61.314 +		pt = maddr_to_page(pgd_val(*pgd));
  61.315 +		list_add_tail(&pt->list, &d->arch.mm->pt_list);
  61.316 +	}
  61.317  
  61.318  	pud = pud_offset(pgd, mpaddr);
  61.319  	if (pud_none(*pud))
  61.320 +	{
  61.321  		pud_populate(mm, pud, pmd_alloc_one(mm,mpaddr));
  61.322 +		pt = maddr_to_page(pud_val(*pud));
  61.323 +		list_add_tail(&pt->list, &d->arch.mm->pt_list);
  61.324 +	}
  61.325  
  61.326  	pmd = pmd_offset(pud, mpaddr);
  61.327  	if (pmd_none(*pmd))
  61.328 +	{
  61.329  		pmd_populate_kernel(mm, pmd, pte_alloc_one_kernel(mm,mpaddr));
  61.330  //		pmd_populate(mm, pmd, pte_alloc_one(mm,mpaddr));
  61.331 +		pt = maddr_to_page(pmd_val(*pmd));
  61.332 +		list_add_tail(&pt->list, &d->arch.mm->pt_list);
  61.333 +	}
  61.334  
  61.335  	pte = pte_offset_map(pmd, mpaddr);
  61.336  	if (pte_none(*pte)) {
  61.337 @@ -543,12 +649,13 @@ unsigned long lookup_domain_mpa(struct d
  61.338  
  61.339  #ifdef CONFIG_DOMAIN0_CONTIGUOUS
  61.340  	if (d == dom0) {
  61.341 +		pte_t pteval;
  61.342  		if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
  61.343  			//printk("lookup_domain_mpa: bad dom0 mpaddr 0x%lx!\n",mpaddr);
  61.344  			//printk("lookup_domain_mpa: start=0x%lx,end=0x%lx!\n",dom0_start,dom0_start+dom0_size);
  61.345  			mpafoo(mpaddr);
  61.346  		}
  61.347 -		pte_t pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
  61.348 +		pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
  61.349  			__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
  61.350  		pte = &pteval;
  61.351  		return *(unsigned long *)pte;
  61.352 @@ -639,7 +746,7 @@ void loaddomainelfimage(struct domain *d
  61.353  	Elf_Phdr phdr;
  61.354  	int h, filesz, memsz;
  61.355  	unsigned long elfaddr, dom_mpaddr, dom_imva;
  61.356 -	struct page *p;
  61.357 +	struct page_info *p;
  61.358    
  61.359  	copy_memory(&ehdr, (void *) image_start, sizeof(Elf_Ehdr));
  61.360  	for ( h = 0; h < ehdr.e_phnum; h++ ) {
    62.1 --- a/xen/arch/ia64/xen/gdbstub.c	Mon Mar 20 09:56:46 2006 +0100
    62.2 +++ b/xen/arch/ia64/xen/gdbstub.c	Mon Mar 20 09:56:54 2006 +0100
    62.3 @@ -32,6 +32,7 @@
    62.4  
    62.5  
    62.6  #include <xen/lib.h>
    62.7 +#include <xen/mm.h>
    62.8  #include <asm/byteorder.h>
    62.9  #include <asm/debugger.h>
   62.10  #include <asm/uaccess.h>
    63.1 --- a/xen/arch/ia64/xen/irq.c	Mon Mar 20 09:56:46 2006 +0100
    63.2 +++ b/xen/arch/ia64/xen/irq.c	Mon Mar 20 09:56:54 2006 +0100
    63.3 @@ -1338,6 +1338,7 @@ typedef struct {
    63.4      struct domain *guest[IRQ_MAX_GUESTS];
    63.5  } irq_guest_action_t;
    63.6  
    63.7 +/*
    63.8  static void __do_IRQ_guest(int irq)
    63.9  {
   63.10      irq_desc_t         *desc = &irq_desc[irq];
   63.11 @@ -1353,7 +1354,7 @@ static void __do_IRQ_guest(int irq)
   63.12          send_guest_pirq(d, irq);
   63.13      }
   63.14  }
   63.15 -
   63.16 + */
   63.17  int pirq_guest_unmask(struct domain *d)
   63.18  {
   63.19      irq_desc_t    *desc;
    64.1 --- a/xen/arch/ia64/xen/mm_init.c	Mon Mar 20 09:56:46 2006 +0100
    64.2 +++ b/xen/arch/ia64/xen/mm_init.c	Mon Mar 20 09:56:54 2006 +0100
    64.3 @@ -60,16 +60,16 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF
    64.4  #ifdef CONFIG_VIRTUAL_MEM_MAP
    64.5  unsigned long vmalloc_end = VMALLOC_END_INIT;
    64.6  EXPORT_SYMBOL(vmalloc_end);
    64.7 -struct page *vmem_map;
    64.8 +struct page_info *vmem_map;
    64.9  EXPORT_SYMBOL(vmem_map);
   64.10  #endif
   64.11  
   64.12  // static int pgt_cache_water[2] = { 25, 50 };
   64.13  
   64.14 -struct page *zero_page_memmap_ptr;		/* map entry for zero page */
   64.15 +#ifndef XEN
   64.16 +struct page_info *zero_page_memmap_ptr;	/* map entry for zero page */
   64.17  EXPORT_SYMBOL(zero_page_memmap_ptr);
   64.18  
   64.19 -#ifdef XEN
   64.20  void *high_memory;
   64.21  EXPORT_SYMBOL(high_memory);
   64.22  
   64.23 @@ -172,7 +172,7 @@ pmd_t fastcall *__pmd_alloc(struct mm_st
   64.24  pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
   64.25  {
   64.26  	if (!pmd_present(*pmd)) {
   64.27 -		struct page *new;
   64.28 +		struct page_info *new;
   64.29  
   64.30  		spin_unlock(&mm->page_table_lock);
   64.31  		new = pte_alloc_one(mm, address);
   64.32 @@ -202,7 +202,7 @@ void
   64.33  update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte)
   64.34  {
   64.35  	unsigned long addr;
   64.36 -	struct page *page;
   64.37 +	struct page_info *page;
   64.38  
   64.39  	if (!pte_exec(pte))
   64.40  		return;				/* not an executable page... */
   64.41 @@ -386,7 +386,7 @@ int
   64.42  create_mem_map_page_table (u64 start, u64 end, void *arg)
   64.43  {
   64.44  	unsigned long address, start_page, end_page;
   64.45 -	struct page *map_start, *map_end;
   64.46 +	struct page_info *map_start, *map_end;
   64.47  	int node;
   64.48  	pgd_t *pgd;
   64.49  	pmd_t *pmd;
   64.50 @@ -417,8 +417,8 @@ create_mem_map_page_table (u64 start, u6
   64.51  }
   64.52  
   64.53  struct memmap_init_callback_data {
   64.54 -	struct page *start;
   64.55 -	struct page *end;
   64.56 +	struct page_info *start;
   64.57 +	struct page_info *end;
   64.58  	int nid;
   64.59  	unsigned long zone;
   64.60  };
   64.61 @@ -427,7 +427,7 @@ static int
   64.62  virtual_memmap_init (u64 start, u64 end, void *arg)
   64.63  {
   64.64  	struct memmap_init_callback_data *args;
   64.65 -	struct page *map_start, *map_end;
   64.66 +	struct page_info *map_start, *map_end;
   64.67  
   64.68  	args = (struct memmap_init_callback_data *) arg;
   64.69  
   64.70 @@ -440,13 +440,13 @@ virtual_memmap_init (u64 start, u64 end,
   64.71  		map_end = args->end;
   64.72  
   64.73  	/*
   64.74 -	 * We have to initialize "out of bounds" struct page elements that fit completely
   64.75 +	 * We have to initialize "out of bounds" struct page_info elements that fit completely
   64.76  	 * on the same pages that were allocated for the "in bounds" elements because they
   64.77  	 * may be referenced later (and found to be "reserved").
   64.78  	 */
   64.79 -	map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1)) / sizeof(struct page);
   64.80 +	map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1)) / sizeof(struct page_info);
   64.81  	map_end += ((PAGE_ALIGN((unsigned long) map_end) - (unsigned long) map_end)
   64.82 -		    / sizeof(struct page));
   64.83 +		    / sizeof(struct page_info));
   64.84  
   64.85  	if (map_start < map_end)
   64.86  		memmap_init_zone(map_start, (unsigned long) (map_end - map_start),
   64.87 @@ -455,7 +455,7 @@ virtual_memmap_init (u64 start, u64 end,
   64.88  }
   64.89  
   64.90  void
   64.91 -memmap_init (struct page *start, unsigned long size, int nid,
   64.92 +memmap_init (struct page_info *start, unsigned long size, int nid,
   64.93  	     unsigned long zone, unsigned long start_pfn)
   64.94  {
   64.95  	if (!vmem_map)
   64.96 @@ -476,7 +476,7 @@ int
   64.97  ia64_mfn_valid (unsigned long pfn)
   64.98  {
   64.99  	char byte;
  64.100 -	struct page *pg = mfn_to_page(pfn);
  64.101 +	struct page_info *pg = mfn_to_page(pfn);
  64.102  
  64.103  	return     (__get_user(byte, (char *) pg) == 0)
  64.104  		&& ((((u64)pg & PAGE_MASK) == (((u64)(pg + 1) - 1) & PAGE_MASK))
    65.1 --- a/xen/arch/ia64/xen/privop.c	Mon Mar 20 09:56:46 2006 +0100
    65.2 +++ b/xen/arch/ia64/xen/privop.c	Mon Mar 20 09:56:54 2006 +0100
    65.3 @@ -20,6 +20,9 @@ extern void zero_reflect_counts(void);
    65.4  
    65.5  long priv_verbose=0;
    65.6  
    65.7 +/* Set to 1 to handle privified instructions from the privify tool. */
    65.8 +static const int privify_en = 0;
    65.9 +
   65.10  /**************************************************************************
   65.11  Hypercall bundle creation
   65.12  **************************************************************************/
   65.13 @@ -131,7 +134,8 @@ IA64FAULT priv_ptc_e(VCPU *vcpu, INST64 
   65.14  	UINT src = inst.M28.r3;
   65.15  
   65.16  	// NOTE: ptc_e with source gr > 63 is emulated as a fc r(y-64)
   65.17 -	if (src > 63) return(vcpu_fc(vcpu,vcpu_get_gr(vcpu,src - 64)));
   65.18 +	if (privify_en && src > 63)
   65.19 +		return(vcpu_fc(vcpu,vcpu_get_gr(vcpu,src - 64)));
   65.20  	return vcpu_ptc_e(vcpu,vcpu_get_gr(vcpu,src));
   65.21  }
   65.22  
   65.23 @@ -178,7 +182,7 @@ IA64FAULT priv_tpa(VCPU *vcpu, INST64 in
   65.24  	UINT src = inst.M46.r3;
   65.25  
   65.26  	// NOTE: tpa with source gr > 63 is emulated as a ttag rx=r(y-64)
   65.27 -	if (src > 63)
   65.28 +	if (privify_en && src > 63)
   65.29  		fault = vcpu_ttag(vcpu,vcpu_get_gr(vcpu,src-64),&padr);
   65.30  	else fault = vcpu_tpa(vcpu,vcpu_get_gr(vcpu,src),&padr);
   65.31  	if (fault == IA64_NO_FAULT)
   65.32 @@ -193,7 +197,7 @@ IA64FAULT priv_tak(VCPU *vcpu, INST64 in
   65.33  	UINT src = inst.M46.r3;
   65.34  
   65.35  	// NOTE: tak with source gr > 63 is emulated as a thash rx=r(y-64)
   65.36 -	if (src > 63)
   65.37 +	if (privify_en && src > 63)
   65.38  		fault = vcpu_thash(vcpu,vcpu_get_gr(vcpu,src-64),&key);
   65.39  	else fault = vcpu_tak(vcpu,vcpu_get_gr(vcpu,src),&key);
   65.40  	if (fault == IA64_NO_FAULT)
   65.41 @@ -280,7 +284,8 @@ IA64FAULT priv_mov_to_ar_reg(VCPU *vcpu,
   65.42  	// I26 and M29 are identical for these fields
   65.43  	UINT64 ar3 = inst.M29.ar3;
   65.44  
   65.45 -	if (inst.M29.r2 > 63 && inst.M29.ar3 < 8) { // privified mov from kr
   65.46 +	if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8) {
   65.47 +		// privified mov from kr
   65.48  		UINT64 val;
   65.49  		if (vcpu_get_ar(vcpu,ar3,&val) != IA64_ILLOP_FAULT)
   65.50  			return vcpu_set_gr(vcpu, inst.M29.r2-64, val,0);
   65.51 @@ -404,14 +409,17 @@ IA64FAULT priv_mov_from_rr(VCPU *vcpu, I
   65.52  {
   65.53  	UINT64 val;
   65.54  	IA64FAULT fault;
   65.55 +	int reg;
   65.56  	
   65.57 -	if (inst.M43.r1 > 63) { // privified mov from cpuid
   65.58 -		fault = vcpu_get_cpuid(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
   65.59 +	reg = vcpu_get_gr(vcpu,inst.M43.r3);
   65.60 +	if (privify_en && inst.M43.r1 > 63) {
   65.61 +		// privified mov from cpuid
   65.62 +		fault = vcpu_get_cpuid(vcpu,reg,&val);
   65.63  		if (fault == IA64_NO_FAULT)
   65.64  			return vcpu_set_gr(vcpu, inst.M43.r1-64, val, 0);
   65.65  	}
   65.66  	else {
   65.67 -		fault = vcpu_get_rr(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
   65.68 +		fault = vcpu_get_rr(vcpu,reg,&val);
   65.69  		if (fault == IA64_NO_FAULT)
   65.70  			return vcpu_set_gr(vcpu, inst.M43.r1, val, 0);
   65.71  	}
   65.72 @@ -455,14 +463,17 @@ IA64FAULT priv_mov_from_pmc(VCPU *vcpu, 
   65.73  {
   65.74  	UINT64 val;
   65.75  	IA64FAULT fault;
   65.76 +	int reg;
   65.77  	
   65.78 -	if (inst.M43.r1 > 63) { // privified mov from pmd
   65.79 -		fault = vcpu_get_pmd(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
   65.80 +	reg = vcpu_get_gr(vcpu,inst.M43.r3);
   65.81 +	if (privify_en && inst.M43.r1 > 63) {
   65.82 +		// privified mov from pmd
   65.83 +		fault = vcpu_get_pmd(vcpu,reg,&val);
   65.84  		if (fault == IA64_NO_FAULT)
   65.85  			return vcpu_set_gr(vcpu, inst.M43.r1-64, val, 0);
   65.86  	}
   65.87  	else {
   65.88 -		fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
   65.89 +		fault = vcpu_get_pmc(vcpu,reg,&val);
   65.90  		if (fault == IA64_NO_FAULT)
   65.91  			return vcpu_set_gr(vcpu, inst.M43.r1, val, 0);
   65.92  	}
   65.93 @@ -666,7 +677,7 @@ priv_handle_op(VCPU *vcpu, REGS *regs, i
   65.94  		else if (inst.generic.major != 1) break;
   65.95  		x6 = inst.M29.x6;
   65.96  		if (x6 == 0x2a) {
   65.97 -			if (inst.M29.r2 > 63 && inst.M29.ar3 < 8)
   65.98 +			if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8)
   65.99  				privcnt.mov_from_ar++; // privified mov from kr
  65.100  			else privcnt.mov_to_ar_reg++;
  65.101  			return priv_mov_to_ar_reg(vcpu,inst);
  65.102 @@ -674,14 +685,14 @@ priv_handle_op(VCPU *vcpu, REGS *regs, i
  65.103  		if (inst.M29.x3 != 0) break;
  65.104  		if (!(pfunc = Mpriv_funcs[x6])) break;
  65.105  		if (x6 == 0x1e || x6 == 0x1f)  { // tpa or tak are "special"
  65.106 -			if (inst.M46.r3 > 63) {
  65.107 +			if (privify_en && inst.M46.r3 > 63) {
  65.108  				if (x6 == 0x1e) x6 = 0x1b;
  65.109  				else x6 = 0x1a;
  65.110  			}
  65.111  		}
  65.112 -		if (x6 == 52 && inst.M28.r3 > 63)
  65.113 +		if (privify_en && x6 == 52 && inst.M28.r3 > 63)
  65.114  			privcnt.fc++;
  65.115 -		else if (x6 == 16 && inst.M43.r3 > 63)
  65.116 +		else if (privify_en && x6 == 16 && inst.M43.r3 > 63)
  65.117  			privcnt.cpuid++;
  65.118  		else privcnt.Mpriv_cnt[x6]++;
  65.119  		return (*pfunc)(vcpu,inst);
  65.120 @@ -718,7 +729,7 @@ priv_handle_op(VCPU *vcpu, REGS *regs, i
  65.121  #endif
  65.122  		if (inst.I26.x3 != 0) break;  // I26.x3 == I27.x3
  65.123  		if (inst.I26.x6 == 0x2a) {
  65.124 -			if (inst.I26.r2 > 63 && inst.I26.ar3 < 8)
  65.125 +			if (privify_en && inst.I26.r2 > 63 && inst.I26.ar3 < 8)
  65.126  				privcnt.mov_from_ar++; // privified mov from kr
  65.127  			else privcnt.mov_to_ar_reg++;
  65.128  			return priv_mov_to_ar_reg(vcpu,inst);
  65.129 @@ -797,12 +808,17 @@ priv_emulate(VCPU *vcpu, REGS *regs, UIN
  65.130  #define HYPERPRIVOP_GET_RR		0x10
  65.131  #define HYPERPRIVOP_SET_RR		0x11
  65.132  #define HYPERPRIVOP_SET_KR		0x12
  65.133 -#define HYPERPRIVOP_MAX			0x12
  65.134 +#define HYPERPRIVOP_FC			0x13
  65.135 +#define HYPERPRIVOP_GET_CPUID		0x14
  65.136 +#define HYPERPRIVOP_GET_PMD		0x15
  65.137 +#define HYPERPRIVOP_GET_EFLAG		0x16
  65.138 +#define HYPERPRIVOP_SET_EFLAG		0x17
  65.139 +#define HYPERPRIVOP_MAX			0x17
  65.140  
  65.141  static const char * const hyperpriv_str[HYPERPRIVOP_MAX+1] = {
  65.142  	0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i", "ssm.i",
  65.143  	"=ivr", "=tpr", "tpr=", "eoi", "itm=", "thash", "ptc.ga", "itr.d",
  65.144 -	"=rr", "rr=", "kr="
  65.145 +	"=rr", "rr=", "kr=", "fc", "=cpuid", "=pmd", "=ar.eflg", "ar.eflg="
  65.146  };
  65.147  
  65.148  unsigned long slow_hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 };
  65.149 @@ -889,6 +905,24 @@ ia64_hyperprivop(unsigned long iim, REGS
  65.150  	    case HYPERPRIVOP_SET_KR:
  65.151  		(void)vcpu_set_ar(v,regs->r8,regs->r9);
  65.152  		return 1;
  65.153 +	    case HYPERPRIVOP_FC:
  65.154 +		(void)vcpu_fc(v,regs->r8);
  65.155 +		return 1;
  65.156 +	    case HYPERPRIVOP_GET_CPUID:
  65.157 +		(void)vcpu_get_cpuid(v,regs->r8,&val);
  65.158 +		regs->r8 = val;
  65.159 +		return 1;
  65.160 +	    case HYPERPRIVOP_GET_PMD:
  65.161 +		(void)vcpu_get_pmd(v,regs->r8,&val);
  65.162 +		regs->r8 = val;
  65.163 +		return 1;
  65.164 +	    case HYPERPRIVOP_GET_EFLAG:
  65.165 +		(void)vcpu_get_ar(v,24,&val);
  65.166 +		regs->r8 = val;
  65.167 +		return 1;
  65.168 +	    case HYPERPRIVOP_SET_EFLAG:
  65.169 +		(void)vcpu_set_ar(v,24,regs->r8);
  65.170 +		return 1;
  65.171  	}
  65.172  	return 0;
  65.173  }
  65.174 @@ -934,7 +968,7 @@ static const char * const cr_str[128] = 
  65.175  };
  65.176  
  65.177  // FIXME: should use snprintf to ensure no buffer overflow
  65.178 -int dump_privop_counts(char *buf)
  65.179 +static int dump_privop_counts(char *buf)
  65.180  {
  65.181  	int i, j;
  65.182  	UINT64 sum = 0;
  65.183 @@ -1007,7 +1041,7 @@ int dump_privop_counts(char *buf)
  65.184  	return s - buf;
  65.185  }
  65.186  
  65.187 -int zero_privop_counts(char *buf)
  65.188 +static int zero_privop_counts(char *buf)
  65.189  {
  65.190  	int i, j;
  65.191  	char *s = buf;
  65.192 @@ -1043,7 +1077,7 @@ void privop_count_addr(unsigned long iip
  65.193  	v->overflow++;;
  65.194  }
  65.195  
  65.196 -int dump_privop_addrs(char *buf)
  65.197 +static int dump_privop_addrs(char *buf)
  65.198  {
  65.199  	int i,j;
  65.200  	char *s = buf;
  65.201 @@ -1061,7 +1095,7 @@ int dump_privop_addrs(char *buf)
  65.202  	return s - buf;
  65.203  }
  65.204  
  65.205 -void zero_privop_addrs(void)
  65.206 +static void zero_privop_addrs(void)
  65.207  {
  65.208  	int i,j;
  65.209  	for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
  65.210 @@ -1085,7 +1119,7 @@ extern unsigned long idle_when_pending;
  65.211  extern unsigned long pal_halt_light_count;
  65.212  extern unsigned long context_switch_count;
  65.213  
  65.214 -int dump_misc_stats(char *buf)
  65.215 +static int dump_misc_stats(char *buf)
  65.216  {
  65.217  	char *s = buf;
  65.218  	s += sprintf(s,"Virtual TR translations: %ld\n",tr_translate_count);
  65.219 @@ -1102,7 +1136,7 @@ int dump_misc_stats(char *buf)
  65.220  	return s - buf;
  65.221  }
  65.222  
  65.223 -void zero_misc_stats(void)
  65.224 +static void zero_misc_stats(void)
  65.225  {
  65.226  	dtlb_translate_count = 0;
  65.227  	tr_translate_count = 0;
  65.228 @@ -1117,7 +1151,7 @@ void zero_misc_stats(void)
  65.229  	context_switch_count = 0;
  65.230  }
  65.231  
  65.232 -int dump_hyperprivop_counts(char *buf)
  65.233 +static int dump_hyperprivop_counts(char *buf)
  65.234  {
  65.235  	int i;
  65.236  	char *s = buf;
  65.237 @@ -1138,7 +1172,7 @@ int dump_hyperprivop_counts(char *buf)
  65.238  	return s - buf;
  65.239  }
  65.240  
  65.241 -void zero_hyperprivop_counts(void)
  65.242 +static void zero_hyperprivop_counts(void)
  65.243  {
  65.244  	int i;
  65.245  	for (i = 0; i <= HYPERPRIVOP_MAX; i++) slow_hyperpriv_cnt[i] = 0;
    66.1 --- a/xen/arch/ia64/xen/process.c	Mon Mar 20 09:56:46 2006 +0100
    66.2 +++ b/xen/arch/ia64/xen/process.c	Mon Mar 20 09:56:54 2006 +0100
    66.3 @@ -1,3 +1,4 @@
    66.4 +
    66.5  /*
    66.6   * Miscellaneous process/domain related routines
    66.7   * 
    66.8 @@ -41,6 +42,7 @@ extern long platform_is_hp_ski(void);
    66.9  extern int ia64_hyperprivop(unsigned long, REGS *);
   66.10  extern int ia64_hypercall(struct pt_regs *regs);
   66.11  extern void vmx_do_launch(struct vcpu *);
   66.12 +extern unsigned long lookup_domain_mpa(struct domain *,unsigned long);
   66.13  
   66.14  extern unsigned long dom0_start, dom0_size;
   66.15  
   66.16 @@ -57,21 +59,8 @@ extern unsigned long dom0_start, dom0_si
   66.17  			IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \
   66.18  			IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA)
   66.19  
   66.20 -#define PSCB(x,y)	VCPU(x,y)
   66.21 -#define PSCBX(x,y)	x->arch.y
   66.22 -
   66.23 -extern unsigned long vcpu_verbose;
   66.24 -
   66.25 -long do_iopl(domid_t domain, unsigned int new_io_pl)
   66.26 -{
   66.27 -	dummy();
   66.28 -	return 0;
   66.29 -}
   66.30 -
   66.31  #include <xen/sched-if.h>
   66.32  
   66.33 -extern struct schedule_data schedule_data[NR_CPUS];
   66.34 -
   66.35  void schedule_tail(struct vcpu *prev)
   66.36  {
   66.37  	context_saved(prev);
   66.38 @@ -95,9 +84,6 @@ unsigned long translate_domain_pte(unsig
   66.39  {
   66.40  	struct domain *d = current->domain;
   66.41  	unsigned long mask, pteval2, mpaddr;
   66.42 -	unsigned long lookup_domain_mpa(struct domain *,unsigned long);
   66.43 -	extern struct domain *dom0;
   66.44 -	extern unsigned long dom0_start, dom0_size;
   66.45  
   66.46  	// FIXME address had better be pre-validated on insert
   66.47  	mask = ~itir_mask(itir);
   66.48 @@ -127,7 +113,6 @@ unsigned long translate_domain_pte(unsig
   66.49  // given a current domain metaphysical address, return the physical address
   66.50  unsigned long translate_domain_mpaddr(unsigned long mpaddr)
   66.51  {
   66.52 -	extern unsigned long lookup_domain_mpa(struct domain *,unsigned long);
   66.53  	unsigned long pteval;
   66.54  
   66.55  	if (current->domain == dom0) {
   66.56 @@ -224,7 +209,7 @@ void reflect_interruption(unsigned long 
   66.57  
   66.58  void foodpi(void) {}
   66.59  
   66.60 -unsigned long pending_false_positive = 0;
   66.61 +static unsigned long pending_false_positive = 0;
   66.62  
   66.63  void reflect_extint(struct pt_regs *regs)
   66.64  {
   66.65 @@ -293,13 +278,14 @@ void ia64_do_page_fault (unsigned long a
   66.66  		return;
   66.67  	}
   66.68  
   66.69 -	fault = vcpu_translate(current,address,is_data,&pteval,&itir,&iha);
   66.70 +	fault = vcpu_translate(current,address,is_data,0,&pteval,&itir,&iha);
   66.71  	if (fault == IA64_NO_FAULT) {
   66.72  		pteval = translate_domain_pte(pteval,address,itir);
   66.73  		vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)&0x3f);
   66.74  		return;
   66.75  	}
   66.76 -	if (IS_VMM_ADDRESS(iip)) {
   66.77 +	if (!user_mode (regs)) {
   66.78 +		/* The fault occurs inside Xen.  */
   66.79  		if (!ia64_done_with_exception(regs)) {
   66.80  			// should never happen.  If it does, region 0 addr may
   66.81  			// indicate a bad xen pointer
   66.82 @@ -543,7 +529,6 @@ unsigned long running_on_sim = 0;
   66.83  void
   66.84  do_ssc(unsigned long ssc, struct pt_regs *regs)
   66.85  {
   66.86 -	extern unsigned long lookup_domain_mpa(struct domain *,unsigned long);
   66.87  	unsigned long arg0, arg1, arg2, arg3, retval;
   66.88  	char buf[2];
   66.89  /**/	static int last_fd, last_count;	// FIXME FIXME FIXME
   66.90 @@ -653,14 +638,14 @@ if (!running_on_sim) { printf("SSC_OPEN,
   66.91  	vcpu_increment_iip(current);
   66.92  }
   66.93  
   66.94 +/* Also read in hyperprivop.S  */
   66.95  int first_break = 1;
   66.96  
   66.97  void
   66.98  ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim)
   66.99  {
  66.100 -	struct domain *d = (struct domain *) current->domain;
  66.101 +	struct domain *d = current->domain;
  66.102  	struct vcpu *v = current;
  66.103 -	extern unsigned long running_on_sim;
  66.104  
  66.105  	if (first_break) {
  66.106  		if (platform_is_hp_ski()) running_on_sim = 1;
  66.107 @@ -668,8 +653,7 @@ ia64_handle_break (unsigned long ifa, st
  66.108  		first_break = 0;
  66.109  	}
  66.110  	if (iim == 0x80001 || iim == 0x80002) {	//FIXME: don't hardcode constant
  66.111 -		if (running_on_sim) do_ssc(vcpu_get_gr(current,36), regs);
  66.112 -		else do_ssc(vcpu_get_gr(current,36), regs);
  66.113 +		do_ssc(vcpu_get_gr(current,36), regs);
  66.114  	} 
  66.115  #ifdef CRASH_DEBUG
  66.116  	else if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs)) {
  66.117 @@ -711,6 +695,7 @@ ia64_handle_privop (unsigned long ifa, s
  66.118  	}
  66.119  }
  66.120  
  66.121 +/* Used in vhpt.h.  */
  66.122  #define INTR_TYPE_MAX	10
  66.123  UINT64 int_counts[INTR_TYPE_MAX];
  66.124  
    67.1 --- a/xen/arch/ia64/xen/regionreg.c	Mon Mar 20 09:56:46 2006 +0100
    67.2 +++ b/xen/arch/ia64/xen/regionreg.c	Mon Mar 20 09:56:54 2006 +0100
    67.3 @@ -157,7 +157,6 @@ int deallocate_rid_range(struct domain *
    67.4  	int rid_block_end = d->arch.ending_rid >> IA64_MIN_IMPL_RID_BITS;
    67.5  	int rid_block_start = d->arch.starting_rid >> IA64_MIN_IMPL_RID_BITS;
    67.6  
    67.7 -	return 1;  // KLUDGE ALERT
    67.8  	//
    67.9  	// not all domains will have allocated RIDs (physical mode loaders for instance)
   67.10  	//
   67.11 @@ -250,13 +249,18 @@ int set_one_rr(unsigned long rr, unsigne
   67.12  	newrrv.rid = newrid;
   67.13  	newrrv.ve = 1;  // VHPT now enabled for region 7!!
   67.14  	newrrv.ps = PAGE_SHIFT;
   67.15 -	if (rreg == 0)
   67.16 +
   67.17 +	if (rreg == 0) {
   67.18  		v->arch.metaphysical_saved_rr0 = vmMangleRID(newrrv.rrval);
   67.19 -	else if (rreg == 7)
   67.20 +		if (!PSCB(v,metaphysical_mode))
   67.21 +			set_rr(rr,newrrv.rrval);
   67.22 +	} else if (rreg == 7) {
   67.23  		ia64_new_rr7(vmMangleRID(newrrv.rrval),v->vcpu_info,
   67.24  			     v->arch.privregs, __get_cpu_var(vhpt_paddr),
   67.25  			     (unsigned long) pal_vaddr);
   67.26 -	else set_rr(rr,newrrv.rrval);
   67.27 +	} else {
   67.28 +		set_rr(rr,newrrv.rrval);
   67.29 +	}
   67.30  #endif
   67.31  	return 1;
   67.32  }
    68.1 --- a/xen/arch/ia64/xen/vcpu.c	Mon Mar 20 09:56:46 2006 +0100
    68.2 +++ b/xen/arch/ia64/xen/vcpu.c	Mon Mar 20 09:56:54 2006 +0100
    68.3 @@ -6,12 +6,6 @@
    68.4   *
    68.5   */
    68.6  
    68.7 -#if 1
    68.8 -// TEMPORARY PATCH for match_dtlb uses this, can be removed later
    68.9 -// FIXME SMP
   68.10 -int in_tpa = 0;
   68.11 -#endif
   68.12 -
   68.13  #include <linux/sched.h>
   68.14  #include <public/arch-ia64.h>
   68.15  #include <asm/ia64_int.h>
   68.16 @@ -30,19 +24,18 @@ extern void getreg(unsigned long regnum,
   68.17  extern void setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs);
   68.18  extern void panic_domain(struct pt_regs *, const char *, ...);
   68.19  extern int set_metaphysical_rr0(void);
   68.20 +extern unsigned long translate_domain_pte(UINT64,UINT64,UINT64);
   68.21 +extern unsigned long translate_domain_mpaddr(unsigned long);
   68.22 +extern void ia64_global_tlb_purge(UINT64 start, UINT64 end, UINT64 nbits);
   68.23 +
   68.24  
   68.25  typedef	union {
   68.26  	struct ia64_psr ia64_psr;
   68.27  	unsigned long i64;
   68.28  } PSR;
   68.29  
   68.30 -//typedef	struct pt_regs	REGS;
   68.31 -//typedef struct domain VCPU;
   68.32 -
   68.33  // this def for vcpu_regs won't work if kernel stack is present
   68.34  //#define	vcpu_regs(vcpu) ((struct pt_regs *) vcpu->arch.regs
   68.35 -#define	PSCB(x,y)	VCPU(x,y)
   68.36 -#define	PSCBX(x,y)	x->arch.y
   68.37  
   68.38  #define	TRUE	1
   68.39  #define	FALSE	0
   68.40 @@ -71,18 +64,6 @@ unsigned long tr_translate_count = 0;
   68.41  unsigned long phys_translate_count = 0;
   68.42  
   68.43  unsigned long vcpu_verbose = 0;
   68.44 -#define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0)
   68.45 -
   68.46 -//#define vcpu_quick_region_check(_tr_regions,_ifa)	1
   68.47 -#define vcpu_quick_region_check(_tr_regions,_ifa)			\
   68.48 -	(_tr_regions & (1 << ((unsigned long)_ifa >> 61)))
   68.49 -#define vcpu_quick_region_set(_tr_regions,_ifa)				\
   68.50 -	do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0)
   68.51 -
   68.52 -// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
   68.53 -#define vcpu_match_tr_entry(_trp,_ifa,_rid)				\
   68.54 -	((_trp->p && (_trp->rid==_rid) && (_ifa >= _trp->vadr) &&	\
   68.55 -	(_ifa < (_trp->vadr + (1L<< _trp->ps)) - 1)))
   68.56  
   68.57  /**************************************************************************
   68.58   VCPU general register access routines
   68.59 @@ -238,7 +219,6 @@ IA64FAULT vcpu_reset_psr_sm(VCPU *vcpu, 
   68.60  	return IA64_NO_FAULT;
   68.61  }
   68.62  
   68.63 -extern UINT64 vcpu_check_pending_interrupts(VCPU *vcpu);
   68.64  #define SPURIOUS_VECTOR 0xf
   68.65  
   68.66  IA64FAULT vcpu_set_psr_dt(VCPU *vcpu)
   68.67 @@ -659,13 +639,6 @@ void vcpu_pend_interrupt(VCPU *vcpu, UIN
   68.68      }
   68.69  }
   68.70  
   68.71 -void early_tick(VCPU *vcpu)
   68.72 -{
   68.73 -	UINT64 *p = &PSCBX(vcpu,irr[3]);
   68.74 -	printf("vcpu_check_pending: about to deliver early tick\n");
   68.75 -	printf("&irr[0]=%p, irr[0]=0x%lx\n",p,*p);
   68.76 -}
   68.77 -
   68.78  #define	IA64_TPR_MMI	0x10000
   68.79  #define	IA64_TPR_MIC	0x000f0
   68.80  
   68.81 @@ -677,7 +650,7 @@ void early_tick(VCPU *vcpu)
   68.82   * and this must be checked independently; see vcpu_deliverable interrupts() */
   68.83  UINT64 vcpu_check_pending_interrupts(VCPU *vcpu)
   68.84  {
   68.85 -	UINT64 *p, *q, *r, bits, bitnum, mask, i, vector;
   68.86 +	UINT64 *p, *r, bits, bitnum, mask, i, vector;
   68.87  
   68.88  	/* Always check pending event, since guest may just ack the
   68.89  	 * event injection without handle. Later guest may throw out
   68.90 @@ -691,8 +664,8 @@ check_start:
   68.91  
   68.92  	p = &PSCBX(vcpu,irr[3]);
   68.93  	r = &PSCBX(vcpu,insvc[3]);
   68.94 -	for (i = 3; ; p--, q--, r--, i--) {
   68.95 -		bits = *p /* & *q */;
   68.96 +	for (i = 3; ; p--, r--, i--) {
   68.97 +		bits = *p ;
   68.98  		if (bits) break; // got a potential interrupt
   68.99  		if (*r) {
  68.100  			// nothing in this word which is pending+inservice
  68.101 @@ -713,7 +686,7 @@ check_start:
  68.102  	if (vector == (PSCB(vcpu,itv) & 0xff)) {
  68.103  		uint64_t now = ia64_get_itc();
  68.104  		if (now < PSCBX(vcpu,domain_itm)) {
  68.105 -			printk("Ooops, pending guest timer before its due\n");
  68.106 +//			printk("Ooops, pending guest timer before its due\n");
  68.107  			PSCBX(vcpu,irr[i]) &= ~mask;
  68.108  			goto check_start;
  68.109  		}
  68.110 @@ -753,12 +726,12 @@ UINT64 vcpu_deliverable_timer(VCPU *vcpu
  68.111  
  68.112  IA64FAULT vcpu_get_lid(VCPU *vcpu, UINT64 *pval)
  68.113  {
  68.114 -//extern unsigned long privop_trace;
  68.115 -//privop_trace=1;
  68.116 -	//TODO: Implement this
  68.117 -	printf("vcpu_get_lid: WARNING: Getting cr.lid always returns zero\n");
  68.118 -	//*pval = 0;
  68.119 -	*pval = ia64_getreg(_IA64_REG_CR_LID);
  68.120 +	/* Use real LID for domain0 until vIOSAPIC is present.
  68.121 +	   Use EID=0, ID=vcpu_id for domU.  */
  68.122 +	if (vcpu->domain == dom0)
  68.123 +		*pval = ia64_getreg(_IA64_REG_CR_LID);
  68.124 +	else
  68.125 +		*pval = vcpu->vcpu_id << 24;
  68.126  	return IA64_NO_FAULT;
  68.127  }
  68.128  
  68.129 @@ -932,6 +905,7 @@ IA64FAULT vcpu_set_tpr(VCPU *vcpu, UINT6
  68.130  {
  68.131  	if (val & 0xff00) return IA64_RSVDREG_FAULT;
  68.132  	PSCB(vcpu,tpr) = val;
  68.133 +	/* This can unmask interrupts.  */
  68.134  	if (vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
  68.135  		PSCB(vcpu,pending_interruption) = 1;
  68.136  	return (IA64_NO_FAULT);
  68.137 @@ -945,8 +919,8 @@ IA64FAULT vcpu_set_eoi(VCPU *vcpu, UINT6
  68.138  	p = &PSCBX(vcpu,insvc[3]);
  68.139  	for (i = 3; (i >= 0) && !(bits = *p); i--, p--);
  68.140  	if (i < 0) {
  68.141 -		printf("Trying to EOI interrupt when none are in-service.\r\n");
  68.142 -		return;
  68.143 +		printf("Trying to EOI interrupt when none are in-service.\n");
  68.144 +		return IA64_NO_FAULT;
  68.145  	}
  68.146  	bitnum = ia64_fls(bits);
  68.147  	vec = bitnum + (i*64);
  68.148 @@ -957,7 +931,7 @@ IA64FAULT vcpu_set_eoi(VCPU *vcpu, UINT6
  68.149  	if (PSCB(vcpu,interrupt_delivery_enabled)) { // but only if enabled...
  68.150  		// worry about this later... Linux only calls eoi
  68.151  		// with interrupts disabled
  68.152 -		printf("Trying to EOI interrupt with interrupts enabled\r\n");
  68.153 +		printf("Trying to EOI interrupt with interrupts enabled\n");
  68.154  	}
  68.155  	if (vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
  68.156  		PSCB(vcpu,pending_interruption) = 1;
  68.157 @@ -1296,7 +1270,7 @@ unsigned long recover_to_break_fault_cou
  68.158  
  68.159  int warn_region0_address = 0; // FIXME later: tie to a boot parameter?
  68.160  
  68.161 -IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha)
  68.162 +IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, BOOLEAN in_tpa, UINT64 *pteval, UINT64 *itir, UINT64 *iha)
  68.163  {
  68.164  	unsigned long region = address >> 61;
  68.165  	unsigned long pta, pte, rid, rr;
  68.166 @@ -1309,13 +1283,23 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN
  68.167  // FIXME: This seems to happen even though it shouldn't.  Need to track
  68.168  // this down, but since it has been apparently harmless, just flag it for now
  68.169  //			panic_domain(vcpu_regs(vcpu),
  68.170 -			printk(
  68.171 -			 "vcpu_translate: bad physical address: 0x%lx\n",address);
  68.172 +
  68.173 +			/*
  68.174 +			 * Guest may execute itc.d and rfi with psr.dt=0
  68.175 +			 * When VMM try to fetch opcode, tlb miss may happen,
  68.176 +			 * At this time PSCB(vcpu,metaphysical_mode)=1,
  68.177 +			 * region=5,VMM need to handle this tlb miss as if
  68.178 +			 * PSCB(vcpu,metaphysical_mode)=0
  68.179 +			 */           
  68.180 +			printk("vcpu_translate: bad physical address: 0x%lx\n",
  68.181 +			       address);
  68.182 +		} else {
  68.183 +			*pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS |
  68.184 +			          _PAGE_PL_2 | _PAGE_AR_RWX;
  68.185 +			*itir = PAGE_SHIFT << 2;
  68.186 +			phys_translate_count++;
  68.187 +			return IA64_NO_FAULT;
  68.188  		}
  68.189 -		*pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
  68.190 -		*itir = PAGE_SHIFT << 2;
  68.191 -		phys_translate_count++;
  68.192 -		return IA64_NO_FAULT;
  68.193  	}
  68.194  	else if (!region && warn_region0_address) {
  68.195  		REGS *regs = vcpu_regs(vcpu);
  68.196 @@ -1408,9 +1392,7 @@ IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 va
  68.197  	UINT64 pteval, itir, mask, iha;
  68.198  	IA64FAULT fault;
  68.199  
  68.200 -	in_tpa = 1;
  68.201 -	fault = vcpu_translate(vcpu, vadr, 1, &pteval, &itir, &iha);
  68.202 -	in_tpa = 0;
  68.203 +	fault = vcpu_translate(vcpu, vadr, TRUE, TRUE, &pteval, &itir, &iha);
  68.204  	if (fault == IA64_NO_FAULT)
  68.205  	{
  68.206  		mask = itir_mask(itir);
  68.207 @@ -1655,8 +1637,11 @@ IA64FAULT vcpu_set_rr(VCPU *vcpu, UINT64
  68.208  
  68.209  IA64FAULT vcpu_get_rr(VCPU *vcpu, UINT64 reg, UINT64 *pval)
  68.210  {
  68.211 -	UINT val = PSCB(vcpu,rrs)[reg>>61];
  68.212 -	*pval = val;
  68.213 +	if(VMX_DOMAIN(vcpu)){
  68.214 +		*pval = VMX(vcpu,vrr[reg>>61]);
  68.215 +	}else{
  68.216 +		*pval = PSCB(vcpu,rrs)[reg>>61];
  68.217 +	}
  68.218  	return (IA64_NO_FAULT);
  68.219  }
  68.220  
  68.221 @@ -1693,7 +1678,7 @@ IA64FAULT vcpu_set_pkr(VCPU *vcpu, UINT6
  68.222   VCPU translation register access routines
  68.223  **************************************************************************/
  68.224  
  68.225 -static void vcpu_purge_tr_entry(TR_ENTRY *trp)
  68.226 +static inline void vcpu_purge_tr_entry(TR_ENTRY *trp)
  68.227  {
  68.228  	trp->p = 0;
  68.229  }
  68.230 @@ -1747,8 +1732,6 @@ IA64FAULT vcpu_itr_i(VCPU *vcpu, UINT64 
  68.231  
  68.232  void foobar(void) { /*vcpu_verbose = 1;*/ }
  68.233  
  68.234 -extern struct domain *dom0;
  68.235 -
  68.236  void vcpu_itc_no_srlz(VCPU *vcpu, UINT64 IorD, UINT64 vaddr, UINT64 pte, UINT64 mp_pte, UINT64 logps)
  68.237  {
  68.238  	unsigned long psr;
  68.239 @@ -1793,7 +1776,6 @@ void vcpu_itc_no_srlz(VCPU *vcpu, UINT64
  68.240  IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
  68.241  {
  68.242  	unsigned long pteval, logps = itir_ps(itir);
  68.243 -	unsigned long translate_domain_pte(UINT64,UINT64,UINT64);
  68.244  	BOOLEAN swap_rr0 = (!(ifa>>61) && PSCB(vcpu,metaphysical_mode));
  68.245  
  68.246  	if (logps < PAGE_SHIFT) {
  68.247 @@ -1813,7 +1795,6 @@ IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 
  68.248  IA64FAULT vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
  68.249  {
  68.250  	unsigned long pteval, logps = itir_ps(itir);
  68.251 -	unsigned long translate_domain_pte(UINT64,UINT64,UINT64);
  68.252  	BOOLEAN swap_rr0 = (!(ifa>>61) && PSCB(vcpu,metaphysical_mode));
  68.253  
  68.254  	// FIXME: validate ifa here (not in Xen space), COULD MACHINE CHECK!
  68.255 @@ -1849,8 +1830,6 @@ IA64FAULT vcpu_fc(VCPU *vcpu, UINT64 vad
  68.256  	// TODO: Only allowed for current vcpu
  68.257  	UINT64 mpaddr, paddr;
  68.258  	IA64FAULT fault;
  68.259 -	unsigned long translate_domain_mpaddr(unsigned long);
  68.260 -	IA64FAULT vcpu_tpa(VCPU *, UINT64, UINT64 *);
  68.261  
  68.262  	fault = vcpu_tpa(vcpu, vadr, &mpaddr);
  68.263  	if (fault == IA64_NO_FAULT) {
  68.264 @@ -1885,7 +1864,6 @@ IA64FAULT vcpu_ptc_g(VCPU *vcpu, UINT64 
  68.265  
  68.266  IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 vadr,UINT64 addr_range)
  68.267  {
  68.268 -	extern void ia64_global_tlb_purge(UINT64 start, UINT64 end, UINT64 nbits);
  68.269  	// FIXME: validate not flushing Xen addresses
  68.270  	// if (Xen address) return(IA64_ILLOP_FAULT);
  68.271  	// FIXME: ??breaks if domain PAGE_SIZE < Xen PAGE_SIZE
    69.1 --- a/xen/arch/ia64/xen/xenirq.c	Mon Mar 20 09:56:46 2006 +0100
    69.2 +++ b/xen/arch/ia64/xen/xenirq.c	Mon Mar 20 09:56:54 2006 +0100
    69.3 @@ -68,7 +68,7 @@ void irq_exit(void)
    69.4   * ONLY gets called from ia64_leave_kernel
    69.5   * ONLY call with interrupts enabled
    69.6   */
    69.7 -void process_soft_irq()
    69.8 +void process_soft_irq(void)
    69.9  {
   69.10  	if (!in_interrupt() && local_softirq_pending()) {
   69.11  		add_preempt_count(SOFTIRQ_OFFSET);
    70.1 --- a/xen/arch/ia64/xen/xenmem.c	Mon Mar 20 09:56:46 2006 +0100
    70.2 +++ b/xen/arch/ia64/xen/xenmem.c	Mon Mar 20 09:56:54 2006 +0100
    70.3 @@ -13,12 +13,11 @@
    70.4  #include <asm/pgtable.h>
    70.5  #include <xen/mm.h>
    70.6  
    70.7 -extern struct page *zero_page_memmap_ptr;
    70.8  struct page_info *frame_table;
    70.9  unsigned long frame_table_size;
   70.10  unsigned long max_page;
   70.11  
   70.12 -struct page *mem_map;
   70.13 +struct page_info *mem_map;
   70.14  #define MAX_DMA_ADDRESS ~0UL	// FIXME???
   70.15  
   70.16  #ifdef CONFIG_VIRTUAL_MEM_MAP
   70.17 @@ -35,6 +34,8 @@ void
   70.18  paging_init (void)
   70.19  {
   70.20  	unsigned int mpt_order;
   70.21 +	unsigned long i;
   70.22 +
   70.23  	/* Create machine to physical mapping table
   70.24  	 * NOTE: similar to frame table, later we may need virtually
   70.25  	 * mapped mpt table if large hole exists. Also MAX_ORDER needs
   70.26 @@ -47,10 +48,9 @@ paging_init (void)
   70.27  		panic("Not enough memory to bootstrap Xen.\n");
   70.28  
   70.29  	printk("machine to physical table: 0x%lx\n", (u64)mpt_table);
   70.30 -	memset(mpt_table, INVALID_M2P_ENTRY, mpt_table_size);
   70.31 -	/* Other mapping setup */
   70.32 -
   70.33 -	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
   70.34 +	for (i = 0; i < (1UL << mpt_order); i++) {
   70.35 +		mpt_table[i] = INVALID_M2P_ENTRY;
   70.36 +	}
   70.37  }
   70.38  
   70.39  /* FIXME: postpone support to machines with big holes between physical memorys.
    71.1 --- a/xen/arch/ia64/xen/xenmisc.c	Mon Mar 20 09:56:46 2006 +0100
    71.2 +++ b/xen/arch/ia64/xen/xenmisc.c	Mon Mar 20 09:56:54 2006 +0100
    71.3 @@ -114,23 +114,6 @@ while(1);
    71.4  #endif
    71.5  
    71.6  ///////////////////////////////
    71.7 -// from arch/ia64/page_alloc.c
    71.8 -///////////////////////////////
    71.9 -DEFINE_PER_CPU(struct page_state, page_states) = {0};
   71.10 -unsigned long totalram_pages;
   71.11 -
   71.12 -void __mod_page_state(unsigned long offset, unsigned long delta)
   71.13 -{
   71.14 -	unsigned long flags;
   71.15 -	void* ptr;
   71.16 -
   71.17 -	local_irq_save(flags);
   71.18 -	ptr = &__get_cpu_var(page_states);
   71.19 -	*(unsigned long*)(ptr + offset) += delta;
   71.20 -	local_irq_restore(flags);
   71.21 -}
   71.22 -
   71.23 -///////////////////////////////
   71.24  // from arch/x86/flushtlb.c
   71.25  ///////////////////////////////
   71.26  
   71.27 @@ -147,12 +130,17 @@ void init_percpu_info(void)
   71.28      //memset(percpu_info, 0, sizeof(percpu_info));
   71.29  }
   71.30  
   71.31 -#if 0
   71.32 -void free_page_type(struct page_info *page, unsigned int type)
   71.33 +void free_page_type(struct page_info *page, u32 type)
   71.34  {
   71.35 -	dummy();
   71.36 +//	dummy();
   71.37 +	return;
   71.38  }
   71.39 -#endif
   71.40 +
   71.41 +int alloc_page_type(struct page_info *page, u32 type)
   71.42 +{
   71.43 +//	dummy();
   71.44 +	return 1;
   71.45 +}
   71.46  
   71.47  ///////////////////////////////
   71.48  //// misc memory stuff
   71.49 @@ -166,7 +154,7 @@ unsigned long __get_free_pages(unsigned 
   71.50  	return (unsigned long)p;
   71.51  }
   71.52  
   71.53 -void __free_pages(struct page *page, unsigned int order)
   71.54 +void __free_pages(struct page_info *page, unsigned int order)
   71.55  {
   71.56  	if (order) BUG();
   71.57  	free_xenheap_page(page);
   71.58 @@ -306,9 +294,9 @@ void context_switch(struct vcpu *prev, s
   71.59      uint64_t pta;
   71.60  
   71.61      local_irq_save(spsr);
   71.62 -    if(VMX_DOMAIN(prev)){
   71.63 -    	vtm_domain_out(prev);
   71.64 -    }
   71.65 +//    if(VMX_DOMAIN(prev)){
   71.66 +//    	vtm_domain_out(prev);
   71.67 +//    }
   71.68  	context_switch_count++;
   71.69  	switch_to(prev,next,prev);
   71.70  //    if(VMX_DOMAIN(current)){
   71.71 @@ -326,7 +314,7 @@ if (!i--) { printk("+"); i = 1000000; }
   71.72  }
   71.73  
   71.74      if (VMX_DOMAIN(current)){
   71.75 -        vtm_domain_in(current);
   71.76 +//        vtm_domain_in(current);
   71.77  		vmx_load_all_rr(current);
   71.78      }else{
   71.79      	extern char ia64_ivt;
   71.80 @@ -415,3 +403,203 @@ void sync_split_caches(void)
   71.81  	}
   71.82  	else printk("sync_split_caches ignored for CPU with no split cache\n");
   71.83  }
   71.84 +
   71.85 +///////////////////////////////
   71.86 +// from arch/x86/mm.c
   71.87 +///////////////////////////////
   71.88 +
   71.89 +#ifdef VERBOSE
   71.90 +#define MEM_LOG(_f, _a...)                           \
   71.91 +  printk("DOM%u: (file=mm.c, line=%d) " _f "\n", \
   71.92 +         current->domain->domain_id , __LINE__ , ## _a )
   71.93 +#else
   71.94 +#define MEM_LOG(_f, _a...) ((void)0)
   71.95 +#endif
   71.96 +
   71.97 +void cleanup_writable_pagetable(struct domain *d)
   71.98 +{
   71.99 +  return;
  71.100 +}
  71.101 +
  71.102 +void put_page_type(struct page_info *page)
  71.103 +{
  71.104 +    u32 nx, x, y = page->u.inuse.type_info;
  71.105 +
  71.106 + again:
  71.107 +    do {
  71.108 +        x  = y;
  71.109 +        nx = x - 1;
  71.110 +
  71.111 +        ASSERT((x & PGT_count_mask) != 0);
  71.112 +
  71.113 +        /*
  71.114 +         * The page should always be validated while a reference is held. The 
  71.115 +         * exception is during domain destruction, when we forcibly invalidate 
  71.116 +         * page-table pages if we detect a referential loop.
  71.117 +         * See domain.c:relinquish_list().
  71.118 +         */
  71.119 +        ASSERT((x & PGT_validated) || 
  71.120 +               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
  71.121 +
  71.122 +        if ( unlikely((nx & PGT_count_mask) == 0) )
  71.123 +        {
  71.124 +            /* Record TLB information for flush later. Races are harmless. */
  71.125 +            page->tlbflush_timestamp = tlbflush_current_time();
  71.126 +            
  71.127 +            if ( unlikely((nx & PGT_type_mask) <= PGT_l4_page_table) &&
  71.128 +                 likely(nx & PGT_validated) )
  71.129 +            {
  71.130 +                /*
  71.131 +                 * Page-table pages must be unvalidated when count is zero. The
  71.132 +                 * 'free' is safe because the refcnt is non-zero and validated
  71.133 +                 * bit is clear => other ops will spin or fail.
  71.134 +                 */
  71.135 +                if ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, 
  71.136 +                                           x & ~PGT_validated)) != x) )
  71.137 +                    goto again;
  71.138 +                /* We cleared the 'valid bit' so we do the clean up. */
  71.139 +                free_page_type(page, x);
  71.140 +                /* Carry on, but with the 'valid bit' now clear. */
  71.141 +                x  &= ~PGT_validated;
  71.142 +                nx &= ~PGT_validated;
  71.143 +            }
  71.144 +        }
  71.145 +        else if ( unlikely(((nx & (PGT_pinned | PGT_count_mask)) == 
  71.146 +                            (PGT_pinned | 1)) &&
  71.147 +                           ((nx & PGT_type_mask) != PGT_writable_page)) )
  71.148 +        {
  71.149 +            /* Page is now only pinned. Make the back pointer mutable again. */
  71.150 +            nx |= PGT_va_mutable;
  71.151 +        }
  71.152 +    }
  71.153 +    while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
  71.154 +}
  71.155 +
  71.156 +
  71.157 +int get_page_type(struct page_info *page, u32 type)
  71.158 +{
  71.159 +    u32 nx, x, y = page->u.inuse.type_info;
  71.160 +
  71.161 + again:
  71.162 +    do {
  71.163 +        x  = y;
  71.164 +        nx = x + 1;
  71.165 +        if ( unlikely((nx & PGT_count_mask) == 0) )
  71.166 +        {
  71.167 +            MEM_LOG("Type count overflow on pfn %lx", page_to_mfn(page));
  71.168 +            return 0;
  71.169 +        }
  71.170 +        else if ( unlikely((x & PGT_count_mask) == 0) )
  71.171 +        {
  71.172 +            if ( (x & (PGT_type_mask|PGT_va_mask)) != type )
  71.173 +            {
  71.174 +                if ( (x & PGT_type_mask) != (type & PGT_type_mask) )
  71.175 +                {
  71.176 +                    /*
  71.177 +                     * On type change we check to flush stale TLB
  71.178 +                     * entries. This may be unnecessary (e.g., page
  71.179 +                     * was GDT/LDT) but those circumstances should be
  71.180 +                     * very rare.
  71.181 +                     */
  71.182 +                    cpumask_t mask =
  71.183 +                        page_get_owner(page)->domain_dirty_cpumask;
  71.184 +                    tlbflush_filter(mask, page->tlbflush_timestamp);
  71.185 +
  71.186 +                    if ( unlikely(!cpus_empty(mask)) )
  71.187 +                    {
  71.188 +                        perfc_incrc(need_flush_tlb_flush);
  71.189 +                        flush_tlb_mask(mask);
  71.190 +                    }
  71.191 +                }
  71.192 +
  71.193 +                /* We lose existing type, back pointer, and validity. */
  71.194 +                nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated);
  71.195 +                nx |= type;
  71.196 +
  71.197 +                /* No special validation needed for writable pages. */
  71.198 +                /* Page tables and GDT/LDT need to be scanned for validity. */
  71.199 +                if ( type == PGT_writable_page )
  71.200 +                    nx |= PGT_validated;
  71.201 +            }
  71.202 +        }
  71.203 +        else
  71.204 +        {
  71.205 +            if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) )
  71.206 +            {
  71.207 +                if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
  71.208 +                {
  71.209 +                    if ( current->domain == page_get_owner(page) )
  71.210 +                    {
  71.211 +                        /*
  71.212 +                         * This ensures functions like set_gdt() see up-to-date
  71.213 +                         * type info without needing to clean up writable p.t.
  71.214 +                         * state on the fast path.
  71.215 +                         */
  71.216 +                        LOCK_BIGLOCK(current->domain);
  71.217 +                        cleanup_writable_pagetable(current->domain);
  71.218 +                        y = page->u.inuse.type_info;
  71.219 +                        UNLOCK_BIGLOCK(current->domain);
  71.220 +                        /* Can we make progress now? */
  71.221 +                        if ( ((y & PGT_type_mask) == (type & PGT_type_mask)) ||
  71.222 +                             ((y & PGT_count_mask) == 0) )
  71.223 +                            goto again;
  71.224 +                    }
  71.225 +                    if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
  71.226 +                         ((type & PGT_type_mask) != PGT_l1_page_table) )
  71.227 +                        MEM_LOG("Bad type (saw %" PRtype_info
  71.228 +                                " != exp %" PRtype_info ") "
  71.229 +                                "for mfn %lx (pfn %lx)",
  71.230 +                                x, type, page_to_mfn(page),
  71.231 +                                get_gpfn_from_mfn(page_to_mfn(page)));
  71.232 +                    return 0;
  71.233 +                }
  71.234 +                else if ( (x & PGT_va_mask) == PGT_va_mutable )
  71.235 +                {
  71.236 +                    /* The va backpointer is mutable, hence we update it. */
  71.237 +                    nx &= ~PGT_va_mask;
  71.238 +                    nx |= type; /* we know the actual type is correct */
  71.239 +                }
  71.240 +                else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
  71.241 +                          ((type & PGT_va_mask) != (x & PGT_va_mask)) )
  71.242 +                {
  71.243 +#ifdef CONFIG_X86_PAE
  71.244 +                    /* We use backptr as extra typing. Cannot be unknown. */
  71.245 +                    if ( (type & PGT_type_mask) == PGT_l2_page_table )
  71.246 +                        return 0;
  71.247 +#endif
  71.248 +                    /* This table is possibly mapped at multiple locations. */
  71.249 +                    nx &= ~PGT_va_mask;
  71.250 +                    nx |= PGT_va_unknown;
  71.251 +                }
  71.252 +            }
  71.253 +            if ( unlikely(!(x & PGT_validated)) )
  71.254 +            {
  71.255 +                /* Someone else is updating validation of this page. Wait... */
  71.256 +                while ( (y = page->u.inuse.type_info) == x )
  71.257 +                    cpu_relax();
  71.258 +                goto again;
  71.259 +            }
  71.260 +        }
  71.261 +    }
  71.262 +    while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
  71.263 +
  71.264 +    if ( unlikely(!(nx & PGT_validated)) )
  71.265 +    {
  71.266 +        /* Try to validate page type; drop the new reference on failure. */
  71.267 +        if ( unlikely(!alloc_page_type(page, type)) )
  71.268 +        {
  71.269 +            MEM_LOG("Error while validating mfn %lx (pfn %lx) for type %"
  71.270 +                    PRtype_info ": caf=%08x taf=%" PRtype_info,
  71.271 +                    page_to_mfn(page), get_gpfn_from_mfn(page_to_mfn(page)),
  71.272 +                    type, page->count_info, page->u.inuse.type_info);
  71.273 +            /* Noone else can get a reference. We hold the only ref. */
  71.274 +            page->u.inuse.type_info = 0;
  71.275 +            return 0;
  71.276 +        }
  71.277 +
  71.278 +        /* Noone else is updating simultaneously. */
  71.279 +        __set_bit(_PGT_validated, &page->u.inuse.type_info);
  71.280 +    }
  71.281 +
  71.282 +    return 1;
  71.283 +}
    72.1 --- a/xen/arch/ia64/xen/xensetup.c	Mon Mar 20 09:56:46 2006 +0100
    72.2 +++ b/xen/arch/ia64/xen/xensetup.c	Mon Mar 20 09:56:54 2006 +0100
    72.3 @@ -27,6 +27,7 @@
    72.4  unsigned long xenheap_phys_end;
    72.5  
    72.6  char saved_command_line[COMMAND_LINE_SIZE];
    72.7 +char dom0_command_line[COMMAND_LINE_SIZE];
    72.8  
    72.9  struct vcpu *idle_vcpu[NR_CPUS];
   72.10  
   72.11 @@ -119,11 +120,12 @@ static char null[4] = { 0 };
   72.12  void early_cmdline_parse(char **cmdline_p)
   72.13  {
   72.14      char *guest_cmd;
   72.15 -    char *split = "--";
   72.16 +    static const char * const split = "--";
   72.17  
   72.18      if (*cmdline_p == NULL) {
   72.19  	*cmdline_p = &null[0];
   72.20  	saved_command_line[0] = '\0';
   72.21 +	dom0_command_line[0] = '\0';
   72.22  	return;
   72.23      }
   72.24  
   72.25 @@ -138,7 +140,8 @@ void early_cmdline_parse(char **cmdline_
   72.26  	while (*guest_cmd == ' ') guest_cmd++;
   72.27      }
   72.28  
   72.29 -    strlcpy(saved_command_line, guest_cmd, COMMAND_LINE_SIZE);
   72.30 +    strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
   72.31 +    strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
   72.32      return;
   72.33  }
   72.34  
   72.35 @@ -155,24 +158,6 @@ struct ns16550_defaults ns16550_com2 = {
   72.36      .parity    = 'n',
   72.37      .stop_bits = 1
   72.38  };
   72.39 -/*  This is a wrapper function of init_domheap_pages,
   72.40 - *  memory exceeds (max_page<<PAGE_SHIFT) will not be reclaimed.
   72.41 - *  This function will go away when the virtual memmap/discontig
   72.42 - *  memory issues are solved
   72.43 - */
   72.44 -void init_domheap_pages_wrapper(unsigned long ps, unsigned long pe)
   72.45 -{
   72.46 -    unsigned long s_nrm, e_nrm, max_mem;
   72.47 -    max_mem = (max_page+1)<<PAGE_SHIFT;
   72.48 -    s_nrm = (ps+PAGE_SIZE-1)&PAGE_MASK;
   72.49 -    e_nrm = pe&PAGE_MASK;
   72.50 -    s_nrm = min(s_nrm, max_mem);
   72.51 -    e_nrm = min(e_nrm, max_mem);
   72.52 -    if(s_nrm < e_nrm)
   72.53 -         init_domheap_pages(s_nrm, e_nrm);
   72.54 -}
   72.55 -
   72.56 -
   72.57  
   72.58  void start_kernel(void)
   72.59  {
   72.60 @@ -349,7 +334,6 @@ printk("num_online_cpus=%d, max_cpus=%d\
   72.61          if ( num_online_cpus() >= max_cpus )
   72.62              break;
   72.63          if ( !cpu_online(i) ) {
   72.64 -printk("About to call __cpu_up(%d)\n",i);
   72.65              __cpu_up(i);
   72.66  	}
   72.67      }
   72.68 @@ -395,17 +379,6 @@ printk("About to call domain_create()\n"
   72.69      /* PIN domain0 on CPU 0.  */
   72.70      dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
   72.71  
   72.72 -    /* The stash space for the initial kernel image can now be freed up. */
   72.73 -    /* init_domheap_pages_wrapper is temporary solution, please refer to the
   72.74 -     * descriptor of this function */
   72.75 -    init_domheap_pages_wrapper(ia64_boot_param->domain_start,
   72.76 -           ia64_boot_param->domain_start+ia64_boot_param->domain_size);
   72.77 -    /* throw away initrd area passed from elilo */
   72.78 -    if (ia64_boot_param->initrd_size) {
   72.79 -        init_domheap_pages_wrapper(ia64_boot_param->initrd_start,
   72.80 -           ia64_boot_param->initrd_start+ia64_boot_param->initrd_size);
   72.81 -    }
   72.82 -
   72.83      if (!running_on_sim)  // slow on ski and pages are pre-initialized to zero
   72.84  	scrub_heap_pages();
   72.85  
    73.1 --- a/xen/arch/ia64/xen/xentime.c	Mon Mar 20 09:56:46 2006 +0100
    73.2 +++ b/xen/arch/ia64/xen/xentime.c	Mon Mar 20 09:56:54 2006 +0100
    73.3 @@ -116,6 +116,12 @@ xen_timer_interrupt (int irq, void *dev_
    73.4  	}
    73.5  #endif
    73.6  #endif
    73.7 +
    73.8 +#if 0
    73.9 +	/* Nobody seems to be able to explain this code.
   73.10 +	   It seems to be accumulated tricks, which are not required anymore.
   73.11 +	   Also I have made many tests, I'd like to get confirmation from
   73.12 +	   other site (TG).  */
   73.13  	if (current->domain == dom0) {
   73.14  		// FIXME: there's gotta be a better way of doing this...
   73.15  		// We have to ensure that domain0 is launched before we
   73.16 @@ -130,6 +136,7 @@ xen_timer_interrupt (int irq, void *dev_
   73.17  			vcpu_wake(dom0->vcpu[0]);
   73.18  		}
   73.19  	}
   73.20 +#endif
   73.21  	if (!is_idle_domain(current->domain))  {
   73.22  		if (vcpu_timer_expired(current)) {
   73.23  			vcpu_pend_timer(current);
   73.24 @@ -141,7 +148,7 @@ xen_timer_interrupt (int irq, void *dev_
   73.25  	new_itm = local_cpu_data->itm_next;
   73.26  
   73.27  	if (!VMX_DOMAIN(current) && !time_after(ia64_get_itc(), new_itm))
   73.28 -		return;
   73.29 +		return IRQ_HANDLED;
   73.30  
   73.31  	if (VMX_DOMAIN(current))
   73.32  		vcpu_wake(current);
    74.1 --- a/xen/arch/x86/Makefile	Mon Mar 20 09:56:46 2006 +0100
    74.2 +++ b/xen/arch/x86/Makefile	Mon Mar 20 09:56:54 2006 +0100
    74.3 @@ -1,59 +1,61 @@
    74.4 -
    74.5  include $(BASEDIR)/Rules.mk
    74.6  
    74.7 -OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S))
    74.8 -OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c))
    74.9 -OBJS += $(patsubst %.c,%.o,$(wildcard acpi/*.c))
   74.10 -OBJS += $(patsubst %.c,%.o,$(wildcard genapic/*.c))
   74.11 -OBJS += $(patsubst %.c,%.o,$(wildcard cpu/*.c))
   74.12 -OBJS += $(patsubst %.c,%.o,$(wildcard cpu/mcheck/*.c))
   74.13 -OBJS += $(patsubst %.c,%.o,$(wildcard cpu/mtrr/*.c))
   74.14 -OBJS += $(patsubst %.c,%.o,$(wildcard hvm/*.c))
   74.15 -OBJS += $(patsubst %.c,%.o,$(wildcard hvm/vmx/*.c))
   74.16 -OBJS += $(patsubst %.S,%.o,$(wildcard hvm/vmx/$(TARGET_SUBARCH)/*.S))
   74.17 -OBJS += $(patsubst %.c,%.o,$(wildcard hvm/svm/*.c))
   74.18 -OBJS += $(patsubst %.S,%.o,$(wildcard hvm/svm/$(TARGET_SUBARCH)/*.S))
   74.19 +subdirs-y += acpi
   74.20 +subdirs-y += cpu
   74.21 +subdirs-y += genapic
   74.22 +subdirs-y += hvm
   74.23  
   74.24 -ifeq ($(TARGET_SUBARCH),x86_64) 
   74.25 -OBJS := $(subst cpu/centaur.o,,$(OBJS))
   74.26 -OBJS := $(subst cpu/cyrix.o,,$(OBJS))
   74.27 -OBJS := $(subst cpu/rise.o,,$(OBJS))
   74.28 -OBJS := $(subst cpu/transmeta.o,,$(OBJS))
   74.29 +subdirs-$(x86_32) += x86_32
   74.30 +subdirs-$(x86_64) += x86_64
   74.31 +
   74.32 +obj-y += apic.o
   74.33 +obj-y += audit.o
   74.34 +obj-y += bitops.o
   74.35 +obj-y += delay.o
   74.36 +obj-y += dmi_scan.o
   74.37 +obj-y += dom0_ops.o
   74.38 +obj-y += domain.o
   74.39 +obj-y += domain_build.o
   74.40 +obj-y += e820.o
   74.41 +obj-y += extable.o
   74.42 +obj-y += flushtlb.o
   74.43 +obj-y += i387.o
   74.44 +obj-y += i8259.o
   74.45 +obj-y += io_apic.o
   74.46 +obj-y += irq.o
   74.47 +obj-y += microcode.o
   74.48 +obj-y += mm.o
   74.49 +obj-y += mpparse.o
   74.50 +obj-y += nmi.o
   74.51 +obj-y += physdev.o
   74.52 +obj-y += rwlock.o
   74.53 +obj-y += setup.o
   74.54 +obj-y += smp.o
   74.55 +obj-y += smpboot.o
   74.56 +obj-y += string.o
   74.57 +obj-y += time.o
   74.58 +obj-y += trampoline.o
   74.59 +obj-y += traps.o
   74.60 +obj-y += usercopy.o
   74.61 +obj-y += x86_emulate.o
   74.62 +
   74.63 +ifneq ($(pae),n)
   74.64 +obj-$(x86_32) += shadow.o shadow_public.o shadow_guest32.o
   74.65 +else
   74.66 +obj-$(x86_32) += shadow32.o
   74.67  endif
   74.68  
   74.69 -OBJS := $(patsubst shadow%.o,,$(OBJS))	# drop all
   74.70 -ifeq ($(TARGET_SUBARCH),x86_64) 
   74.71 - OBJS += shadow.o shadow_public.o shadow_guest32.o shadow_guest32pae.o	# x86_64: new code
   74.72 -endif
   74.73 -ifeq ($(TARGET_SUBARCH),x86_32) 
   74.74 - ifneq ($(pae),n)
   74.75 -  OBJS += shadow.o shadow_public.o shadow_guest32.o	# x86_32p: new code
   74.76 - else
   74.77 -  OBJS += shadow32.o			# x86_32: old code
   74.78 - endif
   74.79 -endif
   74.80 +obj-$(x86_64) += shadow.o shadow_public.o shadow_guest32.o shadow_guest32pae.o
   74.81  
   74.82 -ifneq ($(supervisor_mode_kernel),y)
   74.83 -OBJS := $(subst x86_32/supervisor_mode_kernel.o,,$(OBJS))
   74.84 -endif
   74.85 +obj-$(crash_debug) += gdbstub.o
   74.86  
   74.87 -OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
   74.88 -OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
   74.89 -
   74.90 -ifneq ($(crash_debug),y)
   74.91 -OBJS := $(patsubst gdbstub%.o,,$(OBJS))
   74.92 -endif
   74.93 -
   74.94 -default: $(TARGET)
   74.95 +include $(BASEDIR)/Post.mk
   74.96  
   74.97  $(TARGET): $(TARGET)-syms boot/mkelf32
   74.98  	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
   74.99  	`$(NM) $(TARGET)-syms | sort | tail -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
  74.100  
  74.101 -$(CURDIR)/arch.o: $(OBJS)
  74.102 -	$(LD) $(LDFLAGS) -r -o $@ $(OBJS)
  74.103 -
  74.104 -$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds
  74.105 +$(TARGET)-syms: boot/$(TARGET_SUBARCH).o xen.lds
  74.106  	$(LD) $(LDFLAGS) -T xen.lds -N \
  74.107  	    boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@
  74.108  	$(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
  74.109 @@ -77,21 +79,5 @@ boot/mkelf32: boot/mkelf32.c
  74.110  
  74.111  shadow_guest32.o: shadow.c
  74.112  
  74.113 -clean:
  74.114 -	rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32
  74.115 -	rm -f x86_32/*.o x86_32/*~ x86_32/core
  74.116 -	rm -f x86_64/*.o x86_64/*~ x86_64/core
  74.117 -	rm -f mtrr/*.o mtrr/*~ mtrr/core
  74.118 -	rm -f acpi/*.o acpi/*~ acpi/core
  74.119 -	rm -f genapic/*.o genapic/*~ genapic/core
  74.120 -	rm -f cpu/*.o cpu/*~ cpu/core
  74.121 -	rm -f hvm/*.o hvm/*~ hvm/core
  74.122 -	rm -f hvm/vmx/*.o hvm/vmx/*~ hvm/vmx/core
  74.123 -	rm -f hvm/vmx/x86_32/*.o hvm/vmx/x86_32/*~ hvm/vmx/x86_32/core
  74.124 -	rm -f hvm/vmx/x86_64/*.o hvm/vmx/x86_64/*~ hvm/vmx/x86_64/core
  74.125 -	rm -f hvm/svm/*.o hvm/svm/*~ hvm/svm/core
  74.126 -	rm -f hvm/svm/x86_32/*.o hvm/svm/x86_32/*~ hvm/svm/x86_32/core
  74.127 -	rm -f hvm/svm/x86_64/*.o hvm/svm/x86_64/*~ hvm/svm/x86_64/core
  74.128 -	rm -f xen.lds
  74.129 -
  74.130 -.PHONY: default clean
  74.131 +clean:: FORCE
  74.132 +	rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32
    75.1 --- a/xen/arch/x86/Rules.mk	Mon Mar 20 09:56:46 2006 +0100
    75.2 +++ b/xen/arch/x86/Rules.mk	Mon Mar 20 09:56:54 2006 +0100
    75.3 @@ -1,6 +1,8 @@
    75.4  ########################################
    75.5  # x86-specific definitions
    75.6  
    75.7 +HAS_ACPI := y
    75.8 +
    75.9  #
   75.10  # If you change any of these configuration options then you must
   75.11  # 'make clean' before rebuilding.
   75.12 @@ -31,13 +33,17 @@ CFLAGS  += -DCONFIG_X86_SUPERVISOR_MODE_
   75.13  endif
   75.14  
   75.15  ifeq ($(XEN_TARGET_ARCH),x86_32)
   75.16 -LDFLAGS += -m elf_i386 
   75.17 +LDFLAGS += -m elf_i386
   75.18 +x86_32 := y
   75.19 +x86_64 := n
   75.20  endif
   75.21  
   75.22  ifeq ($(TARGET_SUBARCH),x86_64)
   75.23  CFLAGS  += -mno-red-zone -fpic -fno-reorder-blocks
   75.24  CFLAGS  += -fno-asynchronous-unwind-tables
   75.25  LDFLAGS += -m elf_x86_64
   75.26 +x86_32 := n
   75.27 +x86_64 := y
   75.28  endif
   75.29  
   75.30  # Test for at least GCC v3.2.x.
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/xen/arch/x86/acpi/Makefile	Mon Mar 20 09:56:54 2006 +0100
    76.3 @@ -0,0 +1,5 @@
    76.4 +include $(BASEDIR)/Rules.mk
    76.5 +
    76.6 +obj-y += boot.o
    76.7 +
    76.8 +include $(BASEDIR)/Post.mk
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/xen/arch/x86/cpu/Makefile	Mon Mar 20 09:56:54 2006 +0100
    77.3 @@ -0,0 +1,16 @@
    77.4 +include $(BASEDIR)/Rules.mk
    77.5 +
    77.6 +subdirs-y += mcheck
    77.7 +subdirs-y += mtrr
    77.8 +
    77.9 +obj-y += amd.o
   77.10 +obj-y += common.o
   77.11 +obj-y += intel.o
   77.12 +obj-y += intel_cacheinfo.o
   77.13 +
   77.14 +obj-$(x86_32) += centaur.o
   77.15 +obj-$(x86_32) += cyrix.o
   77.16 +obj-$(x86_32) += rise.o
   77.17 +obj-$(x86_32) += transmeta.o
   77.18 +
   77.19 +include $(BASEDIR)/Post.mk
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/xen/arch/x86/cpu/mcheck/Makefile	Mon Mar 20 09:56:54 2006 +0100
    78.3 @@ -0,0 +1,11 @@
    78.4 +include $(BASEDIR)/Rules.mk
    78.5 +
    78.6 +obj-y += k7.o
    78.7 +obj-y += mce.o
    78.8 +obj-y += non-fatal.o
    78.9 +obj-y += p4.o
   78.10 +obj-y += p5.o
   78.11 +obj-y += p6.o
   78.12 +obj-y += winchip.o
   78.13 +
   78.14 +include $(BASEDIR)/Post.mk
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/xen/arch/x86/cpu/mtrr/Makefile	Mon Mar 20 09:56:54 2006 +0100
    79.3 @@ -0,0 +1,10 @@
    79.4 +include $(BASEDIR)/Rules.mk
    79.5 +
    79.6 +obj-y += amd.o
    79.7 +obj-y += centaur.o
    79.8 +obj-y += cyrix.o
    79.9 +obj-y += generic.o
   79.10 +obj-y += main.o
   79.11 +obj-y += state.o
   79.12 +
   79.13 +include $(BASEDIR)/Post.mk
    80.1 --- a/xen/arch/x86/domain.c	Mon Mar 20 09:56:46 2006 +0100
    80.2 +++ b/xen/arch/x86/domain.c	Mon Mar 20 09:56:54 2006 +0100
    80.3 @@ -51,6 +51,9 @@ struct percpu_ctxt {
    80.4  } __cacheline_aligned;
    80.5  static struct percpu_ctxt percpu_ctxt[NR_CPUS];
    80.6  
    80.7 +static void paravirt_ctxt_switch_from(struct vcpu *v);
    80.8 +static void paravirt_ctxt_switch_to(struct vcpu *v);
    80.9 +
   80.10  static void continue_idle_domain(struct vcpu *v)
   80.11  {
   80.12      reset_stack_and_jump(idle_loop);
   80.13 @@ -226,6 +229,9 @@ struct vcpu *alloc_vcpu_struct(struct do
   80.14          v->arch.schedule_tail = continue_nonidle_domain;
   80.15      }
   80.16  
   80.17 +    v->arch.ctxt_switch_from = paravirt_ctxt_switch_from;
   80.18 +    v->arch.ctxt_switch_to   = paravirt_ctxt_switch_to;
   80.19 +
   80.20      v->arch.perdomain_ptes =
   80.21          d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
   80.22  
   80.23 @@ -685,21 +691,32 @@ static void save_segments(struct vcpu *v
   80.24      percpu_ctxt[smp_processor_id()].dirty_segment_mask = dirty_segment_mask;
   80.25  }
   80.26  
   80.27 -#define switch_kernel_stack(_n,_c) ((void)0)
   80.28 +#define switch_kernel_stack(v) ((void)0)
   80.29  
   80.30  #elif defined(__i386__)
   80.31  
   80.32  #define load_segments(n) ((void)0)
   80.33  #define save_segments(p) ((void)0)
   80.34  
   80.35 -static inline void switch_kernel_stack(struct vcpu *n, unsigned int cpu)
   80.36 +static inline void switch_kernel_stack(struct vcpu *v)
   80.37  {
   80.38 -    struct tss_struct *tss = &init_tss[cpu];
   80.39 -    tss->esp1 = n->arch.guest_context.kernel_sp;
   80.40 -    tss->ss1  = n->arch.guest_context.kernel_ss;
   80.41 +    struct tss_struct *tss = &init_tss[smp_processor_id()];
   80.42 +    tss->esp1 = v->arch.guest_context.kernel_sp;
   80.43 +    tss->ss1  = v->arch.guest_context.kernel_ss;
   80.44  }
   80.45  
   80.46 -#endif
   80.47 +#endif /* __i386__ */
   80.48 +
   80.49 +static void paravirt_ctxt_switch_from(struct vcpu *v)
   80.50 +{
   80.51 +    save_segments(v);
   80.52 +}
   80.53 +
   80.54 +static void paravirt_ctxt_switch_to(struct vcpu *v)
   80.55 +{
   80.56 +    set_int80_direct_trap(v);
   80.57 +    switch_kernel_stack(v);
   80.58 +}
   80.59  
   80.60  #define loaddebug(_v,_reg) \
   80.61      __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
   80.62 @@ -720,15 +737,7 @@ static void __context_switch(void)
   80.63                 stack_regs,
   80.64                 CTXT_SWITCH_STACK_BYTES);
   80.65          unlazy_fpu(p);
   80.66 -        if ( !hvm_guest(p) )
   80.67 -        {
   80.68 -            save_segments(p);
   80.69 -        }
   80.70 -        else
   80.71 -        {
   80.72 -            hvm_save_segments(p);
   80.73 -            hvm_load_msrs();
   80.74 -        }
   80.75 +        p->arch.ctxt_switch_from(p);
   80.76      }
   80.77  
   80.78      if ( !is_idle_vcpu(n) )
   80.79 @@ -749,15 +758,7 @@ static void __context_switch(void)
   80.80              loaddebug(&n->arch.guest_context, 7);
   80.81          }
   80.82  
   80.83 -        if ( !hvm_guest(n) )
   80.84 -        {
   80.85 -            set_int80_direct_trap(n);
   80.86 -            switch_kernel_stack(n, cpu);
   80.87 -        }
   80.88 -        else
   80.89 -        {
   80.90 -            hvm_restore_msrs(n);
   80.91 -        }
   80.92 +        n->arch.ctxt_switch_to(n);
   80.93      }
   80.94  
   80.95      if ( p->domain != n->domain )
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/xen/arch/x86/genapic/Makefile	Mon Mar 20 09:56:54 2006 +0100
    81.3 @@ -0,0 +1,10 @@
    81.4 +include $(BASEDIR)/Rules.mk
    81.5 +
    81.6 +obj-y += bigsmp.o
    81.7 +obj-y += default.o
    81.8 +obj-y += es7000.o
    81.9 +obj-y += es7000plat.o
   81.10 +obj-y += probe.o
   81.11 +obj-y += summit.o
   81.12 +
   81.13 +include $(BASEDIR)/Post.mk
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/xen/arch/x86/hvm/Makefile	Mon Mar 20 09:56:54 2006 +0100
    82.3 @@ -0,0 +1,14 @@
    82.4 +include $(BASEDIR)/Rules.mk
    82.5 +
    82.6 +subdirs-y += svm
    82.7 +subdirs-y += vmx
    82.8 +
    82.9 +obj-y += hvm.o
   82.10 +obj-y += i8259.o
   82.11 +obj-y += intercept.o
   82.12 +obj-y += io.o
   82.13 +obj-y += platform.o
   82.14 +obj-y += vioapic.o
   82.15 +obj-y += vlapic.o
   82.16 +
   82.17 +include $(BASEDIR)/Post.mk
    83.1 --- a/xen/arch/x86/hvm/intercept.c	Mon Mar 20 09:56:46 2006 +0100
    83.2 +++ b/xen/arch/x86/hvm/intercept.c	Mon Mar 20 09:56:54 2006 +0100
    83.3 @@ -338,10 +338,10 @@ void hlt_timer_fn(void *data)
    83.4  
    83.5  static __inline__ void missed_ticks(struct hvm_virpit*vpit)
    83.6  {
    83.7 -    int        missed_ticks;
    83.8 +    int missed_ticks;
    83.9  
   83.10      missed_ticks = (NOW() - vpit->scheduled)/(s_time_t) vpit->period;
   83.11 -    if ( missed_ticks > 0 ) {
   83.12 +    if ( missed_ticks++ >= 0 ) {
   83.13          vpit->pending_intr_nr += missed_ticks;
   83.14          vpit->scheduled += missed_ticks * vpit->period;
   83.15      }
   83.16 @@ -355,22 +355,16 @@ static void pit_timer_fn(void *data)
   83.17  
   83.18      /* pick up missed timer tick */
   83.19      missed_ticks(vpit);
   83.20 -
   83.21 -    vpit->pending_intr_nr++;
   83.22      if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
   83.23 -        vpit->scheduled += vpit->period;
   83.24          set_timer(&vpit->pit_timer, vpit->scheduled);
   83.25      }
   83.26  }
   83.27  
   83.28 +/* pick up missed timer ticks at deactive time */
   83.29  void pickup_deactive_ticks(struct hvm_virpit *vpit)
   83.30  {
   83.31 -
   83.32      if ( !active_timer(&(vpit->pit_timer)) ) {
   83.33 -        /* pick up missed timer tick */
   83.34          missed_ticks(vpit);
   83.35 -    
   83.36 -        vpit->scheduled += vpit->period;
   83.37          set_timer(&vpit->pit_timer, vpit->scheduled);
   83.38      }
   83.39  }
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/xen/arch/x86/hvm/svm/Makefile	Mon Mar 20 09:56:54 2006 +0100
    84.3 @@ -0,0 +1,12 @@
    84.4 +include $(BASEDIR)/Rules.mk
    84.5 +
    84.6 +subdirs-$(x86_32) += x86_32
    84.7 +subdirs-$(x86_64) += x86_64
    84.8 +
    84.9 +obj-y += emulate.o
   84.10 +obj-y += instrlen.o
   84.11 +obj-y += intr.o
   84.12 +obj-y += svm.o
   84.13 +obj-y += vmcb.o
   84.14 +
   84.15 +include $(BASEDIR)/Post.mk
    85.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Mar 20 09:56:46 2006 +0100
    85.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Mar 20 09:56:54 2006 +0100
    85.3 @@ -200,7 +200,8 @@ int svm_initialize_guest_resources(struc
    85.4      return 1;
    85.5  }
    85.6  
    85.7 -void svm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
    85.8 +static void svm_store_cpu_guest_regs(
    85.9 +    struct vcpu *v, struct cpu_user_regs *regs)
   85.10  {
   85.11      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   85.12  
   85.13 @@ -227,24 +228,12 @@ void svm_store_cpu_guest_regs(struct vcp
   85.14  #endif
   85.15  }
   85.16  
   85.17 -void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
   85.18 +static void svm_load_cpu_guest_regs(
   85.19 +    struct vcpu *v, struct cpu_user_regs *regs)
   85.20  {
   85.21      svm_load_cpu_user_regs(v, regs);
   85.22  }
   85.23  
   85.24 -#ifdef __x86_64__
   85.25 -
   85.26 -void svm_save_segments(struct vcpu *v)
   85.27 -{
   85.28 -}
   85.29 -void svm_load_msrs(void)
   85.30 -{
   85.31 -}
   85.32 -void svm_restore_msrs(struct vcpu *v)
   85.33 -{
   85.34 -}
   85.35 -#endif
   85.36 -
   85.37  #define IS_CANO_ADDRESS(add) 1
   85.38  
   85.39  static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
   85.40 @@ -459,12 +448,6 @@ int start_svm(void)
   85.41      hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
   85.42      hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
   85.43  
   85.44 -#ifdef __x86_64__
   85.45 -    hvm_funcs.save_segments = svm_save_segments;
   85.46 -    hvm_funcs.load_msrs = svm_load_msrs;
   85.47 -    hvm_funcs.restore_msrs = svm_restore_msrs;
   85.48 -#endif
   85.49 -
   85.50      hvm_funcs.store_cpu_guest_ctrl_regs = svm_store_cpu_guest_ctrl_regs;
   85.51      hvm_funcs.modify_guest_state = svm_modify_guest_state;
   85.52  
   85.53 @@ -687,9 +670,19 @@ static void arch_svm_do_launch(struct vc
   85.54      reset_stack_and_jump(svm_asm_do_launch);
   85.55  }
   85.56  
   85.57 +static void svm_ctxt_switch_from(struct vcpu *v)
   85.58 +{
   85.59 +}
   85.60 +
   85.61 +static void svm_ctxt_switch_to(struct vcpu *v)
   85.62 +{
   85.63 +}
   85.64 +
   85.65  void svm_final_setup_guest(struct vcpu *v)
   85.66  {
   85.67 -    v->arch.schedule_tail = arch_svm_do_launch;
   85.68 +    v->arch.schedule_tail    = arch_svm_do_launch;
   85.69 +    v->arch.ctxt_switch_from = svm_ctxt_switch_from;
   85.70 +    v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
   85.71  
   85.72      if (v == v->domain->vcpu[0]) 
   85.73      {
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/xen/arch/x86/hvm/svm/x86_32/Makefile	Mon Mar 20 09:56:54 2006 +0100
    86.3 @@ -0,0 +1,5 @@
    86.4 +include $(BASEDIR)/Rules.mk
    86.5 +
    86.6 +obj-y += exits.o
    86.7 +
    86.8 +include $(BASEDIR)/Post.mk
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/xen/arch/x86/hvm/svm/x86_64/Makefile	Mon Mar 20 09:56:54 2006 +0100
    87.3 @@ -0,0 +1,5 @@
    87.4 +include $(BASEDIR)/Rules.mk
    87.5 +
    87.6 +obj-y += exits.o
    87.7 +
    87.8 +include $(BASEDIR)/Post.mk
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/xen/arch/x86/hvm/vmx/Makefile	Mon Mar 20 09:56:54 2006 +0100
    88.3 @@ -0,0 +1,10 @@
    88.4 +include $(BASEDIR)/Rules.mk
    88.5 +
    88.6 +subdirs-$(x86_32) += x86_32
    88.7 +subdirs-$(x86_64) += x86_64
    88.8 +
    88.9 +obj-y += io.o
   88.10 +obj-y += vmcs.o
   88.11 +obj-y += vmx.o
   88.12 +
   88.13 +include $(BASEDIR)/Post.mk
    89.1 --- a/xen/arch/x86/hvm/vmx/io.c	Mon Mar 20 09:56:46 2006 +0100
    89.2 +++ b/xen/arch/x86/hvm/vmx/io.c	Mon Mar 20 09:56:54 2006 +0100
    89.3 @@ -40,20 +40,33 @@
    89.4  
    89.5  #define BSP_CPU(v)    (!(v->vcpu_id))
    89.6  
    89.7 -void vmx_set_tsc_shift(struct vcpu *v, struct hvm_virpit *vpit)
    89.8 +static inline 
    89.9 +void __set_tsc_offset(u64  offset)
   89.10  {
   89.11 -    u64   drift;
   89.12 +    __vmwrite(TSC_OFFSET, offset);
   89.13 +#if defined (__i386__)
   89.14 +    __vmwrite(TSC_OFFSET_HIGH, offset >> 32);
   89.15 +#endif
   89.16 +}
   89.17  
   89.18 -    if ( vpit->first_injected )
   89.19 -        drift = vpit->period_cycles * vpit->pending_intr_nr;
   89.20 -    else 
   89.21 -        drift = 0;
   89.22 -    vpit->shift = v->arch.hvm_vmx.tsc_offset - drift;
   89.23 -    __vmwrite(TSC_OFFSET, vpit->shift);
   89.24 +u64 get_guest_time(struct vcpu *v)
   89.25 +{
   89.26 +    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
   89.27 +    u64    host_tsc;
   89.28 +    
   89.29 +    rdtscll(host_tsc);
   89.30 +    return host_tsc + vpit->cache_tsc_offset;
   89.31 +}
   89.32  
   89.33 -#if defined (__i386__)
   89.34 -    __vmwrite(TSC_OFFSET_HIGH, ((vpit->shift)>> 32));
   89.35 -#endif
   89.36 +void set_guest_time(struct vcpu *v, u64 gtime)
   89.37 +{
   89.38 +    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
   89.39 +    u64    host_tsc;
   89.40 +   
   89.41 +    rdtscll(host_tsc);
   89.42 +    
   89.43 +    vpit->cache_tsc_offset = gtime - host_tsc;
   89.44 +    __set_tsc_offset(vpit->cache_tsc_offset);
   89.45  }
   89.46  
   89.47  static inline void
   89.48 @@ -64,6 +77,7 @@ interrupt_post_injection(struct vcpu * v
   89.49      if ( is_pit_irq(v, vector, type) ) {
   89.50          if ( !vpit->first_injected ) {
   89.51              vpit->pending_intr_nr = 0;
   89.52 +            vpit->last_pit_gtime = get_guest_time(v);
   89.53              vpit->scheduled = NOW() + vpit->period;
   89.54              set_timer(&vpit->pit_timer, vpit->scheduled);
   89.55              vpit->first_injected = 1;
   89.56 @@ -71,7 +85,9 @@ interrupt_post_injection(struct vcpu * v
   89.57              vpit->pending_intr_nr--;
   89.58          }
   89.59          vpit->inject_point = NOW();
   89.60 -        vmx_set_tsc_shift (v, vpit);
   89.61 +
   89.62 +        vpit->last_pit_gtime += vpit->period;
   89.63 +        set_guest_time(v, vpit->last_pit_gtime);
   89.64      }
   89.65  
   89.66      switch(type)
   89.67 @@ -189,15 +205,16 @@ void vmx_do_resume(struct vcpu *v)
   89.68  
   89.69      vmx_stts();
   89.70  
   89.71 +    /* pick up the elapsed PIT ticks and re-enable pit_timer */
   89.72 +    if ( vpit->first_injected) {
   89.73 +        set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
   89.74 +        pickup_deactive_ticks(vpit);
   89.75 +    }
   89.76 +
   89.77      if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
   89.78           test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
   89.79          hvm_wait_io();
   89.80  
   89.81 -    /* pick up the elapsed PIT ticks and re-enable pit_timer */
   89.82 -    if ( vpit->first_injected )
   89.83 -        pickup_deactive_ticks(vpit);
   89.84 -    vmx_set_tsc_shift(v, vpit);
   89.85 -
   89.86      /* We can't resume the guest if we're waiting on I/O */
   89.87      ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
   89.88  }
    90.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Mon Mar 20 09:56:46 2006 +0100
    90.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Mon Mar 20 09:56:54 2006 +0100
    90.3 @@ -195,7 +195,6 @@ static void vmx_do_launch(struct vcpu *v
    90.4  /* Update CR3, GDT, LDT, TR */
    90.5      unsigned int  error = 0;
    90.6      unsigned long cr0, cr4;
    90.7 -    u64     host_tsc;
    90.8  
    90.9      if (v->vcpu_id == 0)
   90.10          hvm_setup_platform(v->domain);
   90.11 @@ -250,9 +249,7 @@ static void vmx_do_launch(struct vcpu *v
   90.12      v->arch.hvm_vmx.launch_cpu = smp_processor_id();
   90.13  
   90.14      /* init guest tsc to start from 0 */
   90.15 -    rdtscll(host_tsc);
   90.16 -    v->arch.hvm_vmx.tsc_offset = 0 - host_tsc;
   90.17 -    vmx_set_tsc_shift(v, &v->domain->arch.hvm_domain.vpit);
   90.18 +    set_guest_time(v, 0);
   90.19  }
   90.20  
   90.21  /*
    91.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Mar 20 09:56:46 2006 +0100
    91.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Mar 20 09:56:54 2006 +0100
    91.3 @@ -50,9 +50,14 @@
    91.4  static unsigned long trace_values[NR_CPUS][4];
    91.5  #define TRACE_VMEXIT(index,value) trace_values[smp_processor_id()][index]=value
    91.6  
    91.7 +static void vmx_ctxt_switch_from(struct vcpu *v);
    91.8 +static void vmx_ctxt_switch_to(struct vcpu *v);
    91.9 +
   91.10  void vmx_final_setup_guest(struct vcpu *v)
   91.11  {
   91.12 -    v->arch.schedule_tail = arch_vmx_do_launch;
   91.13 +    v->arch.schedule_tail    = arch_vmx_do_launch;
   91.14 +    v->arch.ctxt_switch_from = vmx_ctxt_switch_from;
   91.15 +    v->arch.ctxt_switch_to   = vmx_ctxt_switch_to;
   91.16  
   91.17      if ( v->vcpu_id == 0 )
   91.18      {
   91.19 @@ -105,6 +110,7 @@ static void vmx_relinquish_guest_resourc
   91.20  }
   91.21  
   91.22  #ifdef __x86_64__
   91.23 +
   91.24  static struct vmx_msr_state percpu_msr[NR_CPUS];
   91.25  
   91.26  static u32 msr_data_index[VMX_MSR_COUNT] =
   91.27 @@ -113,7 +119,7 @@ static u32 msr_data_index[VMX_MSR_COUNT]
   91.28      MSR_SYSCALL_MASK, MSR_EFER,
   91.29  };
   91.30  
   91.31 -void vmx_save_segments(struct vcpu *v)
   91.32 +static void vmx_save_segments(struct vcpu *v)
   91.33  {
   91.34      rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.msr_content.shadow_gs);
   91.35  }
   91.36 @@ -124,7 +130,7 @@ void vmx_save_segments(struct vcpu *v)
   91.37   * are not modified once set for generic domains, we don't save them,
   91.38   * but simply reset them to the values set at percpu_traps_init().
   91.39   */
   91.40 -void vmx_load_msrs(void)
   91.41 +static void vmx_load_msrs(void)
   91.42  {
   91.43      struct vmx_msr_state *host_state = &percpu_msr[smp_processor_id()];
   91.44      int i;
   91.45 @@ -166,118 +172,143 @@ static void vmx_save_init_msrs(void)
   91.46  #define IS_CANO_ADDRESS(add) 1
   91.47  static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
   91.48  {
   91.49 -    u64     msr_content = 0;
   91.50 -    struct vcpu *vc = current;
   91.51 -    struct vmx_msr_state * msr = &vc->arch.hvm_vmx.msr_content;
   91.52 -    switch(regs->ecx){
   91.53 +    u64 msr_content = 0;
   91.54 +    struct vcpu *v = current;
   91.55 +    struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content;
   91.56 +
   91.57 +    switch ( regs->ecx ) {
   91.58      case MSR_EFER:
   91.59 +        HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content 0x%"PRIx64, msr_content);
   91.60          msr_content = msr->msr_items[VMX_INDEX_MSR_EFER];
   91.61 -        HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content %"PRIx64"\n", msr_content);
   91.62 -        if (test_bit(VMX_CPU_STATE_LME_ENABLED,
   91.63 -                     &vc->arch.hvm_vmx.cpu_state))
   91.64 -            msr_content |= 1 << _EFER_LME;
   91.65  
   91.66 -        if (VMX_LONG_GUEST(vc))
   91.67 -            msr_content |= 1 << _EFER_LMA;
   91.68 +        /* the following code may be not needed */
   91.69 +        if ( test_bit(VMX_CPU_STATE_LME_ENABLED, &v->arch.hvm_vmx.cpu_state) )
   91.70 +            msr_content |= EFER_LME;
   91.71 +        else
   91.72 +            msr_content &= ~EFER_LME;
   91.73 +
   91.74 +        if ( VMX_LONG_GUEST(v) )
   91.75 +            msr_content |= EFER_LMA;
   91.76 +        else
   91.77 +            msr_content &= ~EFER_LMA;
   91.78          break;
   91.79 +
   91.80      case MSR_FS_BASE:
   91.81 -        if (!(VMX_LONG_GUEST(vc)))
   91.82 +        if ( !(VMX_LONG_GUEST(v)) )
   91.83              /* XXX should it be GP fault */
   91.84              domain_crash_synchronous();
   91.85 +
   91.86          __vmread(GUEST_FS_BASE, &msr_content);
   91.87          break;
   91.88 +
   91.89      case MSR_GS_BASE:
   91.90 -        if (!(VMX_LONG_GUEST(vc)))
   91.91 +        if ( !(VMX_LONG_GUEST(v)) )
   91.92              domain_crash_synchronous();
   91.93 +
   91.94          __vmread(GUEST_GS_BASE, &msr_content);
   91.95          break;
   91.96 +
   91.97      case MSR_SHADOW_GS_BASE:
   91.98          msr_content = msr->shadow_gs;
   91.99          break;
  91.100  
  91.101 -        CASE_READ_MSR(STAR);
  91.102 -        CASE_READ_MSR(LSTAR);
  91.103 -        CASE_READ_MSR(CSTAR);
  91.104 -        CASE_READ_MSR(SYSCALL_MASK);
  91.105 +    CASE_READ_MSR(STAR);
  91.106 +    CASE_READ_MSR(LSTAR);
  91.107 +    CASE_READ_MSR(CSTAR);
  91.108 +    CASE_READ_MSR(SYSCALL_MASK);
  91.109 +
  91.110      default:
  91.111          return 0;
  91.112      }
  91.113 -    HVM_DBG_LOG(DBG_LEVEL_2, "mode_do_msr_read: msr_content: %"PRIx64"\n",
  91.114 -                msr_content);
  91.115 +
  91.116 +    HVM_DBG_LOG(DBG_LEVEL_2, "msr_content: 0x%"PRIx64, msr_content);
  91.117 +
  91.118      regs->eax = msr_content & 0xffffffff;
  91.119      regs->edx = msr_content >> 32;
  91.120 +
  91.121      return 1;
  91.122  }
  91.123  
  91.124  static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
  91.125  {
  91.126 -    u64     msr_content = regs->eax | ((u64)regs->edx << 32);
  91.127 -    struct vcpu *vc = current;
  91.128 -    struct vmx_msr_state * msr = &vc->arch.hvm_vmx.msr_content;
  91.129 -    struct vmx_msr_state * host_state =
  91.130 -        &percpu_msr[smp_processor_id()];
  91.131 +    u64 msr_content = regs->eax | ((u64)regs->edx << 32);
  91.132 +    struct vcpu *v = current;
  91.133 +    struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content;
  91.134 +    struct vmx_msr_state *host_state = &percpu_msr[smp_processor_id()];
  91.135  
  91.136 -    HVM_DBG_LOG(DBG_LEVEL_1, " mode_do_msr_write msr %lx "
  91.137 -                "msr_content %"PRIx64"\n",
  91.138 +    HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%lx msr_content 0x%"PRIx64"\n",
  91.139                  (unsigned long)regs->ecx, msr_content);
  91.140  
  91.141 -    switch (regs->ecx){
  91.142 +    switch ( regs->ecx ) {
  91.143      case MSR_EFER:
  91.144          /* offending reserved bit will cause #GP */
  91.145 -        if ( msr_content &
  91.146 -                ~( EFER_LME | EFER_LMA | EFER_NX | EFER_SCE ) )
  91.147 -             vmx_inject_exception(vc, TRAP_gp_fault, 0);
  91.148 +        if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
  91.149 +        {
  91.150 +            printk("trying to set reserved bit in EFER\n");
  91.151 +            vmx_inject_exception(v, TRAP_gp_fault, 0);
  91.152 +            return 0;
  91.153 +        }
  91.154  
  91.155 -        if ((msr_content & EFER_LME) ^
  91.156 -            test_bit(VMX_CPU_STATE_LME_ENABLED,
  91.157 -                     &vc->arch.hvm_vmx.cpu_state)){
  91.158 -            if ( vmx_paging_enabled(vc) ||
  91.159 +        /* LME: 0 -> 1 */
  91.160 +        if ( msr_content & EFER_LME &&
  91.161 +             !test_bit(VMX_CPU_STATE_LME_ENABLED, &v->arch.hvm_vmx.cpu_state) )
  91.162 +        {
  91.163 +            if ( vmx_paging_enabled(v) ||
  91.164                   !test_bit(VMX_CPU_STATE_PAE_ENABLED,
  91.165 -                           &vc->arch.hvm_vmx.cpu_state)) {
  91.166 -                vmx_inject_exception(vc, TRAP_gp_fault, 0);
  91.167 +                           &v->arch.hvm_vmx.cpu_state) )
  91.168 +            {
  91.169 +                printk("trying to set LME bit when "
  91.170 +                       "in paging mode or PAE bit is not set\n");
  91.171 +                vmx_inject_exception(v, TRAP_gp_fault, 0);
  91.172 +                return 0;
  91.173              }
  91.174 +
  91.175 +            set_bit(VMX_CPU_STATE_LME_ENABLED, &v->arch.hvm_vmx.cpu_state);
  91.176          }
  91.177 -        if (msr_content & EFER_LME)
  91.178 -            set_bit(VMX_CPU_STATE_LME_ENABLED,
  91.179 -                    &vc->arch.hvm_vmx.cpu_state);
  91.180  
  91.181 -        msr->msr_items[VMX_INDEX_MSR_EFER] =
  91.182 -            msr_content;
  91.183 +        msr->msr_items[VMX_INDEX_MSR_EFER] = msr_content;
  91.184          break;
  91.185  
  91.186      case MSR_FS_BASE:
  91.187      case MSR_GS_BASE:
  91.188 -        if (!(VMX_LONG_GUEST(vc)))
  91.189 +        if ( !(VMX_LONG_GUEST(v)) )
  91.190              domain_crash_synchronous();
  91.191 -        if (!IS_CANO_ADDRESS(msr_content)){
  91.192 +
  91.193 +        if ( !IS_CANO_ADDRESS(msr_content) )
  91.194 +        {
  91.195              HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
  91.196 -            vmx_inject_exception(vc, TRAP_gp_fault, 0);
  91.197 +            vmx_inject_exception(v, TRAP_gp_fault, 0);
  91.198 +            return 0;
  91.199          }
  91.200 -        if (regs->ecx == MSR_FS_BASE)
  91.201 +
  91.202 +        if ( regs->ecx == MSR_FS_BASE )
  91.203              __vmwrite(GUEST_FS_BASE, msr_content);
  91.204          else
  91.205              __vmwrite(GUEST_GS_BASE, msr_content);
  91.206 +
  91.207          break;
  91.208  
  91.209      case MSR_SHADOW_GS_BASE:
  91.210 -        if (!(VMX_LONG_GUEST(vc)))
  91.211 +        if ( !(VMX_LONG_GUEST(v)) )
  91.212              domain_crash_synchronous();
  91.213 -        vc->arch.hvm_vmx.msr_content.shadow_gs = msr_content;
  91.214 +
  91.215 +        v->arch.hvm_vmx.msr_content.shadow_gs = msr_content;
  91.216          wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
  91.217          break;
  91.218  
  91.219 -        CASE_WRITE_MSR(STAR);
  91.220 -        CASE_WRITE_MSR(LSTAR);
  91.221 -        CASE_WRITE_MSR(CSTAR);
  91.222 -        CASE_WRITE_MSR(SYSCALL_MASK);
  91.223 +    CASE_WRITE_MSR(STAR);
  91.224 +    CASE_WRITE_MSR(LSTAR);
  91.225 +    CASE_WRITE_MSR(CSTAR);
  91.226 +    CASE_WRITE_MSR(SYSCALL_MASK);
  91.227 +
  91.228      default:
  91.229          return 0;
  91.230      }
  91.231 +
  91.232      return 1;
  91.233  }
  91.234  
  91.235 -void
  91.236 -vmx_restore_msrs(struct vcpu *v)
  91.237 +static void vmx_restore_msrs(struct vcpu *v)
  91.238  {
  91.239      int i = 0;
  91.240      struct vmx_msr_state *guest_state;
  91.241 @@ -297,22 +328,52 @@ vmx_restore_msrs(struct vcpu *v)
  91.242  
  91.243          HVM_DBG_LOG(DBG_LEVEL_2,
  91.244                      "restore guest's index %d msr %lx with %lx\n",
  91.245 -                    i, (unsigned long) msr_data_index[i], (unsigned long) guest_state->msr_items[i]);
  91.246 +                    i, (unsigned long)msr_data_index[i],
  91.247 +                    (unsigned long)guest_state->msr_items[i]);
  91.248          set_bit(i, &host_state->flags);
  91.249          wrmsrl(msr_data_index[i], guest_state->msr_items[i]);
  91.250          clear_bit(i, &guest_flags);
  91.251      }
  91.252  }
  91.253  #else  /* __i386__ */
  91.254 -#define  vmx_save_init_msrs()   ((void)0)
  91.255  
  91.256 -static inline int  long_mode_do_msr_read(struct cpu_user_regs *regs){
  91.257 +#define vmx_save_segments(v)      ((void)0)
  91.258 +#define vmx_load_msrs()           ((void)0)
  91.259 +#define vmx_restore_msrs(v)       ((void)0)
  91.260 +#define vmx_save_init_msrs()      ((void)0)
  91.261 +
  91.262 +static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
  91.263 +{
  91.264      return 0;
  91.265  }
  91.266 -static inline int  long_mode_do_msr_write(struct cpu_user_regs *regs){
  91.267 +
  91.268 +static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
  91.269 +{
  91.270      return 0;
  91.271  }
  91.272 -#endif
  91.273 +
  91.274 +#endif /* __i386__ */
  91.275 +
  91.276 +static void vmx_freeze_time(struct vcpu *v)
  91.277 +{
  91.278 +    struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
  91.279 +    
  91.280 +    v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
  91.281 +    if ( vpit->first_injected )
  91.282 +        stop_timer(&(vpit->pit_timer));
  91.283 +}
  91.284 +
  91.285 +static void vmx_ctxt_switch_from(struct vcpu *v)
  91.286 +{
  91.287 +    vmx_freeze_time(v);
  91.288 +    vmx_save_segments(v);
  91.289 +    vmx_load_msrs();
  91.290 +}
  91.291 +
  91.292 +static void vmx_ctxt_switch_to(struct vcpu *v)
  91.293 +{
  91.294 +    vmx_restore_msrs(v);
  91.295 +}
  91.296  
  91.297  void stop_vmx(void)
  91.298  {
  91.299 @@ -554,12 +615,6 @@ int start_vmx(void)
  91.300      hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
  91.301      hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
  91.302  
  91.303 -#ifdef __x86_64__
  91.304 -    hvm_funcs.save_segments = vmx_save_segments;
  91.305 -    hvm_funcs.load_msrs = vmx_load_msrs;
  91.306 -    hvm_funcs.restore_msrs = vmx_restore_msrs;
  91.307 -#endif
  91.308 -
  91.309      hvm_funcs.store_cpu_guest_ctrl_regs = vmx_store_cpu_guest_ctrl_regs;
  91.310      hvm_funcs.modify_guest_state = vmx_modify_guest_state;
  91.311  
  91.312 @@ -670,27 +725,31 @@ static void vmx_do_no_device_fault(void)
  91.313  /* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */
  91.314  #define VMX_VCPU_CPUID_L1_RESERVED 0xffff9a46
  91.315  
  91.316 -static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs)
  91.317 +static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs)
  91.318  {
  91.319 +    unsigned int input = (unsigned int)regs->eax;
  91.320 +    unsigned int count = (unsigned int)regs->ecx;
  91.321      unsigned int eax, ebx, ecx, edx;
  91.322      unsigned long eip;
  91.323      struct vcpu *v = current;
  91.324  
  91.325      __vmread(GUEST_RIP, &eip);
  91.326  
  91.327 -    HVM_DBG_LOG(DBG_LEVEL_1,
  91.328 -                "do_cpuid: (eax) %lx, (ebx) %lx, (ecx) %lx, (edx) %lx,"
  91.329 -                " (esi) %lx, (edi) %lx",
  91.330 +    HVM_DBG_LOG(DBG_LEVEL_3, "(eax) 0x%08lx, (ebx) 0x%08lx, "
  91.331 +                "(ecx) 0x%08lx, (edx) 0x%08lx, (esi) 0x%08lx, (edi) 0x%08lx",
  91.332                  (unsigned long)regs->eax, (unsigned long)regs->ebx,
  91.333                  (unsigned long)regs->ecx, (unsigned long)regs->edx,
  91.334                  (unsigned long)regs->esi, (unsigned long)regs->edi);
  91.335  
  91.336 -    cpuid(input, &eax, &ebx, &ecx, &edx);
  91.337 +    if ( input == 4 )
  91.338 +        cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
  91.339 +    else
  91.340 +        cpuid(input, &eax, &ebx, &ecx, &edx);
  91.341  
  91.342      if ( input == 1 )
  91.343      {
  91.344          if ( hvm_apic_support(v->domain) &&
  91.345 -                !vlapic_global_enabled((VLAPIC(v))) )
  91.346 +             !vlapic_global_enabled((VLAPIC(v))) )
  91.347              clear_bit(X86_FEATURE_APIC, &edx);
  91.348  
  91.349  #if CONFIG_PAGING_LEVELS < 3
  91.350 @@ -725,10 +784,12 @@ static void vmx_vmexit_do_cpuid(unsigned
  91.351      regs->ecx = (unsigned long) ecx;
  91.352      regs->edx = (unsigned long) edx;
  91.353  
  91.354 -    HVM_DBG_LOG(DBG_LEVEL_1,
  91.355 -                "vmx_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x, ebx=%x, ecx=%x, edx=%x",
  91.356 -                eip, input, eax, ebx, ecx, edx);
  91.357 -
  91.358 +    HVM_DBG_LOG(DBG_LEVEL_3, "eip@%lx, input: 0x%lx, "
  91.359 +                "output: eax = 0x%08lx, ebx = 0x%08lx, "
  91.360 +                "ecx = 0x%08lx, edx = 0x%08lx",
  91.361 +                (unsigned long)eip, (unsigned long)input,
  91.362 +                (unsigned long)eax, (unsigned long)ebx,
  91.363 +                (unsigned long)ecx, (unsigned long)edx);
  91.364  }
  91.365  
  91.366  #define CASE_GET_REG_P(REG, reg)    \
  91.367 @@ -1656,7 +1717,7 @@ static inline void vmx_do_msr_read(struc
  91.368  
  91.369          rdtscll(msr_content);
  91.370          vpit = &(v->domain->arch.hvm_domain.vpit);
  91.371 -        msr_content += vpit->shift;
  91.372 +        msr_content += vpit->cache_tsc_offset;
  91.373          break;
  91.374      }
  91.375      case MSR_IA32_SYSENTER_CS:
  91.376 @@ -1700,22 +1761,8 @@ static inline void vmx_do_msr_write(stru
  91.377  
  91.378      switch (regs->ecx) {
  91.379      case MSR_IA32_TIME_STAMP_COUNTER:
  91.380 -    {
  91.381 -        struct hvm_virpit *vpit;
  91.382 -        u64 host_tsc, drift;
  91.383 -
  91.384 -        rdtscll(host_tsc);
  91.385 -        vpit = &(v->domain->arch.hvm_domain.vpit);
  91.386 -        drift = v->arch.hvm_vmx.tsc_offset - vpit->shift;
  91.387 -        vpit->shift = msr_content - host_tsc;
  91.388 -	v->arch.hvm_vmx.tsc_offset = vpit->shift + drift;
  91.389 -        __vmwrite(TSC_OFFSET, vpit->shift);
  91.390 -
  91.391 -#if defined (__i386__)
  91.392 -        __vmwrite(TSC_OFFSET_HIGH, ((vpit->shift)>>32));
  91.393 -#endif
  91.394 +        set_guest_time(v, msr_content);
  91.395          break;
  91.396 -    }
  91.397      case MSR_IA32_SYSENTER_CS:
  91.398          __vmwrite(GUEST_SYSENTER_CS, msr_content);
  91.399          break;
  91.400 @@ -2014,8 +2061,8 @@ asmlinkage void vmx_vmexit_handler(struc
  91.401          __hvm_bug(&regs);
  91.402          break;
  91.403      case EXIT_REASON_CPUID:
  91.404 +        vmx_vmexit_do_cpuid(&regs);
  91.405          __get_instruction_length(inst_len);
  91.406 -        vmx_vmexit_do_cpuid(regs.eax, &regs);
  91.407          __update_guest_eip(inst_len);
  91.408          break;
  91.409      case EXIT_REASON_HLT:
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/Makefile	Mon Mar 20 09:56:54 2006 +0100
    92.3 @@ -0,0 +1,5 @@
    92.4 +include $(BASEDIR)/Rules.mk
    92.5 +
    92.6 +obj-y += exits.o
    92.7 +
    92.8 +include $(BASEDIR)/Post.mk
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/Makefile	Mon Mar 20 09:56:54 2006 +0100
    93.3 @@ -0,0 +1,5 @@
    93.4 +include $(BASEDIR)/Rules.mk
    93.5 +
    93.6 +obj-y += exits.o
    93.7 +
    93.8 +include $(BASEDIR)/Post.mk
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/xen/arch/x86/x86_32/Makefile	Mon Mar 20 09:56:54 2006 +0100
    94.3 @@ -0,0 +1,11 @@
    94.4 +include $(BASEDIR)/Rules.mk
    94.5 +
    94.6 +obj-y += domain_page.o
    94.7 +obj-y += entry.o
    94.8 +obj-y += mm.o
    94.9 +obj-y += seg_fixup.o
   94.10 +obj-y += traps.o
   94.11 +
   94.12 +obj-$(supervisor_mode_kernel) += supervisor_mode_kernel.o
   94.13 +
   94.14 +include $(BASEDIR)/Post.mk
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/xen/arch/x86/x86_64/Makefile	Mon Mar 20 09:56:54 2006 +0100
    95.3 @@ -0,0 +1,7 @@
    95.4 +include $(BASEDIR)/Rules.mk
    95.5 +
    95.6 +obj-y += entry.o
    95.7 +obj-y += mm.o
    95.8 +obj-y += traps.o
    95.9 +
   95.10 +include $(BASEDIR)/Post.mk
    96.1 --- a/xen/common/Makefile	Mon Mar 20 09:56:46 2006 +0100
    96.2 +++ b/xen/common/Makefile	Mon Mar 20 09:56:54 2006 +0100
    96.3 @@ -1,19 +1,34 @@
    96.4 -
    96.5  include $(BASEDIR)/Rules.mk
    96.6  
    96.7 -ifneq ($(perfc),y)
    96.8 -OBJS := $(subst perfc.o,,$(OBJS))
    96.9 -endif
   96.10 -ifneq ($(crash_debug),y)
   96.11 -OBJS := $(patsubst gdbstub.o,,$(OBJS))
   96.12 -endif
   96.13 +obj-y += acm_ops.o
   96.14 +obj-y += bitmap.o
   96.15 +obj-y += dom0_ops.o
   96.16 +obj-y += domain.o
   96.17 +obj-y += elf.o
   96.18 +obj-y += event_channel.o
   96.19 +obj-y += grant_table.o
   96.20 +obj-y += kernel.o
   96.21 +obj-y += keyhandler.o
   96.22 +obj-y += lib.o
   96.23 +obj-y += memory.o
   96.24 +obj-y += multicall.o
   96.25 +obj-y += page_alloc.o
   96.26 +obj-y += rangeset.o
   96.27 +obj-y += sched_bvt.o
   96.28 +obj-y += sched_sedf.o
   96.29 +obj-y += schedule.o
   96.30 +obj-y += softirq.o
   96.31 +obj-y += string.o
   96.32 +obj-y += symbols.o
   96.33 +obj-y += trace.o
   96.34 +obj-y += timer.o
   96.35 +obj-y += vsprintf.o
   96.36 +obj-y += xmalloc.o
   96.37  
   96.38 -default: common.o
   96.39 -common.o: $(OBJS)
   96.40 -	$(LD) $(LDFLAGS) -r -o common.o $(OBJS)
   96.41 +obj-$(perfc)       += perfc.o
   96.42 +obj-$(crash_debug) += gdbstub.o
   96.43  
   96.44 -clean:
   96.45 -	rm -f *.o *~ core
   96.46 +include $(BASEDIR)/Post.mk
   96.47  
   96.48  # Object file contains changeset and compiler information.
   96.49  kernel.o: $(BASEDIR)/include/xen/compile.h
    97.1 --- a/xen/drivers/Makefile	Mon Mar 20 09:56:46 2006 +0100
    97.2 +++ b/xen/drivers/Makefile	Mon Mar 20 09:56:54 2006 +0100
    97.3 @@ -1,8 +1,6 @@
    97.4 +include $(BASEDIR)/Rules.mk
    97.5  
    97.6 -default:
    97.7 -	$(MAKE) -C char
    97.8 -	$(MAKE) -C acpi
    97.9 +subdirs-y := char/
   97.10 +subdirs-$(HAS_ACPI) += acpi/
   97.11  
   97.12 -clean:
   97.13 -	$(MAKE) -C char clean
   97.14 -	$(MAKE) -C acpi clean
   97.15 +include $(BASEDIR)/Post.mk
    98.1 --- a/xen/drivers/acpi/Makefile	Mon Mar 20 09:56:46 2006 +0100
    98.2 +++ b/xen/drivers/acpi/Makefile	Mon Mar 20 09:56:54 2006 +0100
    98.3 @@ -1,11 +1,5 @@
    98.4 -
    98.5  include $(BASEDIR)/Rules.mk
    98.6  
    98.7 -OBJS := tables.o
    98.8 +obj-y += tables.o
    98.9  
   98.10 -default: driver.o
   98.11 -driver.o: $(OBJS)
   98.12 -	$(LD) $(LDFLAGS) -r -o driver.o $(OBJS)
   98.13 -
   98.14 -clean:
   98.15 -	rm -f *.o *~ core
   98.16 +include $(BASEDIR)/Post.mk
    99.1 --- a/xen/drivers/char/Makefile	Mon Mar 20 09:56:46 2006 +0100
    99.2 +++ b/xen/drivers/char/Makefile	Mon Mar 20 09:56:54 2006 +0100
    99.3 @@ -1,12 +1,10 @@
    99.4 -
    99.5  include $(BASEDIR)/Rules.mk
    99.6  
    99.7 -default: driver.o
    99.8 -driver.o: $(OBJS)
    99.9 -	$(LD) $(LDFLAGS) -r -o driver.o $(OBJS)
   99.10 +obj-y += console.o
   99.11 +obj-y += ns16550.o
   99.12 +obj-y += serial.o
   99.13  
   99.14 -clean:
   99.15 -	rm -f *.o *~ core
   99.16 +include $(BASEDIR)/Post.mk
   99.17  
   99.18  # Object file contains changeset and compiler information.
   99.19  console.o: $(BASEDIR)/include/xen/compile.h
   100.1 --- a/xen/include/asm-ia64/config.h	Mon Mar 20 09:56:46 2006 +0100
   100.2 +++ b/xen/include/asm-ia64/config.h	Mon Mar 20 09:56:54 2006 +0100
   100.3 @@ -74,7 +74,7 @@ extern unsigned long dom0_start;
   100.4  extern unsigned long dom0_size;
   100.5  
   100.6  // from linux/include/linux/mm.h
   100.7 -extern struct page *mem_map;
   100.8 +extern struct page_info *mem_map;
   100.9  
  100.10  // xen/include/asm/config.h
  100.11  extern char _end[]; /* standard ELF symbol */
  100.12 @@ -134,9 +134,6 @@ extern int smp_num_siblings;
  100.13  #define smp_num_siblings 1
  100.14  #endif
  100.15  
  100.16 -// from linux/include/linux/mm.h
  100.17 -struct page;
  100.18 -
  100.19  // function calls; see decl in xen/include/xen/sched.h
  100.20  #undef free_task_struct
  100.21  #undef alloc_task_struct
  100.22 @@ -206,8 +203,6 @@ void sort_main_extable(void);
  100.23  #define _atomic_read(v) ((v).counter)
  100.24  #define atomic_compareandswap(old, new, v) ((atomic_t){ cmpxchg(v, _atomic_read(old), _atomic_read(new)) })
  100.25  
  100.26 -// see include/asm-ia64/mm.h, handle remaining page_info uses until gone
  100.27 -#define page_info page
  100.28  // Deprivated linux inf and put here for short time compatibility
  100.29  #define kmalloc(s, t) xmalloc_bytes((s))
  100.30  #define kfree(s) xfree((s))
  100.31 @@ -249,7 +244,7 @@ extern unsigned long loops_per_jiffy;
  100.32  extern char saved_command_line[];
  100.33  struct screen_info { };
  100.34  #define seq_printf(a,b...) printf(b)
  100.35 -#define CONFIG_BLK_DEV_INITRD // needed to reserve memory for domain0
  100.36 +//#define CONFIG_BLK_DEV_INITRD // needed to reserve memory for domain0
  100.37  
  100.38  void dummy_called(char *function);
  100.39  #define dummy()	dummy_called((char *) __FUNCTION__)
   101.1 --- a/xen/include/asm-ia64/dom_fw.h	Mon Mar 20 09:56:46 2006 +0100
   101.2 +++ b/xen/include/asm-ia64/dom_fw.h	Mon Mar 20 09:56:54 2006 +0100
   101.3 @@ -119,7 +119,7 @@ extern unsigned long dom_fw_setup(struct
   101.4  #define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_PADDR	FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX)
   101.5  #define FW_HYPERCALL_EFI_RESET_SYSTEM_PADDR		FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX)
   101.6  
   101.7 -extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
   101.8 +extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64);
   101.9  extern struct sal_ret_values sal_emulator (long index, unsigned long in1, unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, unsigned long in6, unsigned long in7);
  101.10  extern struct ia64_pal_retval pal_emulator_static (unsigned long);
  101.11  
   102.1 --- a/xen/include/asm-ia64/domain.h	Mon Mar 20 09:56:46 2006 +0100
   102.2 +++ b/xen/include/asm-ia64/domain.h	Mon Mar 20 09:56:54 2006 +0100
   102.3 @@ -14,7 +14,6 @@
   102.4  extern void domain_relinquish_resources(struct domain *);
   102.5  
   102.6  struct arch_domain {
   102.7 -    struct mm_struct *active_mm;
   102.8      struct mm_struct *mm;
   102.9      unsigned long metaphysical_rr0;
  102.10      unsigned long metaphysical_rr4;
  102.11 @@ -68,7 +67,6 @@ struct arch_vcpu {
  102.12      int breakimm;			// from arch_domain (so is pinned)
  102.13      int starting_rid;		/* first RID assigned to domain */
  102.14      int ending_rid;		/* one beyond highest RID assigned to domain */
  102.15 -    struct mm_struct *active_mm;
  102.16      struct thread_struct _thread;	// this must be last
  102.17  
  102.18      thash_cb_t *vtlb;
  102.19 @@ -81,7 +79,6 @@ struct arch_vcpu {
  102.20      struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
  102.21  };
  102.22  
  102.23 -#define active_mm arch.active_mm
  102.24  //#define thread arch._thread
  102.25  
  102.26  // FOLLOWING FROM linux-2.6.7/include/sched.h
  102.27 @@ -102,6 +99,8 @@ struct mm_struct {
  102.28  #endif
  102.29  	spinlock_t page_table_lock;		/* Protects task page tables and mm->rss */
  102.30  
  102.31 +	struct list_head pt_list;		/* List of pagetable */
  102.32 +
  102.33  	struct list_head mmlist;		/* List of all active mm's.  These are globally strung
  102.34  						 * together off init_mm.mmlist, and are protected
  102.35  						 * by mmlist_lock
   103.1 --- a/xen/include/asm-ia64/flushtlb.h	Mon Mar 20 09:56:46 2006 +0100
   103.2 +++ b/xen/include/asm-ia64/flushtlb.h	Mon Mar 20 09:56:54 2006 +0100
   103.3 @@ -1,6 +1,8 @@
   103.4  #ifndef __FLUSHTLB_H__
   103.5  #define __FLUSHTLB_H__
   103.6  
   103.7 +#include <asm/tlbflush.h>
   103.8 +
   103.9  /* The current time as shown by the virtual TLB clock. */
  103.10  extern u32 tlbflush_clock;
  103.11  
   104.1 --- a/xen/include/asm-ia64/linux-xen/asm/page.h	Mon Mar 20 09:56:46 2006 +0100
   104.2 +++ b/xen/include/asm-ia64/linux-xen/asm/page.h	Mon Mar 20 09:56:54 2006 +0100
   104.3 @@ -75,7 +75,7 @@ do {						\
   104.4  	flush_dcache_page(page);		\
   104.5  } while (0)
   104.6  
   104.7 -
   104.8 +#ifndef XEN
   104.9  #define alloc_zeroed_user_highpage(vma, vaddr) \
  104.10  ({						\
  104.11  	struct page *page = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr); \
  104.12 @@ -83,6 +83,7 @@ do {						\
  104.13   		flush_dcache_page(page);	\
  104.14  	page;					\
  104.15  })
  104.16 +#endif
  104.17  
  104.18  #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
  104.19  
   105.1 --- a/xen/include/asm-ia64/linux-xen/asm/pgalloc.h	Mon Mar 20 09:56:46 2006 +0100
   105.2 +++ b/xen/include/asm-ia64/linux-xen/asm/pgalloc.h	Mon Mar 20 09:56:54 2006 +0100
   105.3 @@ -106,11 +106,13 @@ static inline void pmd_free(pmd_t * pmd)
   105.4  
   105.5  #define __pmd_free_tlb(tlb, pmd)	pmd_free(pmd)
   105.6  
   105.7 +#ifndef XEN
   105.8  static inline void
   105.9  pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, struct page *pte)
  105.10  {
  105.11  	pmd_val(*pmd_entry) = page_to_maddr(pte);
  105.12  }
  105.13 +#endif
  105.14  
  105.15  static inline void
  105.16  pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
  105.17 @@ -118,11 +120,13 @@ pmd_populate_kernel(struct mm_struct *mm
  105.18  	pmd_val(*pmd_entry) = __pa(pte);
  105.19  }
  105.20  
  105.21 +#ifndef XEN
  105.22  static inline struct page *pte_alloc_one(struct mm_struct *mm,
  105.23  					 unsigned long addr)
  105.24  {
  105.25  	return virt_to_page(pgtable_quicklist_alloc());
  105.26  }
  105.27 +#endif
  105.28  
  105.29  static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
  105.30  					  unsigned long addr)
  105.31 @@ -130,6 +134,7 @@ static inline pte_t *pte_alloc_one_kerne
  105.32  	return pgtable_quicklist_alloc();
  105.33  }
  105.34  
  105.35 +#ifndef XEN
  105.36  static inline void pte_free(struct page *pte)
  105.37  {
  105.38  	pgtable_quicklist_free(page_address(pte));
  105.39 @@ -141,6 +146,7 @@ static inline void pte_free_kernel(pte_t
  105.40  }
  105.41  
  105.42  #define __pte_free_tlb(tlb, pte)	pte_free(pte)
  105.43 +#endif
  105.44  
  105.45  extern void check_pgt_cache(void);
  105.46  
   106.1 --- a/xen/include/asm-ia64/linux-xen/asm/pgtable.h	Mon Mar 20 09:56:46 2006 +0100
   106.2 +++ b/xen/include/asm-ia64/linux-xen/asm/pgtable.h	Mon Mar 20 09:56:54 2006 +0100
   106.3 @@ -467,8 +467,10 @@ extern void paging_init (void);
   106.4   * for zero-mapped memory areas etc..
   106.5   */
   106.6  extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
   106.7 +#ifndef XEN
   106.8  extern struct page *zero_page_memmap_ptr;
   106.9  #define ZERO_PAGE(vaddr) (zero_page_memmap_ptr)
  106.10 +#endif
  106.11  
  106.12  /* We provide our own get_unmapped_area to cope with VA holes for userland */
  106.13  #define HAVE_ARCH_UNMAPPED_AREA
   107.1 --- a/xen/include/asm-ia64/linux-xen/asm/system.h	Mon Mar 20 09:56:46 2006 +0100
   107.2 +++ b/xen/include/asm-ia64/linux-xen/asm/system.h	Mon Mar 20 09:56:54 2006 +0100
   107.3 @@ -290,6 +290,9 @@ void cpu_idle_wait(void);
   107.4  
   107.5  #ifdef XEN
   107.6  #include <asm/xensystem.h>
   107.7 +#ifndef __ASSEMBLY__
   107.8 +struct resource;
   107.9 +#endif
  107.10  #endif
  107.11  
  107.12  #endif /* _ASM_IA64_SYSTEM_H */
   108.1 --- a/xen/include/asm-ia64/linux-xen/asm/tlbflush.h	Mon Mar 20 09:56:46 2006 +0100
   108.2 +++ b/xen/include/asm-ia64/linux-xen/asm/tlbflush.h	Mon Mar 20 09:56:54 2006 +0100
   108.3 @@ -80,7 +80,11 @@ flush_tlb_page (struct vm_area_struct *v
   108.4  #ifdef CONFIG_SMP
   108.5  	flush_tlb_range(vma, (addr & PAGE_MASK), (addr & PAGE_MASK) + PAGE_SIZE);
   108.6  #else
   108.7 +#ifdef XEN
   108.8 +	if (vma->vm_mm == current->domain->arch.mm)
   108.9 +#else
  108.10  	if (vma->vm_mm == current->active_mm)
  108.11 +#endif
  108.12  		ia64_ptcl(addr, (PAGE_SHIFT << 2));
  108.13  #ifndef XEN
  108.14  // FIXME SMP?
   109.1 --- a/xen/include/asm-ia64/linux-xen/linux/gfp.h	Mon Mar 20 09:56:46 2006 +0100
   109.2 +++ b/xen/include/asm-ia64/linux-xen/linux/gfp.h	Mon Mar 20 09:56:54 2006 +0100
   109.3 @@ -3,6 +3,7 @@
   109.4  
   109.5  #ifdef XEN
   109.6  #include <asm/bitops.h>
   109.7 +#include <linux/topology.h>
   109.8  #endif
   109.9  #include <linux/mmzone.h>
  109.10  #include <linux/stddef.h>
  109.11 @@ -81,6 +82,7 @@ struct vm_area_struct;
  109.12   * optimized to &contig_page_data at compile-time.
  109.13   */
  109.14  
  109.15 +#ifndef XEN
  109.16  #ifndef HAVE_ARCH_FREE_PAGE
  109.17  static inline void arch_free_page(struct page *page, int order) { }
  109.18  #endif
  109.19 @@ -134,6 +136,7 @@ extern void FASTCALL(free_cold_page(stru
  109.20  
  109.21  #define __free_page(page) __free_pages((page), 0)
  109.22  #define free_page(addr) free_pages((addr),0)
  109.23 +#endif /* XEN */
  109.24  
  109.25  void page_alloc_init(void);
  109.26  #ifdef CONFIG_NUMA
   110.1 --- a/xen/include/asm-ia64/linux/README.origin	Mon Mar 20 09:56:46 2006 +0100
   110.2 +++ b/xen/include/asm-ia64/linux/README.origin	Mon Mar 20 09:56:54 2006 +0100
   110.3 @@ -14,13 +14,10 @@ initrd.h		-> linux/include/linux/initrd.
   110.4  jiffies.h		-> linux/include/linux/jiffies.h
   110.5  kmalloc_sizes.h		-> linux/include/linux/kmalloc_sizes.h
   110.6  linkage.h		-> linux/include/linux/linkage.h
   110.7 -mmzone.h		-> linux/include/linux/mmzone.h
   110.8  notifier.h		-> linux/include/linux/notifier.h
   110.9  numa.h			-> linux/include/linux/numa.h
  110.10 -page-flags.h		-> linux/include/linux/page-flags.h
  110.11  percpu.h		-> linux/include/linux/percpu.h
  110.12  preempt.h		-> linux/include/linux/preempt.h
  110.13 -rbtree.h		-> linux/include/linux/rbtree.h
  110.14  rwsem.h			-> linux/include/linux/rwsem.h
  110.15  seqlock.h		-> linux/include/linux/seqlock.h
  110.16  sort.h			-> linux/include/linux/sort.h
   111.1 --- a/xen/include/asm-ia64/linux/asm-generic/README.origin	Mon Mar 20 09:56:46 2006 +0100
   111.2 +++ b/xen/include/asm-ia64/linux/asm-generic/README.origin	Mon Mar 20 09:56:54 2006 +0100
   111.3 @@ -10,7 +10,6 @@ errno-base.h		-> linux/include/asm-gener
   111.4  errno.h			-> linux/include/asm-generic/errno.h
   111.5  ide_iops.h		-> linux/include/asm-generic/ide_iops.h
   111.6  iomap.h			-> linux/include/asm-generic/iomap.h
   111.7 -pci-dma-compat.h	-> linux/include/asm-generic/pci-dma-compat.h
   111.8  pci.h			-> linux/include/asm-generic/pci.h
   111.9  pgtable.h		-> linux/include/asm-generic/pgtable.h
  111.10  pgtable-nopud.h		-> linux/include/asm-generic/pgtable-nopud.h
   112.1 --- a/xen/include/asm-ia64/linux/asm-generic/pci-dma-compat.h	Mon Mar 20 09:56:46 2006 +0100
   112.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.3 @@ -1,107 +0,0 @@
   112.4 -/* include this file if the platform implements the dma_ DMA Mapping API
   112.5 - * and wants to provide the pci_ DMA Mapping API in terms of it */
   112.6 -
   112.7 -#ifndef _ASM_GENERIC_PCI_DMA_COMPAT_H
   112.8 -#define _ASM_GENERIC_PCI_DMA_COMPAT_H
   112.9 -
  112.10 -#include <linux/dma-mapping.h>
  112.11 -
  112.12 -/* note pci_set_dma_mask isn't here, since it's a public function
  112.13 - * exported from drivers/pci, use dma_supported instead */
  112.14 -
  112.15 -static inline int
  112.16 -pci_dma_supported(struct pci_dev *hwdev, u64 mask)
  112.17 -{
  112.18 -	return dma_supported(hwdev == NULL ? NULL : &hwdev->dev, mask);
  112.19 -}
  112.20 -
  112.21 -static inline void *
  112.22 -pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
  112.23 -		     dma_addr_t *dma_handle)
  112.24 -{
  112.25 -	return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
  112.26 -}
  112.27 -
  112.28 -static inline void
  112.29 -pci_free_consistent(struct pci_dev *hwdev, size_t size,
  112.30 -		    void *vaddr, dma_addr_t dma_handle)
  112.31 -{
  112.32 -	dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, vaddr, dma_handle);
  112.33 -}
  112.34 -
  112.35 -static inline dma_addr_t
  112.36 -pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
  112.37 -{
  112.38 -	return dma_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
  112.39 -}
  112.40 -
  112.41 -static inline void
  112.42 -pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
  112.43 -		 size_t size, int direction)
  112.44 -{
  112.45 -	dma_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
  112.46 -}
  112.47 -
  112.48 -static inline dma_addr_t
  112.49 -pci_map_page(struct pci_dev *hwdev, struct page *page,
  112.50 -	     unsigned long offset, size_t size, int direction)
  112.51 -{
  112.52 -	return dma_map_page(hwdev == NULL ? NULL : &hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
  112.53 -}
  112.54 -
  112.55 -static inline void
  112.56 -pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
  112.57 -	       size_t size, int direction)
  112.58 -{
  112.59 -	dma_unmap_page(hwdev == NULL ? NULL : &hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
  112.60 -}
  112.61 -
  112.62 -static inline int
  112.63 -pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
  112.64 -	   int nents, int direction)
  112.65 -{
  112.66 -	return dma_map_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
  112.67 -}
  112.68 -
  112.69 -static inline void
  112.70 -pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
  112.71 -	     int nents, int direction)
  112.72 -{
  112.73 -	dma_unmap_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
  112.74 -}
  112.75 -
  112.76 -static inline void
  112.77 -pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
  112.78 -		    size_t size, int direction)
  112.79 -{
  112.80 -	dma_sync_single_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
  112.81 -}
  112.82 -
  112.83 -static inline void
  112.84 -pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
  112.85 -		    size_t size, int direction)
  112.86 -{
  112.87 -	dma_sync_single_for_device(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
  112.88 -}
  112.89 -
  112.90 -static inline void
  112.91 -pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
  112.92 -		int nelems, int direction)
  112.93 -{
  112.94 -	dma_sync_sg_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
  112.95 -}
  112.96 -
  112.97 -static inline void
  112.98 -pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
  112.99 -		int nelems, int direction)
 112.100 -{
 112.101 -	dma_sync_sg_for_device(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
 112.102 -}
 112.103 -
 112.104 -static inline int
 112.105 -pci_dma_mapping_error(dma_addr_t dma_addr)
 112.106 -{
 112.107 -	return dma_mapping_error(dma_addr);
 112.108 -}
 112.109 -
 112.110 -#endif
   113.1 --- a/xen/include/asm-ia64/linux/asm/README.origin	Mon Mar 20 09:56:46 2006 +0100
   113.2 +++ b/xen/include/asm-ia64/linux/asm/README.origin	Mon Mar 20 09:56:54 2006 +0100
   113.3 @@ -42,7 +42,6 @@ ptrace_offsets.h	-> linux/include/asm-ia
   113.4  rse.h			-> linux/include/asm-ia64/rse.h
   113.5  rwsem.h			-> linux/include/asm-ia64/rwsem.h
   113.6  sal.h			-> linux/include/asm-ia64/sal.h
   113.7 -scatterlist.h		-> linux/include/asm-ia64/scatterlist.h
   113.8  sections.h		-> linux/include/asm-ia64/sections.h
   113.9  semaphore.h		-> linux/include/asm-ia64/semaphore.h
  113.10  setup.h			-> linux/include/asm-ia64/setup.h
   114.1 --- a/xen/include/asm-ia64/linux/asm/hw_irq.h	Mon Mar 20 09:56:46 2006 +0100
   114.2 +++ b/xen/include/asm-ia64/linux/asm/hw_irq.h	Mon Mar 20 09:56:54 2006 +0100
   114.3 @@ -85,6 +85,7 @@ extern int assign_irq_vector (int irq);	
   114.4  extern void free_irq_vector (int vector);
   114.5  extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
   114.6  extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
   114.7 +extern int xen_do_IRQ(ia64_vector vector);
   114.8  
   114.9  static inline void
  114.10  hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
   115.1 --- a/xen/include/asm-ia64/linux/asm/irq.h	Mon Mar 20 09:56:46 2006 +0100
   115.2 +++ b/xen/include/asm-ia64/linux/asm/irq.h	Mon Mar 20 09:56:54 2006 +0100
   115.3 @@ -40,4 +40,6 @@ struct irqaction;
   115.4  struct pt_regs;
   115.5  int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
   115.6  
   115.7 +extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
   115.8 +
   115.9  #endif /* _ASM_IA64_IRQ_H */
   116.1 --- a/xen/include/asm-ia64/linux/asm/scatterlist.h	Mon Mar 20 09:56:46 2006 +0100
   116.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.3 @@ -1,28 +0,0 @@
   116.4 -#ifndef _ASM_IA64_SCATTERLIST_H
   116.5 -#define _ASM_IA64_SCATTERLIST_H
   116.6 -
   116.7 -/*
   116.8 - * Modified 1998-1999, 2001-2002, 2004
   116.9 - *	David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
  116.10 - */
  116.11 -
  116.12 -struct scatterlist {
  116.13 -	struct page *page;
  116.14 -	unsigned int offset;
  116.15 -	unsigned int length;	/* buffer length */
  116.16 -
  116.17 -	dma_addr_t dma_address;
  116.18 -	unsigned int dma_length;
  116.19 -};
  116.20 -
  116.21 -/*
  116.22 - * It used to be that ISA_DMA_THRESHOLD had something to do with the
  116.23 - * DMA-limits of ISA-devices.  Nowadays, its only remaining use (apart
  116.24 - * from the aha1542.c driver, which isn't 64-bit clean anyhow) is to
  116.25 - * tell the block-layer (via BLK_BOUNCE_ISA) what the max. physical
  116.26 - * address of a page is that is allocated with GFP_DMA.  On IA-64,
  116.27 - * that's 4GB - 1.
  116.28 - */
  116.29 -#define ISA_DMA_THRESHOLD	0xffffffff
  116.30 -
  116.31 -#endif /* _ASM_IA64_SCATTERLIST_H */
   117.1 --- a/xen/include/asm-ia64/linux/mmzone.h	Mon Mar 20 09:56:46 2006 +0100
   117.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.3 @@ -1,592 +0,0 @@
   117.4 -#ifndef _LINUX_MMZONE_H
   117.5 -#define _LINUX_MMZONE_H
   117.6 -
   117.7 -#ifdef __KERNEL__
   117.8 -#ifndef __ASSEMBLY__
   117.9 -
  117.10 -#include <linux/config.h>
  117.11 -#include <linux/spinlock.h>
  117.12 -#include <linux/list.h>
  117.13 -#include <linux/wait.h>
  117.14 -#include <linux/cache.h>
  117.15 -#include <linux/threads.h>
  117.16 -#include <linux/numa.h>
  117.17 -#include <linux/init.h>
  117.18 -#include <asm/atomic.h>
  117.19 -
  117.20 -/* Free memory management - zoned buddy allocator.  */
  117.21 -#ifndef CONFIG_FORCE_MAX_ZONEORDER
  117.22 -#define MAX_ORDER 11
  117.23 -#else
  117.24 -#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
  117.25 -#endif
  117.26 -
  117.27 -struct free_area {
  117.28 -	struct list_head	free_list;
  117.29 -	unsigned long		nr_free;
  117.30 -};
  117.31 -
  117.32 -struct pglist_data;
  117.33 -
  117.34 -/*
  117.35 - * zone->lock and zone->lru_lock are two of the hottest locks in the kernel.
  117.36 - * So add a wild amount of padding here to ensure that they fall into separate
  117.37 - * cachelines.  There are very few zone structures in the machine, so space
  117.38 - * consumption is not a concern here.
  117.39 - */
  117.40 -#if defined(CONFIG_SMP)
  117.41 -struct zone_padding {
  117.42 -	char x[0];
  117.43 -} ____cacheline_maxaligned_in_smp;
  117.44 -#define ZONE_PADDING(name)	struct zone_padding name;
  117.45 -#else
  117.46 -#define ZONE_PADDING(name)
  117.47 -#endif
  117.48 -
  117.49 -struct per_cpu_pages {
  117.50 -	int count;		/* number of pages in the list */
  117.51 -	int low;		/* low watermark, refill needed */
  117.52 -	int high;		/* high watermark, emptying needed */
  117.53 -	int batch;		/* chunk size for buddy add/remove */
  117.54 -	struct list_head list;	/* the list of pages */
  117.55 -};
  117.56 -
  117.57 -struct per_cpu_pageset {
  117.58 -	struct per_cpu_pages pcp[2];	/* 0: hot.  1: cold */
  117.59 -#ifdef CONFIG_NUMA
  117.60 -	unsigned long numa_hit;		/* allocated in intended node */
  117.61 -	unsigned long numa_miss;	/* allocated in non intended node */
  117.62 -	unsigned long numa_foreign;	/* was intended here, hit elsewhere */
  117.63 -	unsigned long interleave_hit; 	/* interleaver prefered this zone */
  117.64 -	unsigned long local_node;	/* allocation from local node */
  117.65 -	unsigned long other_node;	/* allocation from other node */
  117.66 -#endif
  117.67 -} ____cacheline_aligned_in_smp;
  117.68 -
  117.69 -#ifdef CONFIG_NUMA
  117.70 -#define zone_pcp(__z, __cpu) ((__z)->pageset[(__cpu)])
  117.71 -#else
  117.72 -#define zone_pcp(__z, __cpu) (&(__z)->pageset[(__cpu)])
  117.73 -#endif
  117.74 -
  117.75 -#define ZONE_DMA		0
  117.76 -#define ZONE_NORMAL		1
  117.77 -#define ZONE_HIGHMEM		2
  117.78 -
  117.79 -#define MAX_NR_ZONES		3	/* Sync this with ZONES_SHIFT */
  117.80 -#define ZONES_SHIFT		2	/* ceil(log2(MAX_NR_ZONES)) */
  117.81 -
  117.82 -
  117.83 -/*
  117.84 - * When a memory allocation must conform to specific limitations (such
  117.85 - * as being suitable for DMA) the caller will pass in hints to the
  117.86 - * allocator in the gfp_mask, in the zone modifier bits.  These bits
  117.87 - * are used to select a priority ordered list of memory zones which
  117.88 - * match the requested limits.  GFP_ZONEMASK defines which bits within
  117.89 - * the gfp_mask should be considered as zone modifiers.  Each valid
  117.90 - * combination of the zone modifier bits has a corresponding list
  117.91 - * of zones (in node_zonelists).  Thus for two zone modifiers there
  117.92 - * will be a maximum of 4 (2 ** 2) zonelists, for 3 modifiers there will
  117.93 - * be 8 (2 ** 3) zonelists.  GFP_ZONETYPES defines the number of possible
  117.94 - * combinations of zone modifiers in "zone modifier space".
  117.95 - */
  117.96 -#define GFP_ZONEMASK	0x03
  117.97 -/*
  117.98 - * As an optimisation any zone modifier bits which are only valid when
  117.99 - * no other zone modifier bits are set (loners) should be placed in
 117.100 - * the highest order bits of this field.  This allows us to reduce the
 117.101 - * extent of the zonelists thus saving space.  For example in the case
 117.102 - * of three zone modifier bits, we could require up to eight zonelists.
 117.103 - * If the left most zone modifier is a "loner" then the highest valid
 117.104 - * zonelist would be four allowing us to allocate only five zonelists.
 117.105 - * Use the first form when the left most bit is not a "loner", otherwise
 117.106 - * use the second.
 117.107 - */
 117.108 -/* #define GFP_ZONETYPES	(GFP_ZONEMASK + 1) */		/* Non-loner */
 117.109 -#define GFP_ZONETYPES	((GFP_ZONEMASK + 1) / 2 + 1)		/* Loner */
 117.110 -
 117.111 -/*
 117.112 - * On machines where it is needed (eg PCs) we divide physical memory
 117.113 - * into multiple physical zones. On a PC we have 3 zones:
 117.114 - *
 117.115 - * ZONE_DMA	  < 16 MB	ISA DMA capable memory
 117.116 - * ZONE_NORMAL	16-896 MB	direct mapped by the kernel
 117.117 - * ZONE_HIGHMEM	 > 896 MB	only page cache and user processes
 117.118 - */
 117.119 -
 117.120 -struct zone {
 117.121 -	/* Fields commonly accessed by the page allocator */
 117.122 -	unsigned long		free_pages;
 117.123 -	unsigned long		pages_min, pages_low, pages_high;
 117.124 -	/*
 117.125 -	 * We don't know if the memory that we're going to allocate will be freeable
 117.126 -	 * or/and it will be released eventually, so to avoid totally wasting several
 117.127 -	 * GB of ram we must reserve some of the lower zone memory (otherwise we risk
 117.128 -	 * to run OOM on the lower zones despite there's tons of freeable ram
 117.129 -	 * on the higher zones). This array is recalculated at runtime if the
 117.130 -	 * sysctl_lowmem_reserve_ratio sysctl changes.
 117.131 -	 */
 117.132 -	unsigned long		lowmem_reserve[MAX_NR_ZONES];
 117.133 -
 117.134 -#ifdef CONFIG_NUMA
 117.135 -	struct per_cpu_pageset	*pageset[NR_CPUS];
 117.136 -#else
 117.137 -	struct per_cpu_pageset	pageset[NR_CPUS];
 117.138 -#endif
 117.139 -	/*
 117.140 -	 * free areas of different sizes
 117.141 -	 */
 117.142 -	spinlock_t		lock;
 117.143 -	struct free_area	free_area[MAX_ORDER];
 117.144 -
 117.145 -
 117.146 -	ZONE_PADDING(_pad1_)
 117.147 -
 117.148 -	/* Fields commonly accessed by the page reclaim scanner */
 117.149 -	spinlock_t		lru_lock;	
 117.150 -	struct list_head	active_list;
 117.151 -	struct list_head	inactive_list;
 117.152 -	unsigned long		nr_scan_active;
 117.153 -	unsigned long		nr_scan_inactive;
 117.154 -	unsigned long		nr_active;
 117.155 -	unsigned long		nr_inactive;
 117.156 -	unsigned long		pages_scanned;	   /* since last reclaim */
 117.157 -	int			all_unreclaimable; /* All pages pinned */
 117.158 -
 117.159 -	/*
 117.160 -	 * Does the allocator try to reclaim pages from the zone as soon
 117.161 -	 * as it fails a watermark_ok() in __alloc_pages?
 117.162 -	 */
 117.163 -	int			reclaim_pages;
 117.164 -	/* A count of how many reclaimers are scanning this zone */
 117.165 -	atomic_t		reclaim_in_progress;
 117.166 -
 117.167 -	/*
 117.168 -	 * prev_priority holds the scanning priority for this zone.  It is
 117.169 -	 * defined as the scanning priority at which we achieved our reclaim
 117.170 -	 * target at the previous try_to_free_pages() or balance_pgdat()
 117.171 -	 * invokation.
 117.172 -	 *
 117.173 -	 * We use prev_priority as a measure of how much stress page reclaim is
 117.174 -	 * under - it drives the swappiness decision: whether to unmap mapped
 117.175 -	 * pages.
 117.176 -	 *
 117.177 -	 * temp_priority is used to remember the scanning priority at which
 117.178 -	 * this zone was successfully refilled to free_pages == pages_high.
 117.179 -	 *
 117.180 -	 * Access to both these fields is quite racy even on uniprocessor.  But
 117.181 -	 * it is expected to average out OK.
 117.182 -	 */
 117.183 -	int temp_priority;
 117.184 -	int prev_priority;
 117.185 -
 117.186 -
 117.187 -	ZONE_PADDING(_pad2_)
 117.188 -	/* Rarely used or read-mostly fields */
 117.189 -
 117.190 -	/*
 117.191 -	 * wait_table		-- the array holding the hash table
 117.192 -	 * wait_table_size	-- the size of the hash table array
 117.193 -	 * wait_table_bits	-- wait_table_size == (1 << wait_table_bits)
 117.194 -	 *
 117.195 -	 * The purpose of all these is to keep track of the people
 117.196 -	 * waiting for a page to become available and make them
 117.197 -	 * runnable again when possible. The trouble is that this
 117.198 -	 * consumes a lot of space, especially when so few things
 117.199 -	 * wait on pages at a given time. So instead of using
 117.200 -	 * per-page waitqueues, we use a waitqueue hash table.
 117.201 -	 *
 117.202 -	 * The bucket discipline is to sleep on the same queue when
 117.203 -	 * colliding and wake all in that wait queue when removing.
 117.204 -	 * When something wakes, it must check to be sure its page is
 117.205 -	 * truly available, a la thundering herd. The cost of a
 117.206 -	 * collision is great, but given the expected load of the
 117.207 -	 * table, they should be so rare as to be outweighed by the
 117.208 -	 * benefits from the saved space.
 117.209 -	 *
 117.210 -	 * __wait_on_page_locked() and unlock_page() in mm/filemap.c, are the
 117.211 -	 * primary users of these fields, and in mm/page_alloc.c
 117.212 -	 * free_area_init_core() performs the initialization of them.
 117.213 -	 */
 117.214 -	wait_queue_head_t	* wait_table;
 117.215 -	unsigned long		wait_table_size;
 117.216 -	unsigned long		wait_table_bits;
 117.217 -
 117.218 -	/*
 117.219 -	 * Discontig memory support fields.
 117.220 -	 */
 117.221 -	struct pglist_data	*zone_pgdat;
 117.222 -	struct page		*zone_mem_map;
 117.223 -	/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
 117.224 -	unsigned long		zone_start_pfn;
 117.225 -
 117.226 -	unsigned long		spanned_pages;	/* total size, including holes */
 117.227 -	unsigned long		present_pages;	/* amount of memory (excluding holes) */
 117.228 -
 117.229 -	/*
 117.230 -	 * rarely used fields:
 117.231 -	 */
 117.232 -	char			*name;
 117.233 -} ____cacheline_maxaligned_in_smp;
 117.234 -
 117.235 -
 117.236 -/*
 117.237 - * The "priority" of VM scanning is how much of the queues we will scan in one
 117.238 - * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the
 117.239 - * queues ("queue_length >> 12") during an aging round.
 117.240 - */
 117.241 -#define DEF_PRIORITY 12
 117.242 -
 117.243 -/*
 117.244 - * One allocation request operates on a zonelist. A zonelist
 117.245 - * is a list of zones, the first one is the 'goal' of the
 117.246 - * allocation, the other zones are fallback zones, in decreasing
 117.247 - * priority.
 117.248 - *
 117.249 - * Right now a zonelist takes up less than a cacheline. We never
 117.250 - * modify it apart from boot-up, and only a few indices are used,
 117.251 - * so despite the zonelist table being relatively big, the cache
 117.252 - * footprint of this construct is very small.
 117.253 - */
 117.254 -struct zonelist {
 117.255 -	struct zone *zones[MAX_NUMNODES * MAX_NR_ZONES + 1]; // NULL delimited
 117.256 -};
 117.257 -
 117.258 -
 117.259 -/*
 117.260 - * The pg_data_t structure is used in machines with CONFIG_DISCONTIGMEM
 117.261 - * (mostly NUMA machines?) to denote a higher-level memory zone than the
 117.262 - * zone denotes.
 117.263 - *
 117.264 - * On NUMA machines, each NUMA node would have a pg_data_t to describe
 117.265 - * it's memory layout.
 117.266 - *
 117.267 - * Memory statistics and page replacement data structures are maintained on a
 117.268 - * per-zone basis.
 117.269 - */
 117.270 -struct bootmem_data;
 117.271 -typedef struct pglist_data {
 117.272 -	struct zone node_zones[MAX_NR_ZONES];
 117.273 -	struct zonelist node_zonelists[GFP_ZONETYPES];
 117.274 -	int nr_zones;
 117.275 -#ifdef CONFIG_FLAT_NODE_MEM_MAP
 117.276 -	struct page *node_mem_map;
 117.277 -#endif
 117.278 -	struct bootmem_data *bdata;
 117.279 -	unsigned long node_start_pfn;
 117.280 -	unsigned long node_present_pages; /* total number of physical pages */
 117.281 -	unsigned long node_spanned_pages; /* total size of physical page
 117.282 -					     range, including holes */
 117.283 -	int node_id;
 117.284 -	struct pglist_data *pgdat_next;
 117.285 -	wait_queue_head_t kswapd_wait;
 117.286 -	struct task_struct *kswapd;
 117.287 -	int kswapd_max_order;
 117.288 -} pg_data_t;
 117.289 -
 117.290 -#define node_present_pages(nid)	(NODE_DATA(nid)->node_present_pages)
 117.291 -#define node_spanned_pages(nid)	(NODE_DATA(nid)->node_spanned_pages)
 117.292 -#ifdef CONFIG_FLAT_NODE_MEM_MAP
 117.293 -#define pgdat_page_nr(pgdat, pagenr)	((pgdat)->node_mem_map + (pagenr))
 117.294 -#else
 117.295 -#define pgdat_page_nr(pgdat, pagenr)	mfn_to_page((pgdat)->node_start_pfn + (pagenr))
 117.296 -#endif
 117.297 -#define nid_page_nr(nid, pagenr) 	pgdat_page_nr(NODE_DATA(nid),(pagenr))
 117.298 -
 117.299 -extern struct pglist_data *pgdat_list;
 117.300 -
 117.301 -void __get_zone_counts(unsigned long *active, unsigned long *inactive,
 117.302 -			unsigned long *free, struct pglist_data *pgdat);
 117.303 -void get_zone_counts(unsigned long *active, unsigned long *inactive,
 117.304 -			unsigned long *free);
 117.305 -void build_all_zonelists(void);
 117.306 -void wakeup_kswapd(struct zone *zone, int order);
 117.307 -int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
 117.308 -		int alloc_type, int can_try_harder, int gfp_high);
 117.309 -
 117.310 -#ifdef CONFIG_HAVE_MEMORY_PRESENT
 117.311 -void memory_present(int nid, unsigned long start, unsigned long end);
 117.312 -#else
 117.313 -static inline void memory_present(int nid, unsigned long start, unsigned long end) {}
 117.314 -#endif
 117.315 -
 117.316 -#ifdef CONFIG_NEED_NODE_MEMMAP_SIZE
 117.317 -unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
 117.318 -#endif
 117.319 -
 117.320 -/*
 117.321 - * zone_idx() returns 0 for the ZONE_DMA zone, 1 for the ZONE_NORMAL zone, etc.
 117.322 - */
 117.323 -#define zone_idx(zone)		((zone) - (zone)->zone_pgdat->node_zones)
 117.324 -
 117.325 -/**
 117.326 - * for_each_pgdat - helper macro to iterate over all nodes
 117.327 - * @pgdat - pointer to a pg_data_t variable
 117.328 - *
 117.329 - * Meant to help with common loops of the form
 117.330 - * pgdat = pgdat_list;
 117.331 - * while(pgdat) {
 117.332 - * 	...
 117.333 - * 	pgdat = pgdat->pgdat_next;
 117.334 - * }
 117.335 - */
 117.336 -#define for_each_pgdat(pgdat) \
 117.337 -	for (pgdat = pgdat_list; pgdat; pgdat = pgdat->pgdat_next)
 117.338 -
 117.339 -/*
 117.340 - * next_zone - helper magic for for_each_zone()
 117.341 - * Thanks to William Lee Irwin III for this piece of ingenuity.
 117.342 - */
 117.343 -static inline struct zone *next_zone(struct zone *zone)
 117.344 -{
 117.345 -	pg_data_t *pgdat = zone->zone_pgdat;
 117.346 -
 117.347 -	if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
 117.348 -		zone++;
 117.349 -	else if (pgdat->pgdat_next) {
 117.350 -		pgdat = pgdat->pgdat_next;
 117.351 -		zone = pgdat->node_zones;
 117.352 -	} else
 117.353 -		zone = NULL;
 117.354 -
 117.355 -	return zone;
 117.356 -}
 117.357 -
 117.358 -/**
 117.359 - * for_each_zone - helper macro to iterate over all memory zones
 117.360 - * @zone - pointer to struct zone variable
 117.361 - *
 117.362 - * The user only needs to declare the zone variable, for_each_zone
 117.363 - * fills it in. This basically means for_each_zone() is an
 117.364 - * easier to read version of this piece of code:
 117.365 - *
 117.366 - * for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
 117.367 - * 	for (i = 0; i < MAX_NR_ZONES; ++i) {
 117.368 - * 		struct zone * z = pgdat->node_zones + i;
 117.369 - * 		...
 117.370 - * 	}
 117.371 - * }
 117.372 - */
 117.373 -#define for_each_zone(zone) \
 117.374 -	for (zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
 117.375 -
 117.376 -static inline int is_highmem_idx(int idx)
 117.377 -{
 117.378 -	return (idx == ZONE_HIGHMEM);
 117.379 -}
 117.380 -
 117.381 -static inline int is_normal_idx(int idx)
 117.382 -{
 117.383 -	return (idx == ZONE_NORMAL);
 117.384 -}
 117.385 -/**
 117.386 - * is_highmem - helper function to quickly check if a struct zone is a 
 117.387 - *              highmem zone or not.  This is an attempt to keep references
 117.388 - *              to ZONE_{DMA/NORMAL/HIGHMEM/etc} in general code to a minimum.
 117.389 - * @zone - pointer to struct zone variable
 117.390 - */
 117.391 -static inline int is_highmem(struct zone *zone)
 117.392 -{
 117.393 -	return zone == zone->zone_pgdat->node_zones + ZONE_HIGHMEM;
 117.394 -}
 117.395 -
 117.396 -static inline int is_normal(struct zone *zone)
 117.397 -{
 117.398 -	return zone == zone->zone_pgdat->node_zones + ZONE_NORMAL;
 117.399 -}
 117.400 -
 117.401 -/* These two functions are used to setup the per zone pages min values */
 117.402 -struct ctl_table;
 117.403 -struct file;
 117.404 -int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *, 
 117.405 -					void __user *, size_t *, loff_t *);
 117.406 -extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
 117.407 -int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *,
 117.408 -					void __user *, size_t *, loff_t *);
 117.409 -
 117.410 -#include <linux/topology.h>
 117.411 -/* Returns the number of the current Node. */
 117.412 -#define numa_node_id()		(cpu_to_node(raw_smp_processor_id()))
 117.413 -
 117.414 -#ifndef CONFIG_NEED_MULTIPLE_NODES
 117.415 -
 117.416 -extern struct pglist_data contig_page_data;
 117.417 -#define NODE_DATA(nid)		(&contig_page_data)
 117.418 -#define NODE_MEM_MAP(nid)	mem_map
 117.419 -#define MAX_NODES_SHIFT		1
 117.420 -#define pfn_to_nid(pfn)		(0)
 117.421 -
 117.422 -#else /* CONFIG_NEED_MULTIPLE_NODES */
 117.423 -
 117.424 -#include <asm/mmzone.h>
 117.425 -
 117.426 -#endif /* !CONFIG_NEED_MULTIPLE_NODES */
 117.427 -
 117.428 -#ifdef CONFIG_SPARSEMEM
 117.429 -#include <asm/sparsemem.h>
 117.430 -#endif
 117.431 -
 117.432 -#if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED)
 117.433 -/*
 117.434 - * with 32 bit page->flags field, we reserve 8 bits for node/zone info.
 117.435 - * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
 117.436 - */
 117.437 -#define FLAGS_RESERVED		8
 117.438 -
 117.439 -#elif BITS_PER_LONG == 64
 117.440 -/*
 117.441 - * with 64 bit flags field, there's plenty of room.
 117.442 - */
 117.443 -#define FLAGS_RESERVED		32
 117.444 -
 117.445 -#else
 117.446 -
 117.447 -#error BITS_PER_LONG not defined
 117.448 -
 117.449 -#endif
 117.450 -
 117.451 -#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
 117.452 -#define early_pfn_to_nid(nid)  (0UL)
 117.453 -#endif
 117.454 -
 117.455 -#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)
 117.456 -#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT)
 117.457 -
 117.458 -#ifdef CONFIG_SPARSEMEM
 117.459 -
 117.460 -/*
 117.461 - * SECTION_SHIFT    		#bits space required to store a section #
 117.462 - *
 117.463 - * PA_SECTION_SHIFT		physical address to/from section number
 117.464 - * PFN_SECTION_SHIFT		pfn to/from section number
 117.465 - */
 117.466 -#define SECTIONS_SHIFT		(MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
 117.467 -
 117.468 -#define PA_SECTION_SHIFT	(SECTION_SIZE_BITS)
 117.469 -#define PFN_SECTION_SHIFT	(SECTION_SIZE_BITS - PAGE_SHIFT)
 117.470 -
 117.471 -#define NR_MEM_SECTIONS		(1UL << SECTIONS_SHIFT)
 117.472 -
 117.473 -#define PAGES_PER_SECTION       (1UL << PFN_SECTION_SHIFT)
 117.474 -#define PAGE_SECTION_MASK	(~(PAGES_PER_SECTION-1))
 117.475 -
 117.476 -#if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS
 117.477 -#error Allocator MAX_ORDER exceeds SECTION_SIZE
 117.478 -#endif
 117.479 -
 117.480 -struct page;
 117.481 -struct mem_section {
 117.482 -	/*
 117.483 -	 * This is, logically, a pointer to an array of struct
 117.484 -	 * pages.  However, it is stored with some other magic.
 117.485 -	 * (see sparse.c::sparse_init_one_section())
 117.486 -	 *
 117.487 -	 * Making it a UL at least makes someone do a cast
 117.488 -	 * before using it wrong.
 117.489 -	 */
 117.490 -	unsigned long section_mem_map;
 117.491 -};
 117.492 -
 117.493 -extern struct mem_section mem_section[NR_MEM_SECTIONS];
 117.494 -
 117.495 -static inline struct mem_section *__nr_to_section(unsigned long nr)
 117.496 -{
 117.497 -	return &mem_section[nr];
 117.498 -}
 117.499 -
 117.500 -/*
 117.501 - * We use the lower bits of the mem_map pointer to store
 117.502 - * a little bit of information.  There should be at least
 117.503 - * 3 bits here due to 32-bit alignment.
 117.504 - */
 117.505 -#define	SECTION_MARKED_PRESENT	(1UL<<0)
 117.506 -#define SECTION_HAS_MEM_MAP	(1UL<<1)
 117.507 -#define SECTION_MAP_LAST_BIT	(1UL<<2)
 117.508 -#define SECTION_MAP_MASK	(~(SECTION_MAP_LAST_BIT-1))
 117.509 -
 117.510 -static inline struct page *__section_mem_map_addr(struct mem_section *section)
 117.511 -{
 117.512 -	unsigned long map = section->section_mem_map;
 117.513 -	map &= SECTION_MAP_MASK;
 117.514 -	return (struct page *)map;
 117.515 -}
 117.516 -
 117.517 -static inline int valid_section(struct mem_section *section)
 117.518 -{
 117.519 -	return (section->section_mem_map & SECTION_MARKED_PRESENT);
 117.520 -}
 117.521 -
 117.522 -static inline int section_has_mem_map(struct mem_section *section)
 117.523 -{
 117.524 -	return (section->section_mem_map & SECTION_HAS_MEM_MAP);
 117.525 -}
 117.526 -
 117.527 -static inline int valid_section_nr(unsigned long nr)
 117.528 -{
 117.529 -	return valid_section(__nr_to_section(nr));
 117.530 -}
 117.531 -
 117.532 -/*
 117.533 - * Given a kernel address, find the home node of the underlying memory.
 117.534 - */
 117.535 -#define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
 117.536 -
 117.537 -static inline struct mem_section *__pfn_to_section(unsigned long pfn)
 117.538 -{
 117.539 -	return __nr_to_section(pfn_to_section_nr(pfn));
 117.540 -}
 117.541 -
 117.542 -#define mfn_to_page(pfn) 						\
 117.543 -({ 									\
 117.544 -	unsigned long __pfn = (pfn);					\
 117.545 -	__section_mem_map_addr(__pfn_to_section(__pfn)) + __pfn;	\
 117.546 -})
 117.547 -#define page_to_mfn(page)						\
 117.548 -({									\
 117.549 -	page - __section_mem_map_addr(__nr_to_section(			\
 117.550 -		page_to_section(page)));				\
 117.551 -})
 117.552 -
 117.553 -static inline int mfn_valid(unsigned long pfn)
 117.554 -{
 117.555 -	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
 117.556 -		return 0;
 117.557 -	return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
 117.558 -}
 117.559 -
 117.560 -/*
 117.561 - * These are _only_ used during initialisation, therefore they
 117.562 - * can use __initdata ...  They could have names to indicate
 117.563 - * this restriction.
 117.564 - */
 117.565 -#ifdef CONFIG_NUMA
 117.566 -#define pfn_to_nid		early_pfn_to_nid
 117.567 -#endif
 117.568 -
 117.569 -#define pfn_to_pgdat(pfn)						\
 117.570 -({									\
 117.571 -	NODE_DATA(pfn_to_nid(pfn));					\
 117.572 -})
 117.573 -
 117.574 -#define early_mfn_valid(pfn)	mfn_valid(pfn)
 117.575 -void sparse_init(void);
 117.576 -#else
 117.577 -#define sparse_init()	do {} while (0)
 117.578 -#endif /* CONFIG_SPARSEMEM */
 117.579 -
 117.580 -#ifdef CONFIG_NODES_SPAN_OTHER_NODES
 117.581 -#define early_pfn_in_nid(pfn, nid)	(early_pfn_to_nid(pfn) == (nid))
 117.582 -#else
 117.583 -#define early_pfn_in_nid(pfn, nid)	(1)
 117.584 -#endif
 117.585 -
 117.586 -#ifndef early_mfn_valid
 117.587 -#define early_mfn_valid(pfn)	(1)
 117.588 -#endif
 117.589 -
 117.590 -void memory_present(int nid, unsigned long start, unsigned long end);
 117.591 -unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
 117.592 -
 117.593 -#endif /* !__ASSEMBLY__ */
 117.594 -#endif /* __KERNEL__ */
 117.595 -#endif /* _LINUX_MMZONE_H */
   118.1 --- a/xen/include/asm-ia64/linux/page-flags.h	Mon Mar 20 09:56:46 2006 +0100
   118.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.3 @@ -1,324 +0,0 @@
   118.4 -/*
   118.5 - * Macros for manipulating and testing page->flags
   118.6 - */
   118.7 -
   118.8 -#ifndef PAGE_FLAGS_H
   118.9 -#define PAGE_FLAGS_H
  118.10 -
  118.11 -#include <linux/percpu.h>
  118.12 -#include <linux/cache.h>
  118.13 -#include <asm/pgtable.h>
  118.14 -
  118.15 -/*
  118.16 - * Various page->flags bits:
  118.17 - *
  118.18 - * PG_reserved is set for special pages, which can never be swapped out. Some
  118.19 - * of them might not even exist (eg empty_bad_page)...
  118.20 - *
  118.21 - * The PG_private bitflag is set if page->private contains a valid value.
  118.22 - *
  118.23 - * During disk I/O, PG_locked is used. This bit is set before I/O and
  118.24 - * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks
  118.25 - * waiting for the I/O on this page to complete.
  118.26 - *
  118.27 - * PG_uptodate tells whether the page's contents is valid.  When a read
  118.28 - * completes, the page becomes uptodate, unless a disk I/O error happened.
  118.29 - *
  118.30 - * For choosing which pages to swap out, inode pages carry a PG_referenced bit,
  118.31 - * which is set any time the system accesses that page through the (mapping,
  118.32 - * index) hash table.  This referenced bit, together with the referenced bit
  118.33 - * in the page tables, is used to manipulate page->age and move the page across
  118.34 - * the active, inactive_dirty and inactive_clean lists.
  118.35 - *
  118.36 - * Note that the referenced bit, the page->lru list_head and the active,
  118.37 - * inactive_dirty and inactive_clean lists are protected by the
  118.38 - * zone->lru_lock, and *NOT* by the usual PG_locked bit!
  118.39 - *
  118.40 - * PG_error is set to indicate that an I/O error occurred on this page.
  118.41 - *
  118.42 - * PG_arch_1 is an architecture specific page state bit.  The generic code
  118.43 - * guarantees that this bit is cleared for a page when it first is entered into
  118.44 - * the page cache.
  118.45 - *
  118.46 - * PG_highmem pages are not permanently mapped into the kernel virtual address
  118.47 - * space, they need to be kmapped separately for doing IO on the pages.  The
  118.48 - * struct page (these bits with information) are always mapped into kernel
  118.49 - * address space...
  118.50 - */
  118.51 -
  118.52 -/*
  118.53 - * Don't use the *_dontuse flags.  Use the macros.  Otherwise you'll break
  118.54 - * locked- and dirty-page accounting.  The top eight bits of page->flags are
  118.55 - * used for page->zone, so putting flag bits there doesn't work.
  118.56 - */
  118.57 -#define PG_locked	 	 0	/* Page is locked. Don't touch. */
  118.58 -#define PG_error		 1
  118.59 -#define PG_referenced		 2
  118.60 -#define PG_uptodate		 3
  118.61 -
  118.62 -#define PG_dirty	 	 4
  118.63 -#define PG_lru			 5
  118.64 -#define PG_active		 6
  118.65 -#define PG_slab			 7	/* slab debug (Suparna wants this) */
  118.66 -
  118.67 -#define PG_checked		 8	/* kill me in 2.5.<early>. */
  118.68 -#define PG_arch_1		 9
  118.69 -#define PG_reserved		10
  118.70 -#define PG_private		11	/* Has something at ->private */
  118.71 -
  118.72 -#define PG_writeback		12	/* Page is under writeback */
  118.73 -#define PG_nosave		13	/* Used for system suspend/resume */
  118.74 -#define PG_compound		14	/* Part of a compound page */
  118.75 -#define PG_swapcache		15	/* Swap page: swp_entry_t in private */
  118.76 -
  118.77 -#define PG_mappedtodisk		16	/* Has blocks allocated on-disk */
  118.78 -#define PG_reclaim		17	/* To be reclaimed asap */
  118.79 -#define PG_nosave_free		18	/* Free, should not be written */
  118.80 -#define PG_uncached		19	/* Page has been mapped as uncached */
  118.81 -
  118.82 -/*
  118.83 - * Global page accounting.  One instance per CPU.  Only unsigned longs are
  118.84 - * allowed.
  118.85 - */
  118.86 -struct page_state {
  118.87 -	unsigned long nr_dirty;		/* Dirty writeable pages */
  118.88 -	unsigned long nr_writeback;	/* Pages under writeback */
  118.89 -	unsigned long nr_unstable;	/* NFS unstable pages */
  118.90 -	unsigned long nr_page_table_pages;/* Pages used for pagetables */
  118.91 -	unsigned long nr_mapped;	/* mapped into pagetables */
  118.92 -	unsigned long nr_slab;		/* In slab */
  118.93 -#define GET_PAGE_STATE_LAST nr_slab
  118.94 -
  118.95 -	/*
  118.96 -	 * The below are zeroed by get_page_state().  Use get_full_page_state()
  118.97 -	 * to add up all these.
  118.98 -	 */
  118.99 -	unsigned long pgpgin;		/* Disk reads */
 118.100 -	unsigned long pgpgout;		/* Disk writes */
 118.101 -	unsigned long pswpin;		/* swap reads */
 118.102 -	unsigned long pswpout;		/* swap writes */
 118.103 -	unsigned long pgalloc_high;	/* page allocations */
 118.104 -
 118.105 -	unsigned long pgalloc_normal;
 118.106 -	unsigned long pgalloc_dma;
 118.107 -	unsigned long pgfree;		/* page freeings */
 118.108 -	unsigned long pgactivate;	/* pages moved inactive->active */
 118.109 -	unsigned long pgdeactivate;	/* pages moved active->inactive */
 118.110 -
 118.111 -	unsigned long pgfault;		/* faults (major+minor) */
 118.112 -	unsigned long pgmajfault;	/* faults (major only) */
 118.113 -	unsigned long pgrefill_high;	/* inspected in refill_inactive_zone */
 118.114 -	unsigned long pgrefill_normal;
 118.115 -	unsigned long pgrefill_dma;
 118.116 -
 118.117 -	unsigned long pgsteal_high;	/* total highmem pages reclaimed */
 118.118 -	unsigned long pgsteal_normal;
 118.119 -	unsigned long pgsteal_dma;
 118.120 -	unsigned long pgscan_kswapd_high;/* total highmem pages scanned */
 118.121 -	unsigned long pgscan_kswapd_normal;
 118.122 -
 118.123 -	unsigned long pgscan_kswapd_dma;
 118.124 -	unsigned long pgscan_direct_high;/* total highmem pages scanned */
 118.125 -	unsigned long pgscan_direct_normal;
 118.126 -	unsigned long pgscan_direct_dma;
 118.127 -	unsigned long pginodesteal;	/* pages reclaimed via inode freeing */
 118.128 -
 118.129 -	unsigned long slabs_scanned;	/* slab objects scanned */
 118.130 -	unsigned long kswapd_steal;	/* pages reclaimed by kswapd */
 118.131 -	unsigned long kswapd_inodesteal;/* reclaimed via kswapd inode freeing */
 118.132 -	unsigned long pageoutrun;	/* kswapd's calls to page reclaim */
 118.133 -	unsigned long allocstall;	/* direct reclaim calls */
 118.134 -
 118.135 -	unsigned long pgrotated;	/* pages rotated to tail of the LRU */
 118.136 -	unsigned long nr_bounce;	/* pages for bounce buffers */
 118.137 -};
 118.138 -
 118.139 -extern void get_page_state(struct page_state *ret);
 118.140 -extern void get_full_page_state(struct page_state *ret);
 118.141 -extern unsigned long __read_page_state(unsigned long offset);
 118.142 -extern void __mod_page_state(unsigned long offset, unsigned long delta);
 118.143 -
 118.144 -#define read_page_state(member) \
 118.145 -	__read_page_state(offsetof(struct page_state, member))
 118.146 -
 118.147 -#define mod_page_state(member, delta)	\
 118.148 -	__mod_page_state(offsetof(struct page_state, member), (delta))
 118.149 -
 118.150 -#define inc_page_state(member)	mod_page_state(member, 1UL)
 118.151 -#define dec_page_state(member)	mod_page_state(member, 0UL - 1)
 118.152 -#define add_page_state(member,delta) mod_page_state(member, (delta))
 118.153 -#define sub_page_state(member,delta) mod_page_state(member, 0UL - (delta))
 118.154 -
 118.155 -#define mod_page_state_zone(zone, member, delta)				\
 118.156 -	do {									\
 118.157 -		unsigned offset;						\
 118.158 -		if (is_highmem(zone))						\
 118.159 -			offset = offsetof(struct page_state, member##_high);	\
 118.160 -		else if (is_normal(zone))					\
 118.161 -			offset = offsetof(struct page_state, member##_normal);	\
 118.162 -		else								\
 118.163 -			offset = offsetof(struct page_state, member##_dma);	\
 118.164 -		__mod_page_state(offset, (delta));				\
 118.165 -	} while (0)
 118.166 -
 118.167 -/*
 118.168 - * Manipulation of page state flags
 118.169 - */
 118.170 -#define PageLocked(page)		\
 118.171 -		test_bit(PG_locked, &(page)->flags)
 118.172 -#define SetPageLocked(page)		\
 118.173 -		set_bit(PG_locked, &(page)->flags)
 118.174 -#define TestSetPageLocked(page)		\
 118.175 -		test_and_set_bit(PG_locked, &(page)->flags)
 118.176 -#define ClearPageLocked(page)		\
 118.177 -		clear_bit(PG_locked, &(page)->flags)
 118.178 -#define TestClearPageLocked(page)	\
 118.179 -		test_and_clear_bit(PG_locked, &(page)->flags)
 118.180 -
 118.181 -#define PageError(page)		test_bit(PG_error, &(page)->flags)
 118.182 -#define SetPageError(page)	set_bit(PG_error, &(page)->flags)
 118.183 -#define ClearPageError(page)	clear_bit(PG_error, &(page)->flags)
 118.184 -
 118.185 -#define PageReferenced(page)	test_bit(PG_referenced, &(page)->flags)
 118.186 -#define SetPageReferenced(page)	set_bit(PG_referenced, &(page)->flags)
 118.187 -#define ClearPageReferenced(page)	clear_bit(PG_referenced, &(page)->flags)
 118.188 -#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
 118.189 -
 118.190 -#define PageUptodate(page)	test_bit(PG_uptodate, &(page)->flags)
 118.191 -#ifndef SetPageUptodate
 118.192 -#define SetPageUptodate(page)	set_bit(PG_uptodate, &(page)->flags)
 118.193 -#endif
 118.194 -#define ClearPageUptodate(page)	clear_bit(PG_uptodate, &(page)->flags)
 118.195 -
 118.196 -#define PageDirty(page)		test_bit(PG_dirty, &(page)->flags)
 118.197 -#define SetPageDirty(page)	set_bit(PG_dirty, &(page)->flags)
 118.198 -#define TestSetPageDirty(page)	test_and_set_bit(PG_dirty, &(page)->flags)
 118.199 -#define ClearPageDirty(page)	clear_bit(PG_dirty, &(page)->flags)
 118.200 -#define TestClearPageDirty(page) test_and_clear_bit(PG_dirty, &(page)->flags)
 118.201 -
 118.202 -#define SetPageLRU(page)	set_bit(PG_lru, &(page)->flags)
 118.203 -#define PageLRU(page)		test_bit(PG_lru, &(page)->flags)
 118.204 -#define TestSetPageLRU(page)	test_and_set_bit(PG_lru, &(page)->flags)
 118.205 -#define TestClearPageLRU(page)	test_and_clear_bit(PG_lru, &(page)->flags)
 118.206 -
 118.207 -#define PageActive(page)	test_bit(PG_active, &(page)->flags)
 118.208 -#define SetPageActive(page)	set_bit(PG_active, &(page)->flags)
 118.209 -#define ClearPageActive(page)	clear_bit(PG_active, &(page)->flags)
 118.210 -#define TestClearPageActive(page) test_and_clear_bit(PG_active, &(page)->flags)
 118.211 -#define TestSetPageActive(page) test_and_set_bit(PG_active, &(page)->flags)
 118.212 -
 118.213 -#define PageSlab(page)		test_bit(PG_slab, &(page)->flags)
 118.214 -#define SetPageSlab(page)	set_bit(PG_slab, &(page)->flags)
 118.215 -#define ClearPageSlab(page)	clear_bit(PG_slab, &(page)->flags)
 118.216 -#define TestClearPageSlab(page)	test_and_clear_bit(PG_slab, &(page)->flags)
 118.217 -#define TestSetPageSlab(page)	test_and_set_bit(PG_slab, &(page)->flags)
 118.218 -
 118.219 -#ifdef CONFIG_HIGHMEM
 118.220 -#define PageHighMem(page)	is_highmem(page_zone(page))
 118.221 -#else
 118.222 -#define PageHighMem(page)	0 /* needed to optimize away at compile time */
 118.223 -#endif
 118.224 -
 118.225 -#define PageChecked(page)	test_bit(PG_checked, &(page)->flags)
 118.226 -#define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
 118.227 -#define ClearPageChecked(page)	clear_bit(PG_checked, &(page)->flags)
 118.228 -
 118.229 -#define PageReserved(page)	test_bit(PG_reserved, &(page)->flags)
 118.230 -#define SetPageReserved(page)	set_bit(PG_reserved, &(page)->flags)
 118.231 -#define ClearPageReserved(page)	clear_bit(PG_reserved, &(page)->flags)
 118.232 -#define __ClearPageReserved(page)	__clear_bit(PG_reserved, &(page)->flags)
 118.233 -
 118.234 -#define SetPagePrivate(page)	set_bit(PG_private, &(page)->flags)
 118.235 -#define ClearPagePrivate(page)	clear_bit(PG_private, &(page)->flags)
 118.236 -#define PagePrivate(page)	test_bit(PG_private, &(page)->flags)
 118.237 -#define __SetPagePrivate(page)  __set_bit(PG_private, &(page)->flags)
 118.238 -#define __ClearPagePrivate(page) __clear_bit(PG_private, &(page)->flags)
 118.239 -
 118.240 -#define PageWriteback(page)	test_bit(PG_writeback, &(page)->flags)
 118.241 -#define SetPageWriteback(page)						\
 118.242 -	do {								\
 118.243 -		if (!test_and_set_bit(PG_writeback,			\
 118.244 -				&(page)->flags))			\
 118.245 -			inc_page_state(nr_writeback);			\
 118.246 -	} while (0)
 118.247 -#define TestSetPageWriteback(page)					\
 118.248 -	({								\
 118.249 -		int ret;						\
 118.250 -		ret = test_and_set_bit(PG_writeback,			\
 118.251 -					&(page)->flags);		\
 118.252 -		if (!ret)						\
 118.253 -			inc_page_state(nr_writeback);			\
 118.254 -		ret;							\
 118.255 -	})
 118.256 -#define ClearPageWriteback(page)					\
 118.257 -	do {								\
 118.258 -		if (test_and_clear_bit(PG_writeback,			\
 118.259 -				&(page)->flags))			\
 118.260 -			dec_page_state(nr_writeback);			\
 118.261 -	} while (0)
 118.262 -#define TestClearPageWriteback(page)					\
 118.263 -	({								\
 118.264 -		int ret;						\
 118.265 -		ret = test_and_clear_bit(PG_writeback,			\
 118.266 -				&(page)->flags);			\
 118.267 -		if (ret)						\
 118.268 -			dec_page_state(nr_writeback);			\
 118.269 -		ret;							\
 118.270 -	})
 118.271 -
 118.272 -#define PageNosave(page)	test_bit(PG_nosave, &(page)->flags)
 118.273 -#define SetPageNosave(page)	set_bit(PG_nosave, &(page)->flags)
 118.274 -#define TestSetPageNosave(page)	test_and_set_bit(PG_nosave, &(page)->flags)
 118.275 -#define ClearPageNosave(page)		clear_bit(PG_nosave, &(page)->flags)
 118.276 -#define TestClearPageNosave(page)	test_and_clear_bit(PG_nosave, &(page)->flags)
 118.277 -
 118.278 -#define PageNosaveFree(page)	test_bit(PG_nosave_free, &(page)->flags)
 118.279 -#define SetPageNosaveFree(page)	set_bit(PG_nosave_free, &(page)->flags)
 118.280 -#define ClearPageNosaveFree(page)		clear_bit(PG_nosave_free, &(page)->flags)
 118.281 -
 118.282 -#define PageMappedToDisk(page)	test_bit(PG_mappedtodisk, &(page)->flags)
 118.283 -#define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
 118.284 -#define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
 118.285 -
 118.286 -#define PageReclaim(page)	test_bit(PG_reclaim, &(page)->flags)
 118.287 -#define SetPageReclaim(page)	set_bit(PG_reclaim, &(page)->flags)
 118.288 -#define ClearPageReclaim(page)	clear_bit(PG_reclaim, &(page)->flags)
 118.289 -#define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags)
 118.290 -
 118.291 -#ifdef CONFIG_HUGETLB_PAGE
 118.292 -#define PageCompound(page)	test_bit(PG_compound, &(page)->flags)
 118.293 -#else
 118.294 -#define PageCompound(page)	0
 118.295 -#endif
 118.296 -#define SetPageCompound(page)	set_bit(PG_compound, &(page)->flags)
 118.297 -#define ClearPageCompound(page)	clear_bit(PG_compound, &(page)->flags)
 118.298 -
 118.299 -#ifdef CONFIG_SWAP
 118.300 -#define PageSwapCache(page)	test_bit(PG_swapcache, &(page)->flags)
 118.301 -#define SetPageSwapCache(page)	set_bit(PG_swapcache, &(page)->flags)
 118.302 -#define ClearPageSwapCache(page) clear_bit(PG_swapcache, &(page)->flags)
 118.303 -#else
 118.304 -#define PageSwapCache(page)	0
 118.305 -#endif
 118.306 -
 118.307 -#define PageUncached(page)	test_bit(PG_uncached, &(page)->flags)
 118.308 -#define SetPageUncached(page)	set_bit(PG_uncached, &(page)->flags)
 118.309 -#define ClearPageUncached(page)	clear_bit(PG_uncached, &(page)->flags)
 118.310 -
 118.311 -struct page;	/* forward declaration */
 118.312 -
 118.313 -int test_clear_page_dirty(struct page *page);
 118.314 -int test_clear_page_writeback(struct page *page);
 118.315 -int test_set_page_writeback(struct page *page);
 118.316 -
 118.317 -static inline void clear_page_dirty(struct page *page)
 118.318 -{
 118.319 -	test_clear_page_dirty(page);
 118.320 -}
 118.321 -
 118.322 -static inline void set_page_writeback(struct page *page)
 118.323 -{
 118.324 -	test_set_page_writeback(page);
 118.325 -}
 118.326 -
 118.327 -#endif	/* PAGE_FLAGS_H */
   119.1 --- a/xen/include/asm-ia64/linux/rbtree.h	Mon Mar 20 09:56:46 2006 +0100
   119.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.3 @@ -1,141 +0,0 @@
   119.4 -/*
   119.5 -  Red Black Trees
   119.6 -  (C) 1999  Andrea Arcangeli <andrea@suse.de>
   119.7 -  
   119.8 -  This program is free software; you can redistribute it and/or modify
   119.9 -  it under the terms of the GNU General Public License as published by
  119.10 -  the Free Software Foundation; either version 2 of the License, or
  119.11 -  (at your option) any later version.
  119.12 -
  119.13 -  This program is distributed in the hope that it will be useful,
  119.14 -  but WITHOUT ANY WARRANTY; without even the implied warranty of
  119.15 -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  119.16 -  GNU General Public License for more details.
  119.17 -
  119.18 -  You should have received a copy of the GNU General Public License
  119.19 -  along with this program; if not, write to the Free Software
  119.20 -  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  119.21 -
  119.22 -  linux/include/linux/rbtree.h
  119.23 -
  119.24 -  To use rbtrees you'll have to implement your own insert and search cores.
  119.25 -  This will avoid us to use callbacks and to drop drammatically performances.
  119.26 -  I know it's not the cleaner way,  but in C (not in C++) to get
  119.27 -  performances and genericity...
  119.28 -
  119.29 -  Some example of insert and search follows here. The search is a plain
  119.30 -  normal search over an ordered tree. The insert instead must be implemented
  119.31 -  int two steps: as first thing the code must insert the element in
  119.32 -  order as a red leaf in the tree, then the support library function
  119.33 -  rb_insert_color() must be called. Such function will do the
  119.34 -  not trivial work to rebalance the rbtree if necessary.
  119.35 -
  119.36 ------------------------------------------------------------------------
  119.37 -static inline struct page * rb_search_page_cache(struct inode * inode,
  119.38 -						 unsigned long offset)
  119.39 -{
  119.40 -	struct rb_node * n = inode->i_rb_page_cache.rb_node;
  119.41 -	struct page * page;
  119.42 -
  119.43 -	while (n)
  119.44 -	{
  119.45 -		page = rb_entry(n, struct page, rb_page_cache);
  119.46 -
  119.47 -		if (offset < page->offset)
  119.48 -			n = n->rb_left;
  119.49 -		else if (offset > page->offset)
  119.50 -			n = n->rb_right;
  119.51 -		else
  119.52 -			return page;
  119.53 -	}
  119.54 -	return NULL;
  119.55 -}
  119.56 -
  119.57 -static inline struct page * __rb_insert_page_cache(struct inode * inode,
  119.58 -						   unsigned long offset,
  119.59 -						   struct rb_node * node)
  119.60 -{
  119.61 -	struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
  119.62 -	struct rb_node * parent = NULL;
  119.63 -	struct page * page;
  119.64 -
  119.65 -	while (*p)
  119.66 -	{
  119.67 -		parent = *p;
  119.68 -		page = rb_entry(parent, struct page, rb_page_cache);
  119.69 -
  119.70 -		if (offset < page->offset)
  119.71 -			p = &(*p)->rb_left;
  119.72 -		else if (offset > page->offset)
  119.73 -			p = &(*p)->rb_right;
  119.74 -		else
  119.75 -			return page;
  119.76 -	}
  119.77 -
  119.78 -	rb_link_node(node, parent, p);
  119.79 -
  119.80 -	return NULL;
  119.81 -}
  119.82 -
  119.83 -static inline struct page * rb_insert_page_cache(struct inode * inode,
  119.84 -						 unsigned long offset,
  119.85 -						 struct rb_node * node)
  119.86 -{
  119.87 -	struct page * ret;
  119.88 -	if ((ret = __rb_insert_page_cache(inode, offset, node)))
  119.89 -		goto out;
  119.90 -	rb_insert_color(node, &inode->i_rb_page_cache);
  119.91 - out:
  119.92 -	return ret;
  119.93 -}
  119.94 ------------------------------------------------------------------------
  119.95 -*/
  119.96 -
  119.97 -#ifndef	_LINUX_RBTREE_H
  119.98 -#define	_LINUX_RBTREE_H
  119.99 -
 119.100 -#include <linux/kernel.h>
 119.101 -#include <linux/stddef.h>
 119.102 -
 119.103 -struct rb_node
 119.104 -{
 119.105 -	struct rb_node *rb_parent;
 119.106 -	int rb_color;
 119.107 -#define	RB_RED		0
 119.108 -#define	RB_BLACK	1
 119.109 -	struct rb_node *rb_right;
 119.110 -	struct rb_node *rb_left;
 119.111 -};
 119.112 -
 119.113 -struct rb_root
 119.114 -{
 119.115 -	struct rb_node *rb_node;
 119.116 -};
 119.117 -
 119.118 -#define RB_ROOT	(struct rb_root) { NULL, }
 119.119 -#define	rb_entry(ptr, type, member) container_of(ptr, type, member)
 119.120 -
 119.121 -extern void rb_insert_color(struct rb_node *, struct rb_root *);
 119.122 -extern void rb_erase(struct rb_node *, struct rb_root *);
 119.123 -
 119.124 -/* Find logical next and previous nodes in a tree */
 119.125 -extern struct rb_node *rb_next(struct rb_node *);
 119.126 -extern struct rb_node *rb_prev(struct rb_node *);
 119.127 -extern struct rb_node *rb_first(struct rb_root *);
 119.128 -extern struct rb_node *rb_last(struct rb_root *);
 119.129 -
 119.130 -/* Fast replacement of a single node without remove/rebalance/add/rebalance */
 119.131 -extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, 
 119.132 -			    struct rb_root *root);
 119.133 -
 119.134 -static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
 119.135 -				struct rb_node ** rb_link)
 119.136 -{
 119.137 -	node->rb_parent = parent;
 119.138 -	node->rb_color = RB_RED;
 119.139 -	node->rb_left = node->rb_right = NULL;
 119.140 -
 119.141 -	*rb_link = node;
 119.142 -}
 119.143 -
 119.144 -#endif	/* _LINUX_RBTREE_H */
   120.1 --- a/xen/include/asm-ia64/mm.h	Mon Mar 20 09:56:46 2006 +0100
   120.2 +++ b/xen/include/asm-ia64/mm.h	Mon Mar 20 09:56:54 2006 +0100
   120.3 @@ -10,8 +10,6 @@
   120.4  #include <xen/perfc.h>
   120.5  #include <xen/sched.h>
   120.6  
   120.7 -#include <linux/rbtree.h>
   120.8 -
   120.9  #include <asm/processor.h>
  120.10  #include <asm/atomic.h>
  120.11  #include <asm/flushtlb.h>
  120.12 @@ -36,37 +34,38 @@ typedef unsigned long page_flags_t;
  120.13  
  120.14  #define PRtype_info "08x"
  120.15  
  120.16 -struct page
  120.17 +struct page_info
  120.18  {
  120.19      /* Each frame can be threaded onto a doubly-linked list. */
  120.20      struct list_head list;
  120.21  
  120.22 -    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
  120.23 -    u32 tlbflush_timestamp;
  120.24 -
  120.25      /* Reference count and various PGC_xxx flags and fields. */
  120.26      u32 count_info;
  120.27  
  120.28      /* Context-dependent fields follow... */
  120.29      union {
  120.30  
  120.31 -        /* Page is in use by a domain. */
  120.32 +        /* Page is in use: ((count_info & PGC_count_mask) != 0). */
  120.33          struct {
  120.34 -            /* Owner of this page. */
  120.35 -            u32	_domain;
  120.36 +            /* Owner of this page (NULL if page is anonymous). */
  120.37 +            u32 _domain; /* pickled format */
  120.38              /* Type reference count and various PGT_xxx flags and fields. */
  120.39 -            u32 type_info;
  120.40 -        } inuse;
  120.41 +            unsigned long type_info;
  120.42 +        } __attribute__ ((packed)) inuse;
  120.43  
  120.44 -        /* Page is on a free list. */
  120.45 +        /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
  120.46          struct {
  120.47 +            /* Order-size of the free chunk this page is the head of. */
  120.48 +            u32 order;
  120.49              /* Mask of possibly-tainted TLBs. */
  120.50              cpumask_t cpumask;
  120.51 -            /* Order-size of the free chunk this page is the head of. */
  120.52 -            u8 order;
  120.53 -        } free;
  120.54 +        } __attribute__ ((packed)) free;
  120.55  
  120.56      } u;
  120.57 +
  120.58 +    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
  120.59 +    u32 tlbflush_timestamp;
  120.60 +
  120.61  #if 0
  120.62  // following added for Linux compiling
  120.63      page_flags_t flags;
  120.64 @@ -77,34 +76,46 @@ struct page
  120.65  
  120.66  #define set_page_count(p,v) 	atomic_set(&(p)->_count, v - 1)
  120.67  
  120.68 -/* Still small set of flags defined by far on IA-64 */
  120.69 +/*
  120.70 + * Still small set of flags defined by far on IA-64.
  120.71 + * IA-64 should make it a definition same as x86_64.
  120.72 + */
  120.73  /* The following page types are MUTUALLY EXCLUSIVE. */
  120.74  #define PGT_none            (0<<29) /* no special uses of this page */
  120.75  #define PGT_l1_page_table   (1<<29) /* using this page as an L1 page table? */
  120.76  #define PGT_l2_page_table   (2<<29) /* using this page as an L2 page table? */
  120.77  #define PGT_l3_page_table   (3<<29) /* using this page as an L3 page table? */
  120.78  #define PGT_l4_page_table   (4<<29) /* using this page as an L4 page table? */
  120.79 -#define PGT_writable_page   (5<<29) /* has writable mappings of this page? */
  120.80 -#define PGT_type_mask       (5<<29) /* Bits 29-31. */
  120.81 + /* Value 5 reserved. See asm-x86/mm.h */
  120.82 + /* Value 6 reserved. See asm-x86/mm.h */
  120.83 +#define PGT_writable_page   (7<<29) /* has writable mappings of this page? */
  120.84 +#define PGT_type_mask       (7<<29) /* Bits 29-31. */
  120.85  
  120.86   /* Has this page been validated for use as its current type? */
  120.87  #define _PGT_validated      28
  120.88  #define PGT_validated       (1<<_PGT_validated)
  120.89 -/* Owning guest has pinned this page to its current type? */
  120.90 + /* Owning guest has pinned this page to its current type? */
  120.91  #define _PGT_pinned         27
  120.92  #define PGT_pinned          (1U<<_PGT_pinned)
  120.93  
  120.94 -/* 27-bit count of uses of this frame as its current type. */
  120.95 -#define PGT_count_mask      ((1U<<27)-1)
  120.96 + /* The 27 most significant bits of virt address if this is a page table. */
  120.97 +#define PGT_va_shift        32
  120.98 +#define PGT_va_mask         ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
  120.99 + /* Is the back pointer still mutable (i.e. not fixed yet)? */
 120.100 +#define PGT_va_mutable      ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
 120.101 + /* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
 120.102 +#define PGT_va_unknown      ((unsigned long)((1U<<28)-2)<<PGT_va_shift)
 120.103  
 120.104 -/* Cleared when the owning guest 'frees' this page. */
 120.105 + /* 16-bit count of uses of this frame as its current type. */
 120.106 +#define PGT_count_mask      ((1U<<16)-1)
 120.107 +
 120.108 + /* Cleared when the owning guest 'frees' this page. */
 120.109  #define _PGC_allocated      31
 120.110  #define PGC_allocated       (1U<<_PGC_allocated)
 120.111 -/* Set when the page is used as a page table */
 120.112 -#define _PGC_page_table     30
 120.113 -#define PGC_page_table      (1U<<_PGC_page_table)
 120.114 -/* 30-bit count of references to this frame. */
 120.115 -#define PGC_count_mask      ((1U<<30)-1)
 120.116 + /* Bit 30 reserved. See asm-x86/mm.h */
 120.117 + /* Bit 29 reserved. See asm-x86/mm.h */
 120.118 + /* 29-bit count of references to this frame. */
 120.119 +#define PGC_count_mask      ((1U<<29)-1)
 120.120  
 120.121  #define IS_XEN_HEAP_FRAME(_pfn) ((page_to_maddr(_pfn) < xenheap_phys_end) \
 120.122  				 && (page_to_maddr(_pfn) >= xen_pstart))
 120.123 @@ -139,7 +150,6 @@ extern unsigned long gmfn_to_mfn_foreign
 120.124  
 120.125  static inline void put_page(struct page_info *page)
 120.126  {
 120.127 -#ifdef VALIDATE_VT	// doesn't work with non-VTI in grant tables yet
 120.128      u32 nx, x, y = page->count_info;
 120.129  
 120.130      do {
 120.131 @@ -150,14 +160,12 @@ static inline void put_page(struct page_
 120.132  
 120.133      if (unlikely((nx & PGC_count_mask) == 0))
 120.134  	free_domheap_page(page);
 120.135 -#endif
 120.136  }
 120.137  
 120.138  /* count_info and ownership are checked atomically. */
 120.139  static inline int get_page(struct page_info *page,
 120.140                             struct domain *domain)
 120.141  {
 120.142 -#ifdef VALIDATE_VT
 120.143      u64 x, nx, y = *((u64*)&page->count_info);
 120.144      u32 _domain = pickle_domptr(domain);
 120.145  
 120.146 @@ -173,14 +181,13 @@ static inline int get_page(struct page_i
 120.147  	    return 0;
 120.148  	}
 120.149      }
 120.150 -    while(unlikely(y = cmpxchg(&page->count_info, x, nx)) != x);
 120.151 -#endif
 120.152 +    while(unlikely((y = cmpxchg((u64*)&page->count_info, x, nx)) != x));
 120.153      return 1;
 120.154  }
 120.155  
 120.156 -/* No type info now */
 120.157 -#define put_page_type(page)
 120.158 -#define get_page_type(page, type) 1
 120.159 +extern void put_page_type(struct page_info *page);
 120.160 +extern int get_page_type(struct page_info *page, u32 type);
 120.161 +
 120.162  static inline void put_page_and_type(struct page_info *page)
 120.163  {
 120.164      put_page_type(page);
 120.165 @@ -219,7 +226,7 @@ void memguard_unguard_range(void *p, uns
 120.166  
 120.167  // prototype of misc memory stuff
 120.168  //unsigned long __get_free_pages(unsigned int mask, unsigned int order);
 120.169 -//void __free_pages(struct page *page, unsigned int order);
 120.170 +//void __free_pages(struct page_info *page, unsigned int order);
 120.171  void *pgtable_quicklist_alloc(void);
 120.172  void pgtable_quicklist_free(void *pgtable_entry);
 120.173  
 120.174 @@ -339,11 +346,11 @@ struct vm_area_struct {
 120.175  #define NODEZONE_SHIFT (sizeof(page_flags_t)*8 - MAX_NODES_SHIFT - MAX_ZONES_SHIFT)
 120.176  #define NODEZONE(node, zone)	((node << ZONES_SHIFT) | zone)
 120.177  
 120.178 -static inline unsigned long page_zonenum(struct page *page)
 120.179 +static inline unsigned long page_zonenum(struct page_info *page)
 120.180  {
 120.181  	return (page->flags >> NODEZONE_SHIFT) & (~(~0UL << ZONES_SHIFT));
 120.182  }
 120.183 -static inline unsigned long page_to_nid(struct page *page)
 120.184 +static inline unsigned long page_to_nid(struct page_info *page)
 120.185  {
 120.186  	return (page->flags >> (NODEZONE_SHIFT + ZONES_SHIFT));
 120.187  }
 120.188 @@ -351,12 +358,12 @@ static inline unsigned long page_to_nid(
 120.189  struct zone;
 120.190  extern struct zone *zone_table[];
 120.191  
 120.192 -static inline struct zone *page_zone(struct page *page)
 120.193 +static inline struct zone *page_zone(struct page_info *page)
 120.194  {
 120.195  	return zone_table[page->flags >> NODEZONE_SHIFT];
 120.196  }
 120.197  
 120.198 -static inline void set_page_zone(struct page *page, unsigned long nodezone_num)
 120.199 +static inline void set_page_zone(struct page_info *page, unsigned long nodezone_num)
 120.200  {
 120.201  	page->flags &= ~(~0UL << NODEZONE_SHIFT);
 120.202  	page->flags |= nodezone_num << NODEZONE_SHIFT;
 120.203 @@ -367,7 +374,7 @@ static inline void set_page_zone(struct 
 120.204  extern unsigned long max_mapnr;
 120.205  #endif
 120.206  
 120.207 -static inline void *lowmem_page_address(struct page *page)
 120.208 +static inline void *lowmem_page_address(struct page_info *page)
 120.209  {
 120.210  	return __va(page_to_mfn(page) << PAGE_SHIFT);
 120.211  }
 120.212 @@ -386,8 +393,8 @@ static inline void *lowmem_page_address(
 120.213  #endif
 120.214  
 120.215  #if defined(HASHED_PAGE_VIRTUAL)
 120.216 -void *page_address(struct page *page);
 120.217 -void set_page_address(struct page *page, void *virtual);
 120.218 +void *page_address(struct page_info *page);
 120.219 +void set_page_address(struct page_info *page, void *virtual);
 120.220  void page_address_init(void);
 120.221  #endif
 120.222  
 120.223 @@ -400,7 +407,7 @@ void page_address_init(void);
 120.224  
 120.225  #ifndef CONFIG_DEBUG_PAGEALLOC
 120.226  static inline void
 120.227 -kernel_map_pages(struct page *page, int numpages, int enable)
 120.228 +kernel_map_pages(struct page_info *page, int numpages, int enable)
 120.229  {
 120.230  }
 120.231  #endif
 120.232 @@ -415,8 +422,8 @@ extern unsigned long lookup_domain_mpa(s
 120.233  #undef machine_to_phys_mapping
 120.234  #define machine_to_phys_mapping	mpt_table
 120.235  
 120.236 -#define INVALID_M2P_ENTRY        (~0U)
 120.237 -#define VALID_M2P(_e)            (!((_e) & (1U<<63)))
 120.238 +#define INVALID_M2P_ENTRY        (~0UL)
 120.239 +#define VALID_M2P(_e)            (!((_e) & (1UL<<63)))
 120.240  #define IS_INVALID_M2P_ENTRY(_e) (!VALID_M2P(_e))
 120.241  
 120.242  #define set_gpfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn))
 120.243 @@ -463,4 +470,6 @@ extern unsigned long lookup_domain_mpa(s
 120.244  /* Arch-specific portion of memory_op hypercall. */
 120.245  #define arch_memory_op(op, arg) (-ENOSYS)
 120.246  
 120.247 +extern void assign_domain_page(struct domain *d, unsigned long mpaddr,
 120.248 +			       unsigned long physaddr);
 120.249  #endif /* __ASM_IA64_MM_H__ */
   121.1 --- a/xen/include/asm-ia64/regionreg.h	Mon Mar 20 09:56:46 2006 +0100
   121.2 +++ b/xen/include/asm-ia64/regionreg.h	Mon Mar 20 09:56:54 2006 +0100
   121.3 @@ -64,4 +64,13 @@ vmMangleRID(unsigned long RIDVal)
   121.4  // since vmMangleRID is symmetric, use it for unmangling also
   121.5  #define vmUnmangleRID(x)	vmMangleRID(x)
   121.6  
   121.7 +extern unsigned long allocate_metaphysical_rr(void);
   121.8 +
   121.9 +struct domain;
  121.10 +extern int allocate_rid_range(struct domain *d, unsigned long ridbits);
  121.11 +extern int deallocate_rid_range(struct domain *d);
  121.12 +
  121.13 +struct vcpu;
  121.14 +extern void init_all_rr(struct vcpu *v);
  121.15 +
  121.16  #endif		/* !_REGIONREG_H_ */
   122.1 --- a/xen/include/asm-ia64/vcpu.h	Mon Mar 20 09:56:46 2006 +0100
   122.2 +++ b/xen/include/asm-ia64/vcpu.h	Mon Mar 20 09:56:54 2006 +0100
   122.3 @@ -7,7 +7,6 @@
   122.4  //#include "thread.h"
   122.5  #include <asm/ia64_int.h>
   122.6  #include <public/arch-ia64.h>
   122.7 -
   122.8  typedef	unsigned long UINT64;
   122.9  typedef	unsigned int UINT;
  122.10  typedef	int BOOLEAN;
  122.11 @@ -16,7 +15,10 @@ typedef	struct vcpu VCPU;
  122.12  
  122.13  typedef cpu_user_regs_t REGS;
  122.14  
  122.15 -#define VCPU(_v,_x)	_v->arch.privregs->_x
  122.16 +
  122.17 +#define VCPU(_v,_x)	(_v->arch.privregs->_x)
  122.18 +#define PSCB(_v,_x) VCPU(_v,_x)
  122.19 +#define PSCBX(_v,_x) (_v->arch._x)
  122.20  
  122.21  #define PRIVOP_ADDR_COUNT
  122.22  #ifdef PRIVOP_ADDR_COUNT
  122.23 @@ -140,7 +142,9 @@ extern IA64FAULT vcpu_ptc_g(VCPU *vcpu, 
  122.24  extern IA64FAULT vcpu_ptc_ga(VCPU *vcpu, UINT64 vadr, UINT64 addr_range);
  122.25  extern IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
  122.26  extern IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr, UINT64 addr_range);
  122.27 -extern IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha);
  122.28 +extern IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address,
  122.29 +				BOOLEAN is_data, BOOLEAN in_tpa,
  122.30 +				UINT64 *pteval, UINT64 *itir, UINT64 *iha);
  122.31  extern IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr);
  122.32  extern IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa);
  122.33  extern IA64FAULT vcpu_fc(VCPU *vcpu, UINT64 vadr);
  122.34 @@ -173,4 +177,18 @@ itir_mask(UINT64 itir)
  122.35      return (~((1UL << itir_ps(itir)) - 1));
  122.36  }
  122.37  
  122.38 +#define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0)
  122.39 +
  122.40 +//#define vcpu_quick_region_check(_tr_regions,_ifa) 1
  122.41 +#define vcpu_quick_region_check(_tr_regions,_ifa)           \
  122.42 +    (_tr_regions & (1 << ((unsigned long)_ifa >> 61)))
  122.43 +#define vcpu_quick_region_set(_tr_regions,_ifa)             \
  122.44 +    do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0)
  122.45 +
  122.46 +// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
  122.47 +#define vcpu_match_tr_entry(_trp,_ifa,_rid)             \
  122.48 +    ((_trp->p && (_trp->rid==_rid) && (_ifa >= _trp->vadr) &&   \
  122.49 +    (_ifa < (_trp->vadr + (1L<< _trp->ps)) - 1)))
  122.50 +
  122.51 +
  122.52  #endif
   123.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.2 +++ b/xen/include/asm-ia64/vlsapic.h	Mon Mar 20 09:56:54 2006 +0100
   123.3 @@ -0,0 +1,35 @@
   123.4 +
   123.5 +
   123.6 +/* -*-  Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
   123.7 +/*
   123.8 + * Copyright (c) 2004, Intel Corporation.
   123.9 + *
  123.10 + * This program is free software; you can redistribute it and/or modify it
  123.11 + * under the terms and conditions of the GNU General Public License,
  123.12 + * version 2, as published by the Free Software Foundation.
  123.13 + *
  123.14 + * This program is distributed in the hope it will be useful, but WITHOUT
  123.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  123.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  123.17 + * more details.
  123.18 + *
  123.19 + * You should have received a copy of the GNU General Public License along with
  123.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  123.21 + * Place - Suite 330, Boston, MA 02111-1307 USA.
  123.22 + *
  123.23 + * 
  123.24 + */
  123.25 +
  123.26 +#ifndef _LSAPIC_H
  123.27 +#define _LSAPIC_H
  123.28 +#include <xen/sched.h>
  123.29 +
  123.30 +extern void vmx_virq_line_init(struct domain *d);
  123.31 +extern void vtm_init(struct vcpu *vcpu);
  123.32 +extern void vtm_set_itc(struct  vcpu *vcpu, uint64_t new_itc);
  123.33 +extern void vtm_set_itm(struct vcpu *vcpu, uint64_t val);
  123.34 +extern void vtm_set_itv(struct vcpu *vcpu, uint64_t val);
  123.35 +extern void vmx_vexirq(struct vcpu  *vcpu);
  123.36 +extern void vhpi_detection(struct vcpu *vcpu);
  123.37 +
  123.38 +#endif
   124.1 --- a/xen/include/asm-ia64/vmmu.h	Mon Mar 20 09:56:46 2006 +0100
   124.2 +++ b/xen/include/asm-ia64/vmmu.h	Mon Mar 20 09:56:54 2006 +0100
   124.3 @@ -68,11 +68,14 @@ typedef union search_section {
   124.4  } search_section_t;
   124.5  
   124.6  
   124.7 -typedef enum {
   124.8 +enum {
   124.9          ISIDE_TLB=0,
  124.10          DSIDE_TLB=1
  124.11 -} CACHE_LINE_TYPE;
  124.12 -
  124.13 +};
  124.14 +#define VTLB_PTE_P_BIT      0
  124.15 +#define VTLB_PTE_IO_BIT     60
  124.16 +#define VTLB_PTE_IO         (1UL<<VTLB_PTE_IO_BIT)
  124.17 +#define VTLB_PTE_P         (1UL<<VTLB_PTE_P_BIT)
  124.18  typedef struct thash_data {
  124.19      union {
  124.20          struct {
  124.21 @@ -86,18 +89,16 @@ typedef struct thash_data {
  124.22              u64 ppn  : 38; // 12-49
  124.23              u64 rv2  :  2; // 50-51
  124.24              u64 ed   :  1; // 52
  124.25 -            u64 ig1  :  3; // 53-55
  124.26 -            u64 len  :  4; // 56-59
  124.27 -            u64 ig2  :  3; // 60-63
  124.28 +            u64 ig1  :  3; // 53-63
  124.29          };
  124.30          struct {
  124.31              u64 __rv1 : 53;	// 0-52
  124.32              u64 contiguous : 1; //53
  124.33              u64 tc : 1;     // 54 TR or TC
  124.34 -            CACHE_LINE_TYPE cl : 1; // 55 I side or D side cache line
  124.35 +            u64 cl : 1; // 55 I side or D side cache line
  124.36              // next extension to ig1, only for TLB instance
  124.37 -            u64 __ig1  :  4; // 56-59
  124.38 -            u64 locked  : 1;	// 60 entry locked or not
  124.39 +            u64 len  :  4; // 56-59
  124.40 +            u64 io  : 1;	// 60 entry is for io or not
  124.41              u64 nomap : 1;   // 61 entry cann't be inserted into machine TLB.
  124.42              u64 checked : 1; // 62 for VTLB/VHPT sanity check
  124.43              u64 invalid : 1; // 63 invalid entry
  124.44 @@ -112,12 +113,12 @@ typedef struct thash_data {
  124.45              u64 key  : 24; // 8-31
  124.46              u64 rv4  : 32; // 32-63
  124.47          };
  124.48 -        struct {
  124.49 -            u64 __rv3  : 32; // 0-31
  124.50 +//        struct {
  124.51 +//            u64 __rv3  : 32; // 0-31
  124.52              // next extension to rv4
  124.53 -            u64 rid  : 24;  // 32-55
  124.54 -            u64 __rv4  : 8; // 56-63
  124.55 -        };
  124.56 +//            u64 rid  : 24;  // 32-55
  124.57 +//            u64 __rv4  : 8; // 56-63
  124.58 +//        };
  124.59          u64 itir;
  124.60      };
  124.61      union {
  124.62 @@ -136,7 +137,8 @@ typedef struct thash_data {
  124.63      };
  124.64      union {
  124.65          struct thash_data *next;
  124.66 -        u64  tr_idx;
  124.67 +        u64  rid;  // only used in guest TR
  124.68 +//        u64  tr_idx;
  124.69      };
  124.70  } thash_data_t;
  124.71  
  124.72 @@ -152,7 +154,7 @@ typedef struct thash_data {
  124.73  
  124.74  #define INVALID_VHPT(hdata)     ((hdata)->ti)
  124.75  #define INVALID_TLB(hdata)      ((hdata)->ti)
  124.76 -#define INVALID_TR(hdata)      ((hdata)->invalid)
  124.77 +#define INVALID_TR(hdata)      (!(hdata)->p)
  124.78  #define INVALID_ENTRY(hcb, hdata)       INVALID_VHPT(hdata)
  124.79  
  124.80  /*        ((hcb)->ht==THASH_TLB ? INVALID_TLB(hdata) : INVALID_VHPT(hdata)) */
  124.81 @@ -199,18 +201,18 @@ typedef thash_data_t *(FIND_NEXT_OVL_FN)
  124.82  typedef void (REM_THASH_FN)(struct thash_cb *hcb, thash_data_t *entry);
  124.83  typedef void (INS_THASH_FN)(struct thash_cb *hcb, thash_data_t *entry, u64 va);
  124.84  
  124.85 -typedef struct tlb_special {
  124.86 -        thash_data_t     itr[NITRS];
  124.87 -        thash_data_t     dtr[NDTRS];
  124.88 -        struct thash_cb  *vhpt;
  124.89 -} tlb_special_t;
  124.90 +//typedef struct tlb_special {
  124.91 +//        thash_data_t     itr[NITRS];
  124.92 +//        thash_data_t     dtr[NDTRS];
  124.93 +//        struct thash_cb  *vhpt;
  124.94 +//} tlb_special_t;
  124.95  
  124.96  //typedef struct vhpt_cb {
  124.97          //u64     pta;    // pta value.
  124.98  //        GET_MFN_FN      *get_mfn;
  124.99  //        TTAG_FN         *tag_func;
 124.100  //} vhpt_special;
 124.101 -
 124.102 +/*
 124.103  typedef struct thash_internal {
 124.104          thash_data_t *hash_base;
 124.105          thash_data_t *cur_cch;  // head of overlap search
 124.106 @@ -227,7 +229,7 @@ typedef struct thash_internal {
 124.107          u64     _curva;         // current address to search
 124.108          u64     _eva;
 124.109  } thash_internal_t;
 124.110 -
 124.111 + */
 124.112  #define  THASH_CB_MAGIC         0x55aa00aa55aa55aaUL
 124.113  typedef struct thash_cb {
 124.114          /* THASH base information */
 124.115 @@ -243,6 +245,7 @@ typedef struct thash_cb {
 124.116          thash_cch_mem_t *cch_freelist;
 124.117          struct vcpu *vcpu;
 124.118          PTA     pta;
 124.119 +        struct thash_cb *vhpt;
 124.120          /* VTLB/VHPT common information */
 124.121  //        FIND_OVERLAP_FN *find_overlap;
 124.122  //        FIND_NEXT_OVL_FN *next_overlap;
 124.123 @@ -251,15 +254,15 @@ typedef struct thash_cb {
 124.124  //        REM_NOTIFIER_FN *remove_notifier;
 124.125          /* private information */
 124.126  //        thash_internal_t  priv;
 124.127 -        union {
 124.128 -                tlb_special_t  *ts;
 124.129 +//        union {
 124.130 +//                tlb_special_t  *ts;
 124.131  //                vhpt_special   *vs;
 124.132 -        };
 124.133 +//        };
 124.134          // Internal positon information, buffer and storage etc. TBD
 124.135  } thash_cb_t;
 124.136  
 124.137 -#define ITR(hcb,id)             ((hcb)->ts->itr[id])
 124.138 -#define DTR(hcb,id)             ((hcb)->ts->dtr[id])
 124.139 +//#define ITR(hcb,id)             ((hcb)->ts->itr[id])
 124.140 +//#define DTR(hcb,id)             ((hcb)->ts->dtr[id])
 124.141  #define INVALIDATE_HASH_HEADER(hcb,hash)    INVALIDATE_TLB_HEADER(hash)
 124.142  /*              \
 124.143  {           if ((hcb)->ht==THASH_TLB){            \
 124.144 @@ -290,10 +293,10 @@ extern void thash_init(thash_cb_t *hcb, 
 124.145   *      4: Return the entry in hash table or collision chain.
 124.146   *
 124.147   */
 124.148 -extern void thash_vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va);
 124.149 +extern void thash_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa);
 124.150  //extern void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va);
 124.151 -extern void thash_tr_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va, int idx);
 124.152 -extern thash_data_t *vtr_find_overlap(thash_cb_t *hcb, thash_data_t *data, char cl);
 124.153 +//extern void thash_tr_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va, int idx);
 124.154 +extern int vtr_find_overlap(struct vcpu *vcpu, u64 va, u64 ps, int is_data);
 124.155  extern u64 get_mfn(struct domain *d, u64 gpfn);
 124.156  /*
 124.157   * Force to delete a found entry no matter TR or foreign map for TLB.
 124.158 @@ -344,13 +347,8 @@ extern thash_data_t *thash_find_next_ove
 124.159   *    NOTES:
 124.160   *
 124.161   */
 124.162 -extern void thash_purge_entries(thash_cb_t *hcb, 
 124.163 -                        thash_data_t *in, search_section_t p_sect);
 124.164 -extern void thash_purge_entries_ex(thash_cb_t *hcb,
 124.165 -                        u64 rid, u64 va, u64 sz, 
 124.166 -                        search_section_t p_sect, 
 124.167 -                        CACHE_LINE_TYPE cl);
 124.168 -extern void thash_purge_and_insert(thash_cb_t *hcb, thash_data_t *in, u64 va);
 124.169 +extern void thash_purge_entries(thash_cb_t *hcb, u64 va, u64 ps);
 124.170 +extern void thash_purge_and_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa);
 124.171  
 124.172  /*
 124.173   * Purge all TCs or VHPT entries including those in Hash table.
 124.174 @@ -363,10 +361,7 @@ extern void thash_purge_all(thash_cb_t *
 124.175