ia64/xen-unstable

changeset 14025:d907467f08cd

merge with xen-unstable.hg
author awilliam@xenbuild2.aw
date Tue Feb 20 12:58:22 2007 -0700 (2007-02-20)
parents 04c23c1ef888 ecb6cd61a9cf
children 409e94d0a35b
files linux-2.6-xen-sparse/drivers/char/tpm/tpm.c linux-2.6-xen-sparse/include/linux/pfn.h tools/libxc/xc_linux_build.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c xen/arch/ia64/xen/domain.c xen/common/elf.c
line diff
     1.1 --- a/extras/mini-os/Makefile	Sun Feb 18 16:13:13 2007 -0700
     1.2 +++ b/extras/mini-os/Makefile	Tue Feb 20 12:58:22 2007 -0700
     1.3 @@ -44,10 +44,6 @@ ARCH_LINKS =
     1.4  # This can be overwritten from arch specific rules.
     1.5  EXTRA_INC =
     1.6  
     1.7 -# Special build dependencies.
     1.8 -# Build all after touching this/these file(s) (see minios.mk)
     1.9 -SPEC_DEPENDS = minios.mk
    1.10 -
    1.11  # Include the architecture family's special makerules.
    1.12  # This must be before include minios.mk!
    1.13  include $(TARGET_ARCH_DIR)/arch.mk
    1.14 @@ -57,7 +53,6 @@ include minios.mk
    1.15  
    1.16  # Define some default flags for linking.
    1.17  LDLIBS := 
    1.18 -LDFLAGS := 
    1.19  LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
    1.20  LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
    1.21  
     2.1 --- a/extras/mini-os/arch/x86/Makefile	Sun Feb 18 16:13:13 2007 -0700
     2.2 +++ b/extras/mini-os/arch/x86/Makefile	Tue Feb 20 12:58:22 2007 -0700
     2.3 @@ -3,9 +3,6 @@
     2.4  # It's is used for x86_32, x86_32y and x86_64
     2.5  #
     2.6  
     2.7 -# Rebuild all after touching this/these extra file(s) (see mini-os.mk)
     2.8 -SPEC_DEP = arch.mk
     2.9 -
    2.10  # include arch.mk has to be before mini-os.mk!
    2.11  include arch.mk
    2.12  include ../../minios.mk
    2.13 @@ -25,5 +22,5 @@ all: $(ARCH_LIB)
    2.14  	$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
    2.15  
    2.16  clean:
    2.17 -	rm -f $(ARCH_LIB) $(ARCH_OBJS)
    2.18 +	rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
    2.19  
     3.1 --- a/extras/mini-os/arch/x86/arch.mk	Sun Feb 18 16:13:13 2007 -0700
     3.2 +++ b/extras/mini-os/arch/x86/arch.mk	Tue Feb 20 12:58:22 2007 -0700
     3.3 @@ -6,6 +6,7 @@
     3.4  ifeq ($(TARGET_ARCH),x86_32)
     3.5  ARCH_CFLAGS  := -m32 -march=i686
     3.6  ARCH_LDFLAGS := -m elf_i386
     3.7 +ARCH_ASFLAGS := -m32
     3.8  EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
     3.9  EXTRA_SRC += arch/$(EXTRA_INC)
    3.10  endif
    3.11 @@ -19,10 +20,10 @@ endif
    3.12  
    3.13  ifeq ($(TARGET_ARCH),x86_64)
    3.14  ARCH_CFLAGS := -m64 -mno-red-zone -fpic -fno-reorder-blocks
    3.15 -ARCH_CFLAGS := -fno-asynchronous-unwind-tables
    3.16 +ARCH_CFLAGS += -fno-asynchronous-unwind-tables
    3.17 +ARCH_ASFLAGS := -m64
    3.18  ARCH_LDFLAGS := -m elf_x86_64
    3.19  EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
    3.20  EXTRA_SRC += arch/$(EXTRA_INC)
    3.21  endif
    3.22  
    3.23 -
     4.1 --- a/extras/mini-os/minios.mk	Sun Feb 18 16:13:13 2007 -0700
     4.2 +++ b/extras/mini-os/minios.mk	Tue Feb 20 12:58:22 2007 -0700
     4.3 @@ -11,6 +11,7 @@ DEF_CFLAGS += -Wstrict-prototypes -Wnest
     4.4  DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
     4.5  
     4.6  DEF_ASFLAGS = -D__ASSEMBLY__
     4.7 +DEF_LDFLAGS =
     4.8  
     4.9  ifeq ($(debug),y)
    4.10  DEF_CFLAGS += -g
    4.11 @@ -23,21 +24,27 @@ endif
    4.12  # ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
    4.13  CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
    4.14  ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
    4.15 +LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
    4.16  
    4.17  # The path pointing to the architecture specific header files.
    4.18 -ARCH_SPEC_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
    4.19 +ARCH_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
    4.20 +
    4.21 +# Special build dependencies.
    4.22 +# Rebuild all after touching this/these file(s)
    4.23 +EXTRA_DEPS = $(MINI-OS_ROOT)/minios.mk \
    4.24 +		$(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk
    4.25  
    4.26  # Find all header files for checking dependencies.
    4.27  HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h)
    4.28  HDRS += $(wildcard $(MINI-OS_ROOT)/include/xen/*.h)
    4.29 -HDRS += $(wildcard $(ARCH_SPEC_INC)/*.h)
    4.30 +HDRS += $(wildcard $(ARCH_INC)/*.h)
    4.31  # For special wanted header directories.
    4.32  extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
    4.33  HDRS += $(extra_heads)
    4.34  
    4.35  # Add the special header directories to the include paths.
    4.36  extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
    4.37 -override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_SPEC_INC)	$(extra_incl)
    4.38 +override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_INC)	$(extra_incl)
    4.39  
    4.40  # The name of the architecture specific library.
    4.41  # This is on x86_32: libx86_32.a
    4.42 @@ -51,10 +58,10 @@ HEAD_ARCH_OBJ := $(TARGET_ARCH).o
    4.43  HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
    4.44  
    4.45  
    4.46 -%.o: %.c $(HDRS) Makefile $(SPEC_DEPENDS)
    4.47 +%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
    4.48  	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
    4.49  
    4.50 -%.o: %.S $(HDRS) Makefile $(SPEC_DEPENDS)
    4.51 +%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
    4.52  	$(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
    4.53  
    4.54  
     5.1 --- a/extras/mini-os/xenbus/xenbus.c	Sun Feb 18 16:13:13 2007 -0700
     5.2 +++ b/extras/mini-os/xenbus/xenbus.c	Tue Feb 20 12:58:22 2007 -0700
     5.3 @@ -210,7 +210,7 @@ static int allocate_xenbus_id(void)
     5.4      }
     5.5      nr_live_reqs++;
     5.6      req_info[o_probe].in_use = 1;
     5.7 -    probe = o_probe + 1;
     5.8 +    probe = (o_probe + 1) % NR_REQS;
     5.9      spin_unlock(&req_lock);
    5.10      init_waitqueue_head(&req_info[o_probe].waitq);
    5.11  
     6.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile	Sun Feb 18 16:13:13 2007 -0700
     6.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile	Tue Feb 20 12:58:22 2007 -0700
     6.3 @@ -98,4 +98,5 @@ n-obj-xen := i8259.o timers/ reboot.o sm
     6.4  obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
     6.5  obj-y := $(call cherrypickxen, $(obj-y))
     6.6  extra-y := $(call cherrypickxen, $(extra-y))
     6.7 +%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
     6.8  endif
     7.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Sun Feb 18 16:13:13 2007 -0700
     7.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Tue Feb 20 12:58:22 2007 -0700
     7.3 @@ -12,6 +12,8 @@
     7.4  #include <xen/interface/xen.h>
     7.5  #include <xen/interface/elfnote.h>
     7.6  
     7.7 +#define _PAGE_PRESENT 0x1
     7.8 +
     7.9  /*
    7.10   * References to members of the new_cpu_data structure.
    7.11   */
    7.12 @@ -198,7 +200,9 @@ ENTRY(cpu_gdt_table)
    7.13  	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
    7.14  #ifdef CONFIG_X86_PAE
    7.15  	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
    7.16 +	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .quad,  _PAGE_PRESENT,_PAGE_PRESENT)
    7.17  #else
    7.18  	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
    7.19 +	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  _PAGE_PRESENT,_PAGE_PRESENT)
    7.20  #endif
    7.21  	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
     8.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Sun Feb 18 16:13:13 2007 -0700
     8.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Tue Feb 20 12:58:22 2007 -0700
     8.3 @@ -1034,8 +1034,16 @@ e820_all_mapped(unsigned long s, unsigne
     8.4  	u64 start = s;
     8.5  	u64 end = e;
     8.6  	int i;
     8.7 +
     8.8 +#ifndef CONFIG_XEN
     8.9  	for (i = 0; i < e820.nr_map; i++) {
    8.10  		struct e820entry *ei = &e820.map[i];
    8.11 +#else
    8.12 +	if (!is_initial_xendomain())
    8.13 +		return 0;
    8.14 +	for (i = 0; i < machine_e820.nr_map; ++i) {
    8.15 +		const struct e820entry *ei = &machine_e820.map[i];
    8.16 +#endif
    8.17  		if (type && ei->type != type)
    8.18  			continue;
    8.19  		/* is the region (part) in overlap with the current region ?*/
    8.20 @@ -1505,9 +1513,6 @@ e820_setup_gap(struct e820entry *e820, i
    8.21   */
    8.22  static int __init request_standard_resources(void)
    8.23  {
    8.24 -#ifdef CONFIG_XEN
    8.25 -	struct xen_memory_map memmap;
    8.26 -#endif
    8.27  	int	      i;
    8.28  
    8.29  	/* Nothing to do if not running in dom0. */
    8.30 @@ -1516,13 +1521,6 @@ static int __init request_standard_resou
    8.31  
    8.32  	printk("Setting up standard PCI resources\n");
    8.33  #ifdef CONFIG_XEN
    8.34 -	memmap.nr_entries = E820MAX;
    8.35 -	set_xen_guest_handle(memmap.buffer, machine_e820.map);
    8.36 -
    8.37 -	if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
    8.38 -		BUG();
    8.39 -	machine_e820.nr_map = memmap.nr_entries;
    8.40 -
    8.41  	legacy_init_iomem_resources(machine_e820.map, machine_e820.nr_map,
    8.42  				    &code_resource, &data_resource);
    8.43  #else
    8.44 @@ -1546,12 +1544,22 @@ subsys_initcall(request_standard_resourc
    8.45  
    8.46  static void __init register_memory(void)
    8.47  {
    8.48 -
    8.49  #ifdef CONFIG_XEN
    8.50 -	e820_setup_gap(machine_e820.map, machine_e820.nr_map);
    8.51 -#else
    8.52 -	e820_setup_gap(e820.map, e820.nr_map);
    8.53 +	if (is_initial_xendomain()) {
    8.54 +		struct xen_memory_map memmap;
    8.55 +
    8.56 +		memmap.nr_entries = E820MAX;
    8.57 +		set_xen_guest_handle(memmap.buffer, machine_e820.map);
    8.58 +
    8.59 +		if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
    8.60 +			BUG();
    8.61 +
    8.62 +		machine_e820.nr_map = memmap.nr_entries;
    8.63 +		e820_setup_gap(machine_e820.map, machine_e820.nr_map);
    8.64 +	}
    8.65 +	else
    8.66  #endif
    8.67 +		e820_setup_gap(e820.map, e820.nr_map);
    8.68  }
    8.69  
    8.70  #ifdef CONFIG_MCA
     9.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Sun Feb 18 16:13:13 2007 -0700
     9.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Tue Feb 20 12:58:22 2007 -0700
     9.3 @@ -222,8 +222,7 @@ int read_current_timer(unsigned long *ti
     9.4  void init_cpu_khz(void)
     9.5  {
     9.6  	u64 __cpu_khz = 1000000ULL << 32;
     9.7 -	struct vcpu_time_info *info;
     9.8 -	info = &HYPERVISOR_shared_info->vcpu_info[0].time;
     9.9 +	struct vcpu_time_info *info = &vcpu_info(0)->time;
    9.10  	do_div(__cpu_khz, info->tsc_to_system_mul);
    9.11  	if (info->tsc_shift < 0)
    9.12  		cpu_khz = __cpu_khz << -info->tsc_shift;
    9.13 @@ -293,14 +292,13 @@ static void update_wallclock(void)
    9.14   * Reads a consistent set of time-base values from Xen, into a shadow data
    9.15   * area.
    9.16   */
    9.17 -static void get_time_values_from_xen(void)
    9.18 +static void get_time_values_from_xen(int cpu)
    9.19  {
    9.20 -	shared_info_t           *s = HYPERVISOR_shared_info;
    9.21  	struct vcpu_time_info   *src;
    9.22  	struct shadow_time_info *dst;
    9.23  
    9.24 -	src = &s->vcpu_info[smp_processor_id()].time;
    9.25 -	dst = &per_cpu(shadow_time, smp_processor_id());
    9.26 +	src = &vcpu_info(cpu)->time;
    9.27 +	dst = &per_cpu(shadow_time, cpu);
    9.28  
    9.29  	do {
    9.30  		dst->version = src->version;
    9.31 @@ -320,7 +318,7 @@ static inline int time_values_up_to_date
    9.32  	struct vcpu_time_info   *src;
    9.33  	struct shadow_time_info *dst;
    9.34  
    9.35 -	src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
    9.36 +	src = &vcpu_info(cpu)->time;
    9.37  	dst = &per_cpu(shadow_time, cpu);
    9.38  
    9.39  	rmb();
    9.40 @@ -412,7 +410,7 @@ void do_gettimeofday(struct timeval *tv)
    9.41  			 * overflowed). Detect that and recalculate
    9.42  			 * with fresh values.
    9.43  			 */
    9.44 -			get_time_values_from_xen();
    9.45 +			get_time_values_from_xen(cpu);
    9.46  			continue;
    9.47  		}
    9.48  	} while (read_seqretry(&xtime_lock, seq) ||
    9.49 @@ -456,7 +454,7 @@ int do_settimeofday(struct timespec *tv)
    9.50  		nsec = tv->tv_nsec - get_nsec_offset(shadow);
    9.51  		if (time_values_up_to_date(cpu))
    9.52  			break;
    9.53 -		get_time_values_from_xen();
    9.54 +		get_time_values_from_xen(cpu);
    9.55  	}
    9.56  	sec = tv->tv_sec;
    9.57  	__normalize_time(&sec, &nsec);
    9.58 @@ -551,7 +549,7 @@ unsigned long long monotonic_clock(void)
    9.59  		barrier();
    9.60  		time = shadow->system_timestamp + get_nsec_offset(shadow);
    9.61  		if (!time_values_up_to_date(cpu))
    9.62 -			get_time_values_from_xen();
    9.63 +			get_time_values_from_xen(cpu);
    9.64  		barrier();
    9.65  	} while (local_time_version != shadow->version);
    9.66  
    9.67 @@ -621,7 +619,7 @@ irqreturn_t timer_interrupt(int irq, voi
    9.68  	write_seqlock(&xtime_lock);
    9.69  
    9.70  	do {
    9.71 -		get_time_values_from_xen();
    9.72 +		get_time_values_from_xen(cpu);
    9.73  
    9.74  		/* Obtain a consistent snapshot of elapsed wallclock cycles. */
    9.75  		delta = delta_cpu =
    9.76 @@ -708,7 +706,7 @@ irqreturn_t timer_interrupt(int irq, voi
    9.77  	if (delta_cpu > 0) {
    9.78  		do_div(delta_cpu, NS_PER_TICK);
    9.79  		per_cpu(processed_system_time, cpu) += delta_cpu * NS_PER_TICK;
    9.80 -		if (user_mode(regs))
    9.81 +		if (user_mode_vm(regs))
    9.82  			account_user_time(current, (cputime_t)delta_cpu);
    9.83  		else
    9.84  			account_system_time(current, HARDIRQ_OFFSET,
    9.85 @@ -722,7 +720,7 @@ irqreturn_t timer_interrupt(int irq, voi
    9.86  	/* Local timer processing (see update_process_times()). */
    9.87  	run_local_timers();
    9.88  	if (rcu_pending(cpu))
    9.89 -		rcu_check_callbacks(cpu, user_mode(regs));
    9.90 +		rcu_check_callbacks(cpu, user_mode_vm(regs));
    9.91  	scheduler_tick();
    9.92  	run_posix_cpu_timers(current);
    9.93  	profile_tick(CPU_PROFILING, regs);
    9.94 @@ -921,7 +919,7 @@ void __init time_init(void)
    9.95  		return;
    9.96  	}
    9.97  #endif
    9.98 -	get_time_values_from_xen();
    9.99 +	get_time_values_from_xen(0);
   9.100  
   9.101  	processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
   9.102  	per_cpu(processed_system_time, 0) = processed_system_time;
   9.103 @@ -1029,7 +1027,7 @@ void time_resume(void)
   9.104  {
   9.105  	init_cpu_khz();
   9.106  
   9.107 -	get_time_values_from_xen();
   9.108 +	get_time_values_from_xen(0);
   9.109  
   9.110  	processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
   9.111  	per_cpu(processed_system_time, 0) = processed_system_time;
    10.1 --- a/linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c	Sun Feb 18 16:13:13 2007 -0700
    10.2 +++ b/linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c	Tue Feb 20 12:58:22 2007 -0700
    10.3 @@ -67,7 +67,7 @@ char * __init machine_specific_memory_se
    10.4  	if ( rc == -ENOSYS ) {
    10.5  		memmap.nr_entries = 1;
    10.6  		map[0].addr = 0ULL;
    10.7 -		map[0].size = PFN_PHYS(xen_start_info->nr_pages);
    10.8 +		map[0].size = PFN_PHYS((unsigned long long)xen_start_info->nr_pages);
    10.9  		/* 8MB slack (to balance backend allocations). */
   10.10  		map[0].size += 8ULL << 20;
   10.11  		map[0].type = E820_RAM;
    11.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c	Sun Feb 18 16:13:13 2007 -0700
    11.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c	Tue Feb 20 12:58:22 2007 -0700
    11.3 @@ -731,7 +731,7 @@ do_sigbus:
    11.4  	force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
    11.5  }
    11.6  
    11.7 -#ifndef CONFIG_X86_PAE
    11.8 +#if !HAVE_SHARED_KERNEL_PMD
    11.9  void vmalloc_sync_all(void)
   11.10  {
   11.11  	/*
    12.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/util.c	Sun Feb 18 16:13:13 2007 -0700
    12.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/util.c	Tue Feb 20 12:58:22 2007 -0700
    12.3 @@ -95,18 +95,6 @@ void free_vm_area(struct vm_struct *area
    12.4  }
    12.5  EXPORT_SYMBOL_GPL(free_vm_area);
    12.6  
    12.7 -void lock_vm_area(struct vm_struct *area)
    12.8 -{
    12.9 -	// nothing
   12.10 -}
   12.11 -EXPORT_SYMBOL_GPL(lock_vm_area);
   12.12 -
   12.13 -void unlock_vm_area(struct vm_struct *area)
   12.14 -{
   12.15 -	// nothing
   12.16 -}
   12.17 -EXPORT_SYMBOL_GPL(unlock_vm_area);
   12.18 -
   12.19  /*
   12.20   * Local variables:
   12.21   *  c-file-style: "linux"
    13.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile	Sun Feb 18 16:13:13 2007 -0700
    13.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile	Tue Feb 20 12:58:22 2007 -0700
    13.3 @@ -72,4 +72,5 @@ include $(srctree)/scripts/Makefile.xen
    13.4  obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
    13.5  obj-y := $(call cherrypickxen, $(obj-y))
    13.6  extra-y := $(call cherrypickxen, $(extra-y))
    13.7 +%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
    13.8  endif
    14.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Sun Feb 18 16:13:13 2007 -0700
    14.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Tue Feb 20 12:58:22 2007 -0700
    14.3 @@ -127,8 +127,19 @@ e820_any_mapped(unsigned long start, uns
    14.4  int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
    14.5  {
    14.6  	int i;
    14.7 +
    14.8 +#ifndef CONFIG_XEN
    14.9  	for (i = 0; i < e820.nr_map; i++) {
   14.10  		struct e820entry *ei = &e820.map[i];
   14.11 +#else
   14.12 +	extern struct e820map machine_e820;
   14.13 +
   14.14 +	if (!is_initial_xendomain())
   14.15 +		return 0;
   14.16 +	for (i = 0; i < machine_e820.nr_map; i++) {
   14.17 +		const struct e820entry *ei = &machine_e820.map[i];
   14.18 +#endif
   14.19 +
   14.20  		if (type && ei->type != type)
   14.21  			continue;
   14.22  		/* is the region (part) in overlap with the current region ?*/
    15.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c	Sun Feb 18 16:13:13 2007 -0700
    15.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c	Tue Feb 20 12:58:22 2007 -0700
    15.3 @@ -18,9 +18,8 @@
    15.4  #define VGABASE		((void __iomem *)0xffffffff800b8000UL)
    15.5  #endif
    15.6  
    15.7 +#ifndef CONFIG_XEN
    15.8  static int max_ypos = 25, max_xpos = 80;
    15.9 -
   15.10 -#ifndef CONFIG_XEN
   15.11  static int current_ypos = 25, current_xpos = 0; 
   15.12  
   15.13  static void early_vga_write(struct console *con, const char *str, unsigned n)
   15.14 @@ -154,10 +153,6 @@ static __init void early_serial_init(cha
   15.15  
   15.16  #else /* CONFIG_XEN */
   15.17  
   15.18 -#undef SCREEN_INFO
   15.19 -#define SCREEN_INFO screen_info
   15.20 -extern struct screen_info screen_info;
   15.21 -
   15.22  static void
   15.23  early_serial_write(struct console *con, const char *s, unsigned count)
   15.24  {
   15.25 @@ -273,11 +268,13 @@ int __init setup_early_printk(char *opt)
   15.26  		early_serial_init(buf);
   15.27  		early_console = &early_serial_console;
   15.28  	} else if (!strncmp(buf, "vga", 3)
   15.29 +#ifndef CONFIG_XEN
   15.30  	           && SCREEN_INFO.orig_video_isVGA == 1) {
   15.31  		max_xpos = SCREEN_INFO.orig_video_cols;
   15.32  		max_ypos = SCREEN_INFO.orig_video_lines;
   15.33 -#ifndef CONFIG_XEN
   15.34  		current_ypos = SCREEN_INFO.orig_y;
   15.35 +#else
   15.36 +	           || !strncmp(buf, "xen", 3)) {
   15.37  #endif
   15.38  		early_console = &early_vga_console;
   15.39   	} else if (!strncmp(buf, "simnow", 6)) {
    16.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Sun Feb 18 16:13:13 2007 -0700
    16.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S	Tue Feb 20 12:58:22 2007 -0700
    16.3 @@ -32,9 +32,6 @@
    16.4   */
    16.5  
    16.6  #define ASSEMBLY 1
    16.7 -#ifdef CONFIG_DEBUG_INFO
    16.8 -#undef CONFIG_DEBUG_INFO
    16.9 -#endif
   16.10  #include <linux/linkage.h>
   16.11  #include <asm/segment.h>
   16.12  #include <asm/smp.h>
   16.13 @@ -537,6 +534,7 @@ END(stub_rt_sigreturn)
   16.14   */ 
   16.15  
   16.16  retint_check:
   16.17 +	CFI_DEFAULT_STACK
   16.18  	movl threadinfo_flags(%rcx),%edx
   16.19  	andl %edi,%edx
   16.20  	CFI_REMEMBER_STATE
    17.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Sun Feb 18 16:13:13 2007 -0700
    17.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Tue Feb 20 12:58:22 2007 -0700
    17.3 @@ -25,7 +25,9 @@
    17.4  
    17.5  #include <xen/interface/elfnote.h>
    17.6  
    17.7 -	.text
    17.8 +#define _PAGE_PRESENT 0x1
    17.9 +
   17.10 +	.section .bootstrap.text, "ax", @progbits
   17.11  	.code64
   17.12  #define VIRT_ENTRY_OFFSET 0x0
   17.13  .org VIRT_ENTRY_OFFSET
   17.14 @@ -49,7 +51,7 @@ ENTRY(_stext)
   17.15  #define NEXT_PAGE(name) \
   17.16  	$page = $page + 1; \
   17.17  	.org $page * 0x1000; \
   17.18 -	phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \
   17.19 +	phys_##name = $page * 0x1000 + __PHYSICAL_START; \
   17.20  ENTRY(name)
   17.21  
   17.22  NEXT_PAGE(init_level4_pgt)
   17.23 @@ -181,5 +183,6 @@ ENTRY(empty_zero_page)
   17.24  #endif /* !CONFIG_XEN_COMPAT_030002 */
   17.25  	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  startup_64)
   17.26  	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
   17.27 +	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .quad,  _PAGE_PRESENT,_PAGE_PRESENT)
   17.28  	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
   17.29  	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
    18.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c	Sun Feb 18 16:13:13 2007 -0700
    18.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c	Tue Feb 20 12:58:22 2007 -0700
    18.3 @@ -170,7 +170,7 @@ static void __cpuinit MP_processor_info 
    18.4  	cpu_set(cpu, cpu_present_map);
    18.5  }
    18.6  #else
    18.7 -void __init MP_processor_info (struct mpc_config_processor *m)
    18.8 +static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
    18.9  {
   18.10  	num_processors++;
   18.11  }
    19.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c	Sun Feb 18 16:13:13 2007 -0700
    19.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c	Tue Feb 20 12:58:22 2007 -0700
    19.3 @@ -499,8 +499,6 @@ static inline void __save_init_fpu( stru
    19.4  	 * This is basically '__unlazy_fpu', except that we queue a
    19.5  	 * multicall to indicate FPU task switch, rather than
    19.6  	 * synchronously trapping to Xen.
    19.7 -	 * This must be here to ensure both math_state_restore() and
    19.8 -	 * kernel_fpu_begin() work consistently. 
    19.9  	 * The AMD workaround requires it to be after DS reload, or
   19.10  	 * after DS has been cleared, which we do in __prepare_arch_switch.
   19.11  	 */
   19.12 @@ -579,7 +577,7 @@ static inline void __save_init_fpu( stru
   19.13  		HYPERVISOR_set_segment_base(SEGBASE_GS_USER, next->gs); 
   19.14  
   19.15  	/* 
   19.16 -	 * Switch the PDA and FPU contexts.
   19.17 +	 * Switch the PDA context.
   19.18  	 */
   19.19  	prev->userrsp = read_pda(oldrsp); 
   19.20  	write_pda(oldrsp, next->userrsp); 
    20.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Sun Feb 18 16:13:13 2007 -0700
    20.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Tue Feb 20 12:58:22 2007 -0700
    20.3 @@ -90,9 +90,6 @@ EXPORT_SYMBOL(HYPERVISOR_shared_info);
    20.4  extern char hypercall_page[PAGE_SIZE];
    20.5  EXPORT_SYMBOL(hypercall_page);
    20.6  
    20.7 -/* Allows setting of maximum possible memory size  */
    20.8 -unsigned long xen_override_max_pfn;
    20.9 -
   20.10  static int xen_panic_event(struct notifier_block *, unsigned long, void *);
   20.11  static struct notifier_block xen_panic_block = {
   20.12  	xen_panic_event, NULL, 0 /* try to go last */
   20.13 @@ -580,13 +577,13 @@ static void discover_ebda(void)
   20.14  	if (ebda_size > 64*1024)
   20.15  		ebda_size = 64*1024;
   20.16  }
   20.17 +#else
   20.18 +#define discover_ebda() ((void)0)
   20.19  #endif
   20.20  
   20.21  void __init setup_arch(char **cmdline_p)
   20.22  {
   20.23  #ifdef CONFIG_XEN
   20.24 -	struct xen_memory_map memmap;
   20.25 -
   20.26  	/* Register a call for panic conditions. */
   20.27  	atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
   20.28  
   20.29 @@ -675,9 +672,7 @@ void __init setup_arch(char **cmdline_p)
   20.30  
   20.31  	check_efer();
   20.32  
   20.33 -#ifndef CONFIG_XEN
   20.34  	discover_ebda();
   20.35 -#endif
   20.36  
   20.37  	init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
   20.38  
   20.39 @@ -719,7 +714,6 @@ void __init setup_arch(char **cmdline_p)
   20.40  	/* reserve ebda region */
   20.41  	if (ebda_addr)
   20.42  		reserve_bootmem_generic(ebda_addr, ebda_size);
   20.43 -#endif
   20.44  
   20.45  #ifdef CONFIG_SMP
   20.46  	/*
   20.47 @@ -732,6 +726,7 @@ void __init setup_arch(char **cmdline_p)
   20.48  	/* Reserve SMP trampoline */
   20.49  	reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE);
   20.50  #endif
   20.51 +#endif
   20.52  
   20.53  #ifdef CONFIG_ACPI_SLEEP
   20.54         /*
   20.55 @@ -895,6 +890,8 @@ void __init setup_arch(char **cmdline_p)
   20.56  	probe_roms();
   20.57  #ifdef CONFIG_XEN
   20.58  	if (is_initial_xendomain()) {
   20.59 +		struct xen_memory_map memmap;
   20.60 +
   20.61  		memmap.nr_entries = E820MAX;
   20.62  		set_xen_guest_handle(memmap.buffer, machine_e820.map);
   20.63  
   20.64 @@ -1378,9 +1375,7 @@ void __cpuinit identify_cpu(struct cpuin
   20.65  			c->x86_capability[2] = cpuid_edx(0x80860001);
   20.66  	}
   20.67  
   20.68 -#ifdef CONFIG_X86_XEN_GENAPIC
   20.69  	c->apicid = phys_pkg_id(0);
   20.70 -#endif
   20.71  
   20.72  	/*
   20.73  	 * Vendor-specific initialization.  In this section we
    21.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c	Sun Feb 18 16:13:13 2007 -0700
    21.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c	Tue Feb 20 12:58:22 2007 -0700
    21.3 @@ -411,8 +411,7 @@ asmlinkage void __kprobes do_page_fault(
    21.4  	prefetchw(&mm->mmap_sem);
    21.5  
    21.6  	/* get the address */
    21.7 -	address = HYPERVISOR_shared_info->vcpu_info[
    21.8 -		smp_processor_id()].arch.cr2;
    21.9 +	address = current_vcpu_info()->arch.cr2;
   21.10  
   21.11  	info.si_code = SEGV_MAPERR;
   21.12  
    22.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Sun Feb 18 16:13:13 2007 -0700
    22.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Feb 20 12:58:22 2007 -0700
    22.3 @@ -77,7 +77,7 @@ extern unsigned long start_pfn;
    22.4  	(((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +	\
    22.5  	__START_KERNEL_map)))
    22.6  
    22.7 -static void early_make_page_readonly(void *va, unsigned int feature)
    22.8 +static void __meminit early_make_page_readonly(void *va, unsigned int feature)
    22.9  {
   22.10  	unsigned long addr, _va = (unsigned long)va;
   22.11  	pte_t pte, *ptep;
   22.12 @@ -279,8 +279,8 @@ static __init void set_pte_phys(unsigned
   22.13  	__flush_tlb_one(vaddr);
   22.14  }
   22.15  
   22.16 -static void set_pte_phys_ma(unsigned long vaddr,
   22.17 -			 unsigned long phys, pgprot_t prot)
   22.18 +static __init void set_pte_phys_ma(unsigned long vaddr,
   22.19 +				   unsigned long phys, pgprot_t prot)
   22.20  {
   22.21  	pgd_t *pgd;
   22.22  	pud_t *pud;
   22.23 @@ -361,9 +361,10 @@ void __init
   22.24  }
   22.25  
   22.26  /*
   22.27 - * At this point it only supports vsyscall area.
   22.28 + * This only supports vsyscall area.
   22.29   */
   22.30 -void __set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
   22.31 +void __init
   22.32 +__set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
   22.33  {
   22.34  	unsigned long address = __fix_to_virt(idx);
   22.35  
   22.36 @@ -377,15 +378,6 @@ void __set_fixmap_user (enum fixed_addre
   22.37  
   22.38  unsigned long __initdata table_start, table_end; 
   22.39  
   22.40 -unsigned long get_machine_pfn(unsigned long addr)
   22.41 -{
   22.42 -	pud_t* pud = pud_offset_k(NULL, addr);
   22.43 -	pmd_t* pmd = pmd_offset(pud, addr);
   22.44 -	pte_t *pte = pte_offset_kernel(pmd, addr);
   22.45 -
   22.46 -	return pte_mfn(*pte);
   22.47 -} 
   22.48 -
   22.49  static __meminit void *alloc_static_page(unsigned long *phys)
   22.50  {
   22.51  	unsigned long va = (start_pfn << PAGE_SHIFT) + __START_KERNEL_map;
   22.52 @@ -531,10 +523,6 @@ void __init xen_init_pt(void)
   22.53  {
   22.54  	unsigned long addr, *page;
   22.55  
   22.56 -	memset((void *)init_level4_pgt,   0, PAGE_SIZE);
   22.57 -	memset((void *)level3_kernel_pgt, 0, PAGE_SIZE);
   22.58 -	memset((void *)level2_kernel_pgt, 0, PAGE_SIZE);
   22.59 -
   22.60  	/* Find the initial pte page that was built for us. */
   22.61  	page = (unsigned long *)xen_start_info->pt_base;
   22.62  	addr = page[pgd_index(__START_KERNEL_map)];
   22.63 @@ -595,7 +583,7 @@ void __init xen_init_pt(void)
   22.64  		mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
   22.65  }
   22.66  
   22.67 -void __init extend_init_mapping(unsigned long tables_space)
   22.68 +static void __init extend_init_mapping(unsigned long tables_space)
   22.69  {
   22.70  	unsigned long va = __START_KERNEL_map;
   22.71  	unsigned long phys, addr, *pte_page;
    23.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Sun Feb 18 16:13:13 2007 -0700
    23.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Tue Feb 20 12:58:22 2007 -0700
    23.3 @@ -22,7 +22,7 @@ config TCG_TPM
    23.4  
    23.5  config TCG_TIS
    23.6  	tristate "TPM Interface Specification 1.2 Interface"
    23.7 -	depends on TCG_TPM
    23.8 +	depends on TCG_TPM && PNPACPI
    23.9  	---help---
   23.10  	  If you have a TPM security chip that is compliant with the
   23.11  	  TCG TIS 1.2 TPM specification say Yes and it will be accessible
    24.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Sun Feb 18 16:13:13 2007 -0700
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,1222 +0,0 @@
    24.4 -/*
    24.5 - * Copyright (C) 2004 IBM Corporation
    24.6 - *
    24.7 - * Authors:
    24.8 - * Leendert van Doorn <leendert@watson.ibm.com>
    24.9 - * Dave Safford <safford@watson.ibm.com>
   24.10 - * Reiner Sailer <sailer@watson.ibm.com>
   24.11 - * Kylene Hall <kjhall@us.ibm.com>
   24.12 - *
   24.13 - * Maintained by: <tpmdd_devel@lists.sourceforge.net>
   24.14 - *
   24.15 - * Device driver for TCG/TCPA TPM (trusted platform module).
   24.16 - * Specifications at www.trustedcomputinggroup.org	 
   24.17 - *
   24.18 - * This program is free software; you can redistribute it and/or
   24.19 - * modify it under the terms of the GNU General Public License as
   24.20 - * published by the Free Software Foundation, version 2 of the
   24.21 - * License.
   24.22 - * 
   24.23 - * Note, the TPM chip is not interrupt driven (only polling)
   24.24 - * and can have very long timeouts (minutes!). Hence the unusual
   24.25 - * calls to msleep.
   24.26 - *
   24.27 - */
   24.28 -
   24.29 -#include <linux/sched.h>
   24.30 -#include <linux/poll.h>
   24.31 -#include <linux/spinlock.h>
   24.32 -#include "tpm.h"
   24.33 -
   24.34 -enum tpm_const {
   24.35 -	TPM_MINOR = 224,	/* officially assigned */
   24.36 -#ifndef CONFIG_XEN
   24.37 -	TPM_BUFSIZE = 2048,
   24.38 -#endif
   24.39 -	TPM_NUM_DEVICES = 256,
   24.40 -};
   24.41 -
   24.42 -enum tpm_duration {
   24.43 -	TPM_SHORT = 0,
   24.44 -	TPM_MEDIUM = 1,
   24.45 -	TPM_LONG = 2,
   24.46 -	TPM_UNDEFINED,
   24.47 -};
   24.48 -
   24.49 -#define TPM_MAX_ORDINAL 243
   24.50 -#define TPM_MAX_PROTECTED_ORDINAL 12
   24.51 -#define TPM_PROTECTED_ORDINAL_MASK 0xFF
   24.52 -
   24.53 -static LIST_HEAD(tpm_chip_list);
   24.54 -static DEFINE_SPINLOCK(driver_lock);
   24.55 -static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
   24.56 -
   24.57 -/*
   24.58 - * Array with one entry per ordinal defining the maximum amount
   24.59 - * of time the chip could take to return the result.  The ordinal
   24.60 - * designation of short, medium or long is defined in a table in
   24.61 - * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
   24.62 - * values of the SHORT, MEDIUM, and LONG durations are retrieved
   24.63 - * from the chip during initialization with a call to tpm_get_timeouts.
   24.64 - */
   24.65 -static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
   24.66 -	TPM_UNDEFINED,		/* 0 */
   24.67 -	TPM_UNDEFINED,
   24.68 -	TPM_UNDEFINED,
   24.69 -	TPM_UNDEFINED,
   24.70 -	TPM_UNDEFINED,
   24.71 -	TPM_UNDEFINED,		/* 5 */
   24.72 -	TPM_UNDEFINED,
   24.73 -	TPM_UNDEFINED,
   24.74 -	TPM_UNDEFINED,
   24.75 -	TPM_UNDEFINED,
   24.76 -	TPM_SHORT,		/* 10 */
   24.77 -	TPM_SHORT,
   24.78 -};
   24.79 -
   24.80 -static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
   24.81 -	TPM_UNDEFINED,		/* 0 */
   24.82 -	TPM_UNDEFINED,
   24.83 -	TPM_UNDEFINED,
   24.84 -	TPM_UNDEFINED,
   24.85 -	TPM_UNDEFINED,
   24.86 -	TPM_UNDEFINED,		/* 5 */
   24.87 -	TPM_UNDEFINED,
   24.88 -	TPM_UNDEFINED,
   24.89 -	TPM_UNDEFINED,
   24.90 -	TPM_UNDEFINED,
   24.91 -	TPM_SHORT,		/* 10 */
   24.92 -	TPM_SHORT,
   24.93 -	TPM_MEDIUM,
   24.94 -	TPM_LONG,
   24.95 -	TPM_LONG,
   24.96 -	TPM_MEDIUM,		/* 15 */
   24.97 -	TPM_SHORT,
   24.98 -	TPM_SHORT,
   24.99 -	TPM_MEDIUM,
  24.100 -	TPM_LONG,
  24.101 -	TPM_SHORT,		/* 20 */
  24.102 -	TPM_SHORT,
  24.103 -	TPM_MEDIUM,
  24.104 -	TPM_MEDIUM,
  24.105 -	TPM_MEDIUM,
  24.106 -	TPM_SHORT,		/* 25 */
  24.107 -	TPM_SHORT,
  24.108 -	TPM_MEDIUM,
  24.109 -	TPM_SHORT,
  24.110 -	TPM_SHORT,
  24.111 -	TPM_MEDIUM,		/* 30 */
  24.112 -	TPM_LONG,
  24.113 -	TPM_MEDIUM,
  24.114 -	TPM_SHORT,
  24.115 -	TPM_SHORT,
  24.116 -	TPM_SHORT,		/* 35 */
  24.117 -	TPM_MEDIUM,
  24.118 -	TPM_MEDIUM,
  24.119 -	TPM_UNDEFINED,
  24.120 -	TPM_UNDEFINED,
  24.121 -	TPM_MEDIUM,		/* 40 */
  24.122 -	TPM_LONG,
  24.123 -	TPM_MEDIUM,
  24.124 -	TPM_SHORT,
  24.125 -	TPM_SHORT,
  24.126 -	TPM_SHORT,		/* 45 */
  24.127 -	TPM_SHORT,
  24.128 -	TPM_SHORT,
  24.129 -	TPM_SHORT,
  24.130 -	TPM_LONG,
  24.131 -	TPM_MEDIUM,		/* 50 */
  24.132 -	TPM_MEDIUM,
  24.133 -	TPM_UNDEFINED,
  24.134 -	TPM_UNDEFINED,
  24.135 -	TPM_UNDEFINED,
  24.136 -	TPM_UNDEFINED,		/* 55 */
  24.137 -	TPM_UNDEFINED,
  24.138 -	TPM_UNDEFINED,
  24.139 -	TPM_UNDEFINED,
  24.140 -	TPM_UNDEFINED,
  24.141 -	TPM_MEDIUM,		/* 60 */
  24.142 -	TPM_MEDIUM,
  24.143 -	TPM_MEDIUM,
  24.144 -	TPM_SHORT,
  24.145 -	TPM_SHORT,
  24.146 -	TPM_MEDIUM,		/* 65 */
  24.147 -	TPM_UNDEFINED,
  24.148 -	TPM_UNDEFINED,
  24.149 -	TPM_UNDEFINED,
  24.150 -	TPM_UNDEFINED,
  24.151 -	TPM_SHORT,		/* 70 */
  24.152 -	TPM_SHORT,
  24.153 -	TPM_UNDEFINED,
  24.154 -	TPM_UNDEFINED,
  24.155 -	TPM_UNDEFINED,
  24.156 -	TPM_UNDEFINED,		/* 75 */
  24.157 -	TPM_UNDEFINED,
  24.158 -	TPM_UNDEFINED,
  24.159 -	TPM_UNDEFINED,
  24.160 -	TPM_UNDEFINED,
  24.161 -	TPM_LONG,		/* 80 */
  24.162 -	TPM_UNDEFINED,
  24.163 -	TPM_MEDIUM,
  24.164 -	TPM_LONG,
  24.165 -	TPM_SHORT,
  24.166 -	TPM_UNDEFINED,		/* 85 */
  24.167 -	TPM_UNDEFINED,
  24.168 -	TPM_UNDEFINED,
  24.169 -	TPM_UNDEFINED,
  24.170 -	TPM_UNDEFINED,
  24.171 -	TPM_SHORT,		/* 90 */
  24.172 -	TPM_SHORT,
  24.173 -	TPM_SHORT,
  24.174 -	TPM_SHORT,
  24.175 -	TPM_SHORT,
  24.176 -	TPM_UNDEFINED,		/* 95 */
  24.177 -	TPM_UNDEFINED,
  24.178 -	TPM_UNDEFINED,
  24.179 -	TPM_UNDEFINED,
  24.180 -	TPM_UNDEFINED,
  24.181 -	TPM_MEDIUM,		/* 100 */
  24.182 -	TPM_SHORT,
  24.183 -	TPM_SHORT,
  24.184 -	TPM_UNDEFINED,
  24.185 -	TPM_UNDEFINED,
  24.186 -	TPM_UNDEFINED,		/* 105 */
  24.187 -	TPM_UNDEFINED,
  24.188 -	TPM_UNDEFINED,
  24.189 -	TPM_UNDEFINED,
  24.190 -	TPM_UNDEFINED,
  24.191 -	TPM_SHORT,		/* 110 */
  24.192 -	TPM_SHORT,
  24.193 -	TPM_SHORT,
  24.194 -	TPM_SHORT,
  24.195 -	TPM_SHORT,
  24.196 -	TPM_SHORT,		/* 115 */
  24.197 -	TPM_SHORT,
  24.198 -	TPM_SHORT,
  24.199 -	TPM_UNDEFINED,
  24.200 -	TPM_UNDEFINED,
  24.201 -	TPM_LONG,		/* 120 */
  24.202 -	TPM_LONG,
  24.203 -	TPM_MEDIUM,
  24.204 -	TPM_UNDEFINED,
  24.205 -	TPM_SHORT,
  24.206 -	TPM_SHORT,		/* 125 */
  24.207 -	TPM_SHORT,
  24.208 -	TPM_LONG,
  24.209 -	TPM_SHORT,
  24.210 -	TPM_SHORT,
  24.211 -	TPM_SHORT,		/* 130 */
  24.212 -	TPM_MEDIUM,
  24.213 -	TPM_UNDEFINED,
  24.214 -	TPM_SHORT,
  24.215 -	TPM_MEDIUM,
  24.216 -	TPM_UNDEFINED,		/* 135 */
  24.217 -	TPM_UNDEFINED,
  24.218 -	TPM_UNDEFINED,
  24.219 -	TPM_UNDEFINED,
  24.220 -	TPM_UNDEFINED,
  24.221 -	TPM_SHORT,		/* 140 */
  24.222 -	TPM_SHORT,
  24.223 -	TPM_UNDEFINED,
  24.224 -	TPM_UNDEFINED,
  24.225 -	TPM_UNDEFINED,
  24.226 -	TPM_UNDEFINED,		/* 145 */
  24.227 -	TPM_UNDEFINED,
  24.228 -	TPM_UNDEFINED,
  24.229 -	TPM_UNDEFINED,
  24.230 -	TPM_UNDEFINED,
  24.231 -	TPM_SHORT,		/* 150 */
  24.232 -	TPM_MEDIUM,
  24.233 -	TPM_MEDIUM,
  24.234 -	TPM_SHORT,
  24.235 -	TPM_SHORT,
  24.236 -	TPM_UNDEFINED,		/* 155 */
  24.237 -	TPM_UNDEFINED,
  24.238 -	TPM_UNDEFINED,
  24.239 -	TPM_UNDEFINED,
  24.240 -	TPM_UNDEFINED,
  24.241 -	TPM_SHORT,		/* 160 */
  24.242 -	TPM_SHORT,
  24.243 -	TPM_SHORT,
  24.244 -	TPM_SHORT,
  24.245 -	TPM_UNDEFINED,
  24.246 -	TPM_UNDEFINED,		/* 165 */
  24.247 -	TPM_UNDEFINED,
  24.248 -	TPM_UNDEFINED,
  24.249 -	TPM_UNDEFINED,
  24.250 -	TPM_UNDEFINED,
  24.251 -	TPM_LONG,		/* 170 */
  24.252 -	TPM_UNDEFINED,
  24.253 -	TPM_UNDEFINED,
  24.254 -	TPM_UNDEFINED,
  24.255 -	TPM_UNDEFINED,
  24.256 -	TPM_UNDEFINED,		/* 175 */
  24.257 -	TPM_UNDEFINED,
  24.258 -	TPM_UNDEFINED,
  24.259 -	TPM_UNDEFINED,
  24.260 -	TPM_UNDEFINED,
  24.261 -	TPM_MEDIUM,		/* 180 */
  24.262 -	TPM_SHORT,
  24.263 -	TPM_MEDIUM,
  24.264 -	TPM_MEDIUM,
  24.265 -	TPM_MEDIUM,
  24.266 -	TPM_MEDIUM,		/* 185 */
  24.267 -	TPM_SHORT,
  24.268 -	TPM_UNDEFINED,
  24.269 -	TPM_UNDEFINED,
  24.270 -	TPM_UNDEFINED,
  24.271 -	TPM_UNDEFINED,		/* 190 */
  24.272 -	TPM_UNDEFINED,
  24.273 -	TPM_UNDEFINED,
  24.274 -	TPM_UNDEFINED,
  24.275 -	TPM_UNDEFINED,
  24.276 -	TPM_UNDEFINED,		/* 195 */
  24.277 -	TPM_UNDEFINED,
  24.278 -	TPM_UNDEFINED,
  24.279 -	TPM_UNDEFINED,
  24.280 -	TPM_UNDEFINED,
  24.281 -	TPM_SHORT,		/* 200 */
  24.282 -	TPM_UNDEFINED,
  24.283 -	TPM_UNDEFINED,
  24.284 -	TPM_UNDEFINED,
  24.285 -	TPM_SHORT,
  24.286 -	TPM_SHORT,		/* 205 */
  24.287 -	TPM_SHORT,
  24.288 -	TPM_SHORT,
  24.289 -	TPM_SHORT,
  24.290 -	TPM_SHORT,
  24.291 -	TPM_MEDIUM,		/* 210 */
  24.292 -	TPM_UNDEFINED,
  24.293 -	TPM_MEDIUM,
  24.294 -	TPM_MEDIUM,
  24.295 -	TPM_MEDIUM,
  24.296 -	TPM_UNDEFINED,		/* 215 */
  24.297 -	TPM_MEDIUM,
  24.298 -	TPM_UNDEFINED,
  24.299 -	TPM_UNDEFINED,
  24.300 -	TPM_SHORT,
  24.301 -	TPM_SHORT,		/* 220 */
  24.302 -	TPM_SHORT,
  24.303 -	TPM_SHORT,
  24.304 -	TPM_SHORT,
  24.305 -	TPM_SHORT,
  24.306 -	TPM_UNDEFINED,		/* 225 */
  24.307 -	TPM_UNDEFINED,
  24.308 -	TPM_UNDEFINED,
  24.309 -	TPM_UNDEFINED,
  24.310 -	TPM_UNDEFINED,
  24.311 -	TPM_SHORT,		/* 230 */
  24.312 -	TPM_LONG,
  24.313 -	TPM_MEDIUM,
  24.314 -	TPM_UNDEFINED,
  24.315 -	TPM_UNDEFINED,
  24.316 -	TPM_UNDEFINED,		/* 235 */
  24.317 -	TPM_UNDEFINED,
  24.318 -	TPM_UNDEFINED,
  24.319 -	TPM_UNDEFINED,
  24.320 -	TPM_UNDEFINED,
  24.321 -	TPM_SHORT,		/* 240 */
  24.322 -	TPM_UNDEFINED,
  24.323 -	TPM_MEDIUM,
  24.324 -};
  24.325 -
  24.326 -static void user_reader_timeout(unsigned long ptr)
  24.327 -{
  24.328 -	struct tpm_chip *chip = (struct tpm_chip *) ptr;
  24.329 -
  24.330 -	schedule_work(&chip->work);
  24.331 -}
  24.332 -
  24.333 -static void timeout_work(void *ptr)
  24.334 -{
  24.335 -	struct tpm_chip *chip = ptr;
  24.336 -
  24.337 -	down(&chip->buffer_mutex);
  24.338 -	atomic_set(&chip->data_pending, 0);
  24.339 -#ifndef CONFIG_XEN
  24.340 -	memset(chip->data_buffer, 0, TPM_BUFSIZE);
  24.341 -#else
  24.342 -	memset(chip->data_buffer, 0, get_chip_buffersize(chip));
  24.343 -#endif
  24.344 -	up(&chip->buffer_mutex);
  24.345 -}
  24.346 -
  24.347 -/*
  24.348 - * Returns max number of jiffies to wait
  24.349 - */
  24.350 -unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  24.351 -					   u32 ordinal)
  24.352 -{
  24.353 -	int duration_idx = TPM_UNDEFINED;
  24.354 -	int duration = 0;
  24.355 -
  24.356 -	if (ordinal < TPM_MAX_ORDINAL)
  24.357 -		duration_idx = tpm_ordinal_duration[ordinal];
  24.358 -	else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
  24.359 -		 TPM_MAX_PROTECTED_ORDINAL)
  24.360 -		duration_idx =
  24.361 -		    tpm_protected_ordinal_duration[ordinal &
  24.362 -						   TPM_PROTECTED_ORDINAL_MASK];
  24.363 -
  24.364 -	if (duration_idx != TPM_UNDEFINED)
  24.365 -		duration = chip->vendor.duration[duration_idx];
  24.366 -	if (duration <= 0)
  24.367 -		return 2 * 60 * HZ;
  24.368 -	else
  24.369 -		return duration;
  24.370 -}
  24.371 -EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
  24.372 -
  24.373 -/*
  24.374 - * Internal kernel interface to transmit TPM commands
  24.375 - */
  24.376 -static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
  24.377 -			    size_t bufsiz)
  24.378 -{
  24.379 -	ssize_t rc;
  24.380 -	u32 count, ordinal;
  24.381 -	unsigned long stop;
  24.382 -
  24.383 -	count = be32_to_cpu(*((__be32 *) (buf + 2)));
  24.384 -	ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
  24.385 -	if (count == 0)
  24.386 -		return -ENODATA;
  24.387 -	if (count > bufsiz) {
  24.388 -		dev_err(chip->dev,
  24.389 -			"invalid count value %x %zx \n", count, bufsiz);
  24.390 -		return -E2BIG;
  24.391 -	}
  24.392 -
  24.393 -	down(&chip->tpm_mutex);
  24.394 -
  24.395 -	if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
  24.396 -		dev_err(chip->dev,
  24.397 -			"tpm_transmit: tpm_send: error %zd\n", rc);
  24.398 -		goto out;
  24.399 -	}
  24.400 -
  24.401 -	if (chip->vendor.irq)
  24.402 -		goto out_recv;
  24.403 -
  24.404 -	stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
  24.405 -	do {
  24.406 -		u8 status = chip->vendor.status(chip);
  24.407 -		if ((status & chip->vendor.req_complete_mask) ==
  24.408 -		    chip->vendor.req_complete_val)
  24.409 -			goto out_recv;
  24.410 -
  24.411 -		if ((status == chip->vendor.req_canceled)) {
  24.412 -			dev_err(chip->dev, "Operation Canceled\n");
  24.413 -			rc = -ECANCELED;
  24.414 -			goto out;
  24.415 -		}
  24.416 -
  24.417 -		msleep(TPM_TIMEOUT);	/* CHECK */
  24.418 -		rmb();
  24.419 -	} while (time_before(jiffies, stop));
  24.420 -
  24.421 -	chip->vendor.cancel(chip);
  24.422 -	dev_err(chip->dev, "Operation Timed out\n");
  24.423 -	rc = -ETIME;
  24.424 -	goto out;
  24.425 -
  24.426 -out_recv:
  24.427 -	rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
  24.428 -	if (rc < 0)
  24.429 -		dev_err(chip->dev,
  24.430 -			"tpm_transmit: tpm_recv: error %zd\n", rc);
  24.431 -out:
  24.432 -	up(&chip->tpm_mutex);
  24.433 -	return rc;
  24.434 -}
  24.435 -
  24.436 -#define TPM_DIGEST_SIZE 20
  24.437 -#define TPM_ERROR_SIZE 10
  24.438 -#define TPM_RET_CODE_IDX 6
  24.439 -#define TPM_GET_CAP_RET_SIZE_IDX 10
  24.440 -#define TPM_GET_CAP_RET_UINT32_1_IDX 14
  24.441 -#define TPM_GET_CAP_RET_UINT32_2_IDX 18
  24.442 -#define TPM_GET_CAP_RET_UINT32_3_IDX 22
  24.443 -#define TPM_GET_CAP_RET_UINT32_4_IDX 26
  24.444 -#define TPM_GET_CAP_PERM_DISABLE_IDX 16
  24.445 -#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
  24.446 -#define TPM_GET_CAP_RET_BOOL_1_IDX 14
  24.447 -#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
  24.448 -
  24.449 -#define TPM_CAP_IDX 13
  24.450 -#define TPM_CAP_SUBCAP_IDX 21
  24.451 -
  24.452 -enum tpm_capabilities {
  24.453 -	TPM_CAP_FLAG = 4,
  24.454 -	TPM_CAP_PROP = 5,
  24.455 -};
  24.456 -
  24.457 -enum tpm_sub_capabilities {
  24.458 -	TPM_CAP_PROP_PCR = 0x1,
  24.459 -	TPM_CAP_PROP_MANUFACTURER = 0x3,
  24.460 -	TPM_CAP_FLAG_PERM = 0x8,
  24.461 -	TPM_CAP_FLAG_VOL = 0x9,
  24.462 -	TPM_CAP_PROP_OWNER = 0x11,
  24.463 -	TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
  24.464 -	TPM_CAP_PROP_TIS_DURATION = 0x20,
  24.465 -};
  24.466 -
  24.467 -/*
  24.468 - * This is a semi generic GetCapability command for use
  24.469 - * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
  24.470 - * and their associated sub_capabilities.
  24.471 - */
  24.472 -
  24.473 -static const u8 tpm_cap[] = {
  24.474 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
  24.475 -	0, 0, 0, 22,		/* length */
  24.476 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  24.477 -	0, 0, 0, 0,		/* TPM_CAP_<TYPE> */
  24.478 -	0, 0, 0, 4,		/* TPM_CAP_SUB_<TYPE> size */
  24.479 -	0, 0, 1, 0		/* TPM_CAP_SUB_<TYPE> */
  24.480 -};
  24.481 -
  24.482 -static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
  24.483 -			    char *desc)
  24.484 -{
  24.485 -	int err;
  24.486 -
  24.487 -	len = tpm_transmit(chip, data, len);
  24.488 -	if (len <  0)
  24.489 -		return len;
  24.490 -	if (len == TPM_ERROR_SIZE) {
  24.491 -		err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
  24.492 -		dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
  24.493 -		return err;
  24.494 -	}
  24.495 -	return 0;
  24.496 -}
  24.497 -
  24.498 -void tpm_gen_interrupt(struct tpm_chip *chip)
  24.499 -{
  24.500 -	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
  24.501 -	ssize_t rc;
  24.502 -
  24.503 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.504 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.505 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
  24.506 -
  24.507 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.508 -			"attempting to determine the timeouts");
  24.509 -}
  24.510 -EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
  24.511 -
  24.512 -void tpm_get_timeouts(struct tpm_chip *chip)
  24.513 -{
  24.514 -	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
  24.515 -	ssize_t rc;
  24.516 -	u32 timeout;
  24.517 -
  24.518 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.519 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.520 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
  24.521 -
  24.522 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.523 -			"attempting to determine the timeouts");
  24.524 -	if (rc)
  24.525 -		goto duration;
  24.526 -
  24.527 -	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
  24.528 -	    != 4 * sizeof(u32))
  24.529 -		goto duration;
  24.530 -
  24.531 -	/* Don't overwrite default if value is 0 */
  24.532 -	timeout =
  24.533 -	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
  24.534 -	if (timeout)
  24.535 -		chip->vendor.timeout_a = msecs_to_jiffies(timeout);
  24.536 -	timeout =
  24.537 -	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
  24.538 -	if (timeout)
  24.539 -		chip->vendor.timeout_b = msecs_to_jiffies(timeout);
  24.540 -	timeout =
  24.541 -	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
  24.542 -	if (timeout)
  24.543 -		chip->vendor.timeout_c = msecs_to_jiffies(timeout);
  24.544 -	timeout =
  24.545 -	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
  24.546 -	if (timeout)
  24.547 -		chip->vendor.timeout_d = msecs_to_jiffies(timeout);
  24.548 -
  24.549 -duration:
  24.550 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.551 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.552 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
  24.553 -
  24.554 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.555 -			"attempting to determine the durations");
  24.556 -	if (rc)
  24.557 -		return;
  24.558 -
  24.559 -	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
  24.560 -	    != 3 * sizeof(u32))
  24.561 -		return;
  24.562 -
  24.563 -	chip->vendor.duration[TPM_SHORT] =
  24.564 -	    msecs_to_jiffies(be32_to_cpu
  24.565 -			     (*((__be32 *) (data +
  24.566 -					    TPM_GET_CAP_RET_UINT32_1_IDX))));
  24.567 -	chip->vendor.duration[TPM_MEDIUM] =
  24.568 -	    msecs_to_jiffies(be32_to_cpu
  24.569 -			     (*((__be32 *) (data +
  24.570 -					    TPM_GET_CAP_RET_UINT32_2_IDX))));
  24.571 -	chip->vendor.duration[TPM_LONG] =
  24.572 -	    msecs_to_jiffies(be32_to_cpu
  24.573 -			     (*((__be32 *) (data +
  24.574 -					    TPM_GET_CAP_RET_UINT32_3_IDX))));
  24.575 -}
  24.576 -EXPORT_SYMBOL_GPL(tpm_get_timeouts);
  24.577 -
  24.578 -void tpm_continue_selftest(struct tpm_chip *chip)
  24.579 -{
  24.580 -	u8 data[] = {
  24.581 -		0, 193,			/* TPM_TAG_RQU_COMMAND */
  24.582 -		0, 0, 0, 10,		/* length */
  24.583 -		0, 0, 0, 83,		/* TPM_ORD_GetCapability */
  24.584 -	};
  24.585 -
  24.586 -	tpm_transmit(chip, data, sizeof(data));
  24.587 -}
  24.588 -EXPORT_SYMBOL_GPL(tpm_continue_selftest);
  24.589 -
  24.590 -ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
  24.591 -			char *buf)
  24.592 -{
  24.593 -	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
  24.594 -	ssize_t rc;
  24.595 -
  24.596 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.597 -	if (chip == NULL)
  24.598 -		return -ENODEV;
  24.599 -
  24.600 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.601 -	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  24.602 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
  24.603 -
  24.604 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.605 -			"attemtping to determine the permanent state");
  24.606 -	if (rc)
  24.607 -		return 0;
  24.608 -	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
  24.609 -}
  24.610 -EXPORT_SYMBOL_GPL(tpm_show_enabled);
  24.611 -
  24.612 -ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
  24.613 -			char *buf)
  24.614 -{
  24.615 -	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
  24.616 -	ssize_t rc;
  24.617 -
  24.618 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.619 -	if (chip == NULL)
  24.620 -		return -ENODEV;
  24.621 -
  24.622 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.623 -	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  24.624 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
  24.625 -
  24.626 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.627 -			"attemtping to determine the permanent state");
  24.628 -	if (rc)
  24.629 -		return 0;
  24.630 -	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
  24.631 -}
  24.632 -EXPORT_SYMBOL_GPL(tpm_show_active);
  24.633 -
  24.634 -ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
  24.635 -			char *buf)
  24.636 -{
  24.637 -	u8 data[sizeof(tpm_cap)];
  24.638 -	ssize_t rc;
  24.639 -
  24.640 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.641 -	if (chip == NULL)
  24.642 -		return -ENODEV;
  24.643 -
  24.644 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.645 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.646 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
  24.647 -
  24.648 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.649 -			"attempting to determine the owner state");
  24.650 -	if (rc)
  24.651 -		return 0;
  24.652 -	return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
  24.653 -}
  24.654 -EXPORT_SYMBOL_GPL(tpm_show_owned);
  24.655 -
  24.656 -ssize_t tpm_show_temp_deactivated(struct device * dev,
  24.657 -				struct device_attribute * attr, char *buf)
  24.658 -{
  24.659 -	u8 data[sizeof(tpm_cap)];
  24.660 -	ssize_t rc;
  24.661 -
  24.662 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.663 -	if (chip == NULL)
  24.664 -		return -ENODEV;
  24.665 -
  24.666 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.667 -	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  24.668 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
  24.669 -
  24.670 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.671 -			"attempting to determine the temporary state");
  24.672 -	if (rc)
  24.673 -		return 0;
  24.674 -	return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
  24.675 -}
  24.676 -EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
  24.677 -
  24.678 -static const u8 pcrread[] = {
  24.679 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
  24.680 -	0, 0, 0, 14,		/* length */
  24.681 -	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
  24.682 -	0, 0, 0, 0		/* PCR index */
  24.683 -};
  24.684 -
  24.685 -ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
  24.686 -		      char *buf)
  24.687 -{
  24.688 -	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
  24.689 -	ssize_t rc;
  24.690 -	int i, j, num_pcrs;
  24.691 -	__be32 index;
  24.692 -	char *str = buf;
  24.693 -
  24.694 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.695 -	if (chip == NULL)
  24.696 -		return -ENODEV;
  24.697 -
  24.698 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.699 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.700 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
  24.701 -
  24.702 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.703 -			"attempting to determine the number of PCRS");
  24.704 -	if (rc)
  24.705 -		return 0;
  24.706 -
  24.707 -	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
  24.708 -	for (i = 0; i < num_pcrs; i++) {
  24.709 -		memcpy(data, pcrread, sizeof(pcrread));
  24.710 -		index = cpu_to_be32(i);
  24.711 -		memcpy(data + 10, &index, 4);
  24.712 -		rc = transmit_cmd(chip, data, sizeof(data),
  24.713 -				"attempting to read a PCR");
  24.714 -		if (rc)
  24.715 -			goto out;
  24.716 -		str += sprintf(str, "PCR-%02d: ", i);
  24.717 -		for (j = 0; j < TPM_DIGEST_SIZE; j++)
  24.718 -			str += sprintf(str, "%02X ", *(data + 10 + j));
  24.719 -		str += sprintf(str, "\n");
  24.720 -	}
  24.721 -out:
  24.722 -	return str - buf;
  24.723 -}
  24.724 -EXPORT_SYMBOL_GPL(tpm_show_pcrs);
  24.725 -
  24.726 -#define  READ_PUBEK_RESULT_SIZE 314
  24.727 -static const u8 readpubek[] = {
  24.728 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
  24.729 -	0, 0, 0, 30,		/* length */
  24.730 -	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
  24.731 -};
  24.732 -
  24.733 -ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
  24.734 -		       char *buf)
  24.735 -{
  24.736 -	u8 *data;
  24.737 -	ssize_t err;
  24.738 -	int i, rc;
  24.739 -	char *str = buf;
  24.740 -
  24.741 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.742 -	if (chip == NULL)
  24.743 -		return -ENODEV;
  24.744 -
  24.745 -	data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
  24.746 -	if (!data)
  24.747 -		return -ENOMEM;
  24.748 -
  24.749 -	memcpy(data, readpubek, sizeof(readpubek));
  24.750 -
  24.751 -	err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
  24.752 -			"attempting to read the PUBEK");
  24.753 -	if (err)
  24.754 -		goto out;
  24.755 -
  24.756 -	/* 
  24.757 -	   ignore header 10 bytes
  24.758 -	   algorithm 32 bits (1 == RSA )
  24.759 -	   encscheme 16 bits
  24.760 -	   sigscheme 16 bits
  24.761 -	   parameters (RSA 12->bytes: keybit, #primes, expbit)  
  24.762 -	   keylenbytes 32 bits
  24.763 -	   256 byte modulus
  24.764 -	   ignore checksum 20 bytes
  24.765 -	 */
  24.766 -
  24.767 -	str +=
  24.768 -	    sprintf(str,
  24.769 -		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
  24.770 -		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
  24.771 -		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
  24.772 -		    "Modulus length: %d\nModulus: \n",
  24.773 -		    data[10], data[11], data[12], data[13], data[14],
  24.774 -		    data[15], data[16], data[17], data[22], data[23],
  24.775 -		    data[24], data[25], data[26], data[27], data[28],
  24.776 -		    data[29], data[30], data[31], data[32], data[33],
  24.777 -		    be32_to_cpu(*((__be32 *) (data + 34))));
  24.778 -
  24.779 -	for (i = 0; i < 256; i++) {
  24.780 -		str += sprintf(str, "%02X ", data[i + 38]);
  24.781 -		if ((i + 1) % 16 == 0)
  24.782 -			str += sprintf(str, "\n");
  24.783 -	}
  24.784 -out:
  24.785 -	rc = str - buf;
  24.786 -	kfree(data);
  24.787 -	return rc;
  24.788 -}
  24.789 -EXPORT_SYMBOL_GPL(tpm_show_pubek);
  24.790 -
  24.791 -#define CAP_VERSION_1_1 6
  24.792 -#define CAP_VERSION_1_2 0x1A
  24.793 -#define CAP_VERSION_IDX 13
  24.794 -static const u8 cap_version[] = {
  24.795 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
  24.796 -	0, 0, 0, 18,		/* length */
  24.797 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  24.798 -	0, 0, 0, 0,
  24.799 -	0, 0, 0, 0
  24.800 -};
  24.801 -
  24.802 -ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
  24.803 -		      char *buf)
  24.804 -{
  24.805 -	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
  24.806 -	ssize_t rc;
  24.807 -	char *str = buf;
  24.808 -
  24.809 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.810 -	if (chip == NULL)
  24.811 -		return -ENODEV;
  24.812 -
  24.813 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.814 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.815 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
  24.816 -
  24.817 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.818 -			"attempting to determine the manufacturer");
  24.819 -	if (rc)
  24.820 -		return 0;
  24.821 -
  24.822 -	str += sprintf(str, "Manufacturer: 0x%x\n",
  24.823 -		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
  24.824 -
  24.825 -	memcpy(data, cap_version, sizeof(cap_version));
  24.826 -	data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
  24.827 -	rc = transmit_cmd(chip, data, sizeof(data),
  24.828 -			"attempting to determine the 1.1 version");
  24.829 -	if (rc)
  24.830 -		goto out;
  24.831 -
  24.832 -	str += sprintf(str,
  24.833 -		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
  24.834 -		       (int) data[14], (int) data[15], (int) data[16],
  24.835 -		       (int) data[17]);
  24.836 -
  24.837 -out:
  24.838 -	return str - buf;
  24.839 -}
  24.840 -EXPORT_SYMBOL_GPL(tpm_show_caps);
  24.841 -
  24.842 -ssize_t tpm_show_caps_1_2(struct device * dev,
  24.843 -			  struct device_attribute * attr, char *buf)
  24.844 -{
  24.845 -	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
  24.846 -	ssize_t len;
  24.847 -	char *str = buf;
  24.848 -
  24.849 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.850 -	if (chip == NULL)
  24.851 -		return -ENODEV;
  24.852 -
  24.853 -	memcpy(data, tpm_cap, sizeof(tpm_cap));
  24.854 -	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  24.855 -	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
  24.856 -
  24.857 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
  24.858 -	    TPM_ERROR_SIZE) {
  24.859 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  24.860 -			"attempting to determine the manufacturer\n",
  24.861 -			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
  24.862 -		return 0;
  24.863 -	}
  24.864 -
  24.865 -	str += sprintf(str, "Manufacturer: 0x%x\n",
  24.866 -		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
  24.867 -
  24.868 -	memcpy(data, cap_version, sizeof(cap_version));
  24.869 -	data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
  24.870 -
  24.871 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
  24.872 -	    TPM_ERROR_SIZE) {
  24.873 -		dev_err(chip->dev, "A TPM error (%d) occurred "
  24.874 -			"attempting to determine the 1.2 version\n",
  24.875 -			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
  24.876 -		goto out;
  24.877 -	}
  24.878 -	str += sprintf(str,
  24.879 -		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
  24.880 -		       (int) data[16], (int) data[17], (int) data[18],
  24.881 -		       (int) data[19]);
  24.882 -
  24.883 -out:
  24.884 -	return str - buf;
  24.885 -}
  24.886 -EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
  24.887 -
  24.888 -ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
  24.889 -			const char *buf, size_t count)
  24.890 -{
  24.891 -	struct tpm_chip *chip = dev_get_drvdata(dev);
  24.892 -	if (chip == NULL)
  24.893 -		return 0;
  24.894 -
  24.895 -	chip->vendor.cancel(chip);
  24.896 -	return count;
  24.897 -}
  24.898 -EXPORT_SYMBOL_GPL(tpm_store_cancel);
  24.899 -
  24.900 -/*
  24.901 - * Device file system interface to the TPM
  24.902 - */
  24.903 -int tpm_open(struct inode *inode, struct file *file)
  24.904 -{
  24.905 -	int rc = 0, minor = iminor(inode);
  24.906 -	struct tpm_chip *chip = NULL, *pos;
  24.907 -
  24.908 -	spin_lock(&driver_lock);
  24.909 -
  24.910 -	list_for_each_entry(pos, &tpm_chip_list, list) {
  24.911 -		if (pos->vendor.miscdev.minor == minor) {
  24.912 -			chip = pos;
  24.913 -			break;
  24.914 -		}
  24.915 -	}
  24.916 -
  24.917 -	if (chip == NULL) {
  24.918 -		rc = -ENODEV;
  24.919 -		goto err_out;
  24.920 -	}
  24.921 -
  24.922 -	if (chip->num_opens) {
  24.923 -		dev_dbg(chip->dev, "Another process owns this TPM\n");
  24.924 -		rc = -EBUSY;
  24.925 -		goto err_out;
  24.926 -	}
  24.927 -
  24.928 -	chip->num_opens++;
  24.929 -	get_device(chip->dev);
  24.930 -
  24.931 -	spin_unlock(&driver_lock);
  24.932 -
  24.933 -#ifndef CONFIG_XEN
  24.934 -	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
  24.935 -#else
  24.936 -	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
  24.937 -	                            GFP_KERNEL);
  24.938 -#endif
  24.939 -	if (chip->data_buffer == NULL) {
  24.940 -		chip->num_opens--;
  24.941 -		put_device(chip->dev);
  24.942 -		return -ENOMEM;
  24.943 -	}
  24.944 -
  24.945 -	atomic_set(&chip->data_pending, 0);
  24.946 -
  24.947 -	file->private_data = chip;
  24.948 -	return 0;
  24.949 -
  24.950 -err_out:
  24.951 -	spin_unlock(&driver_lock);
  24.952 -	return rc;
  24.953 -}
  24.954 -EXPORT_SYMBOL_GPL(tpm_open);
  24.955 -
  24.956 -int tpm_release(struct inode *inode, struct file *file)
  24.957 -{
  24.958 -	struct tpm_chip *chip = file->private_data;
  24.959 -
  24.960 -	spin_lock(&driver_lock);
  24.961 -	file->private_data = NULL;
  24.962 -	chip->num_opens--;
  24.963 -	del_singleshot_timer_sync(&chip->user_read_timer);
  24.964 -	flush_scheduled_work();
  24.965 -	atomic_set(&chip->data_pending, 0);
  24.966 -	put_device(chip->dev);
  24.967 -	kfree(chip->data_buffer);
  24.968 -	spin_unlock(&driver_lock);
  24.969 -	return 0;
  24.970 -}
  24.971 -EXPORT_SYMBOL_GPL(tpm_release);
  24.972 -
  24.973 -ssize_t tpm_write(struct file *file, const char __user *buf,
  24.974 -		  size_t size, loff_t *off)
  24.975 -{
  24.976 -	struct tpm_chip *chip = file->private_data;
  24.977 -	int in_size = size, out_size;
  24.978 -
  24.979 -	/* cannot perform a write until the read has cleared
  24.980 -	   either via tpm_read or a user_read_timer timeout */
  24.981 -	while (atomic_read(&chip->data_pending) != 0)
  24.982 -		msleep(TPM_TIMEOUT);
  24.983 -
  24.984 -	down(&chip->buffer_mutex);
  24.985 -
  24.986 -#ifndef CONFIG_XEN
  24.987 -	if (in_size > TPM_BUFSIZE)
  24.988 -		in_size = TPM_BUFSIZE;
  24.989 -#else
  24.990 -	if (in_size > get_chip_buffersize(chip))
  24.991 -		in_size = get_chip_buffersize(chip);
  24.992 -#endif
  24.993 -
  24.994 -	if (copy_from_user
  24.995 -	    (chip->data_buffer, (void __user *) buf, in_size)) {
  24.996 -		up(&chip->buffer_mutex);
  24.997 -		return -EFAULT;
  24.998 -	}
  24.999 -
 24.1000 -	/* atomic tpm command send and result receive */
 24.1001 -#ifndef CONFIG_XEN
 24.1002 -	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
 24.1003 -#else
 24.1004 -	out_size = tpm_transmit(chip, chip->data_buffer,
 24.1005 -	                        get_chip_buffersize(chip));
 24.1006 -#endif
 24.1007 -
 24.1008 -	atomic_set(&chip->data_pending, out_size);
 24.1009 -#ifdef CONFIG_XEN
 24.1010 -	atomic_set(&chip->data_position, 0);
 24.1011 -#endif
 24.1012 -	up(&chip->buffer_mutex);
 24.1013 -
 24.1014 -	/* Set a timeout by which the reader must come claim the result */
 24.1015 -	mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
 24.1016 -
 24.1017 -	return in_size;
 24.1018 -}
 24.1019 -EXPORT_SYMBOL_GPL(tpm_write);
 24.1020 -
 24.1021 -ssize_t tpm_read(struct file *file, char __user *buf,
 24.1022 -		 size_t size, loff_t *off)
 24.1023 -{
 24.1024 -	struct tpm_chip *chip = file->private_data;
 24.1025 -	int ret_size;
 24.1026 -#ifdef CONFIG_XEN
 24.1027 -	int pos, pending = 0;
 24.1028 -#endif
 24.1029 -
 24.1030 -#ifndef CONFIG_XEN
 24.1031 -	del_singleshot_timer_sync(&chip->user_read_timer);
 24.1032 -	flush_scheduled_work();
 24.1033 -#endif
 24.1034 -	ret_size = atomic_read(&chip->data_pending);
 24.1035 -#ifndef CONFIG_XEN
 24.1036 -	atomic_set(&chip->data_pending, 0);
 24.1037 -#endif
 24.1038 -	if (ret_size > 0) {	/* relay data */
 24.1039 -		if (size < ret_size)
 24.1040 -			ret_size = size;
 24.1041 -
 24.1042 -#ifdef CONFIG_XEN
 24.1043 -		pos = atomic_read(&chip->data_position);
 24.1044 -#endif
 24.1045 -		down(&chip->buffer_mutex);
 24.1046 -#ifndef CONFIG_XEN
 24.1047 -		if (copy_to_user(buf, chip->data_buffer, ret_size))
 24.1048 -#else
 24.1049 -		if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
 24.1050 -#endif
 24.1051 -			ret_size = -EFAULT;
 24.1052 -#ifdef CONFIG_XEN
 24.1053 -		} else {
 24.1054 -			pending = atomic_read(&chip->data_pending) - ret_size;
 24.1055 -			if ( pending ) {
 24.1056 -				atomic_set(&chip->data_pending, pending);
 24.1057 -				atomic_set(&chip->data_position,
 24.1058 -				           pos+ret_size);
 24.1059 -			}
 24.1060 -		}
 24.1061 -#endif
 24.1062 -		up(&chip->buffer_mutex);
 24.1063 -	}
 24.1064 -
 24.1065 -#ifdef CONFIG_XEN
 24.1066 - 	if ( ret_size <= 0 || pending == 0 ) {
 24.1067 -		atomic_set(&chip->data_pending, 0);
 24.1068 -		del_singleshot_timer_sync(&chip->user_read_timer);
 24.1069 -		flush_scheduled_work();
 24.1070 -	}
 24.1071 -#endif
 24.1072 -	return ret_size;
 24.1073 -}
 24.1074 -EXPORT_SYMBOL_GPL(tpm_read);
 24.1075 -
 24.1076 -void tpm_remove_hardware(struct device *dev)
 24.1077 -{
 24.1078 -	struct tpm_chip *chip = dev_get_drvdata(dev);
 24.1079 -
 24.1080 -	if (chip == NULL) {
 24.1081 -		dev_err(dev, "No device data found\n");
 24.1082 -		return;
 24.1083 -	}
 24.1084 -
 24.1085 -	spin_lock(&driver_lock);
 24.1086 -
 24.1087 -	list_del(&chip->list);
 24.1088 -
 24.1089 -	spin_unlock(&driver_lock);
 24.1090 -
 24.1091 -	dev_set_drvdata(dev, NULL);
 24.1092 -	misc_deregister(&chip->vendor.miscdev);
 24.1093 -	kfree(chip->vendor.miscdev.name);
 24.1094 -
 24.1095 -	sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
 24.1096 -	tpm_bios_log_teardown(chip->bios_dir);
 24.1097 -
 24.1098 -	clear_bit(chip->dev_num, dev_mask);
 24.1099 -
 24.1100 -	kfree(chip);
 24.1101 -
 24.1102 -	put_device(dev);
 24.1103 -}
 24.1104 -EXPORT_SYMBOL_GPL(tpm_remove_hardware);
 24.1105 -
 24.1106 -static u8 savestate[] = {
 24.1107 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
 24.1108 -	0, 0, 0, 10,		/* blob length (in bytes) */
 24.1109 -	0, 0, 0, 152		/* TPM_ORD_SaveState */
 24.1110 -};
 24.1111 -
 24.1112 -/*
 24.1113 - * We are about to suspend. Save the TPM state
 24.1114 - * so that it can be restored.
 24.1115 - */
 24.1116 -int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
 24.1117 -{
 24.1118 -	struct tpm_chip *chip = dev_get_drvdata(dev);
 24.1119 -	if (chip == NULL)
 24.1120 -		return -ENODEV;
 24.1121 -
 24.1122 -	tpm_transmit(chip, savestate, sizeof(savestate));
 24.1123 -	return 0;
 24.1124 -}
 24.1125 -EXPORT_SYMBOL_GPL(tpm_pm_suspend);
 24.1126 -
 24.1127 -/*
 24.1128 - * Resume from a power safe. The BIOS already restored
 24.1129 - * the TPM state.
 24.1130 - */
 24.1131 -int tpm_pm_resume(struct device *dev)
 24.1132 -{
 24.1133 -	struct tpm_chip *chip = dev_get_drvdata(dev);
 24.1134 -
 24.1135 -	if (chip == NULL)
 24.1136 -		return -ENODEV;
 24.1137 -
 24.1138 -	return 0;
 24.1139 -}
 24.1140 -EXPORT_SYMBOL_GPL(tpm_pm_resume);
 24.1141 -
 24.1142 -/*
 24.1143 - * Called from tpm_<specific>.c probe function only for devices 
 24.1144 - * the driver has determined it should claim.  Prior to calling
 24.1145 - * this function the specific probe function has called pci_enable_device
 24.1146 - * upon errant exit from this function specific probe function should call
 24.1147 - * pci_disable_device
 24.1148 - */
 24.1149 -struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
 24.1150 -				       *entry)
 24.1151 -{
 24.1152 -#define DEVNAME_SIZE 7
 24.1153 -
 24.1154 -	char *devname;
 24.1155 -	struct tpm_chip *chip;
 24.1156 -
 24.1157 -	/* Driver specific per-device data */
 24.1158 -	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 24.1159 -	if (chip == NULL)
 24.1160 -		return NULL;
 24.1161 -
 24.1162 -	init_MUTEX(&chip->buffer_mutex);
 24.1163 -	init_MUTEX(&chip->tpm_mutex);
 24.1164 -	INIT_LIST_HEAD(&chip->list);
 24.1165 -
 24.1166 -	INIT_WORK(&chip->work, timeout_work, chip);
 24.1167 -
 24.1168 -	init_timer(&chip->user_read_timer);
 24.1169 -	chip->user_read_timer.function = user_reader_timeout;
 24.1170 -	chip->user_read_timer.data = (unsigned long) chip;
 24.1171 -
 24.1172 -	memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
 24.1173 -
 24.1174 -	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
 24.1175 -
 24.1176 -	if (chip->dev_num >= TPM_NUM_DEVICES) {
 24.1177 -		dev_err(dev, "No available tpm device numbers\n");
 24.1178 -		kfree(chip);
 24.1179 -		return NULL;
 24.1180 -	} else if (chip->dev_num == 0)
 24.1181 -		chip->vendor.miscdev.minor = TPM_MINOR;
 24.1182 -	else
 24.1183 -		chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
 24.1184 -
 24.1185 -	set_bit(chip->dev_num, dev_mask);
 24.1186 -
 24.1187 -	devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
 24.1188 -	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
 24.1189 -	chip->vendor.miscdev.name = devname;
 24.1190 -
 24.1191 -	chip->vendor.miscdev.dev = dev;
 24.1192 -	chip->dev = get_device(dev);
 24.1193 -
 24.1194 -	if (misc_register(&chip->vendor.miscdev)) {
 24.1195 -		dev_err(chip->dev,
 24.1196 -			"unable to misc_register %s, minor %d\n",
 24.1197 -			chip->vendor.miscdev.name,
 24.1198 -			chip->vendor.miscdev.minor);
 24.1199 -		put_device(dev);
 24.1200 -		clear_bit(chip->dev_num, dev_mask);
 24.1201 -		kfree(chip);
 24.1202 -		kfree(devname);
 24.1203 -		return NULL;
 24.1204 -	}
 24.1205 -
 24.1206 -	spin_lock(&driver_lock);
 24.1207 -
 24.1208 -	dev_set_drvdata(dev, chip);
 24.1209 -
 24.1210 -	list_add(&chip->list, &tpm_chip_list);
 24.1211 -
 24.1212 -	spin_unlock(&driver_lock);
 24.1213 -
 24.1214 -	sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
 24.1215 -
 24.1216 -	chip->bios_dir = tpm_bios_log_setup(devname);
 24.1217 -
 24.1218 -	return chip;
 24.1219 -}
 24.1220 -EXPORT_SYMBOL_GPL(tpm_register_hardware);
 24.1221 -
 24.1222 -MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 24.1223 -MODULE_DESCRIPTION("TPM Driver");
 24.1224 -MODULE_VERSION("2.0");
 24.1225 -MODULE_LICENSE("GPL");
    25.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Sun Feb 18 16:13:13 2007 -0700
    25.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Tue Feb 20 12:58:22 2007 -0700
    25.3 @@ -26,13 +26,6 @@
    25.4  #include <linux/platform_device.h>
    25.5  #include <linux/io.h>
    25.6  
    25.7 -#ifdef CONFIG_XEN
    25.8 -enum tpm_bufsize {
    25.9 -	TPM_MIN_BUFFERSIZE = 2048,
   25.10 -	TPM_MAX_BUFFERSIZE = 64 * 1024,
   25.11 -};
   25.12 -#endif
   25.13 -
   25.14  enum tpm_timeout {
   25.15  	TPM_TIMEOUT = 5,	/* msecs */
   25.16  };
   25.17 @@ -68,9 +61,6 @@ struct tpm_vendor_specific {
   25.18  	const u8 req_complete_mask;
   25.19  	const u8 req_complete_val;
   25.20  	const u8 req_canceled;
   25.21 -#ifdef CONFIG_XEN
   25.22 -	u32 buffersize;
   25.23 -#endif
   25.24  	void __iomem *iobase;		/* ioremapped address */
   25.25  	unsigned long base;		/* TPM base address */
   25.26  
   25.27 @@ -104,9 +94,6 @@ struct tpm_chip {
   25.28  	/* Data passed to and from the tpm via the read/write calls */
   25.29  	u8 *data_buffer;
   25.30  	atomic_t data_pending;
   25.31 -#ifdef CONFIG_XEN
   25.32 -	atomic_t data_position;
   25.33 -#endif
   25.34  	struct semaphore buffer_mutex;
   25.35  
   25.36  	struct timer_list user_read_timer;	/* user needs to claim result */
   25.37 @@ -138,17 +125,6 @@ static inline void tpm_write_index(int b
   25.38  }
   25.39  
   25.40  #ifdef CONFIG_XEN
   25.41 -static inline u32 get_chip_buffersize(struct tpm_chip *chip)
   25.42 -{
   25.43 -	u32 size = chip->vendor.buffersize;
   25.44 -	if (size > TPM_MAX_BUFFERSIZE) {
   25.45 -		return TPM_MAX_BUFFERSIZE;
   25.46 -	} else if (size < TPM_MIN_BUFFERSIZE) {
   25.47 -		return TPM_MIN_BUFFERSIZE;
   25.48 -	}
   25.49 -	return size;
   25.50 -}
   25.51 -
   25.52  static inline void *chip_get_private(const struct tpm_chip *chip)
   25.53  {
   25.54  	return chip->priv;
    26.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Sun Feb 18 16:13:13 2007 -0700
    26.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Tue Feb 20 12:58:22 2007 -0700
    26.3 @@ -519,9 +519,6 @@ struct tpm_chip *init_vtpm(struct device
    26.4  	vtpms->tpmvd = tvd;
    26.5  	vtpms->tpm_private = tp;
    26.6  
    26.7 -	if (tvd)
    26.8 -		tpm_vtpm.buffersize = tvd->max_tx_size;
    26.9 -
   26.10  	chip = tpm_register_hardware(dev, &tpm_vtpm);
   26.11  	if (!chip) {
   26.12  		rc = -ENODEV;
    27.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Sun Feb 18 16:13:13 2007 -0700
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Tue Feb 20 12:58:22 2007 -0700
    27.3 @@ -60,7 +60,7 @@
    27.4  static struct proc_dir_entry *balloon_pde;
    27.5  #endif
    27.6  
    27.7 -static DECLARE_MUTEX(balloon_mutex);
    27.8 +static DEFINE_MUTEX(balloon_mutex);
    27.9  
   27.10  /*
   27.11   * Protects atomic reservation decrease/increase against concurrent increases.
   27.12 @@ -321,7 +321,7 @@ static void balloon_process(void *unused
   27.13  	int need_sleep = 0;
   27.14  	long credit;
   27.15  
   27.16 -	down(&balloon_mutex);
   27.17 +	mutex_lock(&balloon_mutex);
   27.18  
   27.19  	do {
   27.20  		credit = current_target() - bs.current_pages;
   27.21 @@ -340,7 +340,7 @@ static void balloon_process(void *unused
   27.22  	if (current_target() != bs.current_pages)
   27.23  		mod_timer(&balloon_timer, jiffies + HZ);
   27.24  
   27.25 -	up(&balloon_mutex);
   27.26 +	mutex_unlock(&balloon_mutex);
   27.27  }
   27.28  
   27.29  /* Resets the Xen limit, sets new target, and kicks off processing. */
    28.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Sun Feb 18 16:13:13 2007 -0700
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Tue Feb 20 12:58:22 2007 -0700
    28.3 @@ -58,15 +58,12 @@ blkif_t *blkif_alloc(domid_t domid)
    28.4  static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
    28.5  {
    28.6  	struct gnttab_map_grant_ref op;
    28.7 -	int ret;
    28.8  
    28.9  	gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   28.10  			  GNTMAP_host_map, shared_page, blkif->domid);
   28.11  
   28.12 -	lock_vm_area(blkif->blk_ring_area);
   28.13 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   28.14 -	unlock_vm_area(blkif->blk_ring_area);
   28.15 -	BUG_ON(ret);
   28.16 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   28.17 +		BUG();
   28.18  
   28.19  	if (op.status) {
   28.20  		DPRINTK(" Grant table operation failure !\n");
   28.21 @@ -82,15 +79,12 @@ static int map_frontend_page(blkif_t *bl
   28.22  static void unmap_frontend_page(blkif_t *blkif)
   28.23  {
   28.24  	struct gnttab_unmap_grant_ref op;
   28.25 -	int ret;
   28.26  
   28.27  	gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   28.28  			    GNTMAP_host_map, blkif->shmem_handle);
   28.29  
   28.30 -	lock_vm_area(blkif->blk_ring_area);
   28.31 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   28.32 -	unlock_vm_area(blkif->blk_ring_area);
   28.33 -	BUG_ON(ret);
   28.34 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   28.35 +		BUG();
   28.36  }
   28.37  
   28.38  int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
    29.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Sun Feb 18 16:13:13 2007 -0700
    29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Tue Feb 20 12:58:22 2007 -0700
    29.3 @@ -58,15 +58,12 @@ blkif_t *tap_alloc_blkif(domid_t domid)
    29.4  static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
    29.5  {
    29.6  	struct gnttab_map_grant_ref op;
    29.7 -	int ret;
    29.8  
    29.9  	gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   29.10  			  GNTMAP_host_map, shared_page, blkif->domid);
   29.11  
   29.12 -	lock_vm_area(blkif->blk_ring_area);
   29.13 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   29.14 -	unlock_vm_area(blkif->blk_ring_area);
   29.15 -	BUG_ON(ret);
   29.16 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   29.17 +		BUG();
   29.18  
   29.19  	if (op.status) {
   29.20  		DPRINTK(" Grant table operation failure !\n");
   29.21 @@ -82,15 +79,12 @@ static int map_frontend_page(blkif_t *bl
   29.22  static void unmap_frontend_page(blkif_t *blkif)
   29.23  {
   29.24  	struct gnttab_unmap_grant_ref op;
   29.25 -	int ret;
   29.26  
   29.27  	gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   29.28  			    GNTMAP_host_map, blkif->shmem_handle);
   29.29  
   29.30 -	lock_vm_area(blkif->blk_ring_area);
   29.31 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   29.32 -	unlock_vm_area(blkif->blk_ring_area);
   29.33 -	BUG_ON(ret);
   29.34 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   29.35 +		BUG();
   29.36  }
   29.37  
   29.38  int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, 
    30.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Sun Feb 18 16:13:13 2007 -0700
    30.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Tue Feb 20 12:58:22 2007 -0700
    30.3 @@ -3,7 +3,7 @@
    30.4   *
    30.5   * Granting foreign access to our memory reservation.
    30.6   *
    30.7 - * Copyright (c) 2005, Christopher Clark
    30.8 + * Copyright (c) 2005-2006, Christopher Clark
    30.9   * Copyright (c) 2004-2005, K A Fraser
   30.10   *
   30.11   * This program is free software; you can redistribute it and/or
   30.12 @@ -35,7 +35,6 @@
   30.13  #include <linux/module.h>
   30.14  #include <linux/sched.h>
   30.15  #include <linux/mm.h>
   30.16 -#include <linux/vmalloc.h>
   30.17  #include <xen/interface/xen.h>
   30.18  #include <xen/gnttab.h>
   30.19  #include <asm/pgtable.h>
   30.20 @@ -43,6 +42,7 @@
   30.21  #include <asm/synch_bitops.h>
   30.22  #include <asm/io.h>
   30.23  #include <xen/interface/memory.h>
   30.24 +#include <xen/driver_util.h>
   30.25  
   30.26  #ifdef HAVE_XEN_PLATFORM_COMPAT_H
   30.27  #include <xen/platform-compat.h>
   30.28 @@ -50,37 +50,51 @@
   30.29  
   30.30  /* External tools reserve first few grant table entries. */
   30.31  #define NR_RESERVED_ENTRIES 8
   30.32 +#define GNTTAB_LIST_END 0xffffffff
   30.33 +#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(grant_entry_t))
   30.34  
   30.35 -#define NR_GRANT_ENTRIES \
   30.36 -	(NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry))
   30.37 -#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
   30.38 -
   30.39 -static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
   30.40 +static grant_ref_t **gnttab_list;
   30.41 +static unsigned int nr_grant_frames;
   30.42 +static unsigned int boot_max_nr_grant_frames;
   30.43  static int gnttab_free_count;
   30.44  static grant_ref_t gnttab_free_head;
   30.45  static DEFINE_SPINLOCK(gnttab_list_lock);
   30.46  
   30.47  static struct grant_entry *shared;
   30.48 +#ifndef CONFIG_XEN
   30.49 +static unsigned long resume_frames;
   30.50 +#endif
   30.51  
   30.52  static struct gnttab_free_callback *gnttab_free_callback_list;
   30.53  
   30.54 +static int gnttab_expand(unsigned int req_entries);
   30.55 +
   30.56 +#define RPP (PAGE_SIZE / sizeof(grant_ref_t))
   30.57 +#define gnttab_entry(entry) (gnttab_list[(entry) / RPP][(entry) % RPP])
   30.58 +
   30.59  static int get_free_entries(int count)
   30.60  {
   30.61  	unsigned long flags;
   30.62 -	int ref;
   30.63 +	int ref, rc;
   30.64  	grant_ref_t head;
   30.65 +
   30.66  	spin_lock_irqsave(&gnttab_list_lock, flags);
   30.67 -	if (gnttab_free_count < count) {
   30.68 +
   30.69 +	if ((gnttab_free_count < count) &&
   30.70 +	    ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) {
   30.71  		spin_unlock_irqrestore(&gnttab_list_lock, flags);
   30.72 -		return -1;
   30.73 +		return rc;
   30.74  	}
   30.75 +
   30.76  	ref = head = gnttab_free_head;
   30.77  	gnttab_free_count -= count;
   30.78  	while (count-- > 1)
   30.79 -		head = gnttab_list[head];
   30.80 -	gnttab_free_head = gnttab_list[head];
   30.81 -	gnttab_list[head] = GNTTAB_LIST_END;
   30.82 +		head = gnttab_entry(head);
   30.83 + 	gnttab_free_head = gnttab_entry(head);
   30.84 +	gnttab_entry(head) = GNTTAB_LIST_END;
   30.85 +
   30.86  	spin_unlock_irqrestore(&gnttab_list_lock, flags);
   30.87 +
   30.88  	return ref;
   30.89  }
   30.90  
   30.91 @@ -116,7 +130,7 @@ static void put_free_entry(grant_ref_t r
   30.92  {
   30.93  	unsigned long flags;
   30.94  	spin_lock_irqsave(&gnttab_list_lock, flags);
   30.95 -	gnttab_list[ref] = gnttab_free_head;
   30.96 +	gnttab_entry(ref) = gnttab_free_head;
   30.97  	gnttab_free_head = ref;
   30.98  	gnttab_free_count++;
   30.99  	check_free_callbacks();
  30.100 @@ -132,7 +146,7 @@ int gnttab_grant_foreign_access(domid_t 
  30.101  {
  30.102  	int ref;
  30.103  
  30.104 -	if (unlikely((ref = get_free_entry()) == -1))
  30.105 +	if (unlikely((ref = get_free_entry()) < 0))
  30.106  		return -ENOSPC;
  30.107  
  30.108  	shared[ref].frame = frame;
  30.109 @@ -202,7 +216,7 @@ int gnttab_grant_foreign_transfer(domid_
  30.110  {
  30.111  	int ref;
  30.112  
  30.113 -	if (unlikely((ref = get_free_entry()) == -1))
  30.114 +	if (unlikely((ref = get_free_entry()) < 0))
  30.115  		return -ENOSPC;
  30.116  	gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
  30.117  
  30.118 @@ -273,11 +287,11 @@ void gnttab_free_grant_references(grant_
  30.119  		return;
  30.120  	spin_lock_irqsave(&gnttab_list_lock, flags);
  30.121  	ref = head;
  30.122 -	while (gnttab_list[ref] != GNTTAB_LIST_END) {
  30.123 -		ref = gnttab_list[ref];
  30.124 +	while (gnttab_entry(ref) != GNTTAB_LIST_END) {
  30.125 +		ref = gnttab_entry(ref);
  30.126  		count++;
  30.127  	}
  30.128 -	gnttab_list[ref] = gnttab_free_head;
  30.129 +	gnttab_entry(ref) = gnttab_free_head;
  30.130  	gnttab_free_head = head;
  30.131  	gnttab_free_count += count;
  30.132  	check_free_callbacks();
  30.133 @@ -289,7 +303,7 @@ int gnttab_alloc_grant_references(u16 co
  30.134  {
  30.135  	int h = get_free_entries(count);
  30.136  
  30.137 -	if (h == -1)
  30.138 +	if (h < 0)
  30.139  		return -ENOSPC;
  30.140  
  30.141  	*head = h;
  30.142 @@ -309,7 +323,7 @@ int gnttab_claim_grant_reference(grant_r
  30.143  	grant_ref_t g = *private_head;
  30.144  	if (unlikely(g == GNTTAB_LIST_END))
  30.145  		return -ENOSPC;
  30.146 -	*private_head = gnttab_list[g];
  30.147 +	*private_head = gnttab_entry(g);
  30.148  	return g;
  30.149  }
  30.150  EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
  30.151 @@ -317,7 +331,7 @@ EXPORT_SYMBOL_GPL(gnttab_claim_grant_ref
  30.152  void gnttab_release_grant_reference(grant_ref_t *private_head,
  30.153  				    grant_ref_t release)
  30.154  {
  30.155 -	gnttab_list[release] = *private_head;
  30.156 +	gnttab_entry(release) = *private_head;
  30.157  	*private_head = release;
  30.158  }
  30.159  EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
  30.160 @@ -356,6 +370,64 @@ void gnttab_cancel_free_callback(struct 
  30.161  }
  30.162  EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback);
  30.163  
  30.164 +static int grow_gnttab_list(unsigned int more_frames)
  30.165 +{
  30.166 +	unsigned int new_nr_grant_frames, extra_entries, i;
  30.167 +
  30.168 +	new_nr_grant_frames = nr_grant_frames + more_frames;
  30.169 +	extra_entries       = more_frames * GREFS_PER_GRANT_FRAME;
  30.170 +
  30.171 +	for (i = nr_grant_frames; i < new_nr_grant_frames; i++)
  30.172 +	{
  30.173 +		gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC);
  30.174 +		if (!gnttab_list[i])
  30.175 +			goto grow_nomem;
  30.176 +	}
  30.177 +
  30.178 +
  30.179 +	for (i = GREFS_PER_GRANT_FRAME * nr_grant_frames;
  30.180 +	     i < GREFS_PER_GRANT_FRAME * new_nr_grant_frames - 1; i++)
  30.181 +		gnttab_entry(i) = i + 1;
  30.182 +
  30.183 +	gnttab_entry(i) = gnttab_free_head;
  30.184 +	gnttab_free_head = GREFS_PER_GRANT_FRAME * nr_grant_frames;
  30.185 +	gnttab_free_count += extra_entries;
  30.186 +
  30.187 +	nr_grant_frames = new_nr_grant_frames;
  30.188 +
  30.189 +	check_free_callbacks();
  30.190 +
  30.191 +	return 0;
  30.192 +	
  30.193 +grow_nomem:
  30.194 +	for ( ; i >= nr_grant_frames; i--)
  30.195 +		free_page((unsigned long) gnttab_list[i]);
  30.196 +	return -ENOMEM;
  30.197 +}
  30.198 +
  30.199 +static unsigned int __max_nr_grant_frames(void)
  30.200 +{
  30.201 +	struct gnttab_query_size query;
  30.202 +	int rc;
  30.203 +
  30.204 +	query.dom = DOMID_SELF;
  30.205 +
  30.206 +	rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1);
  30.207 +	if ((rc < 0) || (query.status != GNTST_okay))
  30.208 +		return 4; /* Legacy max supported number of frames */
  30.209 +
  30.210 +	return query.max_nr_frames;
  30.211 +}
  30.212 +
  30.213 +static inline unsigned int max_nr_grant_frames(void)
  30.214 +{
  30.215 +	unsigned int xen_max = __max_nr_grant_frames();
  30.216 +
  30.217 +	if (xen_max > boot_max_nr_grant_frames)
  30.218 +		return boot_max_nr_grant_frames;
  30.219 +	return xen_max;
  30.220 +}
  30.221 +
  30.222  #ifdef CONFIG_XEN
  30.223  
  30.224  #ifndef __ia64__
  30.225 @@ -378,49 +450,62 @@ static int unmap_pte_fn(pte_t *pte, stru
  30.226  }
  30.227  #endif
  30.228  
  30.229 -int gnttab_resume(void)
  30.230 +static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
  30.231  {
  30.232  	struct gnttab_setup_table setup;
  30.233 -	unsigned long frames[NR_GRANT_FRAMES];
  30.234 +	unsigned long *frames;
  30.235 +	unsigned int nr_gframes = end_idx + 1;
  30.236  	int rc;
  30.237 -#ifndef __ia64__
  30.238 -	void *pframes = frames;
  30.239 -	struct vm_struct *area;
  30.240 -#endif
  30.241 +
  30.242 +	frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
  30.243 +	if (!frames)
  30.244 +		return -ENOMEM;
  30.245  
  30.246  	setup.dom        = DOMID_SELF;
  30.247 -	setup.nr_frames  = NR_GRANT_FRAMES;
  30.248 +	setup.nr_frames  = nr_gframes;
  30.249  	set_xen_guest_handle(setup.frame_list, frames);
  30.250  
  30.251  	rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
  30.252 -	if (rc == -ENOSYS)
  30.253 +	if (rc == -ENOSYS) {
  30.254 +		kfree(frames);
  30.255  		return -ENOSYS;
  30.256 +	}
  30.257  
  30.258  	BUG_ON(rc || setup.status);
  30.259  
  30.260  #ifndef __ia64__
  30.261  	if (shared == NULL) {
  30.262 -		area = get_vm_area(PAGE_SIZE * NR_GRANT_FRAMES, VM_IOREMAP);
  30.263 +		struct vm_struct *area;
  30.264 +		area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
  30.265  		BUG_ON(area == NULL);
  30.266  		shared = area->addr;
  30.267  	}
  30.268  	rc = apply_to_page_range(&init_mm, (unsigned long)shared,
  30.269 -				 PAGE_SIZE * NR_GRANT_FRAMES,
  30.270 -				 map_pte_fn, &pframes);
  30.271 +				 PAGE_SIZE * nr_gframes,
  30.272 +				 map_pte_fn, &frames);
  30.273  	BUG_ON(rc);
  30.274 +        frames -= nr_gframes; /* adjust after map_pte_fn() */
  30.275  #else
  30.276  	shared = __va(frames[0] << PAGE_SHIFT);
  30.277 -	printk("grant table at %p\n", shared);
  30.278  #endif
  30.279  
  30.280 +	kfree(frames);
  30.281 +
  30.282  	return 0;
  30.283  }
  30.284  
  30.285 +int gnttab_resume(void)
  30.286 +{
  30.287 +	if (max_nr_grant_frames() < nr_grant_frames)
  30.288 +		return -ENOSYS;
  30.289 +	return gnttab_map(0, nr_grant_frames - 1);
  30.290 +}
  30.291 +
  30.292  int gnttab_suspend(void)
  30.293  {
  30.294  #ifndef __ia64__
  30.295  	apply_to_page_range(&init_mm, (unsigned long)shared,
  30.296 -			    PAGE_SIZE * NR_GRANT_FRAMES,
  30.297 +			    PAGE_SIZE * nr_grant_frames,
  30.298  			    unmap_pte_fn, NULL);
  30.299  #endif
  30.300  	return 0;
  30.301 @@ -430,24 +515,39 @@ int gnttab_suspend(void)
  30.302  
  30.303  #include <platform-pci.h>
  30.304  
  30.305 -int gnttab_resume(void)
  30.306 +static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
  30.307  {
  30.308 -	unsigned long frames;
  30.309  	struct xen_add_to_physmap xatp;
  30.310  	unsigned int i;
  30.311  
  30.312 -	frames = alloc_xen_mmio(PAGE_SIZE * NR_GRANT_FRAMES);
  30.313 -
  30.314 -	for (i = 0; i < NR_GRANT_FRAMES; i++) {
  30.315 +	/* Loop backwards, so that the first hypercall has the largest index,
  30.316 +	 * ensuring that the table will grow only once.
  30.317 +	 */
  30.318 +	for (i = end_idx; i >= start_idx; i--) {
  30.319  		xatp.domid = DOMID_SELF;
  30.320  		xatp.idx = i;
  30.321  		xatp.space = XENMAPSPACE_grant_table;
  30.322 -		xatp.gpfn = (frames >> PAGE_SHIFT) + i;
  30.323 +		xatp.gpfn = (resume_frames >> PAGE_SHIFT) + i;
  30.324  		if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
  30.325  			BUG();
  30.326  	}
  30.327 +}
  30.328  
  30.329 -	shared = ioremap(frames, PAGE_SIZE * NR_GRANT_FRAMES);
  30.330 +int gnttab_resume(void)
  30.331 +{
  30.332 +	struct xen_add_to_physmap xatp;
  30.333 +	unsigned int i, max_nr_gframes, nr_gframes;
  30.334 +
  30.335 +	nr_gframes = nr_grant_frames;
  30.336 +	max_nr_gframes = max_nr_grant_frames();
  30.337 +	if (max_nr_gframes < nr_gframes)
  30.338 +		return -ENOSYS;
  30.339 +
  30.340 +	resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
  30.341 +
  30.342 +	gnttab_map(0, nr_gframes - 1);
  30.343 +
  30.344 +	shared = ioremap(resume_frames, PAGE_SIZE * max_nr_gframes);
  30.345  	if (shared == NULL) {
  30.346  		printk("error to ioremap gnttab share frames\n");
  30.347  		return -1;
  30.348 @@ -459,28 +559,79 @@ int gnttab_resume(void)
  30.349  int gnttab_suspend(void)
  30.350  {
  30.351  	iounmap(shared);
  30.352 +	resume_frames = 0;
  30.353  	return 0;
  30.354  }
  30.355  
  30.356  #endif /* !CONFIG_XEN */
  30.357  
  30.358 +static int gnttab_expand(unsigned int req_entries)
  30.359 +{
  30.360 +	int rc;
  30.361 +	unsigned int cur, extra;
  30.362 +
  30.363 +	cur = nr_grant_frames;
  30.364 +	extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
  30.365 +		 GREFS_PER_GRANT_FRAME);
  30.366 +	if (cur + extra > max_nr_grant_frames())
  30.367 +		return -ENOSPC;
  30.368 +
  30.369 +	if ((rc = gnttab_map(cur, cur + extra - 1)) == 0)
  30.370 +		rc = grow_gnttab_list(extra);
  30.371 +
  30.372 +	return rc;
  30.373 +}
  30.374 +
  30.375  int __devinit gnttab_init(void)
  30.376  {
  30.377  	int i;
  30.378 +	unsigned int max_nr_glist_frames;
  30.379 +	unsigned int nr_init_grefs;
  30.380  
  30.381  	if (!is_running_on_xen())
  30.382  		return -ENODEV;
  30.383  
  30.384 +	nr_grant_frames = 1;
  30.385 +	boot_max_nr_grant_frames = __max_nr_grant_frames();
  30.386 +
  30.387 +	/* Determine the maximum number of frames required for the
  30.388 +	 * grant reference free list on the current hypervisor.
  30.389 +	 */
  30.390 +	max_nr_glist_frames = (boot_max_nr_grant_frames *
  30.391 +			       GREFS_PER_GRANT_FRAME /
  30.392 +			       (PAGE_SIZE / sizeof(grant_ref_t)));
  30.393 +
  30.394 +	gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *),
  30.395 +			      GFP_KERNEL);
  30.396 +	if (gnttab_list == NULL)
  30.397 +		return -ENOMEM;
  30.398 +
  30.399 +	for (i = 0; i < nr_grant_frames; i++) {
  30.400 +		gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
  30.401 +		if (gnttab_list[i] == NULL)
  30.402 +			goto ini_nomem;
  30.403 +	}
  30.404 +
  30.405  	if (gnttab_resume() < 0)
  30.406  		return -ENODEV;
  30.407  
  30.408 -	for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
  30.409 -		gnttab_list[i] = i + 1;
  30.410 -	gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
  30.411 +	nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
  30.412 +
  30.413 +	for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++)
  30.414 +		gnttab_entry(i) = i + 1;
  30.415 +
  30.416 +	gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END;
  30.417 +	gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES;
  30.418  	gnttab_free_head  = NR_RESERVED_ENTRIES;
  30.419  
  30.420  	printk("Grant table initialized\n");
  30.421  	return 0;
  30.422 +
  30.423 + ini_nomem:
  30.424 +	for (i--; i >= 0; i--)
  30.425 +		free_page((unsigned long)gnttab_list[i]);
  30.426 +	kfree(gnttab_list);
  30.427 +	return -ENOMEM;
  30.428  }
  30.429  
  30.430  #ifdef CONFIG_XEN
    31.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Sun Feb 18 16:13:13 2007 -0700
    31.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Tue Feb 20 12:58:22 2007 -0700
    31.3 @@ -349,8 +349,7 @@ void __init smp_prepare_cpus(unsigned in
    31.4  
    31.5  void __devinit smp_prepare_boot_cpu(void)
    31.6  {
    31.7 -	cpu_present_map  = cpumask_of_cpu(0);
    31.8 -	cpu_online_map   = cpumask_of_cpu(0);
    31.9 +	prefill_possible_map();
   31.10  }
   31.11  
   31.12  #ifdef CONFIG_HOTPLUG_CPU
    32.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Sun Feb 18 16:13:13 2007 -0700
    32.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Tue Feb 20 12:58:22 2007 -0700
    32.3 @@ -194,15 +194,12 @@ static int map_frontend_pages(
    32.4  	netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref)
    32.5  {
    32.6  	struct gnttab_map_grant_ref op;
    32.7 -	int ret;
    32.8  
    32.9  	gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr,
   32.10  			  GNTMAP_host_map, tx_ring_ref, netif->domid);
   32.11      
   32.12 -	lock_vm_area(netif->tx_comms_area);
   32.13 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   32.14 -	unlock_vm_area(netif->tx_comms_area);
   32.15 -	BUG_ON(ret);
   32.16 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   32.17 +		BUG();
   32.18  
   32.19  	if (op.status) { 
   32.20  		DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
   32.21 @@ -215,10 +212,8 @@ static int map_frontend_pages(
   32.22  	gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr,
   32.23  			  GNTMAP_host_map, rx_ring_ref, netif->domid);
   32.24  
   32.25 -	lock_vm_area(netif->rx_comms_area);
   32.26 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   32.27 -	unlock_vm_area(netif->rx_comms_area);
   32.28 -	BUG_ON(ret);
   32.29 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   32.30 +		BUG();
   32.31  
   32.32  	if (op.status) {
   32.33  		DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
   32.34 @@ -234,23 +229,18 @@ static int map_frontend_pages(
   32.35  static void unmap_frontend_pages(netif_t *netif)
   32.36  {
   32.37  	struct gnttab_unmap_grant_ref op;
   32.38 -	int ret;
   32.39  
   32.40  	gnttab_set_unmap_op(&op, (unsigned long)netif->tx_comms_area->addr,
   32.41  			    GNTMAP_host_map, netif->tx_shmem_handle);
   32.42  
   32.43 -	lock_vm_area(netif->tx_comms_area);
   32.44 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   32.45 -	unlock_vm_area(netif->tx_comms_area);
   32.46 -	BUG_ON(ret);
   32.47 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   32.48 +		BUG();
   32.49  
   32.50  	gnttab_set_unmap_op(&op, (unsigned long)netif->rx_comms_area->addr,
   32.51  			    GNTMAP_host_map, netif->rx_shmem_handle);
   32.52  
   32.53 -	lock_vm_area(netif->rx_comms_area);
   32.54 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   32.55 -	unlock_vm_area(netif->rx_comms_area);
   32.56 -	BUG_ON(ret);
   32.57 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   32.58 +		BUG();
   32.59  }
   32.60  
   32.61  int netif_map(netif_t *netif, unsigned long tx_ring_ref,
    33.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Sun Feb 18 16:13:13 2007 -0700
    33.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Tue Feb 20 12:58:22 2007 -0700
    33.3 @@ -79,16 +79,13 @@ tpmif_t *tpmif_find(domid_t domid, struc
    33.4  
    33.5  static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
    33.6  {
    33.7 -	int ret;
    33.8  	struct gnttab_map_grant_ref op;
    33.9  
   33.10  	gnttab_set_map_op(&op, (unsigned long)tpmif->tx_area->addr,
   33.11  			  GNTMAP_host_map, shared_page, tpmif->domid);
   33.12  
   33.13 -	lock_vm_area(tpmif->tx_area);
   33.14 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   33.15 -	unlock_vm_area(tpmif->tx_area);
   33.16 -	BUG_ON(ret);
   33.17 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   33.18 +		BUG();
   33.19  
   33.20  	if (op.status) {
   33.21  		DPRINTK(" Grant table operation failure !\n");
   33.22 @@ -104,15 +101,12 @@ static int map_frontend_page(tpmif_t *tp
   33.23  static void unmap_frontend_page(tpmif_t *tpmif)
   33.24  {
   33.25  	struct gnttab_unmap_grant_ref op;
   33.26 -	int ret;
   33.27  
   33.28  	gnttab_set_unmap_op(&op, (unsigned long)tpmif->tx_area->addr,
   33.29  			    GNTMAP_host_map, tpmif->shmem_handle);
   33.30  
   33.31 -	lock_vm_area(tpmif->tx_area);
   33.32 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   33.33 -	unlock_vm_area(tpmif->tx_area);
   33.34 -	BUG_ON(ret);
   33.35 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   33.36 +		BUG();
   33.37  }
   33.38  
   33.39  int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
    34.1 --- a/linux-2.6-xen-sparse/drivers/xen/util.c	Sun Feb 18 16:13:13 2007 -0700
    34.2 +++ b/linux-2.6-xen-sparse/drivers/xen/util.c	Tue Feb 20 12:58:22 2007 -0700
    34.3 @@ -30,6 +30,11 @@ struct vm_struct *alloc_vm_area(unsigned
    34.4  		return NULL;
    34.5  	}
    34.6  
    34.7 +	/* Map page directories into every address space. */
    34.8 +#ifdef CONFIG_X86
    34.9 +	vmalloc_sync_all();
   34.10 +#endif
   34.11 +
   34.12  	return area;
   34.13  }
   34.14  EXPORT_SYMBOL_GPL(alloc_vm_area);
   34.15 @@ -42,29 +47,3 @@ void free_vm_area(struct vm_struct *area
   34.16  	kfree(area);
   34.17  }
   34.18  EXPORT_SYMBOL_GPL(free_vm_area);
   34.19 -
   34.20 -void lock_vm_area(struct vm_struct *area)
   34.21 -{
   34.22 -	unsigned long i;
   34.23 -	char c;
   34.24 -
   34.25 -	/*
   34.26 -	 * Prevent context switch to a lazy mm that doesn't have this area
   34.27 -	 * mapped into its page tables.
   34.28 -	 */
   34.29 -	preempt_disable();
   34.30 -
   34.31 -	/*
   34.32 -	 * Ensure that the page tables are mapped into the current mm. The
   34.33 -	 * page-fault path will copy the page directory pointers from init_mm.
   34.34 -	 */
   34.35 -	for (i = 0; i < area->size; i += PAGE_SIZE)
   34.36 -		(void)__get_user(c, (char __user *)area->addr + i);
   34.37 -}
   34.38 -EXPORT_SYMBOL_GPL(lock_vm_area);
   34.39 -
   34.40 -void unlock_vm_area(struct vm_struct *area)
   34.41 -{
   34.42 -	preempt_enable();
   34.43 -}
   34.44 -EXPORT_SYMBOL_GPL(unlock_vm_area);
    35.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c	Sun Feb 18 16:13:13 2007 -0700
    35.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c	Tue Feb 20 12:58:22 2007 -0700
    35.3 @@ -48,9 +48,8 @@ struct vm_struct *xenbus_map_ring_valloc
    35.4  	gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
    35.5  			  gnt_ref, dev->otherend_id);
    35.6  	
    35.7 -	lock_vm_area(area);
    35.8 -	BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
    35.9 -	unlock_vm_area(area);
   35.10 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   35.11 +		BUG();
   35.12  
   35.13  	if (op.status != GNTST_okay) {
   35.14  		free_vm_area(area);
   35.15 @@ -76,7 +75,8 @@ int xenbus_map_ring(struct xenbus_device
   35.16  	
   35.17  	gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
   35.18  			  gnt_ref, dev->otherend_id);
   35.19 -	BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
   35.20 +	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
   35.21 +		BUG();
   35.22  
   35.23  	if (op.status != GNTST_okay) {
   35.24  		xenbus_dev_fatal(dev, op.status,
   35.25 @@ -98,9 +98,8 @@ int xenbus_unmap_ring_vfree(struct xenbu
   35.26  	gnttab_set_unmap_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
   35.27  			    (grant_handle_t)area->phys_addr);
   35.28  
   35.29 -	lock_vm_area(area);
   35.30 -	BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
   35.31 -	unlock_vm_area(area);
   35.32 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   35.33 +		BUG();
   35.34  
   35.35  	if (op.status == GNTST_okay)
   35.36  		free_vm_area(area);
   35.37 @@ -121,7 +120,8 @@ int xenbus_unmap_ring(struct xenbus_devi
   35.38  
   35.39  	gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
   35.40  			    handle);
   35.41 -	BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
   35.42 +	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
   35.43 +		BUG();
   35.44  
   35.45  	if (op.status != GNTST_okay)
   35.46  		xenbus_dev_error(dev, op.status,
    36.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h	Sun Feb 18 16:13:13 2007 -0700
    36.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h	Tue Feb 20 12:58:22 2007 -0700
    36.3 @@ -56,6 +56,9 @@
    36.4  
    36.5  extern shared_info_t *HYPERVISOR_shared_info;
    36.6  
    36.7 +#define vcpu_info(cpu) (HYPERVISOR_shared_info->vcpu_info + (cpu))
    36.8 +#define current_vcpu_info() vcpu_info(smp_processor_id())
    36.9 +
   36.10  #ifdef CONFIG_X86_32
   36.11  extern unsigned long hypervisor_virt_start;
   36.12  #endif
    37.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h	Sun Feb 18 16:13:13 2007 -0700
    37.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h	Tue Feb 20 12:58:22 2007 -0700
    37.3 @@ -12,12 +12,6 @@
    37.4  
    37.5  #ifndef __ASSEMBLY__
    37.6  
    37.7 -#ifdef CONFIG_SMP
    37.8 -#define __vcpu_id smp_processor_id()
    37.9 -#else
   37.10 -#define __vcpu_id 0
   37.11 -#endif
   37.12 -
   37.13  /* 
   37.14   * The use of 'barrier' in the following reflects their use as local-lock
   37.15   * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
   37.16 @@ -26,8 +20,7 @@
   37.17   * includes these barriers, for example.
   37.18   */
   37.19  
   37.20 -#define __raw_local_save_flags()					\
   37.21 -	(&HYPERVISOR_shared_info->vcpu_info[__vcpu_id])->evtchn_upcall_mask;
   37.22 +#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
   37.23  
   37.24  #define raw_local_save_flags(flags) \
   37.25  		do { (flags) = __raw_local_save_flags(); } while (0)
   37.26 @@ -36,7 +29,7 @@
   37.27  do {									\
   37.28  	vcpu_info_t *_vcpu;						\
   37.29  	barrier();							\
   37.30 -	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
   37.31 +	_vcpu = current_vcpu_info();					\
   37.32  	if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {			\
   37.33  		barrier(); /* unmask then check (avoid races) */	\
   37.34  		if (unlikely(_vcpu->evtchn_upcall_pending))		\
   37.35 @@ -46,9 +39,7 @@ do {									\
   37.36  
   37.37  #define raw_local_irq_disable()						\
   37.38  do {									\
   37.39 -	vcpu_info_t *_vcpu;						\
   37.40 -	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
   37.41 -	_vcpu->evtchn_upcall_mask = 1;					\
   37.42 +	current_vcpu_info()->evtchn_upcall_mask = 1;			\
   37.43  	barrier();							\
   37.44  } while (0)
   37.45  
   37.46 @@ -56,7 +47,7 @@ do {									\
   37.47  do {									\
   37.48  	vcpu_info_t *_vcpu;						\
   37.49  	barrier();							\
   37.50 -	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
   37.51 +	_vcpu = current_vcpu_info();					\
   37.52  	_vcpu->evtchn_upcall_mask = 0;					\
   37.53  	barrier(); /* unmask then check (avoid races) */		\
   37.54  	if (unlikely(_vcpu->evtchn_upcall_pending))			\
    38.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h	Sun Feb 18 16:13:13 2007 -0700
    38.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h	Tue Feb 20 12:58:22 2007 -0700
    38.3 @@ -21,6 +21,7 @@ typedef unsigned long maddr_t;
    38.4  #ifdef CONFIG_XEN
    38.5  
    38.6  extern unsigned long *phys_to_machine_mapping;
    38.7 +extern unsigned long  max_mapnr;
    38.8  
    38.9  #undef machine_to_phys_mapping
   38.10  extern unsigned long *machine_to_phys_mapping;
   38.11 @@ -30,20 +31,20 @@ static inline unsigned long pfn_to_mfn(u
   38.12  {
   38.13  	if (xen_feature(XENFEAT_auto_translated_physmap))
   38.14  		return pfn;
   38.15 -	return phys_to_machine_mapping[(unsigned int)(pfn)] &
   38.16 -		~FOREIGN_FRAME_BIT;
   38.17 +	BUG_ON(max_mapnr && pfn >= max_mapnr);
   38.18 +	return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
   38.19  }
   38.20  
   38.21  static inline int phys_to_machine_mapping_valid(unsigned long pfn)
   38.22  {
   38.23  	if (xen_feature(XENFEAT_auto_translated_physmap))
   38.24  		return 1;
   38.25 +	BUG_ON(max_mapnr && pfn >= max_mapnr);
   38.26  	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
   38.27  }
   38.28  
   38.29  static inline unsigned long mfn_to_pfn(unsigned long mfn)
   38.30  {
   38.31 -	extern unsigned long max_mapnr;
   38.32  	unsigned long pfn;
   38.33  
   38.34  	if (xen_feature(XENFEAT_auto_translated_physmap))
   38.35 @@ -92,7 +93,6 @@ static inline unsigned long mfn_to_pfn(u
   38.36   */
   38.37  static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
   38.38  {
   38.39 -	extern unsigned long max_mapnr;
   38.40  	unsigned long pfn = mfn_to_pfn(mfn);
   38.41  	if ((pfn < max_mapnr)
   38.42  	    && !xen_feature(XENFEAT_auto_translated_physmap)
   38.43 @@ -103,6 +103,7 @@ static inline unsigned long mfn_to_local
   38.44  
   38.45  static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
   38.46  {
   38.47 +	BUG_ON(max_mapnr && pfn >= max_mapnr);
   38.48  	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   38.49  		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
   38.50  		return;
   38.51 @@ -124,6 +125,20 @@ static inline paddr_t machine_to_phys(ma
   38.52  	return phys;
   38.53  }
   38.54  
   38.55 +#ifdef CONFIG_X86_PAE
   38.56 +static inline paddr_t pte_phys_to_machine(paddr_t phys)
   38.57 +{
   38.58 +	/*
   38.59 +	 * In PAE mode, the NX bit needs to be dealt with in the value
   38.60 +	 * passed to pfn_to_mfn(). On x86_64, we need to mask it off,
   38.61 +	 * but for i386 the conversion to ulong for the argument will
   38.62 +	 * clip it off.
   38.63 +	 */
   38.64 +	maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
   38.65 +	machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
   38.66 +	return machine;
   38.67 +}
   38.68 +
   38.69  static inline paddr_t pte_machine_to_phys(maddr_t machine)
   38.70  {
   38.71  	/*
   38.72 @@ -136,6 +151,7 @@ static inline paddr_t pte_machine_to_phy
   38.73  	phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
   38.74  	return phys;
   38.75  }
   38.76 +#endif
   38.77  
   38.78  #else /* !CONFIG_XEN */
   38.79  
   38.80 @@ -146,7 +162,6 @@ static inline paddr_t pte_machine_to_phy
   38.81  #define phys_to_machine_mapping_valid(pfn) (1)
   38.82  #define phys_to_machine(phys) ((maddr_t)(phys))
   38.83  #define machine_to_phys(mach) ((paddr_t)(mach))
   38.84 -#define pte_machine_to_phys(mach) ((paddr_t)(mach))
   38.85  
   38.86  #endif /* !CONFIG_XEN */
   38.87  
    39.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Sun Feb 18 16:13:13 2007 -0700
    39.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h	Tue Feb 20 12:58:22 2007 -0700
    39.3 @@ -29,6 +29,13 @@
    39.4  #include <xen/interface/xen.h>
    39.5  #include <xen/features.h>
    39.6  
    39.7 +/*
    39.8 + * Need to repeat this here in order to not include pgtable.h (which in turn
    39.9 + * depends on definitions made here), but to be able to use the symbolic
   39.10 + * below. The preprocessor will warn if the two definitions aren't identical.
   39.11 + */
   39.12 +#define _PAGE_PRESENT	0x001
   39.13 +
   39.14  #define arch_free_page(_page,_order)		\
   39.15  ({	int foreign = PageForeign(_page);	\
   39.16  	if (foreign)				\
   39.17 @@ -81,40 +88,38 @@ typedef struct { unsigned long long pgpr
   39.18  #define pgprot_val(x)	((x).pgprot)
   39.19  #include <asm/maddr.h>
   39.20  #define __pte(x) ({ unsigned long long _x = (x);        \
   39.21 -    if (_x & 1) _x = phys_to_machine(_x);               \
   39.22 +    if (_x & _PAGE_PRESENT) _x = pte_phys_to_machine(_x);   \
   39.23      ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
   39.24  #define __pgd(x) ({ unsigned long long _x = (x); \
   39.25 -    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
   39.26 +    (pgd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
   39.27  #define __pmd(x) ({ unsigned long long _x = (x); \
   39.28 -    (((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); })
   39.29 +    (pmd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
   39.30 +static inline unsigned long long pte_val_ma(pte_t x)
   39.31 +{
   39.32 +	return ((unsigned long long)x.pte_high << 32) | x.pte_low;
   39.33 +}
   39.34  static inline unsigned long long pte_val(pte_t x)
   39.35  {
   39.36 -	unsigned long long ret;
   39.37 -
   39.38 -	if (x.pte_low) {
   39.39 -		ret = x.pte_low | (unsigned long long)x.pte_high << 32;
   39.40 -		ret = pte_machine_to_phys(ret) | 1;
   39.41 -	} else {
   39.42 -		ret = 0;
   39.43 -	}
   39.44 +	unsigned long long ret = pte_val_ma(x);
   39.45 +	if (x.pte_low & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
   39.46  	return ret;
   39.47  }
   39.48  static inline unsigned long long pmd_val(pmd_t x)
   39.49  {
   39.50  	unsigned long long ret = x.pmd;
   39.51 -	if (ret) ret = pte_machine_to_phys(ret) | 1;
   39.52 +#ifdef CONFIG_XEN_COMPAT_030002
   39.53 +	if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
   39.54 +#else
   39.55 +	if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
   39.56 +#endif
   39.57  	return ret;
   39.58  }
   39.59  static inline unsigned long long pgd_val(pgd_t x)
   39.60  {
   39.61  	unsigned long long ret = x.pgd;
   39.62 -	if (ret) ret = pte_machine_to_phys(ret) | 1;
   39.63 +	if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
   39.64  	return ret;
   39.65  }
   39.66 -static inline unsigned long long pte_val_ma(pte_t x)
   39.67 -{
   39.68 -	return (unsigned long long)x.pte_high << 32 | x.pte_low;
   39.69 -}
   39.70  #define HPAGE_SHIFT	21
   39.71  #else
   39.72  typedef struct { unsigned long pte_low; } pte_t;
   39.73 @@ -123,23 +128,23 @@ typedef struct { unsigned long pgprot; }
   39.74  #define pgprot_val(x)	((x).pgprot)
   39.75  #include <asm/maddr.h>
   39.76  #define boot_pte_t pte_t /* or would you rather have a typedef */
   39.77 -#define pte_val(x)	(((x).pte_low & 1) ? \
   39.78 -			 pte_machine_to_phys((x).pte_low) : \
   39.79 +#define pte_val(x)	(((x).pte_low & _PAGE_PRESENT) ? \
   39.80 +			 machine_to_phys((x).pte_low) : \
   39.81  			 (x).pte_low)
   39.82  #define pte_val_ma(x)	((x).pte_low)
   39.83  #define __pte(x) ({ unsigned long _x = (x); \
   39.84 -    (((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
   39.85 +    (pte_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
   39.86  #define __pgd(x) ({ unsigned long _x = (x); \
   39.87 -    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
   39.88 +    (pgd_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
   39.89  static inline unsigned long pgd_val(pgd_t x)
   39.90  {
   39.91  	unsigned long ret = x.pgd;
   39.92 -	if (ret) ret = pte_machine_to_phys(ret) | 1;
   39.93 +	if (ret & _PAGE_PRESENT) ret = machine_to_phys(ret);
   39.94  	return ret;
   39.95  }
   39.96  #define HPAGE_SHIFT	22
   39.97  #endif
   39.98 -#define PTE_MASK	PAGE_MASK
   39.99 +#define PTE_MASK	PHYSICAL_PAGE_MASK
  39.100  
  39.101  #ifdef CONFIG_HUGETLB_PAGE
  39.102  #define HPAGE_SIZE	((1UL) << HPAGE_SHIFT)
    40.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h	Sun Feb 18 16:13:13 2007 -0700
    40.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h	Tue Feb 20 12:58:22 2007 -0700
    40.3 @@ -38,8 +38,11 @@
    40.4  
    40.5  #define ptep_get_and_clear(mm,addr,xp)	__pte_ma(xchg(&(xp)->pte_low, 0))
    40.6  #define pte_same(a, b)		((a).pte_low == (b).pte_low)
    40.7 -#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
    40.8 -#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
    40.9 +#define __pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
   40.10 +#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
   40.11 +	__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
   40.12 +#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
   40.13 +	mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
   40.14  
   40.15  #define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
   40.16  
    41.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h	Sun Feb 18 16:13:13 2007 -0700
    41.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h	Tue Feb 20 12:58:22 2007 -0700
    41.3 @@ -52,22 +52,14 @@ static inline int pte_exec_kernel(pte_t 
    41.4   */
    41.5  #define __HAVE_ARCH_SET_PTE_ATOMIC
    41.6  
    41.7 -#if 1
    41.8 -/* use writable pagetables */
    41.9  static inline void set_pte(pte_t *ptep, pte_t pte)
   41.10  {
   41.11  	ptep->pte_high = pte.pte_high;
   41.12  	smp_wmb();
   41.13  	ptep->pte_low = pte.pte_low;
   41.14  }
   41.15 -# define set_pte_atomic(pteptr,pteval) \
   41.16 +#define set_pte_atomic(pteptr,pteval) \
   41.17  		set_64bit((unsigned long long *)(pteptr),pte_val_ma(pteval))
   41.18 -#else
   41.19 -/* no writable pagetables */
   41.20 -# define set_pte(pteptr,pteval)				\
   41.21 -		xen_l1_entry_update((pteptr), (pteval))
   41.22 -# define set_pte_atomic(pteptr,pteval) set_pte(pteptr,pteval)
   41.23 -#endif
   41.24  
   41.25  #define set_pte_at(_mm,addr,ptep,pteval) do {				\
   41.26  	if (((_mm) != current->mm && (_mm) != &init_mm) ||		\
   41.27 @@ -145,21 +137,24 @@ static inline int pte_none(pte_t pte)
   41.28  	return !pte.pte_low && !pte.pte_high;
   41.29  }
   41.30  
   41.31 -#define pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) |\
   41.32 -		       (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)))
   41.33 -#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
   41.34 +#define __pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) | \
   41.35 +			 ((_pte).pte_high << (32-PAGE_SHIFT)))
   41.36 +#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
   41.37 +	__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
   41.38 +#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
   41.39 +	mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
   41.40  
   41.41  extern unsigned long long __supported_pte_mask;
   41.42  
   41.43  static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
   41.44  {
   41.45 -	return pfn_pte_ma(pfn_to_mfn(page_nr), pgprot);
   41.46 +	return __pte((((unsigned long long)page_nr << PAGE_SHIFT) |
   41.47 +			pgprot_val(pgprot)) & __supported_pte_mask);
   41.48  }
   41.49  
   41.50  static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
   41.51  {
   41.52 -	BUG(); panic("needs review");
   41.53 -	return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \
   41.54 +	return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) |
   41.55  			pgprot_val(pgprot)) & __supported_pte_mask);
   41.56  }
   41.57  
   41.58 @@ -180,6 +175,6 @@ static inline pmd_t pfn_pmd(unsigned lon
   41.59  
   41.60  #define __pmd_free_tlb(tlb, x)		do { } while (0)
   41.61  
   41.62 -#define vmalloc_sync_all() ((void)0)
   41.63 +void vmalloc_sync_all(void);
   41.64  
   41.65  #endif /* _I386_PGTABLE_3LEVEL_H */
    42.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h	Sun Feb 18 16:13:13 2007 -0700
    42.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h	Tue Feb 20 12:58:22 2007 -0700
    42.3 @@ -315,18 +315,19 @@ static inline void clone_pgd_range(pgd_t
    42.4  
    42.5  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
    42.6  {
    42.7 -	pte.pte_low &= _PAGE_CHG_MASK;
    42.8 -	pte.pte_low |= pgprot_val(newprot);
    42.9 -#ifdef CONFIG_X86_PAE
   42.10  	/*
   42.11 -	 * Chop off the NX bit (if present), and add the NX portion of
   42.12 -	 * the newprot (if present):
   42.13 +	 * Since this might change the present bit (which controls whether
   42.14 +	 * a pte_t object has undergone p2m translation), we must use
   42.15 +	 * pte_val() on the input pte and __pte() for the return value.
   42.16  	 */
   42.17 -	pte.pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
   42.18 -	pte.pte_high |= (pgprot_val(newprot) >> 32) & \
   42.19 -					(__supported_pte_mask >> 32);
   42.20 +	paddr_t pteval = pte_val(pte);
   42.21 +
   42.22 +	pteval &= _PAGE_CHG_MASK;
   42.23 +	pteval |= pgprot_val(newprot);
   42.24 +#ifdef CONFIG_X86_PAE
   42.25 +	pteval &= __supported_pte_mask;
   42.26  #endif
   42.27 -	return pte;
   42.28 +	return __pte(pteval);
   42.29  }
   42.30  
   42.31  #define pmd_large(pmd) \
   42.32 @@ -432,12 +433,15 @@ extern void noexec_setup(const char *str
   42.33  #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
   42.34  	do {								  \
   42.35  		if (__dirty) {						  \
   42.36 -		        if ( likely((__vma)->vm_mm == current->mm) ) {    \
   42.37 -			    BUG_ON(HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
   42.38 -			} else {                                          \
   42.39 -                            xen_l1_entry_update((__ptep), (__entry)); \
   42.40 -			    flush_tlb_page((__vma), (__address));         \
   42.41 -			}                                                 \
   42.42 +			if ( likely((__vma)->vm_mm == current->mm) ) {	  \
   42.43 +				BUG_ON(HYPERVISOR_update_va_mapping(__address, \
   42.44 +					__entry,			  \
   42.45 +					(unsigned long)(__vma)->vm_mm->cpu_vm_mask.bits| \
   42.46 +					UVMF_INVLPG|UVMF_MULTI));	  \
   42.47 +			} else {					  \
   42.48 +				xen_l1_entry_update(__ptep, __entry);	  \
   42.49 +				flush_tlb_page(__vma, __address);	  \
   42.50 +			}						  \
   42.51  		}							  \
   42.52  	} while (0)
   42.53  
    43.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h	Sun Feb 18 16:13:13 2007 -0700
    43.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h	Tue Feb 20 12:58:22 2007 -0700
    43.3 @@ -100,8 +100,7 @@ extern struct task_struct * FASTCALL(__s
    43.4  #define write_cr0(x) \
    43.5  	__asm__ __volatile__("movl %0,%%cr0": :"r" (x))
    43.6  
    43.7 -#define read_cr2() \
    43.8 -	(HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
    43.9 +#define read_cr2() (current_vcpu_info()->arch.cr2)
   43.10  #define write_cr2(x) \
   43.11  	__asm__ __volatile__("movl %0,%%cr2": :"r" (x))
   43.12  
    44.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h	Sun Feb 18 16:13:13 2007 -0700
    44.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h	Tue Feb 20 12:58:22 2007 -0700
    44.3 @@ -15,12 +15,6 @@
    44.4   * Interrupt control:
    44.5   */
    44.6  
    44.7 -#ifdef CONFIG_SMP
    44.8 -#define __vcpu_id smp_processor_id()
    44.9 -#else
   44.10 -#define __vcpu_id 0
   44.11 -#endif
   44.12 -
   44.13  /*
   44.14   * The use of 'barrier' in the following reflects their use as local-lock
   44.15   * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
   44.16 @@ -29,8 +23,7 @@
   44.17   * includes these barriers, for example.
   44.18   */
   44.19  
   44.20 -#define __raw_local_save_flags()					\
   44.21 -	(&HYPERVISOR_shared_info->vcpu_info[__vcpu_id])->evtchn_upcall_mask;
   44.22 +#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
   44.23  
   44.24  #define raw_local_save_flags(flags) \
   44.25  		do { (flags) = __raw_local_save_flags(); } while (0)
   44.26 @@ -39,7 +32,7 @@
   44.27  do {									\
   44.28  	vcpu_info_t *_vcpu;						\
   44.29  	barrier();							\
   44.30 -	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
   44.31 +	_vcpu = current_vcpu_info();		\
   44.32  	if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {			\
   44.33  		barrier(); /* unmask then check (avoid races) */	\
   44.34  		if ( unlikely(_vcpu->evtchn_upcall_pending) )		\
   44.35 @@ -76,9 +69,7 @@ static inline int raw_irqs_disabled_flag
   44.36  
   44.37  #define raw_local_irq_disable()						\
   44.38  do {									\
   44.39 -	vcpu_info_t *_vcpu;						\
   44.40 -	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
   44.41 -	_vcpu->evtchn_upcall_mask = 1;					\
   44.42 +	current_vcpu_info()->evtchn_upcall_mask = 1;					\
   44.43  	barrier();							\
   44.44  } while (0)
   44.45  
   44.46 @@ -86,7 +77,7 @@ do {									\
   44.47  do {									\
   44.48  	vcpu_info_t *_vcpu;						\
   44.49  	barrier();							\
   44.50 -	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];		\
   44.51 +	_vcpu = current_vcpu_info();		\
   44.52  	_vcpu->evtchn_upcall_mask = 0;					\
   44.53  	barrier(); /* unmask then check (avoid races) */		\
   44.54  	if ( unlikely(_vcpu->evtchn_upcall_pending) )			\
    45.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h	Sun Feb 18 16:13:13 2007 -0700
    45.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h	Tue Feb 20 12:58:22 2007 -0700
    45.3 @@ -25,14 +25,15 @@ static inline unsigned long pfn_to_mfn(u
    45.4  {
    45.5  	if (xen_feature(XENFEAT_auto_translated_physmap))
    45.6  		return pfn;
    45.7 -	return phys_to_machine_mapping[(unsigned int)(pfn)] &
    45.8 -		~FOREIGN_FRAME_BIT;
    45.9 +	BUG_ON(end_pfn && pfn >= end_pfn);
   45.10 +	return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
   45.11  }
   45.12  
   45.13  static inline int phys_to_machine_mapping_valid(unsigned long pfn)
   45.14  {
   45.15  	if (xen_feature(XENFEAT_auto_translated_physmap))
   45.16  		return 1;
   45.17 +	BUG_ON(end_pfn && pfn >= end_pfn);
   45.18  	return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
   45.19  }
   45.20  
   45.21 @@ -96,6 +97,7 @@ static inline unsigned long mfn_to_local
   45.22  
   45.23  static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
   45.24  {
   45.25 +	BUG_ON(end_pfn && pfn >= end_pfn);
   45.26  	if (xen_feature(XENFEAT_auto_translated_physmap)) {
   45.27  		BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
   45.28  		return;
   45.29 @@ -117,6 +119,14 @@ static inline paddr_t machine_to_phys(ma
   45.30  	return phys;
   45.31  }
   45.32  
   45.33 +static inline paddr_t pte_phys_to_machine(paddr_t phys)
   45.34 +{
   45.35 +	maddr_t machine;
   45.36 +	machine = pfn_to_mfn((phys & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT);
   45.37 +	machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
   45.38 +	return machine;
   45.39 +}
   45.40 +
   45.41  static inline paddr_t pte_machine_to_phys(maddr_t machine)
   45.42  {
   45.43  	paddr_t phys;
   45.44 @@ -134,7 +144,6 @@ static inline paddr_t pte_machine_to_phy
   45.45  #define phys_to_machine_mapping_valid(pfn) (1)
   45.46  #define phys_to_machine(phys) ((maddr_t)(phys))
   45.47  #define machine_to_phys(mach) ((paddr_t)(mach))
   45.48 -#define pte_machine_to_phys(mach) ((paddr_t)(mach))
   45.49  
   45.50  #endif /* !CONFIG_XEN */
   45.51  
    46.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Sun Feb 18 16:13:13 2007 -0700
    46.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h	Tue Feb 20 12:58:22 2007 -0700
    46.3 @@ -9,6 +9,13 @@
    46.4  #endif
    46.5  #include <xen/interface/xen.h> 
    46.6  
    46.7 +/*
    46.8 + * Need to repeat this here in order to not include pgtable.h (which in turn
    46.9 + * depends on definitions made here), but to be able to use the symbolic
   46.10 + * below. The preprocessor will warn if the two definitions aren't identical.
   46.11 + */
   46.12 +#define _PAGE_PRESENT	0x001
   46.13 +
   46.14  #define arch_free_page(_page,_order)		\
   46.15  ({	int foreign = PageForeign(_page);	\
   46.16  	if (foreign)				\
   46.17 @@ -95,28 +102,33 @@ typedef struct { unsigned long pgd; } pg
   46.18  
   46.19  typedef struct { unsigned long pgprot; } pgprot_t;
   46.20  
   46.21 -#define pte_val(x)	(((x).pte & 1) ? pte_machine_to_phys((x).pte) : \
   46.22 +#define pte_val(x)	(((x).pte & _PAGE_PRESENT) ? \
   46.23 +			 pte_machine_to_phys((x).pte) : \
   46.24  			 (x).pte)
   46.25  #define pte_val_ma(x)	((x).pte)
   46.26  
   46.27  static inline unsigned long pmd_val(pmd_t x)
   46.28  {
   46.29  	unsigned long ret = x.pmd;
   46.30 -	if (ret) ret = pte_machine_to_phys(ret);
   46.31 +#ifdef CONFIG_XEN_COMPAT_030002
   46.32 +	if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
   46.33 +#else
   46.34 +	if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
   46.35 +#endif
   46.36  	return ret;
   46.37  }
   46.38  
   46.39  static inline unsigned long pud_val(pud_t x)
   46.40  {
   46.41  	unsigned long ret = x.pud;
   46.42 -	if (ret) ret = pte_machine_to_phys(ret);
   46.43 +	if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
   46.44  	return ret;
   46.45  }
   46.46  
   46.47  static inline unsigned long pgd_val(pgd_t x)
   46.48  {
   46.49  	unsigned long ret = x.pgd;
   46.50 -	if (ret) ret = pte_machine_to_phys(ret);
   46.51 +	if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
   46.52  	return ret;
   46.53  }
   46.54  
   46.55 @@ -124,25 +136,25 @@ static inline unsigned long pgd_val(pgd_
   46.56  
   46.57  static inline pte_t __pte(unsigned long x)
   46.58  {
   46.59 -	if (x & 1) x = phys_to_machine(x);
   46.60 +	if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
   46.61  	return ((pte_t) { (x) });
   46.62  }
   46.63  
   46.64  static inline pmd_t __pmd(unsigned long x)
   46.65  {
   46.66 -	if ((x & 1)) x = phys_to_machine(x);
   46.67 +	if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
   46.68  	return ((pmd_t) { (x) });
   46.69  }
   46.70  
   46.71  static inline pud_t __pud(unsigned long x)
   46.72  {
   46.73 -	if ((x & 1)) x = phys_to_machine(x);
   46.74 +	if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
   46.75  	return ((pud_t) { (x) });
   46.76  }
   46.77  
   46.78  static inline pgd_t __pgd(unsigned long x)
   46.79  {
   46.80 -	if ((x & 1)) x = phys_to_machine(x);
   46.81 +	if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
   46.82  	return ((pgd_t) { (x) });
   46.83  }
   46.84  
    47.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h	Sun Feb 18 16:13:13 2007 -0700
    47.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h	Tue Feb 20 12:58:22 2007 -0700
    47.3 @@ -302,19 +302,20 @@ static inline unsigned long pud_bad(pud_
    47.4  
    47.5  #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
    47.6  
    47.7 -#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
    47.8 -#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
    47.9 +#define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
   47.10 +#define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
   47.11 +	__pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
   47.12 +#define pte_pfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
   47.13 +	mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
   47.14  
   47.15  #define pte_page(x)	pfn_to_page(pte_pfn(x))
   47.16  
   47.17  static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
   47.18  {
   47.19 -	pte_t pte;
   47.20 -        
   47.21 -	(pte).pte = (pfn_to_mfn(page_nr) << PAGE_SHIFT);
   47.22 -	(pte).pte |= pgprot_val(pgprot);
   47.23 -	(pte).pte &= __supported_pte_mask;
   47.24 -	return pte;
   47.25 +	unsigned long pte = page_nr << PAGE_SHIFT;
   47.26 +	pte |= pgprot_val(pgprot);
   47.27 +	pte &= __supported_pte_mask;
   47.28 +	return __pte(pte);
   47.29  }
   47.30  
   47.31  /*
   47.32 @@ -446,18 +447,25 @@ static inline pud_t *pud_offset_k(pgd_t 
   47.33  /* physical address -> PTE */
   47.34  static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
   47.35  { 
   47.36 -	pte_t pte;
   47.37 -	(pte).pte = physpage | pgprot_val(pgprot); 
   47.38 -	return pte; 
   47.39 +	unsigned long pteval;
   47.40 +	pteval = physpage | pgprot_val(pgprot);
   47.41 +	return __pte(pteval);
   47.42  }
   47.43   
   47.44  /* Change flags of a PTE */
   47.45  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
   47.46  { 
   47.47 -        (pte).pte &= _PAGE_CHG_MASK;
   47.48 -	(pte).pte |= pgprot_val(newprot);
   47.49 -	(pte).pte &= __supported_pte_mask;
   47.50 -       return pte; 
   47.51 +	/*
   47.52 +	 * Since this might change the present bit (which controls whether
   47.53 +	 * a pte_t object has undergone p2m translation), we must use
   47.54 +	 * pte_val() on the input pte and __pte() for the return value.
   47.55 +	 */
   47.56 +	unsigned long pteval = pte_val(pte);
   47.57 +
   47.58 +	pteval &= _PAGE_CHG_MASK;
   47.59 +	pteval |= pgprot_val(newprot);
   47.60 +	pteval &= __supported_pte_mask;
   47.61 +	return __pte(pteval);
   47.62  }
   47.63  
   47.64  #define pte_index(address) \
   47.65 @@ -479,24 +487,18 @@ static inline pte_t pte_modify(pte_t pte
   47.66   * race with other CPU's that might be updating the dirty
   47.67   * bit at the same time. */
   47.68  #define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
   47.69 -#if 0
   47.70  #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
   47.71  	do {								  \
   47.72  		if (__dirty) {						  \
   47.73 -			set_pte(__ptep, __entry);			  \
   47.74 -			flush_tlb_page(__vma, __address);		  \
   47.75 -		}							  \
   47.76 -	} while (0)
   47.77 -#endif
   47.78 -#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
   47.79 -	do {								  \
   47.80 -		if (__dirty) {						  \
   47.81 -		        if ( likely((__vma)->vm_mm == current->mm) ) {    \
   47.82 -			    BUG_ON(HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
   47.83 -			} else {                                          \
   47.84 -                            xen_l1_entry_update((__ptep), (__entry)); \
   47.85 -			    flush_tlb_page((__vma), (__address));         \
   47.86 -			}                                                 \
   47.87 +			if ( likely((__vma)->vm_mm == current->mm) ) {	  \
   47.88 +				BUG_ON(HYPERVISOR_update_va_mapping(__address, \
   47.89 +					__entry,			  \
   47.90 +					(unsigned long)(__vma)->vm_mm->cpu_vm_mask.bits| \
   47.91 +						UVMF_INVLPG|UVMF_MULTI)); \
   47.92 +			} else {					  \
   47.93 +				xen_l1_entry_update(__ptep, __entry);	  \
   47.94 +				flush_tlb_page(__vma, __address);	  \
   47.95 +			}						  \
   47.96  		}							  \
   47.97  	} while (0)
   47.98  
    48.1 --- a/linux-2.6-xen-sparse/include/linux/pfn.h	Sun Feb 18 16:13:13 2007 -0700
    48.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.3 @@ -1,9 +0,0 @@
    48.4 -#ifndef _LINUX_PFN_H_
    48.5 -#define _LINUX_PFN_H_
    48.6 -
    48.7 -#define PFN_ALIGN(x)	(((unsigned long long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
    48.8 -#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
    48.9 -#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
   48.10 -#define PFN_PHYS(x)	((unsigned long long)(x) << PAGE_SHIFT)
   48.11 -
   48.12 -#endif
    49.1 --- a/linux-2.6-xen-sparse/include/xen/driver_util.h	Sun Feb 18 16:13:13 2007 -0700
    49.2 +++ b/linux-2.6-xen-sparse/include/xen/driver_util.h	Tue Feb 20 12:58:22 2007 -0700
    49.3 @@ -9,8 +9,4 @@
    49.4  extern struct vm_struct *alloc_vm_area(unsigned long size);
    49.5  extern void free_vm_area(struct vm_struct *area);
    49.6  
    49.7 -/* Lock an area so that PTEs are accessible in the current address space. */
    49.8 -extern void lock_vm_area(struct vm_struct *area);
    49.9 -extern void unlock_vm_area(struct vm_struct *area);
   49.10 -
   49.11  #endif /* __ASM_XEN_DRIVER_UTIL_H__ */
    50.1 --- a/linux-2.6-xen-sparse/include/xen/gnttab.h	Sun Feb 18 16:13:13 2007 -0700
    50.2 +++ b/linux-2.6-xen-sparse/include/xen/gnttab.h	Tue Feb 20 12:58:22 2007 -0700
    50.3 @@ -43,13 +43,6 @@
    50.4  #include <xen/interface/grant_table.h>
    50.5  #include <xen/features.h>
    50.6  
    50.7 -/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
    50.8 -#ifdef __ia64__
    50.9 -#define NR_GRANT_FRAMES 1
   50.10 -#else
   50.11 -#define NR_GRANT_FRAMES 4
   50.12 -#endif
   50.13 -
   50.14  struct gnttab_free_callback {
   50.15  	struct gnttab_free_callback *next;
   50.16  	void (*fn)(void *);
   50.17 @@ -109,12 +102,6 @@ void gnttab_grant_foreign_access_ref(gra
   50.18  void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
   50.19  				       unsigned long pfn);
   50.20  
   50.21 -#ifdef __ia64__
   50.22 -#define gnttab_map_vaddr(map) __va(map.dev_bus_addr)
   50.23 -#else
   50.24 -#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
   50.25 -#endif
   50.26 -
   50.27  int gnttab_suspend(void);
   50.28  int gnttab_resume(void);
   50.29  
    51.1 --- a/patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch	Sun Feb 18 16:13:13 2007 -0700
    51.2 +++ b/patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch	Tue Feb 20 12:58:22 2007 -0700
    51.3 @@ -1,7 +1,7 @@
    51.4  diff -pruN ../orig-linux-2.6.18/include/linux/elfnote.h ./include/linux/elfnote.h
    51.5  --- ../orig-linux-2.6.18/include/linux/elfnote.h	2007-01-12 18:19:44.000000000 +0000
    51.6  +++ ./include/linux/elfnote.h	2007-01-12 18:21:02.000000000 +0000
    51.7 -@@ -31,22 +31,24 @@
    51.8 +@@ -31,22 +31,38 @@
    51.9   /*
   51.10    * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
   51.11    * turn out to be the same size and shape), followed by the name and
   51.12 @@ -25,9 +25,21 @@ diff -pruN ../orig-linux-2.6.18/include/
   51.13  -2:.align 4
   51.14  -3:\desc
   51.15  -4:.align 4
   51.16 --.popsection
   51.17 ++#ifdef __STDC__
   51.18 ++#define ELFNOTE(name, type, desctype, descdata...) \
   51.19 ++.pushsection .note.name			;	\
   51.20 ++  .align 4				;	\
   51.21 ++  .long 2f - 1f		/* namesz */	;	\
   51.22 ++  .long 4f - 3f		/* descsz */	;	\
   51.23 ++  .long type				;	\
   51.24 ++1:.asciz #name				;	\
   51.25 ++2:.align 4				;	\
   51.26 ++3:desctype descdata			;	\
   51.27 ++4:.align 4				;	\
   51.28 + .popsection
   51.29  -.endm
   51.30 -+#define ELFNOTE(name, type, desctype, descdata)	\
   51.31 ++#else /* !__STDC__, i.e. -traditional */
   51.32 ++#define ELFNOTE(name, type, desctype, descdata) \
   51.33  +.pushsection .note.name			;	\
   51.34  +  .align 4				;	\
   51.35  +  .long 2f - 1f		/* namesz */	;	\
   51.36 @@ -37,7 +49,8 @@ diff -pruN ../orig-linux-2.6.18/include/
   51.37  +2:.align 4				;	\
   51.38  +3:desctype descdata			;	\
   51.39  +4:.align 4				;	\
   51.40 -+.popsection				;
   51.41 ++.popsection
   51.42 ++#endif /* __STDC__ */
   51.43   #else	/* !__ASSEMBLER__ */
   51.44   #include <linux/elf.h>
   51.45   /*
    52.1 --- a/tools/blktap/drivers/Makefile	Sun Feb 18 16:13:13 2007 -0700
    52.2 +++ b/tools/blktap/drivers/Makefile	Tue Feb 20 12:58:22 2007 -0700
    52.3 @@ -5,7 +5,7 @@ INCLUDES += -I.. -I../lib
    52.4  
    52.5  IBIN         = blktapctrl tapdisk
    52.6  QCOW_UTIL    = img2qcow qcow2raw qcow-create
    52.7 -INST_DIR  = /usr/sbin
    52.8 +INST_DIR     = /usr/sbin
    52.9  LIBAIO_DIR   = ../../libaio/src
   52.10  
   52.11  CFLAGS   += -Werror
   52.12 @@ -17,7 +17,7 @@ CFLAGS   += -D_GNU_SOURCE
   52.13  
   52.14  # Get gcc to generate the dependencies for us.
   52.15  CFLAGS   += -Wp,-MD,.$(@F).d
   52.16 -DEPS     = .*.d
   52.17 +DEPS      = .*.d
   52.18  
   52.19  THREADLIB := -lpthread -lz
   52.20  LIBS      := -L. -L.. -L../lib
   52.21 @@ -29,10 +29,10 @@ LIBS      += -L$(XEN_XENSTORE) -lxenstor
   52.22  
   52.23  AIOLIBS   := $(LIBAIO_DIR)/libaio.a
   52.24  
   52.25 -BLK-OBJS  := block-aio.o 
   52.26 -BLK-OBJS  += block-sync.o 
   52.27 +BLK-OBJS  := block-aio.o
   52.28 +BLK-OBJS  += block-sync.o
   52.29  BLK-OBJS  += block-vmdk.o
   52.30 -BLK-OBJS  += block-ram.o 
   52.31 +BLK-OBJS  += block-ram.o
   52.32  BLK-OBJS  += block-qcow.o
   52.33  BLK-OBJS  += aes.o
   52.34  
   52.35 @@ -52,13 +52,13 @@ tapdisk: $(BLK-OBJS) tapdisk.c
   52.36  qcow-util: img2qcow qcow2raw qcow-create
   52.37  
   52.38  img2qcow qcow2raw qcow-create: %: $(BLK-OBJS)
   52.39 -	$(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS)  $(LIBS)
   52.40 +	$(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS) $(LIBS)
   52.41  
   52.42  install: all
   52.43 -	$(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(DESTDIR)$(INST_DIR)
   52.44 +	$(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(VHD_UTIL) $(DESTDIR)$(INST_DIR)
   52.45  
   52.46  clean:
   52.47 -	rm -rf *.o *~ $(DEPS) xen TAGS $(IBIN) $(LIB) $(QCOW_UTIL)
   52.48 +	rm -rf *.o *~ $(DEPS) xen TAGS $(IBIN) $(LIB) $(QCOW_UTIL) $(VHD_UTIL)
   52.49  
   52.50  .PHONY: clean install
   52.51  
    53.1 --- a/tools/blktap/drivers/block-aio.c	Sun Feb 18 16:13:13 2007 -0700
    53.2 +++ b/tools/blktap/drivers/block-aio.c	Tue Feb 20 12:58:22 2007 -0700
    53.3 @@ -58,6 +58,7 @@ struct pending_aio {
    53.4  	td_callback_t cb;
    53.5  	int id;
    53.6  	void *private;
    53.7 +	uint64_t lsec;
    53.8  };
    53.9  
   53.10  struct tdaio_state {
   53.11 @@ -139,12 +140,23 @@ static int get_image_info(struct td_stat
   53.12  	return 0;
   53.13  }
   53.14  
   53.15 +static inline void init_fds(struct disk_driver *dd)
   53.16 +{
   53.17 +	int i;
   53.18 +	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
   53.19 +
   53.20 +	for(i = 0; i < MAX_IOFD; i++) 
   53.21 +		dd->io_fd[i] = 0;
   53.22 +
   53.23 +	dd->io_fd[0] = prv->poll_fd;
   53.24 +}
   53.25 +
   53.26  /* Open the disk file and initialize aio state. */
   53.27 -int tdaio_open (struct td_state *s, const char *name)
   53.28 +int tdaio_open (struct disk_driver *dd, const char *name)
   53.29  {
   53.30  	int i, fd, ret = 0;
   53.31 -	struct tdaio_state *prv = (struct tdaio_state *)s->private;
   53.32 -	s->private = prv;
   53.33 +	struct td_state    *s   = dd->td_state;
   53.34 +	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
   53.35  
   53.36  	DPRINTF("block-aio open('%s')", name);
   53.37  	/* Initialize AIO */
   53.38 @@ -194,47 +206,21 @@ int tdaio_open (struct td_state *s, cons
   53.39  
   53.40          prv->fd = fd;
   53.41  
   53.42 +	init_fds(dd);
   53.43  	ret = get_image_info(s, fd);
   53.44 +
   53.45  done:
   53.46  	return ret;	
   53.47  }
   53.48  
   53.49 -int tdaio_queue_read(struct td_state *s, uint64_t sector,
   53.50 -			       int nb_sectors, char *buf, td_callback_t cb,
   53.51 -			       int id, void *private)
   53.52 +int tdaio_queue_read(struct disk_driver *dd, uint64_t sector,
   53.53 +		     int nb_sectors, char *buf, td_callback_t cb,
   53.54 +		     int id, void *private)
   53.55  {
   53.56  	struct   iocb *io;
   53.57  	struct   pending_aio *pio;
   53.58 -	struct   tdaio_state *prv = (struct tdaio_state *)s->private;
   53.59 -	int      size    = nb_sectors * s->sector_size;
   53.60 -	uint64_t offset  = sector * (uint64_t)s->sector_size;
   53.61 -	long     ioidx;
   53.62 -	
   53.63 -	if (prv->iocb_free_count == 0)
   53.64 -		return -ENOMEM;
   53.65 -	io = prv->iocb_free[--prv->iocb_free_count];
   53.66 -	
   53.67 -	ioidx = IOCB_IDX(prv, io);
   53.68 -	pio = &prv->pending_aio[ioidx];
   53.69 -	pio->cb = cb;
   53.70 -	pio->id = id;
   53.71 -	pio->private = private;
   53.72 -	
   53.73 -	io_prep_pread(io, prv->fd, buf, size, offset);
   53.74 -	io->data = (void *)ioidx;
   53.75 -	
   53.76 -	prv->iocb_queue[prv->iocb_queued++] = io;
   53.77 -	
   53.78 -	return 0;
   53.79 -}
   53.80 -			
   53.81 -int tdaio_queue_write(struct td_state *s, uint64_t sector,
   53.82 -			       int nb_sectors, char *buf, td_callback_t cb,
   53.83 -			       int id, void *private)
   53.84 -{
   53.85 -	struct   iocb *io;
   53.86 -	struct   pending_aio *pio;
   53.87 -	struct   tdaio_state *prv = (struct tdaio_state *)s->private;
   53.88 +	struct   td_state    *s   = dd->td_state;
   53.89 +	struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
   53.90  	int      size    = nb_sectors * s->sector_size;
   53.91  	uint64_t offset  = sector * (uint64_t)s->sector_size;
   53.92  	long     ioidx;
   53.93 @@ -248,19 +234,51 @@ int tdaio_queue_write(struct td_state *s
   53.94  	pio->cb = cb;
   53.95  	pio->id = id;
   53.96  	pio->private = private;
   53.97 +	pio->lsec = sector;
   53.98 +	
   53.99 +	io_prep_pread(io, prv->fd, buf, size, offset);
  53.100 +	io->data = (void *)ioidx;
  53.101 +	
  53.102 +	prv->iocb_queue[prv->iocb_queued++] = io;
  53.103 +
  53.104 +	return 0;
  53.105 +}
  53.106 +			
  53.107 +int tdaio_queue_write(struct disk_driver *dd, uint64_t sector,
  53.108 +		      int nb_sectors, char *buf, td_callback_t cb,
  53.109 +		      int id, void *private)
  53.110 +{
  53.111 +	struct   iocb *io;
  53.112 +	struct   pending_aio *pio;
  53.113 +	struct   td_state    *s   = dd->td_state;
  53.114 +	struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
  53.115 +	int      size    = nb_sectors * s->sector_size;
  53.116 +	uint64_t offset  = sector * (uint64_t)s->sector_size;
  53.117 +	long     ioidx;
  53.118 +	
  53.119 +	if (prv->iocb_free_count == 0)
  53.120 +		return -ENOMEM;
  53.121 +	io = prv->iocb_free[--prv->iocb_free_count];
  53.122 +	
  53.123 +	ioidx = IOCB_IDX(prv, io);
  53.124 +	pio = &prv->pending_aio[ioidx];
  53.125 +	pio->cb = cb;
  53.126 +	pio->id = id;
  53.127 +	pio->private = private;
  53.128 +	pio->lsec = sector;
  53.129  	
  53.130  	io_prep_pwrite(io, prv->fd, buf, size, offset);
  53.131  	io->data = (void *)ioidx;
  53.132  	
  53.133  	prv->iocb_queue[prv->iocb_queued++] = io;
  53.134 -	
  53.135 +
  53.136  	return 0;
  53.137  }
  53.138  			
  53.139 -int tdaio_submit(struct td_state *s)
  53.140 +int tdaio_submit(struct disk_driver *dd)
  53.141  {
  53.142  	int ret;
  53.143 -	struct   tdaio_state *prv = (struct tdaio_state *)s->private;
  53.144 +	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
  53.145  
  53.146  	ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
  53.147  	
  53.148 @@ -269,38 +287,24 @@ int tdaio_submit(struct td_state *s)
  53.149  	/* Success case: */
  53.150  	prv->iocb_queued = 0;
  53.151  	
  53.152 -	return ret;
  53.153 +	return 0;
  53.154  }
  53.155  
  53.156 -int *tdaio_get_fd(struct td_state *s)
  53.157 +int tdaio_close(struct disk_driver *dd)
  53.158  {
  53.159 -	struct tdaio_state *prv = (struct tdaio_state *)s->private;
  53.160 -	int *fds, i;
  53.161 -
  53.162 -	fds = malloc(sizeof(int) * MAX_IOFD);
  53.163 -	/*initialise the FD array*/
  53.164 -	for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
  53.165 -
  53.166 -	fds[0] = prv->poll_fd;
  53.167 -
  53.168 -	return fds;	
  53.169 -}
  53.170 -
  53.171 -int tdaio_close(struct td_state *s)
  53.172 -{
  53.173 -	struct tdaio_state *prv = (struct tdaio_state *)s->private;
  53.174 +	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
  53.175  	
  53.176  	io_destroy(prv->aio_ctx);
  53.177  	close(prv->fd);
  53.178 -	
  53.179 +
  53.180  	return 0;
  53.181  }
  53.182  
  53.183 -int tdaio_do_callbacks(struct td_state *s, int sid)
  53.184 +int tdaio_do_callbacks(struct disk_driver *dd, int sid)
  53.185  {
  53.186  	int ret, i, rsp = 0;
  53.187  	struct io_event *ep;
  53.188 -	struct tdaio_state *prv = (struct tdaio_state *)s->private;
  53.189 +	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
  53.190  
  53.191  	/* Non-blocking test for completed io. */
  53.192  	ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
  53.193 @@ -311,22 +315,34 @@ int tdaio_do_callbacks(struct td_state *
  53.194  		struct pending_aio *pio;
  53.195  		
  53.196  		pio = &prv->pending_aio[(long)io->data];
  53.197 -		rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1,
  53.198 +		rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1,
  53.199 +			       pio->lsec, io->u.c.nbytes >> 9, 
  53.200  			       pio->id, pio->private);
  53.201  
  53.202  		prv->iocb_free[prv->iocb_free_count++] = io;
  53.203  	}
  53.204  	return rsp;
  53.205  }
  53.206 -	
  53.207 +
  53.208 +int tdaio_has_parent(struct disk_driver *dd)
  53.209 +{
  53.210 +	return 0;
  53.211 +}
  53.212 +
  53.213 +int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent)
  53.214 +{
  53.215 +	return -EINVAL;
  53.216 +}
  53.217 +
  53.218  struct tap_disk tapdisk_aio = {
  53.219 -	"tapdisk_aio",
  53.220 -	sizeof(struct tdaio_state),
  53.221 -	tdaio_open,
  53.222 -	tdaio_queue_read,
  53.223 -	tdaio_queue_write,
  53.224 -	tdaio_submit,
  53.225 -	tdaio_get_fd,
  53.226 -	tdaio_close,
  53.227 -	tdaio_do_callbacks,
  53.228 +	.disk_type          = "tapdisk_aio",
  53.229 +	.private_data_size  = sizeof(struct tdaio_state),
  53.230 +	.td_open            = tdaio_open,
  53.231 +	.td_queue_read      = tdaio_queue_read,
  53.232 +	.td_queue_write     = tdaio_queue_write,
  53.233 +	.td_submit          = tdaio_submit,
  53.234 +	.td_has_parent      = tdaio_has_parent,
  53.235 +	.td_get_parent      = tdaio_get_parent,
  53.236 +	.td_close           = tdaio_close,
  53.237 +	.td_do_callbacks    = tdaio_do_callbacks,
  53.238  };
    54.1 --- a/tools/blktap/drivers/block-qcow.c	Sun Feb 18 16:13:13 2007 -0700
    54.2 +++ b/tools/blktap/drivers/block-qcow.c	Tue Feb 20 12:58:22 2007 -0700
    54.3 @@ -55,7 +55,6 @@
    54.4  
    54.5  /******AIO DEFINES******/
    54.6  #define REQUEST_ASYNC_FD 1
    54.7 -#define MAX_QCOW_IDS  0xFFFF
    54.8  #define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
    54.9  
   54.10  struct pending_aio {
   54.11 @@ -65,7 +64,6 @@ struct pending_aio {
   54.12  	int nb_sectors;
   54.13  	char *buf;
   54.14  	uint64_t sector;
   54.15 -	int qcow_idx;
   54.16  };
   54.17  
   54.18  #define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
   54.19 @@ -115,9 +113,9 @@ typedef struct QCowHeader_ext {
   54.20  struct tdqcow_state {
   54.21          int fd;                        /*Main Qcow file descriptor */
   54.22  	uint64_t fd_end;               /*Store a local record of file length */
   54.23 -	int bfd;                       /*Backing file descriptor*/
   54.24  	char *name;                    /*Record of the filename*/
   54.25 -	int poll_pipe[2];              /*dummy fd for polling on */
   54.26 +	uint32_t backing_file_size;
   54.27 +	uint64_t backing_file_offset;
   54.28  	int encrypted;                 /*File contents are encrypted or plain*/
   54.29  	int cluster_bits;              /*Determines length of cluster as 
   54.30  					*indicated by file hdr*/
   54.31 @@ -149,7 +147,6 @@ struct tdqcow_state {
   54.32  	AES_KEY aes_decrypt_key;       /*AES key*/
   54.33          /* libaio state */
   54.34          io_context_t       aio_ctx;
   54.35 -	int		   nr_reqs [MAX_QCOW_IDS];
   54.36          struct iocb        iocb_list  [MAX_AIO_REQS];
   54.37          struct iocb       *iocb_free  [MAX_AIO_REQS];
   54.38          struct pending_aio pending_aio[MAX_AIO_REQS];
   54.39 @@ -162,10 +159,11 @@ struct tdqcow_state {
   54.40  
   54.41  static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
   54.42  
   54.43 -static int init_aio_state(struct td_state *bs)
   54.44 +static int init_aio_state(struct disk_driver *dd)
   54.45  {
   54.46          int i;
   54.47 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
   54.48 +	struct td_state     *bs = dd->td_state;
   54.49 +	struct tdqcow_state  *s = (struct tdqcow_state *)dd->private;
   54.50          long     ioidx;
   54.51  
   54.52          /*Initialize Locking bitmap*/
   54.53 @@ -202,8 +200,7 @@ static int init_aio_state(struct td_stat
   54.54  
   54.55          for (i=0;i<MAX_AIO_REQS;i++)
   54.56                  s->iocb_free[i] = &s->iocb_list[i];
   54.57 -	for (i=0;i<MAX_QCOW_IDS;i++)
   54.58 -		s->nr_reqs[i] = 0;
   54.59 +
   54.60          DPRINTF("AIO state initialised\n");
   54.61  
   54.62          return 0;
   54.63 @@ -238,7 +235,10 @@ static uint32_t gen_cksum(char *ptr, int
   54.64  
   54.65  	if(!md) return 0;
   54.66  
   54.67 -	if (MD5((unsigned char *)ptr, len, md) != md) return 0;
   54.68 +	if (MD5((unsigned char *)ptr, len, md) != md) {
   54.69 +		free(md);
   54.70 +		return 0;
   54.71 +	}
   54.72  
   54.73  	memcpy(&ret, md, sizeof(uint32_t));
   54.74  	free(md);
   54.75 @@ -247,26 +247,42 @@ static uint32_t gen_cksum(char *ptr, int
   54.76  
   54.77  static int get_filesize(char *filename, uint64_t *size, struct stat *st)
   54.78  {
   54.79 -	int blockfd;
   54.80 +	int fd;
   54.81 +	QCowHeader header;
   54.82  
   54.83  	/*Set to the backing file size*/
   54.84 +	fd = open(filename, O_RDONLY);
   54.85 +	if (fd < 0)
   54.86 +		return -1;
   54.87 +	if (read(fd, &header, sizeof(header)) < sizeof(header)) {
   54.88 +		close(fd);
   54.89 +		return -1;
   54.90 +	}
   54.91 +	close(fd);
   54.92 +	
   54.93 +	be32_to_cpus(&header.magic);
   54.94 +	be64_to_cpus(&header.size);
   54.95 +	if (header.magic == QCOW_MAGIC) {
   54.96 +		*size = header.size >> SECTOR_SHIFT;
   54.97 +		return 0;
   54.98 +	}
   54.99 +
  54.100  	if(S_ISBLK(st->st_mode)) {
  54.101 -		blockfd = open(filename, O_RDONLY);
  54.102 -		if (blockfd < 0)
  54.103 +		fd = open(filename, O_RDONLY);
  54.104 +		if (fd < 0)
  54.105  			return -1;
  54.106 -		if (ioctl(blockfd,BLKGETSIZE,size)!=0) {
  54.107 +		if (ioctl(fd,BLKGETSIZE,size)!=0) {
  54.108  			printf("Unable to get Block device size\n");
  54.109 -			close(blockfd);
  54.110 +			close(fd);
  54.111  			return -1;
  54.112  		}
  54.113 -		close(blockfd);
  54.114 +		close(fd);
  54.115  	} else *size = (st->st_size >> SECTOR_SHIFT);	
  54.116  	return 0;
  54.117  }
  54.118  
  54.119 -static int qcow_set_key(struct td_state *bs, const char *key)
  54.120 +static int qcow_set_key(struct tdqcow_state *s, const char *key)
  54.121  {
  54.122 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.123  	uint8_t keybuf[16];
  54.124  	int len, i;
  54.125  	
  54.126 @@ -306,10 +322,9 @@ static int qcow_set_key(struct td_state 
  54.127  	return 0;
  54.128  }
  54.129  
  54.130 -static int async_read(struct tdqcow_state *s, int fd, int size, 
  54.131 -		     uint64_t offset,
  54.132 -		     char *buf, td_callback_t cb,
  54.133 -		     int id, uint64_t sector, int qcow_idx, void *private)
  54.134 +static int async_read(struct tdqcow_state *s, int size, 
  54.135 +		      uint64_t offset, char *buf, td_callback_t cb,
  54.136 +		      int id, uint64_t sector, void *private)
  54.137  {
  54.138          struct   iocb *io;
  54.139          struct   pending_aio *pio;
  54.140 @@ -325,9 +340,8 @@ static int async_read(struct tdqcow_stat
  54.141  	pio->nb_sectors = size/512;
  54.142  	pio->buf = buf;
  54.143  	pio->sector = sector;
  54.144 -	pio->qcow_idx = qcow_idx;
  54.145  
  54.146 -        io_prep_pread(io, fd, buf, size, offset);
  54.147 +        io_prep_pread(io, s->fd, buf, size, offset);
  54.148          io->data = (void *)ioidx;
  54.149  
  54.150          s->iocb_queue[s->iocb_queued++] = io;
  54.151 @@ -335,10 +349,9 @@ static int async_read(struct tdqcow_stat
  54.152          return 1;
  54.153  }
  54.154  
  54.155 -static int async_write(struct tdqcow_state *s, int fd, int size, 
  54.156 -		     uint64_t offset,
  54.157 -		     char *buf, td_callback_t cb,
  54.158 -		      int id, uint64_t sector, int qcow_idx, void *private)
  54.159 +static int async_write(struct tdqcow_state *s, int size,
  54.160 +		       uint64_t offset, char *buf, td_callback_t cb,
  54.161 +		       int id, uint64_t sector, void *private)
  54.162  {
  54.163          struct   iocb *io;
  54.164          struct   pending_aio *pio;
  54.165 @@ -354,9 +367,8 @@ static int async_write(struct tdqcow_sta
  54.166  	pio->nb_sectors = size/512;
  54.167  	pio->buf = buf;
  54.168  	pio->sector = sector;
  54.169 -	pio->qcow_idx = qcow_idx;
  54.170  
  54.171 -        io_prep_pwrite(io, fd, buf, size, offset);
  54.172 +        io_prep_pwrite(io, s->fd, buf, size, offset);
  54.173          io->data = (void *)ioidx;
  54.174  
  54.175          s->iocb_queue[s->iocb_queued++] = io;
  54.176 @@ -383,17 +395,6 @@ static void aio_unlock(struct tdqcow_sta
  54.177  	return;
  54.178  }
  54.179  
  54.180 -/*TODO - Use a freelist*/
  54.181 -static int get_free_idx(struct tdqcow_state *s)
  54.182 -{
  54.183 -	int i;
  54.184 -	
  54.185 -	for(i = 0; i < MAX_QCOW_IDS; i++) {
  54.186 -		if(s->nr_reqs[i] == 0) return i;
  54.187 -	}
  54.188 -	return -1;
  54.189 -}
  54.190 -
  54.191  /* 
  54.192   * The crypt function is compatible with the linux cryptoloop
  54.193   * algorithm for < 4 GB images. NOTE: out_buf == in_buf is
  54.194 @@ -425,23 +426,23 @@ static int qtruncate(int fd, off_t lengt
  54.195  {
  54.196  	int ret, i; 
  54.197  	int current = 0, rem = 0;
  54.198 -	int sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
  54.199 +	uint64_t sectors;
  54.200  	struct stat st;
  54.201 -	char buf[DEFAULT_SECTOR_SIZE];
  54.202 +	char *buf;
  54.203  
  54.204  	/* If length is greater than the current file len
  54.205  	 * we synchronously write zeroes to the end of the 
  54.206  	 * file, otherwise we truncate the length down
  54.207  	 */
  54.208 -	memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
  54.209  	ret = fstat(fd, &st);
  54.210 -	if (ret == -1)
  54.211 +	if (ret == -1) 
  54.212  		return -1;
  54.213  	if (S_ISBLK(st.st_mode))
  54.214  		return 0;
  54.215 -
  54.216 +	
  54.217 +	sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
  54.218  	current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
  54.219 -	rem = st.st_size % DEFAULT_SECTOR_SIZE;
  54.220 +	rem     = st.st_size % DEFAULT_SECTOR_SIZE;
  54.221  
  54.222  	/* If we are extending this file, we write zeros to the end --
  54.223  	 * this tries to ensure that the extents allocated wind up being
  54.224 @@ -449,28 +450,40 @@ static int qtruncate(int fd, off_t lengt
  54.225  	 */
  54.226  	if(st.st_size < sectors * DEFAULT_SECTOR_SIZE) {
  54.227  		/*We are extending the file*/
  54.228 +		if ((ret = posix_memalign((void **)&buf, 
  54.229 +					  512, DEFAULT_SECTOR_SIZE))) {
  54.230 +			DPRINTF("posix_memalign failed: %d\n", ret);
  54.231 +			return -1;
  54.232 +		}
  54.233 +		memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
  54.234  		if (lseek(fd, 0, SEEK_END)==-1) {
  54.235 -			fprintf(stderr, 
  54.236 -				"Lseek EOF failed (%d), internal error\n",
  54.237 +			DPRINTF("Lseek EOF failed (%d), internal error\n",
  54.238  				errno);
  54.239 +			free(buf);
  54.240  			return -1;
  54.241  		}
  54.242  		if (rem) {
  54.243  			ret = write(fd, buf, rem);
  54.244 -			if (ret != rem)
  54.245 +			if (ret != rem) {
  54.246 +				DPRINTF("write failed: ret = %d, err = %s\n",
  54.247 +					ret, strerror(errno));
  54.248 +				free(buf);
  54.249  				return -1;
  54.250 +			}
  54.251  		}
  54.252  		for (i = current; i < sectors; i++ ) {
  54.253  			ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
  54.254 -			if (ret != DEFAULT_SECTOR_SIZE)
  54.255 +			if (ret != DEFAULT_SECTOR_SIZE) {
  54.256 +				DPRINTF("write failed: ret = %d, err = %s\n",
  54.257 +					ret, strerror(errno));
  54.258 +				free(buf);
  54.259  				return -1;
  54.260 +			}
  54.261  		}
  54.262 -		
  54.263 +		free(buf);
  54.264  	} else if(sparse && (st.st_size > sectors * DEFAULT_SECTOR_SIZE))
  54.265 -		if (ftruncate(fd, sectors * DEFAULT_SECTOR_SIZE)==-1) {
  54.266 -			fprintf(stderr,
  54.267 -				"Ftruncate failed (%d), internal error\n",
  54.268 -                                errno);
  54.269 +		if (ftruncate(fd, (off_t)sectors * DEFAULT_SECTOR_SIZE)==-1) {
  54.270 +			DPRINTF("Ftruncate failed (%s)\n", strerror(errno));
  54.271  			return -1;
  54.272  		}
  54.273  	return 0;
  54.274 @@ -490,12 +503,11 @@ static int qtruncate(int fd, off_t lengt
  54.275   *
  54.276   * return 0 if not allocated.
  54.277   */
  54.278 -static uint64_t get_cluster_offset(struct td_state *bs,
  54.279 +static uint64_t get_cluster_offset(struct tdqcow_state *s,
  54.280                                     uint64_t offset, int allocate,
  54.281                                     int compressed_size,
  54.282                                     int n_start, int n_end)
  54.283  {
  54.284 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.285  	int min_index, i, j, l1_index, l2_index, l2_sector, l1_sector;
  54.286  	char *tmp_ptr, *tmp_ptr2, *l2_ptr, *l1_ptr;
  54.287  	uint64_t l2_offset, *l2_table, cluster_offset, tmp;
  54.288 @@ -550,8 +562,10 @@ static uint64_t get_cluster_offset(struc
  54.289  		 * entry is written before blocks.
  54.290  		 */
  54.291  		lseek(s->fd, s->l1_table_offset + (l1_sector << 12), SEEK_SET);
  54.292 -		if (write(s->fd, tmp_ptr, 4096) != 4096)
  54.293 +		if (write(s->fd, tmp_ptr, 4096) != 4096) {
  54.294 +			free(tmp_ptr);
  54.295  		 	return 0;
  54.296 +		}
  54.297  		free(tmp_ptr);
  54.298  
  54.299  		new_l2_table = 1;
  54.300 @@ -716,9 +730,10 @@ found:
  54.301  	return cluster_offset;
  54.302  }
  54.303  
  54.304 -static void init_cluster_cache(struct td_state *bs)
  54.305 +static void init_cluster_cache(struct disk_driver *dd)
  54.306  {
  54.307 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.308 +	struct td_state     *bs = dd->td_state;
  54.309 +	struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
  54.310  	uint32_t count = 0;
  54.311  	int i, cluster_entries;
  54.312  
  54.313 @@ -727,22 +742,20 @@ static void init_cluster_cache(struct td
  54.314  		cluster_entries, s->cluster_size);
  54.315  
  54.316  	for (i = 0; i < bs->size; i += cluster_entries) {
  54.317 -		if (get_cluster_offset(bs, i << 9, 0, 0, 0, 1)) count++;
  54.318 +		if (get_cluster_offset(s, i << 9, 0, 0, 0, 1)) count++;
  54.319  		if (count >= L2_CACHE_SIZE) return;
  54.320  	}
  54.321  	DPRINTF("Finished cluster initialisation, added %d entries\n", count);
  54.322  	return;
  54.323  }
  54.324  
  54.325 -static int qcow_is_allocated(struct td_state *bs, int64_t sector_num, 
  54.326 +static int qcow_is_allocated(struct tdqcow_state *s, int64_t sector_num,
  54.327                               int nb_sectors, int *pnum)
  54.328  {
  54.329 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.330 -
  54.331  	int index_in_cluster, n;
  54.332  	uint64_t cluster_offset;
  54.333  
  54.334 -	cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
  54.335 +	cluster_offset = get_cluster_offset(s, sector_num << 9, 0, 0, 0, 0);
  54.336  	index_in_cluster = sector_num & (s->cluster_sectors - 1);
  54.337  	n = s->cluster_sectors - index_in_cluster;
  54.338  	if (n > nb_sectors)
  54.339 @@ -800,11 +813,23 @@ static int decompress_cluster(struct tdq
  54.340  	return 0;
  54.341  }
  54.342  
  54.343 +static inline void init_fds(struct disk_driver *dd)
  54.344 +{
  54.345 +	int i;
  54.346 +	struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
  54.347 +
  54.348 +	for(i = 0; i < MAX_IOFD; i++) 
  54.349 +		dd->io_fd[i] = 0;
  54.350 +
  54.351 +	dd->io_fd[0] = s->poll_fd;
  54.352 +}
  54.353 +
  54.354  /* Open the disk file and initialize qcow state. */
  54.355 -int tdqcow_open (struct td_state *bs, const char *name)
  54.356 +int tdqcow_open (struct disk_driver *dd, const char *name)
  54.357  {
  54.358  	int fd, len, i, shift, ret, size, l1_table_size;
  54.359 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.360 +	struct td_state     *bs = dd->td_state;
  54.361 +	struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
  54.362  	char *buf;
  54.363  	QCowHeader *header;
  54.364  	QCowHeader_ext *exthdr;
  54.365 @@ -812,10 +837,6 @@ int tdqcow_open (struct td_state *bs, co
  54.366  	uint64_t final_cluster = 0;
  54.367  
  54.368   	DPRINTF("QCOW: Opening %s\n",name);
  54.369 -	/* set up a pipe so that we can hand back a poll fd that won't fire.*/
  54.370 -	ret = pipe(s->poll_pipe);
  54.371 -	if (ret != 0)
  54.372 -		return (0 - errno);
  54.373  
  54.374  	fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
  54.375  	if (fd < 0) {
  54.376 @@ -826,7 +847,7 @@ int tdqcow_open (struct td_state *bs, co
  54.377  	s->fd = fd;
  54.378  	asprintf(&s->name,"%s", name);
  54.379  
  54.380 -	ASSERT(sizeof(header) < 512);
  54.381 +	ASSERT(sizeof(QCowHeader) + sizeof(QCowHeader_ext) < 512);
  54.382  
  54.383  	ret = posix_memalign((void **)&buf, 512, 512);
  54.384  	if (ret != 0) goto fail;
  54.385 @@ -861,7 +882,9 @@ int tdqcow_open (struct td_state *bs, co
  54.386  	s->cluster_alloc = s->l2_size;
  54.387  	bs->size = header->size / 512;
  54.388  	s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
  54.389 -	
  54.390 +	s->backing_file_offset = header->backing_file_offset;
  54.391 +	s->backing_file_size   = header->backing_file_size;
  54.392 +
  54.393  	/* read the level 1 table */
  54.394  	shift = s->cluster_bits + s->l2_bits;
  54.395  	s->l1_size = (header->size + (1LL << shift) - 1) >> shift;
  54.396 @@ -887,7 +910,7 @@ int tdqcow_open (struct td_state *bs, co
  54.397  	if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
  54.398  		goto fail;
  54.399  
  54.400 -	for(i = 0;i < s->l1_size; i++) {
  54.401 +	for(i = 0; i < s->l1_size; i++) {
  54.402  		//be64_to_cpus(&s->l1_table[i]);
  54.403  		//DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
  54.404  		if (s->l1_table[i] > final_cluster)
  54.405 @@ -907,41 +930,15 @@ int tdqcow_open (struct td_state *bs, co
  54.406  	if(ret != 0) goto fail;
  54.407  	s->cluster_cache_offset = -1;
  54.408  
  54.409 -	/* read the backing file name */
  54.410 -	s->bfd = -1;
  54.411 -	if (header->backing_file_offset != 0) {
  54.412 -		DPRINTF("Reading backing file data\n");
  54.413 -		len = header->backing_file_size;
  54.414 -		if (len > 1023)
  54.415 -			len = 1023;
  54.416 -
  54.417 -                /*TODO - Fix read size for O_DIRECT and use original fd!*/
  54.418 -		fd = open(name, O_RDONLY | O_LARGEFILE);
  54.419 -
  54.420 -		lseek(fd, header->backing_file_offset, SEEK_SET);
  54.421 -		if (read(fd, bs->backing_file, len) != len)
  54.422 -			goto fail;
  54.423 -		bs->backing_file[len] = '\0';
  54.424 -		close(fd);
  54.425 -		/***********************************/
  54.426 -
  54.427 -		/*Open backing file*/
  54.428 -		fd = open(bs->backing_file, O_RDONLY | O_DIRECT | O_LARGEFILE);
  54.429 -		if (fd < 0) {
  54.430 -			DPRINTF("Unable to open backing file: %s\n",
  54.431 -				bs->backing_file);
  54.432 -			goto fail;
  54.433 -		}
  54.434 -		s->bfd = fd;
  54.435 +	if (s->backing_file_offset != 0)
  54.436  		s->cluster_alloc = 1; /*Cannot use pre-alloc*/
  54.437 -	}
  54.438  
  54.439          bs->sector_size = 512;
  54.440          bs->info = 0;
  54.441  	
  54.442  	/*Detect min_cluster_alloc*/
  54.443  	s->min_cluster_alloc = 1; /*Default*/
  54.444 -	if (s->bfd == -1 && (s->l1_table_offset % 4096 == 0) ) {
  54.445 +	if (s->backing_file_offset == 0 && s->l1_table_offset % 4096 == 0) {
  54.446  		/*We test to see if the xen magic # exists*/
  54.447  		exthdr = (QCowHeader_ext *)(buf + sizeof(QCowHeader));
  54.448  		be32_to_cpus(&exthdr->xmagic);
  54.449 @@ -962,10 +959,11 @@ int tdqcow_open (struct td_state *bs, co
  54.450  	}
  54.451  
  54.452   end_xenhdr:
  54.453 -	if (init_aio_state(bs)!=0) {
  54.454 +	if (init_aio_state(dd)!=0) {
  54.455  		DPRINTF("Unable to initialise AIO state\n");
  54.456  		goto fail;
  54.457  	}
  54.458 +	init_fds(dd);
  54.459  	s->fd_end = (final_cluster == 0 ? (s->l1_table_offset + l1_table_size) : 
  54.460  				(final_cluster + s->cluster_size));
  54.461  
  54.462 @@ -981,213 +979,145 @@ fail:
  54.463  	return -1;
  54.464  }
  54.465  
  54.466 - int tdqcow_queue_read(struct td_state *bs, uint64_t sector,
  54.467 -			       int nb_sectors, char *buf, td_callback_t cb,
  54.468 -			       int id, void *private)
  54.469 +int tdqcow_queue_read(struct disk_driver *dd, uint64_t sector,
  54.470 +		      int nb_sectors, char *buf, td_callback_t cb,
  54.471 +		      int id, void *private)
  54.472  {
  54.473 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.474 -	int ret = 0, index_in_cluster, n, i, qcow_idx, asubmit = 0;
  54.475 -	uint64_t cluster_offset;
  54.476 +	struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
  54.477 +	int ret = 0, index_in_cluster, n, i, rsp = 0;
  54.478 +	uint64_t cluster_offset, sec, nr_secs;
  54.479 +
  54.480 +	sec     = sector;
  54.481 +	nr_secs = nb_sectors;
  54.482  
  54.483  	/*Check we can get a lock*/
  54.484 -	for (i = 0; i < nb_sectors; i++)
  54.485 -		if (!aio_can_lock(s, sector + i)) {
  54.486 -			DPRINTF("AIO_CAN_LOCK failed [%llu]\n", 
  54.487 -				(long long) sector + i);
  54.488 -			return -EBUSY;
  54.489 -		}
  54.490 -	
  54.491 +	for (i = 0; i < nb_sectors; i++) 
  54.492 +		if (!aio_can_lock(s, sector + i)) 
  54.493 +			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  54.494 +
  54.495  	/*We store a local record of the request*/
  54.496 -	qcow_idx = get_free_idx(s);
  54.497  	while (nb_sectors > 0) {
  54.498  		cluster_offset = 
  54.499 -			get_cluster_offset(bs, sector << 9, 0, 0, 0, 0);
  54.500 +			get_cluster_offset(s, sector << 9, 0, 0, 0, 0);
  54.501  		index_in_cluster = sector & (s->cluster_sectors - 1);
  54.502  		n = s->cluster_sectors - index_in_cluster;
  54.503  		if (n > nb_sectors)
  54.504  			n = nb_sectors;
  54.505  
  54.506 -		if (s->iocb_free_count == 0 || !aio_lock(s, sector)) {
  54.507 -			DPRINTF("AIO_LOCK or iocb_free_count (%d) failed" 
  54.508 -				"[%llu]\n", s->iocb_free_count, 
  54.509 -				(long long) sector);
  54.510 -			return -ENOMEM;
  54.511 -		}
  54.512 +		if (s->iocb_free_count == 0 || !aio_lock(s, sector)) 
  54.513 +			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  54.514  		
  54.515 -		if (!cluster_offset && (s->bfd > 0)) {
  54.516 -			s->nr_reqs[qcow_idx]++;
  54.517 -			asubmit += async_read(s, s->bfd, n * 512, sector << 9, 
  54.518 -					      buf, cb, id, sector, 
  54.519 -					      qcow_idx, private);
  54.520 -		} else if(!cluster_offset) {
  54.521 -			memset(buf, 0, 512 * n);
  54.522 +		if(!cluster_offset) {
  54.523  			aio_unlock(s, sector);
  54.524 +			ret = cb(dd, BLK_NOT_ALLOCATED, 
  54.525 +				 sector, n, id, private);
  54.526 +			if (ret == -EBUSY) {
  54.527 +				/* mark remainder of request
  54.528 +				 * as busy and try again later */
  54.529 +				return cb(dd, -EBUSY, sector + n,
  54.530 +					  nb_sectors - n, id, private);
  54.531 +			} else rsp += ret;
  54.532  		} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
  54.533 +			aio_unlock(s, sector);
  54.534  			if (decompress_cluster(s, cluster_offset) < 0) {
  54.535 -				ret = -1;
  54.536 +				rsp += cb(dd, -EIO, sector, 
  54.537 +					  nb_sectors, id, private);
  54.538  				goto done;
  54.539  			}
  54.540  			memcpy(buf, s->cluster_cache + index_in_cluster * 512, 
  54.541  			       512 * n);
  54.542 -		} else {			
  54.543 -			s->nr_reqs[qcow_idx]++;
  54.544 -			asubmit += async_read(s, s->fd, n * 512, 
  54.545 -					      (cluster_offset + 
  54.546 -					       index_in_cluster * 512), 
  54.547 -					      buf, cb, id, sector, 
  54.548 -					      qcow_idx, private);
  54.549 +			rsp += cb(dd, 0, sector, n, id, private);
  54.550 +		} else {
  54.551 +			async_read(s, n * 512, 
  54.552 +				   (cluster_offset + index_in_cluster * 512),
  54.553 +				   buf, cb, id, sector, private);
  54.554  		}
  54.555  		nb_sectors -= n;
  54.556  		sector += n;
  54.557  		buf += n * 512;
  54.558  	}
  54.559  done:
  54.560 -        /*Callback if no async requests outstanding*/
  54.561 -        if (!asubmit) return cb(bs, ret == -1 ? -1 : 0, id, private);
  54.562 -
  54.563 -	return 0;
  54.564 +	return rsp;
  54.565  }
  54.566  
  54.567 - int tdqcow_queue_write(struct td_state *bs, uint64_t sector,
  54.568 -			       int nb_sectors, char *buf, td_callback_t cb,
  54.569 -			       int id, void *private)
  54.570 +int tdqcow_queue_write(struct disk_driver *dd, uint64_t sector,
  54.571 +		       int nb_sectors, char *buf, td_callback_t cb,
  54.572 +		       int id, void *private)
  54.573  {
  54.574 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.575 -	int ret = 0, index_in_cluster, n, i, qcow_idx, asubmit = 0;
  54.576 -	uint64_t cluster_offset;
  54.577 +	struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
  54.578 +	int ret = 0, index_in_cluster, n, i;
  54.579 +	uint64_t cluster_offset, sec, nr_secs;
  54.580 +
  54.581 +	sec     = sector;
  54.582 +	nr_secs = nb_sectors;
  54.583  
  54.584  	/*Check we can get a lock*/
  54.585  	for (i = 0; i < nb_sectors; i++)
  54.586 -		if (!aio_can_lock(s, sector + i))  {
  54.587 -			DPRINTF("AIO_CAN_LOCK failed [%llu]\n", 
  54.588 -				(long long) (sector + i));
  54.589 -			return -EBUSY;
  54.590 -		}
  54.591 +		if (!aio_can_lock(s, sector + i))  
  54.592 +			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  54.593  		   
  54.594  	/*We store a local record of the request*/
  54.595 -	qcow_idx = get_free_idx(s);	
  54.596  	while (nb_sectors > 0) {
  54.597  		index_in_cluster = sector & (s->cluster_sectors - 1);
  54.598  		n = s->cluster_sectors - index_in_cluster;
  54.599  		if (n > nb_sectors)
  54.600  			n = nb_sectors;
  54.601  
  54.602 -		if (s->iocb_free_count == 0 || !aio_lock(s, sector)){
  54.603 -			DPRINTF("AIO_LOCK or iocb_free_count (%d) failed" 
  54.604 -				"[%llu]\n", s->iocb_free_count, 
  54.605 -				(long long) sector);
  54.606 -			return -ENOMEM;
  54.607 +		if (s->iocb_free_count == 0 || !aio_lock(s, sector))
  54.608 +			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  54.609 +
  54.610 +		cluster_offset = get_cluster_offset(s, sector << 9, 1, 0,
  54.611 +						    index_in_cluster, 
  54.612 +						    index_in_cluster+n);
  54.613 +		if (!cluster_offset) {
  54.614 +			DPRINTF("Ooops, no write cluster offset!\n");
  54.615 +			return cb(dd, -EIO, sector, nb_sectors, id, private);
  54.616  		}
  54.617  
  54.618 -		if (!IS_ZERO(buf,n * 512)) {
  54.619 -
  54.620 -			cluster_offset = get_cluster_offset(bs, sector << 9, 
  54.621 -							    1, 0, 
  54.622 -							    index_in_cluster, 
  54.623 -							    index_in_cluster+n
  54.624 -				);
  54.625 -			if (!cluster_offset) {
  54.626 -				DPRINTF("Ooops, no write cluster offset!\n");
  54.627 -				ret = -1;
  54.628 -				goto done;
  54.629 -			}
  54.630 -
  54.631 -			if (s->crypt_method) {
  54.632 -				encrypt_sectors(s, sector, s->cluster_data, 
  54.633 -						(unsigned char *)buf, n, 1,
  54.634 -						&s->aes_encrypt_key);
  54.635 -				s->nr_reqs[qcow_idx]++;
  54.636 -				asubmit += async_write(s, s->fd, n * 512, 
  54.637 -						       (cluster_offset + 
  54.638 -							index_in_cluster*512), 
  54.639 -						       (char *)s->cluster_data,
  54.640 -						       cb, id, sector, 
  54.641 -						       qcow_idx, private);
  54.642 -			} else {
  54.643 -				s->nr_reqs[qcow_idx]++;
  54.644 -				asubmit += async_write(s, s->fd, n * 512, 
  54.645 -						       (cluster_offset + 
  54.646 -							index_in_cluster*512),
  54.647 -						       buf, cb, id, sector, 
  54.648 -						       qcow_idx, private);
  54.649 -			}
  54.650 +		if (s->crypt_method) {
  54.651 +			encrypt_sectors(s, sector, s->cluster_data, 
  54.652 +					(unsigned char *)buf, n, 1,
  54.653 +					&s->aes_encrypt_key);
  54.654 +			async_write(s, n * 512, 
  54.655 +				    (cluster_offset + index_in_cluster*512),
  54.656 +				    (char *)s->cluster_data, cb, id, sector, 
  54.657 +				    private);
  54.658  		} else {
  54.659 -			/*Write data contains zeros, but we must check to see 
  54.660 -			  if cluster already allocated*/
  54.661 -			cluster_offset = get_cluster_offset(bs, sector << 9, 
  54.662 -							    0, 0, 
  54.663 -							    index_in_cluster, 
  54.664 -							    index_in_cluster+n
  54.665 -				);	
  54.666 -			if(cluster_offset) {
  54.667 -				if (s->crypt_method) {
  54.668 -					encrypt_sectors(s, sector, 
  54.669 -							s->cluster_data, 
  54.670 -							(unsigned char *)buf, 
  54.671 -							n, 1,
  54.672 -							&s->aes_encrypt_key);
  54.673 -					s->nr_reqs[qcow_idx]++;
  54.674 -					asubmit += async_write(s, s->fd, 
  54.675 -							       n * 512, 
  54.676 -							       (cluster_offset+
  54.677 -								index_in_cluster * 512), 
  54.678 -							       (char *)s->cluster_data, cb, id, sector, 
  54.679 -							       qcow_idx, private);
  54.680 -				} else {
  54.681 -					s->nr_reqs[qcow_idx]++;
  54.682 -					asubmit += async_write(s, s->fd, n*512,
  54.683 -							       cluster_offset + index_in_cluster * 512, 
  54.684 -							       buf, cb, id, sector, 
  54.685 -							       qcow_idx, private);
  54.686 -				}
  54.687 -			}
  54.688 -			else aio_unlock(s, sector);
  54.689 +			async_write(s, n * 512, 
  54.690 +				    (cluster_offset + index_in_cluster*512),
  54.691 +				    buf, cb, id, sector, private);
  54.692  		}
  54.693 +		
  54.694  		nb_sectors -= n;
  54.695  		sector += n;
  54.696  		buf += n * 512;
  54.697  	}
  54.698  	s->cluster_cache_offset = -1; /* disable compressed cache */
  54.699  
  54.700 -done:
  54.701 -	/*Callback if no async requests outstanding*/
  54.702 -        if (!asubmit) return cb(bs, ret == -1 ? -1 : 0, id, private);
  54.703 -
  54.704  	return 0;
  54.705  }
  54.706   		
  54.707 -int tdqcow_submit(struct td_state *bs)
  54.708 +int tdqcow_submit(struct disk_driver *dd)
  54.709  {
  54.710          int ret;
  54.711 -        struct   tdqcow_state *prv = (struct tdqcow_state *)bs->private;
  54.712 +        struct   tdqcow_state *prv = (struct tdqcow_state *)dd->private;
  54.713  
  54.714 -        ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
  54.715 +	if (!prv->iocb_queued)
  54.716 +		return 0;
  54.717 +
  54.718 +	ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
  54.719  
  54.720          /* XXX: TODO: Handle error conditions here. */
  54.721  
  54.722          /* Success case: */
  54.723          prv->iocb_queued = 0;
  54.724  
  54.725 -        return ret;
  54.726 +        return 0;
  54.727  }
  54.728  
  54.729 -
  54.730 -int *tdqcow_get_fd(struct td_state *bs)
  54.731 +int tdqcow_close(struct disk_driver *dd)
  54.732  {
  54.733 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.734 -	int *fds, i;
  54.735 -
  54.736 -	fds = malloc(sizeof(int) * MAX_IOFD);
  54.737 -	/*initialise the FD array*/
  54.738 -	for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
  54.739 -
  54.740 -	fds[0] = s->poll_fd;
  54.741 -	return fds;
  54.742 -}
  54.743 -
  54.744 -int tdqcow_close(struct td_state *bs)
  54.745 -{
  54.746 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.747 +	struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
  54.748  	uint32_t cksum, out;
  54.749  	int fd, offset;
  54.750  
  54.751 @@ -1203,6 +1133,7 @@ int tdqcow_close(struct td_state *bs)
  54.752  		close(fd);
  54.753  	}
  54.754  
  54.755 +	io_destroy(s->aio_ctx);
  54.756  	free(s->name);
  54.757  	free(s->l1_table);
  54.758  	free(s->l2_cache);
  54.759 @@ -1212,11 +1143,11 @@ int tdqcow_close(struct td_state *bs)
  54.760  	return 0;
  54.761  }
  54.762  
  54.763 -int tdqcow_do_callbacks(struct td_state *s, int sid)
  54.764 +int tdqcow_do_callbacks(struct disk_driver *dd, int sid)
  54.765  {
  54.766          int ret, i, rsp = 0,*ptr;
  54.767          struct io_event *ep;
  54.768 -        struct tdqcow_state *prv = (struct tdqcow_state *)s->private;
  54.769 +        struct tdqcow_state *prv = (struct tdqcow_state *)dd->private;
  54.770  
  54.771          if (sid > MAX_IOFD) return 1;
  54.772  	
  54.773 @@ -1224,25 +1155,24 @@ int tdqcow_do_callbacks(struct td_state 
  54.774          ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
  54.775                             NULL);
  54.776  
  54.777 -        for (ep=prv->aio_events, i = ret; i-->0; ep++) {
  54.778 +        for (ep = prv->aio_events, i = ret; i-- > 0; ep++) {
  54.779                  struct iocb        *io  = ep->obj;
  54.780                  struct pending_aio *pio;
  54.781  
  54.782                  pio = &prv->pending_aio[(long)io->data];
  54.783  
  54.784  		aio_unlock(prv, pio->sector);
  54.785 -		if (pio->id >= 0) {
  54.786 -			if (prv->crypt_method)
  54.787 -				encrypt_sectors(prv, pio->sector, 
  54.788 -						(unsigned char *)pio->buf, 
  54.789 -						(unsigned char *)pio->buf, 
  54.790 -						pio->nb_sectors, 0, 
  54.791 -						&prv->aes_decrypt_key);
  54.792 -			prv->nr_reqs[pio->qcow_idx]--;
  54.793 -			if (prv->nr_reqs[pio->qcow_idx] == 0) 
  54.794 -			        rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1, pio->id, 
  54.795 -					       pio->private);
  54.796 -		} else if (pio->id == -2) free(pio->buf);
  54.797 +
  54.798 +		if (prv->crypt_method)
  54.799 +			encrypt_sectors(prv, pio->sector, 
  54.800 +					(unsigned char *)pio->buf, 
  54.801 +					(unsigned char *)pio->buf, 
  54.802 +					pio->nb_sectors, 0, 
  54.803 +					&prv->aes_decrypt_key);
  54.804 +
  54.805 +		rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1, 
  54.806 +			       pio->sector, pio->nb_sectors,
  54.807 +			       pio->id, pio->private);
  54.808  
  54.809                  prv->iocb_free[prv->iocb_free_count++] = io;
  54.810          }
  54.811 @@ -1250,7 +1180,7 @@ int tdqcow_do_callbacks(struct td_state 
  54.812  }
  54.813  
  54.814  int qcow_create(const char *filename, uint64_t total_size,
  54.815 -                      const char *backing_file, int sparse)
  54.816 +		const char *backing_file, int sparse)
  54.817  {
  54.818  	int fd, header_size, backing_filename_len, l1_size, i;
  54.819  	int shift, length, adjust, flags = 0, ret = 0;
  54.820 @@ -1391,9 +1321,8 @@ int qcow_create(const char *filename, ui
  54.821  	return 0;
  54.822  }
  54.823  
  54.824 -int qcow_make_empty(struct td_state *bs)
  54.825 +int qcow_make_empty(struct tdqcow_state *s)
  54.826  {
  54.827 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.828  	uint32_t l1_length = s->l1_size * sizeof(uint64_t);
  54.829  
  54.830  	memset(s->l1_table, 0, l1_length);
  54.831 @@ -1412,19 +1341,16 @@ int qcow_make_empty(struct td_state *bs)
  54.832  	return 0;
  54.833  }
  54.834  
  54.835 -int qcow_get_cluster_size(struct td_state *bs)
  54.836 +int qcow_get_cluster_size(struct tdqcow_state *s)
  54.837  {
  54.838 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.839 -
  54.840  	return s->cluster_size;
  54.841  }
  54.842  
  54.843  /* XXX: put compressed sectors first, then all the cluster aligned
  54.844     tables to avoid losing bytes in alignment */
  54.845 -int qcow_compress_cluster(struct td_state *bs, int64_t sector_num, 
  54.846 +int qcow_compress_cluster(struct tdqcow_state *s, int64_t sector_num, 
  54.847                            const uint8_t *buf)
  54.848  {
  54.849 -	struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
  54.850  	z_stream strm;
  54.851  	int ret, out_len;
  54.852  	uint8_t *out_buf;
  54.853 @@ -1463,7 +1389,7 @@ int qcow_compress_cluster(struct td_stat
  54.854  		/* could not compress: write normal cluster */
  54.855  		//tdqcow_queue_write(bs, sector_num, buf, s->cluster_sectors);
  54.856  	} else {
  54.857 -		cluster_offset = get_cluster_offset(bs, sector_num << 9, 2, 
  54.858 +		cluster_offset = get_cluster_offset(s, sector_num << 9, 2, 
  54.859                                              out_len, 0, 0);
  54.860  		cluster_offset &= s->cluster_offset_mask;
  54.861  		lseek(s->fd, cluster_offset, SEEK_SET);
  54.862 @@ -1477,15 +1403,54 @@ int qcow_compress_cluster(struct td_stat
  54.863  	return 0;
  54.864  }
  54.865  
  54.866 +int tdqcow_has_parent(struct disk_driver *dd)
  54.867 +{
  54.868 +	struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
  54.869 +	return (s->backing_file_offset ? 1 : 0);
  54.870 +}
  54.871 +
  54.872 +int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd)
  54.873 +{
  54.874 +	off_t off;
  54.875 +	char *buf, *filename;
  54.876 +	int len, secs, ret = -1;
  54.877 +	struct tdqcow_state *child  = (struct tdqcow_state *)cdd->private;
  54.878 +
  54.879 +	if (!child->backing_file_offset)
  54.880 +		return -1;
  54.881 +
  54.882 +	/* read the backing file name */
  54.883 +	len  = child->backing_file_size;
  54.884 +	off  = child->backing_file_offset - (child->backing_file_offset % 512);
  54.885 +	secs = (len + (child->backing_file_offset - off) + 511) >> 9;
  54.886 +
  54.887 +	if (posix_memalign((void **)&buf, 512, secs << 9)) 
  54.888 +		return -1;
  54.889 +
  54.890 +	if (lseek(child->fd, off, SEEK_SET) == (off_t)-1)
  54.891 +		goto out;
  54.892 +
  54.893 +	if (read(child->fd, buf, secs << 9) != secs << 9)
  54.894 +		goto out;
  54.895 +	filename      = buf + (child->backing_file_offset - off);
  54.896 +	filename[len] = '\0';
  54.897 +
  54.898 +	/*Open backing file*/
  54.899 +	ret = tdqcow_open(pdd, filename);
  54.900 + out:
  54.901 +	free(buf);
  54.902 +	return ret;
  54.903 +}
  54.904 +
  54.905  struct tap_disk tapdisk_qcow = {
  54.906 -	"tapdisk_qcow",
  54.907 -	sizeof(struct tdqcow_state),
  54.908 -	tdqcow_open,
  54.909 -	tdqcow_queue_read,
  54.910 -	tdqcow_queue_write,
  54.911 -	tdqcow_submit,
  54.912 -	tdqcow_get_fd,
  54.913 -	tdqcow_close,
  54.914 -	tdqcow_do_callbacks,
  54.915 +	.disk_type           = "tapdisk_qcow",
  54.916 +	.private_data_size   = sizeof(struct tdqcow_state),
  54.917 +	.td_open             = tdqcow_open,
  54.918 +	.td_queue_read       = tdqcow_queue_read,
  54.919 +	.td_queue_write      = tdqcow_queue_write,
  54.920 +	.td_submit           = tdqcow_submit,
  54.921 +	.td_has_parent       = tdqcow_has_parent,
  54.922 +	.td_get_parent       = tdqcow_get_parent,
  54.923 +	.td_close            = tdqcow_close,
  54.924 +	.td_do_callbacks     = tdqcow_do_callbacks,
  54.925  };
  54.926 -
    55.1 --- a/tools/blktap/drivers/block-ram.c	Sun Feb 18 16:13:13 2007 -0700
    55.2 +++ b/tools/blktap/drivers/block-ram.c	Tue Feb 20 12:58:22 2007 -0700
    55.3 @@ -123,14 +123,25 @@ static int get_image_info(struct td_stat
    55.4  	return 0;
    55.5  }
    55.6  
    55.7 +static inline void init_fds(struct disk_driver *dd)
    55.8 +{
    55.9 +        int i;
   55.10 +	struct tdram_state *prv = (struct tdram_state *)dd->private;
   55.11 +
   55.12 +        for(i =0 ; i < MAX_IOFD; i++)
   55.13 +		dd->io_fd[i] = 0;
   55.14 +
   55.15 +        dd->io_fd[0] = prv->poll_pipe[0];
   55.16 +}
   55.17 +
   55.18  /* Open the disk file and initialize ram state. */
   55.19 -int tdram_open (struct td_state *s, const char *name)
   55.20 +int tdram_open (struct disk_driver *dd, const char *name)
   55.21  {
   55.22 +	char *p;
   55.23 +	uint64_t size;
   55.24  	int i, fd, ret = 0, count = 0;
   55.25 -	struct tdram_state *prv = (struct tdram_state *)s->private;
   55.26 -	uint64_t size;
   55.27 -	char *p;
   55.28 -	s->private = prv;
   55.29 +	struct td_state    *s     = dd->td_state;
   55.30 +	struct tdram_state *prv   = (struct tdram_state *)dd->private;
   55.31  
   55.32  	connections++;
   55.33  	
   55.34 @@ -209,88 +220,80 @@ int tdram_open (struct td_state *s, cons
   55.35  		ret = 0;
   55.36  	} 
   55.37  
   55.38 +	init_fds(dd);
   55.39  done:
   55.40  	return ret;
   55.41  }
   55.42  
   55.43 - int tdram_queue_read(struct td_state *s, uint64_t sector,
   55.44 -			       int nb_sectors, char *buf, td_callback_t cb,
   55.45 -			       int id, void *private)
   55.46 + int tdram_queue_read(struct disk_driver *dd, uint64_t sector,
   55.47 +		      int nb_sectors, char *buf, td_callback_t cb,
   55.48 +		      int id, void *private)
   55.49  {
   55.50 -	struct tdram_state *prv = (struct tdram_state *)s->private;
   55.51 +	struct td_state    *s   = dd->td_state;
   55.52 +	struct tdram_state *prv = (struct tdram_state *)dd->private;
   55.53  	int      size    = nb_sectors * s->sector_size;
   55.54  	uint64_t offset  = sector * (uint64_t)s->sector_size;
   55.55 -	int ret;
   55.56  
   55.57  	memcpy(buf, img + offset, size);
   55.58 -	ret = size;
   55.59  
   55.60 -	cb(s, (ret < 0) ? ret: 0, id, private);
   55.61 -
   55.62 -	return ret;
   55.63 +	return cb(dd, 0, sector, nb_sectors, id, private);
   55.64  }
   55.65  
   55.66 - int tdram_queue_write(struct td_state *s, uint64_t sector,
   55.67 -			       int nb_sectors, char *buf, td_callback_t cb,
   55.68 -			       int id, void *private)
   55.69 +int tdram_queue_write(struct disk_driver *dd, uint64_t sector,
   55.70 +		      int nb_sectors, char *buf, td_callback_t cb,
   55.71 +		      int id, void *private)
   55.72  {
   55.73 -	struct tdram_state *prv = (struct tdram_state *)s->private;
   55.74 +	struct td_state    *s   = dd->td_state;
   55.75 +	struct tdram_state *prv = (struct tdram_state *)dd->private;
   55.76  	int      size    = nb_sectors * s->sector_size;
   55.77  	uint64_t offset  = sector * (uint64_t)s->sector_size;
   55.78 -	int ret;
   55.79  	
   55.80 -	/*We assume that write access is controlled at a higher level for multiple disks*/
   55.81 +	/* We assume that write access is controlled
   55.82 +	 * at a higher level for multiple disks */
   55.83  	memcpy(img + offset, buf, size);
   55.84 -	ret = size;
   55.85  
   55.86 -	cb(s, (ret < 0) ? ret : 0, id, private);
   55.87 -
   55.88 -	return ret;
   55.89 +	return cb(dd, 0, sector, nb_sectors, id, private);
   55.90  }
   55.91   		
   55.92 -int tdram_submit(struct td_state *s)
   55.93 +int tdram_submit(struct disk_driver *dd)
   55.94  {
   55.95  	return 0;	
   55.96  }
   55.97  
   55.98 -
   55.99 -int *tdram_get_fd(struct td_state *s)
  55.100 +int tdram_close(struct disk_driver *dd)
  55.101  {
  55.102 -	struct tdram_state *prv = (struct tdram_state *)s->private;
  55.103 -        int *fds, i;
  55.104 -
  55.105 -        fds = malloc(sizeof(int) * MAX_IOFD);
  55.106 -        /*initialise the FD array*/
  55.107 -        for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
  55.108 -
  55.109 -        fds[0] = prv->poll_pipe[0];
  55.110 -        return fds;	
  55.111 -}
  55.112 -
  55.113 -int tdram_close(struct td_state *s)
  55.114 -{
  55.115 -	struct tdram_state *prv = (struct tdram_state *)s->private;
  55.116 +	struct tdram_state *prv = (struct tdram_state *)dd->private;
  55.117  	
  55.118  	connections--;
  55.119  	
  55.120  	return 0;
  55.121  }
  55.122  
  55.123 -int tdram_do_callbacks(struct td_state *s, int sid)
  55.124 +int tdram_do_callbacks(struct disk_driver *dd, int sid)
  55.125  {
  55.126  	/* always ask for a kick */
  55.127  	return 1;
  55.128  }
  55.129  
  55.130 +int tdram_has_parent(struct disk_driver *dd)
  55.131 +{
  55.132 +	return 0;
  55.133 +}
  55.134 +
  55.135 +int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent)
  55.136 +{
  55.137 +	return -EINVAL;
  55.138 +}
  55.139 +
  55.140  struct tap_disk tapdisk_ram = {
  55.141 -	"tapdisk_ram",
  55.142 -	sizeof(struct tdram_state),
  55.143 -	tdram_open,
  55.144 -	tdram_queue_read,
  55.145 -	tdram_queue_write,
  55.146 -	tdram_submit,
  55.147 -	tdram_get_fd,
  55.148 -	tdram_close,
  55.149 -	tdram_do_callbacks,
  55.150 +	.disk_type          = "tapdisk_ram",
  55.151 +	.private_data_size  = sizeof(struct tdram_state),
  55.152 +	.td_open            = tdram_open,
  55.153 +	.td_queue_read      = tdram_queue_read,
  55.154 +	.td_queue_write     = tdram_queue_write,
  55.155 +	.td_submit          = tdram_submit,
  55.156 +	.td_has_parent      = tdram_has_parent,
  55.157 +	.td_get_parent      = tdram_get_parent,
  55.158 +	.td_close           = tdram_close,
  55.159 +	.td_do_callbacks    = tdram_do_callbacks,
  55.160  };
  55.161 -
    56.1 --- a/tools/blktap/drivers/block-sync.c	Sun Feb 18 16:13:13 2007 -0700
    56.2 +++ b/tools/blktap/drivers/block-sync.c	Tue Feb 20 12:58:22 2007 -0700
    56.3 @@ -106,12 +106,23 @@ static int get_image_info(struct td_stat
    56.4  	return 0;
    56.5  }
    56.6  
    56.7 +static inline void init_fds(struct disk_driver *dd)
    56.8 +{
    56.9 +	int i;
   56.10 +	struct tdsync_state *prv = (struct tdsync_state *)dd->private;
   56.11 +	
   56.12 +	for(i = 0; i < MAX_IOFD; i++)
   56.13 +		dd->io_fd[i] = 0;
   56.14 +
   56.15 +	dd->io_fd[0] = prv->poll_pipe[0];
   56.16 +}
   56.17 +
   56.18  /* Open the disk file and initialize aio state. */
   56.19 -int tdsync_open (struct td_state *s, const char *name)
   56.20 +int tdsync_open (struct disk_driver *dd, const char *name)
   56.21  {
   56.22  	int i, fd, ret = 0;
   56.23 -	struct tdsync_state *prv = (struct tdsync_state *)s->private;
   56.24 -	s->private = prv;
   56.25 +	struct td_state     *s   = dd->td_state;
   56.26 +	struct tdsync_state *prv = (struct tdsync_state *)dd->private;
   56.27  	
   56.28  	/* set up a pipe so that we can hand back a poll fd that won't fire.*/
   56.29  	ret = pipe(prv->poll_pipe);
   56.30 @@ -138,16 +149,18 @@ int tdsync_open (struct td_state *s, con
   56.31  
   56.32          prv->fd = fd;
   56.33  
   56.34 +	init_fds(dd);
   56.35  	ret = get_image_info(s, fd);
   56.36  done:
   56.37  	return ret;	
   56.38  }
   56.39  
   56.40 - int tdsync_queue_read(struct td_state *s, uint64_t sector,
   56.41 + int tdsync_queue_read(struct disk_driver *dd, uint64_t sector,
   56.42  			       int nb_sectors, char *buf, td_callback_t cb,
   56.43  			       int id, void *private)
   56.44  {
   56.45 -	struct tdsync_state *prv = (struct tdsync_state *)s->private;
   56.46 +	struct td_state     *s   = dd->td_state;
   56.47 +	struct tdsync_state *prv = (struct tdsync_state *)dd->private;
   56.48  	int      size    = nb_sectors * s->sector_size;
   56.49  	uint64_t offset  = sector * (uint64_t)s->sector_size;
   56.50  	int ret;
   56.51 @@ -162,16 +175,15 @@ done:
   56.52  		} 
   56.53  	} else ret = 0 - errno;
   56.54  		
   56.55 -	cb(s, (ret < 0) ? ret: 0, id, private);
   56.56 -	
   56.57 -	return 1;
   56.58 +	return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private);
   56.59  }
   56.60  
   56.61 - int tdsync_queue_write(struct td_state *s, uint64_t sector,
   56.62 + int tdsync_queue_write(struct disk_driver *dd, uint64_t sector,
   56.63  			       int nb_sectors, char *buf, td_callback_t cb,
   56.64  			       int id, void *private)
   56.65  {
   56.66 -	struct tdsync_state *prv = (struct tdsync_state *)s->private;
   56.67 +	struct td_state     *s   = dd->td_state;
   56.68 +	struct tdsync_state *prv = (struct tdsync_state *)dd->private;
   56.69  	int      size    = nb_sectors * s->sector_size;
   56.70  	uint64_t offset  = sector * (uint64_t)s->sector_size;
   56.71  	int ret = 0;
   56.72 @@ -186,34 +198,17 @@ done:
   56.73  		}
   56.74  	} else ret = 0 - errno;
   56.75  		
   56.76 -	cb(s, (ret < 0) ? ret : 0, id, private);
   56.77 -	
   56.78 -	return 1;
   56.79 +	return cb(dd, (ret < 0) ? ret : 0, sector, nb_sectors, id, private);
   56.80  }
   56.81   		
   56.82 -int tdsync_submit(struct td_state *s)
   56.83 +int tdsync_submit(struct disk_driver *dd)
   56.84  {
   56.85  	return 0;	
   56.86  }
   56.87  
   56.88 -
   56.89 -int *tdsync_get_fd(struct td_state *s)
   56.90 +int tdsync_close(struct disk_driver *dd)
   56.91  {
   56.92 -	struct tdsync_state *prv = (struct tdsync_state *)s->private;
   56.93 -	
   56.94 -	int *fds, i;
   56.95 -
   56.96 -	fds = malloc(sizeof(int) * MAX_IOFD);
   56.97 -	/*initialise the FD array*/
   56.98 -	for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
   56.99 -
  56.100 -	fds[0] = prv->poll_pipe[0];
  56.101 -	return fds;
  56.102 -}
  56.103 -
  56.104 -int tdsync_close(struct td_state *s)
  56.105 -{
  56.106 -	struct tdsync_state *prv = (struct tdsync_state *)s->private;
  56.107 +	struct tdsync_state *prv = (struct tdsync_state *)dd->private;
  56.108  	
  56.109  	close(prv->fd);
  56.110  	close(prv->poll_pipe[0]);
  56.111 @@ -222,21 +217,31 @@ int tdsync_close(struct td_state *s)
  56.112  	return 0;
  56.113  }
  56.114  
  56.115 -int tdsync_do_callbacks(struct td_state *s, int sid)
  56.116 +int tdsync_do_callbacks(struct disk_driver *dd, int sid)
  56.117  {
  56.118  	/* always ask for a kick */
  56.119  	return 1;
  56.120  }
  56.121  
  56.122 +int tdsync_has_parent(struct disk_driver *dd)
  56.123 +{
  56.124 +	return 0;
  56.125 +}
  56.126 +
  56.127 +int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent)
  56.128 +{
  56.129 +	return -EINVAL;
  56.130 +}
  56.131 +
  56.132  struct tap_disk tapdisk_sync = {
  56.133 -	"tapdisk_sync",
  56.134 -	sizeof(struct tdsync_state),
  56.135 -	tdsync_open,
  56.136 -	tdsync_queue_read,
  56.137 -	tdsync_queue_write,
  56.138 -	tdsync_submit,
  56.139 -	tdsync_get_fd,
  56.140 -	tdsync_close,
  56.141 -	tdsync_do_callbacks,
  56.142 +	.disk_type           = "tapdisk_sync",
  56.143 +	.private_data_size   = sizeof(struct tdsync_state),
  56.144 +	.td_open             = tdsync_open,
  56.145 +	.td_queue_read       = tdsync_queue_read,
  56.146 +	.td_queue_write      = tdsync_queue_write,
  56.147 +	.td_submit           = tdsync_submit,
  56.148 +	.td_has_parent       = tdsync_has_parent,
  56.149 +	.td_get_parent       = tdsync_get_parent,
  56.150 +	.td_close            = tdsync_close,
  56.151 +	.td_do_callbacks     = tdsync_do_callbacks,
  56.152  };
  56.153 -
    57.1 --- a/tools/blktap/drivers/block-vmdk.c	Sun Feb 18 16:13:13 2007 -0700
    57.2 +++ b/tools/blktap/drivers/block-vmdk.c	Tue Feb 20 12:58:22 2007 -0700
    57.3 @@ -107,14 +107,25 @@ struct tdvmdk_state {
    57.4      	unsigned int cluster_sectors;
    57.5  };
    57.6  
    57.7 +static inline void init_fds(struct disk_driver *dd)
    57.8 +{
    57.9 +        int i;
   57.10 +	struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
   57.11 +
   57.12 +        for (i = 0; i < MAX_IOFD; i++)
   57.13 +		dd->io_fd[i] = 0;
   57.14 +
   57.15 +        dd->io_fd[0] = prv->poll_pipe[0];
   57.16 +}
   57.17  
   57.18  /* Open the disk file and initialize aio state. */
   57.19 -static int tdvmdk_open (struct td_state *s, const char *name)
   57.20 +static int tdvmdk_open (struct disk_driver *dd, const char *name)
   57.21  {
   57.22  	int ret, fd;
   57.23      	int l1_size, i;
   57.24      	uint32_t magic;
   57.25 -	struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
   57.26 +	struct td_state     *s   = dd->td_state;
   57.27 +	struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
   57.28  
   57.29  	/* set up a pipe so that we can hand back a poll fd that won't fire.*/
   57.30  	ret = pipe(prv->poll_pipe);
   57.31 @@ -206,6 +217,7 @@ static int tdvmdk_open (struct td_state 
   57.32      	if (!prv->l2_cache)
   57.33          	goto fail;
   57.34      	prv->fd = fd;
   57.35 +	init_fds(dd);
   57.36  	DPRINTF("VMDK File opened successfully\n");
   57.37      	return 0;
   57.38  	
   57.39 @@ -218,10 +230,9 @@ fail:
   57.40  	return -1;
   57.41  }
   57.42  
   57.43 -static uint64_t get_cluster_offset(struct td_state *s, 
   57.44 +static uint64_t get_cluster_offset(struct tdvmdk_state *prv, 
   57.45                                     uint64_t offset, int allocate)
   57.46  {
   57.47 -	struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
   57.48      	unsigned int l1_index, l2_offset, l2_index;
   57.49      	int min_index, i, j;
   57.50      	uint32_t min_count, *l2_table, tmp;
   57.51 @@ -291,16 +302,17 @@ static uint64_t get_cluster_offset(struc
   57.52      	return cluster_offset;
   57.53  }
   57.54  
   57.55 -static int tdvmdk_queue_read(struct td_state *s, uint64_t sector,
   57.56 +static int tdvmdk_queue_read(struct disk_driver *dd, uint64_t sector,
   57.57  			       int nb_sectors, char *buf, td_callback_t cb,
   57.58  			       int id, void *private)
   57.59  {
   57.60 -	struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
   57.61 +	struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
   57.62      	int index_in_cluster, n;
   57.63      	uint64_t cluster_offset;
   57.64      	int ret = 0;
   57.65 +
   57.66      	while (nb_sectors > 0) {
   57.67 -        	cluster_offset = get_cluster_offset(s, sector << 9, 0);
   57.68 +        	cluster_offset = get_cluster_offset(prv, sector << 9, 0);
   57.69          	index_in_cluster = sector % prv->cluster_sectors;
   57.70          	n = prv->cluster_sectors - index_in_cluster;
   57.71          	if (n > nb_sectors)
   57.72 @@ -321,27 +333,24 @@ static int tdvmdk_queue_read(struct td_s
   57.73          	buf += n * 512;
   57.74      	}
   57.75  done:
   57.76 -	cb(s, ret == -1 ? -1 : 0, id, private);
   57.77 -	
   57.78 -	return 1;
   57.79 +	return cb(dd, ret == -1 ? -1 : 0, sector, nb_sectors, id, private);
   57.80  }
   57.81  
   57.82 -static  int tdvmdk_queue_write(struct td_state *s, uint64_t sector,
   57.83 +static  int tdvmdk_queue_write(struct disk_driver *dd, uint64_t sector,
   57.84  			       int nb_sectors, char *buf, td_callback_t cb,
   57.85  			       int id, void *private)
   57.86  {
   57.87 -	struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
   57.88 +	struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
   57.89      	int index_in_cluster, n;
   57.90      	uint64_t cluster_offset;
   57.91      	int ret = 0;
   57.92 -    	
   57.93  
   57.94      	while (nb_sectors > 0) {
   57.95          	index_in_cluster = sector & (prv->cluster_sectors - 1);
   57.96          	n = prv->cluster_sectors - index_in_cluster;
   57.97          	if (n > nb_sectors)
   57.98              		n = nb_sectors;
   57.99 -        	cluster_offset = get_cluster_offset(s, sector << 9, 1);
  57.100 +        	cluster_offset = get_cluster_offset(prv, sector << 9, 1);
  57.101          	if (!cluster_offset) {
  57.102              		ret = -1;
  57.103              		goto done;
  57.104 @@ -358,33 +367,17 @@ static  int tdvmdk_queue_write(struct td
  57.105          	buf += n * 512;
  57.106      	}
  57.107  done:
  57.108 -	cb(s, ret == -1 ? -1 : 0, id, private);
  57.109 -	
  57.110 -	return 1;
  57.111 +	return cb(dd, ret == -1 ? -1 : 0, sector, nb_sectors, id, private);
  57.112  }
  57.113   		
  57.114 -static int tdvmdk_submit(struct td_state *s)
  57.115 +static int tdvmdk_submit(struct disk_driver *dd)
  57.116  {
  57.117  	return 0;	
  57.118  }
  57.119  
  57.120 -
  57.121 -static int *tdvmdk_get_fd(struct td_state *s)
  57.122 +static int tdvmdk_close(struct disk_driver *dd)
  57.123  {
  57.124 -	struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
  57.125 -        int *fds, i;
  57.126 -
  57.127 -        fds = malloc(sizeof(int) * MAX_IOFD);
  57.128 -        /*initialise the FD array*/
  57.129 -        for (i=0;i<MAX_IOFD;i++) fds[i] = 0;
  57.130 -
  57.131 -        fds[0] = prv->poll_pipe[0];
  57.132 -        return fds;
  57.133 -}
  57.134 -
  57.135 -static int tdvmdk_close(struct td_state *s)
  57.136 -{
  57.137 -	struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
  57.138 +	struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
  57.139  	
  57.140      	safer_free(prv->l1_table);
  57.141      	safer_free(prv->l1_backup_table);
  57.142 @@ -395,21 +388,31 @@ static int tdvmdk_close(struct td_state 
  57.143  	return 0;
  57.144  }
  57.145  
  57.146 -static int tdvmdk_do_callbacks(struct td_state *s, int sid)
  57.147 +static int tdvmdk_do_callbacks(struct disk_driver *dd, int sid)
  57.148  {
  57.149  	/* always ask for a kick */
  57.150  	return 1;
  57.151  }
  57.152  
  57.153 +static int tdvmdk_has_parent(struct disk_driver *dd)
  57.154 +{
  57.155 +	return 0;
  57.156 +}
  57.157 +
  57.158 +static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver *parent)
  57.159 +{
  57.160 +	return -EINVAL;
  57.161 +}
  57.162 +
  57.163  struct tap_disk tapdisk_vmdk = {
  57.164 -	"tapdisk_vmdk",
  57.165 -	sizeof(struct tdvmdk_state),
  57.166 -	tdvmdk_open,
  57.167 -	tdvmdk_queue_read,
  57.168 -	tdvmdk_queue_write,
  57.169 -	tdvmdk_submit,
  57.170 -	tdvmdk_get_fd,
  57.171 -	tdvmdk_close,
  57.172 -	tdvmdk_do_callbacks,
  57.173 +	.disk_type           = "tapdisk_vmdk",
  57.174 +	.private_data_size   = sizeof(struct tdvmdk_state),
  57.175 +	.td_open             = tdvmdk_open,
  57.176 +	.td_queue_read       = tdvmdk_queue_read,
  57.177 +	.td_queue_write      = tdvmdk_queue_write,
  57.178 +	.td_submit           = tdvmdk_submit,
  57.179 +	.td_has_parent       = tdvmdk_has_parent,
  57.180 +	.td_get_parent       = tdvmdk_get_parent,
  57.181 +	.td_close            = tdvmdk_close,
  57.182 +	.td_do_callbacks     = tdvmdk_do_callbacks,
  57.183  };
  57.184 -
    58.1 --- a/tools/blktap/drivers/img2qcow.c	Sun Feb 18 16:13:13 2007 -0700
    58.2 +++ b/tools/blktap/drivers/img2qcow.c	Tue Feb 20 12:58:22 2007 -0700
    58.3 @@ -147,7 +147,8 @@ static int get_image_info(struct td_stat
    58.4  	return 0;
    58.5  }
    58.6  
    58.7 -static int send_responses(struct td_state *s, int res, int idx, void *private)
    58.8 +static int send_responses(struct disk_driver *dd, int res, uint64_t sec, 
    58.9 +			  int nr_secs, int idx, void *private)
   58.10  {
   58.11  	if (res < 0) DFPRINTF("AIO FAILURE: res [%d]!\n",res);
   58.12  	
   58.13 @@ -159,7 +160,7 @@ static int send_responses(struct td_stat
   58.14  
   58.15  int main(int argc, char *argv[])
   58.16  {
   58.17 -	struct tap_disk *drv;
   58.18 +	struct disk_driver dd;
   58.19  	struct td_state *s;
   58.20  	int ret = -1, fd, len;
   58.21  	fd_set readfds;
   58.22 @@ -195,16 +196,17 @@ int main(int argc, char *argv[])
   58.23  	} else DFPRINTF("Qcow file created: size %llu sectors\n",
   58.24  			(long long unsigned)s->size);
   58.25  	
   58.26 -	drv = &tapdisk_qcow;
   58.27 -	s->private = malloc(drv->private_data_size);
   58.28 +	dd.td_state = s;
   58.29 +	dd.drv      = &tapdisk_qcow;
   58.30 +	dd.private  = malloc(dd.drv->private_data_size);
   58.31  
   58.32          /*Open qcow file*/
   58.33 -        if (drv->td_open(s, argv[1])!=0) {
   58.34 +        if (dd.drv->td_open(&dd, argv[1])!=0) {
   58.35  		DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]);
   58.36  		exit(-1);
   58.37  	}
   58.38  
   58.39 -	io_fd = drv->td_get_fd(s);
   58.40 +	io_fd = dd.io_fd;
   58.41  
   58.42  	/*Initialise the output string*/
   58.43  	memset(output,0x20,25);
   58.44 @@ -245,9 +247,9 @@ int main(int argc, char *argv[])
   58.45  				len = (len >> 9) << 9;
   58.46  			}
   58.47  
   58.48 -			ret = drv->td_queue_write(s, i >> 9,
   58.49 -						  len >> 9, buf, 
   58.50 -						  send_responses, 0, buf);
   58.51 +			ret = dd.drv->td_queue_write(&dd, i >> 9,
   58.52 +						     len >> 9, buf, 
   58.53 +						     send_responses, 0, buf);
   58.54  				
   58.55  			if (!ret) submit_events++;
   58.56  				
   58.57 @@ -261,7 +263,7 @@ int main(int argc, char *argv[])
   58.58  			debug_output(i,s->size << 9);
   58.59  			
   58.60  			if ((submit_events % 10 == 0) || complete) 
   58.61 -				drv->td_submit(s);
   58.62 +				dd.drv->td_submit(&dd);
   58.63  			timeout.tv_usec = 0;
   58.64  			
   58.65  		} else {
   58.66 @@ -275,14 +277,14 @@ int main(int argc, char *argv[])
   58.67                  ret = select(maxfds + 1, &readfds, (fd_set *) 0,
   58.68                               (fd_set *) 0, &timeout);
   58.69  			     
   58.70 -		if (ret > 0) drv->td_do_callbacks(s, 0);
   58.71 +		if (ret > 0) dd.drv->td_do_callbacks(&dd, 0);
   58.72  		if (complete && (returned_events == submit_events)) 
   58.73  			running = 0;
   58.74  	}
   58.75  	memcpy(output+prev+1,"=",1);
   58.76  	DFPRINTF("\r%s     100%%\nTRANSFER COMPLETE\n\n", output);
   58.77 -        drv->td_close(s);
   58.78 -        free(s->private);
   58.79 +        dd.drv->td_close(&dd);
   58.80 +        free(dd.private);
   58.81          free(s);
   58.82  		
   58.83  	return 0;
    59.1 --- a/tools/blktap/drivers/qcow2raw.c	Sun Feb 18 16:13:13 2007 -0700
    59.2 +++ b/tools/blktap/drivers/qcow2raw.c	Tue Feb 20 12:58:22 2007 -0700
    59.3 @@ -55,8 +55,7 @@ static int read_complete = 0, write_comp
    59.4  static int returned_read_events = 0, returned_write_events = 0;
    59.5  static int submit_events = 0;
    59.6  static uint32_t read_idx = 0, write_idx = 0;
    59.7 -struct tap_disk *drv1, *drv2;
    59.8 -struct td_state *sqcow, *saio;
    59.9 +struct disk_driver ddqcow, ddaio;
   59.10  static uint64_t prev = 0, written = 0;
   59.11  static char output[25];
   59.12  
   59.13 @@ -100,7 +99,8 @@ static inline void LOCAL_FD_SET(fd_set *
   59.14  	return;
   59.15  }
   59.16  
   59.17 -static int send_write_responses(struct td_state *s, int res, int idx, void *private)
   59.18 +static int send_write_responses(struct disk_driver *dd, int res, uint64_t sec,
   59.19 +				int nr_secs, int idx, void *private)
   59.20  {
   59.21  	if (res < 0) {
   59.22  		DFPRINTF("AIO FAILURE: res [%d]!\n",res);
   59.23 @@ -112,12 +112,13 @@ static int send_write_responses(struct t
   59.24  	if (complete && (returned_write_events == submit_events)) 
   59.25  		write_complete = 1;
   59.26  
   59.27 -	debug_output(written, s->size << 9);
   59.28 +	debug_output(written, dd->td_state->size << 9);
   59.29  	free(private);
   59.30  	return 0;
   59.31  }
   59.32  
   59.33 -static int send_read_responses(struct td_state *s, int res, int idx, void *private)
   59.34 +static int send_read_responses(struct disk_driver *dd, int res, uint64_t sec,
   59.35 +			       int nr_secs, int idx, void *private)
   59.36  {
   59.37  	int ret;
   59.38  
   59.39 @@ -128,8 +129,8 @@ static int send_read_responses(struct td
   59.40  	if (complete && (returned_read_events == submit_events)) 
   59.41  		read_complete = 1;
   59.42  	
   59.43 -	ret = drv2->td_queue_write(saio, idx, BLOCK_PROCESSSZ>>9, private, 
   59.44 -				   send_write_responses, idx, private);
   59.45 +	ret = ddaio.drv->td_queue_write(&ddaio, idx, BLOCK_PROCESSSZ>>9, private, 
   59.46 +					send_write_responses, idx, private);
   59.47  	if (ret != 0) {
   59.48  		DFPRINTF("ERROR in submitting queue write!\n");
   59.49  		return 0;
   59.50 @@ -137,7 +138,7 @@ static int send_read_responses(struct td
   59.51  
   59.52  	if ( (complete && returned_read_events == submit_events) || 
   59.53  	     (returned_read_events % 10 == 0) ) {
   59.54 -		drv2->td_submit(saio);
   59.55 +		ddaio.drv->td_submit(&ddaio);
   59.56  	}
   59.57  
   59.58  	return 0;
   59.59 @@ -161,20 +162,20 @@ int main(int argc, char *argv[])
   59.60  		exit(-1);
   59.61  	}
   59.62  
   59.63 -	sqcow = malloc(sizeof(struct td_state));
   59.64 -	saio  = malloc(sizeof(struct td_state));
   59.65 +	ddqcow.td_state = malloc(sizeof(struct td_state));
   59.66 +	ddaio.td_state  = malloc(sizeof(struct td_state));
   59.67  	
   59.68  	/*Open qcow source file*/	
   59.69 -	drv1 = &tapdisk_qcow;
   59.70 -	sqcow->private = malloc(drv1->private_data_size);
   59.71 +	ddqcow.drv = &tapdisk_qcow;
   59.72 +	ddqcow.private = malloc(ddqcow.drv->private_data_size);
   59.73  
   59.74 -        if (drv1->td_open(sqcow, argv[2])!=0) {
   59.75 +        if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) {
   59.76  		DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]);
   59.77  		exit(-1);
   59.78  	} else DFPRINTF("QCOW file opened, size %llu\n",
   59.79 -		      (long long unsigned)sqcow->size);
   59.80 +		      (long long unsigned)ddqcow.td_state->size);
   59.81  
   59.82 -	qcowio_fd = drv1->td_get_fd(sqcow);
   59.83 +	qcowio_fd = ddqcow.io_fd;
   59.84  
   59.85          /*Setup aio destination file*/
   59.86  	ret = stat(argv[1],&finfo);
   59.87 @@ -191,12 +192,12 @@ int main(int argc, char *argv[])
   59.88  				       argv[1], 0 - errno);
   59.89  				exit(-1);
   59.90  			}
   59.91 -			if (ftruncate(fd, (off_t)sqcow->size<<9) < 0) {
   59.92 +			if (ftruncate(fd, (off_t)ddqcow.td_state->size<<9) < 0) {
   59.93  				DFPRINTF("Unable to create file "
   59.94  					"[%s] of size %llu (errno %d). "
   59.95  					 "Exiting...\n",
   59.96  					argv[1], 
   59.97 -					(long long unsigned)sqcow->size<<9, 
   59.98 +					(long long unsigned)ddqcow.td_state->size<<9, 
   59.99  					0 - errno);
  59.100  				close(fd);
  59.101  				exit(-1);
  59.102 @@ -238,43 +239,43 @@ int main(int argc, char *argv[])
  59.103  				close(fd);
  59.104  				exit(-1);
  59.105  			}
  59.106 -			if (size < sqcow->size<<9) {
  59.107 +			if (size < ddqcow.td_state->size<<9) {
  59.108  				DFPRINTF("ERROR: Not enough space on device "
  59.109  					"%s (%lu bytes available, %llu bytes required\n",
  59.110  					argv[1], size, 
  59.111 -					(long long unsigned)sqcow->size<<9);
  59.112 +					(long long unsigned)ddqcow.td_state->size<<9);
  59.113  				close(fd);
  59.114  				exit(-1);				
  59.115  			}
  59.116  		} else {
  59.117 -			if (ftruncate(fd, (off_t)sqcow->size<<9) < 0) {
  59.118 +			if (ftruncate(fd, (off_t)ddqcow.td_state->size<<9) < 0) {
  59.119  				DFPRINTF("Unable to create file "
  59.120  					"[%s] of size %llu (errno %d). "
  59.121  					 "Exiting...\n",
  59.122  					argv[1], 
  59.123 -					(long long unsigned)sqcow->size<<9, 
  59.124 +					(long long unsigned)ddqcow.td_state->size<<9, 
  59.125  					 0 - errno);
  59.126  				close(fd);
  59.127  				exit(-1);
  59.128  			} else DFPRINTF("File [%s] truncated to length %llu "
  59.129  					"(%llu)\n", 
  59.130  				       argv[1], 
  59.131 -				       (long long unsigned)sqcow->size<<9, 
  59.132 -				       (long long unsigned)sqcow->size);
  59.133 +				       (long long unsigned)ddqcow.td_state->size<<9, 
  59.134 +				       (long long unsigned)ddqcow.td_state->size);
  59.135  		}
  59.136  		close(fd);
  59.137  	}
  59.138  
  59.139  	/*Open aio destination file*/	
  59.140 -	drv2 = &tapdisk_aio;
  59.141 -	saio->private = malloc(drv2->private_data_size);
  59.142 +	ddaio.drv = &tapdisk_aio;
  59.143 +	ddaio.private = malloc(ddaio.drv->private_data_size);
  59.144  
  59.145 -        if (drv2->td_open(saio, argv[1])!=0) {
  59.146 +        if (ddaio.drv->td_open(&ddaio, argv[1])!=0) {
  59.147  		DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]);
  59.148  		exit(-1);
  59.149  	}
  59.150  
  59.151 -	aio_fd = drv2->td_get_fd(saio);
  59.152 +	aio_fd = ddaio.io_fd;
  59.153  
  59.154  	/*Initialise the output string*/
  59.155  	memset(output,0x20,25);
  59.156 @@ -298,9 +299,9 @@ int main(int argc, char *argv[])
  59.157  			}
  59.158  		
  59.159  			/*Attempt to read 4k sized blocks*/
  59.160 -			ret = drv1->td_queue_read(sqcow, i>>9,
  59.161 -						  BLOCK_PROCESSSZ>>9, buf, 
  59.162 -						  send_read_responses, i>>9, buf);
  59.163 +			ret = ddqcow.drv->td_queue_read(&ddqcow, i>>9,
  59.164 +							BLOCK_PROCESSSZ>>9, buf, 
  59.165 +							send_read_responses, i>>9, buf);
  59.166  
  59.167  			if (ret < 0) {
  59.168  				DFPRINTF("UNABLE TO READ block [%llu]\n",
  59.169 @@ -311,12 +312,12 @@ int main(int argc, char *argv[])
  59.170  				submit_events++;
  59.171  			}
  59.172  
  59.173 -			if (i >= sqcow->size<<9) {
  59.174 +			if (i >= ddqcow.td_state->size<<9) {
  59.175  				complete = 1;
  59.176  			}
  59.177  			
  59.178  			if ((submit_events % 10 == 0) || complete) 
  59.179 -				drv1->td_submit(sqcow);
  59.180 +				ddqcow.drv->td_submit(&ddqcow);
  59.181  			timeout.tv_usec = 0;
  59.182  			
  59.183  		} else {
  59.184 @@ -332,9 +333,9 @@ int main(int argc, char *argv[])
  59.185  			     
  59.186  		if (ret > 0) {
  59.187  			if (FD_ISSET(qcowio_fd[0], &readfds)) 
  59.188 -				drv1->td_do_callbacks(sqcow, 0);
  59.189 +				ddqcow.drv->td_do_callbacks(&ddqcow, 0);
  59.190  			if (FD_ISSET(aio_fd[0], &readfds)) 
  59.191 -				drv2->td_do_callbacks(saio, 0);
  59.192 +				ddaio.drv->td_do_callbacks(&ddaio, 0);
  59.193  		}
  59.194  		if (complete && (returned_write_events == submit_events)) 
  59.195  			running = 0;
    60.1 --- a/tools/blktap/drivers/tapdisk.c	Sun Feb 18 16:13:13 2007 -0700
    60.2 +++ b/tools/blktap/drivers/tapdisk.c	Tue Feb 20 12:58:22 2007 -0700
    60.3 @@ -48,6 +48,12 @@ static pid_t process;
    60.4  int connected_disks = 0;
    60.5  fd_list_entry_t *fd_start = NULL;
    60.6  
    60.7 +int do_cow_read(struct disk_driver *dd, blkif_request_t *req, 
    60.8 +		int sidx, uint64_t sector, int nr_secs);
    60.9 +
   60.10 +#define td_for_each_disk(tds, drv) \
   60.11 +        for (drv = tds->disks; drv != NULL; drv = drv->next)
   60.12 +
   60.13  void usage(void) 
   60.14  {
   60.15  	fprintf(stderr, "blktap-utils: v1.0.0\n");
   60.16 @@ -78,10 +84,17 @@ void daemonize(void)
   60.17  static void unmap_disk(struct td_state *s)
   60.18  {
   60.19  	tapdev_info_t *info = s->ring_info;
   60.20 -	struct tap_disk *drv = s->drv;
   60.21 +	struct disk_driver *dd, *tmp;
   60.22  	fd_list_entry_t *entry;
   60.23  
   60.24 -	drv->td_close(s);
   60.25 +	dd = s->disks;
   60.26 +	while (dd) {
   60.27 +		tmp = dd->next;
   60.28 +		dd->drv->td_close(dd);
   60.29 +		free(dd->private);
   60.30 +		free(dd);
   60.31 +		dd = tmp;
   60.32 +	}
   60.33  
   60.34  	if (info != NULL && info->mem > 0)
   60.35  	        munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE);
   60.36 @@ -96,7 +109,6 @@ static void unmap_disk(struct td_state *
   60.37  	free(s->fd_entry);
   60.38  	free(s->blkif);
   60.39  	free(s->ring_info);
   60.40 -        free(s->private);
   60.41  	free(s);
   60.42  
   60.43  	return;
   60.44 @@ -113,16 +125,19 @@ void sig_handler(int sig)
   60.45  static inline int LOCAL_FD_SET(fd_set *readfds)
   60.46  {
   60.47  	fd_list_entry_t *ptr;
   60.48 +	struct disk_driver *dd;
   60.49  
   60.50  	ptr = fd_start;
   60.51  	while (ptr != NULL) {
   60.52  		if (ptr->tap_fd) {
   60.53  			FD_SET(ptr->tap_fd, readfds);
   60.54 -			if (ptr->io_fd[READ]) 
   60.55 -				FD_SET(ptr->io_fd[READ], readfds);
   60.56 -			maxfds = (ptr->io_fd[READ] > maxfds ? 
   60.57 -					ptr->io_fd[READ]: maxfds);
   60.58 -			maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd: maxfds);
   60.59 +			td_for_each_disk(ptr->s, dd) {
   60.60 +				if (dd->io_fd[READ]) 
   60.61 +					FD_SET(dd->io_fd[READ], readfds);
   60.62 +				maxfds = (dd->io_fd[READ] > maxfds ? 
   60.63 +					  dd->io_fd[READ] : maxfds);
   60.64 +			}
   60.65 +			maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd : maxfds);
   60.66  		}
   60.67  		ptr = ptr->next;
   60.68  	}
   60.69 @@ -130,8 +145,7 @@ static inline int LOCAL_FD_SET(fd_set *r
   60.70  	return 0;
   60.71  }
   60.72  
   60.73 -static inline fd_list_entry_t *add_fd_entry(
   60.74 -	int tap_fd, int io_fd[MAX_IOFD], struct td_state *s)
   60.75 +static inline fd_list_entry_t *add_fd_entry(int tap_fd, struct td_state *s)
   60.76  {
   60.77  	fd_list_entry_t **pprev, *entry;
   60.78  	int i;
   60.79 @@ -139,12 +153,10 @@ static inline fd_list_entry_t *add_fd_en
   60.80  	DPRINTF("Adding fd_list_entry\n");
   60.81  
   60.82  	/*Add to linked list*/
   60.83 -	s->fd_entry = entry = malloc(sizeof(fd_list_entry_t));
   60.84 +	s->fd_entry   = entry = malloc(sizeof(fd_list_entry_t));
   60.85  	entry->tap_fd = tap_fd;
   60.86 -	for (i = 0; i < MAX_IOFD; i++)
   60.87 -		entry->io_fd[i] = io_fd[i];
   60.88 -	entry->s = s;
   60.89 -	entry->next = NULL;
   60.90 +	entry->s      = s;
   60.91 +	entry->next   = NULL;
   60.92  
   60.93  	pprev = &fd_start;
   60.94  	while (*pprev != NULL)
   60.95 @@ -171,7 +183,7 @@ static inline struct td_state *get_state
   60.96  static struct tap_disk *get_driver(int drivertype)
   60.97  {
   60.98  	/* blktapctrl has passed us the driver type */
   60.99 -	
  60.100 +
  60.101  	return dtypes[drivertype]->drv;
  60.102  }
  60.103  
  60.104 @@ -183,14 +195,36 @@ static struct td_state *state_init(void)
  60.105  
  60.106  	s = malloc(sizeof(struct td_state));
  60.107  	blkif = s->blkif = malloc(sizeof(blkif_t));
  60.108 -	s->ring_info = malloc(sizeof(tapdev_info_t));
  60.109 +	s->ring_info = calloc(1, sizeof(tapdev_info_t));
  60.110  
  60.111 -	for (i = 0; i < MAX_REQUESTS; i++)
  60.112 -		blkif->pending_list[i].count = 0;
  60.113 +	for (i = 0; i < MAX_REQUESTS; i++) {
  60.114 +		blkif->pending_list[i].secs_pending = 0;
  60.115 +		blkif->pending_list[i].submitting = 0;
  60.116 +	}
  60.117  
  60.118  	return s;
  60.119  }
  60.120  
  60.121 +static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv)
  60.122 +{
  60.123 +	struct disk_driver *dd;
  60.124 +
  60.125 +	dd = calloc(1, sizeof(struct disk_driver));
  60.126 +	if (!dd)
  60.127 +		return NULL;
  60.128 +	
  60.129 +	dd->private = malloc(drv->private_data_size);
  60.130 +	if (!dd->private) {
  60.131 +		free(dd);
  60.132 +		return NULL;
  60.133 +	}
  60.134 +
  60.135 +	dd->drv      = drv;
  60.136 +	dd->td_state = s;
  60.137 +
  60.138 +	return dd;
  60.139 +}
  60.140 +
  60.141  static int map_new_dev(struct td_state *s, int minor)
  60.142  {
  60.143  	int tap_fd;
  60.144 @@ -246,6 +280,51 @@ static int map_new_dev(struct td_state *
  60.145  	return -1;
  60.146  }
  60.147  
  60.148 +static int open_disk(struct td_state *s, struct disk_driver *dd, char *path)
  60.149 +{
  60.150 +	int err;
  60.151 +	struct disk_driver *d = dd;
  60.152 +
  60.153 +	err = dd->drv->td_open(dd, path);
  60.154 +	if (err)
  60.155 +		return err;
  60.156 +
  60.157 +	/* load backing files as necessary */
  60.158 +	while (d->drv->td_has_parent(d)) {
  60.159 +		struct disk_driver *new;
  60.160 +		
  60.161 +		new = calloc(1, sizeof(struct disk_driver));
  60.162 +		if (!new)
  60.163 +			goto fail;
  60.164 +		new->drv      = d->drv;
  60.165 +		new->td_state = s;
  60.166 +		new->private  = malloc(new->drv->private_data_size);
  60.167 +		if (!new->private) {
  60.168 +			free(new);
  60.169 +			goto fail;
  60.170 +		}
  60.171 +		
  60.172 +		err = d->drv->td_get_parent(d, new);
  60.173 +		if (err)
  60.174 +			goto fail;
  60.175 +
  60.176 +		d = d->next = new;
  60.177 +	}
  60.178 +
  60.179 +	return 0;
  60.180 +
  60.181 + fail:
  60.182 +	DPRINTF("failed opening disk\n");
  60.183 +	while (dd) {
  60.184 +		d = dd->next;
  60.185 +		dd->drv->td_close(dd);
  60.186 +		free(dd->private);
  60.187 +		free(dd);
  60.188 +		dd = d;
  60.189 +	}
  60.190 +	return err;
  60.191 +}
  60.192 +
  60.193  static int read_msg(char *buf)
  60.194  {
  60.195  	int length, len, msglen, tap_fd, *io_fd;
  60.196 @@ -255,6 +334,7 @@ static int read_msg(char *buf)
  60.197  	msg_newdev_t *msg_dev;
  60.198  	msg_pid_t *msg_pid;
  60.199  	struct tap_disk *drv;
  60.200 +	struct disk_driver *dd;
  60.201  	int ret = -1;
  60.202  	struct td_state *s = NULL;
  60.203  	fd_list_entry_t *entry;
  60.204 @@ -289,20 +369,20 @@ static int read_msg(char *buf)
  60.205  			if (s == NULL)
  60.206  				goto params_done;
  60.207  
  60.208 -			s->drv = drv;
  60.209 -			s->private = malloc(drv->private_data_size);
  60.210 -			if (s->private == NULL) {
  60.211 +			s->disks = dd = disk_init(s, drv);
  60.212 +			if (!dd) {
  60.213  				free(s);
  60.214  				goto params_done;
  60.215  			}
  60.216  
  60.217  			/*Open file*/
  60.218 -			ret = drv->td_open(s, path);
  60.219 -			io_fd = drv->td_get_fd(s);
  60.220 +			ret = open_disk(s, dd, path);
  60.221 +			if (ret)
  60.222 +				goto params_done;
  60.223  
  60.224 -			entry = add_fd_entry(0, io_fd, s);
  60.225 +			entry = add_fd_entry(0, s);
  60.226  			entry->cookie = msg->cookie;
  60.227 -			DPRINTF("Entered cookie %d\n",entry->cookie);
  60.228 +			DPRINTF("Entered cookie %d\n", entry->cookie);
  60.229  			
  60.230  			memset(buf, 0x00, MSG_SIZE); 
  60.231  			
  60.232 @@ -323,13 +403,12 @@ static int read_msg(char *buf)
  60.233  			free(path);
  60.234  			return 1;
  60.235  			
  60.236 -			
  60.237 -			
  60.238  		case CTLMSG_NEWDEV:
  60.239  			msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t));
  60.240  
  60.241  			s = get_state(msg->cookie);
  60.242 -			DPRINTF("Retrieving state, cookie %d.....[%s]\n",msg->cookie, (s == NULL ? "FAIL":"OK"));
  60.243 +			DPRINTF("Retrieving state, cookie %d.....[%s]\n",
  60.244 +				msg->cookie, (s == NULL ? "FAIL":"OK"));
  60.245  			if (s != NULL) {
  60.246  				ret = ((map_new_dev(s, msg_dev->devnum) 
  60.247  					== msg_dev->devnum ? 0: -1));
  60.248 @@ -397,49 +476,75 @@ static inline void kick_responses(struct
  60.249  	}
  60.250  }
  60.251  
  60.252 -void io_done(struct td_state *s, int sid)
  60.253 +void io_done(struct disk_driver *dd, int sid)
  60.254  {
  60.255 -	struct tap_disk *drv = s->drv;
  60.256 +	struct tap_disk *drv = dd->drv;
  60.257  
  60.258  	if (!run) return; /*We have received signal to close*/
  60.259  
  60.260 -	if (drv->td_do_callbacks(s, sid) > 0) kick_responses(s);
  60.261 +	if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state);
  60.262  
  60.263  	return;
  60.264  }
  60.265  
  60.266 -int send_responses(struct td_state *s, int res, int idx, void *private)
  60.267 +static inline uint64_t
  60.268 +segment_start(blkif_request_t *req, int sidx)
  60.269  {
  60.270 +	int i;
  60.271 +	uint64_t start = req->sector_number;
  60.272 +
  60.273 +	for (i = 0; i < sidx; i++) 
  60.274 +		start += (req->seg[i].last_sect - req->seg[i].first_sect + 1);
  60.275 +
  60.276 +	return start;
  60.277 +}
  60.278 +
  60.279 +uint64_t sends, responds;
  60.280 +int send_responses(struct disk_driver *dd, int res, 
  60.281 +		   uint64_t sector, int nr_secs, int idx, void *private)
  60.282 +{
  60.283 +	pending_req_t   *preq;
  60.284  	blkif_request_t *req;
  60.285  	int responses_queued = 0;
  60.286 +	struct td_state *s = dd->td_state;
  60.287  	blkif_t *blkif = s->blkif;
  60.288 +	int sidx = (int)(long)private, secs_done = nr_secs;
  60.289  
  60.290 -	req   = &blkif->pending_list[idx].req;
  60.291 -			
  60.292 -	if ( (idx > MAX_REQUESTS-1) || 
  60.293 -	    (blkif->pending_list[idx].count == 0) )
  60.294 +	if ( (idx > MAX_REQUESTS-1) )
  60.295  	{
  60.296  		DPRINTF("invalid index returned(%u)!\n", idx);
  60.297  		return 0;
  60.298  	}
  60.299 -	
  60.300 -	if (res != 0) {
  60.301 -	        blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
  60.302 +	preq = &blkif->pending_list[idx];
  60.303 +	req  = &preq->req;
  60.304 +
  60.305 +	if (res == BLK_NOT_ALLOCATED) {
  60.306 +		res = do_cow_read(dd, req, sidx, sector, nr_secs);
  60.307 +		if (res >= 0) {
  60.308 +			secs_done = res;
  60.309 +			res = 0;
  60.310 +		} else
  60.311 +			secs_done = 0;
  60.312  	}
  60.313  
  60.314 -	blkif->pending_list[idx].count--;
  60.315 +	preq->secs_pending -= secs_done;
  60.316 +
  60.317 +	if (res == -EBUSY && preq->submitting) 
  60.318 +		return -EBUSY;  /* propagate -EBUSY back to higher layers */
  60.319 +	if (res) 
  60.320 +		preq->status = BLKIF_RSP_ERROR;
  60.321  	
  60.322 -	if (blkif->pending_list[idx].count == 0) 
  60.323 +	if (!preq->submitting && preq->secs_pending == 0) 
  60.324  	{
  60.325  		blkif_request_t tmp;
  60.326  		blkif_response_t *rsp;
  60.327 -		
  60.328 -		tmp = blkif->pending_list[idx].req;
  60.329 +
  60.330 +		tmp = preq->req;
  60.331  		rsp = (blkif_response_t *)req;
  60.332  		
  60.333  		rsp->id = tmp.id;
  60.334  		rsp->operation = tmp.operation;
  60.335 -		rsp->status = blkif->pending_list[idx].status;
  60.336 +		rsp->status = preq->status;
  60.337  		
  60.338  		write_rsp_to_ring(s, rsp);
  60.339  		responses_queued++;
  60.340 @@ -447,15 +552,51 @@ int send_responses(struct td_state *s, i
  60.341  	return responses_queued;
  60.342  }
  60.343  
  60.344 +int do_cow_read(struct disk_driver *dd, blkif_request_t *req, 
  60.345 +		int sidx, uint64_t sector, int nr_secs)
  60.346 +{
  60.347 +	char *page;
  60.348 +	int ret, early;
  60.349 +	uint64_t seg_start, seg_end;
  60.350 +	struct td_state  *s = dd->td_state;
  60.351 +	tapdev_info_t *info = s->ring_info;
  60.352 +	struct disk_driver *parent = dd->next;
  60.353 +	
  60.354 +	seg_start = segment_start(req, sidx);
  60.355 +	seg_end   = seg_start + req->seg[sidx].last_sect + 1;
  60.356 +	
  60.357 +	ASSERT(sector >= seg_start && sector + nr_secs <= seg_end);
  60.358 +
  60.359 +	page  = (char *)MMAP_VADDR(info->vstart, 
  60.360 +				   (unsigned long)req->id, sidx);
  60.361 +	page += (req->seg[sidx].first_sect << SECTOR_SHIFT);
  60.362 +	page += ((sector - seg_start) << SECTOR_SHIFT);
  60.363 +
  60.364 +	if (!parent) {
  60.365 +		memset(page, 0, nr_secs << SECTOR_SHIFT);
  60.366 +		return nr_secs;
  60.367 +	}
  60.368 +
  60.369 +	/* reissue request to backing file */
  60.370 +	ret = parent->drv->td_queue_read(parent, sector, nr_secs,
  60.371 +					 page, send_responses, 
  60.372 +					 req->id, (void *)(long)sidx);
  60.373 +	if (ret > 0)
  60.374 +		parent->early += ret;
  60.375 +
  60.376 +	return ((ret >= 0) ? 0 : ret);
  60.377 +}
  60.378 +
  60.379  static void get_io_request(struct td_state *s)
  60.380  {
  60.381 -	RING_IDX          rp, rc, j, i, ret;
  60.382 +	RING_IDX          rp, rc, j, i;
  60.383  	blkif_request_t  *req;
  60.384 -	int idx, nsects;
  60.385 +	int idx, nsects, ret;
  60.386  	uint64_t sector_nr;
  60.387  	char *page;
  60.388  	int early = 0; /* count early completions */
  60.389 -	struct tap_disk *drv = s->drv;
  60.390 +	struct disk_driver *dd = s->disks;
  60.391 +	struct tap_disk *drv   = dd->drv;
  60.392  	blkif_t *blkif = s->blkif;
  60.393  	tapdev_info_t *info = s->ring_info;
  60.394  	int page_size = getpagesize();
  60.395 @@ -466,23 +607,33 @@ static void get_io_request(struct td_sta
  60.396  	rmb();
  60.397  	for (j = info->fe_ring.req_cons; j != rp; j++)
  60.398  	{
  60.399 -		int done = 0; 
  60.400 +		int done = 0, start_seg = 0; 
  60.401  
  60.402  		req = NULL;
  60.403  		req = RING_GET_REQUEST(&info->fe_ring, j);
  60.404  		++info->fe_ring.req_cons;
  60.405  		
  60.406  		if (req == NULL) continue;
  60.407 -		
  60.408 +
  60.409  		idx = req->id;
  60.410 -		ASSERT(blkif->pending_list[idx].count == 0);
  60.411 -		memcpy(&blkif->pending_list[idx].req, req, sizeof(*req));
  60.412 -		blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
  60.413 -		blkif->pending_list[idx].count = req->nr_segments;
  60.414  
  60.415 -		sector_nr = req->sector_number;
  60.416 +		if (info->busy.req) {
  60.417 +			/* continue where we left off last time */
  60.418 +			ASSERT(info->busy.req == req);
  60.419 +			start_seg = info->busy.seg_idx;
  60.420 +			sector_nr = segment_start(req, start_seg);
  60.421 +			info->busy.seg_idx = 0;
  60.422 +			info->busy.req     = NULL;
  60.423 +		} else {
  60.424 +			ASSERT(blkif->pending_list[idx].secs_pending == 0);
  60.425 +			memcpy(&blkif->pending_list[idx].req, 
  60.426 +			       req, sizeof(*req));
  60.427 +			blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
  60.428 +			blkif->pending_list[idx].submitting = 1;
  60.429 +			sector_nr = req->sector_number;
  60.430 +		}
  60.431  
  60.432 -		for (i = 0; i < req->nr_segments; i++) {
  60.433 +		for (i = start_seg; i < req->nr_segments; i++) {
  60.434  			nsects = req->seg[i].last_sect - 
  60.435  				 req->seg[i].first_sect + 1;
  60.436  	
  60.437 @@ -508,31 +659,37 @@ static void get_io_request(struct td_sta
  60.438  					(long long unsigned) sector_nr);
  60.439  				continue;
  60.440  			}
  60.441 -			
  60.442 +
  60.443 +			blkif->pending_list[idx].secs_pending += nsects;
  60.444 +
  60.445  			switch (req->operation) 
  60.446  			{
  60.447  			case BLKIF_OP_WRITE:
  60.448 -				ret = drv->td_queue_write(s, sector_nr,
  60.449 -						nsects, page, send_responses, 
  60.450 -						idx, NULL);
  60.451 -				if (ret > 0) early += ret;
  60.452 +				ret = drv->td_queue_write(dd, sector_nr,
  60.453 +							  nsects, page, 
  60.454 +							  send_responses,
  60.455 +							  idx, (void *)(long)i);
  60.456 +				if (ret > 0) dd->early += ret;
  60.457  				else if (ret == -EBUSY) {
  60.458 -					/*
  60.459 -					 * TODO: Sector is locked         *
  60.460 -					 * Need to put req back on queue  *
  60.461 -					 */
  60.462 +					/* put req back on queue */
  60.463 +					--info->fe_ring.req_cons;
  60.464 +					info->busy.req     = req;
  60.465 +					info->busy.seg_idx = i;
  60.466 +					goto out;
  60.467  				}
  60.468  				break;
  60.469  			case BLKIF_OP_READ:
  60.470 -				ret = drv->td_queue_read(s, sector_nr,
  60.471 -						nsects, page, send_responses, 
  60.472 -						idx, NULL);
  60.473 -				if (ret > 0) early += ret;
  60.474 +				ret = drv->td_queue_read(dd, sector_nr,
  60.475 +							 nsects, page, 
  60.476 +							 send_responses,
  60.477 +							 idx, (void *)(long)i);
  60.478 +				if (ret > 0) dd->early += ret;
  60.479  				else if (ret == -EBUSY) {
  60.480 -					/*
  60.481 -					 * TODO: Sector is locked         *
  60.482 -					 * Need to put req back on queue  *
  60.483 -					 */
  60.484 +					/* put req back on queue */
  60.485 +					--info->fe_ring.req_cons;
  60.486 +					info->busy.req     = req;
  60.487 +					info->busy.seg_idx = i;
  60.488 +					goto out;
  60.489  				}
  60.490  				break;
  60.491  			default:
  60.492 @@ -541,14 +698,22 @@ static void get_io_request(struct td_sta
  60.493  			}
  60.494  			sector_nr += nsects;
  60.495  		}
  60.496 +		blkif->pending_list[idx].submitting = 0;
  60.497 +		/* force write_rsp_to_ring for synchronous case */
  60.498 +		if (blkif->pending_list[idx].secs_pending == 0)
  60.499 +			dd->early += send_responses(dd, 0, 0, 0, idx, (void *)0);
  60.500  	}
  60.501  
  60.502 + out:
  60.503  	/*Batch done*/
  60.504 -	drv->td_submit(s);
  60.505 -	
  60.506 -	if (early > 0) 
  60.507 -		io_done(s,10);
  60.508 -		
  60.509 +	td_for_each_disk(s, dd) {
  60.510 +		dd->early += dd->drv->td_submit(dd);
  60.511 +		if (dd->early > 0) {
  60.512 +			io_done(dd, 10);
  60.513 +			dd->early = 0;
  60.514 +		}
  60.515 +	}
  60.516 +
  60.517  	return;
  60.518  }
  60.519  
  60.520 @@ -558,10 +723,9 @@ int main(int argc, char *argv[])
  60.521  	char *p, *buf;
  60.522  	fd_set readfds, writefds;	
  60.523  	fd_list_entry_t *ptr;
  60.524 -	struct tap_disk *drv;
  60.525  	struct td_state *s;
  60.526  	char openlogbuf[128];
  60.527 -	
  60.528 +
  60.529  	if (argc != 3) usage();
  60.530  
  60.531  	daemonize();
  60.532 @@ -573,12 +737,12 @@ int main(int argc, char *argv[])
  60.533  	signal (SIGINT, sig_handler);
  60.534  
  60.535  	/*Open the control channel*/
  60.536 -	fds[READ] = open(argv[1],O_RDWR|O_NONBLOCK);
  60.537 +	fds[READ]  = open(argv[1],O_RDWR|O_NONBLOCK);
  60.538  	fds[WRITE] = open(argv[2],O_RDWR|O_NONBLOCK);
  60.539  
  60.540  	if ( (fds[READ] < 0) || (fds[WRITE] < 0) ) 
  60.541  	{
  60.542 -		DPRINTF("FD open failed [%d,%d]\n",fds[READ], fds[WRITE]);
  60.543 +		DPRINTF("FD open failed [%d,%d]\n", fds[READ], fds[WRITE]);
  60.544  		exit(-1);
  60.545  	}
  60.546  
  60.547 @@ -608,11 +772,22 @@ int main(int argc, char *argv[])
  60.548  		{
  60.549  			ptr = fd_start;
  60.550  			while (ptr != NULL) {
  60.551 -				if (FD_ISSET(ptr->tap_fd, &readfds)) 
  60.552 +				int progress_made = 0;
  60.553 +				struct disk_driver *dd;
  60.554 +				tapdev_info_t *info = ptr->s->ring_info;
  60.555 +
  60.556 +				td_for_each_disk(ptr->s, dd) {
  60.557 +					if (dd->io_fd[READ] &&
  60.558 +					    FD_ISSET(dd->io_fd[READ], 
  60.559 +						     &readfds)) {
  60.560 +						io_done(dd, READ);
  60.561 +						progress_made = 1;
  60.562 +					}
  60.563 +				}
  60.564 +
  60.565 +				if (FD_ISSET(ptr->tap_fd, &readfds) ||
  60.566 +				    (info->busy.req && progress_made))
  60.567  					get_io_request(ptr->s);
  60.568 -				if (ptr->io_fd[READ] && 
  60.569 -						FD_ISSET(ptr->io_fd[READ], &readfds)) 
  60.570 -					io_done(ptr->s, READ);
  60.571  
  60.572  				ptr = ptr->next;
  60.573  			}
  60.574 @@ -628,11 +803,8 @@ int main(int argc, char *argv[])
  60.575  	ptr = fd_start;
  60.576  	while (ptr != NULL) {
  60.577  		s = ptr->s;
  60.578 -		drv = s->drv;
  60.579  
  60.580  		unmap_disk(s);
  60.581 -		drv->td_close(s);
  60.582 -		free(s->private);
  60.583  		free(s->blkif);
  60.584  		free(s->ring_info);
  60.585  		free(s);
    61.1 --- a/tools/blktap/drivers/tapdisk.h	Sun Feb 18 16:13:13 2007 -0700
    61.2 +++ b/tools/blktap/drivers/tapdisk.h	Tue Feb 20 12:58:22 2007 -0700
    61.3 @@ -43,6 +43,9 @@
    61.4   *   - The fd used for poll is an otherwise unused pipe, which allows poll to 
    61.5   *     be safely called without ever returning anything.
    61.6   * 
    61.7 + * NOTE: tapdisk uses the number of sectors submitted per request as a 
    61.8 + * ref count.  Plugins must use the callback function to communicate the
    61.9 + * completion--or error--of every sector submitted to them.
   61.10   */
   61.11  
   61.12  #ifndef TAPDISK_H_
   61.13 @@ -65,39 +68,55 @@
   61.14  #define SECTOR_SHIFT             9
   61.15  #define DEFAULT_SECTOR_SIZE    512
   61.16  
   61.17 +#define MAX_IOFD                 2
   61.18 +
   61.19 +#define BLK_NOT_ALLOCATED       99
   61.20 +
   61.21 +struct td_state;
   61.22 +struct tap_disk;
   61.23 +
   61.24 +struct disk_driver {
   61.25 +	int early;
   61.26 +	void *private;
   61.27 +	int io_fd[MAX_IOFD];
   61.28 +	struct tap_disk *drv;
   61.29 +	struct td_state *td_state;
   61.30 +	struct disk_driver *next;
   61.31 +};
   61.32 +
   61.33  /* This structure represents the state of an active virtual disk.           */
   61.34  struct td_state {
   61.35 -	void *private;
   61.36 -	void *drv;
   61.37 +	struct disk_driver *disks;
   61.38  	void *blkif;
   61.39  	void *image;
   61.40  	void *ring_info;
   61.41  	void *fd_entry;
   61.42 -	char backing_file[1024]; /*Used by differencing disks, e.g. qcow*/
   61.43  	unsigned long      sector_size;
   61.44  	unsigned long long size;
   61.45  	unsigned int       info;
   61.46  };
   61.47  
   61.48  /* Prototype of the callback to activate as requests complete.              */
   61.49 -typedef int (*td_callback_t)(struct td_state *s, int res, int id, void *prv);
   61.50 +typedef int (*td_callback_t)(struct disk_driver *dd, int res, uint64_t sector,
   61.51 +			     int nb_sectors, int id, void *private);
   61.52  
   61.53  /* Structure describing the interface to a virtual disk implementation.     */
   61.54  /* See note at the top of this file describing this interface.              */
   61.55  struct tap_disk {
   61.56  	const char *disk_type;
   61.57  	int private_data_size;
   61.58 -	int (*td_open)        (struct td_state *s, const char *name);
   61.59 -	int (*td_queue_read)  (struct td_state *s, uint64_t sector,
   61.60 -			       int nb_sectors, char *buf, td_callback_t cb,
   61.61 +	int (*td_open)        (struct disk_driver *dd, const char *name);
   61.62 +	int (*td_queue_read)  (struct disk_driver *dd, uint64_t sector,
   61.63 +			       int nb_sectors, char *buf, td_callback_t cb, 
   61.64  			       int id, void *prv);
   61.65 -	int (*td_queue_write) (struct td_state *s, uint64_t sector,
   61.66 -			       int nb_sectors, char *buf, td_callback_t cb,
   61.67 +	int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
   61.68 +			       int nb_sectors, char *buf, td_callback_t cb, 
   61.69  			       int id, void *prv);
   61.70 -	int (*td_submit)      (struct td_state *s);
   61.71 -	int *(*td_get_fd)      (struct td_state *s);
   61.72 -	int (*td_close)       (struct td_state *s);
   61.73 -	int (*td_do_callbacks)(struct td_state *s, int sid);
   61.74 +	int (*td_submit)      (struct disk_driver *dd);
   61.75 +	int (*td_has_parent)  (struct disk_driver *dd);
   61.76 +	int (*td_get_parent)  (struct disk_driver *dd, struct disk_driver *p);
   61.77 +	int (*td_close)       (struct disk_driver *dd);
   61.78 +	int (*td_do_callbacks)(struct disk_driver *dd, int sid);
   61.79  };
   61.80  
   61.81  typedef struct disk_info {
   61.82 @@ -119,14 +138,13 @@ extern struct tap_disk tapdisk_vmdk;
   61.83  extern struct tap_disk tapdisk_ram;
   61.84  extern struct tap_disk tapdisk_qcow;
   61.85  
   61.86 -#define MAX_DISK_TYPES  20
   61.87 -#define MAX_IOFD        2
   61.88 +#define MAX_DISK_TYPES     20
   61.89  
   61.90 -#define DISK_TYPE_AIO   0
   61.91 -#define DISK_TYPE_SYNC  1
   61.92 -#define DISK_TYPE_VMDK  2
   61.93 -#define DISK_TYPE_RAM   3
   61.94 -#define DISK_TYPE_QCOW  4
   61.95 +#define DISK_TYPE_AIO      0
   61.96 +#define DISK_TYPE_SYNC     1
   61.97 +#define DISK_TYPE_VMDK     2
   61.98 +#define DISK_TYPE_RAM      3
   61.99 +#define DISK_TYPE_QCOW     4
  61.100  
  61.101  
  61.102  /*Define Individual Disk Parameters here */
  61.103 @@ -197,12 +215,10 @@ typedef struct driver_list_entry {
  61.104  typedef struct fd_list_entry {
  61.105  	int cookie;
  61.106  	int  tap_fd;
  61.107 -	int  io_fd[MAX_IOFD];
  61.108  	struct td_state *s;
  61.109  	struct fd_list_entry **pprev, *next;
  61.110  } fd_list_entry_t;
  61.111  
  61.112  int qcow_create(const char *filename, uint64_t total_size,
  61.113  		const char *backing_file, int flags);
  61.114 -
  61.115  #endif /*TAPDISK_H_*/
    62.1 --- a/tools/blktap/lib/blktaplib.h	Sun Feb 18 16:13:13 2007 -0700
    62.2 +++ b/tools/blktap/lib/blktaplib.h	Tue Feb 20 12:58:22 2007 -0700
    62.3 @@ -91,8 +91,9 @@ struct blkif;
    62.4  
    62.5  typedef struct {
    62.6  	blkif_request_t  req;
    62.7 -	struct blkif         *blkif;
    62.8 -	int              count;
    62.9 +	struct blkif    *blkif;
   62.10 +	int              submitting;
   62.11 +	int              secs_pending;
   62.12          int16_t          status;
   62.13  } pending_req_t;
   62.14  
   62.15 @@ -116,7 +117,7 @@ typedef struct blkif {
   62.16  	
   62.17  	void *prv;  /* device-specific data */
   62.18  	void *info; /*Image parameter passing */
   62.19 -	pending_req_t    pending_list[MAX_REQUESTS];
   62.20 +	pending_req_t pending_list[MAX_REQUESTS];
   62.21  	int devnum;
   62.22  	int fds[2];
   62.23  	int be_id;
   62.24 @@ -141,6 +142,11 @@ int blkif_init(blkif_t *blkif, long int 
   62.25  void free_blkif(blkif_t *blkif);
   62.26  void __init_blkif(void);
   62.27  
   62.28 +typedef struct busy_state {
   62.29 +	int seg_idx;
   62.30 +	blkif_request_t *req;
   62.31 +} busy_state_t;
   62.32 +
   62.33  typedef struct tapdev_info {
   62.34  	int fd;
   62.35  	char *mem;
   62.36 @@ -148,6 +154,7 @@ typedef struct tapdev_info {
   62.37  	blkif_back_ring_t  fe_ring;
   62.38  	unsigned long vstart;
   62.39  	blkif_t *blkif;
   62.40 +	busy_state_t busy;
   62.41  } tapdev_info_t;
   62.42  
   62.43  typedef struct domid_translate {
    63.1 --- a/tools/blktap/lib/xs_api.c	Sun Feb 18 16:13:13 2007 -0700
    63.2 +++ b/tools/blktap/lib/xs_api.c	Tue Feb 20 12:58:22 2007 -0700
    63.3 @@ -311,8 +311,8 @@ int unregister_xenbus_watch(struct xs_ha
    63.4  	}
    63.5  
    63.6  	if (!xs_unwatch(h, watch->node, token))
    63.7 -		DPRINTF("XENBUS Failed to release watch %s: %i\n",
    63.8 -			watch->node, er);
    63.9 +		DPRINTF("XENBUS Failed to release watch %s\n",
   63.10 +			watch->node);
   63.11  
   63.12  	list_del(&watch->list);
   63.13  	
   63.14 @@ -351,9 +351,9 @@ int xs_fire_next_watch(struct xs_handle 
   63.15  	
   63.16  	node  = res[XS_WATCH_PATH];
   63.17  	token = res[XS_WATCH_TOKEN];
   63.18 -	
   63.19 +
   63.20  	w = find_watch(token);
   63.21 -	if (w)
   63.22 +	if (w) 
   63.23  		w->callback(h, w, node);
   63.24  
   63.25  	free(res);
    64.1 --- a/tools/check/check_zlib_lib	Sun Feb 18 16:13:13 2007 -0700
    64.2 +++ b/tools/check/check_zlib_lib	Tue Feb 20 12:58:22 2007 -0700
    64.3 @@ -3,8 +3,10 @@
    64.4  
    64.5  RC=0
    64.6  
    64.7 +PATH=/sbin:$PATH
    64.8 +
    64.9  set -e
   64.10 -ldconfig -v 2>&1 | grep -q libz.so || RC=1
   64.11 +ldconfig -p 2>&1 | grep -q libz.so || RC=1
   64.12  
   64.13  if test ${RC} -ne 0; then
   64.14  	echo
    65.1 --- a/tools/console/daemon/io.c	Sun Feb 18 16:13:13 2007 -0700
    65.2 +++ b/tools/console/daemon/io.c	Tue Feb 20 12:58:22 2007 -0700
    65.3 @@ -63,6 +63,7 @@ struct domain
    65.4  	char *conspath;
    65.5  	int ring_ref;
    65.6  	evtchn_port_t local_port;
    65.7 +	evtchn_port_t remote_port;
    65.8  	int xce_handle;
    65.9  	struct xencons_interface *interface;
   65.10  };
   65.11 @@ -234,6 +235,9 @@ static int domain_create_ring(struct dom
   65.12  	if (err)
   65.13  		goto out;
   65.14  
   65.15 +	if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
   65.16 +		goto out;
   65.17 +
   65.18  	if (ring_ref != dom->ring_ref) {
   65.19  		if (dom->interface != NULL)
   65.20  			munmap(dom->interface, getpagesize());
   65.21 @@ -249,6 +253,7 @@ static int domain_create_ring(struct dom
   65.22  	}
   65.23  
   65.24  	dom->local_port = -1;
   65.25 +	dom->remote_port = -1;
   65.26  	if (dom->xce_handle != -1)
   65.27  		xc_evtchn_close(dom->xce_handle);
   65.28  
   65.29 @@ -270,6 +275,7 @@ static int domain_create_ring(struct dom
   65.30  		goto out;
   65.31  	}
   65.32  	dom->local_port = rc;
   65.33 +	dom->remote_port = remote_port;
   65.34  
   65.35  	if (dom->tty_fd == -1) {
   65.36  		dom->tty_fd = domain_create_tty(dom);
   65.37 @@ -279,6 +285,7 @@ static int domain_create_ring(struct dom
   65.38  			xc_evtchn_close(dom->xce_handle);
   65.39  			dom->xce_handle = -1;
   65.40  			dom->local_port = -1;
   65.41 +			dom->remote_port = -1;
   65.42  			goto out;
   65.43  		}
   65.44  	}
   65.45 @@ -336,6 +343,7 @@ static struct domain *create_domain(int 
   65.46  
   65.47  	dom->ring_ref = -1;
   65.48  	dom->local_port = -1;
   65.49 +	dom->remote_port = -1;
   65.50  	dom->interface = NULL;
   65.51  	dom->xce_handle = -1;
   65.52  
    66.1 --- a/tools/firmware/hvmloader/acpi/build.c	Sun Feb 18 16:13:13 2007 -0700
    66.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Tue Feb 20 12:58:22 2007 -0700
    66.3 @@ -110,7 +110,9 @@ int construct_madt(struct acpi_20_madt *
    66.4          memset(lapic, 0, sizeof(*lapic));
    66.5          lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;
    66.6          lapic->length  = sizeof(*lapic);
    66.7 -        lapic->acpi_processor_id = lapic->apic_id = LAPIC_ID(i);
    66.8 +        /* Processor ID must match processor-object IDs in the DSDT. */
    66.9 +        lapic->acpi_processor_id = i;
   66.10 +        lapic->apic_id = LAPIC_ID(i);
   66.11          lapic->flags   = ACPI_LOCAL_APIC_ENABLED;
   66.12          offset += sizeof(*lapic);
   66.13          lapic++;
   66.14 @@ -144,6 +146,79 @@ int construct_hpet(struct acpi_20_hpet *
   66.15      return offset;
   66.16  }
   66.17  
   66.18 +int construct_processor_objects(uint8_t *buf)
   66.19 +{
   66.20 +    static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 };
   66.21 +    static const char hex[] = "0123456789ABCDEF";
   66.22 +    unsigned int i, length, nr_cpus = get_vcpu_nr();
   66.23 +    struct acpi_header *hdr;
   66.24 +    uint8_t *p = buf;
   66.25 +
   66.26 +    /*
   66.27 +     * 1. Table Header.
   66.28 +     */
   66.29 +
   66.30 +    hdr = (struct acpi_header *)p;
   66.31 +    hdr->signature = ASCII32('S','S','D','T');
   66.32 +    hdr->revision  = 2;
   66.33 +    strncpy(hdr->oem_id, ACPI_OEM_ID, 6);
   66.34 +    strncpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID, 8);
   66.35 +    hdr->oem_revision = ACPI_OEM_REVISION;
   66.36 +    hdr->creator_id = ACPI_CREATOR_ID;
   66.37 +    hdr->creator_revision = ACPI_CREATOR_REVISION;
   66.38 +    p += sizeof(*hdr);
   66.39 +
   66.40 +    /*
   66.41 +     * 2. Scope Definition.
   66.42 +     */
   66.43 +
   66.44 +    /* ScopeOp */
   66.45 +    *p++ = 0x10;
   66.46 +
   66.47 +    /* PkgLength (includes length bytes!). */
   66.48 +    length = 1 + 5 + (nr_cpus * sizeof(pdat));
   66.49 +    if ( length <= 0x3f )
   66.50 +    {
   66.51 +        *p++ = length;
   66.52 +    }
   66.53 +    else if ( ++length <= 0xfff )
   66.54 +    {
   66.55 +        *p++ = 0x40 | (length & 0xf);
   66.56 +        *p++ = length >> 4;
   66.57 +    }
   66.58 +    else
   66.59 +    {
   66.60 +        length++;
   66.61 +        *p++ = 0x80 | (length & 0xf);
   66.62 +        *p++ = (length >>  4) & 0xff;
   66.63 +        *p++ = (length >> 12) & 0xff;
   66.64 +    }
   66.65 +
   66.66 +    /* NameString */
   66.67 +    strncpy(p, "\\_PR_", 5);
   66.68 +    p += 5;
   66.69 +
   66.70 +    /*
   66.71 +     * 3. Processor Objects.
   66.72 +     */
   66.73 +
   66.74 +    for ( i = 0; i < nr_cpus; i++ )
   66.75 +    {
   66.76 +        memcpy(p, pdat, sizeof(pdat));
   66.77 +        /* ProcessorName */
   66.78 +        p[5] = hex[(i>>4)&15];
   66.79 +        p[6] = hex[(i>>0)&15];
   66.80 +        /* ProcessorID */
   66.81 +        p[7] = i;
   66.82 +        p += sizeof(pdat);
   66.83 +    }
   66.84 +
   66.85 +    hdr->length = p - buf;
   66.86 +    set_checksum(hdr, offsetof(struct acpi_header, checksum), hdr->length);
   66.87 +
   66.88 +    return hdr->length;
   66.89 +}
   66.90 +
   66.91  int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
   66.92  {
   66.93      int offset = 0, nr_tables = 0;
   66.94 @@ -166,6 +241,10 @@ int construct_secondary_tables(uint8_t *
   66.95      offset += construct_hpet(hpet);
   66.96      table_ptrs[nr_tables++] = (unsigned long)hpet;
   66.97  
   66.98 +    /* Processor Object SSDT. */
   66.99 +    table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
  66.100 +    offset += construct_processor_objects(&buf[offset]);
  66.101 +
  66.102      /* TPM TCPA and SSDT. */
  66.103      tis_hdr = (uint16_t *)0xFED40F00;
  66.104      if ( (tis_hdr[0] == tis_signature[0]) &&
    67.1 --- a/tools/firmware/hvmloader/acpi/dsdt.asl	Sun Feb 18 16:13:13 2007 -0700
    67.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl	Tue Feb 20 12:58:22 2007 -0700
    67.3 @@ -27,14 +27,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
    67.4      Name (\APCL, 0x00010000)
    67.5      Name (\PUID, 0x00)
    67.6  
    67.7 -    Scope (\_PR)
    67.8 -    {
    67.9 -        Processor (CPU0, 0x00, 0x00000000, 0x00) {}
   67.10 -        Processor (CPU1, 0x01, 0x00000000, 0x00) {}
   67.11 -        Processor (CPU2, 0x02, 0x00000000, 0x00) {}
   67.12 -        Processor (CPU3, 0x03, 0x00000000, 0x00) {}
   67.13 -    }
   67.14 -
   67.15      /* Poweroff support - ties in with qemu emulation */
   67.16      Name (\_S5, Package (0x04)
   67.17      {
    68.1 --- a/tools/firmware/hvmloader/acpi/dsdt.c	Sun Feb 18 16:13:13 2007 -0700
    68.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.c	Tue Feb 20 12:58:22 2007 -0700
    68.3 @@ -1,19 +1,19 @@
    68.4  /*
    68.5   * 
    68.6   * Intel ACPI Component Architecture
    68.7 - * ASL Optimizing Compiler version 20060707 [Dec 30 2006]
    68.8 + * ASL Optimizing Compiler version 20060707 [Feb 16 2007]
    68.9   * Copyright (C) 2000 - 2006 Intel Corporation
   68.10   * Supports ACPI Specification Revision 3.0a
   68.11   * 
   68.12 - * Compilation of "dsdt.asl" - Sat Dec 30 15:31:23 2006
   68.13 + * Compilation of "dsdt.asl" - Fri Feb 16 15:14:37 2007
   68.14   * 
   68.15   * C source code output
   68.16   *
   68.17   */
   68.18  unsigned char AmlCode[] =
   68.19  {
   68.20 -    0x44,0x53,0x44,0x54,0xD9,0x0D,0x00,0x00,  /* 00000000    "DSDT...." */
   68.21 -    0x02,0xFB,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
   68.22 +    0x44,0x53,0x44,0x54,0x9F,0x0D,0x00,0x00,  /* 00000000    "DSDT...." */
   68.23 +    0x02,0xEE,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
   68.24      0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00,  /* 00000010    "HVM....." */
   68.25      0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
   68.26      0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
   68.27 @@ -23,438 +23,430 @@ unsigned char AmlCode[] =
   68.28      0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0,  /* 00000040    "APCB...." */
   68.29      0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00,  /* 00000048    "..APCL.." */
   68.30      0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44,  /* 00000050    "....PUID" */
   68.31 -    0x00,0x10,0x39,0x5F,0x50,0x52,0x5F,0x5B,  /* 00000058    "..9_PR_[" */
   68.32 -    0x83,0x0B,0x43,0x50,0x55,0x30,0x00,0x00,  /* 00000060    "..CPU0.." */
   68.33 -    0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x43,  /* 00000068    "....[..C" */
   68.34 -    0x50,0x55,0x31,0x01,0x00,0x00,0x00,0x00,  /* 00000070    "PU1....." */
   68.35 -    0x00,0x5B,0x83,0x0B,0x43,0x50,0x55,0x32,  /* 00000078    ".[..CPU2" */
   68.36 -    0x02,0x00,0x00,0x00,0x00,0x00,0x5B,0x83,  /* 00000080    "......[." */
   68.37 -    0x0B,0x43,0x50,0x55,0x33,0x03,0x00,0x00,  /* 00000088    ".CPU3..." */
   68.38 -    0x00,0x00,0x00,0x08,0x5F,0x53,0x35,0x5F,  /* 00000090    "...._S5_" */
   68.39 -    0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00,  /* 00000098    "........" */
   68.40 -    0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14,  /* 000000A0    "..PICD.." */
   68.41 -    0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68,  /* 000000A8    "._PIC.ph" */
   68.42 -    0x50,0x49,0x43,0x44,0x10,0x44,0xD2,0x5F,  /* 000000B0    "PICD.D._" */
   68.43 -    0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D,  /* 000000B8    "SB_[.I.M" */
   68.44 -    0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000000C0    "EM0._HID" */
   68.45 -    0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43,  /* 000000C8    ".A...._C" */
   68.46 -    0x52,0x53,0x11,0x33,0x0A,0x30,0x8A,0x2B,  /* 000000D0    "RS.3.0.+" */
   68.47 -    0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00,  /* 000000D8    "........" */
   68.48 -    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E0    "........" */
   68.49 -    0x00,0x00,0x00,0x00,0xFF,0xFF,0x09,0x00,  /* 000000E8    "........" */
   68.50 -    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
   68.51 -    0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,  /* 000000F8    "........" */
   68.52 -    0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82,  /* 00000100    "....y.[." */
   68.53 -    0x41,0xCD,0x50,0x43,0x49,0x30,0x08,0x5F,  /* 00000108    "A.PCI0._" */
   68.54 -    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,  /* 00000110    "HID.A..." */
   68.55 -    0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,  /* 00000118    "._UID.._" */
   68.56 -    0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42,  /* 00000120    "ADR.._BB" */
   68.57 -    0x4E,0x00,0x14,0x44,0x08,0x5F,0x43,0x52,  /* 00000128    "N..D._CR" */
   68.58 -    0x53,0x00,0x08,0x50,0x52,0x54,0x30,0x11,  /* 00000130    "S..PRT0." */
   68.59 -    0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00,0x02,  /* 00000138    "B..n...." */
   68.60 -    0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,  /* 00000140    "........" */
   68.61 -    0x00,0x00,0x00,0x01,0x47,0x01,0xF8,0x0C,  /* 00000148    "....G..." */
   68.62 -    0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00,0x01,  /* 00000150    "........" */
   68.63 -    0x0C,0x03,0x00,0x00,0x00,0x00,0xF7,0x0C,  /* 00000158    "........" */
   68.64 -    0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00,0x01,  /* 00000160    "........" */
   68.65 -    0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF,0xFF,  /* 00000168    "........" */
   68.66 -    0x00,0x00,0x00,0xF3,0x87,0x17,0x00,0x00,  /* 00000170    "........" */
   68.67 -    0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000178    "........" */
   68.68 -    0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00,0x00,  /* 00000180    "........" */
   68.69 -    0x00,0x00,0x00,0x00,0x02,0x00,0x87,0x17,  /* 00000188    "........" */
   68.70 -    0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00,  /* 00000190    "........" */
   68.71 -    0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4,  /* 00000198    "........" */
   68.72 -    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,  /* 000001A0    "........" */
   68.73 -    0x79,0x00,0xA4,0x50,0x52,0x54,0x30,0x08,  /* 000001A8    "y..PRT0." */
   68.74 -    0x42,0x55,0x46,0x41,0x11,0x09,0x0A,0x06,  /* 000001B0    "BUFA...." */
   68.75 -    0x23,0x60,0x0C,0x18,0x79,0x00,0x08,0x42,  /* 000001B8    "#`..y..B" */
   68.76 -    0x55,0x46,0x42,0x11,0x09,0x0A,0x06,0x23,  /* 000001C0    "UFB....#" */
   68.77 -    0x00,0x00,0x18,0x79,0x00,0x8B,0x42,0x55,  /* 000001C8    "...y..BU" */
   68.78 -    0x46,0x42,0x01,0x49,0x52,0x51,0x56,0x5B,  /* 000001D0    "FB.IRQV[" */
   68.79 -    0x82,0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,  /* 000001D8    ".H.LNKA." */
   68.80 -    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 000001E0    "_HID.A.." */
   68.81 -    0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,0x14,  /* 000001E8    ".._UID.." */
   68.82 -    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 000001F0    "._STA.{P" */
   68.83 -    0x49,0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,  /* 000001F8    "IRA..`.." */
   68.84 -    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 00000200    ".`......" */
   68.85 -    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 00000208    "......_P" */
   68.86 -    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 00000210    "RS..BUFA" */
   68.87 -    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000218    ".._DIS.}" */
   68.88 -    0x50,0x49,0x52,0x41,0x0A,0x80,0x50,0x49,  /* 00000220    "PIRA..PI" */
   68.89 -    0x52,0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000228    "RA.._CRS" */
   68.90 -    0x00,0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,  /* 00000230    ".{PIRA.." */
   68.91 -    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000238    "`y.`IRQV" */
   68.92 -    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000240    ".BUFB.._" */
   68.93 -    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000248    "SRS..h.I" */
   68.94 -    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000250    "RQ1.IRQ1" */
   68.95 -    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000258    "`v`p`PIR" */
   68.96 -    0x41,0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,  /* 00000260    "A[.I.LNK" */
   68.97 -    0x42,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000268    "B._HID.A" */
   68.98 -    0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,  /* 00000270    "...._UID" */
   68.99 -    0x0A,0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,  /* 00000278    "...._STA" */
  68.100 -    0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 00000280    ".{PIRB.." */
  68.101 -    0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,  /* 00000288    "`...`..." */
  68.102 -    0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,  /* 00000290    "........" */
  68.103 -    0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,  /* 00000298    "._PRS..B" */
  68.104 -    0x55,0x46,0x41,0x14,0x11,0x5F,0x44,0x49,  /* 000002A0    "UFA.._DI" */
  68.105 -    0x53,0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,  /* 000002A8    "S.}PIRB." */
  68.106 -    0x80,0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,  /* 000002B0    ".PIRB.._" */
  68.107 -    0x43,0x52,0x53,0x00,0x7B,0x50,0x49,0x52,  /* 000002B8    "CRS.{PIR" */
  68.108 -    0x42,0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,  /* 000002C0    "B..`y.`I" */
  68.109 -    0x52,0x51,0x56,0xA4,0x42,0x55,0x46,0x42,  /* 000002C8    "RQV.BUFB" */
  68.110 -    0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,  /* 000002D0    ".._SRS.." */
  68.111 -    0x68,0x01,0x49,0x52,0x51,0x31,0x82,0x49,  /* 000002D8    "h.IRQ1.I" */
  68.112 -    0x52,0x51,0x31,0x60,0x76,0x60,0x70,0x60,  /* 000002E0    "RQ1`v`p`" */
  68.113 -    0x50,0x49,0x52,0x42,0x5B,0x82,0x49,0x08,  /* 000002E8    "PIRB[.I." */
  68.114 -    0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,  /* 000002F0    "LNKC._HI" */
  68.115 -    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 000002F8    "D.A...._" */
  68.116 -    0x55,0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,  /* 00000300    "UID...._" */
  68.117 -    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 00000308    "STA.{PIR" */
  68.118 -    0x43,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 00000310    "C..`...`" */
  68.119 -    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00000318    "........" */
  68.120 -    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 00000320    "...._PRS" */
  68.121 -    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 00000328    "..BUFA.." */
  68.122 -    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00000330    "_DIS.}PI" */
  68.123 -    0x52,0x43,0x0A,0x80,0x50,0x49,0x52,0x43,  /* 00000338    "RC..PIRC" */
  68.124 -    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 00000340    ".._CRS.{" */
  68.125 -    0x50,0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,  /* 00000348    "PIRC..`y" */
  68.126 -    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 00000350    ".`IRQV.B" */
  68.127 -    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 00000358    "UFB.._SR" */
  68.128 -    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000360    "S..h.IRQ" */
  68.129 -    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 00000368    "1.IRQ1`v" */
  68.130 -    0x60,0x70,0x60,0x50,0x49,0x52,0x43,0x5B,  /* 00000370    "`p`PIRC[" */
  68.131 -    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,  /* 00000378    ".I.LNKD." */
  68.132 -    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000380    "_HID.A.." */
  68.133 -    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,  /* 00000388    ".._UID.." */
  68.134 -    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 00000390    ".._STA.{" */
  68.135 -    0x50,0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,  /* 00000398    "PIRD..`." */
  68.136 -    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 000003A0    "..`....." */
  68.137 -    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 000003A8    "......._" */
  68.138 -    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 000003B0    "PRS..BUF" */
  68.139 -    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 000003B8    "A.._DIS." */
  68.140 -    0x7D,0x50,0x49,0x52,0x44,0x0A,0x80,0x50,  /* 000003C0    "}PIRD..P" */
  68.141 -    0x49,0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,  /* 000003C8    "IRD.._CR" */
  68.142 -    0x53,0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,  /* 000003D0    "S.{PIRD." */
  68.143 -    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 000003D8    ".`y.`IRQ" */
  68.144 -    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 000003E0    "V.BUFB.." */
  68.145 -    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 000003E8    "_SRS..h." */
  68.146 -    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 000003F0    "IRQ1.IRQ" */
  68.147 -    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 000003F8    "1`v`p`PI" */
  68.148 -    0x52,0x44,0x5B,0x82,0x3A,0x48,0x50,0x45,  /* 00000400    "RD[.:HPE" */
  68.149 -    0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000408    "T._HID.A" */
  68.150 -    0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44,  /* 00000410    "...._UID" */
  68.151 -    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x1F,  /* 00000418    ".._CRS.." */
  68.152 -    0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,0x01,  /* 00000420    "........" */
  68.153 -    0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFE,  /* 00000428    "........" */
  68.154 -    0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,0x00,  /* 00000430    "........" */
  68.155 -    0x00,0x04,0x00,0x00,0x79,0x00,0x14,0x16,  /* 00000438    "....y..." */
  68.156 -    0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50,  /* 00000440    "_PRT...P" */
  68.157 -    0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41,  /* 00000448    "ICD.PRTA" */
  68.158 -    0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52,  /* 00000450    ".PRTP.PR" */
  68.159 -    0x54,0x50,0x12,0x49,0x36,0x3C,0x12,0x0D,  /* 00000458    "TP.I6<.." */
  68.160 -    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 00000460    ".......L" */
  68.161 -    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000468    "NKB....." */
  68.162 -    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000470    ".....LNK" */
  68.163 -    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000478    "C......." */
  68.164 -    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000480    "....LNKD" */
  68.165 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 00000488    "........" */
  68.166 -    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000490    "...LNKA." */
  68.167 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000498    "........" */
  68.168 -    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000004A0    ".LNKC..." */
  68.169 -    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C,  /* 000004A8    ".......L" */
  68.170 -    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000004B0    "NKD....." */
  68.171 -    0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E,  /* 000004B8    "......LN" */
  68.172 -    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004C0    "KA......" */
  68.173 -    0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000004C8    ".....LNK" */
  68.174 -    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000004D0    "B......." */
  68.175 -    0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000004D8    "...LNKD." */
  68.176 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 000004E0    "........" */
  68.177 -    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000004E8    ".LNKA..." */
  68.178 -    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,  /* 000004F0    "........" */
  68.179 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000004F8    "LNKB...." */
  68.180 -    0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C,  /* 00000500    ".......L" */
  68.181 -    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000508    "NKC....." */
  68.182 -    0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000510    ".....LNK" */
  68.183 -    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000518    "A......." */
  68.184 -    0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000520    "...LNKB." */
  68.185 -    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000528    "........" */
  68.186 -    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000530    "..LNKC.." */
  68.187 -    0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,  /* 00000538    "........" */
  68.188 -    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000540    ".LNKD..." */
  68.189 -    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x4C,  /* 00000548    ".......L" */
  68.190 -    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000550    "NKB....." */
  68.191 -    0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000558    ".....LNK" */
  68.192 -    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000560    "C......." */
  68.193 -    0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000568    "....LNKD" */
  68.194 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,  /* 00000570    "........" */
  68.195 -    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000578    "...LNKA." */
  68.196 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000580    "........" */
  68.197 -    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000588    ".LNKC..." */
  68.198 -    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x4C,  /* 00000590    ".......L" */
  68.199 -    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000598    "NKD....." */
  68.200 -    0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,0x4E,  /* 000005A0    "......LN" */
  68.201 -    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005A8    "KA......" */
  68.202 -    0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000005B0    ".....LNK" */
  68.203 -    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000005B8    "B......." */
  68.204 -    0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000005C0    "...LNKD." */
  68.205 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 000005C8    "........" */
  68.206 -    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000005D0    ".LNKA..." */
  68.207 -    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,  /* 000005D8    "........" */
  68.208 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000005E0    "LNKB...." */
  68.209 -    0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,0x4C,  /* 000005E8    ".......L" */
  68.210 -    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 000005F0    "NKC....." */
  68.211 -    0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,0x4B,  /* 000005F8    ".....LNK" */
  68.212 -    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000600    "A......." */
  68.213 -    0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000608    "...LNKB." */
  68.214 -    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000610    "........" */
  68.215 -    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000618    "..LNKC.." */
  68.216 -    0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,  /* 00000620    "........" */
  68.217 -    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000628    ".LNKD..." */
  68.218 -    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x4C,  /* 00000630    ".......L" */
  68.219 -    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000638    "NKB....." */
  68.220 -    0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000640    ".....LNK" */
  68.221 -    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000648    "C......." */
  68.222 -    0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000650    "....LNKD" */
  68.223 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000658    "........" */
  68.224 -    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000660    "...LNKA." */
  68.225 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000668    "........" */
  68.226 -    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000670    ".LNKC..." */
  68.227 -    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C,  /* 00000678    ".......L" */
  68.228 -    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000680    "NKD....." */
  68.229 -    0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000688    "......LN" */
  68.230 -    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000690    "KA......" */
  68.231 -    0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000698    ".....LNK" */
  68.232 -    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006A0    "B......." */
  68.233 -    0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000006A8    "...LNKD." */
  68.234 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 000006B0    "........" */
  68.235 -    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000006B8    ".LNKA..." */
  68.236 -    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,  /* 000006C0    "........" */
  68.237 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000006C8    "LNKB...." */
  68.238 -    0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x4C,  /* 000006D0    ".......L" */
  68.239 -    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 000006D8    "NKC....." */
  68.240 -    0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,0x4B,  /* 000006E0    ".....LNK" */
  68.241 -    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006E8    "A......." */
  68.242 -    0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 000006F0    "...LNKB." */
  68.243 -    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 000006F8    "........" */
  68.244 -    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000700    "..LNKC.." */
  68.245 -    0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,  /* 00000708    "........" */
  68.246 -    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000710    ".LNKD..." */
  68.247 -    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x4C,  /* 00000718    ".......L" */
  68.248 -    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000720    "NKB....." */
  68.249 -    0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000728    ".....LNK" */
  68.250 -    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000730    "C......." */
  68.251 -    0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000738    "....LNKD" */
  68.252 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000740    "........" */
  68.253 -    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000748    "...LNKA." */
  68.254 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000750    "........" */
  68.255 -    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000758    ".LNKC..." */
  68.256 -    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x4C,  /* 00000760    ".......L" */
  68.257 -    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000768    "NKD....." */
  68.258 -    0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000770    "......LN" */
  68.259 -    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000778    "KA......" */
  68.260 -    0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000780    ".....LNK" */
  68.261 -    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000788    "B......." */
  68.262 -    0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000790    "...LNKD." */
  68.263 -    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 00000798    "........" */
  68.264 -    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000007A0    ".LNKA..." */
  68.265 -    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,  /* 000007A8    "........" */
  68.266 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000007B0    "LNKB...." */
  68.267 -    0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x4C,  /* 000007B8    ".......L" */
  68.268 -    0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54,  /* 000007C0    "NKC..PRT" */
  68.269 -    0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,0x04,  /* 000007C8    "A.A/<..." */
  68.270 -    0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A,  /* 000007D0    "........" */
  68.271 -    0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,  /* 000007D8    "........" */
  68.272 -    0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,0x04,  /* 000007E0    "........" */
  68.273 -    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x00,  /* 000007E8    "........" */
  68.274 -    0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000007F0    "........" */
  68.275 -    0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,0x12,  /* 000007F8    "........" */
  68.276 -    0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,  /* 00000800    "........" */
  68.277 -    0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000808    "........" */
  68.278 -    0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,0x12,  /* 00000810    "........" */
  68.279 -    0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000818    "........" */
  68.280 -    0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,  /* 00000820    "........" */
  68.281 -    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,0x0A,  /* 00000828    "........" */
  68.282 -    0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000830    "........" */
  68.283 -    0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,0x04,  /* 00000838    "........" */
  68.284 -    0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,0x0A,  /* 00000840    "........" */
  68.285 -    0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000848    "........" */
  68.286 -    0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,0x0C,  /* 00000850    "........" */
  68.287 -    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000858    "........" */
  68.288 -    0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000860    "........" */
  68.289 -    0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,0x12,  /* 00000868    "...... ." */
  68.290 -    0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,  /* 00000870    "........" */
  68.291 -    0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000878    "..!....." */
  68.292 -    0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,0x22,  /* 00000880    "......."" */
  68.293 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000888    "........" */
  68.294 -    0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,0x04,  /* 00000890    "....#..." */
  68.295 -    0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,0x0A,  /* 00000898    "........" */
  68.296 -    0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05,  /* 000008A0    "$......." */
  68.297 -    0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,0x04,  /* 000008A8    "....%..." */
  68.298 -    0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x00,  /* 000008B0    "........" */
  68.299 -    0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B8    ".&......" */
  68.300 -    0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,0x12,  /* 000008C0    "......'." */
  68.301 -    0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,  /* 000008C8    "........" */
  68.302 -    0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF,  /* 000008D0    "..(....." */
  68.303 -    0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,0x12,  /* 000008D8    "......)." */
  68.304 -    0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,  /* 000008E0    "........" */
  68.305 -    0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,  /* 000008E8    "...*...." */
  68.306 -    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,0x0A,  /* 000008F0    "........" */
  68.307 -    0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07,  /* 000008F8    "+......." */
  68.308 -    0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,0x04,  /* 00000900    "....,..." */
  68.309 -    0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,0x0A,  /* 00000908    "........" */
  68.310 -    0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000910    "-......." */
  68.311 -    0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,0x0C,  /* 00000918    "........" */
  68.312 -    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000920    "........" */
  68.313 -    0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000928    "../....." */
  68.314 -    0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,0x12,  /* 00000930    "........" */
  68.315 -    0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,  /* 00000938    "........" */
  68.316 -    0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000940    "........" */
  68.317 -    0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,0x13,  /* 00000948    "........" */
  68.318 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000950    "........" */
  68.319 -    0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,0x04,  /* 00000958    "........" */
  68.320 -    0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,0x0A,  /* 00000960    "........" */
  68.321 -    0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000968    "........" */
  68.322 -    0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,0x04,  /* 00000970    "........" */
  68.323 -    0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x00,  /* 00000978    "........" */
  68.324 -    0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000980    "........" */
  68.325 -    0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,0x12,  /* 00000988    "........" */
  68.326 -    0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,  /* 00000990    "........" */
  68.327 -    0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000998    "........" */
  68.328 -    0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,0x12,  /* 000009A0    "........" */
  68.329 -    0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,  /* 000009A8    "........" */
  68.330 -    0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,0x0C,  /* 000009B0    "........" */
  68.331 -    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,0x0A,  /* 000009B8    "........" */
  68.332 -    0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B,  /* 000009C0    "........" */
  68.333 -    0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,0x04,  /* 000009C8    "........" */
  68.334 -    0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,0x0A,  /* 000009D0    "........" */
  68.335 -    0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B,  /* 000009D8    "........" */
  68.336 -    0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,0x0C,  /* 000009E0    "........" */
  68.337 -    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 000009E8    "........" */
  68.338 -    0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF,  /* 000009F0    ".. ....." */
  68.339 -    0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,0x12,  /* 000009F8    "......!." */
  68.340 -    0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,  /* 00000A00    "........" */
  68.341 -    0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A08    ".."....." */
  68.342 -    0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,0x23,  /* 00000A10    ".......#" */
  68.343 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000A18    "........" */
  68.344 -    0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,0x04,  /* 00000A20    "....$..." */
  68.345 -    0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x0A,  /* 00000A28    "........" */
  68.346 -    0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000A30    "%......." */
  68.347 -    0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,0x04,  /* 00000A38    "....&..." */
  68.348 -    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x00,  /* 00000A40    "........" */
  68.349 -    0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A48    ".'......" */
  68.350 -    0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,0x12,  /* 00000A50    "......(." */
  68.351 -    0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,  /* 00000A58    "........" */
  68.352 -    0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A60    "..)....." */
  68.353 -    0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,0x12,  /* 00000A68    "......*." */
  68.354 -    0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,  /* 00000A70    "........" */
  68.355 -    0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,0x0C,  /* 00000A78    "...+...." */
  68.356 -    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A80    "........" */
  68.357 -    0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000A88    ",......." */
  68.358 -    0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,0x04,  /* 00000A90    "....-..." */
  68.359 -    0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,0x0A,  /* 00000A98    "........" */
  68.360 -    0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000AA0    "........" */
  68.361 -    0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,0x0C,  /* 00000AA8    "...../.." */
  68.362 -    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000AB0    "........" */
  68.363 -    0x00,0x0A,0x10,0x5B,0x82,0x4C,0x31,0x49,  /* 00000AB8    "...[.L1I" */
  68.364 -    0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52,  /* 00000AC0    "SA_._ADR" */
  68.365 -    0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50,  /* 00000AC8    ".....[.P" */
  68.366 -    0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,0x04,  /* 00000AD0    "IRQ..`.." */
  68.367 -    0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,0x5C,  /* 00000AD8    "..\.[.)\" */
  68.368 -    0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00000AE0    "/._SB_PC" */
  68.369 -    0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x49,  /* 00000AE8    "I0ISA_PI" */
  68.370 -    0x52,0x51,0x01,0x50,0x49,0x52,0x41,0x08,  /* 00000AF0    "RQ.PIRA." */
  68.371 -    0x50,0x49,0x52,0x42,0x08,0x50,0x49,0x52,  /* 00000AF8    "PIRB.PIR" */
  68.372 -    0x43,0x08,0x50,0x49,0x52,0x44,0x08,0x5B,  /* 00000B00    "C.PIRD.[" */
  68.373 -    0x82,0x46,0x0B,0x53,0x59,0x53,0x52,0x08,  /* 00000B08    ".F.SYSR." */
  68.374 -    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000B10    "_HID.A.." */
  68.375 -    0x02,0x08,0x5F,0x55,0x49,0x44,0x01,0x08,  /* 00000B18    ".._UID.." */
  68.376 -    0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,0x0A,  /* 00000B20    "CRS_.N.." */
  68.377 -    0x8A,0x47,0x01,0x10,0x00,0x10,0x00,0x00,  /* 00000B28    ".G......" */
  68.378 -    0x10,0x47,0x01,0x22,0x00,0x22,0x00,0x00,  /* 00000B30    ".G.".".." */
  68.379 -    0x0C,0x47,0x01,0x30,0x00,0x30,0x00,0x00,  /* 00000B38    ".G.0.0.." */
  68.380 -    0x10,0x47,0x01,0x44,0x00,0x44,0x00,0x00,  /* 00000B40    ".G.D.D.." */
  68.381 -    0x1C,0x47,0x01,0x62,0x00,0x62,0x00,0x00,  /* 00000B48    ".G.b.b.." */
  68.382 -    0x02,0x47,0x01,0x65,0x00,0x65,0x00,0x00,  /* 00000B50    ".G.e.e.." */
  68.383 -    0x0B,0x47,0x01,0x72,0x00,0x72,0x00,0x00,  /* 00000B58    ".G.r.r.." */
  68.384 -    0x0E,0x47,0x01,0x80,0x00,0x80,0x00,0x00,  /* 00000B60    ".G......" */
  68.385 -    0x01,0x47,0x01,0x84,0x00,0x84,0x00,0x00,  /* 00000B68    ".G......" */
  68.386 -    0x03,0x47,0x01,0x88,0x00,0x88,0x00,0x00,  /* 00000B70    ".G......" */
  68.387 -    0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,0x00,  /* 00000B78    ".G......" */
  68.388 -    0x03,0x47,0x01,0x90,0x00,0x90,0x00,0x00,  /* 00000B80    ".G......" */
  68.389 -    0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,0x00,  /* 00000B88    ".G......" */
  68.390 -    0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,0x00,  /* 00000B90    ".G......" */
  68.391 -    0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,0x00,  /* 00000B98    ".G......" */
  68.392 -    0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,0x00,  /* 00000BA0    ".G......" */
  68.393 -    0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,0x00,  /* 00000BA8    ".G......" */
  68.394 -    0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,0x52,  /* 00000BB0    ".y..._CR" */
  68.395 -    0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,0x5B,  /* 00000BB8    "S..CRS_[" */
  68.396 -    0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,0x5F,  /* 00000BC0    ".+PIC_._" */
  68.397 -    0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,0x5F,  /* 00000BC8    "HID.A.._" */
  68.398 -    0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47,  /* 00000BD0    "CRS....G" */
  68.399 -    0x01,0x20,0x00,0x20,0x00,0x01,0x02,0x47,  /* 00000BD8    ". . ...G" */
  68.400 -    0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,0x22,  /* 00000BE0    "......."" */
  68.401 -    0x04,0x00,0x79,0x00,0x5B,0x82,0x47,0x05,  /* 00000BE8    "..y.[.G." */
  68.402 -    0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,0x49,  /* 00000BF0    "DMA0._HI" */
  68.403 -    0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,0x5F,  /* 00000BF8    "D.A...._" */
  68.404 -    0x43,0x52,0x53,0x11,0x41,0x04,0x0A,0x3D,  /* 00000C00    "CRS.A..=" */
  68.405 -    0x2A,0x10,0x04,0x47,0x01,0x00,0x00,0x00,  /* 00000C08    "*..G...." */
  68.406 -    0x00,0x00,0x10,0x47,0x01,0x81,0x00,0x81,  /* 00000C10    "...G...." */
  68.407 -    0x00,0x00,0x03,0x47,0x01,0x87,0x00,0x87,  /* 00000C18    "...G...." */
  68.408 -    0x00,0x00,0x01,0x47,0x01,0x89,0x00,0x89,  /* 00000C20    "...G...." */
  68.409 -    0x00,0x00,0x03,0x47,0x01,0x8F,0x00,0x8F,  /* 00000C28    "...G...." */
  68.410 -    0x00,0x00,0x01,0x47,0x01,0xC0,0x00,0xC0,  /* 00000C30    "...G...." */
  68.411 -    0x00,0x00,0x20,0x47,0x01,0x80,0x04,0x80,  /* 00000C38    ".. G...." */
  68.412 -    0x04,0x00,0x10,0x79,0x00,0x5B,0x82,0x25,  /* 00000C40    "...y.[.%" */
  68.413 -    0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49,  /* 00000C48    "TMR_._HI" */
  68.414 -    0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x5F,  /* 00000C50    "D.A...._" */
  68.415 -    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000C58    "CRS....G" */
  68.416 -    0x01,0x40,0x00,0x40,0x00,0x00,0x04,0x22,  /* 00000C60    ".@.@..."" */
  68.417 -    0x01,0x00,0x79,0x00,0x5B,0x82,0x25,0x52,  /* 00000C68    "..y.[.%R" */
  68.418 -    0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,  /* 00000C70    "TC_._HID" */
  68.419 -    0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,0x43,  /* 00000C78    ".A...._C" */
  68.420 -    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000C80    "RS....G." */
  68.421 -    0x70,0x00,0x70,0x00,0x00,0x02,0x22,0x00,  /* 00000C88    "p.p..."." */
  68.422 -    0x01,0x79,0x00,0x5B,0x82,0x22,0x53,0x50,  /* 00000C90    ".y.[."SP" */
  68.423 -    0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000C98    "KR._HID." */
  68.424 -    0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,0x52,  /* 00000CA0    "A...._CR" */
  68.425 -    0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,0x61,  /* 00000CA8    "S....G.a" */
  68.426 -    0x00,0x61,0x00,0x00,0x01,0x79,0x00,0x5B,  /* 00000CB0    ".a...y.[" */
  68.427 -    0x82,0x31,0x50,0x53,0x32,0x4D,0x08,0x5F,  /* 00000CB8    ".1PS2M._" */
  68.428 -    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,  /* 00000CC0    "HID.A..." */
  68.429 -    0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,  /* 00000CC8    "._CID.A." */
  68.430 -    0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,0x41,  /* 00000CD0    "...._STA" */
  68.431 -    0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000CD8    "....._CR" */
  68.432 -    0x53,0x11,0x08,0x0A,0x05,0x22,0x00,0x10,  /* 00000CE0    "S....".." */
  68.433 -    0x79,0x00,0x5B,0x82,0x42,0x04,0x50,0x53,  /* 00000CE8    "y.[.B.PS" */
  68.434 -    0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000CF0    "2K._HID." */
  68.435 -    0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,0x49,  /* 00000CF8    "A...._CI" */
  68.436 -    0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,0x09,  /* 00000D00    "D.A....." */
  68.437 -    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 00000D08    "_STA...." */
  68.438 -    0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,  /* 00000D10    "._CRS..." */
  68.439 -    0x15,0x47,0x01,0x60,0x00,0x60,0x00,0x00,  /* 00000D18    ".G.`.`.." */
  68.440 -    0x01,0x47,0x01,0x64,0x00,0x64,0x00,0x00,  /* 00000D20    ".G.d.d.." */
  68.441 -    0x01,0x22,0x02,0x00,0x79,0x00,0x5B,0x82,  /* 00000D28    "."..y.[." */
  68.442 -    0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,0x48,  /* 00000D30    ":FDC0._H" */
  68.443 -    0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,0x14,  /* 00000D38    "ID.A...." */
  68.444 -    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D40    "._STA..." */
  68.445 -    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1B,  /* 00000D48    ".._CRS.." */
  68.446 -    0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,0x03,  /* 00000D50    "..G....." */
  68.447 -    0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,0x03,  /* 00000D58    "..G....." */
  68.448 -    0x01,0x01,0x22,0x40,0x00,0x2A,0x04,0x00,  /* 00000D60    ".."@.*.." */
  68.449 -    0x79,0x00,0x5B,0x82,0x35,0x55,0x41,0x52,  /* 00000D68    "y.[.5UAR" */
  68.450 -    0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000D70    "1._HID.A" */
  68.451 -    0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,0x44,  /* 00000D78    "...._UID" */
  68.452 -    0x01,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000D80    "..._STA." */
  68.453 -    0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,  /* 00000D88    "...._CRS" */
  68.454 -    0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8,0x03,  /* 00000D90    "....G..." */
  68.455 -    0xF8,0x03,0x01,0x08,0x22,0x10,0x00,0x79,  /* 00000D98    "...."..y" */
  68.456 -    0x00,0x5B,0x82,0x36,0x4C,0x54,0x50,0x31,  /* 00000DA0    ".[.6LTP1" */
  68.457 -    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000DA8    "._HID.A." */
  68.458 -    0x04,0x00,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 00000DB0    "..._UID." */
  68.459 -    0x02,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000DB8    "..._STA." */
  68.460 -    0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,  /* 00000DC0    "...._CRS" */
  68.461 -    0x11,0x10,0x0A,0x0D,0x47,0x01,0x78,0x03,  /* 00000DC8    "....G.x." */
  68.462 -    0x78,0x03,0x08,0x08,0x22,0x80,0x00,0x79,  /* 00000DD0    "x..."..y" */
  68.463 -    0x00,
  68.464 +    0x00,0x08,0x5F,0x53,0x35,0x5F,0x12,0x08,  /* 00000058    ".._S5_.." */
  68.465 +    0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08,  /* 00000060    "........" */
  68.466 +    0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F,  /* 00000068    "PICD..._" */
  68.467 +    0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49,  /* 00000070    "PIC.phPI" */
  68.468 +    0x43,0x44,0x10,0x44,0xD2,0x5F,0x53,0x42,  /* 00000078    "CD.D._SB" */
  68.469 +    0x5F,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,  /* 00000080    "_[.I.MEM" */
  68.470 +    0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000088    "0._HID.A" */
  68.471 +    0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,  /* 00000090    "...._CRS" */
  68.472 +    0x11,0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00,  /* 00000098    ".3.0.+.." */
  68.473 +    0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000A0    "........" */
  68.474 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000A8    "........" */
  68.475 +    0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000000B0    "........" */
  68.476 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000B8    "........" */
  68.477 +    0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,  /* 000000C0    "........" */
  68.478 +    0x00,0x00,0x79,0x00,0x5B,0x82,0x41,0xCD,  /* 000000C8    "..y.[.A." */
  68.479 +    0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49,  /* 000000D0    "PCI0._HI" */
  68.480 +    0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,  /* 000000D8    "D.A...._" */
  68.481 +    0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44,  /* 000000E0    "UID.._AD" */
  68.482 +    0x52,0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,  /* 000000E8    "R.._BBN." */
  68.483 +    0x14,0x44,0x08,0x5F,0x43,0x52,0x53,0x00,  /* 000000F0    ".D._CRS." */
  68.484 +    0x08,0x50,0x52,0x54,0x30,0x11,0x42,0x07,  /* 000000F8    ".PRT0.B." */
  68.485 +    0x0A,0x6E,0x88,0x0D,0x00,0x02,0x0F,0x00,  /* 00000100    ".n......" */
  68.486 +    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,  /* 00000108    "........" */
  68.487 +    0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,  /* 00000110    "..G....." */
  68.488 +    0x01,0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,  /* 00000118    "........" */
  68.489 +    0x00,0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,  /* 00000120    "........" */
  68.490 +    0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,  /* 00000128    "........" */
  68.491 +    0x00,0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,  /* 00000130    "........" */
  68.492 +    0x00,0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,  /* 00000138    "........" */
  68.493 +    0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,  /* 00000140    "........" */
  68.494 +    0xFF,0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,  /* 00000148    "........" */
  68.495 +    0x00,0x00,0x02,0x00,0x87,0x17,0x00,0x00,  /* 00000150    "........" */
  68.496 +    0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000158    "........" */
  68.497 +    0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,  /* 00000160    "........" */
  68.498 +    0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00,  /* 00000168    "......y." */
  68.499 +    0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55,  /* 00000170    ".PRT0.BU" */
  68.500 +    0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x60,  /* 00000178    "FA....#`" */
  68.501 +    0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46,  /* 00000180    "..y..BUF" */
  68.502 +    0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00,  /* 00000188    "B....#.." */
  68.503 +    0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42,  /* 00000190    ".y..BUFB" */
  68.504 +    0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48,  /* 00000198    ".IRQV[.H" */
  68.505 +    0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48,  /* 000001A0    ".LNKA._H" */
  68.506 +    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 000001A8    "ID.A...." */
  68.507 +    0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F,  /* 000001B0    "_UID..._" */
  68.508 +    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 000001B8    "STA.{PIR" */
  68.509 +    0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 000001C0    "A..`...`" */
  68.510 +    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 000001C8    "........" */
  68.511 +    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 000001D0    "...._PRS" */
  68.512 +    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 000001D8    "..BUFA.." */
  68.513 +    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 000001E0    "_DIS.}PI" */
  68.514 +    0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41,  /* 000001E8    "RA..PIRA" */
  68.515 +    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 000001F0    ".._CRS.{" */
  68.516 +    0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79,  /* 000001F8    "PIRA..`y" */
  68.517 +    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 00000200    ".`IRQV.B" */
  68.518 +    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 00000208    "UFB.._SR" */
  68.519 +    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000210    "S..h.IRQ" */
  68.520 +    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 00000218    "1.IRQ1`v" */
  68.521 +    0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B,  /* 00000220    "`p`PIRA[" */
  68.522 +    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08,  /* 00000228    ".I.LNKB." */
  68.523 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000230    "_HID.A.." */
  68.524 +    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,  /* 00000238    ".._UID.." */
  68.525 +    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 00000240    ".._STA.{" */
  68.526 +    0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0,  /* 00000248    "PIRB..`." */
  68.527 +    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 00000250    "..`....." */
  68.528 +    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 00000258    "......._" */
  68.529 +    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 00000260    "PRS..BUF" */
  68.530 +    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 00000268    "A.._DIS." */
  68.531 +    0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50,  /* 00000270    "}PIRB..P" */
  68.532 +    0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52,  /* 00000278    "IRB.._CR" */
  68.533 +    0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 00000280    "S.{PIRB." */
  68.534 +    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 00000288    ".`y.`IRQ" */
  68.535 +    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 00000290    "V.BUFB.." */
  68.536 +    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 00000298    "_SRS..h." */
  68.537 +    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 000002A0    "IRQ1.IRQ" */
  68.538 +    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 000002A8    "1`v`p`PI" */
  68.539 +    0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E,  /* 000002B0    "RB[.I.LN" */
  68.540 +    0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 000002B8    "KC._HID." */
  68.541 +    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 000002C0    "A...._UI" */
  68.542 +    0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54,  /* 000002C8    "D...._ST" */
  68.543 +    0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A,  /* 000002D0    "A.{PIRC." */
  68.544 +    0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,  /* 000002D8    ".`...`.." */
  68.545 +    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 000002E0    "........" */
  68.546 +    0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,  /* 000002E8    ".._PRS.." */
  68.547 +    0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44,  /* 000002F0    "BUFA.._D" */
  68.548 +    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43,  /* 000002F8    "IS.}PIRC" */
  68.549 +    0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A,  /* 00000300    "..PIRC.." */
  68.550 +    0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49,  /* 00000308    "_CRS.{PI" */
  68.551 +    0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60,  /* 00000310    "RC..`y.`" */
  68.552 +    0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46,  /* 00000318    "IRQV.BUF" */
  68.553 +    0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 00000320    "B.._SRS." */
  68.554 +    0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82,  /* 00000328    ".h.IRQ1." */
  68.555 +    0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70,  /* 00000330    "IRQ1`v`p" */
  68.556 +    0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49,  /* 00000338    "`PIRC[.I" */
  68.557 +    0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,  /* 00000340    ".LNKD._H" */
  68.558 +    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000348    "ID.A...." */
  68.559 +    0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C,  /* 00000350    "_UID...." */
  68.560 +    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000358    "_STA.{PI" */
  68.561 +    0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000360    "RD..`..." */
  68.562 +    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000368    "`......." */
  68.563 +    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000370    "....._PR" */
  68.564 +    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000378    "S..BUFA." */
  68.565 +    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000380    "._DIS.}P" */
  68.566 +    0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52,  /* 00000388    "IRD..PIR" */
  68.567 +    0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000390    "D.._CRS." */
  68.568 +    0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60,  /* 00000398    "{PIRD..`" */
  68.569 +    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 000003A0    "y.`IRQV." */
  68.570 +    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 000003A8    "BUFB.._S" */
  68.571 +    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 000003B0    "RS..h.IR" */
  68.572 +    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000003B8    "Q1.IRQ1`" */
  68.573 +    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44,  /* 000003C0    "v`p`PIRD" */
  68.574 +    0x5B,0x82,0x3A,0x48,0x50,0x45,0x54,0x08,  /* 000003C8    "[.:HPET." */
  68.575 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01,  /* 000003D0    "_HID.A.." */
  68.576 +    0x03,0x08,0x5F,0x55,0x49,0x44,0x00,0x08,  /* 000003D8    ".._UID.." */
  68.577 +    0x5F,0x43,0x52,0x53,0x11,0x1F,0x0A,0x1C,  /* 000003E0    "_CRS...." */
  68.578 +    0x87,0x17,0x00,0x00,0x0D,0x01,0x00,0x00,  /* 000003E8    "........" */
  68.579 +    0x00,0x00,0x00,0x00,0xD0,0xFE,0xFF,0x03,  /* 000003F0    "........" */
  68.580 +    0xD0,0xFE,0x00,0x00,0x00,0x00,0x00,0x04,  /* 000003F8    "........" */
  68.581 +    0x00,0x00,0x79,0x00,0x14,0x16,0x5F,0x50,  /* 00000400    "..y..._P" */
  68.582 +    0x52,0x54,0x00,0xA0,0x0A,0x50,0x49,0x43,  /* 00000408    "RT...PIC" */
  68.583 +    0x44,0xA4,0x50,0x52,0x54,0x41,0xA4,0x50,  /* 00000410    "D.PRTA.P" */
  68.584 +    0x52,0x54,0x50,0x08,0x50,0x52,0x54,0x50,  /* 00000418    "RTP.PRTP" */
  68.585 +    0x12,0x49,0x36,0x3C,0x12,0x0D,0x04,0x0C,  /* 00000420    ".I6<...." */
  68.586 +    0xFF,0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000428    ".....LNK" */
  68.587 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000430    "B......." */
  68.588 +    0x01,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000438    "...LNKC." */
  68.589 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 00000440    "........" */
  68.590 +    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000448    "..LNKD.." */
  68.591 +    0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,  /* 00000450    "........" */
  68.592 +    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000458    ".LNKA..." */
  68.593 +    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C,  /* 00000460    ".......L" */
  68.594 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000468    "NKC....." */
  68.595 +    0xFF,0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000470    ".....LNK" */
  68.596 +    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000478    "D......." */
  68.597 +    0x02,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000480    "....LNKA" */
  68.598 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000488    "........" */
  68.599 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000490    "...LNKB." */
  68.600 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000498    "........" */
  68.601 +    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 000004A0    ".LNKD..." */
  68.602 +    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C,  /* 000004A8    ".......L" */
  68.603 +    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000004B0    "NKA....." */
  68.604 +    0xFF,0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E,  /* 000004B8    "......LN" */
  68.605 +    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004C0    "KB......" */
  68.606 +    0xFF,0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000004C8    ".....LNK" */
  68.607 +    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000004D0    "C......." */
  68.608 +    0x04,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000004D8    "...LNKA." */
  68.609 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000004E0    "........" */
  68.610 +    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 000004E8    ".LNKB..." */
  68.611 +    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02,  /* 000004F0    "........" */
  68.612 +    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000004F8    "LNKC...." */
  68.613 +    0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C,  /* 00000500    ".......L" */
  68.614 +    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 00000508    "NKD....." */
  68.615 +    0xFF,0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000510    ".....LNK" */
  68.616 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000518    "B......." */
  68.617 +    0x05,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000520    "...LNKC." */
  68.618 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 00000528    "........" */
  68.619 +    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000530    "..LNKD.." */
  68.620 +    0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,  /* 00000538    "........" */
  68.621 +    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000540    ".LNKA..." */
  68.622 +    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,0x4C,  /* 00000548    ".......L" */
  68.623 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000550    "NKC....." */
  68.624 +    0xFF,0xFF,0x06,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000558    ".....LNK" */
  68.625 +    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000560    "D......." */
  68.626 +    0x06,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000568    "....LNKA" */
  68.627 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06,  /* 00000570    "........" */
  68.628 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000578    "...LNKB." */
  68.629 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 00000580    "........" */
  68.630 +    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000588    ".LNKD..." */
  68.631 +    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x4C,  /* 00000590    ".......L" */
  68.632 +    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000598    "NKA....." */
  68.633 +    0xFF,0xFF,0x07,0x00,0x0A,0x02,0x4C,0x4E,  /* 000005A0    "......LN" */
  68.634 +    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005A8    "KB......" */
  68.635 +    0xFF,0x07,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000005B0    ".....LNK" */
  68.636 +    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000005B8    "C......." */
  68.637 +    0x08,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000005C0    "...LNKA." */
  68.638 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 000005C8    "........" */
  68.639 +    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 000005D0    ".LNKB..." */
  68.640 +    0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02,  /* 000005D8    "........" */
  68.641 +    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000005E0    "LNKC...." */
  68.642 +    0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,0x4C,  /* 000005E8    ".......L" */
  68.643 +    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 000005F0    "NKD....." */
  68.644 +    0xFF,0xFF,0x09,0x00,0x00,0x4C,0x4E,0x4B,  /* 000005F8    ".....LNK" */
  68.645 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000600    "B......." */
  68.646 +    0x09,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000608    "...LNKC." */
  68.647 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,  /* 00000610    "........" */
  68.648 +    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000618    "..LNKD.." */
  68.649 +    0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,  /* 00000620    "........" */
  68.650 +    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000628    ".LNKA..." */
  68.651 +    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x4C,  /* 00000630    ".......L" */
  68.652 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000638    "NKC....." */
  68.653 +    0xFF,0xFF,0x0A,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000640    ".....LNK" */
  68.654 +    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000648    "D......." */
  68.655 +    0x0A,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000650    "....LNKA" */
  68.656 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A,  /* 00000658    "........" */
  68.657 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000660    "...LNKB." */
  68.658 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 00000668    "........" */
  68.659 +    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000670    ".LNKD..." */
  68.660 +    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x4C,  /* 00000678    ".......L" */
  68.661 +    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000680    "NKA....." */
  68.662 +    0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000688    "......LN" */
  68.663 +    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000690    "KB......" */
  68.664 +    0xFF,0x0B,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000698    ".....LNK" */
  68.665 +    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006A0    "C......." */
  68.666 +    0x0C,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000006A8    "...LNKA." */
  68.667 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 000006B0    "........" */
  68.668 +    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 000006B8    ".LNKB..." */
  68.669 +    0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02,  /* 000006C0    "........" */
  68.670 +    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000006C8    "LNKC...." */
  68.671 +    0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x4C,  /* 000006D0    ".......L" */
  68.672 +    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 000006D8    "NKD....." */
  68.673 +    0xFF,0xFF,0x0D,0x00,0x00,0x4C,0x4E,0x4B,  /* 000006E0    ".....LNK" */
  68.674 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006E8    "B......." */
  68.675 +    0x0D,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 000006F0    "...LNKC." */
  68.676 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 000006F8    "........" */
  68.677 +    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000700    "..LNKD.." */
  68.678 +    0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,  /* 00000708    "........" */
  68.679 +    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000710    ".LNKA..." */
  68.680 +    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x4C,  /* 00000718    ".......L" */
  68.681 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000720    "NKC....." */
  68.682 +    0xFF,0xFF,0x0E,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000728    ".....LNK" */
  68.683 +    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000730    "D......." */
  68.684 +    0x0E,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000738    "....LNKA" */
  68.685 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E,  /* 00000740    "........" */
  68.686 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000748    "...LNKB." */
  68.687 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 00000750    "........" */
  68.688 +    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000758    ".LNKD..." */
  68.689 +    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x4C,  /* 00000760    ".......L" */
  68.690 +    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000768    "NKA....." */
  68.691 +    0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000770    "......LN" */
  68.692 +    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000778    "KB......" */
  68.693 +    0xFF,0x0F,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000780    ".....LNK" */
  68.694 +    0x43,0x00,0x08,0x50,0x52,0x54,0x41,0x12,  /* 00000788    "C..PRTA." */
  68.695 +    0x41,0x2F,0x3C,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000790    "A/<....." */
  68.696 +    0xFF,0x01,0x00,0x00,0x00,0x0A,0x14,0x12,  /* 00000798    "........" */
  68.697 +    0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01,  /* 000007A0    "........" */
  68.698 +    0x00,0x0A,0x15,0x12,0x0C,0x04,0x0C,0xFF,  /* 000007A8    "........" */
  68.699 +    0xFF,0x01,0x00,0x0A,0x02,0x00,0x0A,0x16,  /* 000007B0    "........" */
  68.700 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 000007B8    "........" */
  68.701 +    0x0A,0x03,0x00,0x0A,0x17,0x12,0x0B,0x04,  /* 000007C0    "........" */
  68.702 +    0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A,  /* 000007C8    "........" */
  68.703 +    0x18,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,  /* 000007D0    "........" */
  68.704 +    0x00,0x01,0x00,0x0A,0x19,0x12,0x0C,0x04,  /* 000007D8    "........" */
  68.705 +    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x00,  /* 000007E0    "........" */
  68.706 +    0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000007E8    "........" */
  68.707 +    0x02,0x00,0x0A,0x03,0x00,0x0A,0x1B,0x12,  /* 000007F0    "........" */
  68.708 +    0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,  /* 000007F8    "........" */
  68.709 +    0x00,0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000800    "........" */
  68.710 +    0xFF,0x03,0x00,0x01,0x00,0x0A,0x1D,0x12,  /* 00000808    "........" */
  68.711 +    0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 00000810    "........" */
  68.712 +    0x02,0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C,  /* 00000818    "........" */
  68.713 +    0xFF,0xFF,0x03,0x00,0x0A,0x03,0x00,0x0A,  /* 00000820    "........" */
  68.714 +    0x1F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000828    "........" */
  68.715 +    0x00,0x00,0x00,0x0A,0x20,0x12,0x0B,0x04,  /* 00000830    ".... ..." */
  68.716 +    0x0C,0xFF,0xFF,0x04,0x00,0x01,0x00,0x0A,  /* 00000838    "........" */
  68.717 +    0x21,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000840    "!......." */
  68.718 +    0x00,0x0A,0x02,0x00,0x0A,0x22,0x12,0x0C,  /* 00000848    ".....".." */
  68.719 +    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,  /* 00000850    "........" */
  68.720 +    0x00,0x0A,0x23,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000858    "..#....." */
  68.721 +    0xFF,0x05,0x00,0x00,0x00,0x0A,0x24,0x12,  /* 00000860    "......$." */
  68.722 +    0x0B,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01,  /* 00000868    "........" */
  68.723 +    0x00,0x0A,0x25,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000870    "..%....." */
  68.724 +    0xFF,0x05,0x00,0x0A,0x02,0x00,0x0A,0x26,  /* 00000878    ".......&" */
  68.725 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 00000880    "........" */
  68.726 +    0x0A,0x03,0x00,0x0A,0x27,0x12,0x0B,0x04,  /* 00000888    "....'..." */
  68.727 +    0x0C,0xFF,0xFF,0x06,0x00,0x00,0x00,0x0A,  /* 00000890    "........" */
  68.728 +    0x28,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,  /* 00000898    "(......." */
  68.729 +    0x00,0x01,0x00,0x0A,0x29,0x12,0x0C,0x04,  /* 000008A0    "....)..." */
  68.730 +    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x00,  /* 000008A8    "........" */
  68.731 +    0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B0    ".*......" */
  68.732 +    0x06,0x00,0x0A,0x03,0x00,0x0A,0x2B,0x12,  /* 000008B8    "......+." */
  68.733 +    0x0B,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00,  /* 000008C0    "........" */
  68.734 +    0x00,0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,  /* 000008C8    "..,....." */
  68.735 +    0xFF,0x07,0x00,0x01,0x00,0x0A,0x2D,0x12,  /* 000008D0    "......-." */
  68.736 +    0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 000008D8    "........" */
  68.737 +    0x02,0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C,  /* 000008E0    "........" */
  68.738 +    0xFF,0xFF,0x07,0x00,0x0A,0x03,0x00,0x0A,  /* 000008E8    "........" */
  68.739 +    0x2F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,  /* 000008F0    "/......." */
  68.740 +    0x00,0x00,0x00,0x0A,0x11,0x12,0x0B,0x04,  /* 000008F8    "........" */
  68.741 +    0x0C,0xFF,0xFF,0x08,0x00,0x01,0x00,0x0A,  /* 00000900    "........" */
  68.742 +    0x12,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,  /* 00000908    "........" */
  68.743 +    0x00,0x0A,0x02,0x00,0x0A,0x13,0x12,0x0C,  /* 00000910    "........" */
  68.744 +    0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,  /* 00000918    "........" */
  68.745 +    0x00,0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000920    "........" */
  68.746 +    0xFF,0x09,0x00,0x00,0x00,0x0A,0x15,0x12,  /* 00000928    "........" */
  68.747 +    0x0B,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01,  /* 00000930    "........" */
  68.748 +    0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000938    "........" */
  68.749 +    0xFF,0x09,0x00,0x0A,0x02,0x00,0x0A,0x17,  /* 00000940    "........" */
  68.750 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00,  /* 00000948    "........" */
  68.751 +    0x0A,0x03,0x00,0x0A,0x18,0x12,0x0B,0x04,  /* 00000950    "........" */
  68.752 +    0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x00,0x0A,  /* 00000958    "........" */
  68.753 +    0x19,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,  /* 00000960    "........" */
  68.754 +    0x00,0x01,0x00,0x0A,0x1A,0x12,0x0C,0x04,  /* 00000968    "........" */
  68.755 +    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x00,  /* 00000970    "........" */
  68.756 +    0x0A,0x1B,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000978    "........" */
  68.757 +    0x0A,0x00,0x0A,0x03,0x00,0x0A,0x1C,0x12,  /* 00000980    "........" */
  68.758 +    0x0B,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00,  /* 00000988    "........" */
  68.759 +    0x00,0x0A,0x1D,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000990    "........" */
  68.760 +    0xFF,0x0B,0x00,0x01,0x00,0x0A,0x1E,0x12,  /* 00000998    "........" */
  68.761 +    0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 000009A0    "........" */
  68.762 +    0x02,0x00,0x0A,0x1F,0x12,0x0C,0x04,0x0C,  /* 000009A8    "........" */
  68.763 +    0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x00,0x0A,  /* 000009B0    "........" */
  68.764 +    0x20,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,  /* 000009B8    " ......." */
  68.765 +    0x00,0x00,0x00,0x0A,0x21,0x12,0x0B,0x04,  /* 000009C0    "....!..." */
  68.766 +    0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x00,0x0A,  /* 000009C8    "........" */
  68.767 +    0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,  /* 000009D0    ""......." */
  68.768 +    0x00,0x0A,0x02,0x00,0x0A,0x23,0x12,0x0C,  /* 000009D8    ".....#.." */
  68.769 +    0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,  /* 000009E0    "........" */
  68.770 +    0x00,0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,  /* 000009E8    "..$....." */
  68.771 +    0xFF,0x0D,0x00,0x00,0x00,0x0A,0x25,0x12,  /* 000009F0    "......%." */
  68.772 +    0x0B,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01,  /* 000009F8    "........" */
  68.773 +    0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A00    "..&....." */
  68.774 +    0xFF,0x0D,0x00,0x0A,0x02,0x00,0x0A,0x27,  /* 00000A08    ".......'" */
  68.775 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 00000A10    "........" */
  68.776 +    0x0A,0x03,0x00,0x0A,0x28,0x12,0x0B,0x04,  /* 00000A18    "....(..." */
  68.777 +    0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x00,0x0A,  /* 00000A20    "........" */
  68.778 +    0x29,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,  /* 00000A28    ")......." */
  68.779 +    0x00,0x01,0x00,0x0A,0x2A,0x12,0x0C,0x04,  /* 00000A30    "....*..." */
  68.780 +    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x00,  /* 00000A38    "........" */
  68.781 +    0x0A,0x2B,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A40    ".+......" */
  68.782 +    0x0E,0x00,0x0A,0x03,0x00,0x0A,0x2C,0x12,  /* 00000A48    "......,." */
  68.783 +    0x0B,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00,  /* 00000A50    "........" */
  68.784 +    0x00,0x0A,0x2D,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A58    "..-....." */
  68.785 +    0xFF,0x0F,0x00,0x01,0x00,0x0A,0x2E,0x12,  /* 00000A60    "........" */
  68.786 +    0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000A68    "........" */
  68.787 +    0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C,  /* 00000A70    ".../...." */
  68.788 +    0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A78    "........" */
  68.789 +    0x10,0x5B,0x82,0x4C,0x31,0x49,0x53,0x41,  /* 00000A80    ".[.L1ISA" */
  68.790 +    0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,  /* 00000A88    "_._ADR.." */
  68.791 +    0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52,  /* 00000A90    "...[.PIR" */
  68.792 +    0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E,  /* 00000A98    "Q..`...." */
  68.793 +    0x5C,0x00,0x5B,0x81,0x29,0x5C,0x2F,0x04,  /* 00000AA0    "\.[.)\/." */
  68.794 +    0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30,  /* 00000AA8    "_SB_PCI0" */
  68.795 +    0x49,0x53,0x41,0x5F,0x50,0x49,0x52,0x51,  /* 00000AB0    "ISA_PIRQ" */
  68.796 +    0x01,0x50,0x49,0x52,0x41,0x08,0x50,0x49,  /* 00000AB8    ".PIRA.PI" */
  68.797 +    0x52,0x42,0x08,0x50,0x49,0x52,0x43,0x08,  /* 00000AC0    "RB.PIRC." */
  68.798 +    0x50,0x49,0x52,0x44,0x08,0x5B,0x82,0x46,  /* 00000AC8    "PIRD.[.F" */
  68.799 +    0x0B,0x53,0x59,0x53,0x52,0x08,0x5F,0x48,  /* 00000AD0    ".SYSR._H" */
  68.800 +    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08,  /* 00000AD8    "ID.A...." */
  68.801 +    0x5F,0x55,0x49,0x44,0x01,0x08,0x43,0x52,  /* 00000AE0    "_UID..CR" */
  68.802 +    0x53,0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47,  /* 00000AE8    "S_.N...G" */
  68.803 +    0x01,0x10,0x00,0x10,0x00,0x00,0x10,0x47,  /* 00000AF0    ".......G" */
  68.804 +    0x01,0x22,0x00,0x22,0x00,0x00,0x0C,0x47,  /* 00000AF8    "."."...G" */
  68.805 +    0x01,0x30,0x00,0x30,0x00,0x00,0x10,0x47,  /* 00000B00    ".0.0...G" */
  68.806 +    0x01,0x44,0x00,0x44,0x00,0x00,0x1C,0x47,  /* 00000B08    ".D.D...G" */
  68.807 +    0x01,0x62,0x00,0x62,0x00,0x00,0x02,0x47,  /* 00000B10    ".b.b...G" */
  68.808 +    0x01,0x65,0x00,0x65,0x00,0x00,0x0B,0x47,  /* 00000B18    ".e.e...G" */
  68.809 +    0x01,0x72,0x00,0x72,0x00,0x00,0x0E,0x47,  /* 00000B20    ".r.r...G" */
  68.810 +    0x01,0x80,0x00,0x80,0x00,0x00,0x01,0x47,  /* 00000B28    ".......G" */
  68.811 +    0x01,0x84,0x00,0x84,0x00,0x00,0x03,0x47,  /* 00000B30    ".......G" */
  68.812 +    0x01,0x88,0x00,0x88,0x00,0x00,0x01,0x47,  /* 00000B38    ".......G" */
  68.813 +    0x01,0x8C,0x00,0x8C,0x00,0x00,0x03,0x47,  /* 00000B40    ".......G" */
  68.814 +    0x01,0x90,0x00,0x90,0x00,0x00,0x10,0x47,  /* 00000B48    ".......G" */
  68.815 +    0x01,0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47,  /* 00000B50    ".......G" */
  68.816 +    0x01,0xE0,0x00,0xE0,0x00,0x00,0x10,0x47,  /* 00000B58    ".......G" */
  68.817 +    0x01,0xA0,0x08,0xA0,0x08,0x00,0x04,0x47,  /* 00000B60    ".......G" */
  68.818 +    0x01,0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47,  /* 00000B68    ".......G" */
  68.819 +    0x01,0xD0,0x04,0xD0,0x04,0x00,0x02,0x79,  /* 00000B70    ".......y" */
  68.820 +    0x00,0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,  /* 00000B78    "..._CRS." */
  68.821 +    0xA4,0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B,  /* 00000B80    ".CRS_[.+" */
  68.822 +    0x50,0x49,0x43,0x5F,0x08,0x5F,0x48,0x49,  /* 00000B88    "PIC_._HI" */
  68.823 +    0x44,0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52,  /* 00000B90    "D.A.._CR" */
  68.824 +    0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x20,  /* 00000B98    "S....G. " */
  68.825 +    0x00,0x20,0x00,0x01,0x02,0x47,0x01,0xA0,  /* 00000BA0    ". ...G.." */
  68.826 +    0x00,0xA0,0x00,0x01,0x02,0x22,0x04,0x00,  /* 00000BA8    ".....".." */
  68.827 +    0x79,0x00,0x5B,0x82,0x47,0x05,0x44,0x4D,  /* 00000BB0    "y.[.G.DM" */
  68.828 +    0x41,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000BB8    "A0._HID." */
  68.829 +    0x41,0xD0,0x02,0x00,0x08,0x5F,0x43,0x52,  /* 00000BC0    "A...._CR" */
  68.830 +    0x53,0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10,  /* 00000BC8    "S.A..=*." */
  68.831 +    0x04,0x47,0x01,0x00,0x00,0x00,0x00,0x00,  /* 00000BD0    ".G......" */
  68.832 +    0x10,0x47,0x01,0x81,0x00,0x81,0x00,0x00,  /* 00000BD8    ".G......" */
  68.833 +    0x03,0x47,0x01,0x87,0x00,0x87,0x00,0x00,  /* 00000BE0    ".G......" */
  68.834 +    0x01,0x47,0x01,0x89,0x00,0x89,0x00,0x00,  /* 00000BE8    ".G......" */
  68.835 +    0x03,0x47,0x01,0x8F,0x00,0x8F,0x00,0x00,  /* 00000BF0    ".G......" */
  68.836 +    0x01,0x47,0x01,0xC0,0x00,0xC0,0x00,0x00,  /* 00000BF8    ".G......" */
  68.837 +    0x20,0x47,0x01,0x80,0x04,0x80,0x04,0x00,  /* 00000C00    " G......" */
  68.838 +    0x10,0x79,0x00,0x5B,0x82,0x25,0x54,0x4D,  /* 00000C08    ".y.[.%TM" */
  68.839 +    0x52,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000C10    "R_._HID." */
  68.840 +    0x41,0xD0,0x01,0x00,0x08,0x5F,0x43,0x52,  /* 00000C18    "A...._CR" */
  68.841 +    0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x40,  /* 00000C20    "S....G.@" */
  68.842 +    0x00,0x40,0x00,0x00,0x04,0x22,0x01,0x00,  /* 00000C28    ".@...".." */
  68.843 +    0x79,0x00,0x5B,0x82,0x25,0x52,0x54,0x43,  /* 00000C30    "y.[.%RTC" */
  68.844 +    0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000C38    "_._HID.A" */
  68.845 +    0xD0,0x0B,0x00,0x08,0x5F,0x43,0x52,0x53,  /* 00000C40    "...._CRS" */
  68.846 +    0x11,0x10,0x0A,0x0D,0x47,0x01,0x70,0x00,  /* 00000C48    "....G.p." */
  68.847 +    0x70,0x00,0x00,0x02,0x22,0x00,0x01,0x79,  /* 00000C50    "p..."..y" */
  68.848 +    0x00,0x5B,0x82,0x22,0x53,0x50,0x4B,0x52,  /* 00000C58    ".[."SPKR" */
  68.849 +    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000C60    "._HID.A." */
  68.850 +    0x08,0x00,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000C68    "..._CRS." */
  68.851 +    0x0D,0x0A,0x0A,0x47,0x01,0x61,0x00,0x61,  /* 00000C70    "...G.a.a" */
  68.852 +    0x00,0x00,0x01,0x79,0x00,0x5B,0x82,0x31,  /* 00000C78    "...y.[.1" */
  68.853 +    0x50,0x53,0x32,0x4D,0x08,0x5F,0x48,0x49,  /* 00000C80    "PS2M._HI" */
  68.854 +    0x44,0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F,  /* 00000C88    "D.A...._" */
  68.855 +    0x43,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,  /* 00000C90    "CID.A..." */
  68.856 +    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000C98    ".._STA.." */
  68.857 +    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000CA0    "..._CRS." */
  68.858 +    0x08,0x0A,0x05,0x22,0x00,0x10,0x79,0x00,  /* 00000CA8    "..."..y." */
  68.859 +    0x5B,0x82,0x42,0x04,0x50,0x53,0x32,0x4B,  /* 00000CB0    "[.B.PS2K" */
  68.860 +    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000CB8    "._HID.A." */
  68.861 +    0x03,0x03,0x08,0x5F,0x43,0x49,0x44,0x0C,  /* 00000CC0    "..._CID." */
  68.862 +    0x41,0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53,  /* 00000CC8    "A....._S" */
  68.863 +    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000CD0    "TA....._" */
  68.864 +    0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47,  /* 00000CD8    "CRS....G" */
  68.865 +    0x01,0x60,0x00,0x60,0x00,0x00,0x01,0x47,  /* 00000CE0    ".`.`...G" */
  68.866 +    0x01,0x64,0x00,0x64,0x00,0x00,0x01,0x22,  /* 00000CE8    ".d.d..."" */
  68.867 +    0x02,0x00,0x79,0x00,0x5B,0x82,0x3A,0x46,  /* 00000CF0    "..y.[.:F" */
  68.868 +    0x44,0x43,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 00000CF8    "DC0._HID" */
  68.869 +    0x0C,0x41,0xD0,0x07,0x00,0x14,0x09,0x5F,  /* 00000D00    ".A....._" */
  68.870 +    0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,  /* 00000D08    "STA....." */
  68.871 +    0x5F,0x43,0x52,0x53,0x11,0x1B,0x0A,0x18,  /* 00000D10    "_CRS...." */
  68.872 +    0x47,0x01,0xF0,0x03,0xF0,0x03,0x01,0x06,  /* 00000D18    "G......." */
  68.873 +    0x47,0x01,0xF7,0x03,0xF7,0x03,0x01,0x01,  /* 00000D20    "G......." */
  68.874 +    0x22,0x40,0x00,0x2A,0x04,0x00,0x79,0x00,  /* 00000D28    ""@.*..y." */
  68.875 +    0x5B,0x82,0x35,0x55,0x41,0x52,0x31,0x08,  /* 00000D30    "[.5UAR1." */
  68.876 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,  /* 00000D38    "_HID.A.." */
  68.877 +    0x01,0x08,0x5F,0x55,0x49,0x44,0x01,0x14,  /* 00000D40    ".._UID.." */
  68.878 +    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D48    "._STA..." */
  68.879 +    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000D50    ".._CRS.." */
  68.880 +    0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,  /* 00000D58    "..G....." */
  68.881 +    0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B,  /* 00000D60    ".."..y.[" */
  68.882 +    0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F,  /* 00000D68    ".6LTP1._" */
  68.883 +    0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00,  /* 00000D70    "HID.A..." */
  68.884 +    0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,  /* 00000D78    "._UID..." */
  68.885 +    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D80    "._STA..." */
  68.886 +    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000D88    ".._CRS.." */
  68.887 +    0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03,  /* 00000D90    "..G.x.x." */
  68.888 +    0x08,0x08,0x22,0x80,0x00,0x79,0x00,
  68.889  };
  68.890  int DsdtLen=sizeof(AmlCode);
    69.1 --- a/tools/firmware/rombios/32bit/Makefile	Sun Feb 18 16:13:13 2007 -0700
    69.2 +++ b/tools/firmware/rombios/32bit/Makefile	Tue Feb 20 12:58:22 2007 -0700
    69.3 @@ -9,6 +9,8 @@ TARGET = 32bitbios_flat.h
    69.4  
    69.5  CFLAGS += -fno-builtin -O2 -msoft-float -nostdlib
    69.6  CFLAGS += -I../ -DGCC_PROTOS
    69.7 +CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
    69.8 +CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
    69.9  
   69.10  SUBDIRS = tcgbios
   69.11  
    70.1 --- a/tools/firmware/rombios/32bit/tcgbios/Makefile	Sun Feb 18 16:13:13 2007 -0700
    70.2 +++ b/tools/firmware/rombios/32bit/tcgbios/Makefile	Tue Feb 20 12:58:22 2007 -0700
    70.3 @@ -9,6 +9,8 @@ FILES   = tcgbios tpm_drivers
    70.4  OBJECTS = $(foreach f,$(FILES),$(f).o)
    70.5  
    70.6  CFLAGS += -fno-builtin -O2 -msoft-float -nostdlib
    70.7 +CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
    70.8 +CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
    70.9  CFLAGS += -I../ -I../../ -DGCC_PROTOS
   70.10  
   70.11  .PHONY: all clean
    71.1 --- a/tools/ioemu/hw/tpm_tis.c	Sun Feb 18 16:13:13 2007 -0700
    71.2 +++ b/tools/ioemu/hw/tpm_tis.c	Tue Feb 20 12:58:22 2007 -0700
    71.3 @@ -769,6 +769,8 @@ static void tpm_save(QEMUFile* f,void* o
    71.4              if (n > 0) {
    71.5                  if (IS_VALID_LOC(s->active_loc)) {
    71.6                      s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
    71.7 +                    s->loc[s->active_loc].state = STATE_COMPLETION;
    71.8 +                    tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
    71.9                  }
   71.10                  /* close the connection with the vTPM for good */
   71.11                  close_vtpm_channel(s, 1);
   71.12 @@ -881,6 +883,7 @@ void tpm_tis_init(SetIRQFunc *set_irq, v
   71.13      s->Transmitlayer = -1;
   71.14      s->tpmTx.fd[0] = -1;
   71.15      s->tpmTx.fd[1] = -1;
   71.16 +    s->aborting_locty = NO_LOCALITY;
   71.17  
   71.18      tpm_initialize_instance(s, s->vtpm_instance);
   71.19      memset(s->buffer.buf,0,sizeof(s->buffer.buf));
    72.1 --- a/tools/libfsimage/common/fsimage.c	Sun Feb 18 16:13:13 2007 -0700
    72.2 +++ b/tools/libfsimage/common/fsimage.c	Tue Feb 20 12:58:22 2007 -0700
    72.3 @@ -36,7 +36,7 @@
    72.4  
    72.5  static pthread_mutex_t fsi_lock = PTHREAD_MUTEX_INITIALIZER;
    72.6  
    72.7 -fsi_t *fsi_open_fsimage(const char *path, uint64_t off)
    72.8 +fsi_t *fsi_open_fsimage(const char *path, uint64_t off, const char *options)
    72.9  {
   72.10  	fsi_t *fsi = NULL;
   72.11  	int fd;
   72.12 @@ -53,7 +53,7 @@ fsi_t *fsi_open_fsimage(const char *path
   72.13  	fsi->f_data = NULL;
   72.14  
   72.15  	pthread_mutex_lock(&fsi_lock);
   72.16 -	err = find_plugin(fsi, path);
   72.17 +	err = find_plugin(fsi, path, options);
   72.18  	pthread_mutex_unlock(&fsi_lock);
   72.19  	if (err != 0)
   72.20  		goto fail;
    73.1 --- a/tools/libfsimage/common/fsimage.h	Sun Feb 18 16:13:13 2007 -0700
    73.2 +++ b/tools/libfsimage/common/fsimage.h	Tue Feb 20 12:58:22 2007 -0700
    73.3 @@ -35,7 +35,7 @@ extern C {
    73.4  typedef struct fsi fsi_t;
    73.5  typedef struct fsi_file fsi_file_t;
    73.6  
    73.7 -fsi_t *fsi_open_fsimage(const char *, uint64_t);
    73.8 +fsi_t *fsi_open_fsimage(const char *, uint64_t, const char *);
    73.9  void fsi_close_fsimage(fsi_t *);
   73.10  
   73.11  int fsi_file_exists(fsi_t *, const char *);
    74.1 --- a/tools/libfsimage/common/fsimage_grub.c	Sun Feb 18 16:13:13 2007 -0700
    74.2 +++ b/tools/libfsimage/common/fsimage_grub.c	Tue Feb 20 12:58:22 2007 -0700
    74.3 @@ -161,7 +161,7 @@ fsig_substring(const char *s1, const cha
    74.4  }
    74.5  
    74.6  static int
    74.7 -fsig_mount(fsi_t *fsi, const char *path)
    74.8 +fsig_mount(fsi_t *fsi, const char *path, const char *options)
    74.9  {
   74.10  	fsig_plugin_ops_t *ops = fsi->f_plugin->fp_data;
   74.11  	fsi_file_t *ffi;
   74.12 @@ -178,7 +178,7 @@ fsig_mount(fsi_t *fsi, const char *path)
   74.13  
   74.14  	bzero(fsi->f_data, sizeof (fsig_data_t));
   74.15  
   74.16 -	if (!ops->fpo_mount(ffi)) {
   74.17 +	if (!ops->fpo_mount(ffi, options)) {
   74.18  		fsip_file_free(ffi);
   74.19  		free(fsi->f_data);
   74.20  		fsi->f_data = NULL;
    75.1 --- a/tools/libfsimage/common/fsimage_grub.h	Sun Feb 18 16:13:13 2007 -0700
    75.2 +++ b/tools/libfsimage/common/fsimage_grub.h	Tue Feb 20 12:58:22 2007 -0700
    75.3 @@ -38,7 +38,7 @@ extern C {
    75.4  
    75.5  typedef struct fsig_plugin_ops {
    75.6  	int fpo_version;
    75.7 -	int (*fpo_mount)(fsi_file_t *);
    75.8 +	int (*fpo_mount)(fsi_file_t *, const char *);
    75.9  	int (*fpo_dir)(fsi_file_t *, char *);
   75.10  	int (*fpo_read)(fsi_file_t *, char *, int);
   75.11  } fsig_plugin_ops_t;
    76.1 --- a/tools/libfsimage/common/fsimage_plugin.c	Sun Feb 18 16:13:13 2007 -0700
    76.2 +++ b/tools/libfsimage/common/fsimage_plugin.c	Tue Feb 20 12:58:22 2007 -0700
    76.3 @@ -185,7 +185,7 @@ fail:
    76.4  	return (ret);
    76.5  }
    76.6  
    76.7 -int find_plugin(fsi_t *fsi, const char *path)
    76.8 +int find_plugin(fsi_t *fsi, const char *path, const char *options)
    76.9  {
   76.10  	fsi_plugin_t *fp;
   76.11  	int ret = 0;
   76.12 @@ -195,7 +195,7 @@ int find_plugin(fsi_t *fsi, const char *
   76.13  
   76.14  	for (fp = plugins; fp != NULL; fp = fp->fp_next) {
   76.15  		fsi->f_plugin = fp;
   76.16 -		if (fp->fp_ops->fpo_mount(fsi, path) == 0)
   76.17 +		if (fp->fp_ops->fpo_mount(fsi, path, options) == 0)
   76.18  			goto out;
   76.19  	}
   76.20  
    77.1 --- a/tools/libfsimage/common/fsimage_plugin.h	Sun Feb 18 16:13:13 2007 -0700
    77.2 +++ b/tools/libfsimage/common/fsimage_plugin.h	Tue Feb 20 12:58:22 2007 -0700
    77.3 @@ -38,7 +38,7 @@ typedef struct fsi_plugin fsi_plugin_t;
    77.4  
    77.5  typedef struct fsi_plugin_ops {
    77.6  	int fpo_version;
    77.7 -	int (*fpo_mount)(fsi_t *, const char *);
    77.8 +	int (*fpo_mount)(fsi_t *, const char *, const char *);
    77.9  	int (*fpo_umount)(fsi_t *);
   77.10  	fsi_file_t *(*fpo_open)(fsi_t *, const char *);
   77.11  	ssize_t (*fpo_read)(fsi_file_t *, void *, size_t);
    78.1 --- a/tools/libfsimage/common/fsimage_priv.h	Sun Feb 18 16:13:13 2007 -0700
    78.2 +++ b/tools/libfsimage/common/fsimage_priv.h	Tue Feb 20 12:58:22 2007 -0700
    78.3 @@ -53,7 +53,7 @@ struct fsi_file {
    78.4  	void *ff_data;
    78.5  };
    78.6  
    78.7 -int find_plugin(fsi_t *, const char *);
    78.8 +int find_plugin(fsi_t *, const char *, const char *);
    78.9  
   78.10  #ifdef __cplusplus
   78.11  };
    79.1 --- a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c	Sun Feb 18 16:13:13 2007 -0700
    79.2 +++ b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c	Tue Feb 20 12:58:22 2007 -0700
    79.3 @@ -27,7 +27,7 @@
    79.4  #include <inttypes.h>
    79.5  
    79.6  static int
    79.7 -ext2lib_mount(fsi_t *fsi, const char *name)
    79.8 +ext2lib_mount(fsi_t *fsi, const char *name, const char *options)
    79.9  {
   79.10  	int err;
   79.11  	char opts[30] = "";
    80.1 --- a/tools/libfsimage/ext2fs/fsys_ext2fs.c	Sun Feb 18 16:13:13 2007 -0700
    80.2 +++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c	Tue Feb 20 12:58:22 2007 -0700
    80.3 @@ -321,7 +321,7 @@ ffz (unsigned long word)
    80.4  
    80.5  /* check filesystem types and read superblock into memory buffer */
    80.6  int
    80.7 -ext2fs_mount (fsi_file_t *ffi)
    80.8 +ext2fs_mount (fsi_file_t *ffi, const char *options)
    80.9  {
   80.10    int retval = 1;
   80.11  
    81.1 --- a/tools/libfsimage/reiserfs/fsys_reiserfs.c	Sun Feb 18 16:13:13 2007 -0700
    81.2 +++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c	Tue Feb 20 12:58:22 2007 -0700
    81.3 @@ -633,7 +633,7 @@ journal_init (fsi_file_t *ffi)
    81.4  
    81.5  /* check filesystem types and read superblock into memory buffer */
    81.6  int
    81.7 -reiserfs_mount (fsi_file_t *ffi)
    81.8 +reiserfs_mount (fsi_file_t *ffi, const char *options)
    81.9  {
   81.10    struct reiserfs_super_block super;
   81.11    int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
    82.1 --- a/tools/libfsimage/ufs/fsys_ufs.c	Sun Feb 18 16:13:13 2007 -0700
    82.2 +++ b/tools/libfsimage/ufs/fsys_ufs.c	Tue Feb 20 12:58:22 2007 -0700
    82.3 @@ -44,7 +44,7 @@ static grub_daddr32_t sbmap(fsi_file_t *
    82.4  
    82.5  /* read superblock and check fs magic */
    82.6  int
    82.7 -ufs_mount(fsi_file_t *ffi)
    82.8 +ufs_mount(fsi_file_t *ffi, const char *options)
    82.9  {
   82.10  	if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */
   82.11  	    !devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) ||
    83.1 --- a/tools/libxc/Makefile	Sun Feb 18 16:13:13 2007 -0700
    83.2 +++ b/tools/libxc/Makefile	Tue Feb 20 12:58:22 2007 -0700
    83.3 @@ -22,11 +22,7 @@ CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.
    83.4  CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
    83.5  
    83.6  GUEST_SRCS-y :=
    83.7 -GUEST_SRCS-y += xc_load_bin.c
    83.8 -GUEST_SRCS-y += xc_load_elf.c
    83.9  GUEST_SRCS-y += xg_private.c
   83.10 -#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
   83.11 -#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
   83.12  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
   83.13  GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c
   83.14  
    84.1 --- a/tools/libxc/xc_dom.h	Sun Feb 18 16:13:13 2007 -0700
    84.2 +++ b/tools/libxc/xc_dom.h	Tue Feb 20 12:58:22 2007 -0700
    84.3 @@ -7,6 +7,8 @@
    84.4  typedef uint64_t xen_vaddr_t;
    84.5  typedef uint64_t xen_paddr_t;
    84.6  
    84.7 +#define PRIpfn PRI_xen_pfn
    84.8 +
    84.9  struct xc_dom_seg {
   84.10      xen_vaddr_t vstart;
   84.11      xen_vaddr_t vend;
    85.1 --- a/tools/libxc/xc_domain.c	Sun Feb 18 16:13:13 2007 -0700
    85.2 +++ b/tools/libxc/xc_domain.c	Tue Feb 20 12:58:22 2007 -0700
    85.3 @@ -102,7 +102,7 @@ int xc_vcpu_setaffinity(int xc_handle,
    85.4      domctl.domain = (domid_t)domid;
    85.5      domctl.u.vcpuaffinity.vcpu    = vcpu;
    85.6  
    85.7 -    bitmap_64_to_byte(local, &cpumap, sizeof (cpumap));
    85.8 +    bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
    85.9  
   85.10      set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
   85.11  
   85.12 @@ -148,7 +148,7 @@ int xc_vcpu_getaffinity(int xc_handle,
   85.13      ret = do_domctl(xc_handle, &domctl);
   85.14  
   85.15      unlock_pages(local, sizeof (local));
   85.16 -    bitmap_byte_to_64(cpumap, local, sizeof (local));
   85.17 +    bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
   85.18   out:
   85.19      return ret;
   85.20  }
    86.1 --- a/tools/libxc/xc_hvm_build.c	Sun Feb 18 16:13:13 2007 -0700
    86.2 +++ b/tools/libxc/xc_hvm_build.c	Tue Feb 20 12:58:22 2007 -0700
    86.3 @@ -214,15 +214,6 @@ static int setup_guest(int xc_handle,
    86.4              v_start, v_end,
    86.5              elf_uval(&elf, elf.ehdr, e_entry));
    86.6  
    86.7 -    if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
    86.8 -    {
    86.9 -        PERROR("Initial guest OS requires too much space: "
   86.10 -               "(%lluMB is greater than %lluMB limit)\n",
   86.11 -               (unsigned long long)(v_end - v_start) >> 20,
   86.12 -               ((unsigned long long)nr_pages << PAGE_SHIFT) >> 20);
   86.13 -        goto error_out;
   86.14 -    }
   86.15 -
   86.16      if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
   86.17      {
   86.18          PERROR("Could not allocate memory.\n");
    87.1 --- a/tools/libxc/xc_linux_build.c	Sun Feb 18 16:13:13 2007 -0700
    87.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.3 @@ -1,1319 +0,0 @@
    87.4 -/******************************************************************************
    87.5 - * xc_linux_build.c
    87.6 - */
    87.7 -
    87.8 -#include <stddef.h>
    87.9 -#include "xg_private.h"
   87.10 -#include "xc_private.h"
   87.11 -#include <xenctrl.h>
   87.12 -
   87.13 -#include "xc_elf.h"
   87.14 -#include <stdlib.h>
   87.15 -#include <unistd.h>
   87.16 -#include <inttypes.h>
   87.17 -#include <zlib.h>
   87.18 -
   87.19 -/* Handy for printing out '0' prepended values at native pointer size */
   87.20 -#define _p(a) ((void *) ((ulong)a))
   87.21 -
   87.22 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   87.23 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   87.24 -#if defined(__i386__)
   87.25 -#define L3_PROT (_PAGE_PRESENT)
   87.26 -#elif defined(__x86_64__)
   87.27 -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   87.28 -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   87.29 -#endif
   87.30 -
   87.31 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   87.32 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
   87.33 -
   87.34 -struct initrd_info {
   87.35 -    enum { INITRD_none, INITRD_file, INITRD_mem } type;
   87.36 -    /*
   87.37 -     * .len must be filled in by the user for type==INITRD_mem. It is
   87.38 -     * filled in by load_initrd() for INITRD_file and unused for
   87.39 -     * INITRD_none.
   87.40 -     */
   87.41 -    unsigned long len;
   87.42 -    union {
   87.43 -        gzFile file_handle;
   87.44 -        char *mem_addr;
   87.45 -    } u;
   87.46 -};
   87.47 -
   87.48 -static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
   87.49 -    [XENFEAT_writable_page_tables]       = "writable_page_tables",
   87.50 -    [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
   87.51 -    [XENFEAT_auto_translated_physmap]    = "auto_translated_physmap",
   87.52 -    [XENFEAT_supervisor_mode_kernel]     = "supervisor_mode_kernel",
   87.53 -    [XENFEAT_pae_pgdir_above_4gb]        = "pae_pgdir_above_4gb"
   87.54 -};
   87.55 -
   87.56 -static inline void set_feature_bit (int nr, uint32_t *addr)
   87.57 -{
   87.58 -    addr[nr>>5] |= (1<<(nr&31));
   87.59 -}
   87.60 -
   87.61 -static inline int test_feature_bit(int nr, uint32_t *addr)
   87.62 -{
   87.63 -    return !!(addr[nr>>5] & (1<<(nr&31)));
   87.64 -}
   87.65 -
   87.66 -static int parse_features(
   87.67 -    const char *feats,
   87.68 -    uint32_t supported[XENFEAT_NR_SUBMAPS],
   87.69 -    uint32_t required[XENFEAT_NR_SUBMAPS])
   87.70 -{
   87.71 -    const char *end, *p;
   87.72 -    int i, req;
   87.73 -
   87.74 -    if ( (end = strchr(feats, ',')) == NULL )
   87.75 -        end = feats + strlen(feats);
   87.76 -
   87.77 -    while ( feats < end )
   87.78 -    {
   87.79 -        p = strchr(feats, '|');
   87.80 -        if ( (p == NULL) || (p > end) )
   87.81 -            p = end;
   87.82 -
   87.83 -        req = (*feats == '!');
   87.84 -        if ( req )
   87.85 -            feats++;
   87.86 -
   87.87 -        for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
   87.88 -        {
   87.89 -            if ( feature_names[i] == NULL )
   87.90 -                continue;
   87.91 -
   87.92 -            if ( strncmp(feature_names[i], feats, p-feats) == 0 )
   87.93 -            {
   87.94 -                set_feature_bit(i, supported);
   87.95 -                if ( required && req )
   87.96 -                    set_feature_bit(i, required);
   87.97 -                break;
   87.98 -            }
   87.99 -        }
  87.100 -
  87.101 -        if ( i == XENFEAT_NR_SUBMAPS*32 )
  87.102 -        {
  87.103 -            ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats);
  87.104 -            if ( req )
  87.105 -            {
  87.106 -                ERROR("Kernel requires an unknown hypervisor feature.");
  87.107 -                return -EINVAL;
  87.108 -            }
  87.109 -        }
  87.110 -
  87.111 -        feats = p;
  87.112 -        if ( *feats == '|' )
  87.113 -            feats++;
  87.114 -    }
  87.115 -
  87.116 -    return -EINVAL;
  87.117 -}
  87.118 -
  87.119 -static int probeimageformat(const char *image,
  87.120 -                            unsigned long image_size,
  87.121 -                            struct load_funcs *load_funcs)
  87.122 -{
  87.123 -    if ( probe_elf(image, image_size, load_funcs) &&
  87.124 -         probe_bin(image, image_size, load_funcs) )
  87.125 -    {
  87.126 -        xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
  87.127 -        return -EINVAL;
  87.128 -    }
  87.129 -
  87.130 -    return 0;
  87.131 -}
  87.132 -
  87.133 -static int load_initrd(int xc_handle, domid_t dom,
  87.134 -                struct initrd_info *initrd,
  87.135 -                unsigned long physbase,
  87.136 -                xen_pfn_t *phys_to_mach)
  87.137 -{
  87.138 -    char page[PAGE_SIZE];
  87.139 -    unsigned long pfn_start, pfn;
  87.140 -
  87.141 -    if ( initrd->type == INITRD_none )
  87.142 -        return 0;
  87.143 -
  87.144 -    pfn_start = physbase >> PAGE_SHIFT;
  87.145 -
  87.146 -    if ( initrd->type == INITRD_mem )
  87.147 -    {
  87.148 -        unsigned long nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
  87.149 -
  87.150 -        for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
  87.151 -        {
  87.152 -            xc_copy_to_domain_page(
  87.153 -                xc_handle, dom, phys_to_mach[pfn],
  87.154 -                &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
  87.155 -        }
  87.156 -    }
  87.157 -    else
  87.158 -    {
  87.159 -        int readlen;
  87.160 -
  87.161 -        pfn = pfn_start;
  87.162 -        initrd->len = 0;
  87.163 -
  87.164 -        /* gzread returns 0 on EOF */
  87.165 -        while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
  87.166 -        {
  87.167 -            if ( readlen < 0 )
  87.168 -            {
  87.169 -                PERROR("Error reading initrd image, could not");
  87.170 -                return -EINVAL;
  87.171 -            }
  87.172 -
  87.173 -            initrd->len += readlen;
  87.174 -            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
  87.175 -        }
  87.176 -    }
  87.177 -
  87.178 -    return 0;
  87.179 -}
  87.180 -
  87.181 -#define alloc_pt(ltab, vltab)                                           \
  87.182 -do {                                                                    \
  87.183 -    ltab = ppt_alloc++;                                                 \
  87.184 -    ltab = (uint64_t)page_array[ltab] << PAGE_SHIFT;                    \
  87.185 -    if ( vltab != NULL )                                                \
  87.186 -        munmap(vltab, PAGE_SIZE);                                       \
  87.187 -    if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,       \
  87.188 -                                       PROT_READ|PROT_WRITE,            \
  87.189 -                                       ltab >> PAGE_SHIFT)) == NULL )   \
  87.190 -        goto error_out;                                                 \
  87.191 -    memset(vltab, 0x0, PAGE_SIZE);                                      \
  87.192 -} while ( 0 )
  87.193 -
  87.194 -#if defined(__i386__)
  87.195 -
  87.196 -static int setup_pg_tables(int xc_handle, uint32_t dom,
  87.197 -                           vcpu_guest_context_t *ctxt,
  87.198 -                           unsigned long dsi_v_start,
  87.199 -                           unsigned long v_end,
  87.200 -                           xen_pfn_t *page_array,
  87.201 -                           unsigned long vpt_start,
  87.202 -                           unsigned long vpt_end,
  87.203 -                           unsigned shadow_mode_enabled)
  87.204 -{
  87.205 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
  87.206 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
  87.207 -    unsigned long l1tab = 0;
  87.208 -    unsigned long l2tab = 0;
  87.209 -    unsigned long ppt_alloc;
  87.210 -    unsigned long count;
  87.211 -
  87.212 -    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
  87.213 -    alloc_pt(l2tab, vl2tab);
  87.214 -    vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
  87.215 -    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
  87.216 -
  87.217 -    for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
  87.218 -    {
  87.219 -        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
  87.220 -        {
  87.221 -            alloc_pt(l1tab, vl1tab);
  87.222 -            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
  87.223 -            *vl2e++ = l1tab | L2_PROT;
  87.224 -        }
  87.225 -
  87.226 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  87.227 -
  87.228 -        if ( !shadow_mode_enabled )
  87.229 -            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
  87.230 -                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
  87.231 -                *vl1e &= ~_PAGE_RW;
  87.232 -
  87.233 -        vl1e++;
  87.234 -    }
  87.235 -    munmap(vl1tab, PAGE_SIZE);
  87.236 -    munmap(vl2tab, PAGE_SIZE);
  87.237 -    return 0;
  87.238 -
  87.239 - error_out:
  87.240 -    if (vl1tab)
  87.241 -        munmap(vl1tab, PAGE_SIZE);
  87.242 -    if (vl2tab)
  87.243 -        munmap(vl2tab, PAGE_SIZE);
  87.244 -    return -1;
  87.245 -}
  87.246 -
  87.247 -static int setup_pg_tables_pae(int xc_handle, uint32_t dom,
  87.248 -                               vcpu_guest_context_t *ctxt,
  87.249 -                               unsigned long dsi_v_start,
  87.250 -                               unsigned long v_end,
  87.251 -                               xen_pfn_t *page_array,
  87.252 -                               unsigned long vpt_start,
  87.253 -                               unsigned long vpt_end,
  87.254 -                               unsigned shadow_mode_enabled,
  87.255 -                               unsigned pae_mode)
  87.256 -{
  87.257 -    l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
  87.258 -    l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
  87.259 -    l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
  87.260 -    uint64_t l1tab, l2tab, l3tab;
  87.261 -    unsigned long ppt_alloc, count, nmfn;
  87.262 -
  87.263 -    /* First allocate page for page dir. */
  87.264 -    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
  87.265 -
  87.266 -    if ( pae_mode == PAEKERN_extended_cr3 )
  87.267 -    {
  87.268 -        ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
  87.269 -    }
  87.270 -    else if ( page_array[ppt_alloc] > 0xfffff )
  87.271 -    {
  87.272 -        nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
  87.273 -        if ( nmfn == 0 )
  87.274 -        {
  87.275 -            DPRINTF("Couldn't get a page below 4GB :-(\n");
  87.276 -            goto error_out;
  87.277 -        }
  87.278 -        page_array[ppt_alloc] = nmfn;
  87.279 -    }
  87.280 -
  87.281 -    alloc_pt(l3tab, vl3tab);
  87.282 -    vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
  87.283 -    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
  87.284 -
  87.285 -    for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
  87.286 -    {
  87.287 -        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
  87.288 -        {
  87.289 -            if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
  87.290 -            {
  87.291 -                alloc_pt(l2tab, vl2tab);
  87.292 -                vl2e = &vl2tab[l2_table_offset_pae(
  87.293 -                    dsi_v_start + (count << PAGE_SHIFT))];
  87.294 -                *vl3e++ = l2tab | L3_PROT;
  87.295 -            }
  87.296 -
  87.297 -            alloc_pt(l1tab, vl1tab);
  87.298 -            vl1e = &vl1tab[l1_table_offset_pae(
  87.299 -                dsi_v_start + (count << PAGE_SHIFT))];
  87.300 -            *vl2e++ = l1tab | L2_PROT;
  87.301 -
  87.302 -        }
  87.303 -
  87.304 -        *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT;
  87.305 -
  87.306 -        if ( !shadow_mode_enabled )
  87.307 -            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
  87.308 -                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
  87.309 -                *vl1e &= ~_PAGE_RW;
  87.310 -
  87.311 -        vl1e++;
  87.312 -    }
  87.313 -
  87.314 -    /* Xen requires a mid-level pgdir mapping 0xC0000000 region. */
  87.315 -    if ( (vl3tab[3] & _PAGE_PRESENT) == 0 )
  87.316 -    {
  87.317 -        alloc_pt(l2tab, vl2tab);
  87.318 -        vl3tab[3] = l2tab | L3_PROT;
  87.319 -    }
  87.320 -
  87.321 -    munmap(vl1tab, PAGE_SIZE);
  87.322 -    munmap(vl2tab, PAGE_SIZE);
  87.323 -    munmap(vl3tab, PAGE_SIZE);
  87.324 -    return 0;
  87.325 -
  87.326 - error_out:
  87.327 -    if (vl1tab)
  87.328 -        munmap(vl1tab, PAGE_SIZE);
  87.329 -    if (vl2tab)
  87.330 -        munmap(vl2tab, PAGE_SIZE);
  87.331 -    if (vl3tab)
  87.332 -        munmap(vl3tab, PAGE_SIZE);
  87.333 -    return -1;
  87.334 -}
  87.335 -
  87.336 -#endif
  87.337 -
  87.338 -#if defined(__x86_64__)
  87.339 -
  87.340 -static int setup_pg_tables_64(int xc_handle, uint32_t dom,
  87.341 -                              vcpu_guest_context_t *ctxt,
  87.342 -                              unsigned long dsi_v_start,
  87.343 -                              unsigned long v_end,
  87.344 -                              xen_pfn_t *page_array,
  87.345 -                              unsigned long vpt_start,
  87.346 -                              unsigned long vpt_end,
  87.347 -                              int shadow_mode_enabled)
  87.348 -{
  87.349 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
  87.350 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
  87.351 -    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
  87.352 -    l4_pgentry_t *vl4tab=NULL, *vl4e=NULL;
  87.353 -    unsigned long l2tab = 0;
  87.354 -    unsigned long l1tab = 0;
  87.355 -    unsigned long l3tab = 0;
  87.356 -    unsigned long l4tab = 0;
  87.357 -    unsigned long ppt_alloc;
  87.358 -    unsigned long count;
  87.359 -
  87.360 -    /* First allocate page for page dir. */
  87.361 -    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
  87.362 -    alloc_pt(l4tab, vl4tab);
  87.363 -    vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
  87.364 -    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
  87.365 -
  87.366 -    for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
  87.367 -    {
  87.368 -        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
  87.369 -        {
  87.370 -            alloc_pt(l1tab, vl1tab);
  87.371 -
  87.372 -            if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
  87.373 -            {
  87.374 -                alloc_pt(l2tab, vl2tab);
  87.375 -                if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
  87.376 -                {
  87.377 -                    alloc_pt(l3tab, vl3tab);
  87.378 -                    vl3e = &vl3tab[l3_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
  87.379 -                    *vl4e++ = l3tab | L4_PROT;
  87.380 -                }
  87.381 -                vl2e = &vl2tab[l2_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
  87.382 -                *vl3e++ = l2tab | L3_PROT;
  87.383 -            }
  87.384 -            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
  87.385 -            *vl2e++ = l1tab | L2_PROT;
  87.386 -        }
  87.387 -
  87.388 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  87.389 -
  87.390 -        if ( !shadow_mode_enabled )
  87.391 -            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
  87.392 -                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
  87.393 -                *vl1e &= ~_PAGE_RW;
  87.394 -
  87.395 -        vl1e++;
  87.396 -    }
  87.397 -
  87.398 -    munmap(vl1tab, PAGE_SIZE);
  87.399 -    munmap(vl2tab, PAGE_SIZE);
  87.400 -    munmap(vl3tab, PAGE_SIZE);
  87.401 -    munmap(vl4tab, PAGE_SIZE);
  87.402 -    return 0;
  87.403 -
  87.404 - error_out:
  87.405 -    if (vl1tab)
  87.406 -        munmap(vl1tab, PAGE_SIZE);
  87.407 -    if (vl2tab)
  87.408 -        munmap(vl2tab, PAGE_SIZE);
  87.409 -    if (vl3tab)
  87.410 -        munmap(vl3tab, PAGE_SIZE);
  87.411 -    if (vl4tab)
  87.412 -        munmap(vl4tab, PAGE_SIZE);
  87.413 -    return -1;
  87.414 -}
  87.415 -#endif
  87.416 -
  87.417 -#ifdef __ia64__
  87.418 -static int setup_guest(int xc_handle,
  87.419 -                       uint32_t dom,
  87.420 -                       const char *image, unsigned long image_size,
  87.421 -                       struct initrd_info *initrd,
  87.422 -                       unsigned long nr_pages,
  87.423 -                       unsigned long *pvsi, unsigned long *pvke,
  87.424 -                       unsigned long *pvss, vcpu_guest_context_t *ctxt,
  87.425 -                       const char *cmdline,
  87.426 -                       unsigned long shared_info_frame,
  87.427 -                       unsigned long flags,
  87.428 -                       unsigned int store_evtchn, unsigned long *store_mfn,
  87.429 -                       unsigned int console_evtchn, unsigned long *console_mfn,
  87.430 -                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
  87.431 -{
  87.432 -    xen_pfn_t *page_array = NULL;
  87.433 -    struct load_funcs load_funcs;
  87.434 -    struct domain_setup_info dsi;
  87.435 -    unsigned long vinitrd_start;
  87.436 -    unsigned long vinitrd_end;
  87.437 -    unsigned long v_end;
  87.438 -    unsigned long start_page, pgnr;
  87.439 -    start_info_t *start_info;
  87.440 -    unsigned long start_info_mpa;
  87.441 -    struct xen_ia64_boot_param *bp;
  87.442 -    shared_info_t *shared_info;
  87.443 -    int i;
  87.444 -    DECLARE_DOMCTL;
  87.445 -    int rc;
  87.446 -
  87.447 -    rc = probeimageformat(image, image_size, &load_funcs);
  87.448 -    if ( rc != 0 )
  87.449 -        goto error_out;
  87.450 -
  87.451 -    memset(&dsi, 0, sizeof(struct domain_setup_info));
  87.452 -
  87.453 -    rc = (load_funcs.parseimage)(image, image_size, &dsi);
  87.454 -    if ( rc != 0 )
  87.455 -        goto error_out;
  87.456 -
  87.457 -    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
  87.458 -    {
  87.459 -        PERROR("Could not allocate memory");
  87.460 -        goto error_out;
  87.461 -    }
  87.462 -    for ( i = 0; i < nr_pages; i++ )
  87.463 -        page_array[i] = i;
  87.464 -    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
  87.465 -                                           0, 0, page_array) )
  87.466 -    {
  87.467 -        PERROR("Could not allocate memory for PV guest.\n");
  87.468 -        goto error_out;
  87.469 -    }
  87.470 -
  87.471 -    dsi.v_start    = round_pgdown(dsi.v_start);
  87.472 -    vinitrd_start  = round_pgup(dsi.v_end);
  87.473 -    start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
  87.474 -    *pvke          = dsi.v_kernentry;
  87.475 -
  87.476 -    /* Build firmware.  */
  87.477 -    memset(&domctl.u.arch_setup, 0, sizeof(domctl.u.arch_setup));
  87.478 -    domctl.u.arch_setup.flags = 0;
  87.479 -    domctl.u.arch_setup.bp = start_info_mpa + sizeof (start_info_t);
  87.480 -    domctl.u.arch_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT;
  87.481 -    domctl.cmd = XEN_DOMCTL_arch_setup;
  87.482 -    domctl.domain = (domid_t)dom;
  87.483 -    if ( xc_domctl(xc_handle, &domctl) )
  87.484 -        goto error_out;
  87.485 -
  87.486 -    start_page = dsi.v_start >> PAGE_SHIFT;
  87.487 -    /* in order to get initrd->len, we need to load initrd image at first */
  87.488 -    if ( load_initrd(xc_handle, dom, initrd,
  87.489 -                     vinitrd_start - dsi.v_start, page_array + start_page) )
  87.490 -        goto error_out;
  87.491 -
  87.492 -    vinitrd_end    = vinitrd_start + initrd->len;
  87.493 -    v_end          = round_pgup(vinitrd_end);
  87.494 -    pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT;
  87.495 -    if ( pgnr > nr_pages )
  87.496 -    {
  87.497 -        PERROR("too small memory is specified. "
  87.498 -               "At least %ld kb is necessary.\n",
  87.499 -               pgnr << (PAGE_SHIFT - 10));
  87.500 -    }
  87.501 -
  87.502 -    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
  87.503 -           " Loaded kernel: %p->%p\n"
  87.504 -           " Init. ramdisk: %p->%p\n"
  87.505 -           " TOTAL:         %p->%p\n",
  87.506 -           _p(dsi.v_kernstart), _p(dsi.v_kernend),
  87.507 -           _p(vinitrd_start),   _p(vinitrd_end),
  87.508 -           _p(dsi.v_start),     _p(v_end));
  87.509 -    IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
  87.510 -
  87.511 -    (load_funcs.loadimage)(image, image_size, xc_handle, dom,
  87.512 -                           page_array + start_page, &dsi);
  87.513 -
  87.514 -    *store_mfn = page_array[nr_pages - 2]; //XXX
  87.515 -    *console_mfn = page_array[nr_pages - 1]; //XXX
  87.516 -    IPRINTF("start_info: 0x%lx at 0x%lx, "
  87.517 -           "store_mfn: 0x%lx at 0x%lx, "
  87.518 -           "console_mfn: 0x%lx at 0x%lx\n",
  87.519 -           page_array[nr_pages - 3], nr_pages - 3,
  87.520 -           *store_mfn,    nr_pages - 2,
  87.521 -           *console_mfn,  nr_pages - 1);
  87.522 -
  87.523 -    start_info = xc_map_foreign_range(
  87.524 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  87.525 -        page_array[nr_pages - 3]);
  87.526 -    if ( start_info == NULL )
  87.527 -        goto error_out;
  87.528 -
  87.529 -    memset(start_info, 0, sizeof(*start_info));
  87.530 -    rc = xc_version(xc_handle, XENVER_version, NULL);
  87.531 -    sprintf(start_info->magic, "xen-%i.%i-ia64", rc >> 16, rc & (0xFFFF));
  87.532 -    start_info->flags        = flags;
  87.533 -    start_info->store_mfn    = nr_pages - 2;
  87.534 -    start_info->store_evtchn = store_evtchn;
  87.535 -    start_info->console.domU.mfn   = nr_pages - 1;
  87.536 -    start_info->console.domU.evtchn = console_evtchn;
  87.537 -    start_info->nr_pages       = nr_pages; // FIXME?: nr_pages - 2 ????
  87.538 -
  87.539 -    bp = (struct xen_ia64_boot_param *)(start_info + 1);
  87.540 -    bp->command_line = start_info_mpa + offsetof(start_info_t, cmd_line);
  87.541 -    if ( cmdline != NULL )
  87.542 -    {
  87.543 -        strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
  87.544 -        start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = 0;
  87.545 -    }
  87.546 -    if ( initrd->len != 0 )
  87.547 -    {
  87.548 -        bp->initrd_start    = vinitrd_start;
  87.549 -        bp->initrd_size     = initrd->len;
  87.550 -    }
  87.551 -    ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t);
  87.552 -    munmap(start_info, PAGE_SIZE);
  87.553 -
  87.554 -    /*
  87.555 -     * shared_info is assiged into guest pseudo physical address space
  87.556 -     * by XEN_DOMCTL_arch_setup. shared_info_frame is stale value until that.
  87.557 -     * So passed shared_info_frame is stale. obtain the right value here.
  87.558 -     */
  87.559 -    domctl.cmd = XEN_DOMCTL_getdomaininfo;
  87.560 -    domctl.domain = (domid_t)dom;
  87.561 -    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
  87.562 -         ((uint16_t)domctl.domain != dom) )
  87.563 -    {
  87.564 -        PERROR("Could not get info on domain");
  87.565 -        goto error_out;
  87.566 -    }
  87.567 -    shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
  87.568 -
  87.569 -    /* shared_info page starts its life empty. */
  87.570 -    shared_info = xc_map_foreign_range(
  87.571 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
  87.572 -    printf("shared_info = %p frame=%lx\n",
  87.573 -           shared_info, shared_info_frame);
  87.574 -    //memset(shared_info, 0, PAGE_SIZE);
  87.575 -    /* Mask all upcalls... */
  87.576 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  87.577 -        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
  87.578 -    shared_info->arch.start_info_pfn = nr_pages - 3;
  87.579 -
  87.580 -    munmap(shared_info, PAGE_SIZE);
  87.581 -    free(page_array);
  87.582 -    return 0;
  87.583 -
  87.584 - error_out:
  87.585 -    free(page_array);
  87.586 -    return -1;
  87.587 -}
  87.588 -#else /* x86 */
  87.589 -
  87.590 -/* Check if the platform supports the guest kernel format */
  87.591 -static int compat_check(int xc_handle, struct domain_setup_info *dsi)
  87.592 -{
  87.593 -    xen_capabilities_info_t xen_caps = "";
  87.594 -
  87.595 -    if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
  87.596 -        xc_set_error(XC_INVALID_KERNEL,
  87.597 -                     "Cannot determine host capabilities.");
  87.598 -        return 0;
  87.599 -    }
  87.600 -
  87.601 -#ifndef __x86_64__//temp
  87.602 -    if (strstr(xen_caps, "xen-3.0-x86_32p")) {
  87.603 -        if (dsi->pae_kernel == PAEKERN_bimodal) {
  87.604 -            dsi->pae_kernel = PAEKERN_extended_cr3;
  87.605 -        } else if (dsi->pae_kernel == PAEKERN_no) {
  87.606 -            xc_set_error(XC_INVALID_KERNEL,
  87.607 -                         "Non PAE-kernel on PAE host.");
  87.608 -            return 0;
  87.609 -        }
  87.610 -    } else {
  87.611 -        if (dsi->pae_kernel == PAEKERN_bimodal) {
  87.612 -            dsi->pae_kernel = PAEKERN_no;
  87.613 -        } else if (dsi->pae_kernel != PAEKERN_no) {
  87.614 -            xc_set_error(XC_INVALID_KERNEL,
  87.615 -                         "PAE-kernel on non-PAE host.");
  87.616 -            return 0;
  87.617 -        }
  87.618 -    }
  87.619 -#endif
  87.620 -
  87.621 -    return 1;
  87.622 -}
  87.623 -
  87.624 -static inline int increment_ulong(unsigned long *pval, unsigned long inc)
  87.625 -{
  87.626 -    if ( inc >= -*pval )
  87.627 -    {
  87.628 -        ERROR("Value wrapped to zero: image too large?");
  87.629 -        return 0;
  87.630 -    }
  87.631 -    *pval += inc;
  87.632 -    return 1;
  87.633 -}
  87.634 -
  87.635 -static int setup_guest(int xc_handle,
  87.636 -                       uint32_t dom,
  87.637 -                       const char *image, unsigned long image_size,
  87.638 -                       struct initrd_info *initrd,
  87.639 -                       unsigned long nr_pages,
  87.640 -                       unsigned long *pvsi, unsigned long *pvke,
  87.641 -                       unsigned long *pvss, vcpu_guest_context_t *ctxt,
  87.642 -                       const char *cmdline,
  87.643 -                       unsigned long shared_info_frame,
  87.644 -                       unsigned long flags,
  87.645 -                       unsigned int store_evtchn, unsigned long *store_mfn,
  87.646 -                       unsigned int console_evtchn, unsigned long *console_mfn,
  87.647 -                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
  87.648 -{
  87.649 -    xen_pfn_t *page_array = NULL;
  87.650 -    unsigned long count, i;
  87.651 -    unsigned long long hypercall_page;
  87.652 -    int hypercall_page_defined;
  87.653 -    start_info_t *start_info;
  87.654 -    shared_info_t *shared_info;
  87.655 -    const char *p;
  87.656 -    DECLARE_DOMCTL;
  87.657 -    int rc;
  87.658 -
  87.659 -    unsigned long nr_pt_pages;
  87.660 -    unsigned long physmap_pfn;
  87.661 -    xen_pfn_t *physmap, *physmap_e;
  87.662 -
  87.663 -    struct load_funcs load_funcs;
  87.664 -    struct domain_setup_info dsi;
  87.665 -    unsigned long vinitrd_start;
  87.666 -    unsigned long vphysmap_start;
  87.667 -    unsigned long vstartinfo_start;
  87.668 -    unsigned long vstoreinfo_start;
  87.669 -    unsigned long vconsole_start;
  87.670 -    unsigned long vsharedinfo_start = 0; /* XXX gcc */
  87.671 -    unsigned long vstack_start;
  87.672 -    unsigned long vstack_end;
  87.673 -    unsigned long vpt_start;
  87.674 -    unsigned long vpt_end;
  87.675 -    unsigned long v_end;
  87.676 -    unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
  87.677 -    unsigned long shadow_mode_enabled;
  87.678 -    uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
  87.679 -
  87.680 -    rc = probeimageformat(image, image_size, &load_funcs);
  87.681 -    if ( rc != 0 )
  87.682 -        goto error_out;
  87.683 -
  87.684 -    memset(&dsi, 0, sizeof(struct domain_setup_info));
  87.685 -
  87.686 -    rc = (load_funcs.parseimage)(image, image_size, &dsi);
  87.687 -    if ( rc != 0 )
  87.688 -        goto error_out;
  87.689 -
  87.690 -    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
  87.691 -    {
  87.692 -        PERROR("Guest OS must load to a page boundary.");
  87.693 -        goto error_out;
  87.694 -    }
  87.695 -
  87.696 -    if ( !compat_check(xc_handle, &dsi) )
  87.697 -        goto error_out;
  87.698 -
  87.699 -    /* Parse and validate kernel features. */
  87.700 -    if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
  87.701 -    {
  87.702 -        if ( !parse_features(p, supported_features, required_features) )
  87.703 -        {
  87.704 -            ERROR("Failed to parse guest kernel features.");
  87.705 -            goto error_out;
  87.706 -        }
  87.707 -
  87.708 -        IPRINTF("Supported features  = { %08x }.\n", supported_features[0]);
  87.709 -        IPRINTF("Required features   = { %08x }.\n", required_features[0]);
  87.710 -    }
  87.711 -
  87.712 -    for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
  87.713 -    {
  87.714 -        if ( (supported_features[i] & required_features[i]) !=
  87.715 -             required_features[i] )
  87.716 -        {
  87.717 -            ERROR("Guest kernel does not support a required feature.");
  87.718 -            goto error_out;
  87.719 -        }
  87.720 -    }
  87.721 -
  87.722 -    shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
  87.723 -                                           required_features);
  87.724 -
  87.725 -    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
  87.726 -    {
  87.727 -        PERROR("Could not allocate memory");
  87.728 -        goto error_out;
  87.729 -    }
  87.730 -
  87.731 -    for ( i = 0; i < nr_pages; i++ )
  87.732 -        page_array[i] = i;
  87.733 -
  87.734 -    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
  87.735 -                                           0, 0, page_array) )
  87.736 -    {
  87.737 -        PERROR("Could not allocate memory for PV guest.\n");
  87.738 -        goto error_out;
  87.739 -    }
  87.740 -
  87.741 -
  87.742 -    if ( shadow_mode_enabled )
  87.743 -    {
  87.744 -        /*
  87.745 -         * Enable shadow translate mode. This must happen after
  87.746 -         * populate physmap because the p2m reservation is based on
  87.747 -         * the domain's current memory allocation.
  87.748 -         */
  87.749 -        if ( xc_shadow_control(xc_handle, dom,
  87.750 -                           XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE,
  87.751 -                           NULL, 0, NULL, 0, NULL) < 0 )
  87.752 -        {
  87.753 -            PERROR("Could not enable translation mode");
  87.754 -            goto error_out;
  87.755 -        }
  87.756 -
  87.757 -        /* Reinitialise the gpfn->gmfn array. */
  87.758 -        for ( i = 0; i < nr_pages; i++ )
  87.759 -            page_array[i] = i;
  87.760 -    }
  87.761 -
  87.762 -    rc = (load_funcs.loadimage)(image, image_size,
  87.763 -                           xc_handle, dom, page_array,
  87.764 -                           &dsi);
  87.765 -    if ( rc != 0 )
  87.766 -        goto error_out;
  87.767 -
  87.768 -    /*
  87.769 -     * Why do we need this? The number of page-table frames depends on the
  87.770 -     * size of the bootstrap address space. But the size of the address space
  87.771 -     * depends on the number of page-table frames (since each one is mapped
  87.772 -     * read-only). We have a pair of simultaneous equations in two unknowns,
  87.773 -     * which we solve by exhaustive search.
  87.774 -     */
  87.775 -    v_end = round_pgup(dsi.v_end);
  87.776 -    if ( v_end == 0 )
  87.777 -    {
  87.778 -        ERROR("End of mapped kernel image too close to end of memory");
  87.779 -        goto error_out;
  87.780 -    }
  87.781 -
  87.782 -    vinitrd_start = v_end;
  87.783 -    if ( load_initrd(xc_handle, dom, initrd,
  87.784 -                     vinitrd_start - dsi.v_start, page_array) )
  87.785 -        goto error_out;
  87.786 -    if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
  87.787 -        goto error_out;
  87.788 -
  87.789 -    vphysmap_start = v_end;
  87.790 -    if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
  87.791 -        goto error_out;
  87.792 -    vstartinfo_start = v_end;
  87.793 -    if ( !increment_ulong(&v_end, PAGE_SIZE) )
  87.794 -        goto error_out;
  87.795 -    vstoreinfo_start = v_end;
  87.796 -    if ( !increment_ulong(&v_end, PAGE_SIZE) )
  87.797 -        goto error_out;
  87.798 -    vconsole_start = v_end;
  87.799 -    if ( !increment_ulong(&v_end, PAGE_SIZE) )
  87.800 -        goto error_out;
  87.801 -    if ( shadow_mode_enabled ) {
  87.802 -        vsharedinfo_start = v_end;
  87.803 -        if ( !increment_ulong(&v_end, PAGE_SIZE) )
  87.804 -            goto error_out;
  87.805 -    }
  87.806 -    vpt_start = v_end;
  87.807 -
  87.808 -    for ( nr_pt_pages = 2; ; nr_pt_pages++ )
  87.809 -    {
  87.810 -        /* vpt_end = vpt_staret + (nr_pt_pages * PAGE_SIZE); */
  87.811 -        vpt_end = vpt_start;
  87.812 -        if ( !increment_ulong(&vpt_end, nr_pt_pages * PAGE_SIZE) )
  87.813 -            goto error_out;
  87.814 -
  87.815 -        vstack_start = vpt_end;
  87.816 -        /* vstack_end = vstack_start + PAGE_SIZE; */
  87.817 -        vstack_end = vstack_start;
  87.818 -        if ( !increment_ulong(&vstack_end, PAGE_SIZE) )
  87.819 -            goto error_out;
  87.820 -
  87.821 -        /* v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); */
  87.822 -        v_end = vstack_end;
  87.823 -        if ( !increment_ulong(&v_end, (1UL<<22)-1) )
  87.824 -            goto error_out;
  87.825 -        v_end &= ~((1UL<<22)-1);
  87.826 -
  87.827 -        if ( (v_end - vstack_end) < (512UL << 10) )
  87.828 -        {
  87.829 -            /* Add extra 4MB to get >= 512kB padding. */
  87.830 -            if ( !increment_ulong(&v_end, 1UL << 22) )
  87.831 -                goto error_out;
  87.832 -        }
  87.833 -
  87.834 -#define NR(_l,_h,_s)                                                    \
  87.835 -    (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) -    \
  87.836 -    ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
  87.837 -#if defined(__i386__)
  87.838 -        if ( dsi.pae_kernel != PAEKERN_no )
  87.839 -        {
  87.840 -            if ( (1 + /* # L3 */
  87.841 -                  NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */
  87.842 -                  NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT_PAE) + /* # L1 */
  87.843 -                  /* Include a fourth mid-level page directory for Xen. */
  87.844 -                  (v_end <= (3 << L3_PAGETABLE_SHIFT_PAE)))
  87.845 -                  <= nr_pt_pages )
  87.846 -                break;
  87.847 -        }
  87.848 -        else
  87.849 -        {
  87.850 -            if ( (1 + /* # L2 */
  87.851 -                  NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
  87.852 -                 <= nr_pt_pages )
  87.853 -                break;
  87.854 -        }
  87.855 -#elif defined(__x86_64__)
  87.856 -        if ( (1 + /* # L4 */
  87.857 -              NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
  87.858 -              NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
  87.859 -              NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT))  /* # L1 */
  87.860 -             <= nr_pt_pages )
  87.861 -            break;
  87.862 -#endif
  87.863 -    }
  87.864 -
  87.865 -    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
  87.866 -    IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
  87.867 -           _p(dsi.v_kernend));
  87.868 -    if ( initrd->len )
  87.869 -        IPRINTF(" Initial ramdisk:  %p->%p\n", _p(vinitrd_start),
  87.870 -               _p(vinitrd_start + initrd->len));
  87.871 -    IPRINTF(" Phys-Mach map:    %p\n", _p(vphysmap_start));
  87.872 -    IPRINTF(" Start info:       %p\n", _p(vstartinfo_start));
  87.873 -    IPRINTF(" Store page:       %p\n", _p(vstoreinfo_start));
  87.874 -    IPRINTF(" Console page:     %p\n", _p(vconsole_start));
  87.875 -    if ( shadow_mode_enabled )
  87.876 -        IPRINTF(" Shared Info page: %p\n", _p(vsharedinfo_start));
  87.877 -    IPRINTF(" Page tables:      %p\n", _p(vpt_start));
  87.878 -    IPRINTF(" Boot stack:       %p\n", _p(vstack_start));
  87.879 -    IPRINTF(" TOTAL:            %p->%p\n", _p(dsi.v_start), _p(v_end));
  87.880 -    IPRINTF(" ENTRY ADDRESS:    %p\n", _p(dsi.v_kernentry));
  87.881 -
  87.882 -    if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
  87.883 -    {
  87.884 -        PERROR("Initial guest OS requires too much space\n"
  87.885 -               "(%pMB is greater than %luMB limit)\n",
  87.886 -               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
  87.887 -        goto error_out;
  87.888 -    }
  87.889 -
  87.890 -#if defined(__i386__)
  87.891 -    if ( dsi.pae_kernel != PAEKERN_no )
  87.892 -        rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
  87.893 -                                 dsi.v_start, v_end,
  87.894 -                                 page_array, vpt_start, vpt_end,
  87.895 -                                 shadow_mode_enabled, dsi.pae_kernel);
  87.896 -    else
  87.897 -        rc = setup_pg_tables(xc_handle, dom, ctxt,
  87.898 -                             dsi.v_start, v_end,
  87.899 -                             page_array, vpt_start, vpt_end,
  87.900 -                             shadow_mode_enabled);
  87.901 -#endif
  87.902 -#if defined(__x86_64__)
  87.903 -    rc = setup_pg_tables_64(xc_handle, dom, ctxt,
  87.904 -                            dsi.v_start, v_end,
  87.905 -                            page_array, vpt_start, vpt_end,
  87.906 -                            shadow_mode_enabled);
  87.907 -#endif
  87.908 -    if ( rc != 0 )
  87.909 -        goto error_out;
  87.910 -
  87.911 -    /*
  87.912 -     * Pin down l2tab addr as page dir page - causes hypervisor to provide
  87.913 -     * correct protection for the page
  87.914 -     */
  87.915 -    if ( !shadow_mode_enabled )
  87.916 -    {
  87.917 -#if defined(__i386__)
  87.918 -        if ( dsi.pae_kernel != PAEKERN_no )
  87.919 -        {
  87.920 -            if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
  87.921 -                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
  87.922 -                goto error_out;
  87.923 -        }
  87.924 -        else
  87.925 -        {
  87.926 -            if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
  87.927 -                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
  87.928 -                goto error_out;
  87.929 -        }
  87.930 -#elif defined(__x86_64__)
  87.931 -        /*
  87.932 -         * Pin down l4tab addr as page dir page - causes hypervisor to  provide
  87.933 -         * correct protection for the page
  87.934 -         */
  87.935 -        if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
  87.936 -                       xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
  87.937 -            goto error_out;
  87.938 -#endif
  87.939 -    }
  87.940 -
  87.941 -    /* Write the phys->machine table entries (machine->phys already done). */
  87.942 -    physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
  87.943 -    physmap = physmap_e = xc_map_foreign_range(
  87.944 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  87.945 -        page_array[physmap_pfn++]);
  87.946 -    for ( count = 0; count < nr_pages; count++ )
  87.947 -    {
  87.948 -        *physmap_e++ = page_array[count];
  87.949 -        if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 )
  87.950 -        {
  87.951 -            munmap(physmap, PAGE_SIZE);
  87.952 -            physmap = physmap_e = xc_map_foreign_range(
  87.953 -                xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  87.954 -                page_array[physmap_pfn++]);
  87.955 -        }
  87.956 -    }
  87.957 -    munmap(physmap, PAGE_SIZE);
  87.958 -
  87.959 -    if ( shadow_mode_enabled )
  87.960 -    {
  87.961 -        struct xen_add_to_physmap xatp;
  87.962 -
  87.963 -        guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT;
  87.964 -
  87.965 -        /* Map shared info frame into guest physmap. */
  87.966 -        xatp.domid = dom;
  87.967 -        xatp.space = XENMAPSPACE_shared_info;
  87.968 -        xatp.idx   = 0;
  87.969 -        xatp.gpfn  = guest_shared_info_mfn;
  87.970 -        rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
  87.971 -        if ( rc != 0 )
  87.972 -        {
  87.973 -            PERROR("Cannot map shared info pfn");
  87.974 -            goto error_out;
  87.975 -        }
  87.976 -
  87.977 -        /* Map grant table frames into guest physmap. */
  87.978 -        for ( i = 0; ; i++ )
  87.979 -        {
  87.980 -            xatp.domid = dom;
  87.981 -            xatp.space = XENMAPSPACE_grant_table;
  87.982 -            xatp.idx   = i;
  87.983 -            xatp.gpfn  = nr_pages + i;
  87.984 -            rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
  87.985 -            if ( rc != 0 )
  87.986 -            {
  87.987 -                if ( errno == EINVAL )
  87.988 -                    break; /* done all grant tables */
  87.989 -                PERROR("Cannot map grant table pfn");
  87.990 -                goto error_out;
  87.991 -            }
  87.992 -        }
  87.993 -    }
  87.994 -    else
  87.995 -    {
  87.996 -        guest_shared_info_mfn = shared_info_frame;
  87.997 -    }
  87.998 -
  87.999 -    *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT];
 87.1000 -    *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT];
 87.1001 -    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ||
 87.1002 -         xc_clear_domain_page(xc_handle, dom, *console_mfn) )
 87.1003 -        goto error_out;
 87.1004 -    if ( shadow_mode_enabled )
 87.1005 -    {
 87.1006 -        guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT;
 87.1007 -        guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT;
 87.1008 -    }
 87.1009 -    else
 87.1010 -    {
 87.1011 -        guest_store_mfn = *store_mfn;
 87.1012 -        guest_console_mfn = *console_mfn;
 87.1013 -    }
 87.1014 -
 87.1015 -    start_info = xc_map_foreign_range(
 87.1016 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
 87.1017 -        page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
 87.1018 -    /*shared_info, start_info */
 87.1019 -    memset(start_info, 0, sizeof(*start_info));
 87.1020 -    rc = xc_version(xc_handle, XENVER_version, NULL);
 87.1021 -    sprintf(start_info->magic, "xen-%i.%i-x86_%d%s",
 87.1022 -            rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8,
 87.1023 -            (dsi.pae_kernel != PAEKERN_no) ? "p" : "");
 87.1024 -    start_info->nr_pages     = nr_pages;
 87.1025 -    start_info->shared_info  = guest_shared_info_mfn << PAGE_SHIFT;
 87.1026 -    start_info->flags        = flags;
 87.1027 -    start_info->pt_base      = vpt_start;
 87.1028 -    start_info->nr_pt_frames = nr_pt_pages;
 87.1029 -    start_info->mfn_list     = vphysmap_start;
 87.1030 -    start_info->store_mfn    = guest_store_mfn;
 87.1031 -    start_info->store_evtchn = store_evtchn;
 87.1032 -    start_info->console.domU.mfn   = guest_console_mfn;
 87.1033 -    start_info->console.domU.evtchn = console_evtchn;
 87.1034 -    if ( initrd->len != 0 )
 87.1035 -    {
 87.1036 -        start_info->mod_start    = vinitrd_start;
 87.1037 -        start_info->mod_len      = initrd->len;
 87.1038 -    }
 87.1039 -    if ( cmdline != NULL )
 87.1040 -    {
 87.1041 -        strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
 87.1042 -        start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
 87.1043 -    }
 87.1044 -    munmap(start_info, PAGE_SIZE);
 87.1045 -
 87.1046 -    /* shared_info page starts its life empty. */
 87.1047 -    shared_info = xc_map_foreign_range(
 87.1048 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
 87.1049 -    memset(shared_info, 0, PAGE_SIZE);
 87.1050 -    /* Mask all upcalls... */
 87.1051 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
 87.1052 -        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 87.1053 -
 87.1054 -    munmap(shared_info, PAGE_SIZE);
 87.1055 -
 87.1056 -    hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
 87.1057 -                                         &hypercall_page_defined);
 87.1058 -    if ( hypercall_page_defined )
 87.1059 -    {
 87.1060 -        unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT;
 87.1061 -        if ( pfn >= nr_pages )
 87.1062 -            goto error_out;
 87.1063 -        domctl.domain = (domid_t)dom;
 87.1064 -        domctl.u.hypercall_init.gmfn = page_array[pfn];
 87.1065 -        domctl.cmd = XEN_DOMCTL_hypercall_init;
 87.1066 -        if ( xc_domctl(xc_handle, &domctl) )
 87.1067 -            goto error_out;
 87.1068 -    }
 87.1069 -
 87.1070 -    free(page_array);
 87.1071 -
 87.1072 -    *pvsi = vstartinfo_start;
 87.1073 -    *pvss = vstack_start;
 87.1074 -    *pvke = dsi.v_kernentry;
 87.1075 -
 87.1076 -    return 0;
 87.1077 -
 87.1078 - error_out:
 87.1079 -    free(page_array);
 87.1080 -    return -1;
 87.1081 -}
 87.1082 -#endif
 87.1083 -
 87.1084 -static int xc_linux_build_internal(int xc_handle,
 87.1085 -                                   uint32_t domid,
 87.1086 -                                   unsigned int mem_mb,
 87.1087 -                                   const char *image,
 87.1088 -                                   unsigned long image_size,
 87.1089 -                                   struct initrd_info *initrd,
 87.1090 -                                   const char *cmdline,
 87.1091 -                                   const char *features,
 87.1092 -                                   unsigned long flags,
 87.1093 -                                   unsigned int store_evtchn,
 87.1094 -                                   unsigned long *store_mfn,
 87.1095 -                                   unsigned int console_evtchn,
 87.1096 -                                   unsigned long *console_mfn)
 87.1097 -{
 87.1098 -    struct xen_domctl launch_domctl;
 87.1099 -    DECLARE_DOMCTL;
 87.1100 -    int rc;
 87.1101 -    struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt;
 87.1102 -    unsigned long vstartinfo_start, vkern_entry, vstack_start;
 87.1103 -    uint32_t      features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
 87.1104 -
 87.1105 -    if ( features != NULL )
 87.1106 -    {
 87.1107 -        if ( !parse_features(features, features_bitmap, NULL) )
 87.1108 -        {
 87.1109 -            PERROR("Failed to parse configured features\n");
 87.1110 -            goto error_out;
 87.1111 -        }
 87.1112 -    }
 87.1113 -
 87.1114 -    memset(ctxt, 0, sizeof(*ctxt));
 87.1115 -
 87.1116 -    if ( lock_pages(ctxt, sizeof(*ctxt) ) )
 87.1117 -    {
 87.1118 -        PERROR("%s: ctxt lock failed", __func__);
 87.1119 -        return 1;
 87.1120 -    }
 87.1121 -
 87.1122 -    domctl.cmd = XEN_DOMCTL_getdomaininfo;
 87.1123 -    domctl.domain = (domid_t)domid;
 87.1124 -    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
 87.1125 -         ((uint16_t)domctl.domain != domid) )
 87.1126 -    {
 87.1127 -        PERROR("Could not get info on domain");
 87.1128 -        goto error_out;
 87.1129 -    }
 87.1130 -
 87.1131 -    if ( setup_guest(xc_handle, domid, image, image_size,
 87.1132 -                     initrd,
 87.1133 -                     mem_mb << (20 - PAGE_SHIFT),
 87.1134 -                     &vstartinfo_start, &vkern_entry,
 87.1135 -                     &vstack_start, ctxt, cmdline,
 87.1136 -                     domctl.u.getdomaininfo.shared_info_frame,
 87.1137 -                     flags, store_evtchn, store_mfn,
 87.1138 -                     console_evtchn, console_mfn,
 87.1139 -                     features_bitmap) < 0 )
 87.1140 -    {
 87.1141 -        goto error_out;
 87.1142 -    }
 87.1143 -
 87.1144 -#ifdef __ia64__
 87.1145 -    /* based on new_thread in xen/arch/ia64/domain.c */
 87.1146 -    ctxt->user_regs.cr_iip = vkern_entry;
 87.1147 -    ctxt->user_regs.cr_ifs = 1UL << 63;
 87.1148 -    ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default();
 87.1149 -#else /* x86 */
 87.1150 -    /*
 87.1151 -     * Initial register values:
 87.1152 -     *  DS,ES,FS,GS = FLAT_KERNEL_DS
 87.1153 -     *       CS:EIP = FLAT_KERNEL_CS:start_pc
 87.1154 -     *       SS:ESP = FLAT_KERNEL_DS:start_stack
 87.1155 -     *          ESI = start_info
 87.1156 -     *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
 87.1157 -     *       EFLAGS = IF | 2 (bit 1 is reserved and should always be 1)
 87.1158 -     */
 87.1159 -    ctxt->user_regs.ds = FLAT_KERNEL_DS;
 87.1160 -    ctxt->user_regs.es = FLAT_KERNEL_DS;
 87.1161 -    ctxt->user_regs.fs = FLAT_KERNEL_DS;
 87.1162 -    ctxt->user_regs.gs = FLAT_KERNEL_DS;
 87.1163 -    ctxt->user_regs.ss = FLAT_KERNEL_SS;
 87.1164 -    ctxt->user_regs.cs = FLAT_KERNEL_CS;
 87.1165 -    ctxt->user_regs.eip = vkern_entry;
 87.1166 -    ctxt->user_regs.esp = vstack_start + PAGE_SIZE;
 87.1167 -    ctxt->user_regs.esi = vstartinfo_start;
 87.1168 -    ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
 87.1169 -
 87.1170 -    ctxt->flags = VGCF_IN_KERNEL;
 87.1171 -
 87.1172 -    ctxt->kernel_ss = ctxt->user_regs.ss;
 87.1173 -    ctxt->kernel_sp = ctxt->user_regs.esp;
 87.1174 -#endif /* x86 */
 87.1175 -
 87.1176 -    memset(&launch_domctl, 0, sizeof(launch_domctl));
 87.1177 -
 87.1178 -    launch_domctl.domain = (domid_t)domid;
 87.1179 -    launch_domctl.u.vcpucontext.vcpu   = 0;
 87.1180 -    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
 87.1181 -
 87.1182 -    launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
 87.1183 -    rc = xc_domctl(xc_handle, &launch_domctl);
 87.1184 -
 87.1185 -    return rc;
 87.1186 -
 87.1187 - error_out:
 87.1188 -    return -1;
 87.1189 -}
 87.1190 -
 87.1191 -int xc_linux_build_mem(int xc_handle,
 87.1192 -                       uint32_t domid,
 87.1193 -                       unsigned int mem_mb,
 87.1194 -                       const char *image_buffer,
 87.1195 -                       unsigned long image_size,
 87.1196 -                       const char *initrd,
 87.1197 -                       unsigned long initrd_len,
 87.1198 -                       const char *cmdline,
 87.1199 -                       const char *features,
 87.1200 -                       unsigned long flags,
 87.1201 -                       unsigned int store_evtchn,
 87.1202 -                       unsigned long *store_mfn,
 87.1203 -                       unsigned int console_evtchn,
 87.1204 -                       unsigned long *console_mfn)
 87.1205 -{
 87.1206 -    int            sts;
 87.1207 -    char          *img_buf;
 87.1208 -    unsigned long  img_len;
 87.1209 -    struct initrd_info initrd_info = { .type = INITRD_none };
 87.1210 -
 87.1211 -    /* A kernel buffer is required */
 87.1212 -    if ( (image_buffer == NULL) || (image_size == 0) )
 87.1213 -    {
 87.1214 -        ERROR("kernel image buffer not present");
 87.1215 -        return -1;
 87.1216 -    }
 87.1217 -
 87.1218 -    /* If it's gzipped, inflate it;  otherwise, use as is */
 87.1219 -    /* xc_inflate_buffer may return the same buffer pointer if */
 87.1220 -    /* the buffer is already inflated */
 87.1221 -    img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len);
 87.1222 -    if ( img_buf == NULL )
 87.1223 -    {
 87.1224 -        ERROR("unable to inflate kernel image buffer");
 87.1225 -        return -1;
 87.1226 -    }
 87.1227 -
 87.1228 -    /* RAM disks are optional; if we get one, inflate it */
 87.1229 -    if ( initrd != NULL )
 87.1230 -    {
 87.1231 -        initrd_info.type = INITRD_mem;
 87.1232 -        initrd_info.u.mem_addr = xc_inflate_buffer(
 87.1233 -            initrd, initrd_len, &initrd_info.len);
 87.1234 -        if ( initrd_info.u.mem_addr == NULL )
 87.1235 -        {
 87.1236 -            ERROR("unable to inflate ram disk buffer");
 87.1237 -            sts = -1;
 87.1238 -            goto out;
 87.1239 -        }
 87.1240 -    }
 87.1241 -
 87.1242 -    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len,
 87.1243 -                                  &initrd_info, cmdline, features, flags,
 87.1244 -                                  store_evtchn, store_mfn,
 87.1245 -                                  console_evtchn, console_mfn);
 87.1246 -
 87.1247 - out:
 87.1248 -    /* The inflation routines may pass back the same buffer so be */
 87.1249 -    /* sure that we have a buffer and that it's not the one passed in. */
 87.1250 -    /* Don't unnecessarily annoy/surprise/confound the caller */
 87.1251 -    if ( (img_buf != NULL) && (img_buf != image_buffer) )
 87.1252 -        free(img_buf);
 87.1253 -    if ( (initrd_info.u.mem_addr != NULL) &&
 87.1254 -         (initrd_info.u.mem_addr != initrd) )
 87.1255 -        free(initrd_info.u.mem_addr);
 87.1256 -
 87.1257 -    return sts;
 87.1258 -}
 87.1259 -
 87.1260 -int xc_linux_build(int xc_handle,
 87.1261 -                   uint32_t domid,
 87.1262 -                   unsigned int mem_mb,
 87.1263 -                   const char *image_name,
 87.1264 -                   const char *initrd_name,
 87.1265 -                   const char *cmdline,
 87.1266 -                   const char *features,
 87.1267 -                   unsigned long flags,
 87.1268 -                   unsigned int store_evtchn,
 87.1269 -                   unsigned long *store_mfn,
 87.1270 -                   unsigned int console_evtchn,
 87.1271 -                   unsigned long *console_mfn)
 87.1272 -{
 87.1273 -    char *image = NULL;
 87.1274 -    unsigned long image_size;
 87.1275 -    struct initrd_info initrd_info = { .type = INITRD_none };
 87.1276 -    int fd = -1, sts = -1;
 87.1277 -
 87.1278 -    if ( (image_name == NULL) ||
 87.1279 -         ((image = xc_read_image(image_name, &image_size)) == NULL ))
 87.1280 -        return -1;
 87.1281 -
 87.1282 -    if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) )
 87.1283 -    {
 87.1284 -        initrd_info.type = INITRD_file;
 87.1285 -
 87.1286 -        if ( (fd = open(initrd_name, O_RDONLY)) < 0 )
 87.1287 -        {
 87.1288 -            PERROR("Could not open the initial ramdisk image");
 87.1289 -            goto error_out;
 87.1290 -        }
 87.1291 -
 87.1292 -        if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
 87.1293 -        {
 87.1294 -            PERROR("Could not allocate decompression state for initrd");
 87.1295 -            goto error_out;
 87.1296 -        }
 87.1297 -    }
 87.1298 -
 87.1299 -    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size,
 87.1300 -                                  &initrd_info, cmdline, features, flags,
 87.1301 -                                  store_evtchn, store_mfn,
 87.1302 -                                  console_evtchn, console_mfn);
 87.1303 -
 87.1304 - error_out:
 87.1305 -    free(image);
 87.1306 -    if ( initrd_info.type == INITRD_file && initrd_info.u.file_handle )
 87.1307 -        gzclose(initrd_info.u.file_handle);
 87.1308 -    else if ( fd >= 0 )
 87.1309 -        close(fd);
 87.1310 -
 87.1311 -    return sts;
 87.1312 -}
 87.1313 -
 87.1314 -/*
 87.1315 - * Local variables:
 87.1316 - * mode: C
 87.1317 - * c-set-style: "BSD"
 87.1318 - * c-basic-offset: 4
 87.1319 - * tab-width: 4
 87.1320 - * indent-tabs-mode: nil
 87.1321 - * End:
 87.1322 - */
    88.1 --- a/tools/libxc/xc_linux_restore.c	Sun Feb 18 16:13:13 2007 -0700
    88.2 +++ b/tools/libxc/xc_linux_restore.c	Tue Feb 20 12:58:22 2007 -0700
    88.3 @@ -82,7 +82,7 @@ static int uncanonicalize_pagetable(int 
    88.4          if(!(pte & _PAGE_PRESENT))
    88.5              continue; 
    88.6          
    88.7 -        pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
    88.8 +        pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
    88.9          
   88.10          if(pfn >= max_pfn) {
   88.11              /* This "page table page" is probably not one; bail. */
   88.12 @@ -120,12 +120,12 @@ static int uncanonicalize_pagetable(int 
   88.13          if(!(pte & _PAGE_PRESENT))
   88.14              continue;
   88.15          
   88.16 -        pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
   88.17 +        pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
   88.18          
   88.19          if(p2m[pfn] == INVALID_P2M_ENTRY)
   88.20              p2m[pfn] = p2m_batch[nr_mfns++];
   88.21  
   88.22 -        pte &= 0xffffff0000000fffULL;
   88.23 +        pte &= ~MADDR_MASK_X86;
   88.24          pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
   88.25  
   88.26          if(pt_levels == 2)
    89.1 --- a/tools/libxc/xc_linux_save.c	Sun Feb 18 16:13:13 2007 -0700
    89.2 +++ b/tools/libxc/xc_linux_save.c	Tue Feb 20 12:58:22 2007 -0700
    89.3 @@ -495,7 +495,7 @@ static int canonicalize_pagetable(unsign
    89.4          hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
    89.5          he = ((const uint64_t *) spage)[hstart];
    89.6  
    89.7 -        if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) {
    89.8 +        if ( ((he >> PAGE_SHIFT) & MFN_MASK_X86) == m2p_mfn0 ) {
    89.9              /* hvirt starts with xen stuff... */
   89.10              xen_start = hstart;
   89.11          } else if ( hvirt_start != 0xf5800000 ) {
   89.12 @@ -503,7 +503,7 @@ static int canonicalize_pagetable(unsign
   89.13              hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
   89.14              he = ((const uint64_t *) spage)[hstart];
   89.15  
   89.16 -            if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 )
   89.17 +            if( ((he >> PAGE_SHIFT) & MFN_MASK_X86) == m2p_mfn0 )
   89.18                  xen_start = hstart;
   89.19          }
   89.20      }
   89.21 @@ -532,7 +532,7 @@ static int canonicalize_pagetable(unsign
   89.22  
   89.23          if (pte & _PAGE_PRESENT) {
   89.24  
   89.25 -            mfn = (pte >> PAGE_SHIFT) & 0xfffffff;
   89.26 +            mfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
   89.27              if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) {
   89.28                  /* This will happen if the type info is stale which
   89.29                     is quite feasible under live migration */
   89.30 @@ -541,7 +541,7 @@ static int canonicalize_pagetable(unsign
   89.31              } else
   89.32                  pfn = mfn_to_pfn(mfn);
   89.33  
   89.34 -            pte &= 0xffffff0000000fffULL;
   89.35 +            pte &= ~MADDR_MASK_X86;
   89.36              pte |= (uint64_t)pfn << PAGE_SHIFT;
   89.37          }
   89.38  
    90.1 --- a/tools/libxc/xc_load_bin.c	Sun Feb 18 16:13:13 2007 -0700
    90.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.3 @@ -1,306 +0,0 @@
    90.4 -/******************************************************************************
    90.5 - * xc_bin_load.c
    90.6 - *
    90.7 - * Based on xc_elf_load.c
    90.8 - *
    90.9 - * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are
   90.10 - * present. The only requirement is that it must have a xen_bin_image table
   90.11 - * somewhere in the first 8192 bytes, starting on a 32-bit aligned address.
   90.12 - * Those familiar with the multiboot specification should recognize this, it's
   90.13 - * (almost) the same as the multiboot header.
   90.14 - * The layout of the xen_bin_image table is:
   90.15 - *
   90.16 - * Offset Type Name          Note
   90.17 - * 0      uint32_t  magic         required
   90.18 - * 4      uint32_t  flags         required
   90.19 - * 8      uint32_t  checksum      required
   90.20 - * 12     uint32_t  header_addr   required
   90.21 - * 16     uint32_t  load_addr     required
   90.22 - * 20     uint32_t  load_end_addr required
   90.23 - * 24     uint32_t  bss_end_addr  required
   90.24 - * 28     uint32_t  entry_addr    required
   90.25 - *
   90.26 - * - magic
   90.27 - *   Magic number identifying the table. For images to be loaded by Xen 3, the
   90.28 - *   magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set).
   90.29 - * - flags
   90.30 - *   bit 0: indicates whether the image needs to be loaded on a page boundary
   90.31 - *   bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate
   90.32 - *          that memory info should be passed to the image)
   90.33 - *   bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate
   90.34 - *          that the bootloader should pass video mode info to the image)
   90.35 - *   bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate
   90.36 - *           that the values in the fields header_addr - entry_addr are
   90.37 - *           valid)
   90.38 - *   All other bits should be set to 0.
   90.39 - * - checksum
   90.40 - *   When added to "magic" and "flags", the resulting value should be 0.
   90.41 - * - header_addr
   90.42 - *   Contains the virtual address corresponding to the beginning of the
   90.43 - *   table - the memory location at which the magic value is supposed to be
   90.44 - *   loaded. This field serves to synchronize the mapping between OS image
   90.45 - *   offsets and virtual memory addresses.
   90.46 - * - load_addr
   90.47 - *   Contains the virtual address of the beginning of the text segment. The
   90.48 - *   offset in the OS image file at which to start loading is defined by the
   90.49 - *   offset at which the table was found, minus (header addr - load addr).
   90.50 - *   load addr must be less than or equal to header addr.
   90.51 - * - load_end_addr
   90.52 - *   Contains the virtual address of the end of the data segment.
   90.53 - *   (load_end_addr - load_addr) specifies how much data to load. This implies
   90.54 - *   that the text and data segments must be consecutive in the OS image. If
   90.55 - *   this field is zero, the domain builder assumes that the text and data
   90.56 - *   segments occupy the whole OS image file.
   90.57 - * - bss_end_addr
   90.58 - *   Contains the virtual address of the end of the bss segment. The domain
   90.59 - *   builder initializes this area to zero, and reserves the memory it occupies
   90.60 - *   to avoid placing boot modules and other data relevant to the loaded image
   90.61 - *   in that area. If this field is zero, the domain builder assumes that no bss
   90.62 - *   segment is present.
   90.63 - * - entry_addr
   90.64 - *   The virtual address at which to start execution of the loaded image.
   90.65 - *
   90.66 - * Some of the field descriptions were copied from "The Multiboot
   90.67 - * Specification", Copyright 1995, 96 Bryan Ford <baford@cs.utah.edu>,
   90.68 - * Erich Stefan Boleyn <erich@uruk.org> Copyright 1999, 2000, 2001, 2002
   90.69 - * Free Software Foundation, Inc.
   90.70 - */
   90.71 -
   90.72 -#include "xg_private.h"
   90.73 -#include <stdlib.h>
   90.74 -
   90.75 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   90.76 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   90.77 -
   90.78 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   90.79 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
   90.80 -
   90.81 -struct xen_bin_image_table
   90.82 -{
   90.83 -    unsigned long magic;
   90.84 -    unsigned long flags;
   90.85 -    unsigned long checksum;
   90.86 -    unsigned long header_addr;
   90.87 -    unsigned long load_addr;
   90.88 -    unsigned long load_end_addr;
   90.89 -    unsigned long bss_end_addr;
   90.90 -    unsigned long entry_addr;
   90.91 -};
   90.92 -
   90.93 -#define XEN_REACTOS_MAGIC3 0x336ec578
   90.94 -
   90.95 -#define XEN_REACTOS_FLAG_ALIGN4K     0x00000001
   90.96 -#define XEN_REACTOS_FLAG_NEEDMEMINFO 0x00000002
   90.97 -#define XEN_REACTOS_FLAG_NEEDVIDINFO 0x00000004
   90.98 -#define XEN_REACTOS_FLAG_ADDRSVALID  0x00010000
   90.99 -
  90.100 -/* Flags we test for */
  90.101 -#define FLAGS_MASK     ((~ 0) & (~ XEN_REACTOS_FLAG_ALIGN4K))
  90.102 -#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID
  90.103 -
  90.104 -static const struct xen_bin_image_table *
  90.105 -findtable(const char *image, unsigned long image_size);
  90.106 -static int
  90.107 -parsebinimage(
  90.108 -    const char *image, unsigned long image_size,
  90.109 -    struct domain_setup_info *dsi);
  90.110 -static int
  90.111 -loadbinimage(
  90.112 -    const char *image, unsigned long image_size, int xch, uint32_t dom,
  90.113 -    xen_pfn_t *parray, struct domain_setup_info *dsi);
  90.114 -
  90.115 -int probe_bin(const char *image,
  90.116 -              unsigned long image_size,
  90.117 -              struct load_funcs *load_funcs)
  90.118 -{
  90.119 -    if ( findtable(image, image_size) == NULL )
  90.120 -        return -EINVAL;
  90.121 -
  90.122 -    load_funcs->parseimage = parsebinimage;
  90.123 -    load_funcs->loadimage = loadbinimage;
  90.124 -
  90.125 -    return 0;
  90.126 -}
  90.127 -
  90.128 -static const struct xen_bin_image_table *
  90.129 -findtable(const char *image, unsigned long image_size)
  90.130 -{
  90.131 -    const struct xen_bin_image_table *table;
  90.132 -    const unsigned long *probe_ptr;
  90.133 -    unsigned probe_index;
  90.134 -    unsigned probe_count;
  90.135 -
  90.136 -    /* Don't go outside the image */
  90.137 -    if ( image_size < sizeof(struct xen_bin_image_table) )
  90.138 -        return NULL;
  90.139 -
  90.140 -    probe_count = image_size;
  90.141 -    /* Restrict to first 8k */
  90.142 -    if ( probe_count > 8192 )
  90.143 -        probe_count = 8192;
  90.144 -    probe_count = (probe_count - sizeof(struct xen_bin_image_table)) /
  90.145 -                  sizeof(unsigned long);
  90.146 -
  90.147 -    /* Search for the magic header */
  90.148 -    probe_ptr = (const unsigned long *) image;
  90.149 -    table = NULL;
  90.150 -    for ( probe_index = 0; probe_index < probe_count; probe_index++ )
  90.151 -    {
  90.152 -        if ( XEN_REACTOS_MAGIC3 == *probe_ptr )
  90.153 -        {
  90.154 -            table = (const struct xen_bin_image_table *) probe_ptr;
  90.155 -            /* Checksum correct? */
  90.156 -            if ( 0 == table->magic + table->flags + table->checksum )
  90.157 -            {
  90.158 -                return table;
  90.159 -            }
  90.160 -        }
  90.161 -        probe_ptr++;
  90.162 -    }
  90.163 -
  90.164 -    return NULL;
  90.165 -}
  90.166 -
  90.167 -static int parsebinimage(const char *image,
  90.168 -                         unsigned long image_size,
  90.169 -                         struct domain_setup_info *dsi)
  90.170 -{
  90.171 -    const struct xen_bin_image_table *image_info;
  90.172 -    unsigned long start_addr;
  90.173 -    unsigned long end_addr;
  90.174 -
  90.175 -    image_info = findtable(image, image_size);
  90.176 -    if ( NULL == image_info )
  90.177 -    {
  90.178 -        ERROR("Image does not have a valid xen_bin_image_table table.");
  90.179 -        return -EINVAL;
  90.180 -    }
  90.181 -
  90.182 -    /* Check the flags */
  90.183 -    if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) )
  90.184 -    {
  90.185 -        ERROR("xen_bin_image_table flags required 0x%08x found 0x%08lx",
  90.186 -              FLAGS_REQUIRED, image_info->flags & FLAGS_MASK);
  90.187 -        return -EINVAL;
  90.188 -    }
  90.189 -
  90.190 -    /* Sanity check on the addresses */
  90.191 -    if ( image_info->header_addr < image_info->load_addr ||
  90.192 -         ((const char *) image_info - image) <
  90.193 -         (image_info->header_addr - image_info->load_addr) )
  90.194 -    {
  90.195 -        ERROR("Invalid header_addr.");
  90.196 -        return -EINVAL;
  90.197 -    }
  90.198 -    start_addr = image_info->header_addr - ((const char *) image_info - image);
  90.199 -    if ( 0 != image_info->load_end_addr &&
  90.200 -         ( image_info->load_end_addr < image_info->load_end_addr ||
  90.201 -           start_addr + image_size < image_info->load_end_addr ) )
  90.202 -    {
  90.203 -        ERROR("Invalid load_end_addr");
  90.204 -        return -EINVAL;
  90.205 -    }
  90.206 -    end_addr = (0 == image_info->load_end_addr ? start_addr + image_size :
  90.207 -                                                 image_info->load_end_addr);
  90.208 -    if ( 0 != image_info->bss_end_addr &&
  90.209 -         image_info->bss_end_addr < end_addr )
  90.210 -    {
  90.211 -        ERROR("Invalid bss_end_addr");
  90.212 -        return -EINVAL;
  90.213 -    }
  90.214 -
  90.215 -    dsi->v_start = image_info->load_addr;
  90.216 -    if ( 0 != image_info->bss_end_addr )
  90.217 -    {
  90.218 -        dsi->v_end = image_info->bss_end_addr;
  90.219 -    }
  90.220 -    else if ( 0 != image_info->load_end_addr )
  90.221 -    {
  90.222 -        dsi->v_end = image_info->load_end_addr;
  90.223 -    }
  90.224 -    else
  90.225 -    {
  90.226 -        dsi->v_end = image_info->load_addr + image_size -
  90.227 -                     (((const char *) image_info - image) -
  90.228 -                      (image_info->header_addr - image_info->load_addr));
  90.229 -    }
  90.230 -    dsi->v_kernstart = dsi->v_start;
  90.231 -    dsi->v_kernend = dsi->v_end;
  90.232 -    dsi->v_kernentry = image_info->entry_addr;
  90.233 -    dsi->__xen_guest_string = NULL;
  90.234 -
  90.235 -    return 0;
  90.236 -}
  90.237 -
  90.238 -static int
  90.239 -loadbinimage(
  90.240 -    const char *image, unsigned long image_size, int xch, uint32_t dom,
  90.241 -    xen_pfn_t *parray, struct domain_setup_info *dsi)
  90.242 -{
  90.243 -    unsigned long size;
  90.244 -    char         *va;
  90.245 -    unsigned long done, chunksz;
  90.246 -    const struct xen_bin_image_table *image_info;
  90.247 -
  90.248 -    image_info = findtable(image, image_size);
  90.249 -    if ( NULL == image_info )
  90.250 -    {
  90.251 -        ERROR("Image does not have a valid xen_bin_image_table table.");
  90.252 -        return -EINVAL;
  90.253 -    }
  90.254 -
  90.255 -    /* Determine image size */
  90.256 -    if ( 0 == image_info->load_end_addr )
  90.257 -    {
  90.258 -        size = image_size  - (((const char *)image_info - image) -
  90.259 -                              (image_info->header_addr -
  90.260 -                               image_info->load_addr));
  90.261 -    }
  90.262 -    else
  90.263 -    {
  90.264 -        size = image_info->load_end_addr - image_info->load_addr;
  90.265 -    }
  90.266 -
  90.267 -    /* It's possible that we need to skip the first part of the image */
  90.268 -    image += ((const char *)image_info - image) -
  90.269 -             (image_info->header_addr - image_info->load_addr);
  90.270 -
  90.271 -    for ( done = 0; done < size; done += chunksz )
  90.272 -    {
  90.273 -        va = xc_map_foreign_range(
  90.274 -            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
  90.275 -        chunksz = size - done;
  90.276 -        if ( chunksz > PAGE_SIZE )
  90.277 -            chunksz = PAGE_SIZE;
  90.278 -        memcpy(va, image + done, chunksz);
  90.279 -        munmap(va, PAGE_SIZE);
  90.280 -    }
  90.281 -
  90.282 -    if ( 0 != image_info->bss_end_addr &&
  90.283 -         image_info->load_addr + size < image_info->bss_end_addr )
  90.284 -    {
  90.285 -        size = image_info->bss_end_addr - image_info->load_addr;
  90.286 -    }
  90.287 -    for ( ; done < size; done += chunksz )
  90.288 -    {
  90.289 -        va = xc_map_foreign_range(
  90.290 -            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
  90.291 -        chunksz = size - done;
  90.292 -        if ( chunksz > (PAGE_SIZE - (done & (PAGE_SIZE-1))) )
  90.293 -            chunksz = PAGE_SIZE - (done & (PAGE_SIZE-1));
  90.294 -        memset(va + (done & (PAGE_SIZE-1)), 0, chunksz);
  90.295 -        munmap(va, PAGE_SIZE);
  90.296 -    }
  90.297 -
  90.298 -    return 0;
  90.299 -}
  90.300 -
  90.301 -/*
  90.302 - * Local variables:
  90.303 - * mode: C
  90.304 - * c-set-style: "BSD"
  90.305 - * c-basic-offset: 4
  90.306 - * tab-width: 4
  90.307 - * indent-tabs-mode: nil
  90.308 - * End:
  90.309 - */
    91.1 --- a/tools/libxc/xc_load_elf.c	Sun Feb 18 16:13:13 2007 -0700
    91.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.3 @@ -1,684 +0,0 @@
    91.4 -/******************************************************************************
    91.5 - * xc_elf_load.c
    91.6 - */
    91.7 -
    91.8 -#include "xg_private.h"
    91.9 -#include "xc_elf.h"
   91.10 -#include <stdlib.h>
   91.11 -#include <inttypes.h>
   91.12 -
   91.13 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   91.14 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
   91.15 -
   91.16 -static int
   91.17 -parseelfimage(
   91.18 -    const char *image, unsigned long image_size,
   91.19 -    struct domain_setup_info *dsi);
   91.20 -static int
   91.21 -loadelfimage(
   91.22 -    const char *image, unsigned long image_size, int xch, uint32_t dom,
   91.23 -    xen_pfn_t *parray, struct domain_setup_info *dsi);
   91.24 -static int
   91.25 -loadelfsymtab(
   91.26 -    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
   91.27 -    struct domain_setup_info *dsi);
   91.28 -
   91.29 -/*
   91.30 - * Elf header attributes we require for each supported host platform.
   91.31 - * These are checked in parseelfimage().
   91.32 - */
   91.33 -#if defined(__ia64__)
   91.34 -#define ELFCLASS   ELFCLASS64
   91.35 -#define ELFCLASS_DESC "64-bit"
   91.36 -
   91.37 -#define ELFDATA    ELFDATA2LSB
   91.38 -#define ELFDATA_DESC "Little-Endian"
   91.39 -
   91.40 -#define ELFMACHINE EM_IA_64
   91.41 -#define ELFMACHINE_DESC "ia64"
   91.42 -
   91.43 -
   91.44 -#elif defined(__i386__)
   91.45 -#define ELFCLASS   ELFCLASS32
   91.46 -#define ELFCLASS_DESC "32-bit"
   91.47 -
   91.48 -#define ELFDATA    ELFDATA2LSB
   91.49 -#define ELFDATA_DESC "Little-Endian"
   91.50 -
   91.51 -#define ELFMACHINE EM_386
   91.52 -#define ELFMACHINE_DESC "i386"
   91.53 -
   91.54 -
   91.55 -#elif defined(__x86_64__)
   91.56 -#define ELFCLASS   ELFCLASS64
   91.57 -#define ELFCLASS_DESC "64-bit"
   91.58 -
   91.59 -#define ELFDATA    ELFDATA2LSB
   91.60 -#define ELFDATA_DESC "Little-Endian"
   91.61 -
   91.62 -#define ELFMACHINE EM_X86_64
   91.63 -#define ELFMACHINE_DESC "x86_64"
   91.64 -
   91.65 -
   91.66 -#elif defined(__powerpc__)
   91.67 -#define ELFCLASS   ELFCLASS64
   91.68 -#define ELFCLASS_DESC "64-bit"
   91.69 -
   91.70 -#define ELFDATA    ELFDATA2MSB
   91.71 -#define ELFDATA_DESC "Big-Endian"
   91.72 -
   91.73 -#define ELFMACHINE EM_PPC64
   91.74 -#define ELFMACHINE_DESC "ppc64"
   91.75 -#endif
   91.76 -
   91.77 -int probe_elf(const char *image,
   91.78 -              unsigned long image_size,
   91.79 -              struct load_funcs *load_funcs)
   91.80 -{
   91.81 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
   91.82 -
   91.83 -    if ( !IS_ELF(*ehdr) )
   91.84 -        return -EINVAL;
   91.85 -
   91.86 -    load_funcs->parseimage = parseelfimage;
   91.87 -    load_funcs->loadimage = loadelfimage;
   91.88 -
   91.89 -    return 0;
   91.90 -}
   91.91 -
   91.92 -static inline int is_loadable_phdr(const Elf_Phdr *phdr)
   91.93 -{
   91.94 -    return ((phdr->p_type == PT_LOAD) &&
   91.95 -            ((phdr->p_flags & (PF_W|PF_X)) != 0));
   91.96 -}
   91.97 -
   91.98 -/*
   91.99 - * Fallback for kernels containing only the legacy __xen_guest string
  91.100 - * and no ELF notes.
  91.101 - */
  91.102 -static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab)
  91.103 -{
  91.104 -    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
  91.105 -}
  91.106 -
  91.107 -static const char *xen_guest_lookup(
  91.108 -    const struct domain_setup_info *dsi, int type)
  91.109 -{
  91.110 -    const char *xenguest_fallbacks[] = {
  91.111 -        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
  91.112 -        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
  91.113 -        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
  91.114 -        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
  91.115 -        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
  91.116 -        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
  91.117 -        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
  91.118 -        [XEN_ELFNOTE_LOADER] = "LOADER=",
  91.119 -        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
  91.120 -        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
  91.121 -        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
  91.122 -    };
  91.123 -    const char *fallback;
  91.124 -    const char *p;
  91.125 -
  91.126 -    if ( !dsi->__xen_guest_string )
  91.127 -        return NULL;
  91.128 -
  91.129 -    if ( type > sizeof(xenguest_fallbacks) )
  91.130 -        return NULL;
  91.131 -
  91.132 -    if ( (fallback = xenguest_fallbacks[type]) == NULL )
  91.133 -        return NULL;
  91.134 -
  91.135 -    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
  91.136 -        return NULL;
  91.137 -
  91.138 -    return p + strlen(fallback);
  91.139 -}
  91.140 -
  91.141 -static const char *xen_guest_string(
  91.142 -    const struct domain_setup_info *dsi, int type)
  91.143 -{
  91.144 -    const char *p = xen_guest_lookup(dsi, type);
  91.145 -
  91.146 -    /*
  91.147 -     * We special case this since the __xen_guest_section treats the
  91.148 -     * mere precense of the BSD_SYMTAB string as true or false.
  91.149 -     */
  91.150 -    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
  91.151 -        return p ? "yes" : "no";
  91.152 -
  91.153 -    return p;
  91.154 -}
  91.155 -
  91.156 -static unsigned long long xen_guest_numeric(
  91.157 -    const struct domain_setup_info *dsi, int type, int *defined)
  91.158 -{
  91.159 -    const char *p = xen_guest_lookup(dsi, type);
  91.160 -    unsigned long long value;
  91.161 -
  91.162 -    if ( p == NULL )
  91.163 -        return 0;
  91.164 -
  91.165 -    errno = 0;
  91.166 -    value = strtoull(p, NULL, 0);
  91.167 -    if ( errno < 0 )
  91.168 -        return 0;
  91.169 -
  91.170 -    /* We special case this since __xen_guest_section contains a PFN
  91.171 -     * for this field not a virtual address.
  91.172 -     */
  91.173 -    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
  91.174 -        value = dsi->v_start + (value<<PAGE_SHIFT);
  91.175 -
  91.176 -    *defined = 1;
  91.177 -    return value;
  91.178 -}
  91.179 -
  91.180 -/*
  91.181 - * Interface to the Xen ELF notes.
  91.182 - */
  91.183 -#define ELFNOTE_NAME(_n_)   ((const char*)(_n_) + sizeof(*(_n_)))
  91.184 -#define ELFNOTE_DESC(_n_)   (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
  91.185 -#define ELFNOTE_NEXT(_n_)   (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
  91.186 -
  91.187 -static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr)
  91.188 -{
  91.189 -    const Elf_Note *note;
  91.190 -
  91.191 -    if ( shdr->sh_type != SHT_NOTE )
  91.192 -        return 0;
  91.193 -
  91.194 -    for ( note = (const Elf_Note *)(image + shdr->sh_offset);
  91.195 -          note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
  91.196 -          note = (const Elf_Note *)ELFNOTE_NEXT(note) )
  91.197 -    {
  91.198 -        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
  91.199 -            return 1;
  91.200 -    }
  91.201 -
  91.202 -    return 0;
  91.203 -}
  91.204 -
  91.205 -static const Elf_Note *xen_elfnote_lookup(
  91.206 -    const struct domain_setup_info *dsi, int type)
  91.207 -{
  91.208 -    const Elf_Note *note;
  91.209 -
  91.210 -    if ( !dsi->__elfnote_section )
  91.211 -        return NULL;
  91.212 -
  91.213 -    for ( note = (const Elf_Note *)dsi->__elfnote_section;
  91.214 -          note < (const Elf_Note *)dsi->__elfnote_section_end;
  91.215 -          note = (const Elf_Note *)ELFNOTE_NEXT(note) )
  91.216 -    {
  91.217 -        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
  91.218 -            continue;
  91.219 -
  91.220 -        if ( note->type == type )
  91.221 -            return note;
  91.222 -    }
  91.223 -
  91.224 -    return NULL;
  91.225 -}
  91.226 -
  91.227 -const char *xen_elfnote_string(const struct domain_setup_info *dsi, int type)
  91.228 -{
  91.229 -    const Elf_Note *note;
  91.230 -
  91.231 -    if ( !dsi->__elfnote_section )
  91.232 -        return xen_guest_string(dsi, type);
  91.233 -
  91.234 -    note = xen_elfnote_lookup(dsi, type);
  91.235 -    if ( note == NULL )
  91.236 -        return NULL;
  91.237 -
  91.238 -    return (const char *)ELFNOTE_DESC(note);
  91.239 -}
  91.240 -
  91.241 -unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi,
  91.242 -                                       int type, int *defined)
  91.243 -{
  91.244 -    const Elf_Note *note;
  91.245 -
  91.246 -    *defined = 0;
  91.247 -
  91.248 -    if ( !dsi->__elfnote_section )
  91.249 -        return xen_guest_numeric(dsi, type, defined);
  91.250 -
  91.251 -    note = xen_elfnote_lookup(dsi, type);
  91.252 -    if ( note == NULL )
  91.253 -    {
  91.254 -        return 0;
  91.255 -    }
  91.256 -
  91.257 -    switch ( note->descsz )
  91.258 -    {
  91.259 -    case 4:
  91.260 -        *defined = 1;
  91.261 -        return *(const uint32_t*)ELFNOTE_DESC(note);
  91.262 -    case 8:
  91.263 -        *defined = 1;
  91.264 -        return *(const uint64_t*)ELFNOTE_DESC(note);
  91.265 -    default:
  91.266 -        xc_set_error(XC_INVALID_KERNEL,
  91.267 -                     "elfnotes: unknown data size %#x for numeric type note %#x\n",
  91.268 -              note->descsz, type);
  91.269 -        return 0;
  91.270 -    }
  91.271 -}
  91.272 -
  91.273 -static int parseelfimage(const char *image,
  91.274 -                         unsigned long image_len,
  91.275 -                         struct domain_setup_info *dsi)
  91.276 -{
  91.277 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
  91.278 -    const Elf_Phdr *phdr;
  91.279 -    const Elf_Shdr *shdr;
  91.280 -    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
  91.281 -    const char *shstrtab, *p;
  91.282 -    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
  91.283 -
  91.284 -    if ( !IS_ELF(*ehdr) )
  91.285 -    {
  91.286 -        xc_set_error(XC_INVALID_KERNEL,
  91.287 -                     "Kernel image does not have an ELF header.");
  91.288 -        return -EINVAL;
  91.289 -    }
  91.290 -
  91.291 -    if (ehdr->e_machine != ELFMACHINE)
  91.292 -    {
  91.293 -        xc_set_error(XC_INVALID_KERNEL,
  91.294 -                     "Kernel ELF architecture '%d' does not match Xen architecture '%d' (%s)",
  91.295 -                     ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
  91.296 -        return -EINVAL;
  91.297 -    }
  91.298 -    if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
  91.299 -    {
  91.300 -        xc_set_error(XC_INVALID_KERNEL,
  91.301 -                     "Kernel ELF wordsize '%d' does not match Xen wordsize '%d' (%s)",
  91.302 -                     ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
  91.303 -        return -EINVAL;
  91.304 -    }
  91.305 -    if (ehdr->e_ident[EI_DATA] != ELFDATA)
  91.306 -    {
  91.307 -        xc_set_error(XC_INVALID_KERNEL,
  91.308 -                     "Kernel ELF endianness '%d' does not match Xen endianness '%d' (%s)",
  91.309 -                     ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
  91.310 -        return -EINVAL;
  91.311 -    }
  91.312 -    if (ehdr->e_type != ET_EXEC)
  91.313 -    {
  91.314 -        xc_set_error(XC_INVALID_KERNEL,
  91.315 -                     "Kernel ELF type '%d' does not match Xen type '%d'",
  91.316 -                     ehdr->e_type, ET_EXEC);
  91.317 -        return -EINVAL;
  91.318 -    }
  91.319 -
  91.320 -    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
  91.321 -    {
  91.322 -        xc_set_error(XC_INVALID_KERNEL,
  91.323 -                     "ELF program headers extend beyond end of image.");
  91.324 -        return -EINVAL;
  91.325 -    }
  91.326 -
  91.327 -    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
  91.328 -    {
  91.329 -        xc_set_error(XC_INVALID_KERNEL,
  91.330 -                     "ELF section headers extend beyond end of image.");
  91.331 -        return -EINVAL;
  91.332 -    }
  91.333 -
  91.334 -    dsi->__elfnote_section = NULL;
  91.335 -    dsi->__xen_guest_string = NULL;
  91.336 -
  91.337 -    /* Look for .notes segment containing at least one Xen note */
  91.338 -    for ( h = 0; h < ehdr->e_shnum; h++ )
  91.339 -    {
  91.340 -        shdr = (const Elf_Shdr *)(
  91.341 -            image + ehdr->e_shoff + (h*ehdr->e_shentsize));
  91.342 -        if ( !is_xen_elfnote_section(image, shdr) )
  91.343 -            continue;
  91.344 -        dsi->__elfnote_section = (const char *)image + shdr->sh_offset;
  91.345 -        dsi->__elfnote_section_end =
  91.346 -            (const char *)image + shdr->sh_offset + shdr->sh_size;
  91.347 -        break;
  91.348 -    }
  91.349 -
  91.350 -    /* Fall back to looking for the special '__xen_guest' section. */
  91.351 -    if ( dsi->__elfnote_section == NULL )
  91.352 -    {
  91.353 -        /* Find the section-header strings table. */
  91.354 -        if ( ehdr->e_shstrndx == SHN_UNDEF )
  91.355 -        {
  91.356 -            xc_set_error(XC_INVALID_KERNEL,
  91.357 -                         "ELF image has no section-header strings table.");
  91.358 -            return -EINVAL;
  91.359 -        }
  91.360 -        shdr = (const Elf_Shdr *)(image + ehdr->e_shoff +
  91.361 -                            (ehdr->e_shstrndx*ehdr->e_shentsize));
  91.362 -        shstrtab = image + shdr->sh_offset;
  91.363 -
  91.364 -        for ( h = 0; h < ehdr->e_shnum; h++ )
  91.365 -        {
  91.366 -            shdr = (const Elf_Shdr *)(
  91.367 -                image + ehdr->e_shoff + (h*ehdr->e_shentsize));
  91.368 -            if ( is_xen_guest_section(shdr, shstrtab) )
  91.369 -            {
  91.370 -                dsi->__xen_guest_string =
  91.371 -                    (const char *)image + shdr->sh_offset;
  91.372 -                break;
  91.373 -            }
  91.374 -        }
  91.375 -    }
  91.376 -
  91.377 -    /* Check the contents of the Xen notes or guest string. */
  91.378 -    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
  91.379 -    {
  91.380 -        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
  91.381 -        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
  91.382 -        const char *xen_version =
  91.383 -            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
  91.384 -
  91.385 -        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
  91.386 -             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
  91.387 -        {
  91.388 -            xc_set_error(XC_INVALID_KERNEL,
  91.389 -                         "Will only load images built for the generic loader "
  91.390 -                         "or Linux images");
  91.391 -            return -EINVAL;
  91.392 -        }
  91.393 -
  91.394 -        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
  91.395 -        {
  91.396 -            xc_set_error(XC_INVALID_KERNEL,
  91.397 -                         "Will only load images built for Xen v3.0");
  91.398 -            return -EINVAL;
  91.399 -        }
  91.400 -    }
  91.401 -    else
  91.402 -    {
  91.403 -#if defined(__x86_64__) || defined(__i386__)
  91.404 -        xc_set_error(XC_INVALID_KERNEL,
  91.405 -                     "Not a Xen-ELF image: "
  91.406 -                     "No ELF notes or '__xen_guest' section found.");
  91.407 -        return -EINVAL;
  91.408 -#endif
  91.409 -    }
  91.410 -
  91.411 -    /*
  91.412 -     * A "bimodal" ELF note indicates the kernel will adjust to the current
  91.413 -     * paging mode, including handling extended cr3 syntax.  If we have ELF
  91.414 -     * notes then PAE=yes implies that we must support the extended cr3 syntax.
  91.415 -     * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest
  91.416 -     * string. We use strstr() to look for "bimodal" to allow guests to use
  91.417 -     * "yes,bimodal" or "no,bimodal" for compatibility reasons.
  91.418 -     */
  91.419 -
  91.420 -    dsi->pae_kernel = PAEKERN_no;
  91.421 -    if ( dsi->__elfnote_section )
  91.422 -    {
  91.423 -        p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
  91.424 -        if ( p != NULL && strstr(p, "bimodal") != NULL )
  91.425 -            dsi->pae_kernel = PAEKERN_bimodal;
  91.426 -        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
  91.427 -            dsi->pae_kernel = PAEKERN_extended_cr3;
  91.428 -
  91.429 -    }
  91.430 -    else
  91.431 -    {
  91.432 -        p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE);
  91.433 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
  91.434 -        {
  91.435 -            dsi->pae_kernel = PAEKERN_yes;
  91.436 -            if ( !strncmp(p+3, "[extended-cr3]", 14) )
  91.437 -                dsi->pae_kernel = PAEKERN_extended_cr3;
  91.438 -        }
  91.439 -    }
  91.440 -
  91.441 -    /* Initial guess for v_start is 0 if it is not explicitly defined. */
  91.442 -    dsi->v_start =
  91.443 -        xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined);
  91.444 -    if ( !virt_base_defined )
  91.445 -        dsi->v_start = 0;
  91.446 -
  91.447 -    /*
  91.448 -     * If we are using the legacy __xen_guest section then elf_pa_off
  91.449 -     * defaults to v_start in order to maintain compatibility with
  91.450 -     * older hypervisors which set padd in the ELF header to
  91.451 -     * virt_base.
  91.452 -     *
  91.453 -     * If we are using the modern ELF notes interface then the default
  91.454 -     * is 0.
  91.455 -     */
  91.456 -    dsi->elf_paddr_offset = xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET,
  91.457 -                                                &elf_pa_off_defined);
  91.458 -    if ( !elf_pa_off_defined )
  91.459 -    {
  91.460 -        if ( dsi->__elfnote_section )
  91.461 -            dsi->elf_paddr_offset = 0;
  91.462 -        else
  91.463 -            dsi->elf_paddr_offset = dsi->v_start;
  91.464 -    }
  91.465 -
  91.466 -    if ( elf_pa_off_defined && !virt_base_defined )
  91.467 -    {
  91.468 -        xc_set_error(XC_INVALID_KERNEL,
  91.469 -                     "Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
  91.470 -                     " notes or __xen_guest section.");
  91.471 -        return -EINVAL;
  91.472 -    }
  91.473 -
  91.474 -    for ( h = 0; h < ehdr->e_phnum; h++ )
  91.475 -    {
  91.476 -        phdr = (const Elf_Phdr *)(
  91.477 -            image + ehdr->e_phoff + (h*ehdr->e_phentsize));
  91.478 -        if ( !is_loadable_phdr(phdr) )
  91.479 -            continue;
  91.480 -        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
  91.481 -        if ( (vaddr + phdr->p_memsz) < vaddr )
  91.482 -        {
  91.483 -            xc_set_error(XC_INVALID_KERNEL,
  91.484 -                         "ELF program header %d is too large.", h);
  91.485 -            return -EINVAL;
  91.486 -        }
  91.487 -
  91.488 -        if ( vaddr < kernstart )
  91.489 -            kernstart = vaddr;
  91.490 -        if ( (vaddr + phdr->p_memsz) > kernend )
  91.491 -            kernend = vaddr + phdr->p_memsz;
  91.492 -    }
  91.493 -
  91.494 -    dsi->v_kernentry = ehdr->e_entry;
  91.495 -
  91.496 -    virt_entry =
  91.497 -        xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
  91.498 -    if ( virt_entry_defined )
  91.499 -        dsi->v_kernentry = virt_entry;
  91.500 -
  91.501 -    if ( (kernstart > kernend) ||
  91.502 -         (dsi->v_kernentry < kernstart) ||
  91.503 -         (dsi->v_kernentry > kernend) ||
  91.504 -         (dsi->v_start > kernstart) )
  91.505 -    {
  91.506 -        xc_set_error(XC_INVALID_KERNEL,
  91.507 -                     "ELF start or entries are out of bounds.");
  91.508 -        return -EINVAL;
  91.509 -    }
  91.510 -
  91.511 -    p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
  91.512 -    if ( p != NULL && strncmp(p, "yes", 3) == 0 )
  91.513 -        dsi->load_symtab = 1;
  91.514 -
  91.515 -    dsi->v_kernstart = kernstart;
  91.516 -    dsi->v_kernend   = kernend;
  91.517 -    dsi->v_end       = dsi->v_kernend;
  91.518 -
  91.519 -    loadelfsymtab(image, 0, 0, NULL, dsi);
  91.520 -
  91.521 -    return 0;
  91.522 -}
  91.523 -
  91.524 -static int
  91.525 -loadelfimage(
  91.526 -    const char *image, unsigned long elfsize, int xch, uint32_t dom,
  91.527 -    xen_pfn_t *parray, struct domain_setup_info *dsi)
  91.528 -{
  91.529 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
  91.530 -    const Elf_Phdr *phdr;
  91.531 -    int h;
  91.532 -
  91.533 -    char         *va;
  91.534 -    unsigned long pa, done, chunksz;
  91.535 -
  91.536 -    for ( h = 0; h < ehdr->e_phnum; h++ )
  91.537 -    {
  91.538 -        phdr = (const Elf_Phdr *)(
  91.539 -            image + ehdr->e_phoff + (h*ehdr->e_phentsize));
  91.540 -        if ( !is_loadable_phdr(phdr) )
  91.541 -            continue;
  91.542 -
  91.543 -        for ( done = 0; done < phdr->p_filesz; done += chunksz )
  91.544 -        {
  91.545 -            pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset;
  91.546 -            va = xc_map_foreign_range(
  91.547 -                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
  91.548 -            if ( va == NULL )
  91.549 -                return -1;
  91.550 -            chunksz = phdr->p_filesz - done;
  91.551 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  91.552 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  91.553 -            memcpy(va + (pa & (PAGE_SIZE-1)),
  91.554 -                   image + phdr->p_offset + done, chunksz);
  91.555 -            munmap(va, PAGE_SIZE);
  91.556 -        }
  91.557 -
  91.558 -        for ( ; done < phdr->p_memsz; done += chunksz )
  91.559 -        {
  91.560 -            pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset;
  91.561 -            va = xc_map_foreign_range(
  91.562 -                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
  91.563 -            if ( va == NULL )
  91.564 -                return -1;
  91.565 -            chunksz = phdr->p_memsz - done;
  91.566 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  91.567 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  91.568 -            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
  91.569 -            munmap(va, PAGE_SIZE);
  91.570 -        }
  91.571 -    }
  91.572 -
  91.573 -    loadelfsymtab(image, xch, dom, parray, dsi);
  91.574 -
  91.575 -    return 0;
  91.576 -}
  91.577 -
  91.578 -#define ELFROUND (ELFSIZE / 8)
  91.579 -
  91.580 -static int
  91.581 -loadelfsymtab(
  91.582 -    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
  91.583 -    struct domain_setup_info *dsi)
  91.584 -{
  91.585 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
  91.586 -    Elf_Ehdr *sym_ehdr;
  91.587 -    Elf_Shdr *shdr;
  91.588 -    unsigned long maxva, symva;
  91.589 -    char *p;
  91.590 -    int h, i;
  91.591 -
  91.592 -    if ( !dsi->load_symtab )
  91.593 -        return 0;
  91.594 -
  91.595 -    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
  91.596 -               ehdr->e_shnum * sizeof(Elf_Shdr));
  91.597 -    if (p == NULL)
  91.598 -        return 0;
  91.599 -
  91.600 -    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
  91.601 -    symva = maxva;
  91.602 -    maxva += sizeof(int);
  91.603 -    dsi->symtab_addr = maxva;
  91.604 -    dsi->symtab_len = 0;
  91.605 -    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
  91.606 -    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
  91.607 -
  91.608 -    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
  91.609 -    memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
  91.610 -
  91.611 -    for ( h = 0; h < ehdr->e_shnum; h++ )
  91.612 -    {
  91.613 -        if ( shdr[h].sh_type == SHT_STRTAB )
  91.614 -        {
  91.615 -            /* Look for a strtab @i linked to symtab @h. */
  91.616 -            for ( i = 0; i < ehdr->e_shnum; i++ )
  91.617 -                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
  91.618 -                     (shdr[i].sh_link == h) )
  91.619 -                    break;
  91.620 -            /* Skip symtab @h if we found no corresponding strtab @i. */
  91.621 -            if ( i == ehdr->e_shnum )
  91.622 -            {
  91.623 -                shdr[h].sh_offset = 0;
  91.624 -                continue;
  91.625 -            }
  91.626 -        }
  91.627 -
  91.628 -        if ( (shdr[h].sh_type == SHT_STRTAB) ||
  91.629 -             (shdr[h].sh_type == SHT_SYMTAB) )
  91.630 -        {
  91.631 -            if ( parray != NULL )
  91.632 -                xc_map_memcpy(maxva, image + shdr[h].sh_offset,
  91.633 -                              shdr[h].sh_size,
  91.634 -                              xch, dom, parray, dsi->v_start);
  91.635 -
  91.636 -            /* Mangled to be based on ELF header location. */
  91.637 -            shdr[h].sh_offset = maxva - dsi->symtab_addr;
  91.638 -
  91.639 -            dsi->symtab_len += shdr[h].sh_size;
  91.640 -            maxva += shdr[h].sh_size;
  91.641 -            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
  91.642 -        }
  91.643 -
  91.644 -        shdr[h].sh_name = 0;  /* Name is NULL. */
  91.645 -    }
  91.646 -
  91.647 -    if ( dsi->symtab_len == 0 )
  91.648 -    {
  91.649 -        dsi->symtab_addr = 0;
  91.650 -        goto out;
  91.651 -    }
  91.652 -
  91.653 -    if ( parray != NULL )
  91.654 -    {
  91.655 -        *(int *)p = maxva - dsi->symtab_addr;
  91.656 -        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
  91.657 -        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
  91.658 -        sym_ehdr->e_phoff = 0;
  91.659 -        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
  91.660 -        sym_ehdr->e_phentsize = 0;
  91.661 -        sym_ehdr->e_phnum = 0;
  91.662 -        sym_ehdr->e_shstrndx = SHN_UNDEF;
  91.663 -
  91.664 -        /* Copy total length, crafted ELF header and section header table */
  91.665 -        xc_map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
  91.666 -                   ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray,
  91.667 -                   dsi->v_start);
  91.668 -    }
  91.669 -
  91.670 -    dsi->symtab_len = maxva - dsi->symtab_addr;
  91.671 -    dsi->v_end = round_pgup(maxva);
  91.672 -
  91.673 - out:
  91.674 -    free(p);
  91.675 -
  91.676 -    return 0;
  91.677 -}
  91.678 -
  91.679 -/*
  91.680 - * Local variables:
  91.681 - * mode: C
  91.682 - * c-set-style: "BSD"
  91.683 - * c-basic-offset: 4
  91.684 - * tab-width: 4
  91.685 - * indent-tabs-mode: nil
  91.686 - * End:
  91.687 - */
    92.1 --- a/tools/libxc/xc_pagetab.c	Sun Feb 18 16:13:13 2007 -0700
    92.2 +++ b/tools/libxc/xc_pagetab.c	Tue Feb 20 12:58:22 2007 -0700
    92.3 @@ -14,7 +14,7 @@
    92.4  #define L1_PAGETABLE_SHIFT		12
    92.5  #define L2_PAGETABLE_SHIFT		22
    92.6  
    92.7 -#define L0_PAGETABLE_MASK_PAE	0x0000000ffffff000ULL
    92.8 +#define L0_PAGETABLE_MASK_PAE	0x00000ffffffff000ULL
    92.9  #define L1_PAGETABLE_MASK_PAE	0x1ffULL
   92.10  #define L2_PAGETABLE_MASK_PAE	0x1ffULL
   92.11  #define L3_PAGETABLE_MASK_PAE	0x3ULL
   92.12 @@ -33,7 +33,7 @@
   92.13  #define L1_PAGETABLE_SHIFT		L1_PAGETABLE_SHIFT_PAE
   92.14  #define L2_PAGETABLE_SHIFT		L2_PAGETABLE_SHIFT_PAE
   92.15  
   92.16 -#define L0_PAGETABLE_MASK_PAE	0x000000fffffff000ULL
   92.17 +#define L0_PAGETABLE_MASK_PAE	0x000ffffffffff000ULL
   92.18  #define L1_PAGETABLE_MASK_PAE	0x1ffULL
   92.19  #define L2_PAGETABLE_MASK_PAE	0x1ffULL
   92.20  #define L3_PAGETABLE_MASK_PAE	0x1ffULL
    93.1 --- a/tools/libxc/xc_private.c	Sun Feb 18 16:13:13 2007 -0700
    93.2 +++ b/tools/libxc/xc_private.c	Tue Feb 20 12:58:22 2007 -0700
    93.3 @@ -377,26 +377,6 @@ int xc_clear_domain_page(int xc_handle,
    93.4      return 0;
    93.5  }
    93.6  
    93.7 -void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
    93.8 -                   int xch, uint32_t dom, xen_pfn_t *parray,
    93.9 -                   unsigned long vstart)
   93.10 -{
   93.11 -    char *va;
   93.12 -    unsigned long chunksz, done, pa;
   93.13 -
   93.14 -    for ( done = 0; done < size; done += chunksz )
   93.15 -    {
   93.16 -        pa = dst + done - vstart;
   93.17 -        va = xc_map_foreign_range(
   93.18 -            xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   93.19 -        chunksz = size - done;
   93.20 -        if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   93.21 -            chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   93.22 -        memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
   93.23 -        munmap(va, PAGE_SIZE);
   93.24 -    }
   93.25 -}
   93.26 -
   93.27  int xc_domctl(int xc_handle, struct xen_domctl *domctl)
   93.28  {
   93.29      return do_domctl(xc_handle, domctl);
    94.1 --- a/tools/libxc/xg_private.h	Sun Feb 18 16:13:13 2007 -0700
    94.2 +++ b/tools/libxc/xg_private.h	Tue Feb 20 12:58:22 2007 -0700
    94.3 @@ -134,97 +134,27 @@ typedef l4_pgentry_64_t l4_pgentry_t;