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 +#ifdef CONFIG_XEN 8.49 + if (is_initial_xendomain()) { 8.50 + struct xen_memory_map memmap; 8.51 8.52 -#ifdef CONFIG_XEN 8.53 - e820_setup_gap(machine_e820.map, machine_e820.nr_map); 8.54 -#else 8.55 - e820_setup_gap(e820.map, e820.nr_map); 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 + /* 42.10 + * Since this might change the present bit (which controls whether 42.11 + * a pte_t object has undergone p2m translation), we must use 42.12 + * pte_val() on the input pte and __pte() for the return value. 42.13 + */ 42.14 + paddr_t pteval = pte_val(pte); 42.15 + 42.16 + pteval &= _PAGE_CHG_MASK; 42.17 + pteval |= pgprot_val(newprot); 42.18 #ifdef CONFIG_X86_PAE 42.19 - /* 42.20 - * Chop off the NX bit (if present), and add the NX portion of 42.21 - * the newprot (if present): 42.22 - */ 42.23 - pte.pte_high &= ~(1 << (_PAGE_BIT_NX - 32)); 42.24 - pte.pte_high |= (pgprot_val(newprot) >> 32) & \ 42.25 - (__supported_pte_mask >> 32); 42.26 + pteval &= __supported_pte_mask; 42.27 #endif 42.28 - return pte; 42.29 + return __pte(pteval); 42.30 } 42.31 42.32 #define pmd_large(pmd) \ 42.33 @@ -432,12 +433,15 @@ extern void noexec_setup(const char *str 42.34 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ 42.35 do { \ 42.36 if (__dirty) { \ 42.37 - if ( likely((__vma)->vm_mm == current->mm) ) { \ 42.38 - BUG_ON(HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned long)((__vma)->vm_mm->cpu_vm_mask.bits))); \ 42.39 - } else { \ 42.40 - xen_l1_entry_update((__ptep), (__entry)); \ 42.41 - flush_tlb_page((__vma), (__address)); \ 42.42 - } \ 42.43 + if ( likely((__vma)->vm_mm == current->mm) ) { \ 42.44 + BUG_ON(HYPERVISOR_update_va_mapping(__address, \ 42.45 + __entry, \ 42.46 + (unsigned long)(__vma)->vm_mm->cpu_vm_mask.bits| \ 42.47 + UVMF_INVLPG|UVMF_MULTI)); \ 42.48 + } else { \ 42.49 + xen_l1_entry_update(__ptep, __entry); \ 42.50 + flush_tlb_page(__vma, __address); \ 42.51 + } \ 42.52 } \ 42.53 } while (0) 42.54
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,18 +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 + struct td_state *s = dd->td_state; 53.60 + struct tdaio_state *prv = (struct tdaio_state *)dd->private; 53.61 int size = nb_sectors * s->sector_size; 53.62 uint64_t offset = sector * (uint64_t)s->sector_size; 53.63 long ioidx; 53.64 @@ -219,22 +234,24 @@ int tdaio_queue_read(struct td_state *s, 53.65 pio->cb = cb; 53.66 pio->id = id; 53.67 pio->private = private; 53.68 + pio->lsec = sector; 53.69 53.70 io_prep_pread(io, prv->fd, buf, size, offset); 53.71 io->data = (void *)ioidx; 53.72 53.73 prv->iocb_queue[prv->iocb_queued++] = io; 53.74 - 53.75 + 53.76 return 0; 53.77 } 53.78 53.79 -int tdaio_queue_write(struct td_state *s, uint64_t sector, 53.80 - int nb_sectors, char *buf, td_callback_t cb, 53.81 - int id, void *private) 53.82 +int tdaio_queue_write(struct disk_driver *dd, uint64_t sector, 53.83 + int nb_sectors, char *buf, td_callback_t cb, 53.84 + int id, void *private) 53.85 { 53.86 struct iocb *io; 53.87 struct pending_aio *pio; 53.88 - struct tdaio_state *prv = (struct tdaio_state *)s->private; 53.89 + struct td_state *s = dd->td_state; 53.90 + struct tdaio_state *prv = (struct tdaio_state *)dd->private; 53.91 int size = nb_sectors * s->sector_size; 53.92 uint64_t offset = sector * (uint64_t)s->sector_size; 53.93 long ioidx; 53.94 @@ -248,19 +265,20 @@ int tdaio_queue_write(struct td_state *s 53.95 pio->cb = cb; 53.96 pio->id = id; 53.97 pio->private = private; 53.98 + pio->lsec = sector; 53.99 53.100 io_prep_pwrite(io, prv->fd, buf, size, offset); 53.101 io->data = (void *)ioidx; 53.102 53.103 prv->iocb_queue[prv->iocb_queued++] = io; 53.104 - 53.105 + 53.106 return 0; 53.107 } 53.108 53.109 -int tdaio_submit(struct td_state *s) 53.110 +int tdaio_submit(struct disk_driver *dd) 53.111 { 53.112 int ret; 53.113 - struct tdaio_state *prv = (struct tdaio_state *)s->private; 53.114 + struct tdaio_state *prv = (struct tdaio_state *)dd->private; 53.115 53.116 ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue); 53.117 53.118 @@ -269,38 +287,24 @@ int tdaio_submit(struct td_state *s) 53.119 /* Success case: */ 53.120 prv->iocb_queued = 0; 53.121 53.122 - return ret; 53.123 + return 0; 53.124 } 53.125 53.126 -int *tdaio_get_fd(struct td_state *s) 53.127 +int tdaio_close(struct disk_driver *dd) 53.128 { 53.129 - struct tdaio_state *prv = (struct tdaio_state *)s->private; 53.130 - int *fds, i; 53.131 - 53.132 - fds = malloc(sizeof(int) * MAX_IOFD); 53.133 - /*initialise the FD array*/ 53.134 - for(i=0;i<MAX_IOFD;i++) fds[i] = 0; 53.135 - 53.136 - fds[0] = prv->poll_fd; 53.137 - 53.138 - return fds; 53.139 -} 53.140 - 53.141 -int tdaio_close(struct td_state *s) 53.142 -{ 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 io_destroy(prv->aio_ctx); 53.147 close(prv->fd); 53.148 - 53.149 + 53.150 return 0; 53.151 } 53.152 53.153 -int tdaio_do_callbacks(struct td_state *s, int sid) 53.154 +int tdaio_do_callbacks(struct disk_driver *dd, int sid) 53.155 { 53.156 int ret, i, rsp = 0; 53.157 struct io_event *ep; 53.158 - struct tdaio_state *prv = (struct tdaio_state *)s->private; 53.159 + struct tdaio_state *prv = (struct tdaio_state *)dd->private; 53.160 53.161 /* Non-blocking test for completed io. */ 53.162 ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events, 53.163 @@ -311,22 +315,34 @@ int tdaio_do_callbacks(struct td_state * 53.164 struct pending_aio *pio; 53.165 53.166 pio = &prv->pending_aio[(long)io->data]; 53.167 - rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1, 53.168 + rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1, 53.169 + pio->lsec, io->u.c.nbytes >> 9, 53.170 pio->id, pio->private); 53.171 53.172 prv->iocb_free[prv->iocb_free_count++] = io; 53.173 } 53.174 return rsp; 53.175 } 53.176 - 53.177 + 53.178 +int tdaio_has_parent(struct disk_driver *dd) 53.179 +{ 53.180 + return 0; 53.181 +} 53.182 + 53.183 +int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent) 53.184 +{ 53.185 + return -EINVAL; 53.186 +} 53.187 + 53.188 struct tap_disk tapdisk_aio = { 53.189 - "tapdisk_aio", 53.190 - sizeof(struct tdaio_state), 53.191 - tdaio_open, 53.192 - tdaio_queue_read, 53.193 - tdaio_queue_write, 53.194 - tdaio_submit, 53.195 - tdaio_get_fd, 53.196 - tdaio_close, 53.197 - tdaio_do_callbacks, 53.198 + .disk_type = "tapdisk_aio", 53.199 + .private_data_size = sizeof(struct tdaio_state), 53.200 + .td_open = tdaio_open, 53.201 + .td_queue_read = tdaio_queue_read, 53.202 + .td_queue_write = tdaio_queue_write, 53.203 + .td_submit = tdaio_submit, 53.204 + .td_has_parent = tdaio_has_parent, 53.205 + .td_get_parent = tdaio_get_parent, 53.206 + .td_close = tdaio_close, 53.207 + .td_do_callbacks = tdaio_do_callbacks, 53.208 };
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; 94.4 #define PAGE_SHIFT_X86 12 94.5 #define PAGE_SIZE_X86 (1UL << PAGE_SHIFT_X86) 94.6 #define PAGE_MASK_X86 (~(PAGE_SIZE_X86-1)) 94.7 +#if defined(__i386__) 94.8 +#define MADDR_BITS_X86 44 94.9 +#elif defined(__x86_64__) 94.10 +#define MADDR_BITS_X86 52 94.11 +#endif 94.12 +#define MFN_MASK_X86 ((1ULL << (MADDR_BITS_X86 - PAGE_SHIFT_X86)) - 1) 94.13 +#define MADDR_MASK_X86 (MFN_MASK_X86 << PAGE_SHIFT_X86) 94.14 94.15 #define PAGE_SHIFT_IA64 14 94.16 #define PAGE_SIZE_IA64 (1UL << PAGE_SHIFT_IA64) 94.17 #define PAGE_MASK_IA64 (~(PAGE_SIZE_IA64-1)) 94.18 94.19 -struct domain_setup_info 94.20 -{ 94.21 - uint64_t v_start; 94.22 - uint64_t v_end; 94.23 - uint64_t v_kernstart; 94.24 - uint64_t v_kernend; 94.25 - uint64_t v_kernentry; 94.26 - 94.27 - uint64_t elf_paddr_offset; 94.28 - 94.29 #define PAEKERN_no 0 94.30 #define PAEKERN_yes 1 94.31 #define PAEKERN_extended_cr3 2 94.32 #define PAEKERN_bimodal 3 94.33 - unsigned int pae_kernel; 94.34 - 94.35 - unsigned int load_symtab; 94.36 - unsigned long symtab_addr; 94.37 - unsigned long symtab_len; 94.38 - 94.39 - /* 94.40 - * Only o