# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1172001502 25200
# Node ID d907467f08cd4b55604961f4da4224d3ad5fe9d4
# Parent 04c23c1ef8885cf37b1c17a2f406695272ba036d
# Parent ecb6cd61a9cfa70be364aace1cb183bae03b04fd
merge with xen-unstable.hg
---
linux-2.6-xen-sparse/drivers/char/tpm/tpm.c | 1222
---------
linux-2.6-xen-sparse/include/linux/pfn.h | 9
tools/libxc/xc_linux_build.c | 1319
----------
tools/libxc/xc_load_bin.c | 306 --
tools/libxc/xc_load_elf.c | 684
-----
xen/common/elf.c | 520 ---
extras/mini-os/Makefile | 5
extras/mini-os/arch/x86/Makefile | 5
extras/mini-os/arch/x86/arch.mk | 5
extras/mini-os/minios.mk | 17
extras/mini-os/xenbus/xenbus.c | 2
linux-2.6-xen-sparse/arch/i386/kernel/Makefile | 1
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S | 4
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 38
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 30
linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c | 2
linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c | 2
linux-2.6-xen-sparse/arch/ia64/xen/util.c | 12
linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile | 1
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c | 11
linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c | 11
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S | 4
linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S | 7
linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c | 2
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 4
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 15
linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c | 3
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 26
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig | 2
linux-2.6-xen-sparse/drivers/char/tpm/tpm.h | 24
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c | 3
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 6
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c | 14
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 14
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c | 251 +
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c | 3
linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 26
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 14
linux-2.6-xen-sparse/drivers/xen/util.c | 31
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c | 16
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h | 3
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h | 17
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h | 25
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h | 53
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h | 7
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h | 27
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h | 38
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h | 3
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h | 17
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h | 15
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h | 28
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h | 62
linux-2.6-xen-sparse/include/xen/driver_util.h | 4
linux-2.6-xen-sparse/include/xen/gnttab.h | 13
patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch | 5
tools/blktap/drivers/Makefile | 16
tools/blktap/drivers/block-aio.c | 132 -
tools/blktap/drivers/block-qcow.c | 563 ++--
tools/blktap/drivers/block-ram.c | 125
tools/blktap/drivers/block-sync.c | 95
tools/blktap/drivers/block-vmdk.c | 99
tools/blktap/drivers/img2qcow.c | 28
tools/blktap/drivers/qcow2raw.c | 75
tools/blktap/drivers/tapdisk.c | 372 ++
tools/blktap/drivers/tapdisk.h | 62
tools/blktap/lib/blktaplib.h | 13
tools/blktap/lib/xs_api.c | 8
tools/check/check_zlib_lib | 4
tools/console/daemon/io.c | 8
tools/firmware/hvmloader/acpi/build.c | 81
tools/firmware/hvmloader/acpi/dsdt.asl | 8
tools/firmware/hvmloader/acpi/dsdt.c | 866
+++---
tools/firmware/rombios/32bit/Makefile | 2
tools/firmware/rombios/32bit/tcgbios/Makefile | 2
tools/ioemu/hw/tpm_tis.c | 3
tools/libfsimage/common/fsimage.c | 4
tools/libfsimage/common/fsimage.h | 2
tools/libfsimage/common/fsimage_grub.c | 4
tools/libfsimage/common/fsimage_grub.h | 2
tools/libfsimage/common/fsimage_plugin.c | 4
tools/libfsimage/common/fsimage_plugin.h | 2
tools/libfsimage/common/fsimage_priv.h | 2
tools/libfsimage/ext2fs-lib/ext2fs-lib.c | 2
tools/libfsimage/ext2fs/fsys_ext2fs.c | 2
tools/libfsimage/reiserfs/fsys_reiserfs.c | 2
tools/libfsimage/ufs/fsys_ufs.c | 2
tools/libxc/Makefile | 4
tools/libxc/xc_dom.h | 2
tools/libxc/xc_domain.c | 4
tools/libxc/xc_hvm_build.c | 9
tools/libxc/xc_linux_restore.c | 6
tools/libxc/xc_linux_save.c | 8
tools/libxc/xc_pagetab.c | 4
tools/libxc/xc_private.c | 20
tools/libxc/xg_private.h | 84
tools/pygrub/src/fsimage/fsimage.c | 14
tools/python/xen/xend/XendDomainInfo.py | 21
tools/python/xen/xend/image.py | 1
tools/security/xensec_ezpolicy | 6
tools/xcutils/readnotes.c | 138 -
xen/acm/acm_simple_type_enforcement_hooks.c | 18
xen/arch/ia64/xen/domain.c | 10
xen/arch/ia64/xen/mm.c | 4
xen/arch/x86/domain_build.c | 4
xen/arch/x86/hvm/io.c | 5
xen/arch/x86/hvm/platform.c | 31
xen/arch/x86/hvm/svm/svm.c | 32
xen/arch/x86/hvm/vlapic.c | 2
xen/arch/x86/hvm/vmx/vmx.c | 18
xen/arch/x86/mm.c | 36
xen/arch/x86/mm/shadow/common.c | 177 -
xen/arch/x86/mm/shadow/multi.c | 179 -
xen/arch/x86/mm/shadow/private.h | 17
xen/arch/x86/mm/shadow/types.h | 1
xen/arch/x86/traps.c | 29
xen/arch/x86/x86_32/seg_fixup.c | 5
xen/common/compat/grant_table.c | 3
xen/common/grant_table.c | 502 ++-
xen/common/libelf/libelf-dominfo.c | 119
xen/common/libelf/libelf-tools.c | 11
xen/include/asm-ia64/bug.h | 6
xen/include/asm-ia64/grant_table.h | 43
xen/include/asm-powerpc/bug.h | 6
xen/include/asm-powerpc/grant_table.h | 2
xen/include/asm-x86/bug.h | 13
xen/include/asm-x86/grant_table.h | 6
xen/include/asm-x86/hvm/io.h | 1
xen/include/asm-x86/processor.h | 5
xen/include/asm-x86/x86_32/bug.h | 19
xen/include/asm-x86/x86_64/bug.h | 19
xen/include/asm-x86/x86_64/page.h | 14
xen/include/public/arch-ia64.h | 2
xen/include/public/arch-powerpc.h | 2
xen/include/public/arch-x86/xen.h | 2
xen/include/public/elfnote.h | 8
xen/include/public/grant_table.h | 19
xen/include/public/hvm/save.h | 13
xen/include/public/libelf.h | 3
xen/include/xen/grant_table.h | 38
xen/include/xen/lib.h | 5
xen/include/xen/sched.h | 9
141 files changed, 3077 insertions(+), 6260 deletions(-)
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/Makefile Tue Feb 20 12:58:22 2007 -0700
@@ -44,10 +44,6 @@ ARCH_LINKS =
# This can be overwritten from arch specific rules.
EXTRA_INC =
-# Special build dependencies.
-# Build all after touching this/these file(s) (see minios.mk)
-SPEC_DEPENDS = minios.mk
-
# Include the architecture family's special makerules.
# This must be before include minios.mk!
include $(TARGET_ARCH_DIR)/arch.mk
@@ -57,7 +53,6 @@ include minios.mk
# Define some default flags for linking.
LDLIBS :=
-LDFLAGS :=
LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/arch/x86/Makefile
--- a/extras/mini-os/arch/x86/Makefile Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/arch/x86/Makefile Tue Feb 20 12:58:22 2007 -0700
@@ -2,9 +2,6 @@
# x86 architecture specific makefiles.
# It's is used for x86_32, x86_32y and x86_64
#
-
-# Rebuild all after touching this/these extra file(s) (see mini-os.mk)
-SPEC_DEP = arch.mk
# include arch.mk has to be before mini-os.mk!
include arch.mk
@@ -25,5 +22,5 @@ all: $(ARCH_LIB)
$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
clean:
- rm -f $(ARCH_LIB) $(ARCH_OBJS)
+ rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/arch/x86/arch.mk
--- a/extras/mini-os/arch/x86/arch.mk Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/arch/x86/arch.mk Tue Feb 20 12:58:22 2007 -0700
@@ -6,6 +6,7 @@ ifeq ($(TARGET_ARCH),x86_32)
ifeq ($(TARGET_ARCH),x86_32)
ARCH_CFLAGS := -m32 -march=i686
ARCH_LDFLAGS := -m elf_i386
+ARCH_ASFLAGS := -m32
EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
EXTRA_SRC += arch/$(EXTRA_INC)
endif
@@ -19,10 +20,10 @@ endif
ifeq ($(TARGET_ARCH),x86_64)
ARCH_CFLAGS := -m64 -mno-red-zone -fpic -fno-reorder-blocks
-ARCH_CFLAGS := -fno-asynchronous-unwind-tables
+ARCH_CFLAGS += -fno-asynchronous-unwind-tables
+ARCH_ASFLAGS := -m64
ARCH_LDFLAGS := -m elf_x86_64
EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
EXTRA_SRC += arch/$(EXTRA_INC)
endif
-
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/minios.mk
--- a/extras/mini-os/minios.mk Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/minios.mk Tue Feb 20 12:58:22 2007 -0700
@@ -11,6 +11,7 @@ DEF_CFLAGS += -D__XEN_INTERFACE_VERSION_
DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
DEF_ASFLAGS = -D__ASSEMBLY__
+DEF_LDFLAGS =
ifeq ($(debug),y)
DEF_CFLAGS += -g
@@ -23,21 +24,27 @@ endif
# ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
+LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
# The path pointing to the architecture specific header files.
-ARCH_SPEC_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
+ARCH_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
+
+# Special build dependencies.
+# Rebuild all after touching this/these file(s)
+EXTRA_DEPS = $(MINI-OS_ROOT)/minios.mk \
+ $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk
# Find all header files for checking dependencies.
HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h)
HDRS += $(wildcard $(MINI-OS_ROOT)/include/xen/*.h)
-HDRS += $(wildcard $(ARCH_SPEC_INC)/*.h)
+HDRS += $(wildcard $(ARCH_INC)/*.h)
# For special wanted header directories.
extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
HDRS += $(extra_heads)
# Add the special header directories to the include paths.
extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
-override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_SPEC_INC)
$(extra_incl)
+override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_INC)
$(extra_incl)
# The name of the architecture specific library.
# This is on x86_32: libx86_32.a
@@ -51,10 +58,10 @@ HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_AR
HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
-%.o: %.c $(HDRS) Makefile $(SPEC_DEPENDS)
+%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
-%.o: %.S $(HDRS) Makefile $(SPEC_DEPENDS)
+%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
$(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/xenbus/xenbus.c Tue Feb 20 12:58:22 2007 -0700
@@ -210,7 +210,7 @@ static int allocate_xenbus_id(void)
}
nr_live_reqs++;
req_info[o_probe].in_use = 1;
- probe = o_probe + 1;
+ probe = (o_probe + 1) % NR_REQS;
spin_unlock(&req_lock);
init_waitqueue_head(&req_info[o_probe].waitq);
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/i386/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile Tue Feb 20 12:58:22
2007 -0700
@@ -98,4 +98,5 @@ obj-y := $(call filterxen, $(obj-y), $(n
obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
obj-y := $(call cherrypickxen, $(obj-y))
extra-y := $(call cherrypickxen, $(extra-y))
+%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
endif
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Tue Feb 20 12:58:22
2007 -0700
@@ -11,6 +11,8 @@
#include <asm/asm-offsets.h>
#include <xen/interface/xen.h>
#include <xen/interface/elfnote.h>
+
+#define _PAGE_PRESENT 0x1
/*
* References to members of the new_cpu_data structure.
@@ -198,7 +200,9 @@ ENTRY(cpu_gdt_table)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz,
"writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
#ifdef CONFIG_X86_PAE
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
+ ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .quad,
_PAGE_PRESENT,_PAGE_PRESENT)
#else
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no")
+ ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long,
_PAGE_PRESENT,_PAGE_PRESENT)
#endif
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Tue Feb 20 12:58:22
2007 -0700
@@ -1034,8 +1034,16 @@ e820_all_mapped(unsigned long s, unsigne
u64 start = s;
u64 end = e;
int i;
+
+#ifndef CONFIG_XEN
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
+#else
+ if (!is_initial_xendomain())
+ return 0;
+ for (i = 0; i < machine_e820.nr_map; ++i) {
+ const struct e820entry *ei = &machine_e820.map[i];
+#endif
if (type && ei->type != type)
continue;
/* is the region (part) in overlap with the current region ?*/
@@ -1505,9 +1513,6 @@ e820_setup_gap(struct e820entry *e820, i
*/
static int __init request_standard_resources(void)
{
-#ifdef CONFIG_XEN
- struct xen_memory_map memmap;
-#endif
int i;
/* Nothing to do if not running in dom0. */
@@ -1516,13 +1521,6 @@ static int __init request_standard_resou
printk("Setting up standard PCI resources\n");
#ifdef CONFIG_XEN
- memmap.nr_entries = E820MAX;
- set_xen_guest_handle(memmap.buffer, machine_e820.map);
-
- if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
- BUG();
- machine_e820.nr_map = memmap.nr_entries;
-
legacy_init_iomem_resources(machine_e820.map, machine_e820.nr_map,
&code_resource, &data_resource);
#else
@@ -1546,12 +1544,22 @@ subsys_initcall(request_standard_resourc
static void __init register_memory(void)
{
-
#ifdef CONFIG_XEN
- e820_setup_gap(machine_e820.map, machine_e820.nr_map);
-#else
- e820_setup_gap(e820.map, e820.nr_map);
-#endif
+ if (is_initial_xendomain()) {
+ struct xen_memory_map memmap;
+
+ memmap.nr_entries = E820MAX;
+ set_xen_guest_handle(memmap.buffer, machine_e820.map);
+
+ if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
+ BUG();
+
+ machine_e820.nr_map = memmap.nr_entries;
+ e820_setup_gap(machine_e820.map, machine_e820.nr_map);
+ }
+ else
+#endif
+ e820_setup_gap(e820.map, e820.nr_map);
}
#ifdef CONFIG_MCA
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Tue Feb 20 12:58:22
2007 -0700
@@ -222,8 +222,7 @@ void init_cpu_khz(void)
void init_cpu_khz(void)
{
u64 __cpu_khz = 1000000ULL << 32;
- struct vcpu_time_info *info;
- info = &HYPERVISOR_shared_info->vcpu_info[0].time;
+ struct vcpu_time_info *info = &vcpu_info(0)->time;
do_div(__cpu_khz, info->tsc_to_system_mul);
if (info->tsc_shift < 0)
cpu_khz = __cpu_khz << -info->tsc_shift;
@@ -293,14 +292,13 @@ static void update_wallclock(void)
* Reads a consistent set of time-base values from Xen, into a shadow data
* area.
*/
-static void get_time_values_from_xen(void)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
+static void get_time_values_from_xen(int cpu)
+{
struct vcpu_time_info *src;
struct shadow_time_info *dst;
- src = &s->vcpu_info[smp_processor_id()].time;
- dst = &per_cpu(shadow_time, smp_processor_id());
+ src = &vcpu_info(cpu)->time;
+ dst = &per_cpu(shadow_time, cpu);
do {
dst->version = src->version;
@@ -320,7 +318,7 @@ static inline int time_values_up_to_date
struct vcpu_time_info *src;
struct shadow_time_info *dst;
- src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
+ src = &vcpu_info(cpu)->time;
dst = &per_cpu(shadow_time, cpu);
rmb();
@@ -412,7 +410,7 @@ void do_gettimeofday(struct timeval *tv)
* overflowed). Detect that and recalculate
* with fresh values.
*/
- get_time_values_from_xen();
+ get_time_values_from_xen(cpu);
continue;
}
} while (read_seqretry(&xtime_lock, seq) ||
@@ -456,7 +454,7 @@ int do_settimeofday(struct timespec *tv)
nsec = tv->tv_nsec - get_nsec_offset(shadow);
if (time_values_up_to_date(cpu))
break;
- get_time_values_from_xen();
+ get_time_values_from_xen(cpu);
}
sec = tv->tv_sec;
__normalize_time(&sec, &nsec);
@@ -551,7 +549,7 @@ unsigned long long monotonic_clock(void)
barrier();
time = shadow->system_timestamp + get_nsec_offset(shadow);
if (!time_values_up_to_date(cpu))
- get_time_values_from_xen();
+ get_time_values_from_xen(cpu);
barrier();
} while (local_time_version != shadow->version);
@@ -621,7 +619,7 @@ irqreturn_t timer_interrupt(int irq, voi
write_seqlock(&xtime_lock);
do {
- get_time_values_from_xen();
+ get_time_values_from_xen(cpu);
/* Obtain a consistent snapshot of elapsed wallclock cycles. */
delta = delta_cpu =
@@ -708,7 +706,7 @@ irqreturn_t timer_interrupt(int irq, voi
if (delta_cpu > 0) {
do_div(delta_cpu, NS_PER_TICK);
per_cpu(processed_system_time, cpu) += delta_cpu * NS_PER_TICK;
- if (user_mode(regs))
+ if (user_mode_vm(regs))
account_user_time(current, (cputime_t)delta_cpu);
else
account_system_time(current, HARDIRQ_OFFSET,
@@ -722,7 +720,7 @@ irqreturn_t timer_interrupt(int irq, voi
/* Local timer processing (see update_process_times()). */
run_local_timers();
if (rcu_pending(cpu))
- rcu_check_callbacks(cpu, user_mode(regs));
+ rcu_check_callbacks(cpu, user_mode_vm(regs));
scheduler_tick();
run_posix_cpu_timers(current);
profile_tick(CPU_PROFILING, regs);
@@ -921,7 +919,7 @@ void __init time_init(void)
return;
}
#endif
- get_time_values_from_xen();
+ get_time_values_from_xen(0);
processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
per_cpu(processed_system_time, 0) = processed_system_time;
@@ -1029,7 +1027,7 @@ void time_resume(void)
{
init_cpu_khz();
- get_time_values_from_xen();
+ get_time_values_from_xen(0);
processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
per_cpu(processed_system_time, 0) = processed_system_time;
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c
--- a/linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c Tue Feb 20 12:58:22
2007 -0700
@@ -67,7 +67,7 @@ char * __init machine_specific_memory_se
if ( rc == -ENOSYS ) {
memmap.nr_entries = 1;
map[0].addr = 0ULL;
- map[0].size = PFN_PHYS(xen_start_info->nr_pages);
+ map[0].size = PFN_PHYS((unsigned long
long)xen_start_info->nr_pages);
/* 8MB slack (to balance backend allocations). */
map[0].size += 8ULL << 20;
map[0].type = E820_RAM;
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c Tue Feb 20 12:58:22
2007 -0700
@@ -731,7 +731,7 @@ do_sigbus:
force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
}
-#ifndef CONFIG_X86_PAE
+#if !HAVE_SHARED_KERNEL_PMD
void vmalloc_sync_all(void)
{
/*
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/arch/ia64/xen/util.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/util.c Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/util.c Tue Feb 20 12:58:22 2007 -0700
@@ -95,18 +95,6 @@ void free_vm_area(struct vm_struct *area
}
EXPORT_SYMBOL_GPL(free_vm_area);
-void lock_vm_area(struct vm_struct *area)
-{
- // nothing
-}
-EXPORT_SYMBOL_GPL(lock_vm_area);
-
-void unlock_vm_area(struct vm_struct *area)
-{
- // nothing
-}
-EXPORT_SYMBOL_GPL(unlock_vm_area);
-
/*
* Local variables:
* c-file-style: "linux"
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile Tue Feb 20 12:58:22
2007 -0700
@@ -72,4 +72,5 @@ obj-y := $(call filterxen, $(obj-y), $(n
obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
obj-y := $(call cherrypickxen, $(obj-y))
extra-y := $(call cherrypickxen, $(extra-y))
+%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
endif
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Tue Feb 20
12:58:22 2007 -0700
@@ -127,8 +127,19 @@ int __init e820_all_mapped(unsigned long
int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned
type)
{
int i;
+
+#ifndef CONFIG_XEN
for (i = 0; i < e820.nr_map; i++) {
struct e820entry *ei = &e820.map[i];
+#else
+ extern struct e820map machine_e820;
+
+ if (!is_initial_xendomain())
+ return 0;
+ for (i = 0; i < machine_e820.nr_map; i++) {
+ const struct e820entry *ei = &machine_e820.map[i];
+#endif
+
if (type && ei->type != type)
continue;
/* is the region (part) in overlap with the current region ?*/
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c Tue Feb
20 12:58:22 2007 -0700
@@ -18,9 +18,8 @@
#define VGABASE ((void __iomem *)0xffffffff800b8000UL)
#endif
+#ifndef CONFIG_XEN
static int max_ypos = 25, max_xpos = 80;
-
-#ifndef CONFIG_XEN
static int current_ypos = 25, current_xpos = 0;
static void early_vga_write(struct console *con, const char *str, unsigned n)
@@ -154,10 +153,6 @@ static __init void early_serial_init(cha
#else /* CONFIG_XEN */
-#undef SCREEN_INFO
-#define SCREEN_INFO screen_info
-extern struct screen_info screen_info;
-
static void
early_serial_write(struct console *con, const char *s, unsigned count)
{
@@ -273,11 +268,13 @@ int __init setup_early_printk(char *opt)
early_serial_init(buf);
early_console = &early_serial_console;
} else if (!strncmp(buf, "vga", 3)
+#ifndef CONFIG_XEN
&& SCREEN_INFO.orig_video_isVGA == 1) {
max_xpos = SCREEN_INFO.orig_video_cols;
max_ypos = SCREEN_INFO.orig_video_lines;
-#ifndef CONFIG_XEN
current_ypos = SCREEN_INFO.orig_y;
+#else
+ || !strncmp(buf, "xen", 3)) {
#endif
early_console = &early_vga_console;
} else if (!strncmp(buf, "simnow", 6)) {
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Tue Feb 20
12:58:22 2007 -0700
@@ -32,9 +32,6 @@
*/
#define ASSEMBLY 1
-#ifdef CONFIG_DEBUG_INFO
-#undef CONFIG_DEBUG_INFO
-#endif
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/smp.h>
@@ -537,6 +534,7 @@ END(stub_rt_sigreturn)
*/
retint_check:
+ CFI_DEFAULT_STACK
movl threadinfo_flags(%rcx),%edx
andl %edi,%edx
CFI_REMEMBER_STATE
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Tue Feb 20
12:58:22 2007 -0700
@@ -25,7 +25,9 @@
#include <xen/interface/elfnote.h>
- .text
+#define _PAGE_PRESENT 0x1
+
+ .section .bootstrap.text, "ax", @progbits
.code64
#define VIRT_ENTRY_OFFSET 0x0
.org VIRT_ENTRY_OFFSET
@@ -49,7 +51,7 @@ ENTRY(_stext)
#define NEXT_PAGE(name) \
$page = $page + 1; \
.org $page * 0x1000; \
- phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \
+ phys_##name = $page * 0x1000 + __PHYSICAL_START; \
ENTRY(name)
NEXT_PAGE(init_level4_pgt)
@@ -181,5 +183,6 @@ ENTRY(empty_zero_page)
#endif /* !CONFIG_XEN_COMPAT_030002 */
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .quad, startup_64)
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad, hypercall_page)
+ ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .quad,
_PAGE_PRESENT,_PAGE_PRESENT)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz,
"writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c Tue Feb 20
12:58:22 2007 -0700
@@ -170,7 +170,7 @@ static void __cpuinit MP_processor_info
cpu_set(cpu, cpu_present_map);
}
#else
-void __init MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
{
num_processors++;
}
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c Tue Feb 20
12:58:22 2007 -0700
@@ -499,8 +499,6 @@ __switch_to(struct task_struct *prev_p,
* This is basically '__unlazy_fpu', except that we queue a
* multicall to indicate FPU task switch, rather than
* synchronously trapping to Xen.
- * This must be here to ensure both math_state_restore() and
- * kernel_fpu_begin() work consistently.
* The AMD workaround requires it to be after DS reload, or
* after DS has been cleared, which we do in __prepare_arch_switch.
*/
@@ -579,7 +577,7 @@ __switch_to(struct task_struct *prev_p,
HYPERVISOR_set_segment_base(SEGBASE_GS_USER, next->gs);
/*
- * Switch the PDA and FPU contexts.
+ * Switch the PDA context.
*/
prev->userrsp = read_pda(oldrsp);
write_pda(oldrsp, next->userrsp);
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Tue Feb 20
12:58:22 2007 -0700
@@ -90,9 +90,6 @@ extern char hypercall_page[PAGE_SIZE];
extern char hypercall_page[PAGE_SIZE];
EXPORT_SYMBOL(hypercall_page);
-/* Allows setting of maximum possible memory size */
-unsigned long xen_override_max_pfn;
-
static int xen_panic_event(struct notifier_block *, unsigned long, void *);
static struct notifier_block xen_panic_block = {
xen_panic_event, NULL, 0 /* try to go last */
@@ -580,13 +577,13 @@ static void discover_ebda(void)
if (ebda_size > 64*1024)
ebda_size = 64*1024;
}
+#else
+#define discover_ebda() ((void)0)
#endif
void __init setup_arch(char **cmdline_p)
{
#ifdef CONFIG_XEN
- struct xen_memory_map memmap;
-
/* Register a call for panic conditions. */
atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
@@ -675,9 +672,7 @@ void __init setup_arch(char **cmdline_p)
check_efer();
-#ifndef CONFIG_XEN
discover_ebda();
-#endif
init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
@@ -719,7 +714,6 @@ void __init setup_arch(char **cmdline_p)
/* reserve ebda region */
if (ebda_addr)
reserve_bootmem_generic(ebda_addr, ebda_size);
-#endif
#ifdef CONFIG_SMP
/*
@@ -731,6 +725,7 @@ void __init setup_arch(char **cmdline_p)
/* Reserve SMP trampoline */
reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE);
+#endif
#endif
#ifdef CONFIG_ACPI_SLEEP
@@ -895,6 +890,8 @@ void __init setup_arch(char **cmdline_p)
probe_roms();
#ifdef CONFIG_XEN
if (is_initial_xendomain()) {
+ struct xen_memory_map memmap;
+
memmap.nr_entries = E820MAX;
set_xen_guest_handle(memmap.buffer, machine_e820.map);
@@ -1378,9 +1375,7 @@ void __cpuinit identify_cpu(struct cpuin
c->x86_capability[2] = cpuid_edx(0x80860001);
}
-#ifdef CONFIG_X86_XEN_GENAPIC
c->apicid = phys_pkg_id(0);
-#endif
/*
* Vendor-specific initialization. In this section we
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c Tue Feb 20 12:58:22
2007 -0700
@@ -411,8 +411,7 @@ asmlinkage void __kprobes do_page_fault(
prefetchw(&mm->mmap_sem);
/* get the address */
- address = HYPERVISOR_shared_info->vcpu_info[
- smp_processor_id()].arch.cr2;
+ address = current_vcpu_info()->arch.cr2;
info.si_code = SEGV_MAPERR;
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Tue Feb 20 12:58:22
2007 -0700
@@ -77,7 +77,7 @@ extern unsigned long start_pfn;
(((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) + \
__START_KERNEL_map)))
-static void early_make_page_readonly(void *va, unsigned int feature)
+static void __meminit early_make_page_readonly(void *va, unsigned int feature)
{
unsigned long addr, _va = (unsigned long)va;
pte_t pte, *ptep;
@@ -279,8 +279,8 @@ static __init void set_pte_phys(unsigned
__flush_tlb_one(vaddr);
}
-static void set_pte_phys_ma(unsigned long vaddr,
- unsigned long phys, pgprot_t prot)
+static __init void set_pte_phys_ma(unsigned long vaddr,
+ unsigned long phys, pgprot_t prot)
{
pgd_t *pgd;
pud_t *pud;
@@ -361,9 +361,10 @@ __set_fixmap (enum fixed_addresses idx,
}
/*
- * At this point it only supports vsyscall area.
+ * This only supports vsyscall area.
*/
-void __set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t
prot)
+void __init
+__set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
{
unsigned long address = __fix_to_virt(idx);
@@ -376,15 +377,6 @@ void __set_fixmap_user (enum fixed_addre
}
unsigned long __initdata table_start, table_end;
-
-unsigned long get_machine_pfn(unsigned long addr)
-{
- pud_t* pud = pud_offset_k(NULL, addr);
- pmd_t* pmd = pmd_offset(pud, addr);
- pte_t *pte = pte_offset_kernel(pmd, addr);
-
- return pte_mfn(*pte);
-}
static __meminit void *alloc_static_page(unsigned long *phys)
{
@@ -531,10 +523,6 @@ void __init xen_init_pt(void)
{
unsigned long addr, *page;
- memset((void *)init_level4_pgt, 0, PAGE_SIZE);
- memset((void *)level3_kernel_pgt, 0, PAGE_SIZE);
- memset((void *)level2_kernel_pgt, 0, PAGE_SIZE);
-
/* Find the initial pte page that was built for us. */
page = (unsigned long *)xen_start_info->pt_base;
addr = page[pgd_index(__START_KERNEL_map)];
@@ -595,7 +583,7 @@ void __init xen_init_pt(void)
mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
}
-void __init extend_init_mapping(unsigned long tables_space)
+static void __init extend_init_mapping(unsigned long tables_space)
{
unsigned long va = __START_KERNEL_map;
unsigned long phys, addr, *pte_page;
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig Tue Feb 20 12:58:22
2007 -0700
@@ -22,7 +22,7 @@ config TCG_TPM
config TCG_TIS
tristate "TPM Interface Specification 1.2 Interface"
- depends on TCG_TPM
+ depends on TCG_TPM && PNPACPI
---help---
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification say Yes and it will be accessible
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c Sun Feb 18 16:13:13
2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1222 +0,0 @@
-/*
- * Copyright (C) 2004 IBM Corporation
- *
- * Authors:
- * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
- * Dave Safford <safford@xxxxxxxxxxxxxx>
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- * Kylene Hall <kjhall@xxxxxxxxxx>
- *
- * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
- *
- * Device driver for TCG/TCPA TPM (trusted platform module).
- * Specifications at www.trustedcomputinggroup.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- * Note, the TPM chip is not interrupt driven (only polling)
- * and can have very long timeouts (minutes!). Hence the unusual
- * calls to msleep.
- *
- */
-
-#include <linux/sched.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include "tpm.h"
-
-enum tpm_const {
- TPM_MINOR = 224, /* officially assigned */
-#ifndef CONFIG_XEN
- TPM_BUFSIZE = 2048,
-#endif
- TPM_NUM_DEVICES = 256,
-};
-
-enum tpm_duration {
- TPM_SHORT = 0,
- TPM_MEDIUM = 1,
- TPM_LONG = 2,
- TPM_UNDEFINED,
-};
-
-#define TPM_MAX_ORDINAL 243
-#define TPM_MAX_PROTECTED_ORDINAL 12
-#define TPM_PROTECTED_ORDINAL_MASK 0xFF
-
-static LIST_HEAD(tpm_chip_list);
-static DEFINE_SPINLOCK(driver_lock);
-static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
-
-/*
- * Array with one entry per ordinal defining the maximum amount
- * of time the chip could take to return the result. The ordinal
- * designation of short, medium or long is defined in a table in
- * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
- * values of the SHORT, MEDIUM, and LONG durations are retrieved
- * from the chip during initialization with a call to tpm_get_timeouts.
- */
-static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
- TPM_UNDEFINED, /* 0 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 5 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 10 */
- TPM_SHORT,
-};
-
-static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
- TPM_UNDEFINED, /* 0 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 5 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 10 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_LONG,
- TPM_MEDIUM, /* 15 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_SHORT, /* 20 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT, /* 25 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 30 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 35 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 40 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 45 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_LONG,
- TPM_MEDIUM, /* 50 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 55 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 60 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 65 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 70 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 75 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 80 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_SHORT,
- TPM_UNDEFINED, /* 85 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 90 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 95 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 100 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 105 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 110 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 115 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 120 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 125 */
- TPM_SHORT,
- TPM_LONG,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 130 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_UNDEFINED, /* 135 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 140 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 145 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 150 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 155 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 160 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 165 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 170 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 175 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 180 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM, /* 185 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 190 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 195 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 200 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 205 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 210 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_UNDEFINED, /* 215 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 220 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 225 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 230 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 235 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 240 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
-};
-
-static void user_reader_timeout(unsigned long ptr)
-{
- struct tpm_chip *chip = (struct tpm_chip *) ptr;
-
- schedule_work(&chip->work);
-}
-
-static void timeout_work(void *ptr)
-{
- struct tpm_chip *chip = ptr;
-
- down(&chip->buffer_mutex);
- atomic_set(&chip->data_pending, 0);
-#ifndef CONFIG_XEN
- memset(chip->data_buffer, 0, TPM_BUFSIZE);
-#else
- memset(chip->data_buffer, 0, get_chip_buffersize(chip));
-#endif
- up(&chip->buffer_mutex);
-}
-
-/*
- * Returns max number of jiffies to wait
- */
-unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
- u32 ordinal)
-{
- int duration_idx = TPM_UNDEFINED;
- int duration = 0;
-
- if (ordinal < TPM_MAX_ORDINAL)
- duration_idx = tpm_ordinal_duration[ordinal];
- else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
- TPM_MAX_PROTECTED_ORDINAL)
- duration_idx =
- tpm_protected_ordinal_duration[ordinal &
- TPM_PROTECTED_ORDINAL_MASK];
-
- if (duration_idx != TPM_UNDEFINED)
- duration = chip->vendor.duration[duration_idx];
- if (duration <= 0)
- return 2 * 60 * HZ;
- else
- return duration;
-}
-EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
-
-/*
- * Internal kernel interface to transmit TPM commands
- */
-static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
- size_t bufsiz)
-{
- ssize_t rc;
- u32 count, ordinal;
- unsigned long stop;
-
- count = be32_to_cpu(*((__be32 *) (buf + 2)));
- ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
- if (count == 0)
- return -ENODATA;
- if (count > bufsiz) {
- dev_err(chip->dev,
- "invalid count value %x %zx \n", count, bufsiz);
- return -E2BIG;
- }
-
- down(&chip->tpm_mutex);
-
- if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
- dev_err(chip->dev,
- "tpm_transmit: tpm_send: error %zd\n", rc);
- goto out;
- }
-
- if (chip->vendor.irq)
- goto out_recv;
-
- stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
- do {
- u8 status = chip->vendor.status(chip);
- if ((status & chip->vendor.req_complete_mask) ==
- chip->vendor.req_complete_val)
- goto out_recv;
-
- if ((status == chip->vendor.req_canceled)) {
- dev_err(chip->dev, "Operation Canceled\n");
- rc = -ECANCELED;
- goto out;
- }
-
- msleep(TPM_TIMEOUT); /* CHECK */
- rmb();
- } while (time_before(jiffies, stop));
-
- chip->vendor.cancel(chip);
- dev_err(chip->dev, "Operation Timed out\n");
- rc = -ETIME;
- goto out;
-
-out_recv:
- rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
- if (rc < 0)
- dev_err(chip->dev,
- "tpm_transmit: tpm_recv: error %zd\n", rc);
-out:
- up(&chip->tpm_mutex);
- return rc;
-}
-
-#define TPM_DIGEST_SIZE 20
-#define TPM_ERROR_SIZE 10
-#define TPM_RET_CODE_IDX 6
-#define TPM_GET_CAP_RET_SIZE_IDX 10
-#define TPM_GET_CAP_RET_UINT32_1_IDX 14
-#define TPM_GET_CAP_RET_UINT32_2_IDX 18
-#define TPM_GET_CAP_RET_UINT32_3_IDX 22
-#define TPM_GET_CAP_RET_UINT32_4_IDX 26
-#define TPM_GET_CAP_PERM_DISABLE_IDX 16
-#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
-#define TPM_GET_CAP_RET_BOOL_1_IDX 14
-#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
-
-#define TPM_CAP_IDX 13
-#define TPM_CAP_SUBCAP_IDX 21
-
-enum tpm_capabilities {
- TPM_CAP_FLAG = 4,
- TPM_CAP_PROP = 5,
-};
-
-enum tpm_sub_capabilities {
- TPM_CAP_PROP_PCR = 0x1,
- TPM_CAP_PROP_MANUFACTURER = 0x3,
- TPM_CAP_FLAG_PERM = 0x8,
- TPM_CAP_FLAG_VOL = 0x9,
- TPM_CAP_PROP_OWNER = 0x11,
- TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
- TPM_CAP_PROP_TIS_DURATION = 0x20,
-};
-
-/*
- * This is a semi generic GetCapability command for use
- * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
- * and their associated sub_capabilities.
- */
-
-static const u8 tpm_cap[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 22, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 0, /* TPM_CAP_<TYPE> */
- 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */
- 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
-};
-
-static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
- char *desc)
-{
- int err;
-
- len = tpm_transmit(chip, data, len);
- if (len < 0)
- return len;
- if (len == TPM_ERROR_SIZE) {
- err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
- dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
- return err;
- }
- return 0;
-}
-
-void tpm_gen_interrupt(struct tpm_chip *chip)
-{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
- ssize_t rc;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the timeouts");
-}
-EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
-
-void tpm_get_timeouts(struct tpm_chip *chip)
-{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
- ssize_t rc;
- u32 timeout;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the timeouts");
- if (rc)
- goto duration;
-
- if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
- != 4 * sizeof(u32))
- goto duration;
-
- /* Don't overwrite default if value is 0 */
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
- if (timeout)
- chip->vendor.timeout_a = msecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
- if (timeout)
- chip->vendor.timeout_b = msecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
- if (timeout)
- chip->vendor.timeout_c = msecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
- if (timeout)
- chip->vendor.timeout_d = msecs_to_jiffies(timeout);
-
-duration:
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the durations");
- if (rc)
- return;
-
- if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
- != 3 * sizeof(u32))
- return;
-
- chip->vendor.duration[TPM_SHORT] =
- msecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_1_IDX))));
- chip->vendor.duration[TPM_MEDIUM] =
- msecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_2_IDX))));
- chip->vendor.duration[TPM_LONG] =
- msecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_3_IDX))));
-}
-EXPORT_SYMBOL_GPL(tpm_get_timeouts);
-
-void tpm_continue_selftest(struct tpm_chip *chip)
-{
- u8 data[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 10, /* length */
- 0, 0, 0, 83, /* TPM_ORD_GetCapability */
- };
-
- tpm_transmit(chip, data, sizeof(data));
-}
-EXPORT_SYMBOL_GPL(tpm_continue_selftest);
-
-ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
- char *buf)
-{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
- ssize_t rc;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attemtping to determine the permanent state");
- if (rc)
- return 0;
- return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_enabled);
-
-ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
- char *buf)
-{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
- ssize_t rc;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attemtping to determine the permanent state");
- if (rc)
- return 0;
- return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_active);
-
-ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
- char *buf)
-{
- u8 data[sizeof(tpm_cap)];
- ssize_t rc;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the owner state");
- if (rc)
- return 0;
- return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_owned);
-
-ssize_t tpm_show_temp_deactivated(struct device * dev,
- struct device_attribute * attr, char *buf)
-{
- u8 data[sizeof(tpm_cap)];
- ssize_t rc;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the temporary state");
- if (rc)
- return 0;
- return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
-
-static const u8 pcrread[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 14, /* length */
- 0, 0, 0, 21, /* TPM_ORD_PcrRead */
- 0, 0, 0, 0 /* PCR index */
-};
-
-ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
- ssize_t rc;
- int i, j, num_pcrs;
- __be32 index;
- char *str = buf;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the number of PCRS");
- if (rc)
- return 0;
-
- num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
- for (i = 0; i < num_pcrs; i++) {
- memcpy(data, pcrread, sizeof(pcrread));
- index = cpu_to_be32(i);
- memcpy(data + 10, &index, 4);
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to read a PCR");
- if (rc)
- goto out;
- str += sprintf(str, "PCR-%02d: ", i);
- for (j = 0; j < TPM_DIGEST_SIZE; j++)
- str += sprintf(str, "%02X ", *(data + 10 + j));
- str += sprintf(str, "\n");
- }
-out:
- return str - buf;
-}
-EXPORT_SYMBOL_GPL(tpm_show_pcrs);
-
-#define READ_PUBEK_RESULT_SIZE 314
-static const u8 readpubek[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 30, /* length */
- 0, 0, 0, 124, /* TPM_ORD_ReadPubek */
-};
-
-ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- u8 *data;
- ssize_t err;
- int i, rc;
- char *str = buf;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, readpubek, sizeof(readpubek));
-
- err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
- "attempting to read the PUBEK");
- if (err)
- goto out;
-
- /*
- ignore header 10 bytes
- algorithm 32 bits (1 == RSA )
- encscheme 16 bits
- sigscheme 16 bits
- parameters (RSA 12->bytes: keybit, #primes, expbit)
- keylenbytes 32 bits
- 256 byte modulus
- ignore checksum 20 bytes
- */
-
- str +=
- sprintf(str,
- "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
- "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
- " %02X %02X %02X %02X %02X %02X %02X %02X\n"
- "Modulus length: %d\nModulus: \n",
- data[10], data[11], data[12], data[13], data[14],
- data[15], data[16], data[17], data[22], data[23],
- data[24], data[25], data[26], data[27], data[28],
- data[29], data[30], data[31], data[32], data[33],
- be32_to_cpu(*((__be32 *) (data + 34))));
-
- for (i = 0; i < 256; i++) {
- str += sprintf(str, "%02X ", data[i + 38]);
- if ((i + 1) % 16 == 0)
- str += sprintf(str, "\n");
- }
-out:
- rc = str - buf;
- kfree(data);
- return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_show_pubek);
-
-#define CAP_VERSION_1_1 6
-#define CAP_VERSION_1_2 0x1A
-#define CAP_VERSION_IDX 13
-static const u8 cap_version[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 18, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
-
-ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)),
30)];
- ssize_t rc;
- char *str = buf;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the manufacturer");
- if (rc)
- return 0;
-
- str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data +
TPM_GET_CAP_RET_UINT32_1_IDX))));
-
- memcpy(data, cap_version, sizeof(cap_version));
- data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
- rc = transmit_cmd(chip, data, sizeof(data),
- "attempting to determine the 1.1 version");
- if (rc)
- goto out;
-
- str += sprintf(str,
- "TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[14], (int) data[15], (int) data[16],
- (int) data[17]);
-
-out:
- return str - buf;
-}
-EXPORT_SYMBOL_GPL(tpm_show_caps);
-
-ssize_t tpm_show_caps_1_2(struct device * dev,
- struct device_attribute * attr, char *buf)
-{
- u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)),
30)];
- ssize_t len;
- char *str = buf;
-
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
- if ((len = tpm_transmit(chip, data, sizeof(data))) <=
- TPM_ERROR_SIZE) {
- dev_dbg(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the manufacturer\n",
- be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
- return 0;
- }
-
- str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data +
TPM_GET_CAP_RET_UINT32_1_IDX))));
-
- memcpy(data, cap_version, sizeof(cap_version));
- data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
-
- if ((len = tpm_transmit(chip, data, sizeof(data))) <=
- TPM_ERROR_SIZE) {
- dev_err(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the 1.2 version\n",
- be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
- goto out;
- }
- str += sprintf(str,
- "TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[16], (int) data[17], (int) data[18],
- (int) data[19]);
-
-out:
- return str - buf;
-}
-EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
-
-ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return 0;
-
- chip->vendor.cancel(chip);
- return count;
-}
-EXPORT_SYMBOL_GPL(tpm_store_cancel);
-
-/*
- * Device file system interface to the TPM
- */
-int tpm_open(struct inode *inode, struct file *file)
-{
- int rc = 0, minor = iminor(inode);
- struct tpm_chip *chip = NULL, *pos;
-
- spin_lock(&driver_lock);
-
- list_for_each_entry(pos, &tpm_chip_list, list) {
- if (pos->vendor.miscdev.minor == minor) {
- chip = pos;
- break;
- }
- }
-
- if (chip == NULL) {
- rc = -ENODEV;
- goto err_out;
- }
-
- if (chip->num_opens) {
- dev_dbg(chip->dev, "Another process owns this TPM\n");
- rc = -EBUSY;
- goto err_out;
- }
-
- chip->num_opens++;
- get_device(chip->dev);
-
- spin_unlock(&driver_lock);
-
-#ifndef CONFIG_XEN
- chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
-#else
- chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
- GFP_KERNEL);
-#endif
- if (chip->data_buffer == NULL) {
- chip->num_opens--;
- put_device(chip->dev);
- return -ENOMEM;
- }
-
- atomic_set(&chip->data_pending, 0);
-
- file->private_data = chip;
- return 0;
-
-err_out:
- spin_unlock(&driver_lock);
- return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_open);
-
-int tpm_release(struct inode *inode, struct file *file)
-{
- struct tpm_chip *chip = file->private_data;
-
- spin_lock(&driver_lock);
- file->private_data = NULL;
- chip->num_opens--;
- del_singleshot_timer_sync(&chip->user_read_timer);
- flush_scheduled_work();
- atomic_set(&chip->data_pending, 0);
- put_device(chip->dev);
- kfree(chip->data_buffer);
- spin_unlock(&driver_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(tpm_release);
-
-ssize_t tpm_write(struct file *file, const char __user *buf,
- size_t size, loff_t *off)
-{
- struct tpm_chip *chip = file->private_data;
- int in_size = size, out_size;
-
- /* cannot perform a write until the read has cleared
- either via tpm_read or a user_read_timer timeout */
- while (atomic_read(&chip->data_pending) != 0)
- msleep(TPM_TIMEOUT);
-
- down(&chip->buffer_mutex);
-
-#ifndef CONFIG_XEN
- if (in_size > TPM_BUFSIZE)
- in_size = TPM_BUFSIZE;
-#else
- if (in_size > get_chip_buffersize(chip))
- in_size = get_chip_buffersize(chip);
-#endif
-
- if (copy_from_user
- (chip->data_buffer, (void __user *) buf, in_size)) {
- up(&chip->buffer_mutex);
- return -EFAULT;
- }
-
- /* atomic tpm command send and result receive */
-#ifndef CONFIG_XEN
- out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
-#else
- out_size = tpm_transmit(chip, chip->data_buffer,
- get_chip_buffersize(chip));
-#endif
-
- atomic_set(&chip->data_pending, out_size);
-#ifdef CONFIG_XEN
- atomic_set(&chip->data_position, 0);
-#endif
- up(&chip->buffer_mutex);
-
- /* Set a timeout by which the reader must come claim the result */
- mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
-
- return in_size;
-}
-EXPORT_SYMBOL_GPL(tpm_write);
-
-ssize_t tpm_read(struct file *file, char __user *buf,
- size_t size, loff_t *off)
-{
- struct tpm_chip *chip = file->private_data;
- int ret_size;
-#ifdef CONFIG_XEN
- int pos, pending = 0;
-#endif
-
-#ifndef CONFIG_XEN
- del_singleshot_timer_sync(&chip->user_read_timer);
- flush_scheduled_work();
-#endif
- ret_size = atomic_read(&chip->data_pending);
-#ifndef CONFIG_XEN
- atomic_set(&chip->data_pending, 0);
-#endif
- if (ret_size > 0) { /* relay data */
- if (size < ret_size)
- ret_size = size;
-
-#ifdef CONFIG_XEN
- pos = atomic_read(&chip->data_position);
-#endif
- down(&chip->buffer_mutex);
-#ifndef CONFIG_XEN
- if (copy_to_user(buf, chip->data_buffer, ret_size))
-#else
- if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
-#endif
- ret_size = -EFAULT;
-#ifdef CONFIG_XEN
- } else {
- pending = atomic_read(&chip->data_pending) - ret_size;
- if ( pending ) {
- atomic_set(&chip->data_pending, pending);
- atomic_set(&chip->data_position,
- pos+ret_size);
- }
- }
-#endif
- up(&chip->buffer_mutex);
- }
-
-#ifdef CONFIG_XEN
- if ( ret_size <= 0 || pending == 0 ) {
- atomic_set(&chip->data_pending, 0);
- del_singleshot_timer_sync(&chip->user_read_timer);
- flush_scheduled_work();
- }
-#endif
- return ret_size;
-}
-EXPORT_SYMBOL_GPL(tpm_read);
-
-void tpm_remove_hardware(struct device *dev)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
-
- if (chip == NULL) {
- dev_err(dev, "No device data found\n");
- return;
- }
-
- spin_lock(&driver_lock);
-
- list_del(&chip->list);
-
- spin_unlock(&driver_lock);
-
- dev_set_drvdata(dev, NULL);
- misc_deregister(&chip->vendor.miscdev);
- kfree(chip->vendor.miscdev.name);
-
- sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
- tpm_bios_log_teardown(chip->bios_dir);
-
- clear_bit(chip->dev_num, dev_mask);
-
- kfree(chip);
-
- put_device(dev);
-}
-EXPORT_SYMBOL_GPL(tpm_remove_hardware);
-
-static u8 savestate[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 10, /* blob length (in bytes) */
- 0, 0, 0, 152 /* TPM_ORD_SaveState */
-};
-
-/*
- * We are about to suspend. Save the TPM state
- * so that it can be restored.
- */
-int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- tpm_transmit(chip, savestate, sizeof(savestate));
- return 0;
-}
-EXPORT_SYMBOL_GPL(tpm_pm_suspend);
-
-/*
- * Resume from a power safe. The BIOS already restored
- * the TPM state.
- */
-int tpm_pm_resume(struct device *dev)
-{
- struct tpm_chip *chip = dev_get_drvdata(dev);
-
- if (chip == NULL)
- return -ENODEV;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(tpm_pm_resume);
-
-/*
- * Called from tpm_<specific>.c probe function only for devices
- * the driver has determined it should claim. Prior to calling
- * this function the specific probe function has called pci_enable_device
- * upon errant exit from this function specific probe function should call
- * pci_disable_device
- */
-struct tpm_chip *tpm_register_hardware(struct device *dev, const struct
tpm_vendor_specific
- *entry)
-{
-#define DEVNAME_SIZE 7
-
- char *devname;
- struct tpm_chip *chip;
-
- /* Driver specific per-device data */
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return NULL;
-
- init_MUTEX(&chip->buffer_mutex);
- init_MUTEX(&chip->tpm_mutex);
- INIT_LIST_HEAD(&chip->list);
-
- INIT_WORK(&chip->work, timeout_work, chip);
-
- init_timer(&chip->user_read_timer);
- chip->user_read_timer.function = user_reader_timeout;
- chip->user_read_timer.data = (unsigned long) chip;
-
- memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
-
- chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
-
- if (chip->dev_num >= TPM_NUM_DEVICES) {
- dev_err(dev, "No available tpm device numbers\n");
- kfree(chip);
- return NULL;
- } else if (chip->dev_num == 0)
- chip->vendor.miscdev.minor = TPM_MINOR;
- else
- chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
-
- set_bit(chip->dev_num, dev_mask);
-
- devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
- scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
- chip->vendor.miscdev.name = devname;
-
- chip->vendor.miscdev.dev = dev;
- chip->dev = get_device(dev);
-
- if (misc_register(&chip->vendor.miscdev)) {
- dev_err(chip->dev,
- "unable to misc_register %s, minor %d\n",
- chip->vendor.miscdev.name,
- chip->vendor.miscdev.minor);
- put_device(dev);
- clear_bit(chip->dev_num, dev_mask);
- kfree(chip);
- kfree(devname);
- return NULL;
- }
-
- spin_lock(&driver_lock);
-
- dev_set_drvdata(dev, chip);
-
- list_add(&chip->list, &tpm_chip_list);
-
- spin_unlock(&driver_lock);
-
- sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
-
- chip->bios_dir = tpm_bios_log_setup(devname);
-
- return chip;
-}
-EXPORT_SYMBOL_GPL(tpm_register_hardware);
-
-MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
-MODULE_DESCRIPTION("TPM Driver");
-MODULE_VERSION("2.0");
-MODULE_LICENSE("GPL");
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/drivers/char/tpm/tpm.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h Tue Feb 20 12:58:22
2007 -0700
@@ -25,13 +25,6 @@
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/io.h>
-
-#ifdef CONFIG_XEN
-enum tpm_bufsize {
- TPM_MIN_BUFFERSIZE = 2048,
- TPM_MAX_BUFFERSIZE = 64 * 1024,
-};
-#endif
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
@@ -68,9 +61,6 @@ struct tpm_vendor_specific {
const u8 req_complete_mask;
const u8 req_complete_val;
const u8 req_canceled;
-#ifdef CONFIG_XEN
- u32 buffersize;
-#endif
void __iomem *iobase; /* ioremapped address */
unsigned long base; /* TPM base address */
@@ -104,9 +94,6 @@ struct tpm_chip {
/* Data passed to and from the tpm via the read/write calls */
u8 *data_buffer;
atomic_t data_pending;
-#ifdef CONFIG_XEN
- atomic_t data_position;
-#endif
struct semaphore buffer_mutex;
struct timer_list user_read_timer; /* user needs to claim result */
@@ -138,17 +125,6 @@ static inline void tpm_write_index(int b
}
#ifdef CONFIG_XEN
-static inline u32 get_chip_buffersize(struct tpm_chip *chip)
-{
- u32 size = chip->vendor.buffersize;
- if (size > TPM_MAX_BUFFERSIZE) {
- return TPM_MAX_BUFFERSIZE;
- } else if (size < TPM_MIN_BUFFERSIZE) {
- return TPM_MIN_BUFFERSIZE;
- }
- return size;
-}
-
static inline void *chip_get_private(const struct tpm_chip *chip)
{
return chip->priv;
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c Tue Feb 20 12:58:22
2007 -0700
@@ -519,9 +519,6 @@ struct tpm_chip *init_vtpm(struct device
vtpms->tpmvd = tvd;
vtpms->tpm_private = tp;
- if (tvd)
- tpm_vtpm.buffersize = tvd->max_tx_size;
-
chip = tpm_register_hardware(dev, &tpm_vtpm);
if (!chip) {
rc = -ENODEV;
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Feb 20
12:58:22 2007 -0700
@@ -60,7 +60,7 @@ static struct proc_dir_entry *balloon_pd
static struct proc_dir_entry *balloon_pde;
#endif
-static DECLARE_MUTEX(balloon_mutex);
+static DEFINE_MUTEX(balloon_mutex);
/*
* Protects atomic reservation decrease/increase against concurrent increases.
@@ -321,7 +321,7 @@ static void balloon_process(void *unused
int need_sleep = 0;
long credit;
- down(&balloon_mutex);
+ mutex_lock(&balloon_mutex);
do {
credit = current_target() - bs.current_pages;
@@ -340,7 +340,7 @@ static void balloon_process(void *unused
if (current_target() != bs.current_pages)
mod_timer(&balloon_timer, jiffies + HZ);
- up(&balloon_mutex);
+ mutex_unlock(&balloon_mutex);
}
/* Resets the Xen limit, sets new target, and kicks off processing. */
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Feb 20
12:58:22 2007 -0700
@@ -58,15 +58,12 @@ static int map_frontend_page(blkif_t *bl
static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
{
struct gnttab_map_grant_ref op;
- int ret;
gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
GNTMAP_host_map, shared_page, blkif->domid);
- lock_vm_area(blkif->blk_ring_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- unlock_vm_area(blkif->blk_ring_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status) {
DPRINTK(" Grant table operation failure !\n");
@@ -82,15 +79,12 @@ static void unmap_frontend_page(blkif_t
static void unmap_frontend_page(blkif_t *blkif)
{
struct gnttab_unmap_grant_ref op;
- int ret;
gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
GNTMAP_host_map, blkif->shmem_handle);
- lock_vm_area(blkif->blk_ring_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
- unlock_vm_area(blkif->blk_ring_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
}
int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Tue Feb 20
12:58:22 2007 -0700
@@ -58,15 +58,12 @@ static int map_frontend_page(blkif_t *bl
static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
{
struct gnttab_map_grant_ref op;
- int ret;
gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
GNTMAP_host_map, shared_page, blkif->domid);
- lock_vm_area(blkif->blk_ring_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- unlock_vm_area(blkif->blk_ring_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status) {
DPRINTK(" Grant table operation failure !\n");
@@ -82,15 +79,12 @@ static void unmap_frontend_page(blkif_t
static void unmap_frontend_page(blkif_t *blkif)
{
struct gnttab_unmap_grant_ref op;
- int ret;
gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
GNTMAP_host_map, blkif->shmem_handle);
- lock_vm_area(blkif->blk_ring_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
- unlock_vm_area(blkif->blk_ring_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
}
int tap_blkif_map(blkif_t *blkif, unsigned long shared_page,
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Tue Feb 20 12:58:22
2007 -0700
@@ -3,7 +3,7 @@
*
* Granting foreign access to our memory reservation.
*
- * Copyright (c) 2005, Christopher Clark
+ * Copyright (c) 2005-2006, Christopher Clark
* Copyright (c) 2004-2005, K A Fraser
*
* This program is free software; you can redistribute it and/or
@@ -35,7 +35,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/vmalloc.h>
#include <xen/interface/xen.h>
#include <xen/gnttab.h>
#include <asm/pgtable.h>
@@ -43,6 +42,7 @@
#include <asm/synch_bitops.h>
#include <asm/io.h>
#include <xen/interface/memory.h>
+#include <xen/driver_util.h>
#ifdef HAVE_XEN_PLATFORM_COMPAT_H
#include <xen/platform-compat.h>
@@ -50,37 +50,51 @@
/* External tools reserve first few grant table entries. */
#define NR_RESERVED_ENTRIES 8
-
-#define NR_GRANT_ENTRIES \
- (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry))
-#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
-
-static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
+#define GNTTAB_LIST_END 0xffffffff
+#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(grant_entry_t))
+
+static grant_ref_t **gnttab_list;
+static unsigned int nr_grant_frames;
+static unsigned int boot_max_nr_grant_frames;
static int gnttab_free_count;
static grant_ref_t gnttab_free_head;
static DEFINE_SPINLOCK(gnttab_list_lock);
static struct grant_entry *shared;
+#ifndef CONFIG_XEN
+static unsigned long resume_frames;
+#endif
static struct gnttab_free_callback *gnttab_free_callback_list;
+static int gnttab_expand(unsigned int req_entries);
+
+#define RPP (PAGE_SIZE / sizeof(grant_ref_t))
+#define gnttab_entry(entry) (gnttab_list[(entry) / RPP][(entry) % RPP])
+
static int get_free_entries(int count)
{
unsigned long flags;
- int ref;
+ int ref, rc;
grant_ref_t head;
+
spin_lock_irqsave(&gnttab_list_lock, flags);
- if (gnttab_free_count < count) {
+
+ if ((gnttab_free_count < count) &&
+ ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) {
spin_unlock_irqrestore(&gnttab_list_lock, flags);
- return -1;
- }
+ return rc;
+ }
+
ref = head = gnttab_free_head;
gnttab_free_count -= count;
while (count-- > 1)
- head = gnttab_list[head];
- gnttab_free_head = gnttab_list[head];
- gnttab_list[head] = GNTTAB_LIST_END;
+ head = gnttab_entry(head);
+ gnttab_free_head = gnttab_entry(head);
+ gnttab_entry(head) = GNTTAB_LIST_END;
+
spin_unlock_irqrestore(&gnttab_list_lock, flags);
+
return ref;
}
@@ -116,7 +130,7 @@ static void put_free_entry(grant_ref_t r
{
unsigned long flags;
spin_lock_irqsave(&gnttab_list_lock, flags);
- gnttab_list[ref] = gnttab_free_head;
+ gnttab_entry(ref) = gnttab_free_head;
gnttab_free_head = ref;
gnttab_free_count++;
check_free_callbacks();
@@ -132,7 +146,7 @@ int gnttab_grant_foreign_access(domid_t
{
int ref;
- if (unlikely((ref = get_free_entry()) == -1))
+ if (unlikely((ref = get_free_entry()) < 0))
return -ENOSPC;
shared[ref].frame = frame;
@@ -202,7 +216,7 @@ int gnttab_grant_foreign_transfer(domid_
{
int ref;
- if (unlikely((ref = get_free_entry()) == -1))
+ if (unlikely((ref = get_free_entry()) < 0))
return -ENOSPC;
gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
@@ -273,11 +287,11 @@ void gnttab_free_grant_references(grant_
return;
spin_lock_irqsave(&gnttab_list_lock, flags);
ref = head;
- while (gnttab_list[ref] != GNTTAB_LIST_END) {
- ref = gnttab_list[ref];
+ while (gnttab_entry(ref) != GNTTAB_LIST_END) {
+ ref = gnttab_entry(ref);
count++;
}
- gnttab_list[ref] = gnttab_free_head;
+ gnttab_entry(ref) = gnttab_free_head;
gnttab_free_head = head;
gnttab_free_count += count;
check_free_callbacks();
@@ -289,7 +303,7 @@ int gnttab_alloc_grant_references(u16 co
{
int h = get_free_entries(count);
- if (h == -1)
+ if (h < 0)
return -ENOSPC;
*head = h;
@@ -309,7 +323,7 @@ int gnttab_claim_grant_reference(grant_r
grant_ref_t g = *private_head;
if (unlikely(g == GNTTAB_LIST_END))
return -ENOSPC;
- *private_head = gnttab_list[g];
+ *private_head = gnttab_entry(g);
return g;
}
EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
@@ -317,7 +331,7 @@ void gnttab_release_grant_reference(gran
void gnttab_release_grant_reference(grant_ref_t *private_head,
grant_ref_t release)
{
- gnttab_list[release] = *private_head;
+ gnttab_entry(release) = *private_head;
*private_head = release;
}
EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
@@ -356,6 +370,64 @@ void gnttab_cancel_free_callback(struct
}
EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback);
+static int grow_gnttab_list(unsigned int more_frames)
+{
+ unsigned int new_nr_grant_frames, extra_entries, i;
+
+ new_nr_grant_frames = nr_grant_frames + more_frames;
+ extra_entries = more_frames * GREFS_PER_GRANT_FRAME;
+
+ for (i = nr_grant_frames; i < new_nr_grant_frames; i++)
+ {
+ gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC);
+ if (!gnttab_list[i])
+ goto grow_nomem;
+ }
+
+
+ for (i = GREFS_PER_GRANT_FRAME * nr_grant_frames;
+ i < GREFS_PER_GRANT_FRAME * new_nr_grant_frames - 1; i++)
+ gnttab_entry(i) = i + 1;
+
+ gnttab_entry(i) = gnttab_free_head;
+ gnttab_free_head = GREFS_PER_GRANT_FRAME * nr_grant_frames;
+ gnttab_free_count += extra_entries;
+
+ nr_grant_frames = new_nr_grant_frames;
+
+ check_free_callbacks();
+
+ return 0;
+
+grow_nomem:
+ for ( ; i >= nr_grant_frames; i--)
+ free_page((unsigned long) gnttab_list[i]);
+ return -ENOMEM;
+}
+
+static unsigned int __max_nr_grant_frames(void)
+{
+ struct gnttab_query_size query;
+ int rc;
+
+ query.dom = DOMID_SELF;
+
+ rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1);
+ if ((rc < 0) || (query.status != GNTST_okay))
+ return 4; /* Legacy max supported number of frames */
+
+ return query.max_nr_frames;
+}
+
+static inline unsigned int max_nr_grant_frames(void)
+{
+ unsigned int xen_max = __max_nr_grant_frames();
+
+ if (xen_max > boot_max_nr_grant_frames)
+ return boot_max_nr_grant_frames;
+ return xen_max;
+}
+
#ifdef CONFIG_XEN
#ifndef __ia64__
@@ -378,49 +450,62 @@ static int unmap_pte_fn(pte_t *pte, stru
}
#endif
-int gnttab_resume(void)
+static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
{
struct gnttab_setup_table setup;
- unsigned long frames[NR_GRANT_FRAMES];
+ unsigned long *frames;
+ unsigned int nr_gframes = end_idx + 1;
int rc;
-#ifndef __ia64__
- void *pframes = frames;
- struct vm_struct *area;
-#endif
+
+ frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
+ if (!frames)
+ return -ENOMEM;
setup.dom = DOMID_SELF;
- setup.nr_frames = NR_GRANT_FRAMES;
+ setup.nr_frames = nr_gframes;
set_xen_guest_handle(setup.frame_list, frames);
rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- if (rc == -ENOSYS)
+ if (rc == -ENOSYS) {
+ kfree(frames);
return -ENOSYS;
+ }
BUG_ON(rc || setup.status);
#ifndef __ia64__
if (shared == NULL) {
- area = get_vm_area(PAGE_SIZE * NR_GRANT_FRAMES, VM_IOREMAP);
+ struct vm_struct *area;
+ area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
BUG_ON(area == NULL);
shared = area->addr;
}
rc = apply_to_page_range(&init_mm, (unsigned long)shared,
- PAGE_SIZE * NR_GRANT_FRAMES,
- map_pte_fn, &pframes);
+ PAGE_SIZE * nr_gframes,
+ map_pte_fn, &frames);
BUG_ON(rc);
+ frames -= nr_gframes; /* adjust after map_pte_fn() */
#else
shared = __va(frames[0] << PAGE_SHIFT);
- printk("grant table at %p\n", shared);
#endif
- return 0;
+ kfree(frames);
+
+ return 0;
+}
+
+int gnttab_resume(void)
+{
+ if (max_nr_grant_frames() < nr_grant_frames)
+ return -ENOSYS;
+ return gnttab_map(0, nr_grant_frames - 1);
}
int gnttab_suspend(void)
{
#ifndef __ia64__
apply_to_page_range(&init_mm, (unsigned long)shared,
- PAGE_SIZE * NR_GRANT_FRAMES,
+ PAGE_SIZE * nr_grant_frames,
unmap_pte_fn, NULL);
#endif
return 0;
@@ -430,24 +515,39 @@ int gnttab_suspend(void)
#include <platform-pci.h>
-int gnttab_resume(void)
-{
- unsigned long frames;
+static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+{
struct xen_add_to_physmap xatp;
unsigned int i;
- frames = alloc_xen_mmio(PAGE_SIZE * NR_GRANT_FRAMES);
-
- for (i = 0; i < NR_GRANT_FRAMES; i++) {
+ /* Loop backwards, so that the first hypercall has the largest index,
+ * ensuring that the table will grow only once.
+ */
+ for (i = end_idx; i >= start_idx; i--) {
xatp.domid = DOMID_SELF;
xatp.idx = i;
xatp.space = XENMAPSPACE_grant_table;
- xatp.gpfn = (frames >> PAGE_SHIFT) + i;
+ xatp.gpfn = (resume_frames >> PAGE_SHIFT) + i;
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
BUG();
}
-
- shared = ioremap(frames, PAGE_SIZE * NR_GRANT_FRAMES);
+}
+
+int gnttab_resume(void)
+{
+ struct xen_add_to_physmap xatp;
+ unsigned int i, max_nr_gframes, nr_gframes;
+
+ nr_gframes = nr_grant_frames;
+ max_nr_gframes = max_nr_grant_frames();
+ if (max_nr_gframes < nr_gframes)
+ return -ENOSYS;
+
+ resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
+
+ gnttab_map(0, nr_gframes - 1);
+
+ shared = ioremap(resume_frames, PAGE_SIZE * max_nr_gframes);
if (shared == NULL) {
printk("error to ioremap gnttab share frames\n");
return -1;
@@ -459,28 +559,79 @@ int gnttab_suspend(void)
int gnttab_suspend(void)
{
iounmap(shared);
+ resume_frames = 0;
return 0;
}
#endif /* !CONFIG_XEN */
+static int gnttab_expand(unsigned int req_entries)
+{
+ int rc;
+ unsigned int cur, extra;
+
+ cur = nr_grant_frames;
+ extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
+ GREFS_PER_GRANT_FRAME);
+ if (cur + extra > max_nr_grant_frames())
+ return -ENOSPC;
+
+ if ((rc = gnttab_map(cur, cur + extra - 1)) == 0)
+ rc = grow_gnttab_list(extra);
+
+ return rc;
+}
+
int __devinit gnttab_init(void)
{
int i;
+ unsigned int max_nr_glist_frames;
+ unsigned int nr_init_grefs;
if (!is_running_on_xen())
return -ENODEV;
+ nr_grant_frames = 1;
+ boot_max_nr_grant_frames = __max_nr_grant_frames();
+
+ /* Determine the maximum number of frames required for the
+ * grant reference free list on the current hypervisor.
+ */
+ max_nr_glist_frames = (boot_max_nr_grant_frames *
+ GREFS_PER_GRANT_FRAME /
+ (PAGE_SIZE / sizeof(grant_ref_t)));
+
+ gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *),
+ GFP_KERNEL);
+ if (gnttab_list == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < nr_grant_frames; i++) {
+ gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
+ if (gnttab_list[i] == NULL)
+ goto ini_nomem;
+ }
+
if (gnttab_resume() < 0)
return -ENODEV;
- for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
- gnttab_list[i] = i + 1;
- gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
+ nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
+
+ for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++)
+ gnttab_entry(i) = i + 1;
+
+ gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END;
+ gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES;
gnttab_free_head = NR_RESERVED_ENTRIES;
printk("Grant table initialized\n");
return 0;
+
+ ini_nomem:
+ for (i--; i >= 0; i--)
+ free_page((unsigned long)gnttab_list[i]);
+ kfree(gnttab_list);
+ return -ENOMEM;
}
#ifdef CONFIG_XEN
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c Tue Feb 20 12:58:22
2007 -0700
@@ -349,8 +349,7 @@ void __init smp_prepare_cpus(unsigned in
void __devinit smp_prepare_boot_cpu(void)
{
- cpu_present_map = cpumask_of_cpu(0);
- cpu_online_map = cpumask_of_cpu(0);
+ prefill_possible_map();
}
#ifdef CONFIG_HOTPLUG_CPU
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Tue Feb 20
12:58:22 2007 -0700
@@ -194,15 +194,12 @@ static int map_frontend_pages(
netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref)
{
struct gnttab_map_grant_ref op;
- int ret;
gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr,
GNTMAP_host_map, tx_ring_ref, netif->domid);
- lock_vm_area(netif->tx_comms_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- unlock_vm_area(netif->tx_comms_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status) {
DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
@@ -215,10 +212,8 @@ static int map_frontend_pages(
gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr,
GNTMAP_host_map, rx_ring_ref, netif->domid);
- lock_vm_area(netif->rx_comms_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- unlock_vm_area(netif->rx_comms_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status) {
DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
@@ -234,23 +229,18 @@ static void unmap_frontend_pages(netif_t
static void unmap_frontend_pages(netif_t *netif)
{
struct gnttab_unmap_grant_ref op;
- int ret;
gnttab_set_unmap_op(&op, (unsigned long)netif->tx_comms_area->addr,
GNTMAP_host_map, netif->tx_shmem_handle);
- lock_vm_area(netif->tx_comms_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
- unlock_vm_area(netif->tx_comms_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
gnttab_set_unmap_op(&op, (unsigned long)netif->rx_comms_area->addr,
GNTMAP_host_map, netif->rx_shmem_handle);
- lock_vm_area(netif->rx_comms_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
- unlock_vm_area(netif->rx_comms_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
}
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Tue Feb 20
12:58:22 2007 -0700
@@ -79,16 +79,13 @@ tpmif_t *tpmif_find(domid_t domid, struc
static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
{
- int ret;
struct gnttab_map_grant_ref op;
gnttab_set_map_op(&op, (unsigned long)tpmif->tx_area->addr,
GNTMAP_host_map, shared_page, tpmif->domid);
- lock_vm_area(tpmif->tx_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- unlock_vm_area(tpmif->tx_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status) {
DPRINTK(" Grant table operation failure !\n");
@@ -104,15 +101,12 @@ static void unmap_frontend_page(tpmif_t
static void unmap_frontend_page(tpmif_t *tpmif)
{
struct gnttab_unmap_grant_ref op;
- int ret;
gnttab_set_unmap_op(&op, (unsigned long)tpmif->tx_area->addr,
GNTMAP_host_map, tpmif->shmem_handle);
- lock_vm_area(tpmif->tx_area);
- ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
- unlock_vm_area(tpmif->tx_area);
- BUG_ON(ret);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
}
int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c Tue Feb 20 12:58:22 2007 -0700
@@ -30,6 +30,11 @@ struct vm_struct *alloc_vm_area(unsigned
return NULL;
}
+ /* Map page directories into every address space. */
+#ifdef CONFIG_X86
+ vmalloc_sync_all();
+#endif
+
return area;
}
EXPORT_SYMBOL_GPL(alloc_vm_area);
@@ -42,29 +47,3 @@ void free_vm_area(struct vm_struct *area
kfree(area);
}
EXPORT_SYMBOL_GPL(free_vm_area);
-
-void lock_vm_area(struct vm_struct *area)
-{
- unsigned long i;
- char c;
-
- /*
- * Prevent context switch to a lazy mm that doesn't have this area
- * mapped into its page tables.
- */
- preempt_disable();
-
- /*
- * Ensure that the page tables are mapped into the current mm. The
- * page-fault path will copy the page directory pointers from init_mm.
- */
- for (i = 0; i < area->size; i += PAGE_SIZE)
- (void)__get_user(c, (char __user *)area->addr + i);
-}
-EXPORT_SYMBOL_GPL(lock_vm_area);
-
-void unlock_vm_area(struct vm_struct *area)
-{
- preempt_enable();
-}
-EXPORT_SYMBOL_GPL(unlock_vm_area);
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Tue Feb
20 12:58:22 2007 -0700
@@ -48,9 +48,8 @@ struct vm_struct *xenbus_map_ring_valloc
gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
gnt_ref, dev->otherend_id);
- lock_vm_area(area);
- BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
- unlock_vm_area(area);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status != GNTST_okay) {
free_vm_area(area);
@@ -76,7 +75,8 @@ int xenbus_map_ring(struct xenbus_device
gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
gnt_ref, dev->otherend_id);
- BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+ if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+ BUG();
if (op.status != GNTST_okay) {
xenbus_dev_fatal(dev, op.status,
@@ -98,9 +98,8 @@ int xenbus_unmap_ring_vfree(struct xenbu
gnttab_set_unmap_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
(grant_handle_t)area->phys_addr);
- lock_vm_area(area);
- BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
- unlock_vm_area(area);
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
if (op.status == GNTST_okay)
free_vm_area(area);
@@ -121,7 +120,8 @@ int xenbus_unmap_ring(struct xenbus_devi
gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
handle);
- BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+ if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+ BUG();
if (op.status != GNTST_okay)
xenbus_dev_error(dev, op.status,
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Tue Feb
20 12:58:22 2007 -0700
@@ -56,6 +56,9 @@
extern shared_info_t *HYPERVISOR_shared_info;
+#define vcpu_info(cpu) (HYPERVISOR_shared_info->vcpu_info + (cpu))
+#define current_vcpu_info() vcpu_info(smp_processor_id())
+
#ifdef CONFIG_X86_32
extern unsigned long hypervisor_virt_start;
#endif
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h Tue Feb
20 12:58:22 2007 -0700
@@ -12,12 +12,6 @@
#ifndef __ASSEMBLY__
-#ifdef CONFIG_SMP
-#define __vcpu_id smp_processor_id()
-#else
-#define __vcpu_id 0
-#endif
-
/*
* The use of 'barrier' in the following reflects their use as local-lock
* operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
@@ -26,8 +20,7 @@
* includes these barriers, for example.
*/
-#define __raw_local_save_flags() \
- (&HYPERVISOR_shared_info->vcpu_info[__vcpu_id])->evtchn_upcall_mask;
+#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
#define raw_local_save_flags(flags) \
do { (flags) = __raw_local_save_flags(); } while (0)
@@ -36,7 +29,7 @@ do {
\
do { \
vcpu_info_t *_vcpu; \
barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
+ _vcpu = current_vcpu_info(); \
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
barrier(); /* unmask then check (avoid races) */ \
if (unlikely(_vcpu->evtchn_upcall_pending)) \
@@ -46,9 +39,7 @@ do {
\
#define raw_local_irq_disable()
\
do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
- _vcpu->evtchn_upcall_mask = 1; \
+ current_vcpu_info()->evtchn_upcall_mask = 1; \
barrier(); \
} while (0)
@@ -56,7 +47,7 @@ do {
\
do { \
vcpu_info_t *_vcpu; \
barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
+ _vcpu = current_vcpu_info(); \
_vcpu->evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
if (unlikely(_vcpu->evtchn_upcall_pending)) \
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h Tue Feb
20 12:58:22 2007 -0700
@@ -21,6 +21,7 @@ typedef unsigned long maddr_t;
#ifdef CONFIG_XEN
extern unsigned long *phys_to_machine_mapping;
+extern unsigned long max_mapnr;
#undef machine_to_phys_mapping
extern unsigned long *machine_to_phys_mapping;
@@ -30,20 +31,20 @@ static inline unsigned long pfn_to_mfn(u
{
if (xen_feature(XENFEAT_auto_translated_physmap))
return pfn;
- return phys_to_machine_mapping[(unsigned int)(pfn)] &
- ~FOREIGN_FRAME_BIT;
+ BUG_ON(max_mapnr && pfn >= max_mapnr);
+ return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
}
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
{
if (xen_feature(XENFEAT_auto_translated_physmap))
return 1;
+ BUG_ON(max_mapnr && pfn >= max_mapnr);
return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
}
static inline unsigned long mfn_to_pfn(unsigned long mfn)
{
- extern unsigned long max_mapnr;
unsigned long pfn;
if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -92,7 +93,6 @@ static inline unsigned long mfn_to_pfn(u
*/
static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
{
- extern unsigned long max_mapnr;
unsigned long pfn = mfn_to_pfn(mfn);
if ((pfn < max_mapnr)
&& !xen_feature(XENFEAT_auto_translated_physmap)
@@ -103,6 +103,7 @@ static inline unsigned long mfn_to_local
static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
+ BUG_ON(max_mapnr && pfn >= max_mapnr);
if (xen_feature(XENFEAT_auto_translated_physmap)) {
BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
return;
@@ -124,6 +125,20 @@ static inline paddr_t machine_to_phys(ma
return phys;
}
+#ifdef CONFIG_X86_PAE
+static inline paddr_t pte_phys_to_machine(paddr_t phys)
+{
+ /*
+ * In PAE mode, the NX bit needs to be dealt with in the value
+ * passed to pfn_to_mfn(). On x86_64, we need to mask it off,
+ * but for i386 the conversion to ulong for the argument will
+ * clip it off.
+ */
+ maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+ machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
+ return machine;
+}
+
static inline paddr_t pte_machine_to_phys(maddr_t machine)
{
/*
@@ -136,6 +151,7 @@ static inline paddr_t pte_machine_to_phy
phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
return phys;
}
+#endif
#else /* !CONFIG_XEN */
@@ -146,7 +162,6 @@ static inline paddr_t pte_machine_to_phy
#define phys_to_machine_mapping_valid(pfn) (1)
#define phys_to_machine(phys) ((maddr_t)(phys))
#define machine_to_phys(mach) ((paddr_t)(mach))
-#define pte_machine_to_phys(mach) ((paddr_t)(mach))
#endif /* !CONFIG_XEN */
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Sun Feb 18
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Tue Feb 20
12:58:22 2007 -0700
@@ -28,6 +28,13 @@
#include <asm/bug.h>
#include <xen/interface/xen.h>
#include <xen/features.h>
+
+/*
+ * Need to repeat this here in order to not include pgtable.h (which in turn
+ * depends on definitions made here), but to be able to use the symbolic
+ * below. The preprocessor will warn if the two definitions aren't identical.
+ */
+#define _PAGE_PRESENT 0x001
#define arch_free_page(_page,_order) \
({ int foreign = PageForeign(_page); \
@@ -81,39 +88,37 @@ typedef struct { unsigned long long pgpr
#define pgprot_val(x) ((x).pgprot)
#include <asm/maddr.h>
#define __pte(x) ({ unsigned long long _x = (x); \
- if (_x & 1) _x = phys_to_machine(_x); \
+ if (_x & _PAGE_PRESENT) _x = pte_phys_to_machine(_x); \
((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
#define __pgd(x) ({ unsigned long long _x = (x); \
- (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
+ (pgd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
#define __pmd(x) ({ unsigned long long _x = (x); \
- (((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); })
+ (pmd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
+static inline unsigned long long pte_val_ma(pte_t x)
+{
+ return ((unsigned long long)x.pte_high << 32) | x.pte_low;
+}
static inline unsigned long long pte_val(pte_t x)
{
- unsigned long long ret;
-
- if (x.pte_low) {
- ret = x.pte_low | (unsigned long long)x.pte_high << 32;
- ret = pte_machine_to_phys(ret) | 1;
- } else {
- ret = 0;
- }
+ unsigned long long ret = pte_val_ma(x);
+ if (x.pte_low & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
return ret;
}
static inline unsigned long long pmd_val(pmd_t x)
{
unsigned long long ret = x.pmd;
- if (ret) ret = pte_machine_to_phys(ret) | 1;
+#ifdef CONFIG_XEN_COMPAT_030002
+ if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
+#else
+ if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+#endif
return ret;
}
static inline unsigned long long pgd_val(pgd_t x)
{
unsigned long long ret = x.pgd;
- if (ret) ret = pte_machine_to_phys(ret) | 1;
- return ret;
-}
-static inline unsigned long long pte_val_ma(pte_t x)
-{
- return (unsigned long long)x.pte_high << 32 | x.pte_low;
+ if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+ return ret;
}
#define HPAGE_SHIFT 21
#else
@@ -123,23 +128,23 @@ typedef struct { unsigned long pgprot; }
#define pgprot_val(x) ((x).pgprot)
#include <asm/maddr.h>
#define boot_pte_t pte_t /* or would you rather have a typedef */
-#define pte_val(x) (((x).pte_low & 1) ? \
- pte_machine_to_phys((x).pte_low) : \
+#define pte_val(x) (((x).pte_low & _PAGE_PRESENT) ? \
+ machine_to_phys((x).pte_low) : \
(x).pte_low)
#define pte_val_ma(x) ((x).pte_low)
#define __pte(x) ({ unsigned long _x = (x); \
- (((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
+ (pte_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
#define __pgd(x) ({ unsigned long _x = (x); \
- (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
+ (pgd_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
static inline unsigned long pgd_val(pgd_t x)
{
unsigned long ret = x.pgd;
- if (ret) ret = pte_machine_to_phys(ret) | 1;
+ if (ret & _PAGE_PRESENT) ret = machine_to_phys(ret);
return ret;
}
#define HPAGE_SHIFT 22
#endif
-#define PTE_MASK PAGE_MASK
+#define PTE_MASK PHYSICAL_PAGE_MASK
#ifdef CONFIG_HUGETLB_PAGE
#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h
Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h
Tue Feb 20 12:58:22 2007 -0700
@@ -38,8 +38,11 @@
#define ptep_get_and_clear(mm,addr,xp) __pte_ma(xchg(&(xp)->pte_low, 0))
#define pte_same(a, b) ((a).pte_low == (b).pte_low)
-#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
-#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
+#define __pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
+#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+ __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+ mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
#define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h
Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h
Tue Feb 20 12:58:22 2007 -0700
@@ -52,22 +52,14 @@ static inline int pte_exec_kernel(pte_t
*/
#define __HAVE_ARCH_SET_PTE_ATOMIC
-#if 1
-/* use writable pagetables */
static inline void set_pte(pte_t *ptep, pte_t pte)
{
ptep->pte_high = pte.pte_high;
smp_wmb();
ptep->pte_low = pte.pte_low;
}
-# define set_pte_atomic(pteptr,pteval) \
+#define set_pte_atomic(pteptr,pteval) \
set_64bit((unsigned long long *)(pteptr),pte_val_ma(pteval))
-#else
-/* no writable pagetables */
-# define set_pte(pteptr,pteval) \
- xen_l1_entry_update((pteptr), (pteval))
-# define set_pte_atomic(pteptr,pteval) set_pte(pteptr,pteval)
-#endif
#define set_pte_at(_mm,addr,ptep,pteval) do { \
if (((_mm) != current->mm && (_mm) != &init_mm) || \
@@ -145,21 +137,24 @@ static inline int pte_none(pte_t pte)
return !pte.pte_low && !pte.pte_high;
}
-#define pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) |\
- (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)))
-#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
+#define __pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) | \
+ ((_pte).pte_high << (32-PAGE_SHIFT)))
+#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+ __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+ mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
extern unsigned long long __supported_pte_mask;
static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
{
- return pfn_pte_ma(pfn_to_mfn(page_nr), pgprot);
+ return __pte((((unsigned long long)page_nr << PAGE_SHIFT) |
+ pgprot_val(pgprot)) & __supported_pte_mask);
}
static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
{
- BUG(); panic("needs review");
- return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \
+ return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) |
pgprot_val(pgprot)) & __supported_pte_mask);
}
@@ -180,6 +175,6 @@ static inline pmd_t pfn_pmd(unsigned lon
#define __pmd_free_tlb(tlb, x) do { } while (0)
-#define vmalloc_sync_all() ((void)0)
+void vmalloc_sync_all(void);
#endif /* _I386_PGTABLE_3LEVEL_H */
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h Tue Feb
20 12:58:22 2007 -0700
@@ -315,18 +315,19 @@ static inline void clone_pgd_range(pgd_t
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- pte.pte_low &= _PAGE_CHG_MASK;
- pte.pte_low |= pgprot_val(newprot);
+ /*
+ * Since this might change the present bit (which controls whether
+ * a pte_t object has undergone p2m translation), we must use
+ * pte_val() on the input pte and __pte() for the return value.
+ */
+ paddr_t pteval = pte_val(pte);
+
+ pteval &= _PAGE_CHG_MASK;
+ pteval |= pgprot_val(newprot);
#ifdef CONFIG_X86_PAE
- /*
- * Chop off the NX bit (if present), and add the NX portion of
- * the newprot (if present):
- */
- pte.pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
- pte.pte_high |= (pgprot_val(newprot) >> 32) & \
- (__supported_pte_mask >> 32);
-#endif
- return pte;
+ pteval &= __supported_pte_mask;
+#endif
+ return __pte(pteval);
}
#define pmd_large(pmd) \
@@ -432,12 +433,15 @@ extern void noexec_setup(const char *str
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
do { \
if (__dirty) { \
- if ( likely((__vma)->vm_mm == current->mm) ) { \
- BUG_ON(HYPERVISOR_update_va_mapping((__address),
(__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned
long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
- } else { \
- xen_l1_entry_update((__ptep), (__entry)); \
- flush_tlb_page((__vma), (__address)); \
- } \
+ if ( likely((__vma)->vm_mm == current->mm) ) { \
+ BUG_ON(HYPERVISOR_update_va_mapping(__address, \
+ __entry, \
+ (unsigned
long)(__vma)->vm_mm->cpu_vm_mask.bits| \
+ UVMF_INVLPG|UVMF_MULTI)); \
+ } else { \
+ xen_l1_entry_update(__ptep, __entry); \
+ flush_tlb_page(__vma, __address); \
+ } \
} \
} while (0)
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h Tue Feb
20 12:58:22 2007 -0700
@@ -100,8 +100,7 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
#define write_cr0(x) \
__asm__ __volatile__("movl %0,%%cr0": :"r" (x))
-#define read_cr2() \
- (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
+#define read_cr2() (current_vcpu_info()->arch.cr2)
#define write_cr2(x) \
__asm__ __volatile__("movl %0,%%cr2": :"r" (x))
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h Tue Feb
20 12:58:22 2007 -0700
@@ -15,12 +15,6 @@
* Interrupt control:
*/
-#ifdef CONFIG_SMP
-#define __vcpu_id smp_processor_id()
-#else
-#define __vcpu_id 0
-#endif
-
/*
* The use of 'barrier' in the following reflects their use as local-lock
* operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
@@ -29,8 +23,7 @@
* includes these barriers, for example.
*/
-#define __raw_local_save_flags() \
- (&HYPERVISOR_shared_info->vcpu_info[__vcpu_id])->evtchn_upcall_mask;
+#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
#define raw_local_save_flags(flags) \
do { (flags) = __raw_local_save_flags(); } while (0)
@@ -39,7 +32,7 @@ do {
\
do { \
vcpu_info_t *_vcpu; \
barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
+ _vcpu = current_vcpu_info(); \
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
@@ -76,9 +69,7 @@ static inline int raw_irqs_disabled_flag
#define raw_local_irq_disable()
\
do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
- _vcpu->evtchn_upcall_mask = 1; \
+ current_vcpu_info()->evtchn_upcall_mask = 1;
\
barrier(); \
} while (0)
@@ -86,7 +77,7 @@ do {
\
do { \
vcpu_info_t *_vcpu; \
barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
+ _vcpu = current_vcpu_info(); \
_vcpu->evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h Tue Feb
20 12:58:22 2007 -0700
@@ -25,14 +25,15 @@ static inline unsigned long pfn_to_mfn(u
{
if (xen_feature(XENFEAT_auto_translated_physmap))
return pfn;
- return phys_to_machine_mapping[(unsigned int)(pfn)] &
- ~FOREIGN_FRAME_BIT;
+ BUG_ON(end_pfn && pfn >= end_pfn);
+ return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
}
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
{
if (xen_feature(XENFEAT_auto_translated_physmap))
return 1;
+ BUG_ON(end_pfn && pfn >= end_pfn);
return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
}
@@ -96,6 +97,7 @@ static inline unsigned long mfn_to_local
static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
{
+ BUG_ON(end_pfn && pfn >= end_pfn);
if (xen_feature(XENFEAT_auto_translated_physmap)) {
BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
return;
@@ -117,6 +119,14 @@ static inline paddr_t machine_to_phys(ma
return phys;
}
+static inline paddr_t pte_phys_to_machine(paddr_t phys)
+{
+ maddr_t machine;
+ machine = pfn_to_mfn((phys & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT);
+ machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
+ return machine;
+}
+
static inline paddr_t pte_machine_to_phys(maddr_t machine)
{
paddr_t phys;
@@ -134,7 +144,6 @@ static inline paddr_t pte_machine_to_phy
#define phys_to_machine_mapping_valid(pfn) (1)
#define phys_to_machine(phys) ((maddr_t)(phys))
#define machine_to_phys(mach) ((paddr_t)(mach))
-#define pte_machine_to_phys(mach) ((paddr_t)(mach))
#endif /* !CONFIG_XEN */
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h Tue Feb
20 12:58:22 2007 -0700
@@ -8,6 +8,13 @@
#include <asm/bug.h>
#endif
#include <xen/interface/xen.h>
+
+/*
+ * Need to repeat this here in order to not include pgtable.h (which in turn
+ * depends on definitions made here), but to be able to use the symbolic
+ * below. The preprocessor will warn if the two definitions aren't identical.
+ */
+#define _PAGE_PRESENT 0x001
#define arch_free_page(_page,_order) \
({ int foreign = PageForeign(_page); \
@@ -95,28 +102,33 @@ typedef struct { unsigned long pgd; } pg
typedef struct { unsigned long pgprot; } pgprot_t;
-#define pte_val(x) (((x).pte & 1) ? pte_machine_to_phys((x).pte) : \
+#define pte_val(x) (((x).pte & _PAGE_PRESENT) ? \
+ pte_machine_to_phys((x).pte) : \
(x).pte)
#define pte_val_ma(x) ((x).pte)
static inline unsigned long pmd_val(pmd_t x)
{
unsigned long ret = x.pmd;
- if (ret) ret = pte_machine_to_phys(ret);
+#ifdef CONFIG_XEN_COMPAT_030002
+ if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
+#else
+ if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+#endif
return ret;
}
static inline unsigned long pud_val(pud_t x)
{
unsigned long ret = x.pud;
- if (ret) ret = pte_machine_to_phys(ret);
+ if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
return ret;
}
static inline unsigned long pgd_val(pgd_t x)
{
unsigned long ret = x.pgd;
- if (ret) ret = pte_machine_to_phys(ret);
+ if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
return ret;
}
@@ -124,25 +136,25 @@ static inline unsigned long pgd_val(pgd_
static inline pte_t __pte(unsigned long x)
{
- if (x & 1) x = phys_to_machine(x);
+ if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
return ((pte_t) { (x) });
}
static inline pmd_t __pmd(unsigned long x)
{
- if ((x & 1)) x = phys_to_machine(x);
+ if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
return ((pmd_t) { (x) });
}
static inline pud_t __pud(unsigned long x)
{
- if ((x & 1)) x = phys_to_machine(x);
+ if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
return ((pud_t) { (x) });
}
static inline pgd_t __pgd(unsigned long x)
{
- if ((x & 1)) x = phys_to_machine(x);
+ if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
return ((pgd_t) { (x) });
}
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Sun Feb
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h Tue Feb
20 12:58:22 2007 -0700
@@ -302,19 +302,20 @@ static inline unsigned long pud_bad(pud_
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
-#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
+#define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
+#define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
+ __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+#define pte_pfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
+ mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
#define pte_page(x) pfn_to_page(pte_pfn(x))
static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
{
- pte_t pte;
-
- (pte).pte = (pfn_to_mfn(page_nr) << PAGE_SHIFT);
- (pte).pte |= pgprot_val(pgprot);
- (pte).pte &= __supported_pte_mask;
- return pte;
+ unsigned long pte = page_nr << PAGE_SHIFT;
+ pte |= pgprot_val(pgprot);
+ pte &= __supported_pte_mask;
+ return __pte(pte);
}
/*
@@ -446,18 +447,25 @@ static inline pud_t *pud_offset_k(pgd_t
/* physical address -> PTE */
static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
{
- pte_t pte;
- (pte).pte = physpage | pgprot_val(pgprot);
- return pte;
+ unsigned long pteval;
+ pteval = physpage | pgprot_val(pgprot);
+ return __pte(pteval);
}
/* Change flags of a PTE */
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- (pte).pte &= _PAGE_CHG_MASK;
- (pte).pte |= pgprot_val(newprot);
- (pte).pte &= __supported_pte_mask;
- return pte;
+ /*
+ * Since this might change the present bit (which controls whether
+ * a pte_t object has undergone p2m translation), we must use
+ * pte_val() on the input pte and __pte() for the return value.
+ */
+ unsigned long pteval = pte_val(pte);
+
+ pteval &= _PAGE_CHG_MASK;
+ pteval |= pgprot_val(newprot);
+ pteval &= __supported_pte_mask;
+ return __pte(pteval);
}
#define pte_index(address) \
@@ -479,24 +487,18 @@ static inline pte_t pte_modify(pte_t pte
* race with other CPU's that might be updating the dirty
* bit at the same time. */
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#if 0
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
do { \
if (__dirty) { \
- set_pte(__ptep, __entry); \
- flush_tlb_page(__vma, __address); \
- } \
- } while (0)
-#endif
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
- do { \
- if (__dirty) { \
- if ( likely((__vma)->vm_mm == current->mm) ) { \
- BUG_ON(HYPERVISOR_update_va_mapping((__address),
(__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned
long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
- } else { \
- xen_l1_entry_update((__ptep), (__entry)); \
- flush_tlb_page((__vma), (__address)); \
- } \
+ if ( likely((__vma)->vm_mm == current->mm) ) { \
+ BUG_ON(HYPERVISOR_update_va_mapping(__address, \
+ __entry, \
+ (unsigned
long)(__vma)->vm_mm->cpu_vm_mask.bits| \
+ UVMF_INVLPG|UVMF_MULTI)); \
+ } else { \
+ xen_l1_entry_update(__ptep, __entry); \
+ flush_tlb_page(__vma, __address); \
+ } \
} \
} while (0)
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/include/linux/pfn.h
--- a/linux-2.6-xen-sparse/include/linux/pfn.h Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef _LINUX_PFN_H_
-#define _LINUX_PFN_H_
-
-#define PFN_ALIGN(x) (((unsigned long long)(x) + (PAGE_SIZE - 1)) &
PAGE_MASK)
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x) ((unsigned long long)(x) << PAGE_SHIFT)
-
-#endif
diff -r 04c23c1ef888 -r d907467f08cd
linux-2.6-xen-sparse/include/xen/driver_util.h
--- a/linux-2.6-xen-sparse/include/xen/driver_util.h Sun Feb 18 16:13:13
2007 -0700
+++ b/linux-2.6-xen-sparse/include/xen/driver_util.h Tue Feb 20 12:58:22
2007 -0700
@@ -9,8 +9,4 @@ extern struct vm_struct *alloc_vm_area(u
extern struct vm_struct *alloc_vm_area(unsigned long size);
extern void free_vm_area(struct vm_struct *area);
-/* Lock an area so that PTEs are accessible in the current address space. */
-extern void lock_vm_area(struct vm_struct *area);
-extern void unlock_vm_area(struct vm_struct *area);
-
#endif /* __ASM_XEN_DRIVER_UTIL_H__ */
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Tue Feb 20 12:58:22 2007 -0700
@@ -42,13 +42,6 @@
#include <asm/maddr.h> /* maddr_t */
#include <xen/interface/grant_table.h>
#include <xen/features.h>
-
-/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
-#ifdef __ia64__
-#define NR_GRANT_FRAMES 1
-#else
-#define NR_GRANT_FRAMES 4
-#endif
struct gnttab_free_callback {
struct gnttab_free_callback *next;
@@ -109,12 +102,6 @@ void gnttab_grant_foreign_transfer_ref(g
void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
unsigned long pfn);
-#ifdef __ia64__
-#define gnttab_map_vaddr(map) __va(map.dev_bus_addr)
-#else
-#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
-#endif
-
int gnttab_suspend(void);
int gnttab_resume(void);
diff -r 04c23c1ef888 -r d907467f08cd
patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch
--- a/patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch Sun Feb
18 16:13:13 2007 -0700
+++ b/patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch Tue Feb
20 12:58:22 2007 -0700
@@ -1,7 +1,7 @@ diff -pruN ../orig-linux-2.6.18/include/
diff -pruN ../orig-linux-2.6.18/include/linux/elfnote.h
./include/linux/elfnote.h
--- ../orig-linux-2.6.18/include/linux/elfnote.h 2007-01-12
18:19:44.000000000 +0000
+++ ./include/linux/elfnote.h 2007-01-12 18:21:02.000000000 +0000
-@@ -31,22 +31,24 @@
+@@ -31,22 +31,38 @@
/*
* Generate a structure with the same shape as Elf{32,64}_Nhdr (which
* turn out to be the same size and shape), followed by the name and
@@ -25,9 +25,21 @@ diff -pruN ../orig-linux-2.6.18/include/
-2:.align 4
-3:\desc
-4:.align 4
--.popsection
++#ifdef __STDC__
++#define ELFNOTE(name, type, desctype, descdata...) \
++.pushsection .note.name ; \
++ .align 4 ; \
++ .long 2f - 1f /* namesz */ ; \
++ .long 4f - 3f /* descsz */ ; \
++ .long type ; \
++1:.asciz #name ; \
++2:.align 4 ; \
++3:desctype descdata ; \
++4:.align 4 ; \
+ .popsection
-.endm
-+#define ELFNOTE(name, type, desctype, descdata) \
++#else /* !__STDC__, i.e. -traditional */
++#define ELFNOTE(name, type, desctype, descdata) \
+.pushsection .note.name ; \
+ .align 4 ; \
+ .long 2f - 1f /* namesz */ ; \
@@ -37,7 +49,8 @@ diff -pruN ../orig-linux-2.6.18/include/
+2:.align 4 ; \
+3:desctype descdata ; \
+4:.align 4 ; \
-+.popsection ;
++.popsection
++#endif /* __STDC__ */
#else /* !__ASSEMBLER__ */
#include <linux/elf.h>
/*
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/Makefile Tue Feb 20 12:58:22 2007 -0700
@@ -5,7 +5,7 @@ INCLUDES += -I.. -I../lib
IBIN = blktapctrl tapdisk
QCOW_UTIL = img2qcow qcow2raw qcow-create
-INST_DIR = /usr/sbin
+INST_DIR = /usr/sbin
LIBAIO_DIR = ../../libaio/src
CFLAGS += -Werror
@@ -17,7 +17,7 @@ CFLAGS += -D_GNU_SOURCE
# Get gcc to generate the dependencies for us.
CFLAGS += -Wp,-MD,.$(@F).d
-DEPS = .*.d
+DEPS = .*.d
THREADLIB := -lpthread -lz
LIBS := -L. -L.. -L../lib
@@ -29,10 +29,10 @@ LIBS += -L$(XEN_XENSTORE) -lxenstor
AIOLIBS := $(LIBAIO_DIR)/libaio.a
-BLK-OBJS := block-aio.o
-BLK-OBJS += block-sync.o
+BLK-OBJS := block-aio.o
+BLK-OBJS += block-sync.o
BLK-OBJS += block-vmdk.o
-BLK-OBJS += block-ram.o
+BLK-OBJS += block-ram.o
BLK-OBJS += block-qcow.o
BLK-OBJS += aes.o
@@ -52,13 +52,13 @@ qcow-util: img2qcow qcow2raw qcow-create
qcow-util: img2qcow qcow2raw qcow-create
img2qcow qcow2raw qcow-create: %: $(BLK-OBJS)
- $(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS) $(LIBS)
+ $(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS) $(LIBS)
install: all
- $(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(DESTDIR)$(INST_DIR)
+ $(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(VHD_UTIL) $(DESTDIR)$(INST_DIR)
clean:
- rm -rf *.o *~ $(DEPS) xen TAGS $(IBIN) $(LIB) $(QCOW_UTIL)
+ rm -rf *.o *~ $(DEPS) xen TAGS $(IBIN) $(LIB) $(QCOW_UTIL) $(VHD_UTIL)
.PHONY: clean install
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-aio.c Tue Feb 20 12:58:22 2007 -0700
@@ -58,6 +58,7 @@ struct pending_aio {
td_callback_t cb;
int id;
void *private;
+ uint64_t lsec;
};
struct tdaio_state {
@@ -139,12 +140,23 @@ static int get_image_info(struct td_stat
return 0;
}
+static inline void init_fds(struct disk_driver *dd)
+{
+ int i;
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
+
+ for(i = 0; i < MAX_IOFD; i++)
+ dd->io_fd[i] = 0;
+
+ dd->io_fd[0] = prv->poll_fd;
+}
+
/* Open the disk file and initialize aio state. */
-int tdaio_open (struct td_state *s, const char *name)
+int tdaio_open (struct disk_driver *dd, const char *name)
{
int i, fd, ret = 0;
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
- s->private = prv;
+ struct td_state *s = dd->td_state;
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
DPRINTF("block-aio open('%s')", name);
/* Initialize AIO */
@@ -194,18 +206,21 @@ int tdaio_open (struct td_state *s, cons
prv->fd = fd;
+ init_fds(dd);
ret = get_image_info(s, fd);
+
done:
return ret;
}
-int tdaio_queue_read(struct td_state *s, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
- int id, void *private)
+int tdaio_queue_read(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
{
struct iocb *io;
struct pending_aio *pio;
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
+ struct td_state *s = dd->td_state;
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
int size = nb_sectors * s->sector_size;
uint64_t offset = sector * (uint64_t)s->sector_size;
long ioidx;
@@ -219,22 +234,24 @@ int tdaio_queue_read(struct td_state *s,
pio->cb = cb;
pio->id = id;
pio->private = private;
+ pio->lsec = sector;
io_prep_pread(io, prv->fd, buf, size, offset);
io->data = (void *)ioidx;
prv->iocb_queue[prv->iocb_queued++] = io;
-
- return 0;
-}
-
-int tdaio_queue_write(struct td_state *s, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
- int id, void *private)
+
+ return 0;
+}
+
+int tdaio_queue_write(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
{
struct iocb *io;
struct pending_aio *pio;
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
+ struct td_state *s = dd->td_state;
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
int size = nb_sectors * s->sector_size;
uint64_t offset = sector * (uint64_t)s->sector_size;
long ioidx;
@@ -248,19 +265,20 @@ int tdaio_queue_write(struct td_state *s
pio->cb = cb;
pio->id = id;
pio->private = private;
+ pio->lsec = sector;
io_prep_pwrite(io, prv->fd, buf, size, offset);
io->data = (void *)ioidx;
prv->iocb_queue[prv->iocb_queued++] = io;
-
- return 0;
-}
-
-int tdaio_submit(struct td_state *s)
+
+ return 0;
+}
+
+int tdaio_submit(struct disk_driver *dd)
{
int ret;
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
@@ -269,38 +287,24 @@ int tdaio_submit(struct td_state *s)
/* Success case: */
prv->iocb_queued = 0;
- return ret;
-}
-
-int *tdaio_get_fd(struct td_state *s)
-{
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
- int *fds, i;
-
- fds = malloc(sizeof(int) * MAX_IOFD);
- /*initialise the FD array*/
- for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
- fds[0] = prv->poll_fd;
-
- return fds;
-}
-
-int tdaio_close(struct td_state *s)
-{
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
+ return 0;
+}
+
+int tdaio_close(struct disk_driver *dd)
+{
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
io_destroy(prv->aio_ctx);
close(prv->fd);
-
- return 0;
-}
-
-int tdaio_do_callbacks(struct td_state *s, int sid)
+
+ return 0;
+}
+
+int tdaio_do_callbacks(struct disk_driver *dd, int sid)
{
int ret, i, rsp = 0;
struct io_event *ep;
- struct tdaio_state *prv = (struct tdaio_state *)s->private;
+ struct tdaio_state *prv = (struct tdaio_state *)dd->private;
/* Non-blocking test for completed io. */
ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
@@ -311,22 +315,34 @@ int tdaio_do_callbacks(struct td_state *
struct pending_aio *pio;
pio = &prv->pending_aio[(long)io->data];
- rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1,
+ rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1,
+ pio->lsec, io->u.c.nbytes >> 9,
pio->id, pio->private);
prv->iocb_free[prv->iocb_free_count++] = io;
}
return rsp;
}
-
+
+int tdaio_has_parent(struct disk_driver *dd)
+{
+ return 0;
+}
+
+int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+{
+ return -EINVAL;
+}
+
struct tap_disk tapdisk_aio = {
- "tapdisk_aio",
- sizeof(struct tdaio_state),
- tdaio_open,
- tdaio_queue_read,
- tdaio_queue_write,
- tdaio_submit,
- tdaio_get_fd,
- tdaio_close,
- tdaio_do_callbacks,
+ .disk_type = "tapdisk_aio",
+ .private_data_size = sizeof(struct tdaio_state),
+ .td_open = tdaio_open,
+ .td_queue_read = tdaio_queue_read,
+ .td_queue_write = tdaio_queue_write,
+ .td_submit = tdaio_submit,
+ .td_has_parent = tdaio_has_parent,
+ .td_get_parent = tdaio_get_parent,
+ .td_close = tdaio_close,
+ .td_do_callbacks = tdaio_do_callbacks,
};
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-qcow.c Tue Feb 20 12:58:22 2007 -0700
@@ -55,7 +55,6 @@
/******AIO DEFINES******/
#define REQUEST_ASYNC_FD 1
-#define MAX_QCOW_IDS 0xFFFF
#define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
struct pending_aio {
@@ -65,7 +64,6 @@ struct pending_aio {
int nb_sectors;
char *buf;
uint64_t sector;
- int qcow_idx;
};
#define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
@@ -115,9 +113,9 @@ struct tdqcow_state {
struct tdqcow_state {
int fd; /*Main Qcow file descriptor */
uint64_t fd_end; /*Store a local record of file length */
- int bfd; /*Backing file descriptor*/
char *name; /*Record of the filename*/
- int poll_pipe[2]; /*dummy fd for polling on */
+ uint32_t backing_file_size;
+ uint64_t backing_file_offset;
int encrypted; /*File contents are encrypted or plain*/
int cluster_bits; /*Determines length of cluster as
*indicated by file hdr*/
@@ -149,7 +147,6 @@ struct tdqcow_state {
AES_KEY aes_decrypt_key; /*AES key*/
/* libaio state */
io_context_t aio_ctx;
- int nr_reqs [MAX_QCOW_IDS];
struct iocb iocb_list [MAX_AIO_REQS];
struct iocb *iocb_free [MAX_AIO_REQS];
struct pending_aio pending_aio[MAX_AIO_REQS];
@@ -162,10 +159,11 @@ struct tdqcow_state {
static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
-static int init_aio_state(struct td_state *bs)
+static int init_aio_state(struct disk_driver *dd)
{
int i;
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+ struct td_state *bs = dd->td_state;
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
long ioidx;
/*Initialize Locking bitmap*/
@@ -202,8 +200,7 @@ static int init_aio_state(struct td_stat
for (i=0;i<MAX_AIO_REQS;i++)
s->iocb_free[i] = &s->iocb_list[i];
- for (i=0;i<MAX_QCOW_IDS;i++)
- s->nr_reqs[i] = 0;
+
DPRINTF("AIO state initialised\n");
return 0;
@@ -238,7 +235,10 @@ static uint32_t gen_cksum(char *ptr, int
if(!md) return 0;
- if (MD5((unsigned char *)ptr, len, md) != md) return 0;
+ if (MD5((unsigned char *)ptr, len, md) != md) {
+ free(md);
+ return 0;
+ }
memcpy(&ret, md, sizeof(uint32_t));
free(md);
@@ -247,26 +247,42 @@ static uint32_t gen_cksum(char *ptr, int
static int get_filesize(char *filename, uint64_t *size, struct stat *st)
{
- int blockfd;
+ int fd;
+ QCowHeader header;
/*Set to the backing file size*/
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ if (read(fd, &header, sizeof(header)) < sizeof(header)) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ be32_to_cpus(&header.magic);
+ be64_to_cpus(&header.size);
+ if (header.magic == QCOW_MAGIC) {
+ *size = header.size >> SECTOR_SHIFT;
+ return 0;
+ }
+
if(S_ISBLK(st->st_mode)) {
- blockfd = open(filename, O_RDONLY);
- if (blockfd < 0)
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
return -1;
- if (ioctl(blockfd,BLKGETSIZE,size)!=0) {
+ if (ioctl(fd,BLKGETSIZE,size)!=0) {
printf("Unable to get Block device size\n");
- close(blockfd);
+ close(fd);
return -1;
}
- close(blockfd);
+ close(fd);
} else *size = (st->st_size >> SECTOR_SHIFT);
return 0;
}
-static int qcow_set_key(struct td_state *bs, const char *key)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+static int qcow_set_key(struct tdqcow_state *s, const char *key)
+{
uint8_t keybuf[16];
int len, i;
@@ -306,10 +322,9 @@ static int qcow_set_key(struct td_state
return 0;
}
-static int async_read(struct tdqcow_state *s, int fd, int size,
- uint64_t offset,
- char *buf, td_callback_t cb,
- int id, uint64_t sector, int qcow_idx, void *private)
+static int async_read(struct tdqcow_state *s, int size,
+ uint64_t offset, char *buf, td_callback_t cb,
+ int id, uint64_t sector, void *private)
{
struct iocb *io;
struct pending_aio *pio;
@@ -325,9 +340,8 @@ static int async_read(struct tdqcow_stat
pio->nb_sectors = size/512;
pio->buf = buf;
pio->sector = sector;
- pio->qcow_idx = qcow_idx;
-
- io_prep_pread(io, fd, buf, size, offset);
+
+ io_prep_pread(io, s->fd, buf, size, offset);
io->data = (void *)ioidx;
s->iocb_queue[s->iocb_queued++] = io;
@@ -335,10 +349,9 @@ static int async_read(struct tdqcow_stat
return 1;
}
-static int async_write(struct tdqcow_state *s, int fd, int size,
- uint64_t offset,
- char *buf, td_callback_t cb,
- int id, uint64_t sector, int qcow_idx, void *private)
+static int async_write(struct tdqcow_state *s, int size,
+ uint64_t offset, char *buf, td_callback_t cb,
+ int id, uint64_t sector, void *private)
{
struct iocb *io;
struct pending_aio *pio;
@@ -354,9 +367,8 @@ static int async_write(struct tdqcow_sta
pio->nb_sectors = size/512;
pio->buf = buf;
pio->sector = sector;
- pio->qcow_idx = qcow_idx;
-
- io_prep_pwrite(io, fd, buf, size, offset);
+
+ io_prep_pwrite(io, s->fd, buf, size, offset);
io->data = (void *)ioidx;
s->iocb_queue[s->iocb_queued++] = io;
@@ -381,17 +393,6 @@ static void aio_unlock(struct tdqcow_sta
--s->sector_lock[sector];
return;
-}
-
-/*TODO - Use a freelist*/
-static int get_free_idx(struct tdqcow_state *s)
-{
- int i;
-
- for(i = 0; i < MAX_QCOW_IDS; i++) {
- if(s->nr_reqs[i] == 0) return i;
- }
- return -1;
}
/*
@@ -425,23 +426,23 @@ static int qtruncate(int fd, off_t lengt
{
int ret, i;
int current = 0, rem = 0;
- int sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
+ uint64_t sectors;
struct stat st;
- char buf[DEFAULT_SECTOR_SIZE];
+ char *buf;
/* If length is greater than the current file len
* we synchronously write zeroes to the end of the
* file, otherwise we truncate the length down
*/
- memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
ret = fstat(fd, &st);
- if (ret == -1)
+ if (ret == -1)
return -1;
if (S_ISBLK(st.st_mode))
return 0;
-
+
+ sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
- rem = st.st_size % DEFAULT_SECTOR_SIZE;
+ rem = st.st_size % DEFAULT_SECTOR_SIZE;
/* If we are extending this file, we write zeros to the end --
* this tries to ensure that the extents allocated wind up being
@@ -449,28 +450,40 @@ static int qtruncate(int fd, off_t lengt
*/
if(st.st_size < sectors * DEFAULT_SECTOR_SIZE) {
/*We are extending the file*/
+ if ((ret = posix_memalign((void **)&buf,
+ 512, DEFAULT_SECTOR_SIZE))) {
+ DPRINTF("posix_memalign failed: %d\n", ret);
+ return -1;
+ }
+ memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
if (lseek(fd, 0, SEEK_END)==-1) {
- fprintf(stderr,
- "Lseek EOF failed (%d), internal error\n",
+ DPRINTF("Lseek EOF failed (%d), internal error\n",
errno);
+ free(buf);
return -1;
}
if (rem) {
ret = write(fd, buf, rem);
- if (ret != rem)
+ if (ret != rem) {
+ DPRINTF("write failed: ret = %d, err = %s\n",
+ ret, strerror(errno));
+ free(buf);
return -1;
+ }
}
for (i = current; i < sectors; i++ ) {
ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
- if (ret != DEFAULT_SECTOR_SIZE)
+ if (ret != DEFAULT_SECTOR_SIZE) {
+ DPRINTF("write failed: ret = %d, err = %s\n",
+ ret, strerror(errno));
+ free(buf);
return -1;
- }
-
+ }
+ }
+ free(buf);
} else if(sparse && (st.st_size > sectors * DEFAULT_SECTOR_SIZE))
- if (ftruncate(fd, sectors * DEFAULT_SECTOR_SIZE)==-1) {
- fprintf(stderr,
- "Ftruncate failed (%d), internal error\n",
- errno);
+ if (ftruncate(fd, (off_t)sectors * DEFAULT_SECTOR_SIZE)==-1) {
+ DPRINTF("Ftruncate failed (%s)\n", strerror(errno));
return -1;
}
return 0;
@@ -490,12 +503,11 @@ static int qtruncate(int fd, off_t lengt
*
* return 0 if not allocated.
*/
-static uint64_t get_cluster_offset(struct td_state *bs,
+static uint64_t get_cluster_offset(struct tdqcow_state *s,
uint64_t offset, int allocate,
int compressed_size,
int n_start, int n_end)
{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
int min_index, i, j, l1_index, l2_index, l2_sector, l1_sector;
char *tmp_ptr, *tmp_ptr2, *l2_ptr, *l1_ptr;
uint64_t l2_offset, *l2_table, cluster_offset, tmp;
@@ -550,8 +562,10 @@ static uint64_t get_cluster_offset(struc
* entry is written before blocks.
*/
lseek(s->fd, s->l1_table_offset + (l1_sector << 12), SEEK_SET);
- if (write(s->fd, tmp_ptr, 4096) != 4096)
+ if (write(s->fd, tmp_ptr, 4096) != 4096) {
+ free(tmp_ptr);
return 0;
+ }
free(tmp_ptr);
new_l2_table = 1;
@@ -716,9 +730,10 @@ found:
return cluster_offset;
}
-static void init_cluster_cache(struct td_state *bs)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+static void init_cluster_cache(struct disk_driver *dd)
+{
+ struct td_state *bs = dd->td_state;
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
uint32_t count = 0;
int i, cluster_entries;
@@ -727,22 +742,20 @@ static void init_cluster_cache(struct td
cluster_entries, s->cluster_size);
for (i = 0; i < bs->size; i += cluster_entries) {
- if (get_cluster_offset(bs, i << 9, 0, 0, 0, 1)) count++;
+ if (get_cluster_offset(s, i << 9, 0, 0, 0, 1)) count++;
if (count >= L2_CACHE_SIZE) return;
}
DPRINTF("Finished cluster initialisation, added %d entries\n", count);
return;
}
-static int qcow_is_allocated(struct td_state *bs, int64_t sector_num,
+static int qcow_is_allocated(struct tdqcow_state *s, int64_t sector_num,
int nb_sectors, int *pnum)
{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-
int index_in_cluster, n;
uint64_t cluster_offset;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
+ cluster_offset = get_cluster_offset(s, sector_num << 9, 0, 0, 0, 0);
index_in_cluster = sector_num & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
@@ -800,11 +813,23 @@ static int decompress_cluster(struct tdq
return 0;
}
+static inline void init_fds(struct disk_driver *dd)
+{
+ int i;
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+
+ for(i = 0; i < MAX_IOFD; i++)
+ dd->io_fd[i] = 0;
+
+ dd->io_fd[0] = s->poll_fd;
+}
+
/* Open the disk file and initialize qcow state. */
-int tdqcow_open (struct td_state *bs, const char *name)
+int tdqcow_open (struct disk_driver *dd, const char *name)
{
int fd, len, i, shift, ret, size, l1_table_size;
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+ struct td_state *bs = dd->td_state;
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
char *buf;
QCowHeader *header;
QCowHeader_ext *exthdr;
@@ -812,10 +837,6 @@ int tdqcow_open (struct td_state *bs, co
uint64_t final_cluster = 0;
DPRINTF("QCOW: Opening %s\n",name);
- /* set up a pipe so that we can hand back a poll fd that won't fire.*/
- ret = pipe(s->poll_pipe);
- if (ret != 0)
- return (0 - errno);
fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
if (fd < 0) {
@@ -826,7 +847,7 @@ int tdqcow_open (struct td_state *bs, co
s->fd = fd;
asprintf(&s->name,"%s", name);
- ASSERT(sizeof(header) < 512);
+ ASSERT(sizeof(QCowHeader) + sizeof(QCowHeader_ext) < 512);
ret = posix_memalign((void **)&buf, 512, 512);
if (ret != 0) goto fail;
@@ -861,7 +882,9 @@ int tdqcow_open (struct td_state *bs, co
s->cluster_alloc = s->l2_size;
bs->size = header->size / 512;
s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
-
+ s->backing_file_offset = header->backing_file_offset;
+ s->backing_file_size = header->backing_file_size;
+
/* read the level 1 table */
shift = s->cluster_bits + s->l2_bits;
s->l1_size = (header->size + (1LL << shift) - 1) >> shift;
@@ -887,7 +910,7 @@ int tdqcow_open (struct td_state *bs, co
if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
goto fail;
- for(i = 0;i < s->l1_size; i++) {
+ for(i = 0; i < s->l1_size; i++) {
//be64_to_cpus(&s->l1_table[i]);
//DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
if (s->l1_table[i] > final_cluster)
@@ -907,41 +930,15 @@ int tdqcow_open (struct td_state *bs, co
if(ret != 0) goto fail;
s->cluster_cache_offset = -1;
- /* read the backing file name */
- s->bfd = -1;
- if (header->backing_file_offset != 0) {
- DPRINTF("Reading backing file data\n");
- len = header->backing_file_size;
- if (len > 1023)
- len = 1023;
-
- /*TODO - Fix read size for O_DIRECT and use original fd!*/
- fd = open(name, O_RDONLY | O_LARGEFILE);
-
- lseek(fd, header->backing_file_offset, SEEK_SET);
- if (read(fd, bs->backing_file, len) != len)
- goto fail;
- bs->backing_file[len] = '\0';
- close(fd);
- /***********************************/
-
- /*Open backing file*/
- fd = open(bs->backing_file, O_RDONLY | O_DIRECT | O_LARGEFILE);
- if (fd < 0) {
- DPRINTF("Unable to open backing file: %s\n",
- bs->backing_file);
- goto fail;
- }
- s->bfd = fd;
+ if (s->backing_file_offset != 0)
s->cluster_alloc = 1; /*Cannot use pre-alloc*/
- }
bs->sector_size = 512;
bs->info = 0;
/*Detect min_cluster_alloc*/
s->min_cluster_alloc = 1; /*Default*/
- if (s->bfd == -1 && (s->l1_table_offset % 4096 == 0) ) {
+ if (s->backing_file_offset == 0 && s->l1_table_offset % 4096 == 0) {
/*We test to see if the xen magic # exists*/
exthdr = (QCowHeader_ext *)(buf + sizeof(QCowHeader));
be32_to_cpus(&exthdr->xmagic);
@@ -962,10 +959,11 @@ int tdqcow_open (struct td_state *bs, co
}
end_xenhdr:
- if (init_aio_state(bs)!=0) {
+ if (init_aio_state(dd)!=0) {
DPRINTF("Unable to initialise AIO state\n");
goto fail;
}
+ init_fds(dd);
s->fd_end = (final_cluster == 0 ? (s->l1_table_offset + l1_table_size)
:
(final_cluster + s->cluster_size));
@@ -981,213 +979,145 @@ fail:
return -1;
}
- int tdqcow_queue_read(struct td_state *bs, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
- int id, void *private)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
- int ret = 0, index_in_cluster, n, i, qcow_idx, asubmit = 0;
- uint64_t cluster_offset;
+int tdqcow_queue_read(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
+{
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+ int ret = 0, index_in_cluster, n, i, rsp = 0;
+ uint64_t cluster_offset, sec, nr_secs;
+
+ sec = sector;
+ nr_secs = nb_sectors;
/*Check we can get a lock*/
- for (i = 0; i < nb_sectors; i++)
- if (!aio_can_lock(s, sector + i)) {
- DPRINTF("AIO_CAN_LOCK failed [%llu]\n",
- (long long) sector + i);
- return -EBUSY;
- }
-
+ for (i = 0; i < nb_sectors; i++)
+ if (!aio_can_lock(s, sector + i))
+ return cb(dd, -EBUSY, sector, nb_sectors, id, private);
+
/*We store a local record of the request*/
- qcow_idx = get_free_idx(s);
while (nb_sectors > 0) {
cluster_offset =
- get_cluster_offset(bs, sector << 9, 0, 0, 0, 0);
+ get_cluster_offset(s, sector << 9, 0, 0, 0, 0);
index_in_cluster = sector & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- if (s->iocb_free_count == 0 || !aio_lock(s, sector)) {
- DPRINTF("AIO_LOCK or iocb_free_count (%d) failed"
- "[%llu]\n", s->iocb_free_count,
- (long long) sector);
- return -ENOMEM;
- }
+ if (s->iocb_free_count == 0 || !aio_lock(s, sector))
+ return cb(dd, -EBUSY, sector, nb_sectors, id, private);
- if (!cluster_offset && (s->bfd > 0)) {
- s->nr_reqs[qcow_idx]++;
- asubmit += async_read(s, s->bfd, n * 512, sector << 9,
- buf, cb, id, sector,
- qcow_idx, private);
- } else if(!cluster_offset) {
- memset(buf, 0, 512 * n);
+ if(!cluster_offset) {
aio_unlock(s, sector);
+ ret = cb(dd, BLK_NOT_ALLOCATED,
+ sector, n, id, private);
+ if (ret == -EBUSY) {
+ /* mark remainder of request
+ * as busy and try again later */
+ return cb(dd, -EBUSY, sector + n,
+ nb_sectors - n, id, private);
+ } else rsp += ret;
} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+ aio_unlock(s, sector);
if (decompress_cluster(s, cluster_offset) < 0) {
- ret = -1;
+ rsp += cb(dd, -EIO, sector,
+ nb_sectors, id, private);
goto done;
}
memcpy(buf, s->cluster_cache + index_in_cluster * 512,
512 * n);
- } else {
- s->nr_reqs[qcow_idx]++;
- asubmit += async_read(s, s->fd, n * 512,
- (cluster_offset +
- index_in_cluster * 512),
- buf, cb, id, sector,
- qcow_idx, private);
+ rsp += cb(dd, 0, sector, n, id, private);
+ } else {
+ async_read(s, n * 512,
+ (cluster_offset + index_in_cluster * 512),
+ buf, cb, id, sector, private);
}
nb_sectors -= n;
sector += n;
buf += n * 512;
}
done:
- /*Callback if no async requests outstanding*/
- if (!asubmit) return cb(bs, ret == -1 ? -1 : 0, id, private);
-
- return 0;
-}
-
- int tdqcow_queue_write(struct td_state *bs, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
- int id, void *private)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
- int ret = 0, index_in_cluster, n, i, qcow_idx, asubmit = 0;
- uint64_t cluster_offset;
+ return rsp;
+}
+
+int tdqcow_queue_write(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
+{
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+ int ret = 0, index_in_cluster, n, i;
+ uint64_t cluster_offset, sec, nr_secs;
+
+ sec = sector;
+ nr_secs = nb_sectors;
/*Check we can get a lock*/
for (i = 0; i < nb_sectors; i++)
- if (!aio_can_lock(s, sector + i)) {
- DPRINTF("AIO_CAN_LOCK failed [%llu]\n",
- (long long) (sector + i));
- return -EBUSY;
- }
+ if (!aio_can_lock(s, sector + i))
+ return cb(dd, -EBUSY, sector, nb_sectors, id, private);
/*We store a local record of the request*/
- qcow_idx = get_free_idx(s);
while (nb_sectors > 0) {
index_in_cluster = sector & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- if (s->iocb_free_count == 0 || !aio_lock(s, sector)){
- DPRINTF("AIO_LOCK or iocb_free_count (%d) failed"
- "[%llu]\n", s->iocb_free_count,
- (long long) sector);
- return -ENOMEM;
- }
-
- if (!IS_ZERO(buf,n * 512)) {
-
- cluster_offset = get_cluster_offset(bs, sector << 9,
- 1, 0,
- index_in_cluster,
- index_in_cluster+n
- );
- if (!cluster_offset) {
- DPRINTF("Ooops, no write cluster offset!\n");
- ret = -1;
- goto done;
- }
-
- if (s->crypt_method) {
- encrypt_sectors(s, sector, s->cluster_data,
- (unsigned char *)buf, n, 1,
- &s->aes_encrypt_key);
- s->nr_reqs[qcow_idx]++;
- asubmit += async_write(s, s->fd, n * 512,
- (cluster_offset +
- index_in_cluster*512),
- (char *)s->cluster_data,
- cb, id, sector,
- qcow_idx, private);
- } else {
- s->nr_reqs[qcow_idx]++;
- asubmit += async_write(s, s->fd, n * 512,
- (cluster_offset +
- index_in_cluster*512),
- buf, cb, id, sector,
- qcow_idx, private);
- }
+ if (s->iocb_free_count == 0 || !aio_lock(s, sector))
+ return cb(dd, -EBUSY, sector, nb_sectors, id, private);
+
+ cluster_offset = get_cluster_offset(s, sector << 9, 1, 0,
+ index_in_cluster,
+ index_in_cluster+n);
+ if (!cluster_offset) {
+ DPRINTF("Ooops, no write cluster offset!\n");
+ return cb(dd, -EIO, sector, nb_sectors, id, private);
+ }
+
+ if (s->crypt_method) {
+ encrypt_sectors(s, sector, s->cluster_data,
+ (unsigned char *)buf, n, 1,
+ &s->aes_encrypt_key);
+ async_write(s, n * 512,
+ (cluster_offset + index_in_cluster*512),
+ (char *)s->cluster_data, cb, id, sector,
+ private);
} else {
- /*Write data contains zeros, but we must check to see
- if cluster already allocated*/
- cluster_offset = get_cluster_offset(bs, sector << 9,
- 0, 0,
- index_in_cluster,
- index_in_cluster+n
- );
- if(cluster_offset) {
- if (s->crypt_method) {
- encrypt_sectors(s, sector,
- s->cluster_data,
- (unsigned char *)buf,
- n, 1,
- &s->aes_encrypt_key);
- s->nr_reqs[qcow_idx]++;
- asubmit += async_write(s, s->fd,
- n * 512,
- (cluster_offset+
-
index_in_cluster * 512),
- (char
*)s->cluster_data, cb, id, sector,
- qcow_idx,
private);
- } else {
- s->nr_reqs[qcow_idx]++;
- asubmit += async_write(s, s->fd, n*512,
- cluster_offset +
index_in_cluster * 512,
- buf, cb, id,
sector,
- qcow_idx,
private);
- }
- }
- else aio_unlock(s, sector);
- }
+ async_write(s, n * 512,
+ (cluster_offset + index_in_cluster*512),
+ buf, cb, id, sector, private);
+ }
+
nb_sectors -= n;
sector += n;
buf += n * 512;
}
s->cluster_cache_offset = -1; /* disable compressed cache */
-done:
- /*Callback if no async requests outstanding*/
- if (!asubmit) return cb(bs, ret == -1 ? -1 : 0, id, private);
-
return 0;
}
-int tdqcow_submit(struct td_state *bs)
+int tdqcow_submit(struct disk_driver *dd)
{
int ret;
- struct tdqcow_state *prv = (struct tdqcow_state *)bs->private;
-
- ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
+ struct tdqcow_state *prv = (struct tdqcow_state *)dd->private;
+
+ if (!prv->iocb_queued)
+ return 0;
+
+ ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
/* XXX: TODO: Handle error conditions here. */
/* Success case: */
prv->iocb_queued = 0;
- return ret;
-}
-
-
-int *tdqcow_get_fd(struct td_state *bs)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
- int *fds, i;
-
- fds = malloc(sizeof(int) * MAX_IOFD);
- /*initialise the FD array*/
- for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
- fds[0] = s->poll_fd;
- return fds;
-}
-
-int tdqcow_close(struct td_state *bs)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+ return 0;
+}
+
+int tdqcow_close(struct disk_driver *dd)
+{
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
uint32_t cksum, out;
int fd, offset;
@@ -1203,6 +1133,7 @@ int tdqcow_close(struct td_state *bs)
close(fd);
}
+ io_destroy(s->aio_ctx);
free(s->name);
free(s->l1_table);
free(s->l2_cache);
@@ -1212,11 +1143,11 @@ int tdqcow_close(struct td_state *bs)
return 0;
}
-int tdqcow_do_callbacks(struct td_state *s, int sid)
+int tdqcow_do_callbacks(struct disk_driver *dd, int sid)
{
int ret, i, rsp = 0,*ptr;
struct io_event *ep;
- struct tdqcow_state *prv = (struct tdqcow_state *)s->private;
+ struct tdqcow_state *prv = (struct tdqcow_state *)dd->private;
if (sid > MAX_IOFD) return 1;
@@ -1224,25 +1155,24 @@ int tdqcow_do_callbacks(struct td_state
ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
NULL);
- for (ep=prv->aio_events, i = ret; i-->0; ep++) {
+ for (ep = prv->aio_events, i = ret; i-- > 0; ep++) {
struct iocb *io = ep->obj;
struct pending_aio *pio;
pio = &prv->pending_aio[(long)io->data];
aio_unlock(prv, pio->sector);
- if (pio->id >= 0) {
- if (prv->crypt_method)
- encrypt_sectors(prv, pio->sector,
- (unsigned char *)pio->buf,
- (unsigned char *)pio->buf,
- pio->nb_sectors, 0,
- &prv->aes_decrypt_key);
- prv->nr_reqs[pio->qcow_idx]--;
- if (prv->nr_reqs[pio->qcow_idx] == 0)
- rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0
: 1, pio->id,
- pio->private);
- } else if (pio->id == -2) free(pio->buf);
+
+ if (prv->crypt_method)
+ encrypt_sectors(prv, pio->sector,
+ (unsigned char *)pio->buf,
+ (unsigned char *)pio->buf,
+ pio->nb_sectors, 0,
+ &prv->aes_decrypt_key);
+
+ rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1,
+ pio->sector, pio->nb_sectors,
+ pio->id, pio->private);
prv->iocb_free[prv->iocb_free_count++] = io;
}
@@ -1250,7 +1180,7 @@ int tdqcow_do_callbacks(struct td_state
}
int qcow_create(const char *filename, uint64_t total_size,
- const char *backing_file, int sparse)
+ const char *backing_file, int sparse)
{
int fd, header_size, backing_filename_len, l1_size, i;
int shift, length, adjust, flags = 0, ret = 0;
@@ -1391,9 +1321,8 @@ int qcow_create(const char *filename, ui
return 0;
}
-int qcow_make_empty(struct td_state *bs)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+int qcow_make_empty(struct tdqcow_state *s)
+{
uint32_t l1_length = s->l1_size * sizeof(uint64_t);
memset(s->l1_table, 0, l1_length);
@@ -1412,19 +1341,16 @@ int qcow_make_empty(struct td_state *bs)
return 0;
}
-int qcow_get_cluster_size(struct td_state *bs)
-{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-
+int qcow_get_cluster_size(struct tdqcow_state *s)
+{
return s->cluster_size;
}
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
-int qcow_compress_cluster(struct td_state *bs, int64_t sector_num,
+int qcow_compress_cluster(struct tdqcow_state *s, int64_t sector_num,
const uint8_t *buf)
{
- struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
z_stream strm;
int ret, out_len;
uint8_t *out_buf;
@@ -1463,7 +1389,7 @@ int qcow_compress_cluster(struct td_stat
/* could not compress: write normal cluster */
//tdqcow_queue_write(bs, sector_num, buf, s->cluster_sectors);
} else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
+ cluster_offset = get_cluster_offset(s, sector_num << 9, 2,
out_len, 0, 0);
cluster_offset &= s->cluster_offset_mask;
lseek(s->fd, cluster_offset, SEEK_SET);
@@ -1477,15 +1403,54 @@ int qcow_compress_cluster(struct td_stat
return 0;
}
+int tdqcow_has_parent(struct disk_driver *dd)
+{
+ struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+ return (s->backing_file_offset ? 1 : 0);
+}
+
+int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd)
+{
+ off_t off;
+ char *buf, *filename;
+ int len, secs, ret = -1;
+ struct tdqcow_state *child = (struct tdqcow_state *)cdd->private;
+
+ if (!child->backing_file_offset)
+ return -1;
+
+ /* read the backing file name */
+ len = child->backing_file_size;
+ off = child->backing_file_offset - (child->backing_file_offset % 512);
+ secs = (len + (child->backing_file_offset - off) + 511) >> 9;
+
+ if (posix_memalign((void **)&buf, 512, secs << 9))
+ return -1;
+
+ if (lseek(child->fd, off, SEEK_SET) == (off_t)-1)
+ goto out;
+
+ if (read(child->fd, buf, secs << 9) != secs << 9)
+ goto out;
+ filename = buf + (child->backing_file_offset - off);
+ filename[len] = '\0';
+
+ /*Open backing file*/
+ ret = tdqcow_open(pdd, filename);
+ out:
+ free(buf);
+ return ret;
+}
+
struct tap_disk tapdisk_qcow = {
- "tapdisk_qcow",
- sizeof(struct tdqcow_state),
- tdqcow_open,
- tdqcow_queue_read,
- tdqcow_queue_write,
- tdqcow_submit,
- tdqcow_get_fd,
- tdqcow_close,
- tdqcow_do_callbacks,
+ .disk_type = "tapdisk_qcow",
+ .private_data_size = sizeof(struct tdqcow_state),
+ .td_open = tdqcow_open,
+ .td_queue_read = tdqcow_queue_read,
+ .td_queue_write = tdqcow_queue_write,
+ .td_submit = tdqcow_submit,
+ .td_has_parent = tdqcow_has_parent,
+ .td_get_parent = tdqcow_get_parent,
+ .td_close = tdqcow_close,
+ .td_do_callbacks = tdqcow_do_callbacks,
};
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-ram.c
--- a/tools/blktap/drivers/block-ram.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-ram.c Tue Feb 20 12:58:22 2007 -0700
@@ -123,14 +123,25 @@ static int get_image_info(struct td_stat
return 0;
}
+static inline void init_fds(struct disk_driver *dd)
+{
+ int i;
+ struct tdram_state *prv = (struct tdram_state *)dd->private;
+
+ for(i =0 ; i < MAX_IOFD; i++)
+ dd->io_fd[i] = 0;
+
+ dd->io_fd[0] = prv->poll_pipe[0];
+}
+
/* Open the disk file and initialize ram state. */
-int tdram_open (struct td_state *s, const char *name)
-{
+int tdram_open (struct disk_driver *dd, const char *name)
+{
+ char *p;
+ uint64_t size;
int i, fd, ret = 0, count = 0;
- struct tdram_state *prv = (struct tdram_state *)s->private;
- uint64_t size;
- char *p;
- s->private = prv;
+ struct td_state *s = dd->td_state;
+ struct tdram_state *prv = (struct tdram_state *)dd->private;
connections++;
@@ -209,88 +220,80 @@ int tdram_open (struct td_state *s, cons
ret = 0;
}
+ init_fds(dd);
done:
return ret;
}
- int tdram_queue_read(struct td_state *s, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
- int id, void *private)
-{
- struct tdram_state *prv = (struct tdram_state *)s->private;
+ int tdram_queue_read(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
+{
+ struct td_state *s = dd->td_state;
+ struct tdram_state *prv = (struct tdram_state *)dd->private;
int size = nb_sectors * s->sector_size;
uint64_t offset = sector * (uint64_t)s->sector_size;
- int ret;
memcpy(buf, img + offset, size);
- ret = size;
-
- cb(s, (ret < 0) ? ret: 0, id, private);
-
- return ret;
-}
-
- int tdram_queue_write(struct td_state *s, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
- int id, void *private)
-{
- struct tdram_state *prv = (struct tdram_state *)s->private;
+
+ return cb(dd, 0, sector, nb_sectors, id, private);
+}
+
+int tdram_queue_write(struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
+ int id, void *private)
+{
+ struct td_state *s = dd->td_state;
+ struct tdram_state *prv = (struct tdram_state *)dd->private;
int size = nb_sectors * s->sector_size;
uint64_t offset = sector * (uint64_t)s->sector_size;
- int ret;
-
- /*We assume that write access is controlled at a higher level for
multiple disks*/
+
+ /* We assume that write access is controlled
+ * at a higher level for multiple disks */
memcpy(img + offset, buf, size);
- ret = size;
-
- cb(s, (ret < 0) ? ret : 0, id, private);
-
- return ret;
+
+ return cb(dd, 0, sector, nb_sectors, id, private);
}
-int tdram_submit(struct td_state *s)
+int tdram_submit(struct disk_driver *dd)
{
return 0;
}
-
-int *tdram_get_fd(struct td_state *s)
-{
- struct tdram_state *prv = (struct tdram_state *)s->private;
- int *fds, i;
-
- fds = malloc(sizeof(int) * MAX_IOFD);
- /*initialise the FD array*/
- for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
- fds[0] = prv->poll_pipe[0];
- return fds;
-}
-
-int tdram_close(struct td_state *s)
-{
- struct tdram_state *prv = (struct tdram_state *)s->private;
+int tdram_close(struct disk_driver *dd)
+{
+ struct tdram_state *prv = (struct tdram_state *)dd->private;
connections--;
return 0;
}
-int tdram_do_callbacks(struct td_state *s, int sid)
+int tdram_do_callbacks(struct disk_driver *dd, int sid)
{
/* always ask for a kick */
return 1;
}
+int tdram_has_parent(struct disk_driver *dd)
+{
+ return 0;
+}
+
+int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+{
+ return -EINVAL;
+}
+
struct tap_disk tapdisk_ram = {
- "tapdisk_ram",
- sizeof(struct tdram_state),
- tdram_open,
- tdram_queue_read,
- tdram_queue_write,
- tdram_submit,
- tdram_get_fd,
- tdram_close,
- tdram_do_callbacks,
+ .disk_type = "tapdisk_ram",
+ .private_data_size = sizeof(struct tdram_state),
+ .td_open = tdram_open,
+ .td_queue_read = tdram_queue_read,
+ .td_queue_write = tdram_queue_write,
+ .td_submit = tdram_submit,
+ .td_has_parent = tdram_has_parent,
+ .td_get_parent = tdram_get_parent,
+ .td_close = tdram_close,
+ .td_do_callbacks = tdram_do_callbacks,
};
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-sync.c
--- a/tools/blktap/drivers/block-sync.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-sync.c Tue Feb 20 12:58:22 2007 -0700
@@ -106,12 +106,23 @@ static int get_image_info(struct td_stat
return 0;
}
+static inline void init_fds(struct disk_driver *dd)
+{
+ int i;
+ struct tdsync_state *prv = (struct tdsync_state *)dd->private;
+
+ for(i = 0; i < MAX_IOFD; i++)
+ dd->io_fd[i] = 0;
+
+ dd->io_fd[0] = prv->poll_pipe[0];
+}
+
/* Open the disk file and initialize aio state. */
-int tdsync_open (struct td_state *s, const char *name)
+int tdsync_open (struct disk_driver *dd, const char *name)
{
int i, fd, ret = 0;
- struct tdsync_state *prv = (struct tdsync_state *)s->private;
- s->private = prv;
+ struct td_state *s = dd->td_state;
+ struct tdsync_state *prv = (struct tdsync_state *)dd->private;
/* set up a pipe so that we can hand back a poll fd that won't fire.*/
ret = pipe(prv->poll_pipe);
@@ -138,16 +149,18 @@ int tdsync_open (struct td_state *s, con
prv->fd = fd;
+ init_fds(dd);
ret = get_image_info(s, fd);
done:
return ret;
}
- int tdsync_queue_read(struct td_state *s, uint64_t sector,
+ int tdsync_queue_read(struct disk_driver *dd, uint64_t sector,
int nb_sectors, char *buf, td_callback_t cb,
int id, void *private)
{
- struct tdsync_state *prv = (struct tdsync_state *)s->private;
+ struct td_state *s = dd->td_state;
+ struct tdsync_state *prv = (struct tdsync_state *)dd->private;
int size = nb_sectors * s->sector_size;
uint64_t offset = sector * (uint64_t)s->sector_size;
int ret;
@@ -162,16 +175,15 @@ done:
}
} else ret = 0 - errno;
- cb(s, (ret < 0) ? ret: 0, id, private);
-
- return 1;
-}
-
- int tdsync_queue_write(struct td_state *s, uint64_t sector,
+ return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private);
+}
+
+ int tdsync_queue_write(struct disk_driver *dd, uint64_t sector,
int nb_sectors, char *buf, td_callback_t cb,
int id, void *private)
{
- struct tdsync_state *prv = (struct tdsync_state *)s->private;
+ struct td_state *s = dd->td_state;
+ struct tdsync_state *prv = (struct tdsync_state *)dd->private;
int size = nb_sectors * s->sector_size;
uint64_t offset = sector * (uint64_t)s->sector_size;
int ret = 0;
@@ -186,34 +198,17 @@ done:
}
} else ret = 0 - errno;
- cb(s, (ret < 0) ? ret : 0, id, private);
-
- return 1;
+ return cb(dd, (ret < 0) ? ret : 0, sector, nb_sectors, id, private);
}
-int tdsync_submit(struct td_state *s)
+int tdsync_submit(struct disk_driver *dd)
{
return 0;
}
-
-int *tdsync_get_fd(struct td_state *s)
-{
- struct tdsync_state *prv = (struct tdsync_state *)s->private;
-
- int *fds, i;
-
- fds = malloc(sizeof(int) * MAX_IOFD);
- /*initialise the FD array*/
- for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
- fds[0] = prv->poll_pipe[0];
- return fds;
-}
-
-int tdsync_close(struct td_state *s)
-{
- struct tdsync_state *prv = (struct tdsync_state *)s->private;
+int tdsync_close(struct disk_driver *dd)
+{
+ struct tdsync_state *prv = (struct tdsync_state *)dd->private;
close(prv->fd);
close(prv->poll_pipe[0]);
@@ -222,21 +217,31 @@ int tdsync_close(struct td_state *s)
return 0;
}
-int tdsync_do_callbacks(struct td_state *s, int sid)
+int tdsync_do_callbacks(struct disk_driver *dd, int sid)
{
/* always ask for a kick */
return 1;
}
+int tdsync_has_parent(struct disk_driver *dd)
+{
+ return 0;
+}
+
+int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+{
+ return -EINVAL;
+}
+
struct tap_disk tapdisk_sync = {
- "tapdisk_sync",
- sizeof(struct tdsync_state),
- tdsync_open,
- tdsync_queue_read,
- tdsync_queue_write,
- tdsync_submit,
- tdsync_get_fd,
- tdsync_close,
- tdsync_do_callbacks,
+ .disk_type = "tapdisk_sync",
+ .private_data_size = sizeof(struct tdsync_state),
+ .td_open = tdsync_open,
+ .td_queue_read = tdsync_queue_read,
+ .td_queue_write = tdsync_queue_write,
+ .td_submit = tdsync_submit,
+ .td_has_parent = tdsync_has_parent,
+ .td_get_parent = tdsync_get_parent,
+ .td_close = tdsync_close,
+ .td_do_callbacks = tdsync_do_callbacks,
};
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-vmdk.c
--- a/tools/blktap/drivers/block-vmdk.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-vmdk.c Tue Feb 20 12:58:22 2007 -0700
@@ -107,14 +107,25 @@ struct tdvmdk_state {
unsigned int cluster_sectors;
};
+static inline void init_fds(struct disk_driver *dd)
+{
+ int i;
+ struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
+
+ for (i = 0; i < MAX_IOFD; i++)
+ dd->io_fd[i] = 0;
+
+ dd->io_fd[0] = prv->poll_pipe[0];
+}
/* Open the disk file and initialize aio state. */
-static int tdvmdk_open (struct td_state *s, const char *name)
+static int tdvmdk_open (struct disk_driver *dd, const char *name)
{
int ret, fd;
int l1_size, i;
uint32_t magic;
- struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+ struct td_state *s = dd->td_state;
+ struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
/* set up a pipe so that we can hand back a poll fd that won't fire.*/
ret = pipe(prv->poll_pipe);
@@ -206,6 +217,7 @@ static int tdvmdk_open (struct td_state
if (!prv->l2_cache)
goto fail;
prv->fd = fd;
+ init_fds(dd);
DPRINTF("VMDK File opened successfully\n");
return 0;
@@ -218,10 +230,9 @@ fail:
return -1;
}
-static uint64_t get_cluster_offset(struct td_state *s,
+static uint64_t get_cluster_offset(struct tdvmdk_state *prv,
uint64_t offset, int allocate)
{
- struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
uint32_t min_count, *l2_table, tmp;
@@ -291,16 +302,17 @@ static uint64_t get_cluster_offset(struc
return cluster_offset;
}
-static int tdvmdk_queue_read(struct td_state *s, uint64_t sector,
+static int tdvmdk_queue_read(struct disk_driver *dd, uint64_t sector,
int nb_sectors, char *buf, td_callback_t cb,
int id, void *private)
{
- struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+ struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
int index_in_cluster, n;
uint64_t cluster_offset;
int ret = 0;
+
while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(s, sector << 9, 0);
+ cluster_offset = get_cluster_offset(prv, sector << 9, 0);
index_in_cluster = sector % prv->cluster_sectors;
n = prv->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
@@ -321,27 +333,24 @@ static int tdvmdk_queue_read(struct td_s
buf += n * 512;
}
done:
- cb(s, ret == -1 ? -1 : 0, id, private);
-
- return 1;
-}
-
-static int tdvmdk_queue_write(struct td_state *s, uint64_t sector,
+ return cb(dd, ret == -1 ? -1 : 0, sector, nb_sectors, id, private);
+}
+
+static int tdvmdk_queue_write(struct disk_driver *dd, uint64_t sector,
int nb_sectors, char *buf, td_callback_t cb,
int id, void *private)
{
- struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+ struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
int index_in_cluster, n;
uint64_t cluster_offset;
int ret = 0;
-
while (nb_sectors > 0) {
index_in_cluster = sector & (prv->cluster_sectors - 1);
n = prv->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- cluster_offset = get_cluster_offset(s, sector << 9, 1);
+ cluster_offset = get_cluster_offset(prv, sector << 9, 1);
if (!cluster_offset) {
ret = -1;
goto done;
@@ -358,33 +367,17 @@ static int tdvmdk_queue_write(struct td
buf += n * 512;
}
done:
- cb(s, ret == -1 ? -1 : 0, id, private);
-
- return 1;
+ return cb(dd, ret == -1 ? -1 : 0, sector, nb_sectors, id, private);
}
-static int tdvmdk_submit(struct td_state *s)
+static int tdvmdk_submit(struct disk_driver *dd)
{
return 0;
}
-
-static int *tdvmdk_get_fd(struct td_state *s)
-{
- struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
- int *fds, i;
-
- fds = malloc(sizeof(int) * MAX_IOFD);
- /*initialise the FD array*/
- for (i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
- fds[0] = prv->poll_pipe[0];
- return fds;
-}
-
-static int tdvmdk_close(struct td_state *s)
-{
- struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+static int tdvmdk_close(struct disk_driver *dd)
+{
+ struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
safer_free(prv->l1_table);
safer_free(prv->l1_backup_table);
@@ -395,21 +388,31 @@ static int tdvmdk_close(struct td_state
return 0;
}
-static int tdvmdk_do_callbacks(struct td_state *s, int sid)
+static int tdvmdk_do_callbacks(struct disk_driver *dd, int sid)
{
/* always ask for a kick */
return 1;
}
+static int tdvmdk_has_parent(struct disk_driver *dd)
+{
+ return 0;
+}
+
+static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver
*parent)
+{
+ return -EINVAL;
+}
+
struct tap_disk tapdisk_vmdk = {
- "tapdisk_vmdk",
- sizeof(struct tdvmdk_state),
- tdvmdk_open,
- tdvmdk_queue_read,
- tdvmdk_queue_write,
- tdvmdk_submit,
- tdvmdk_get_fd,
- tdvmdk_close,
- tdvmdk_do_callbacks,
+ .disk_type = "tapdisk_vmdk",
+ .private_data_size = sizeof(struct tdvmdk_state),
+ .td_open = tdvmdk_open,
+ .td_queue_read = tdvmdk_queue_read,
+ .td_queue_write = tdvmdk_queue_write,
+ .td_submit = tdvmdk_submit,
+ .td_has_parent = tdvmdk_has_parent,
+ .td_get_parent = tdvmdk_get_parent,
+ .td_close = tdvmdk_close,
+ .td_do_callbacks = tdvmdk_do_callbacks,
};
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/img2qcow.c
--- a/tools/blktap/drivers/img2qcow.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/img2qcow.c Tue Feb 20 12:58:22 2007 -0700
@@ -147,7 +147,8 @@ static int get_image_info(struct td_stat
return 0;
}
-static int send_responses(struct td_state *s, int res, int idx, void *private)
+static int send_responses(struct disk_driver *dd, int res, uint64_t sec,
+ int nr_secs, int idx, void *private)
{
if (res < 0) DFPRINTF("AIO FAILURE: res [%d]!\n",res);
@@ -159,7 +160,7 @@ static int send_responses(struct td_stat
int main(int argc, char *argv[])
{
- struct tap_disk *drv;
+ struct disk_driver dd;
struct td_state *s;
int ret = -1, fd, len;
fd_set readfds;
@@ -195,16 +196,17 @@ int main(int argc, char *argv[])
} else DFPRINTF("Qcow file created: size %llu sectors\n",
(long long unsigned)s->size);
- drv = &tapdisk_qcow;
- s->private = malloc(drv->private_data_size);
+ dd.td_state = s;
+ dd.drv = &tapdisk_qcow;
+ dd.private = malloc(dd.drv->private_data_size);
/*Open qcow file*/
- if (drv->td_open(s, argv[1])!=0) {
+ if (dd.drv->td_open(&dd, argv[1])!=0) {
DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]);
exit(-1);
}
- io_fd = drv->td_get_fd(s);
+ io_fd = dd.io_fd;
/*Initialise the output string*/
memset(output,0x20,25);
@@ -245,9 +247,9 @@ int main(int argc, char *argv[])
len = (len >> 9) << 9;
}
- ret = drv->td_queue_write(s, i >> 9,
- len >> 9, buf,
- send_responses, 0, buf);
+ ret = dd.drv->td_queue_write(&dd, i >> 9,
+ len >> 9, buf,
+ send_responses, 0, buf);
if (!ret) submit_events++;
@@ -261,7 +263,7 @@ int main(int argc, char *argv[])
debug_output(i,s->size << 9);
if ((submit_events % 10 == 0) || complete)
- drv->td_submit(s);
+ dd.drv->td_submit(&dd);
timeout.tv_usec = 0;
} else {
@@ -275,14 +277,14 @@ int main(int argc, char *argv[])
ret = select(maxfds + 1, &readfds, (fd_set *) 0,
(fd_set *) 0, &timeout);
- if (ret > 0) drv->td_do_callbacks(s, 0);
+ if (ret > 0) dd.drv->td_do_callbacks(&dd, 0);
if (complete && (returned_events == submit_events))
running = 0;
}
memcpy(output+prev+1,"=",1);
DFPRINTF("\r%s 100%%\nTRANSFER COMPLETE\n\n", output);
- drv->td_close(s);
- free(s->private);
+ dd.drv->td_close(&dd);
+ free(dd.private);
free(s);
return 0;
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/qcow2raw.c
--- a/tools/blktap/drivers/qcow2raw.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/qcow2raw.c Tue Feb 20 12:58:22 2007 -0700
@@ -55,8 +55,7 @@ static int returned_read_events = 0, ret
static int returned_read_events = 0, returned_write_events = 0;
static int submit_events = 0;
static uint32_t read_idx = 0, write_idx = 0;
-struct tap_disk *drv1, *drv2;
-struct td_state *sqcow, *saio;
+struct disk_driver ddqcow, ddaio;
static uint64_t prev = 0, written = 0;
static char output[25];
@@ -100,7 +99,8 @@ static inline void LOCAL_FD_SET(fd_set *
return;
}
-static int send_write_responses(struct td_state *s, int res, int idx, void
*private)
+static int send_write_responses(struct disk_driver *dd, int res, uint64_t sec,
+ int nr_secs, int idx, void *private)
{
if (res < 0) {
DFPRINTF("AIO FAILURE: res [%d]!\n",res);
@@ -112,12 +112,13 @@ static int send_write_responses(struct t
if (complete && (returned_write_events == submit_events))
write_complete = 1;
- debug_output(written, s->size << 9);
+ debug_output(written, dd->td_state->size << 9);
free(private);
return 0;
}
-static int send_read_responses(struct td_state *s, int res, int idx, void
*private)
+static int send_read_responses(struct disk_driver *dd, int res, uint64_t sec,
+ int nr_secs, int idx, void *private)
{
int ret;
@@ -128,8 +129,8 @@ static int send_read_responses(struct td
if (complete && (returned_read_events == submit_events))
read_complete = 1;
- ret = drv2->td_queue_write(saio, idx, BLOCK_PROCESSSZ>>9, private,
- send_write_responses, idx, private);
+ ret = ddaio.drv->td_queue_write(&ddaio, idx, BLOCK_PROCESSSZ>>9,
private,
+ send_write_responses, idx, private);
if (ret != 0) {
DFPRINTF("ERROR in submitting queue write!\n");
return 0;
@@ -137,7 +138,7 @@ static int send_read_responses(struct td
if ( (complete && returned_read_events == submit_events) ||
(returned_read_events % 10 == 0) ) {
- drv2->td_submit(saio);
+ ddaio.drv->td_submit(&ddaio);
}
return 0;
@@ -161,20 +162,20 @@ int main(int argc, char *argv[])
exit(-1);
}
- sqcow = malloc(sizeof(struct td_state));
- saio = malloc(sizeof(struct td_state));
+ ddqcow.td_state = malloc(sizeof(struct td_state));
+ ddaio.td_state = malloc(sizeof(struct td_state));
/*Open qcow source file*/
- drv1 = &tapdisk_qcow;
- sqcow->private = malloc(drv1->private_data_size);
-
- if (drv1->td_open(sqcow, argv[2])!=0) {
+ ddqcow.drv = &tapdisk_qcow;
+ ddqcow.private = malloc(ddqcow.drv->private_data_size);
+
+ if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) {
DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]);
exit(-1);
} else DFPRINTF("QCOW file opened, size %llu\n",
- (long long unsigned)sqcow->size);
-
- qcowio_fd = drv1->td_get_fd(sqcow);
+ (long long unsigned)ddqcow.td_state->size);
+
+ qcowio_fd = ddqcow.io_fd;
/*Setup aio destination file*/
ret = stat(argv[1],&finfo);
@@ -191,12 +192,12 @@ int main(int argc, char *argv[])
argv[1], 0 - errno);
exit(-1);
}
- if (ftruncate(fd, (off_t)sqcow->size<<9) < 0) {
+ if (ftruncate(fd, (off_t)ddqcow.td_state->size<<9) < 0)
{
DFPRINTF("Unable to create file "
"[%s] of size %llu (errno %d). "
"Exiting...\n",
argv[1],
- (long long unsigned)sqcow->size<<9,
+ (long long
unsigned)ddqcow.td_state->size<<9,
0 - errno);
close(fd);
exit(-1);
@@ -238,43 +239,43 @@ int main(int argc, char *argv[])
close(fd);
exit(-1);
}
- if (size < sqcow->size<<9) {
+ if (size < ddqcow.td_state->size<<9) {
DFPRINTF("ERROR: Not enough space on device "
"%s (%lu bytes available, %llu bytes
required\n",
argv[1], size,
- (long long unsigned)sqcow->size<<9);
+ (long long
unsigned)ddqcow.td_state->size<<9);
close(fd);
exit(-1);
}
} else {
- if (ftruncate(fd, (off_t)sqcow->size<<9) < 0) {
+ if (ftruncate(fd, (off_t)ddqcow.td_state->size<<9) < 0)
{
DFPRINTF("Unable to create file "
"[%s] of size %llu (errno %d). "
"Exiting...\n",
argv[1],
- (long long unsigned)sqcow->size<<9,
+ (long long
unsigned)ddqcow.td_state->size<<9,
0 - errno);
close(fd);
exit(-1);
} else DFPRINTF("File [%s] truncated to length %llu "
"(%llu)\n",
argv[1],
- (long long unsigned)sqcow->size<<9,
- (long long unsigned)sqcow->size);
+ (long long
unsigned)ddqcow.td_state->size<<9,
+ (long long
unsigned)ddqcow.td_state->size);
}
close(fd);
}
/*Open aio destination file*/
- drv2 = &tapdisk_aio;
- saio->private = malloc(drv2->private_data_size);
-
- if (drv2->td_open(saio, argv[1])!=0) {
+ ddaio.drv = &tapdisk_aio;
+ ddaio.private = malloc(ddaio.drv->private_data_size);
+
+ if (ddaio.drv->td_open(&ddaio, argv[1])!=0) {
DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]);
exit(-1);
}
- aio_fd = drv2->td_get_fd(saio);
+ aio_fd = ddaio.io_fd;
/*Initialise the output string*/
memset(output,0x20,25);
@@ -298,9 +299,9 @@ int main(int argc, char *argv[])
}
/*Attempt to read 4k sized blocks*/
- ret = drv1->td_queue_read(sqcow, i>>9,
- BLOCK_PROCESSSZ>>9, buf,
- send_read_responses, i>>9,
buf);
+ ret = ddqcow.drv->td_queue_read(&ddqcow, i>>9,
+ BLOCK_PROCESSSZ>>9,
buf,
+ send_read_responses,
i>>9, buf);
if (ret < 0) {
DFPRINTF("UNABLE TO READ block [%llu]\n",
@@ -311,12 +312,12 @@ int main(int argc, char *argv[])
submit_events++;
}
- if (i >= sqcow->size<<9) {
+ if (i >= ddqcow.td_state->size<<9) {
complete = 1;
}
if ((submit_events % 10 == 0) || complete)
- drv1->td_submit(sqcow);
+ ddqcow.drv->td_submit(&ddqcow);
timeout.tv_usec = 0;
} else {
@@ -332,9 +333,9 @@ int main(int argc, char *argv[])
if (ret > 0) {
if (FD_ISSET(qcowio_fd[0], &readfds))
- drv1->td_do_callbacks(sqcow, 0);
+ ddqcow.drv->td_do_callbacks(&ddqcow, 0);
if (FD_ISSET(aio_fd[0], &readfds))
- drv2->td_do_callbacks(saio, 0);
+ ddaio.drv->td_do_callbacks(&ddaio, 0);
}
if (complete && (returned_write_events == submit_events))
running = 0;
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/tapdisk.c Tue Feb 20 12:58:22 2007 -0700
@@ -48,6 +48,12 @@ int connected_disks = 0;
int connected_disks = 0;
fd_list_entry_t *fd_start = NULL;
+int do_cow_read(struct disk_driver *dd, blkif_request_t *req,
+ int sidx, uint64_t sector, int nr_secs);
+
+#define td_for_each_disk(tds, drv) \
+ for (drv = tds->disks; drv != NULL; drv = drv->next)
+
void usage(void)
{
fprintf(stderr, "blktap-utils: v1.0.0\n");
@@ -78,10 +84,17 @@ static void unmap_disk(struct td_state *
static void unmap_disk(struct td_state *s)
{
tapdev_info_t *info = s->ring_info;
- struct tap_disk *drv = s->drv;
+ struct disk_driver *dd, *tmp;
fd_list_entry_t *entry;
- drv->td_close(s);
+ dd = s->disks;
+ while (dd) {
+ tmp = dd->next;
+ dd->drv->td_close(dd);
+ free(dd->private);
+ free(dd);
+ dd = tmp;
+ }
if (info != NULL && info->mem > 0)
munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE);
@@ -96,7 +109,6 @@ static void unmap_disk(struct td_state *
free(s->fd_entry);
free(s->blkif);
free(s->ring_info);
- free(s->private);
free(s);
return;
@@ -113,16 +125,19 @@ static inline int LOCAL_FD_SET(fd_set *r
static inline int LOCAL_FD_SET(fd_set *readfds)
{
fd_list_entry_t *ptr;
+ struct disk_driver *dd;
ptr = fd_start;
while (ptr != NULL) {
if (ptr->tap_fd) {
FD_SET(ptr->tap_fd, readfds);
- if (ptr->io_fd[READ])
- FD_SET(ptr->io_fd[READ], readfds);
- maxfds = (ptr->io_fd[READ] > maxfds ?
- ptr->io_fd[READ]: maxfds);
- maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd: maxfds);
+ td_for_each_disk(ptr->s, dd) {
+ if (dd->io_fd[READ])
+ FD_SET(dd->io_fd[READ], readfds);
+ maxfds = (dd->io_fd[READ] > maxfds ?
+ dd->io_fd[READ] : maxfds);
+ }
+ maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd : maxfds);
}
ptr = ptr->next;
}
@@ -130,8 +145,7 @@ static inline int LOCAL_FD_SET(fd_set *r
return 0;
}
-static inline fd_list_entry_t *add_fd_entry(
- int tap_fd, int io_fd[MAX_IOFD], struct td_state *s)
+static inline fd_list_entry_t *add_fd_entry(int tap_fd, struct td_state *s)
{
fd_list_entry_t **pprev, *entry;
int i;
@@ -139,12 +153,10 @@ static inline fd_list_entry_t *add_fd_en
DPRINTF("Adding fd_list_entry\n");
/*Add to linked list*/
- s->fd_entry = entry = malloc(sizeof(fd_list_entry_t));
+ s->fd_entry = entry = malloc(sizeof(fd_list_entry_t));
entry->tap_fd = tap_fd;
- for (i = 0; i < MAX_IOFD; i++)
- entry->io_fd[i] = io_fd[i];
- entry->s = s;
- entry->next = NULL;
+ entry->s = s;
+ entry->next = NULL;
pprev = &fd_start;
while (*pprev != NULL)
@@ -171,7 +183,7 @@ static struct tap_disk *get_driver(int d
static struct tap_disk *get_driver(int drivertype)
{
/* blktapctrl has passed us the driver type */
-
+
return dtypes[drivertype]->drv;
}
@@ -183,12 +195,34 @@ static struct td_state *state_init(void)
s = malloc(sizeof(struct td_state));
blkif = s->blkif = malloc(sizeof(blkif_t));
- s->ring_info = malloc(sizeof(tapdev_info_t));
-
- for (i = 0; i < MAX_REQUESTS; i++)
- blkif->pending_list[i].count = 0;
+ s->ring_info = calloc(1, sizeof(tapdev_info_t));
+
+ for (i = 0; i < MAX_REQUESTS; i++) {
+ blkif->pending_list[i].secs_pending = 0;
+ blkif->pending_list[i].submitting = 0;
+ }
return s;
+}
+
+static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv)
+{
+ struct disk_driver *dd;
+
+ dd = calloc(1, sizeof(struct disk_driver));
+ if (!dd)
+ return NULL;
+
+ dd->private = malloc(drv->private_data_size);
+ if (!dd->private) {
+ free(dd);
+ return NULL;
+ }
+
+ dd->drv = drv;
+ dd->td_state = s;
+
+ return dd;
}
static int map_new_dev(struct td_state *s, int minor)
@@ -246,6 +280,51 @@ static int map_new_dev(struct td_state *
return -1;
}
+static int open_disk(struct td_state *s, struct disk_driver *dd, char *path)
+{
+ int err;
+ struct disk_driver *d = dd;
+
+ err = dd->drv->td_open(dd, path);
+ if (err)
+ return err;
+
+ /* load backing files as necessary */
+ while (d->drv->td_has_parent(d)) {
+ struct disk_driver *new;
+
+ new = calloc(1, sizeof(struct disk_driver));
+ if (!new)
+ goto fail;
+ new->drv = d->drv;
+ new->td_state = s;
+ new->private = malloc(new->drv->private_data_size);
+ if (!new->private) {
+ free(new);
+ goto fail;
+ }
+
+ err = d->drv->td_get_parent(d, new);
+ if (err)
+ goto fail;
+
+ d = d->next = new;
+ }
+
+ return 0;
+
+ fail:
+ DPRINTF("failed opening disk\n");
+ while (dd) {
+ d = dd->next;
+ dd->drv->td_close(dd);
+ free(dd->private);
+ free(dd);
+ dd = d;
+ }
+ return err;
+}
+
static int read_msg(char *buf)
{
int length, len, msglen, tap_fd, *io_fd;
@@ -255,6 +334,7 @@ static int read_msg(char *buf)
msg_newdev_t *msg_dev;
msg_pid_t *msg_pid;
struct tap_disk *drv;
+ struct disk_driver *dd;
int ret = -1;
struct td_state *s = NULL;
fd_list_entry_t *entry;
@@ -289,20 +369,20 @@ static int read_msg(char *buf)
if (s == NULL)
goto params_done;
- s->drv = drv;
- s->private = malloc(drv->private_data_size);
- if (s->private == NULL) {
+ s->disks = dd = disk_init(s, drv);
+ if (!dd) {
free(s);
goto params_done;
}
/*Open file*/
- ret = drv->td_open(s, path);
- io_fd = drv->td_get_fd(s);
-
- entry = add_fd_entry(0, io_fd, s);
+ ret = open_disk(s, dd, path);
+ if (ret)
+ goto params_done;
+
+ entry = add_fd_entry(0, s);
entry->cookie = msg->cookie;
- DPRINTF("Entered cookie %d\n",entry->cookie);
+ DPRINTF("Entered cookie %d\n", entry->cookie);
memset(buf, 0x00, MSG_SIZE);
@@ -323,13 +403,12 @@ static int read_msg(char *buf)
free(path);
return 1;
-
-
case CTLMSG_NEWDEV:
msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t));
s = get_state(msg->cookie);
- DPRINTF("Retrieving state, cookie
%d.....[%s]\n",msg->cookie, (s == NULL ? "FAIL":"OK"));
+ DPRINTF("Retrieving state, cookie %d.....[%s]\n",
+ msg->cookie, (s == NULL ? "FAIL":"OK"));
if (s != NULL) {
ret = ((map_new_dev(s, msg_dev->devnum)
== msg_dev->devnum ? 0: -1));
@@ -397,49 +476,75 @@ static inline void kick_responses(struct
}
}
-void io_done(struct td_state *s, int sid)
-{
- struct tap_disk *drv = s->drv;
+void io_done(struct disk_driver *dd, int sid)
+{
+ struct tap_disk *drv = dd->drv;
if (!run) return; /*We have received signal to close*/
- if (drv->td_do_callbacks(s, sid) > 0) kick_responses(s);
+ if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state);
return;
}
-int send_responses(struct td_state *s, int res, int idx, void *private)
-{
+static inline uint64_t
+segment_start(blkif_request_t *req, int sidx)
+{
+ int i;
+ uint64_t start = req->sector_number;
+
+ for (i = 0; i < sidx; i++)
+ start += (req->seg[i].last_sect - req->seg[i].first_sect + 1);
+
+ return start;
+}
+
+uint64_t sends, responds;
+int send_responses(struct disk_driver *dd, int res,
+ uint64_t sector, int nr_secs, int idx, void *private)
+{
+ pending_req_t *preq;
blkif_request_t *req;
int responses_queued = 0;
+ struct td_state *s = dd->td_state;
blkif_t *blkif = s->blkif;
-
- req = &blkif->pending_list[idx].req;
-
- if ( (idx > MAX_REQUESTS-1) ||
- (blkif->pending_list[idx].count == 0) )
+ int sidx = (int)(long)private, secs_done = nr_secs;
+
+ if ( (idx > MAX_REQUESTS-1) )
{
DPRINTF("invalid index returned(%u)!\n", idx);
return 0;
}
+ preq = &blkif->pending_list[idx];
+ req = &preq->req;
+
+ if (res == BLK_NOT_ALLOCATED) {
+ res = do_cow_read(dd, req, sidx, sector, nr_secs);
+ if (res >= 0) {
+ secs_done = res;
+ res = 0;
+ } else
+ secs_done = 0;
+ }
+
+ preq->secs_pending -= secs_done;
+
+ if (res == -EBUSY && preq->submitting)
+ return -EBUSY; /* propagate -EBUSY back to higher layers */
+ if (res)
+ preq->status = BLKIF_RSP_ERROR;
- if (res != 0) {
- blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
- }
-
- blkif->pending_list[idx].count--;
-
- if (blkif->pending_list[idx].count == 0)
+ if (!preq->submitting && preq->secs_pending == 0)
{
blkif_request_t tmp;
blkif_response_t *rsp;
-
- tmp = blkif->pending_list[idx].req;
+
+ tmp = preq->req;
rsp = (blkif_response_t *)req;
rsp->id = tmp.id;
rsp->operation = tmp.operation;
- rsp->status = blkif->pending_list[idx].status;
+ rsp->status = preq->status;
write_rsp_to_ring(s, rsp);
responses_queued++;
@@ -447,15 +552,51 @@ int send_responses(struct td_state *s, i
return responses_queued;
}
+int do_cow_read(struct disk_driver *dd, blkif_request_t *req,
+ int sidx, uint64_t sector, int nr_secs)
+{
+ char *page;
+ int ret, early;
+ uint64_t seg_start, seg_end;
+ struct td_state *s = dd->td_state;
+ tapdev_info_t *info = s->ring_info;
+ struct disk_driver *parent = dd->next;
+
+ seg_start = segment_start(req, sidx);
+ seg_end = seg_start + req->seg[sidx].last_sect + 1;
+
+ ASSERT(sector >= seg_start && sector + nr_secs <= seg_end);
+
+ page = (char *)MMAP_VADDR(info->vstart,
+ (unsigned long)req->id, sidx);
+ page += (req->seg[sidx].first_sect << SECTOR_SHIFT);
+ page += ((sector - seg_start) << SECTOR_SHIFT);
+
+ if (!parent) {
+ memset(page, 0, nr_secs << SECTOR_SHIFT);
+ return nr_secs;
+ }
+
+ /* reissue request to backing file */
+ ret = parent->drv->td_queue_read(parent, sector, nr_secs,
+ page, send_responses,
+ req->id, (void *)(long)sidx);
+ if (ret > 0)
+ parent->early += ret;
+
+ return ((ret >= 0) ? 0 : ret);
+}
+
static void get_io_request(struct td_state *s)
{
- RING_IDX rp, rc, j, i, ret;
+ RING_IDX rp, rc, j, i;
blkif_request_t *req;
- int idx, nsects;
+ int idx, nsects, ret;
uint64_t sector_nr;
char *page;
int early = 0; /* count early completions */
- struct tap_disk *drv = s->drv;
+ struct disk_driver *dd = s->disks;
+ struct tap_disk *drv = dd->drv;
blkif_t *blkif = s->blkif;
tapdev_info_t *info = s->ring_info;
int page_size = getpagesize();
@@ -466,23 +607,33 @@ static void get_io_request(struct td_sta
rmb();
for (j = info->fe_ring.req_cons; j != rp; j++)
{
- int done = 0;
+ int done = 0, start_seg = 0;
req = NULL;
req = RING_GET_REQUEST(&info->fe_ring, j);
++info->fe_ring.req_cons;
if (req == NULL) continue;
-
+
idx = req->id;
- ASSERT(blkif->pending_list[idx].count == 0);
- memcpy(&blkif->pending_list[idx].req, req, sizeof(*req));
- blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
- blkif->pending_list[idx].count = req->nr_segments;
-
- sector_nr = req->sector_number;
-
- for (i = 0; i < req->nr_segments; i++) {
+
+ if (info->busy.req) {
+ /* continue where we left off last time */
+ ASSERT(info->busy.req == req);
+ start_seg = info->busy.seg_idx;
+ sector_nr = segment_start(req, start_seg);
+ info->busy.seg_idx = 0;
+ info->busy.req = NULL;
+ } else {
+ ASSERT(blkif->pending_list[idx].secs_pending == 0);
+ memcpy(&blkif->pending_list[idx].req,
+ req, sizeof(*req));
+ blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
+ blkif->pending_list[idx].submitting = 1;
+ sector_nr = req->sector_number;
+ }
+
+ for (i = start_seg; i < req->nr_segments; i++) {
nsects = req->seg[i].last_sect -
req->seg[i].first_sect + 1;
@@ -508,31 +659,37 @@ static void get_io_request(struct td_sta
(long long unsigned) sector_nr);
continue;
}
-
+
+ blkif->pending_list[idx].secs_pending += nsects;
+
switch (req->operation)
{
case BLKIF_OP_WRITE:
- ret = drv->td_queue_write(s, sector_nr,
- nsects, page, send_responses,
- idx, NULL);
- if (ret > 0) early += ret;
+ ret = drv->td_queue_write(dd, sector_nr,
+ nsects, page,
+ send_responses,
+ idx, (void *)(long)i);
+ if (ret > 0) dd->early += ret;
else if (ret == -EBUSY) {
- /*
- * TODO: Sector is locked *
- * Need to put req back on queue *
- */
+ /* put req back on queue */
+ --info->fe_ring.req_cons;
+ info->busy.req = req;
+ info->busy.seg_idx = i;
+ goto out;
}
break;
case BLKIF_OP_READ:
- ret = drv->td_queue_read(s, sector_nr,
- nsects, page, send_responses,
- idx, NULL);
- if (ret > 0) early += ret;
+ ret = drv->td_queue_read(dd, sector_nr,
+ nsects, page,
+ send_responses,
+ idx, (void *)(long)i);
+ if (ret > 0) dd->early += ret;
else if (ret == -EBUSY) {
- /*
- * TODO: Sector is locked *
- * Need to put req back on queue *
- */
+ /* put req back on queue */
+ --info->fe_ring.req_cons;
+ info->busy.req = req;
+ info->busy.seg_idx = i;
+ goto out;
}
break;
default:
@@ -541,14 +698,22 @@ static void get_io_request(struct td_sta
}
sector_nr += nsects;
}
- }
-
+ blkif->pending_list[idx].submitting = 0;
+ /* force write_rsp_to_ring for synchronous case */
+ if (blkif->pending_list[idx].secs_pending == 0)
+ dd->early += send_responses(dd, 0, 0, 0, idx, (void
*)0);
+ }
+
+ out:
/*Batch done*/
- drv->td_submit(s);
-
- if (early > 0)
- io_done(s,10);
-
+ td_for_each_disk(s, dd) {
+ dd->early += dd->drv->td_submit(dd);
+ if (dd->early > 0) {
+ io_done(dd, 10);
+ dd->early = 0;
+ }
+ }
+
return;
}
@@ -558,10 +723,9 @@ int main(int argc, char *argv[])
char *p, *buf;
fd_set readfds, writefds;
fd_list_entry_t *ptr;
- struct tap_disk *drv;
struct td_state *s;
char openlogbuf[128];
-
+
if (argc != 3) usage();
daemonize();
@@ -573,12 +737,12 @@ int main(int argc, char *argv[])
signal (SIGINT, sig_handler);
/*Open the control channel*/
- fds[READ] = open(argv[1],O_RDWR|O_NONBLOCK);
+ fds[READ] = open(argv[1],O_RDWR|O_NONBLOCK);
fds[WRITE] = open(argv[2],O_RDWR|O_NONBLOCK);
if ( (fds[READ] < 0) || (fds[WRITE] < 0) )
{
- DPRINTF("FD open failed [%d,%d]\n",fds[READ], fds[WRITE]);
+ DPRINTF("FD open failed [%d,%d]\n", fds[READ], fds[WRITE]);
exit(-1);
}
@@ -608,11 +772,22 @@ int main(int argc, char *argv[])
{
ptr = fd_start;
while (ptr != NULL) {
- if (FD_ISSET(ptr->tap_fd, &readfds))
+ int progress_made = 0;
+ struct disk_driver *dd;
+ tapdev_info_t *info = ptr->s->ring_info;
+
+ td_for_each_disk(ptr->s, dd) {
+ if (dd->io_fd[READ] &&
+ FD_ISSET(dd->io_fd[READ],
+ &readfds)) {
+ io_done(dd, READ);
+ progress_made = 1;
+ }
+ }
+
+ if (FD_ISSET(ptr->tap_fd, &readfds) ||
+ (info->busy.req && progress_made))
get_io_request(ptr->s);
- if (ptr->io_fd[READ] &&
- FD_ISSET(ptr->io_fd[READ],
&readfds))
- io_done(ptr->s, READ);
ptr = ptr->next;
}
@@ -628,11 +803,8 @@ int main(int argc, char *argv[])
ptr = fd_start;
while (ptr != NULL) {
s = ptr->s;
- drv = s->drv;
unmap_disk(s);
- drv->td_close(s);
- free(s->private);
free(s->blkif);
free(s->ring_info);
free(s);
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/tapdisk.h Tue Feb 20 12:58:22 2007 -0700
@@ -43,6 +43,9 @@
* - The fd used for poll is an otherwise unused pipe, which allows poll to
* be safely called without ever returning anything.
*
+ * NOTE: tapdisk uses the number of sectors submitted per request as a
+ * ref count. Plugins must use the callback function to communicate the
+ * completion--or error--of every sector submitted to them.
*/
#ifndef TAPDISK_H_
@@ -65,39 +68,55 @@
#define SECTOR_SHIFT 9
#define DEFAULT_SECTOR_SIZE 512
+#define MAX_IOFD 2
+
+#define BLK_NOT_ALLOCATED 99
+
+struct td_state;
+struct tap_disk;
+
+struct disk_driver {
+ int early;
+ void *private;
+ int io_fd[MAX_IOFD];
+ struct tap_disk *drv;
+ struct td_state *td_state;
+ struct disk_driver *next;
+};
+
/* This structure represents the state of an active virtual disk. */
struct td_state {
- void *private;
- void *drv;
+ struct disk_driver *disks;
void *blkif;
void *image;
void *ring_info;
void *fd_entry;
- char backing_file[1024]; /*Used by differencing disks, e.g. qcow*/
unsigned long sector_size;
unsigned long long size;
unsigned int info;
};
/* Prototype of the callback to activate as requests complete. */
-typedef int (*td_callback_t)(struct td_state *s, int res, int id, void *prv);
+typedef int (*td_callback_t)(struct disk_driver *dd, int res, uint64_t sector,
+ int nb_sectors, int id, void *private);
/* Structure describing the interface to a virtual disk implementation. */
/* See note at the top of this file describing this interface. */
struct tap_disk {
const char *disk_type;
int private_data_size;
- int (*td_open) (struct td_state *s, const char *name);
- int (*td_queue_read) (struct td_state *s, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
+ int (*td_open) (struct disk_driver *dd, const char *name);
+ int (*td_queue_read) (struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
int id, void *prv);
- int (*td_queue_write) (struct td_state *s, uint64_t sector,
- int nb_sectors, char *buf, td_callback_t cb,
+ int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
+ int nb_sectors, char *buf, td_callback_t cb,
int id, void *prv);
- int (*td_submit) (struct td_state *s);
- int *(*td_get_fd) (struct td_state *s);
- int (*td_close) (struct td_state *s);
- int (*td_do_callbacks)(struct td_state *s, int sid);
+ int (*td_submit) (struct disk_driver *dd);
+ int (*td_has_parent) (struct disk_driver *dd);
+ int (*td_get_parent) (struct disk_driver *dd, struct disk_driver *p);
+ int (*td_close) (struct disk_driver *dd);
+ int (*td_do_callbacks)(struct disk_driver *dd, int sid);
};
typedef struct disk_info {
@@ -119,14 +138,13 @@ extern struct tap_disk tapdisk_ram;
extern struct tap_disk tapdisk_ram;
extern struct tap_disk tapdisk_qcow;
-#define MAX_DISK_TYPES 20
-#define MAX_IOFD 2
-
-#define DISK_TYPE_AIO 0
-#define DISK_TYPE_SYNC 1
-#define DISK_TYPE_VMDK 2
-#define DISK_TYPE_RAM 3
-#define DISK_TYPE_QCOW 4
+#define MAX_DISK_TYPES 20
+
+#define DISK_TYPE_AIO 0
+#define DISK_TYPE_SYNC 1
+#define DISK_TYPE_VMDK 2
+#define DISK_TYPE_RAM 3
+#define DISK_TYPE_QCOW 4
/*Define Individual Disk Parameters here */
@@ -197,12 +215,10 @@ typedef struct fd_list_entry {
typedef struct fd_list_entry {
int cookie;
int tap_fd;
- int io_fd[MAX_IOFD];
struct td_state *s;
struct fd_list_entry **pprev, *next;
} fd_list_entry_t;
int qcow_create(const char *filename, uint64_t total_size,
const char *backing_file, int flags);
-
#endif /*TAPDISK_H_*/
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/lib/blktaplib.h Tue Feb 20 12:58:22 2007 -0700
@@ -91,8 +91,9 @@ struct blkif;
typedef struct {
blkif_request_t req;
- struct blkif *blkif;
- int count;
+ struct blkif *blkif;
+ int submitting;
+ int secs_pending;
int16_t status;
} pending_req_t;
@@ -116,7 +117,7 @@ typedef struct blkif {
void *prv; /* device-specific data */
void *info; /*Image parameter passing */
- pending_req_t pending_list[MAX_REQUESTS];
+ pending_req_t pending_list[MAX_REQUESTS];
int devnum;
int fds[2];
int be_id;
@@ -141,6 +142,11 @@ void free_blkif(blkif_t *blkif);
void free_blkif(blkif_t *blkif);
void __init_blkif(void);
+typedef struct busy_state {
+ int seg_idx;
+ blkif_request_t *req;
+} busy_state_t;
+
typedef struct tapdev_info {
int fd;
char *mem;
@@ -148,6 +154,7 @@ typedef struct tapdev_info {
blkif_back_ring_t fe_ring;
unsigned long vstart;
blkif_t *blkif;
+ busy_state_t busy;
} tapdev_info_t;
typedef struct domid_translate {
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/lib/xs_api.c
--- a/tools/blktap/lib/xs_api.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/lib/xs_api.c Tue Feb 20 12:58:22 2007 -0700
@@ -311,8 +311,8 @@ int unregister_xenbus_watch(struct xs_ha
}
if (!xs_unwatch(h, watch->node, token))
- DPRINTF("XENBUS Failed to release watch %s: %i\n",
- watch->node, er);
+ DPRINTF("XENBUS Failed to release watch %s\n",
+ watch->node);
list_del(&watch->list);
@@ -351,9 +351,9 @@ int xs_fire_next_watch(struct xs_handle
node = res[XS_WATCH_PATH];
token = res[XS_WATCH_TOKEN];
-
+
w = find_watch(token);
- if (w)
+ if (w)
w->callback(h, w, node);
free(res);
diff -r 04c23c1ef888 -r d907467f08cd tools/check/check_zlib_lib
--- a/tools/check/check_zlib_lib Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/check/check_zlib_lib Tue Feb 20 12:58:22 2007 -0700
@@ -3,8 +3,10 @@
RC=0
+PATH=/sbin:$PATH
+
set -e
-ldconfig -v 2>&1 | grep -q libz.so || RC=1
+ldconfig -p 2>&1 | grep -q libz.so || RC=1
if test ${RC} -ne 0; then
echo
diff -r 04c23c1ef888 -r d907467f08cd tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/console/daemon/io.c Tue Feb 20 12:58:22 2007 -0700
@@ -63,6 +63,7 @@ struct domain
char *conspath;
int ring_ref;
evtchn_port_t local_port;
+ evtchn_port_t remote_port;
int xce_handle;
struct xencons_interface *interface;
};
@@ -234,6 +235,9 @@ static int domain_create_ring(struct dom
if (err)
goto out;
+ if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
+ goto out;
+
if (ring_ref != dom->ring_ref) {
if (dom->interface != NULL)
munmap(dom->interface, getpagesize());
@@ -249,6 +253,7 @@ static int domain_create_ring(struct dom
}
dom->local_port = -1;
+ dom->remote_port = -1;
if (dom->xce_handle != -1)
xc_evtchn_close(dom->xce_handle);
@@ -270,6 +275,7 @@ static int domain_create_ring(struct dom
goto out;
}
dom->local_port = rc;
+ dom->remote_port = remote_port;
if (dom->tty_fd == -1) {
dom->tty_fd = domain_create_tty(dom);
@@ -279,6 +285,7 @@ static int domain_create_ring(struct dom
xc_evtchn_close(dom->xce_handle);
dom->xce_handle = -1;
dom->local_port = -1;
+ dom->remote_port = -1;
goto out;
}
}
@@ -336,6 +343,7 @@ static struct domain *create_domain(int
dom->ring_ref = -1;
dom->local_port = -1;
+ dom->remote_port = -1;
dom->interface = NULL;
dom->xce_handle = -1;
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/hvmloader/acpi/build.c Tue Feb 20 12:58:22 2007 -0700
@@ -110,7 +110,9 @@ int construct_madt(struct acpi_20_madt *
memset(lapic, 0, sizeof(*lapic));
lapic->type = ACPI_PROCESSOR_LOCAL_APIC;
lapic->length = sizeof(*lapic);
- lapic->acpi_processor_id = lapic->apic_id = LAPIC_ID(i);
+ /* Processor ID must match processor-object IDs in the DSDT. */
+ lapic->acpi_processor_id = i;
+ lapic->apic_id = LAPIC_ID(i);
lapic->flags = ACPI_LOCAL_APIC_ENABLED;
offset += sizeof(*lapic);
lapic++;
@@ -144,6 +146,79 @@ int construct_hpet(struct acpi_20_hpet *
return offset;
}
+int construct_processor_objects(uint8_t *buf)
+{
+ static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 };
+ static const char hex[] = "0123456789ABCDEF";
+ unsigned int i, length, nr_cpus = get_vcpu_nr();
+ struct acpi_header *hdr;
+ uint8_t *p = buf;
+
+ /*
+ * 1. Table Header.
+ */
+
+ hdr = (struct acpi_header *)p;
+ hdr->signature = ASCII32('S','S','D','T');
+ hdr->revision = 2;
+ strncpy(hdr->oem_id, ACPI_OEM_ID, 6);
+ strncpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID, 8);
+ hdr->oem_revision = ACPI_OEM_REVISION;
+ hdr->creator_id = ACPI_CREATOR_ID;
+ hdr->creator_revision = ACPI_CREATOR_REVISION;
+ p += sizeof(*hdr);
+
+ /*
+ * 2. Scope Definition.
+ */
+
+ /* ScopeOp */
+ *p++ = 0x10;
+
+ /* PkgLength (includes length bytes!). */
+ length = 1 + 5 + (nr_cpus * sizeof(pdat));
+ if ( length <= 0x3f )
+ {
+ *p++ = length;
+ }
+ else if ( ++length <= 0xfff )
+ {
+ *p++ = 0x40 | (length & 0xf);
+ *p++ = length >> 4;
+ }
+ else
+ {
+ length++;
+ *p++ = 0x80 | (length & 0xf);
+ *p++ = (length >> 4) & 0xff;
+ *p++ = (length >> 12) & 0xff;
+ }
+
+ /* NameString */
+ strncpy(p, "\\_PR_", 5);
+ p += 5;
+
+ /*
+ * 3. Processor Objects.
+ */
+
+ for ( i = 0; i < nr_cpus; i++ )
+ {
+ memcpy(p, pdat, sizeof(pdat));
+ /* ProcessorName */
+ p[5] = hex[(i>>4)&15];
+ p[6] = hex[(i>>0)&15];
+ /* ProcessorID */
+ p[7] = i;
+ p += sizeof(pdat);
+ }
+
+ hdr->length = p - buf;
+ set_checksum(hdr, offsetof(struct acpi_header, checksum), hdr->length);
+
+ return hdr->length;
+}
+
int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
{
int offset = 0, nr_tables = 0;
@@ -165,6 +240,10 @@ int construct_secondary_tables(uint8_t *
hpet = (struct acpi_20_hpet *)&buf[offset];
offset += construct_hpet(hpet);
table_ptrs[nr_tables++] = (unsigned long)hpet;
+
+ /* Processor Object SSDT. */
+ table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
+ offset += construct_processor_objects(&buf[offset]);
/* TPM TCPA and SSDT. */
tis_hdr = (uint16_t *)0xFED40F00;
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl Tue Feb 20 12:58:22 2007 -0700
@@ -27,14 +27,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2,
Name (\APCL, 0x00010000)
Name (\PUID, 0x00)
- Scope (\_PR)
- {
- Processor (CPU0, 0x00, 0x00000000, 0x00) {}
- Processor (CPU1, 0x01, 0x00000000, 0x00) {}
- Processor (CPU2, 0x02, 0x00000000, 0x00) {}
- Processor (CPU3, 0x03, 0x00000000, 0x00) {}
- }
-
/* Poweroff support - ties in with qemu emulation */
Name (\_S5, Package (0x04)
{
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/hvmloader/acpi/dsdt.c
--- a/tools/firmware/hvmloader/acpi/dsdt.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.c Tue Feb 20 12:58:22 2007 -0700
@@ -1,19 +1,19 @@
/*
*
* Intel ACPI Component Architecture
- * ASL Optimizing Compiler version 20060707 [Dec 30 2006]
+ * ASL Optimizing Compiler version 20060707 [Feb 16 2007]
* Copyright (C) 2000 - 2006 Intel Corporation
* Supports ACPI Specification Revision 3.0a
*
- * Compilation of "dsdt.asl" - Sat Dec 30 15:31:23 2006
+ * Compilation of "dsdt.asl" - Fri Feb 16 15:14:37 2007
*
* C source code output
*
*/
unsigned char AmlCode[] =
{
- 0x44,0x53,0x44,0x54,0xD9,0x0D,0x00,0x00, /* 00000000 "DSDT...." */
- 0x02,0xFB,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */
+ 0x44,0x53,0x44,0x54,0x9F,0x0D,0x00,0x00, /* 00000000 "DSDT...." */
+ 0x02,0xEE,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */
0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */
0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */
@@ -23,438 +23,430 @@ unsigned char AmlCode[] =
0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0, /* 00000040 "APCB...." */
0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00, /* 00000048 "..APCL.." */
0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44, /* 00000050 "....PUID" */
- 0x00,0x10,0x39,0x5F,0x50,0x52,0x5F,0x5B, /* 00000058 "..9_PR_[" */
- 0x83,0x0B,0x43,0x50,0x55,0x30,0x00,0x00, /* 00000060 "..CPU0.." */
- 0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x43, /* 00000068 "....[..C" */
- 0x50,0x55,0x31,0x01,0x00,0x00,0x00,0x00, /* 00000070 "PU1....." */
- 0x00,0x5B,0x83,0x0B,0x43,0x50,0x55,0x32, /* 00000078 ".[..CPU2" */
- 0x02,0x00,0x00,0x00,0x00,0x00,0x5B,0x83, /* 00000080 "......[." */
- 0x0B,0x43,0x50,0x55,0x33,0x03,0x00,0x00, /* 00000088 ".CPU3..." */
- 0x00,0x00,0x00,0x08,0x5F,0x53,0x35,0x5F, /* 00000090 "...._S5_" */
- 0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00, /* 00000098 "........" */
- 0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14, /* 000000A0 "..PICD.." */
- 0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68, /* 000000A8 "._PIC.ph" */
- 0x50,0x49,0x43,0x44,0x10,0x44,0xD2,0x5F, /* 000000B0 "PICD.D._" */
- 0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D, /* 000000B8 "SB_[.I.M" */
- 0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44, /* 000000C0 "EM0._HID" */
- 0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43, /* 000000C8 ".A...._C" */
- 0x52,0x53,0x11,0x33,0x0A,0x30,0x8A,0x2B, /* 000000D0 "RS.3.0.+" */
- 0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */
- 0x00,0x00,0x00,0x00,0xFF,0xFF,0x09,0x00, /* 000000E8 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00, /* 000000F8 "........" */
- 0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82, /* 00000100 "....y.[." */
- 0x41,0xCD,0x50,0x43,0x49,0x30,0x08,0x5F, /* 00000108 "A.PCI0._" */
- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03, /* 00000110 "HID.A..." */
- 0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F, /* 00000118 "._UID.._" */
- 0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42, /* 00000120 "ADR.._BB" */
- 0x4E,0x00,0x14,0x44,0x08,0x5F,0x43,0x52, /* 00000128 "N..D._CR" */
- 0x53,0x00,0x08,0x50,0x52,0x54,0x30,0x11, /* 00000130 "S..PRT0." */
- 0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00,0x02, /* 00000138 "B..n...." */
- 0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, /* 00000140 "........" */
- 0x00,0x00,0x00,0x01,0x47,0x01,0xF8,0x0C, /* 00000148 "....G..." */
- 0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00,0x01, /* 00000150 "........" */
- 0x0C,0x03,0x00,0x00,0x00,0x00,0xF7,0x0C, /* 00000158 "........" */
- 0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00,0x01, /* 00000160 "........" */
- 0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF,0xFF, /* 00000168 "........" */
- 0x00,0x00,0x00,0xF3,0x87,0x17,0x00,0x00, /* 00000170 "........" */
- 0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000178 "........" */
- 0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00,0x00, /* 00000180 "........" */
- 0x00,0x00,0x00,0x00,0x02,0x00,0x87,0x17, /* 00000188 "........" */
- 0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00, /* 00000190 "........" */
- 0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4, /* 00000198 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, /* 000001A0 "........" */
- 0x79,0x00,0xA4,0x50,0x52,0x54,0x30,0x08, /* 000001A8 "y..PRT0." */
- 0x42,0x55,0x46,0x41,0x11,0x09,0x0A,0x06, /* 000001B0 "BUFA...." */
- 0x23,0x60,0x0C,0x18,0x79,0x00,0x08,0x42, /* 000001B8 "#`..y..B" */
- 0x55,0x46,0x42,0x11,0x09,0x0A,0x06,0x23, /* 000001C0 "UFB....#" */
- 0x00,0x00,0x18,0x79,0x00,0x8B,0x42,0x55, /* 000001C8 "...y..BU" */
- 0x46,0x42,0x01,0x49,0x52,0x51,0x56,0x5B, /* 000001D0 "FB.IRQV[" */
- 0x82,0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08, /* 000001D8 ".H.LNKA." */
- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 000001E0 "_HID.A.." */
- 0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,0x14, /* 000001E8 ".._UID.." */
- 0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50, /* 000001F0 "._STA.{P" */
- 0x49,0x52,0x41,0x0A,0x80,0x60,0xA0,0x08, /* 000001F8 "IRA..`.." */
- 0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1, /* 00000200 ".`......" */
- 0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50, /* 00000208 "......_P" */
- 0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41, /* 00000210 "RS..BUFA" */
- 0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D, /* 00000218 ".._DIS.}" */
- 0x50,0x49,0x52,0x41,0x0A,0x80,0x50,0x49, /* 00000220 "PIRA..PI" */
- 0x52,0x41,0x14,0x1A,0x5F,0x43,0x52,0x53, /* 00000228 "RA.._CRS" */
- 0x00,0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F, /* 00000230 ".{PIRA.." */
- 0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56, /* 00000238 "`y.`IRQV" */
- 0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F, /* 00000240 ".BUFB.._" */
- 0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49, /* 00000248 "SRS..h.I" */
- 0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31, /* 00000250 "RQ1.IRQ1" */
- 0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52, /* 00000258 "`v`p`PIR" */
- 0x41,0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B, /* 00000260 "A[.I.LNK" */
- 0x42,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000268 "B._HID.A" */
- 0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44, /* 00000270 "...._UID" */
- 0x0A,0x02,0x14,0x1C,0x5F,0x53,0x54,0x41, /* 00000278 "...._STA" */
- 0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,0x80, /* 00000280 ".{PIRB.." */
- 0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4, /* 00000288 "`...`..." */
- 0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14, /* 00000290 "........" */
- 0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,0x42, /* 00000298 "._PRS..B" */
- 0x55,0x46,0x41,0x14,0x11,0x5F,0x44,0x49, /* 000002A0 "UFA.._DI" */
- 0x53,0x00,0x7D,0x50,0x49,0x52,0x42,0x0A, /* 000002A8 "S.}PIRB." */
- 0x80,0x50,0x49,0x52,0x42,0x14,0x1A,0x5F, /* 000002B0 ".PIRB.._" */
- 0x43,0x52,0x53,0x00,0x7B,0x50,0x49,0x52, /* 000002B8 "CRS.{PIR" */
- 0x42,0x0A,0x0F,0x60,0x79,0x01,0x60,0x49, /* 000002C0 "B..`y.`I" */
- 0x52,0x51,0x56,0xA4,0x42,0x55,0x46,0x42, /* 000002C8 "RQV.BUFB" */
- 0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B, /* 000002D0 ".._SRS.." */
- 0x68,0x01,0x49,0x52,0x51,0x31,0x82,0x49, /* 000002D8 "h.IRQ1.I" */
- 0x52,0x51,0x31,0x60,0x76,0x60,0x70,0x60, /* 000002E0 "RQ1`v`p`" */
- 0x50,0x49,0x52,0x42,0x5B,0x82,0x49,0x08, /* 000002E8 "PIRB[.I." */
- 0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49, /* 000002F0 "LNKC._HI" */
- 0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F, /* 000002F8 "D.A...._" */
- 0x55,0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F, /* 00000300 "UID...._" */
- 0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 00000308 "STA.{PIR" */
- 0x43,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 00000310 "C..`...`" */
- 0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 00000318 "........" */
- 0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 00000320 "...._PRS" */
- 0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 00000328 "..BUFA.." */
- 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 00000330 "_DIS.}PI" */
- 0x52,0x43,0x0A,0x80,0x50,0x49,0x52,0x43, /* 00000338 "RC..PIRC" */
- 0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000340 ".._CRS.{" */
- 0x50,0x49,0x52,0x43,0x0A,0x0F,0x60,0x79, /* 00000348 "PIRC..`y" */
- 0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 00000350 ".`IRQV.B" */
- 0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 00000358 "UFB.._SR" */
- 0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 00000360 "S..h.IRQ" */
- 0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 00000368 "1.IRQ1`v" */
- 0x60,0x70,0x60,0x50,0x49,0x52,0x43,0x5B, /* 00000370 "`p`PIRC[" */
- 0x82,0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08, /* 00000378 ".I.LNKD." */
- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000380 "_HID.A.." */
- 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x04, /* 00000388 ".._UID.." */
- 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 00000390 ".._STA.{" */
- 0x50,0x49,0x52,0x44,0x0A,0x80,0x60,0xA0, /* 00000398 "PIRD..`." */
- 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 000003A0 "..`....." */
- 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 000003A8 "......._" */
- 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 000003B0 "PRS..BUF" */
- 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 000003B8 "A.._DIS." */
- 0x7D,0x50,0x49,0x52,0x44,0x0A,0x80,0x50, /* 000003C0 "}PIRD..P" */
- 0x49,0x52,0x44,0x14,0x1A,0x5F,0x43,0x52, /* 000003C8 "IRD.._CR" */
- 0x53,0x00,0x7B,0x50,0x49,0x52,0x44,0x0A, /* 000003D0 "S.{PIRD." */
- 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 000003D8 ".`y.`IRQ" */
- 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 000003E0 "V.BUFB.." */
- 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 000003E8 "_SRS..h." */
- 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 000003F0 "IRQ1.IRQ" */
- 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 000003F8 "1`v`p`PI" */
- 0x52,0x44,0x5B,0x82,0x3A,0x48,0x50,0x45, /* 00000400 "RD[.:HPE" */
- 0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000408 "T._HID.A" */
- 0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44, /* 00000410 "...._UID" */
- 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x1F, /* 00000418 ".._CRS.." */
- 0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,0x01, /* 00000420 "........" */
- 0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFE, /* 00000428 "........" */
- 0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,0x00, /* 00000430 "........" */
- 0x00,0x04,0x00,0x00,0x79,0x00,0x14,0x16, /* 00000438 "....y..." */
- 0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50, /* 00000440 "_PRT...P" */
- 0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41, /* 00000448 "ICD.PRTA" */
- 0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52, /* 00000450 ".PRTP.PR" */
- 0x54,0x50,0x12,0x49,0x36,0x3C,0x12,0x0D, /* 00000458 "TP.I6<.." */
- 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C, /* 00000460 ".......L" */
- 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000468 "NKB....." */
- 0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B, /* 00000470 ".....LNK" */
- 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000478 "C......." */
- 0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000480 "....LNKD" */
- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01, /* 00000488 "........" */
- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 00000490 "...LNKA." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000498 "........" */
- 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 000004A0 ".LNKC..." */
- 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C, /* 000004A8 ".......L" */
- 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000004B0 "NKD....." */
- 0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E, /* 000004B8 "......LN" */
- 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000004C0 "KA......" */
- 0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000004C8 ".....LNK" */
- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004D0 "B......." */
- 0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 000004D8 "...LNKD." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 000004E0 "........" */
- 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000004E8 ".LNKA..." */
- 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02, /* 000004F0 "........" */
- 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000004F8 "LNKB...." */
- 0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C, /* 00000500 ".......L" */
- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000508 "NKC....." */
- 0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,0x4B, /* 00000510 ".....LNK" */
- 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000518 "A......." */
- 0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000520 "...LNKB." */
- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000528 "........" */
- 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000530 "..LNKC.." */
- 0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A, /* 00000538 "........" */
- 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000540 ".LNKD..." */
- 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x4C, /* 00000548 ".......L" */
- 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000550 "NKB....." */
- 0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,0x4B, /* 00000558 ".....LNK" */
- 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000560 "C......." */
- 0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000568 "....LNKD" */
- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05, /* 00000570 "........" */
- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 00000578 "...LNKA." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000580 "........" */
- 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 00000588 ".LNKC..." */
- 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x4C, /* 00000590 ".......L" */
- 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 00000598 "NKD....." */
- 0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,0x4E, /* 000005A0 "......LN" */
- 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005A8 "KA......" */
- 0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000005B0 ".....LNK" */
- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000005B8 "B......." */
- 0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 000005C0 "...LNKD." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 000005C8 "........" */
- 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000005D0 ".LNKA..." */
- 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02, /* 000005D8 "........" */
- 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000005E0 "LNKB...." */
- 0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,0x4C, /* 000005E8 ".......L" */
- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 000005F0 "NKC....." */
- 0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,0x4B, /* 000005F8 ".....LNK" */
- 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000600 "A......." */
- 0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000608 "...LNKB." */
- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000610 "........" */
- 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000618 "..LNKC.." */
- 0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A, /* 00000620 "........" */
- 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000628 ".LNKD..." */
- 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x4C, /* 00000630 ".......L" */
- 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000638 "NKB....." */
- 0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,0x4B, /* 00000640 ".....LNK" */
- 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000648 "C......." */
- 0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000650 "....LNKD" */
- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09, /* 00000658 "........" */
- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 00000660 "...LNKA." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000668 "........" */
- 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 00000670 ".LNKC..." */
- 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C, /* 00000678 ".......L" */
- 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 00000680 "NKD....." */
- 0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E, /* 00000688 "......LN" */
- 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000690 "KA......" */
- 0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000698 ".....LNK" */
- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006A0 "B......." */
- 0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 000006A8 "...LNKD." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 000006B0 "........" */
- 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000006B8 ".LNKA..." */
- 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02, /* 000006C0 "........" */
- 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000006C8 "LNKB...." */
- 0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x4C, /* 000006D0 ".......L" */
- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 000006D8 "NKC....." */
- 0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,0x4B, /* 000006E0 ".....LNK" */
- 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006E8 "A......." */
- 0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 000006F0 "...LNKB." */
- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 000006F8 "........" */
- 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000700 "..LNKC.." */
- 0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A, /* 00000708 "........" */
- 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000710 ".LNKD..." */
- 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x4C, /* 00000718 ".......L" */
- 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000720 "NKB....." */
- 0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,0x4B, /* 00000728 ".....LNK" */
- 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000730 "C......." */
- 0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000738 "....LNKD" */
- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000740 "........" */
- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 00000748 "...LNKA." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000750 "........" */
- 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 00000758 ".LNKC..." */
- 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x4C, /* 00000760 ".......L" */
- 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 00000768 "NKD....." */
- 0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,0x4E, /* 00000770 "......LN" */
- 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000778 "KA......" */
- 0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000780 ".....LNK" */
- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000788 "B......." */
- 0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 00000790 "...LNKD." */
- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 00000798 "........" */
- 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000007A0 ".LNKA..." */
- 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02, /* 000007A8 "........" */
- 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000007B0 "LNKB...." */
- 0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x4C, /* 000007B8 ".......L" */
- 0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54, /* 000007C0 "NKC..PRT" */
- 0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,0x04, /* 000007C8 "A.A/<..." */
- 0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A, /* 000007D0 "........" */
- 0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01, /* 000007D8 "........" */
- 0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,0x04, /* 000007E0 "........" */
- 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x00, /* 000007E8 "........" */
- 0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000007F0 "........" */
- 0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,0x12, /* 000007F8 "........" */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00, /* 00000800 "........" */
- 0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF, /* 00000808 "........" */
- 0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,0x12, /* 00000810 "........" */
- 0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000818 "........" */
- 0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C, /* 00000820 "........" */
- 0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,0x0A, /* 00000828 "........" */
- 0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03, /* 00000830 "........" */
- 0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,0x04, /* 00000838 "........" */
- 0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,0x0A, /* 00000840 "........" */
- 0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03, /* 00000848 "........" */
- 0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,0x0C, /* 00000850 "........" */
- 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03, /* 00000858 "........" */
- 0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,0xFF, /* 00000860 "........" */
- 0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,0x12, /* 00000868 "...... ." */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01, /* 00000870 "........" */
- 0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,0xFF, /* 00000878 "..!....." */
- 0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,0x22, /* 00000880 "......."" */
- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000888 "........" */
- 0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,0x04, /* 00000890 "....#..." */
- 0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,0x0A, /* 00000898 "........" */
- 0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05, /* 000008A0 "$......." */
- 0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,0x04, /* 000008A8 "....%..." */
- 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x00, /* 000008B0 "........" */
- 0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000008B8 ".&......" */
- 0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,0x12, /* 000008C0 "......'." */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00, /* 000008C8 "........" */
- 0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF, /* 000008D0 "..(....." */
- 0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,0x12, /* 000008D8 "......)." */
- 0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 000008E0 "........" */
- 0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C, /* 000008E8 "...*...." */
- 0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,0x0A, /* 000008F0 "........" */
- 0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07, /* 000008F8 "+......." */
- 0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,0x04, /* 00000900 "....,..." */
- 0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,0x0A, /* 00000908 "........" */
- 0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07, /* 00000910 "-......." */
- 0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,0x0C, /* 00000918 "........" */
- 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03, /* 00000920 "........" */
- 0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,0xFF, /* 00000928 "../....." */
- 0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,0x12, /* 00000930 "........" */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01, /* 00000938 "........" */
- 0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF, /* 00000940 "........" */
- 0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,0x13, /* 00000948 "........" */
- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000950 "........" */
- 0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,0x04, /* 00000958 "........" */
- 0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,0x0A, /* 00000960 "........" */
- 0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09, /* 00000968 "........" */
- 0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,0x04, /* 00000970 "........" */
- 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x00, /* 00000978 "........" */
- 0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000980 "........" */
- 0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,0x12, /* 00000988 "........" */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00, /* 00000990 "........" */
- 0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,0xFF, /* 00000998 "........" */
- 0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,0x12, /* 000009A0 "........" */
- 0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 000009A8 "........" */
- 0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,0x0C, /* 000009B0 "........" */
- 0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,0x0A, /* 000009B8 "........" */
- 0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B, /* 000009C0 "........" */
- 0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,0x04, /* 000009C8 "........" */
- 0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,0x0A, /* 000009D0 "........" */
- 0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B, /* 000009D8 "........" */
- 0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,0x0C, /* 000009E0 "........" */
- 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03, /* 000009E8 "........" */
- 0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF, /* 000009F0 ".. ....." */
- 0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,0x12, /* 000009F8 "......!." */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01, /* 00000A00 "........" */
- 0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A08 ".."....." */
- 0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,0x23, /* 00000A10 ".......#" */
- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000A18 "........" */
- 0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,0x04, /* 00000A20 "....$..." */
- 0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x0A, /* 00000A28 "........" */
- 0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000A30 "%......." */
- 0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,0x04, /* 00000A38 "....&..." */
- 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x00, /* 00000A40 "........" */
- 0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A48 ".'......" */
- 0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,0x12, /* 00000A50 "......(." */
- 0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00, /* 00000A58 "........" */
- 0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A60 "..)....." */
- 0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,0x12, /* 00000A68 "......*." */
- 0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 00000A70 "........" */
- 0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,0x0C, /* 00000A78 "...+...." */
- 0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,0x0A, /* 00000A80 "........" */
- 0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000A88 ",......." */
- 0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,0x04, /* 00000A90 "....-..." */
- 0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,0x0A, /* 00000A98 "........" */
- 0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000AA0 "........" */
- 0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,0x0C, /* 00000AA8 "...../.." */
- 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03, /* 00000AB0 "........" */
- 0x00,0x0A,0x10,0x5B,0x82,0x4C,0x31,0x49, /* 00000AB8 "...[.L1I" */
- 0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52, /* 00000AC0 "SA_._ADR" */
- 0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50, /* 00000AC8 ".....[.P" */
- 0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,0x04, /* 00000AD0 "IRQ..`.." */
- 0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,0x5C, /* 00000AD8 "..\.[.)\" */
- 0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00000AE0 "/._SB_PC" */
- 0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x49, /* 00000AE8 "I0ISA_PI" */
- 0x52,0x51,0x01,0x50,0x49,0x52,0x41,0x08, /* 00000AF0 "RQ.PIRA." */
- 0x50,0x49,0x52,0x42,0x08,0x50,0x49,0x52, /* 00000AF8 "PIRB.PIR" */
- 0x43,0x08,0x50,0x49,0x52,0x44,0x08,0x5B, /* 00000B00 "C.PIRD.[" */
- 0x82,0x46,0x0B,0x53,0x59,0x53,0x52,0x08, /* 00000B08 ".F.SYSR." */
- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000B10 "_HID.A.." */
- 0x02,0x08,0x5F,0x55,0x49,0x44,0x01,0x08, /* 00000B18 ".._UID.." */
- 0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,0x0A, /* 00000B20 "CRS_.N.." */
- 0x8A,0x47,0x01,0x10,0x00,0x10,0x00,0x00, /* 00000B28 ".G......" */
- 0x10,0x47,0x01,0x22,0x00,0x22,0x00,0x00, /* 00000B30 ".G.".".." */
- 0x0C,0x47,0x01,0x30,0x00,0x30,0x00,0x00, /* 00000B38 ".G.0.0.." */
- 0x10,0x47,0x01,0x44,0x00,0x44,0x00,0x00, /* 00000B40 ".G.D.D.." */
- 0x1C,0x47,0x01,0x62,0x00,0x62,0x00,0x00, /* 00000B48 ".G.b.b.." */
- 0x02,0x47,0x01,0x65,0x00,0x65,0x00,0x00, /* 00000B50 ".G.e.e.." */
- 0x0B,0x47,0x01,0x72,0x00,0x72,0x00,0x00, /* 00000B58 ".G.r.r.." */
- 0x0E,0x47,0x01,0x80,0x00,0x80,0x00,0x00, /* 00000B60 ".G......" */
- 0x01,0x47,0x01,0x84,0x00,0x84,0x00,0x00, /* 00000B68 ".G......" */
- 0x03,0x47,0x01,0x88,0x00,0x88,0x00,0x00, /* 00000B70 ".G......" */
- 0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,0x00, /* 00000B78 ".G......" */
- 0x03,0x47,0x01,0x90,0x00,0x90,0x00,0x00, /* 00000B80 ".G......" */
- 0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,0x00, /* 00000B88 ".G......" */
- 0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,0x00, /* 00000B90 ".G......" */
- 0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,0x00, /* 00000B98 ".G......" */
- 0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,0x00, /* 00000BA0 ".G......" */
- 0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,0x00, /* 00000BA8 ".G......" */
- 0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,0x52, /* 00000BB0 ".y..._CR" */
- 0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,0x5B, /* 00000BB8 "S..CRS_[" */
- 0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,0x5F, /* 00000BC0 ".+PIC_._" */
- 0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,0x5F, /* 00000BC8 "HID.A.._" */
- 0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47, /* 00000BD0 "CRS....G" */
- 0x01,0x20,0x00,0x20,0x00,0x01,0x02,0x47, /* 00000BD8 ". . ...G" */
- 0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,0x22, /* 00000BE0 "......."" */
- 0x04,0x00,0x79,0x00,0x5B,0x82,0x47,0x05, /* 00000BE8 "..y.[.G." */
- 0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,0x49, /* 00000BF0 "DMA0._HI" */
- 0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,0x5F, /* 00000BF8 "D.A...._" */
- 0x43,0x52,0x53,0x11,0x41,0x04,0x0A,0x3D, /* 00000C00 "CRS.A..=" */
- 0x2A,0x10,0x04,0x47,0x01,0x00,0x00,0x00, /* 00000C08 "*..G...." */
- 0x00,0x00,0x10,0x47,0x01,0x81,0x00,0x81, /* 00000C10 "...G...." */
- 0x00,0x00,0x03,0x47,0x01,0x87,0x00,0x87, /* 00000C18 "...G...." */
- 0x00,0x00,0x01,0x47,0x01,0x89,0x00,0x89, /* 00000C20 "...G...." */
- 0x00,0x00,0x03,0x47,0x01,0x8F,0x00,0x8F, /* 00000C28 "...G...." */
- 0x00,0x00,0x01,0x47,0x01,0xC0,0x00,0xC0, /* 00000C30 "...G...." */
- 0x00,0x00,0x20,0x47,0x01,0x80,0x04,0x80, /* 00000C38 ".. G...." */
- 0x04,0x00,0x10,0x79,0x00,0x5B,0x82,0x25, /* 00000C40 "...y.[.%" */
- 0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49, /* 00000C48 "TMR_._HI" */
- 0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x5F, /* 00000C50 "D.A...._" */
- 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000C58 "CRS....G" */
- 0x01,0x40,0x00,0x40,0x00,0x00,0x04,0x22, /* 00000C60 ".@.@..."" */
- 0x01,0x00,0x79,0x00,0x5B,0x82,0x25,0x52, /* 00000C68 "..y.[.%R" */
- 0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44, /* 00000C70 "TC_._HID" */
- 0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,0x43, /* 00000C78 ".A...._C" */
- 0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000C80 "RS....G." */
- 0x70,0x00,0x70,0x00,0x00,0x02,0x22,0x00, /* 00000C88 "p.p..."." */
- 0x01,0x79,0x00,0x5B,0x82,0x22,0x53,0x50, /* 00000C90 ".y.[."SP" */
- 0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000C98 "KR._HID." */
- 0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,0x52, /* 00000CA0 "A...._CR" */
- 0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,0x61, /* 00000CA8 "S....G.a" */
- 0x00,0x61,0x00,0x00,0x01,0x79,0x00,0x5B, /* 00000CB0 ".a...y.[" */
- 0x82,0x31,0x50,0x53,0x32,0x4D,0x08,0x5F, /* 00000CB8 ".1PS2M._" */
- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13, /* 00000CC0 "HID.A..." */
- 0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0, /* 00000CC8 "._CID.A." */
- 0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000CD0 "...._STA" */
- 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000CD8 "....._CR" */
- 0x53,0x11,0x08,0x0A,0x05,0x22,0x00,0x10, /* 00000CE0 "S....".." */
- 0x79,0x00,0x5B,0x82,0x42,0x04,0x50,0x53, /* 00000CE8 "y.[.B.PS" */
- 0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000CF0 "2K._HID." */
- 0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,0x49, /* 00000CF8 "A...._CI" */
- 0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,0x09, /* 00000D00 "D.A....." */
- 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000D08 "_STA...." */
- 0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A, /* 00000D10 "._CRS..." */
- 0x15,0x47,0x01,0x60,0x00,0x60,0x00,0x00, /* 00000D18 ".G.`.`.." */
- 0x01,0x47,0x01,0x64,0x00,0x64,0x00,0x00, /* 00000D20 ".G.d.d.." */
- 0x01,0x22,0x02,0x00,0x79,0x00,0x5B,0x82, /* 00000D28 "."..y.[." */
- 0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,0x48, /* 00000D30 ":FDC0._H" */
- 0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,0x14, /* 00000D38 "ID.A...." */
- 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D40 "._STA..." */
- 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1B, /* 00000D48 ".._CRS.." */
- 0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,0x03, /* 00000D50 "..G....." */
- 0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,0x03, /* 00000D58 "..G....." */
- 0x01,0x01,0x22,0x40,0x00,0x2A,0x04,0x00, /* 00000D60 ".."@.*.." */
- 0x79,0x00,0x5B,0x82,0x35,0x55,0x41,0x52, /* 00000D68 "y.[.5UAR" */
- 0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000D70 "1._HID.A" */
- 0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,0x44, /* 00000D78 "...._UID" */
- 0x01,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000D80 "..._STA." */
- 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000D88 "...._CRS" */
- 0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8,0x03, /* 00000D90 "....G..." */
- 0xF8,0x03,0x01,0x08,0x22,0x10,0x00,0x79, /* 00000D98 "...."..y" */
- 0x00,0x5B,0x82,0x36,0x4C,0x54,0x50,0x31, /* 00000DA0 ".[.6LTP1" */
- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000DA8 "._HID.A." */
- 0x04,0x00,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000DB0 "..._UID." */
- 0x02,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000DB8 "..._STA." */
- 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000DC0 "...._CRS" */
- 0x11,0x10,0x0A,0x0D,0x47,0x01,0x78,0x03, /* 00000DC8 "....G.x." */
- 0x78,0x03,0x08,0x08,0x22,0x80,0x00,0x79, /* 00000DD0 "x..."..y" */
- 0x00,
+ 0x00,0x08,0x5F,0x53,0x35,0x5F,0x12,0x08, /* 00000058 ".._S5_.." */
+ 0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08, /* 00000060 "........" */
+ 0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F, /* 00000068 "PICD..._" */
+ 0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49, /* 00000070 "PIC.phPI" */
+ 0x43,0x44,0x10,0x44,0xD2,0x5F,0x53,0x42, /* 00000078 "CD.D._SB" */
+ 0x5F,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D, /* 00000080 "_[.I.MEM" */
+ 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000088 "0._HID.A" */
+ 0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53, /* 00000090 "...._CRS" */
+ 0x11,0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00, /* 00000098 ".3.0.+.." */
+ 0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
+ 0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 000000B0 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */
+ 0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, /* 000000C0 "........" */
+ 0x00,0x00,0x79,0x00,0x5B,0x82,0x41,0xCD, /* 000000C8 "..y.[.A." */
+ 0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49, /* 000000D0 "PCI0._HI" */
+ 0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F, /* 000000D8 "D.A...._" */
+ 0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44, /* 000000E0 "UID.._AD" */
+ 0x52,0x00,0x08,0x5F,0x42,0x42,0x4E,0x00, /* 000000E8 "R.._BBN." */
+ 0x14,0x44,0x08,0x5F,0x43,0x52,0x53,0x00, /* 000000F0 ".D._CRS." */
+ 0x08,0x50,0x52,0x54,0x30,0x11,0x42,0x07, /* 000000F8 ".PRT0.B." */
+ 0x0A,0x6E,0x88,0x0D,0x00,0x02,0x0F,0x00, /* 00000100 ".n......" */
+ 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, /* 00000108 "........" */
+ 0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C, /* 00000110 "..G....." */
+ 0x01,0x08,0x88,0x0D,0x00,0x01,0x0C,0x03, /* 00000118 "........" */
+ 0x00,0x00,0x00,0x00,0xF7,0x0C,0x00,0x00, /* 00000120 "........" */
+ 0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03, /* 00000128 "........" */
+ 0x00,0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00, /* 00000130 "........" */
+ 0x00,0xF3,0x87,0x17,0x00,0x00,0x0C,0x03, /* 00000138 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00, /* 00000140 "........" */
+ 0xFF,0xFF,0x0B,0x00,0x00,0x00,0x00,0x00, /* 00000148 "........" */
+ 0x00,0x00,0x02,0x00,0x87,0x17,0x00,0x00, /* 00000150 "........" */
+ 0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000158 "........" */
+ 0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00, /* 00000160 "........" */
+ 0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00, /* 00000168 "......y." */
+ 0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55, /* 00000170 ".PRT0.BU" */
+ 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x60, /* 00000178 "FA....#`" */
+ 0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46, /* 00000180 "..y..BUF" */
+ 0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00, /* 00000188 "B....#.." */
+ 0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42, /* 00000190 ".y..BUFB" */
+ 0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48, /* 00000198 ".IRQV[.H" */
+ 0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48, /* 000001A0 ".LNKA._H" */
+ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000001A8 "ID.A...." */
+ 0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F, /* 000001B0 "_UID..._" */
+ 0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 000001B8 "STA.{PIR" */
+ 0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 000001C0 "A..`...`" */
+ 0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 000001C8 "........" */
+ 0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 000001D0 "...._PRS" */
+ 0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 000001D8 "..BUFA.." */
+ 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 000001E0 "_DIS.}PI" */
+ 0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41, /* 000001E8 "RA..PIRA" */
+ 0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 000001F0 ".._CRS.{" */
+ 0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79, /* 000001F8 "PIRA..`y" */
+ 0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 00000200 ".`IRQV.B" */
+ 0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 00000208 "UFB.._SR" */
+ 0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 00000210 "S..h.IRQ" */
+ 0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 00000218 "1.IRQ1`v" */
+ 0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B, /* 00000220 "`p`PIRA[" */
+ 0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08, /* 00000228 ".I.LNKB." */
+ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000230 "_HID.A.." */
+ 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 00000238 ".._UID.." */
+ 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 00000240 ".._STA.{" */
+ 0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0, /* 00000248 "PIRB..`." */
+ 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 00000250 "..`....." */
+ 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 00000258 "......._" */
+ 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 00000260 "PRS..BUF" */
+ 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000268 "A.._DIS." */
+ 0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50, /* 00000270 "}PIRB..P" */
+ 0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52, /* 00000278 "IRB.._CR" */
+ 0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A, /* 00000280 "S.{PIRB." */
+ 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 00000288 ".`y.`IRQ" */
+ 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 00000290 "V.BUFB.." */
+ 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 00000298 "_SRS..h." */
+ 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 000002A0 "IRQ1.IRQ" */
+ 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 000002A8 "1`v`p`PI" */
+ 0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 000002B0 "RB[.I.LN" */
+ 0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000002B8 "KC._HID." */
+ 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 000002C0 "A...._UI" */
+ 0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54, /* 000002C8 "D...._ST" */
+ 0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A, /* 000002D0 "A.{PIRC." */
+ 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 000002D8 ".`...`.." */
+ 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 000002E0 "........" */
+ 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 000002E8 ".._PRS.." */
+ 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 000002F0 "BUFA.._D" */
+ 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43, /* 000002F8 "IS.}PIRC" */
+ 0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A, /* 00000300 "..PIRC.." */
+ 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000308 "_CRS.{PI" */
+ 0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000310 "RC..`y.`" */
+ 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000318 "IRQV.BUF" */
+ 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000320 "B.._SRS." */
+ 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000328 ".h.IRQ1." */
+ 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000330 "IRQ1`v`p" */
+ 0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49, /* 00000338 "`PIRC[.I" */
+ 0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48, /* 00000340 ".LNKD._H" */
+ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000348 "ID.A...." */
+ 0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C, /* 00000350 "_UID...." */
+ 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 00000358 "_STA.{PI" */
+ 0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000360 "RD..`..." */
+ 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000368 "`......." */
+ 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000370 "....._PR" */
+ 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000378 "S..BUFA." */
+ 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000380 "._DIS.}P" */
+ 0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52, /* 00000388 "IRD..PIR" */
+ 0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000390 "D.._CRS." */
+ 0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60, /* 00000398 "{PIRD..`" */
+ 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 000003A0 "y.`IRQV." */
+ 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 000003A8 "BUFB.._S" */
+ 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 000003B0 "RS..h.IR" */
+ 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 000003B8 "Q1.IRQ1`" */
+ 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44, /* 000003C0 "v`p`PIRD" */
+ 0x5B,0x82,0x3A,0x48,0x50,0x45,0x54,0x08, /* 000003C8 "[.:HPET." */
+ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01, /* 000003D0 "_HID.A.." */
+ 0x03,0x08,0x5F,0x55,0x49,0x44,0x00,0x08, /* 000003D8 ".._UID.." */
+ 0x5F,0x43,0x52,0x53,0x11,0x1F,0x0A,0x1C, /* 000003E0 "_CRS...." */
+ 0x87,0x17,0x00,0x00,0x0D,0x01,0x00,0x00, /* 000003E8 "........" */
+ 0x00,0x00,0x00,0x00,0xD0,0xFE,0xFF,0x03, /* 000003F0 "........" */
+ 0xD0,0xFE,0x00,0x00,0x00,0x00,0x00,0x04, /* 000003F8 "........" */
+ 0x00,0x00,0x79,0x00,0x14,0x16,0x5F,0x50, /* 00000400 "..y..._P" */
+ 0x52,0x54,0x00,0xA0,0x0A,0x50,0x49,0x43, /* 00000408 "RT...PIC" */
+ 0x44,0xA4,0x50,0x52,0x54,0x41,0xA4,0x50, /* 00000410 "D.PRTA.P" */
+ 0x52,0x54,0x50,0x08,0x50,0x52,0x54,0x50, /* 00000418 "RTP.PRTP" */
+ 0x12,0x49,0x36,0x3C,0x12,0x0D,0x04,0x0C, /* 00000420 ".I6<...." */
+ 0xFF,0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B, /* 00000428 ".....LNK" */
+ 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000430 "B......." */
+ 0x01,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000438 "...LNKC." */
+ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 00000440 "........" */
+ 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000448 "..LNKD.." */
+ 0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A, /* 00000450 "........" */
+ 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000458 ".LNKA..." */
+ 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C, /* 00000460 ".......L" */
+ 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000468 "NKC....." */
+ 0xFF,0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B, /* 00000470 ".....LNK" */
+ 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000478 "D......." */
+ 0x02,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000480 "....LNKA" */
+ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02, /* 00000488 "........" */
+ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000490 "...LNKB." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000498 "........" */
+ 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 000004A0 ".LNKD..." */
+ 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C, /* 000004A8 ".......L" */
+ 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000004B0 "NKA....." */
+ 0xFF,0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E, /* 000004B8 "......LN" */
+ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000004C0 "KB......" */
+ 0xFF,0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000004C8 ".....LNK" */
+ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004D0 "C......." */
+ 0x04,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00, /* 000004D8 "...LNKA." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000004E0 "........" */
+ 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 000004E8 ".LNKB..." */
+ 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02, /* 000004F0 "........" */
+ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000004F8 "LNKC...." */
+ 0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C, /* 00000500 ".......L" */
+ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000508 "NKD....." */
+ 0xFF,0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B, /* 00000510 ".....LNK" */
+ 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000518 "B......." */
+ 0x05,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000520 "...LNKC." */
+ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000528 "........" */
+ 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000530 "..LNKD.." */
+ 0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A, /* 00000538 "........" */
+ 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000540 ".LNKA..." */
+ 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,0x4C, /* 00000548 ".......L" */
+ 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000550 "NKC....." */
+ 0xFF,0xFF,0x06,0x00,0x01,0x4C,0x4E,0x4B, /* 00000558 ".....LNK" */
+ 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000560 "D......." */
+ 0x06,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000568 "....LNKA" */
+ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06, /* 00000570 "........" */
+ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000578 "...LNKB." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 00000580 "........" */
+ 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000588 ".LNKD..." */
+ 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x4C, /* 00000590 ".......L" */
+ 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000598 "NKA....." */
+ 0xFF,0xFF,0x07,0x00,0x0A,0x02,0x4C,0x4E, /* 000005A0 "......LN" */
+ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005A8 "KB......" */
+ 0xFF,0x07,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000005B0 ".....LNK" */
+ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000005B8 "C......." */
+ 0x08,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00, /* 000005C0 "...LNKA." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 000005C8 "........" */
+ 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 000005D0 ".LNKB..." */
+ 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02, /* 000005D8 "........" */
+ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000005E0 "LNKC...." */
+ 0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,0x4C, /* 000005E8 ".......L" */
+ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000005F0 "NKD....." */
+ 0xFF,0xFF,0x09,0x00,0x00,0x4C,0x4E,0x4B, /* 000005F8 ".....LNK" */
+ 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000600 "B......." */
+ 0x09,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000608 "...LNKC." */
+ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000610 "........" */
+ 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000618 "..LNKD.." */
+ 0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A, /* 00000620 "........" */
+ 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000628 ".LNKA..." */
+ 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x4C, /* 00000630 ".......L" */
+ 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000638 "NKC....." */
+ 0xFF,0xFF,0x0A,0x00,0x01,0x4C,0x4E,0x4B, /* 00000640 ".....LNK" */
+ 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000648 "D......." */
+ 0x0A,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000650 "....LNKA" */
+ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A, /* 00000658 "........" */
+ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000660 "...LNKB." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 00000668 "........" */
+ 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000670 ".LNKD..." */
+ 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x4C, /* 00000678 ".......L" */
+ 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000680 "NKA....." */
+ 0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x4C,0x4E, /* 00000688 "......LN" */
+ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000690 "KB......" */
+ 0xFF,0x0B,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000698 ".....LNK" */
+ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006A0 "C......." */
+ 0x0C,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00, /* 000006A8 "...LNKA." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 000006B0 "........" */
+ 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 000006B8 ".LNKB..." */
+ 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02, /* 000006C0 "........" */
+ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000006C8 "LNKC...." */
+ 0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x4C, /* 000006D0 ".......L" */
+ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000006D8 "NKD....." */
+ 0xFF,0xFF,0x0D,0x00,0x00,0x4C,0x4E,0x4B, /* 000006E0 ".....LNK" */
+ 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006E8 "B......." */
+ 0x0D,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 000006F0 "...LNKC." */
+ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 000006F8 "........" */
+ 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000700 "..LNKD.." */
+ 0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A, /* 00000708 "........" */
+ 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000710 ".LNKA..." */
+ 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x4C, /* 00000718 ".......L" */
+ 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000720 "NKC....." */
+ 0xFF,0xFF,0x0E,0x00,0x01,0x4C,0x4E,0x4B, /* 00000728 ".....LNK" */
+ 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000730 "D......." */
+ 0x0E,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000738 "....LNKA" */
+ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E, /* 00000740 "........" */
+ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000748 "...LNKB." */
+ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 00000750 "........" */
+ 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000758 ".LNKD..." */
+ 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x4C, /* 00000760 ".......L" */
+ 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000768 "NKA....." */
+ 0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x4C,0x4E, /* 00000770 "......LN" */
+ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000778 "KB......" */
+ 0xFF,0x0F,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000780 ".....LNK" */
+ 0x43,0x00,0x08,0x50,0x52,0x54,0x41,0x12, /* 00000788 "C..PRTA." */
+ 0x41,0x2F,0x3C,0x12,0x0B,0x04,0x0C,0xFF, /* 00000790 "A/<....." */
+ 0xFF,0x01,0x00,0x00,0x00,0x0A,0x14,0x12, /* 00000798 "........" */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01, /* 000007A0 "........" */
+ 0x00,0x0A,0x15,0x12,0x0C,0x04,0x0C,0xFF, /* 000007A8 "........" */
+ 0xFF,0x01,0x00,0x0A,0x02,0x00,0x0A,0x16, /* 000007B0 "........" */
+ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000007B8 "........" */
+ 0x0A,0x03,0x00,0x0A,0x17,0x12,0x0B,0x04, /* 000007C0 "........" */
+ 0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A, /* 000007C8 "........" */
+ 0x18,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02, /* 000007D0 "........" */
+ 0x00,0x01,0x00,0x0A,0x19,0x12,0x0C,0x04, /* 000007D8 "........" */
+ 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x00, /* 000007E0 "........" */
+ 0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000007E8 "........" */
+ 0x02,0x00,0x0A,0x03,0x00,0x0A,0x1B,0x12, /* 000007F0 "........" */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00, /* 000007F8 "........" */
+ 0x00,0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF, /* 00000800 "........" */
+ 0xFF,0x03,0x00,0x01,0x00,0x0A,0x1D,0x12, /* 00000808 "........" */
+ 0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 00000810 "........" */
+ 0x02,0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C, /* 00000818 "........" */
+ 0xFF,0xFF,0x03,0x00,0x0A,0x03,0x00,0x0A, /* 00000820 "........" */
+ 0x1F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04, /* 00000828 "........" */
+ 0x00,0x00,0x00,0x0A,0x20,0x12,0x0B,0x04, /* 00000830 ".... ..." */
+ 0x0C,0xFF,0xFF,0x04,0x00,0x01,0x00,0x0A, /* 00000838 "........" */
+ 0x21,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04, /* 00000840 "!......." */
+ 0x00,0x0A,0x02,0x00,0x0A,0x22,0x12,0x0C, /* 00000848 ".....".." */
+ 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03, /* 00000850 "........" */
+ 0x00,0x0A,0x23,0x12,0x0B,0x04,0x0C,0xFF, /* 00000858 "..#....." */
+ 0xFF,0x05,0x00,0x00,0x00,0x0A,0x24,0x12, /* 00000860 "......$." */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01, /* 00000868 "........" */
+ 0x00,0x0A,0x25,0x12,0x0C,0x04,0x0C,0xFF, /* 00000870 "..%....." */
+ 0xFF,0x05,0x00,0x0A,0x02,0x00,0x0A,0x26, /* 00000878 ".......&" */
+ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000880 "........" */
+ 0x0A,0x03,0x00,0x0A,0x27,0x12,0x0B,0x04, /* 00000888 "....'..." */
+ 0x0C,0xFF,0xFF,0x06,0x00,0x00,0x00,0x0A, /* 00000890 "........" */
+ 0x28,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06, /* 00000898 "(......." */
+ 0x00,0x01,0x00,0x0A,0x29,0x12,0x0C,0x04, /* 000008A0 "....)..." */
+ 0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x00, /* 000008A8 "........" */
+ 0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000008B0 ".*......" */
+ 0x06,0x00,0x0A,0x03,0x00,0x0A,0x2B,0x12, /* 000008B8 "......+." */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00, /* 000008C0 "........" */
+ 0x00,0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF, /* 000008C8 "..,....." */
+ 0xFF,0x07,0x00,0x01,0x00,0x0A,0x2D,0x12, /* 000008D0 "......-." */
+ 0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A, /* 000008D8 "........" */
+ 0x02,0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C, /* 000008E0 "........" */
+ 0xFF,0xFF,0x07,0x00,0x0A,0x03,0x00,0x0A, /* 000008E8 "........" */
+ 0x2F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08, /* 000008F0 "/......." */
+ 0x00,0x00,0x00,0x0A,0x11,0x12,0x0B,0x04, /* 000008F8 "........" */
+ 0x0C,0xFF,0xFF,0x08,0x00,0x01,0x00,0x0A, /* 00000900 "........" */
+ 0x12,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08, /* 00000908 "........" */
+ 0x00,0x0A,0x02,0x00,0x0A,0x13,0x12,0x0C, /* 00000910 "........" */
+ 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03, /* 00000918 "........" */
+ 0x00,0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF, /* 00000920 "........" */
+ 0xFF,0x09,0x00,0x00,0x00,0x0A,0x15,0x12, /* 00000928 "........" */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01, /* 00000930 "........" */
+ 0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF, /* 00000938 "........" */
+ 0xFF,0x09,0x00,0x0A,0x02,0x00,0x0A,0x17, /* 00000940 "........" */
+ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000948 "........" */
+ 0x0A,0x03,0x00,0x0A,0x18,0x12,0x0B,0x04, /* 00000950 "........" */
+ 0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x00,0x0A, /* 00000958 "........" */
+ 0x19,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A, /* 00000960 "........" */
+ 0x00,0x01,0x00,0x0A,0x1A,0x12,0x0C,0x04, /* 00000968 "........" */
+ 0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x00, /* 00000970 "........" */
+ 0x0A,0x1B,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000978 "........" */
+ 0x0A,0x00,0x0A,0x03,0x00,0x0A,0x1C,0x12, /* 00000980 "........" */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00, /* 00000988 "........" */
+ 0x00,0x0A,0x1D,0x12,0x0B,0x04,0x0C,0xFF, /* 00000990 "........" */
+ 0xFF,0x0B,0x00,0x01,0x00,0x0A,0x1E,0x12, /* 00000998 "........" */
+ 0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A, /* 000009A0 "........" */
+ 0x02,0x00,0x0A,0x1F,0x12,0x0C,0x04,0x0C, /* 000009A8 "........" */
+ 0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x00,0x0A, /* 000009B0 "........" */
+ 0x20,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C, /* 000009B8 " ......." */
+ 0x00,0x00,0x00,0x0A,0x21,0x12,0x0B,0x04, /* 000009C0 "....!..." */
+ 0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x00,0x0A, /* 000009C8 "........" */
+ 0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C, /* 000009D0 ""......." */
+ 0x00,0x0A,0x02,0x00,0x0A,0x23,0x12,0x0C, /* 000009D8 ".....#.." */
+ 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03, /* 000009E0 "........" */
+ 0x00,0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF, /* 000009E8 "..$....." */
+ 0xFF,0x0D,0x00,0x00,0x00,0x0A,0x25,0x12, /* 000009F0 "......%." */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01, /* 000009F8 "........" */
+ 0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A00 "..&....." */
+ 0xFF,0x0D,0x00,0x0A,0x02,0x00,0x0A,0x27, /* 00000A08 ".......'" */
+ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000A10 "........" */
+ 0x0A,0x03,0x00,0x0A,0x28,0x12,0x0B,0x04, /* 00000A18 "....(..." */
+ 0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x00,0x0A, /* 00000A20 "........" */
+ 0x29,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E, /* 00000A28 ")......." */
+ 0x00,0x01,0x00,0x0A,0x2A,0x12,0x0C,0x04, /* 00000A30 "....*..." */
+ 0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x00, /* 00000A38 "........" */
+ 0x0A,0x2B,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A40 ".+......" */
+ 0x0E,0x00,0x0A,0x03,0x00,0x0A,0x2C,0x12, /* 00000A48 "......,." */
+ 0x0B,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00, /* 00000A50 "........" */
+ 0x00,0x0A,0x2D,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A58 "..-....." */
+ 0xFF,0x0F,0x00,0x01,0x00,0x0A,0x2E,0x12, /* 00000A60 "........" */
+ 0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000A68 "........" */
+ 0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C, /* 00000A70 ".../...." */
+ 0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A, /* 00000A78 "........" */
+ 0x10,0x5B,0x82,0x4C,0x31,0x49,0x53,0x41, /* 00000A80 ".[.L1ISA" */
+ 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 00000A88 "_._ADR.." */
+ 0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52, /* 00000A90 "...[.PIR" */
+ 0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E, /* 00000A98 "Q..`...." */
+ 0x5C,0x00,0x5B,0x81,0x29,0x5C,0x2F,0x04, /* 00000AA0 "\.[.)\/." */
+ 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00000AA8 "_SB_PCI0" */
+ 0x49,0x53,0x41,0x5F,0x50,0x49,0x52,0x51, /* 00000AB0 "ISA_PIRQ" */
+ 0x01,0x50,0x49,0x52,0x41,0x08,0x50,0x49, /* 00000AB8 ".PIRA.PI" */
+ 0x52,0x42,0x08,0x50,0x49,0x52,0x43,0x08, /* 00000AC0 "RB.PIRC." */
+ 0x50,0x49,0x52,0x44,0x08,0x5B,0x82,0x46, /* 00000AC8 "PIRD.[.F" */
+ 0x0B,0x53,0x59,0x53,0x52,0x08,0x5F,0x48, /* 00000AD0 ".SYSR._H" */
+ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08, /* 00000AD8 "ID.A...." */
+ 0x5F,0x55,0x49,0x44,0x01,0x08,0x43,0x52, /* 00000AE0 "_UID..CR" */
+ 0x53,0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47, /* 00000AE8 "S_.N...G" */
+ 0x01,0x10,0x00,0x10,0x00,0x00,0x10,0x47, /* 00000AF0 ".......G" */
+ 0x01,0x22,0x00,0x22,0x00,0x00,0x0C,0x47, /* 00000AF8 "."."...G" */
+ 0x01,0x30,0x00,0x30,0x00,0x00,0x10,0x47, /* 00000B00 ".0.0...G" */
+ 0x01,0x44,0x00,0x44,0x00,0x00,0x1C,0x47, /* 00000B08 ".D.D...G" */
+ 0x01,0x62,0x00,0x62,0x00,0x00,0x02,0x47, /* 00000B10 ".b.b...G" */
+ 0x01,0x65,0x00,0x65,0x00,0x00,0x0B,0x47, /* 00000B18 ".e.e...G" */
+ 0x01,0x72,0x00,0x72,0x00,0x00,0x0E,0x47, /* 00000B20 ".r.r...G" */
+ 0x01,0x80,0x00,0x80,0x00,0x00,0x01,0x47, /* 00000B28 ".......G" */
+ 0x01,0x84,0x00,0x84,0x00,0x00,0x03,0x47, /* 00000B30 ".......G" */
+ 0x01,0x88,0x00,0x88,0x00,0x00,0x01,0x47, /* 00000B38 ".......G" */
+ 0x01,0x8C,0x00,0x8C,0x00,0x00,0x03,0x47, /* 00000B40 ".......G" */
+ 0x01,0x90,0x00,0x90,0x00,0x00,0x10,0x47, /* 00000B48 ".......G" */
+ 0x01,0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47, /* 00000B50 ".......G" */
+ 0x01,0xE0,0x00,0xE0,0x00,0x00,0x10,0x47, /* 00000B58 ".......G" */
+ 0x01,0xA0,0x08,0xA0,0x08,0x00,0x04,0x47, /* 00000B60 ".......G" */
+ 0x01,0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47, /* 00000B68 ".......G" */
+ 0x01,0xD0,0x04,0xD0,0x04,0x00,0x02,0x79, /* 00000B70 ".......y" */
+ 0x00,0x14,0x0B,0x5F,0x43,0x52,0x53,0x00, /* 00000B78 "..._CRS." */
+ 0xA4,0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B, /* 00000B80 ".CRS_[.+" */
+ 0x50,0x49,0x43,0x5F,0x08,0x5F,0x48,0x49, /* 00000B88 "PIC_._HI" */
+ 0x44,0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52, /* 00000B90 "D.A.._CR" */
+ 0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x20, /* 00000B98 "S....G. " */
+ 0x00,0x20,0x00,0x01,0x02,0x47,0x01,0xA0, /* 00000BA0 ". ...G.." */
+ 0x00,0xA0,0x00,0x01,0x02,0x22,0x04,0x00, /* 00000BA8 ".....".." */
+ 0x79,0x00,0x5B,0x82,0x47,0x05,0x44,0x4D, /* 00000BB0 "y.[.G.DM" */
+ 0x41,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000BB8 "A0._HID." */
+ 0x41,0xD0,0x02,0x00,0x08,0x5F,0x43,0x52, /* 00000BC0 "A...._CR" */
+ 0x53,0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10, /* 00000BC8 "S.A..=*." */
+ 0x04,0x47,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000BD0 ".G......" */
+ 0x10,0x47,0x01,0x81,0x00,0x81,0x00,0x00, /* 00000BD8 ".G......" */
+ 0x03,0x47,0x01,0x87,0x00,0x87,0x00,0x00, /* 00000BE0 ".G......" */
+ 0x01,0x47,0x01,0x89,0x00,0x89,0x00,0x00, /* 00000BE8 ".G......" */
+ 0x03,0x47,0x01,0x8F,0x00,0x8F,0x00,0x00, /* 00000BF0 ".G......" */
+ 0x01,0x47,0x01,0xC0,0x00,0xC0,0x00,0x00, /* 00000BF8 ".G......" */
+ 0x20,0x47,0x01,0x80,0x04,0x80,0x04,0x00, /* 00000C00 " G......" */
+ 0x10,0x79,0x00,0x5B,0x82,0x25,0x54,0x4D, /* 00000C08 ".y.[.%TM" */
+ 0x52,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000C10 "R_._HID." */
+ 0x41,0xD0,0x01,0x00,0x08,0x5F,0x43,0x52, /* 00000C18 "A...._CR" */
+ 0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x40, /* 00000C20 "S....G.@" */
+ 0x00,0x40,0x00,0x00,0x04,0x22,0x01,0x00, /* 00000C28 ".@...".." */
+ 0x79,0x00,0x5B,0x82,0x25,0x52,0x54,0x43, /* 00000C30 "y.[.%RTC" */
+ 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000C38 "_._HID.A" */
+ 0xD0,0x0B,0x00,0x08,0x5F,0x43,0x52,0x53, /* 00000C40 "...._CRS" */
+ 0x11,0x10,0x0A,0x0D,0x47,0x01,0x70,0x00, /* 00000C48 "....G.p." */
+ 0x70,0x00,0x00,0x02,0x22,0x00,0x01,0x79, /* 00000C50 "p..."..y" */
+ 0x00,0x5B,0x82,0x22,0x53,0x50,0x4B,0x52, /* 00000C58 ".[."SPKR" */
+ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C60 "._HID.A." */
+ 0x08,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C68 "..._CRS." */
+ 0x0D,0x0A,0x0A,0x47,0x01,0x61,0x00,0x61, /* 00000C70 "...G.a.a" */
+ 0x00,0x00,0x01,0x79,0x00,0x5B,0x82,0x31, /* 00000C78 "...y.[.1" */
+ 0x50,0x53,0x32,0x4D,0x08,0x5F,0x48,0x49, /* 00000C80 "PS2M._HI" */
+ 0x44,0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F, /* 00000C88 "D.A...._" */
+ 0x43,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13, /* 00000C90 "CID.A..." */
+ 0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4, /* 00000C98 ".._STA.." */
+ 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000CA0 "..._CRS." */
+ 0x08,0x0A,0x05,0x22,0x00,0x10,0x79,0x00, /* 00000CA8 "..."..y." */
+ 0x5B,0x82,0x42,0x04,0x50,0x53,0x32,0x4B, /* 00000CB0 "[.B.PS2K" */
+ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000CB8 "._HID.A." */
+ 0x03,0x03,0x08,0x5F,0x43,0x49,0x44,0x0C, /* 00000CC0 "..._CID." */
+ 0x41,0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53, /* 00000CC8 "A....._S" */
+ 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000CD0 "TA....._" */
+ 0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47, /* 00000CD8 "CRS....G" */
+ 0x01,0x60,0x00,0x60,0x00,0x00,0x01,0x47, /* 00000CE0 ".`.`...G" */
+ 0x01,0x64,0x00,0x64,0x00,0x00,0x01,0x22, /* 00000CE8 ".d.d..."" */
+ 0x02,0x00,0x79,0x00,0x5B,0x82,0x3A,0x46, /* 00000CF0 "..y.[.:F" */
+ 0x44,0x43,0x30,0x08,0x5F,0x48,0x49,0x44, /* 00000CF8 "DC0._HID" */
+ 0x0C,0x41,0xD0,0x07,0x00,0x14,0x09,0x5F, /* 00000D00 ".A....._" */
+ 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000D08 "STA....." */
+ 0x5F,0x43,0x52,0x53,0x11,0x1B,0x0A,0x18, /* 00000D10 "_CRS...." */
+ 0x47,0x01,0xF0,0x03,0xF0,0x03,0x01,0x06, /* 00000D18 "G......." */
+ 0x47,0x01,0xF7,0x03,0xF7,0x03,0x01,0x01, /* 00000D20 "G......." */
+ 0x22,0x40,0x00,0x2A,0x04,0x00,0x79,0x00, /* 00000D28 ""@.*..y." */
+ 0x5B,0x82,0x35,0x55,0x41,0x52,0x31,0x08, /* 00000D30 "[.5UAR1." */
+ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x05, /* 00000D38 "_HID.A.." */
+ 0x01,0x08,0x5F,0x55,0x49,0x44,0x01,0x14, /* 00000D40 ".._UID.." */
+ 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D48 "._STA..." */
+ 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000D50 ".._CRS.." */
+ 0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03, /* 00000D58 "..G....." */
+ 0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B, /* 00000D60 ".."..y.[" */
+ 0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F, /* 00000D68 ".6LTP1._" */
+ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00, /* 00000D70 "HID.A..." */
+ 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000D78 "._UID..." */
+ 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D80 "._STA..." */
+ 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000D88 ".._CRS.." */
+ 0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03, /* 00000D90 "..G.x.x." */
+ 0x08,0x08,0x22,0x80,0x00,0x79,0x00,
};
int DsdtLen=sizeof(AmlCode);
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/rombios/32bit/Makefile
--- a/tools/firmware/rombios/32bit/Makefile Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/rombios/32bit/Makefile Tue Feb 20 12:58:22 2007 -0700
@@ -9,6 +9,8 @@ TARGET = 32bitbios_flat.h
CFLAGS += -fno-builtin -O2 -msoft-float -nostdlib
CFLAGS += -I../ -DGCC_PROTOS
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
SUBDIRS = tcgbios
diff -r 04c23c1ef888 -r d907467f08cd
tools/firmware/rombios/32bit/tcgbios/Makefile
--- a/tools/firmware/rombios/32bit/tcgbios/Makefile Sun Feb 18 16:13:13
2007 -0700
+++ b/tools/firmware/rombios/32bit/tcgbios/Makefile Tue Feb 20 12:58:22
2007 -0700
@@ -9,6 +9,8 @@ OBJECTS = $(foreach f,$(FILES),$(f).o)
OBJECTS = $(foreach f,$(FILES),$(f).o)
CFLAGS += -fno-builtin -O2 -msoft-float -nostdlib
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
CFLAGS += -I../ -I../../ -DGCC_PROTOS
.PHONY: all clean
diff -r 04c23c1ef888 -r d907467f08cd tools/ioemu/hw/tpm_tis.c
--- a/tools/ioemu/hw/tpm_tis.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/ioemu/hw/tpm_tis.c Tue Feb 20 12:58:22 2007 -0700
@@ -769,6 +769,8 @@ static void tpm_save(QEMUFile* f,void* o
if (n > 0) {
if (IS_VALID_LOC(s->active_loc)) {
s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
+ s->loc[s->active_loc].state = STATE_COMPLETION;
+ tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
}
/* close the connection with the vTPM for good */
close_vtpm_channel(s, 1);
@@ -881,6 +883,7 @@ void tpm_tis_init(SetIRQFunc *set_irq, v
s->Transmitlayer = -1;
s->tpmTx.fd[0] = -1;
s->tpmTx.fd[1] = -1;
+ s->aborting_locty = NO_LOCALITY;
tpm_initialize_instance(s, s->vtpm_instance);
memset(s->buffer.buf,0,sizeof(s->buffer.buf));
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage.c
--- a/tools/libfsimage/common/fsimage.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage.c Tue Feb 20 12:58:22 2007 -0700
@@ -36,7 +36,7 @@
static pthread_mutex_t fsi_lock = PTHREAD_MUTEX_INITIALIZER;
-fsi_t *fsi_open_fsimage(const char *path, uint64_t off)
+fsi_t *fsi_open_fsimage(const char *path, uint64_t off, const char *options)
{
fsi_t *fsi = NULL;
int fd;
@@ -53,7 +53,7 @@ fsi_t *fsi_open_fsimage(const char *path
fsi->f_data = NULL;
pthread_mutex_lock(&fsi_lock);
- err = find_plugin(fsi, path);
+ err = find_plugin(fsi, path, options);
pthread_mutex_unlock(&fsi_lock);
if (err != 0)
goto fail;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage.h
--- a/tools/libfsimage/common/fsimage.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage.h Tue Feb 20 12:58:22 2007 -0700
@@ -35,7 +35,7 @@ typedef struct fsi fsi_t;
typedef struct fsi fsi_t;
typedef struct fsi_file fsi_file_t;
-fsi_t *fsi_open_fsimage(const char *, uint64_t);
+fsi_t *fsi_open_fsimage(const char *, uint64_t, const char *);
void fsi_close_fsimage(fsi_t *);
int fsi_file_exists(fsi_t *, const char *);
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_grub.c
--- a/tools/libfsimage/common/fsimage_grub.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_grub.c Tue Feb 20 12:58:22 2007 -0700
@@ -161,7 +161,7 @@ fsig_substring(const char *s1, const cha
}
static int
-fsig_mount(fsi_t *fsi, const char *path)
+fsig_mount(fsi_t *fsi, const char *path, const char *options)
{
fsig_plugin_ops_t *ops = fsi->f_plugin->fp_data;
fsi_file_t *ffi;
@@ -178,7 +178,7 @@ fsig_mount(fsi_t *fsi, const char *path)
bzero(fsi->f_data, sizeof (fsig_data_t));
- if (!ops->fpo_mount(ffi)) {
+ if (!ops->fpo_mount(ffi, options)) {
fsip_file_free(ffi);
free(fsi->f_data);
fsi->f_data = NULL;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_grub.h
--- a/tools/libfsimage/common/fsimage_grub.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_grub.h Tue Feb 20 12:58:22 2007 -0700
@@ -38,7 +38,7 @@ extern C {
typedef struct fsig_plugin_ops {
int fpo_version;
- int (*fpo_mount)(fsi_file_t *);
+ int (*fpo_mount)(fsi_file_t *, const char *);
int (*fpo_dir)(fsi_file_t *, char *);
int (*fpo_read)(fsi_file_t *, char *, int);
} fsig_plugin_ops_t;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_plugin.c
--- a/tools/libfsimage/common/fsimage_plugin.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_plugin.c Tue Feb 20 12:58:22 2007 -0700
@@ -185,7 +185,7 @@ fail:
return (ret);
}
-int find_plugin(fsi_t *fsi, const char *path)
+int find_plugin(fsi_t *fsi, const char *path, const char *options)
{
fsi_plugin_t *fp;
int ret = 0;
@@ -195,7 +195,7 @@ int find_plugin(fsi_t *fsi, const char *
for (fp = plugins; fp != NULL; fp = fp->fp_next) {
fsi->f_plugin = fp;
- if (fp->fp_ops->fpo_mount(fsi, path) == 0)
+ if (fp->fp_ops->fpo_mount(fsi, path, options) == 0)
goto out;
}
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_plugin.h
--- a/tools/libfsimage/common/fsimage_plugin.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_plugin.h Tue Feb 20 12:58:22 2007 -0700
@@ -38,7 +38,7 @@ typedef struct fsi_plugin fsi_plugin_t;
typedef struct fsi_plugin_ops {
int fpo_version;
- int (*fpo_mount)(fsi_t *, const char *);
+ int (*fpo_mount)(fsi_t *, const char *, const char *);
int (*fpo_umount)(fsi_t *);
fsi_file_t *(*fpo_open)(fsi_t *, const char *);
ssize_t (*fpo_read)(fsi_file_t *, void *, size_t);
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_priv.h
--- a/tools/libfsimage/common/fsimage_priv.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_priv.h Tue Feb 20 12:58:22 2007 -0700
@@ -53,7 +53,7 @@ struct fsi_file {
void *ff_data;
};
-int find_plugin(fsi_t *, const char *);
+int find_plugin(fsi_t *, const char *, const char *);
#ifdef __cplusplus
};
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/ext2fs-lib/ext2fs-lib.c
--- a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c Tue Feb 20 12:58:22 2007 -0700
@@ -27,7 +27,7 @@
#include <inttypes.h>
static int
-ext2lib_mount(fsi_t *fsi, const char *name)
+ext2lib_mount(fsi_t *fsi, const char *name, const char *options)
{
int err;
char opts[30] = "";
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/ext2fs/fsys_ext2fs.c
--- a/tools/libfsimage/ext2fs/fsys_ext2fs.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c Tue Feb 20 12:58:22 2007 -0700
@@ -321,7 +321,7 @@ ffz (unsigned long word)
/* check filesystem types and read superblock into memory buffer */
int
-ext2fs_mount (fsi_file_t *ffi)
+ext2fs_mount (fsi_file_t *ffi, const char *options)
{
int retval = 1;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/reiserfs/fsys_reiserfs.c
--- a/tools/libfsimage/reiserfs/fsys_reiserfs.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c Tue Feb 20 12:58:22 2007 -0700
@@ -633,7 +633,7 @@ journal_init (fsi_file_t *ffi)
/* check filesystem types and read superblock into memory buffer */
int
-reiserfs_mount (fsi_file_t *ffi)
+reiserfs_mount (fsi_file_t *ffi, const char *options)
{
struct reiserfs_super_block super;
int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/ufs/fsys_ufs.c
--- a/tools/libfsimage/ufs/fsys_ufs.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/ufs/fsys_ufs.c Tue Feb 20 12:58:22 2007 -0700
@@ -44,7 +44,7 @@ static grub_daddr32_t sbmap(fsi_file_t *
/* read superblock and check fs magic */
int
-ufs_mount(fsi_file_t *ffi)
+ufs_mount(fsi_file_t *ffi, const char *options)
{
if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */
!devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) ||
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/Makefile
--- a/tools/libxc/Makefile Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/Makefile Tue Feb 20 12:58:22 2007 -0700
@@ -22,11 +22,7 @@ CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptra
CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
GUEST_SRCS-y :=
-GUEST_SRCS-y += xc_load_bin.c
-GUEST_SRCS-y += xc_load_elf.c
GUEST_SRCS-y += xg_private.c
-#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
-#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_dom.h
--- a/tools/libxc/xc_dom.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_dom.h Tue Feb 20 12:58:22 2007 -0700
@@ -6,6 +6,8 @@
typedef uint64_t xen_vaddr_t;
typedef uint64_t xen_paddr_t;
+
+#define PRIpfn PRI_xen_pfn
struct xc_dom_seg {
xen_vaddr_t vstart;
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_domain.c Tue Feb 20 12:58:22 2007 -0700
@@ -102,7 +102,7 @@ int xc_vcpu_setaffinity(int xc_handle,
domctl.domain = (domid_t)domid;
domctl.u.vcpuaffinity.vcpu = vcpu;
- bitmap_64_to_byte(local, &cpumap, sizeof (cpumap));
+ bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
@@ -148,7 +148,7 @@ int xc_vcpu_getaffinity(int xc_handle,
ret = do_domctl(xc_handle, &domctl);
unlock_pages(local, sizeof (local));
- bitmap_byte_to_64(cpumap, local, sizeof (local));
+ bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
out:
return ret;
}
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_hvm_build.c Tue Feb 20 12:58:22 2007 -0700
@@ -214,15 +214,6 @@ static int setup_guest(int xc_handle,
v_start, v_end,
elf_uval(&elf, elf.ehdr, e_entry));
- if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
- {
- PERROR("Initial guest OS requires too much space: "
- "(%lluMB is greater than %lluMB limit)\n",
- (unsigned long long)(v_end - v_start) >> 20,
- ((unsigned long long)nr_pages << PAGE_SHIFT) >> 20);
- goto error_out;
- }
-
if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
{
PERROR("Could not allocate memory.\n");
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1319 +0,0 @@
-/******************************************************************************
- * xc_linux_build.c
- */
-
-#include <stddef.h>
-#include "xg_private.h"
-#include "xc_private.h"
-#include <xenctrl.h>
-
-#include "xc_elf.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <zlib.h>
-
-/* Handy for printing out '0' prepended values at native pointer size */
-#define _p(a) ((void *) ((ulong)a))
-
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#if defined(__i386__)
-#define L3_PROT (_PAGE_PRESENT)
-#elif defined(__x86_64__)
-#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#endif
-
-#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-#define round_pgdown(_p) ((_p)&PAGE_MASK)
-
-struct initrd_info {
- enum { INITRD_none, INITRD_file, INITRD_mem } type;
- /*
- * .len must be filled in by the user for type==INITRD_mem. It is
- * filled in by load_initrd() for INITRD_file and unused for
- * INITRD_none.
- */
- unsigned long len;
- union {
- gzFile file_handle;
- char *mem_addr;
- } u;
-};
-
-static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
- [XENFEAT_writable_page_tables] = "writable_page_tables",
- [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
- [XENFEAT_auto_translated_physmap] = "auto_translated_physmap",
- [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel",
- [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
-};
-
-static inline void set_feature_bit (int nr, uint32_t *addr)
-{
- addr[nr>>5] |= (1<<(nr&31));
-}
-
-static inline int test_feature_bit(int nr, uint32_t *addr)
-{
- return !!(addr[nr>>5] & (1<<(nr&31)));
-}
-
-static int parse_features(
- const char *feats,
- uint32_t supported[XENFEAT_NR_SUBMAPS],
- uint32_t required[XENFEAT_NR_SUBMAPS])
-{
- const char *end, *p;
- int i, req;
-
- if ( (end = strchr(feats, ',')) == NULL )
- end = feats + strlen(feats);
-
- while ( feats < end )
- {
- p = strchr(feats, '|');
- if ( (p == NULL) || (p > end) )
- p = end;
-
- req = (*feats == '!');
- if ( req )
- feats++;
-
- for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
- {
- if ( feature_names[i] == NULL )
- continue;
-
- if ( strncmp(feature_names[i], feats, p-feats) == 0 )
- {
- set_feature_bit(i, supported);
- if ( required && req )
- set_feature_bit(i, required);
- break;
- }
- }
-
- if ( i == XENFEAT_NR_SUBMAPS*32 )
- {
- ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats);
- if ( req )
- {
- ERROR("Kernel requires an unknown hypervisor feature.");
- return -EINVAL;
- }
- }
-
- feats = p;
- if ( *feats == '|' )
- feats++;
- }
-
- return -EINVAL;
-}
-
-static int probeimageformat(const char *image,
- unsigned long image_size,
- struct load_funcs *load_funcs)
-{
- if ( probe_elf(image, image_size, load_funcs) &&
- probe_bin(image, image_size, load_funcs) )
- {
- xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int load_initrd(int xc_handle, domid_t dom,
- struct initrd_info *initrd,
- unsigned long physbase,
- xen_pfn_t *phys_to_mach)
-{
- char page[PAGE_SIZE];
- unsigned long pfn_start, pfn;
-
- if ( initrd->type == INITRD_none )
- return 0;
-
- pfn_start = physbase >> PAGE_SHIFT;
-
- if ( initrd->type == INITRD_mem )
- {
- unsigned long nr_pages = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
- for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
- {
- xc_copy_to_domain_page(
- xc_handle, dom, phys_to_mach[pfn],
- &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
- }
- }
- else
- {
- int readlen;
-
- pfn = pfn_start;
- initrd->len = 0;
-
- /* gzread returns 0 on EOF */
- while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
- {
- if ( readlen < 0 )
- {
- PERROR("Error reading initrd image, could not");
- return -EINVAL;
- }
-
- initrd->len += readlen;
- xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
- }
- }
-
- return 0;
-}
-
-#define alloc_pt(ltab, vltab) \
-do { \
- ltab = ppt_alloc++; \
- ltab = (uint64_t)page_array[ltab] << PAGE_SHIFT; \
- if ( vltab != NULL ) \
- munmap(vltab, PAGE_SIZE); \
- if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \
- PROT_READ|PROT_WRITE, \
- ltab >> PAGE_SHIFT)) == NULL ) \
- goto error_out; \
- memset(vltab, 0x0, PAGE_SIZE); \
-} while ( 0 )
-
-#if defined(__i386__)
-
-static int setup_pg_tables(int xc_handle, uint32_t dom,
- vcpu_guest_context_t *ctxt,
- unsigned long dsi_v_start,
- unsigned long v_end,
- xen_pfn_t *page_array,
- unsigned long vpt_start,
- unsigned long vpt_end,
- unsigned shadow_mode_enabled)
-{
- l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
- l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
- unsigned long l1tab = 0;
- unsigned long l2tab = 0;
- unsigned long ppt_alloc;
- unsigned long count;
-
- ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
- alloc_pt(l2tab, vl2tab);
- vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
- ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
-
- for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
- {
- if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
- {
- alloc_pt(l1tab, vl1tab);
- vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
- *vl2e++ = l1tab | L2_PROT;
- }
-
- *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
-
- if ( !shadow_mode_enabled )
- if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
- (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
- *vl1e &= ~_PAGE_RW;
-
- vl1e++;
- }
- munmap(vl1tab, PAGE_SIZE);
- munmap(vl2tab, PAGE_SIZE);
- return 0;
-
- error_out:
- if (vl1tab)
- munmap(vl1tab, PAGE_SIZE);
- if (vl2tab)
- munmap(vl2tab, PAGE_SIZE);
- return -1;
-}
-
-static int setup_pg_tables_pae(int xc_handle, uint32_t dom,
- vcpu_guest_context_t *ctxt,
- unsigned long dsi_v_start,
- unsigned long v_end,
- xen_pfn_t *page_array,
- unsigned long vpt_start,
- unsigned long vpt_end,
- unsigned shadow_mode_enabled,
- unsigned pae_mode)
-{
- l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
- l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
- l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
- uint64_t l1tab, l2tab, l3tab;
- unsigned long ppt_alloc, count, nmfn;
-
- /* First allocate page for page dir. */
- ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
-
- if ( pae_mode == PAEKERN_extended_cr3 )
- {
- ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
- }
- else if ( page_array[ppt_alloc] > 0xfffff )
- {
- nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
- if ( nmfn == 0 )
- {
- DPRINTF("Couldn't get a page below 4GB :-(\n");
- goto error_out;
- }
- page_array[ppt_alloc] = nmfn;
- }
-
- alloc_pt(l3tab, vl3tab);
- vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
- ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
-
- for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
- {
- if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
- {
- if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
- {
- alloc_pt(l2tab, vl2tab);
- vl2e = &vl2tab[l2_table_offset_pae(
- dsi_v_start + (count << PAGE_SHIFT))];
- *vl3e++ = l2tab | L3_PROT;
- }
-
- alloc_pt(l1tab, vl1tab);
- vl1e = &vl1tab[l1_table_offset_pae(
- dsi_v_start + (count << PAGE_SHIFT))];
- *vl2e++ = l1tab | L2_PROT;
-
- }
-
- *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT;
-
- if ( !shadow_mode_enabled )
- if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
- (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
- *vl1e &= ~_PAGE_RW;
-
- vl1e++;
- }
-
- /* Xen requires a mid-level pgdir mapping 0xC0000000 region. */
- if ( (vl3tab[3] & _PAGE_PRESENT) == 0 )
- {
- alloc_pt(l2tab, vl2tab);
- vl3tab[3] = l2tab | L3_PROT;
- }
-
- munmap(vl1tab, PAGE_SIZE);
- munmap(vl2tab, PAGE_SIZE);
- munmap(vl3tab, PAGE_SIZE);
- return 0;
-
- error_out:
- if (vl1tab)
- munmap(vl1tab, PAGE_SIZE);
- if (vl2tab)
- munmap(vl2tab, PAGE_SIZE);
- if (vl3tab)
- munmap(vl3tab, PAGE_SIZE);
- return -1;
-}
-
-#endif
-
-#if defined(__x86_64__)
-
-static int setup_pg_tables_64(int xc_handle, uint32_t dom,
- vcpu_guest_context_t *ctxt,
- unsigned long dsi_v_start,
- unsigned long v_end,
- xen_pfn_t *page_array,
- unsigned long vpt_start,
- unsigned long vpt_end,
- int shadow_mode_enabled)
-{
- l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
- l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
- l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
- l4_pgentry_t *vl4tab=NULL, *vl4e=NULL;
- unsigned long l2tab = 0;
- unsigned long l1tab = 0;
- unsigned long l3tab = 0;
- unsigned long l4tab = 0;
- unsigned long ppt_alloc;
- unsigned long count;
-
- /* First allocate page for page dir. */
- ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
- alloc_pt(l4tab, vl4tab);
- vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
- ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
-
- for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
- {
- if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
- {
- alloc_pt(l1tab, vl1tab);
-
- if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
- {
- alloc_pt(l2tab, vl2tab);
- if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
- {
- alloc_pt(l3tab, vl3tab);
- vl3e = &vl3tab[l3_table_offset(dsi_v_start +
(count<<PAGE_SHIFT))];
- *vl4e++ = l3tab | L4_PROT;
- }
- vl2e = &vl2tab[l2_table_offset(dsi_v_start +
(count<<PAGE_SHIFT))];
- *vl3e++ = l2tab | L3_PROT;
- }
- vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
- *vl2e++ = l1tab | L2_PROT;
- }
-
- *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
-
- if ( !shadow_mode_enabled )
- if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
- (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) )
- *vl1e &= ~_PAGE_RW;
-
- vl1e++;
- }
-
- munmap(vl1tab, PAGE_SIZE);
- munmap(vl2tab, PAGE_SIZE);
- munmap(vl3tab, PAGE_SIZE);
- munmap(vl4tab, PAGE_SIZE);
- return 0;
-
- error_out:
- if (vl1tab)
- munmap(vl1tab, PAGE_SIZE);
- if (vl2tab)
- munmap(vl2tab, PAGE_SIZE);
- if (vl3tab)
- munmap(vl3tab, PAGE_SIZE);
- if (vl4tab)
- munmap(vl4tab, PAGE_SIZE);
- return -1;
-}
-#endif
-
-#ifdef __ia64__
-static int setup_guest(int xc_handle,
- uint32_t dom,
- const char *image, unsigned long image_size,
- struct initrd_info *initrd,
- unsigned long nr_pages,
- unsigned long *pvsi, unsigned long *pvke,
- unsigned long *pvss, vcpu_guest_context_t *ctxt,
- const char *cmdline,
- unsigned long shared_info_frame,
- unsigned long flags,
- unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn,
- uint32_t required_features[XENFEAT_NR_SUBMAPS])
-{
- xen_pfn_t *page_array = NULL;
- struct load_funcs load_funcs;
- struct domain_setup_info dsi;
- unsigned long vinitrd_start;
- unsigned long vinitrd_end;
- unsigned long v_end;
- unsigned long start_page, pgnr;
- start_info_t *start_info;
- unsigned long start_info_mpa;
- struct xen_ia64_boot_param *bp;
- shared_info_t *shared_info;
- int i;
- DECLARE_DOMCTL;
- int rc;
-
- rc = probeimageformat(image, image_size, &load_funcs);
- if ( rc != 0 )
- goto error_out;
-
- memset(&dsi, 0, sizeof(struct domain_setup_info));
-
- rc = (load_funcs.parseimage)(image, image_size, &dsi);
- if ( rc != 0 )
- goto error_out;
-
- if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
- {
- PERROR("Could not allocate memory");
- goto error_out;
- }
- for ( i = 0; i < nr_pages; i++ )
- page_array[i] = i;
- if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
- 0, 0, page_array) )
- {
- PERROR("Could not allocate memory for PV guest.\n");
- goto error_out;
- }
-
- dsi.v_start = round_pgdown(dsi.v_start);
- vinitrd_start = round_pgup(dsi.v_end);
- start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
- *pvke = dsi.v_kernentry;
-
- /* Build firmware. */
- memset(&domctl.u.arch_setup, 0, sizeof(domctl.u.arch_setup));
- domctl.u.arch_setup.flags = 0;
- domctl.u.arch_setup.bp = start_info_mpa + sizeof (start_info_t);
- domctl.u.arch_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT;
- domctl.cmd = XEN_DOMCTL_arch_setup;
- domctl.domain = (domid_t)dom;
- if ( xc_domctl(xc_handle, &domctl) )
- goto error_out;
-
- start_page = dsi.v_start >> PAGE_SHIFT;
- /* in order to get initrd->len, we need to load initrd image at first */
- if ( load_initrd(xc_handle, dom, initrd,
- vinitrd_start - dsi.v_start, page_array + start_page) )
- goto error_out;
-
- vinitrd_end = vinitrd_start + initrd->len;
- v_end = round_pgup(vinitrd_end);
- pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT;
- if ( pgnr > nr_pages )
- {
- PERROR("too small memory is specified. "
- "At least %ld kb is necessary.\n",
- pgnr << (PAGE_SHIFT - 10));
- }
-
- IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
- " Loaded kernel: %p->%p\n"
- " Init. ramdisk: %p->%p\n"
- " TOTAL: %p->%p\n",
- _p(dsi.v_kernstart), _p(dsi.v_kernend),
- _p(vinitrd_start), _p(vinitrd_end),
- _p(dsi.v_start), _p(v_end));
- IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
-
- (load_funcs.loadimage)(image, image_size, xc_handle, dom,
- page_array + start_page, &dsi);
-
- *store_mfn = page_array[nr_pages - 2]; //XXX
- *console_mfn = page_array[nr_pages - 1]; //XXX
- IPRINTF("start_info: 0x%lx at 0x%lx, "
- "store_mfn: 0x%lx at 0x%lx, "
- "console_mfn: 0x%lx at 0x%lx\n",
- page_array[nr_pages - 3], nr_pages - 3,
- *store_mfn, nr_pages - 2,
- *console_mfn, nr_pages - 1);
-
- start_info = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- page_array[nr_pages - 3]);
- if ( start_info == NULL )
- goto error_out;
-
- memset(start_info, 0, sizeof(*start_info));
- rc = xc_version(xc_handle, XENVER_version, NULL);
- sprintf(start_info->magic, "xen-%i.%i-ia64", rc >> 16, rc & (0xFFFF));
- start_info->flags = flags;
- start_info->store_mfn = nr_pages - 2;
- start_info->store_evtchn = store_evtchn;
- start_info->console.domU.mfn = nr_pages - 1;
- start_info->console.domU.evtchn = console_evtchn;
- start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ????
-
- bp = (struct xen_ia64_boot_param *)(start_info + 1);
- bp->command_line = start_info_mpa + offsetof(start_info_t, cmd_line);
- if ( cmdline != NULL )
- {
- strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
- start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = 0;
- }
- if ( initrd->len != 0 )
- {
- bp->initrd_start = vinitrd_start;
- bp->initrd_size = initrd->len;
- }
- ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t);
- munmap(start_info, PAGE_SIZE);
-
- /*
- * shared_info is assiged into guest pseudo physical address space
- * by XEN_DOMCTL_arch_setup. shared_info_frame is stale value until that.
- * So passed shared_info_frame is stale. obtain the right value here.
- */
- domctl.cmd = XEN_DOMCTL_getdomaininfo;
- domctl.domain = (domid_t)dom;
- if ( (xc_domctl(xc_handle, &domctl) < 0) ||
- ((uint16_t)domctl.domain != dom) )
- {
- PERROR("Could not get info on domain");
- goto error_out;
- }
- shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
-
- /* shared_info page starts its life empty. */
- shared_info = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
- printf("shared_info = %p frame=%lx\n",
- shared_info, shared_info_frame);
- //memset(shared_info, 0, PAGE_SIZE);
- /* Mask all upcalls... */
- for ( i = 0; i < MAX_VIRT_CPUS; i++ )
- shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
- shared_info->arch.start_info_pfn = nr_pages - 3;
-
- munmap(shared_info, PAGE_SIZE);
- free(page_array);
- return 0;
-
- error_out:
- free(page_array);
- return -1;
-}
-#else /* x86 */
-
-/* Check if the platform supports the guest kernel format */
-static int compat_check(int xc_handle, struct domain_setup_info *dsi)
-{
- xen_capabilities_info_t xen_caps = "";
-
- if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
- xc_set_error(XC_INVALID_KERNEL,
- "Cannot determine host capabilities.");
- return 0;
- }
-
-#ifndef __x86_64__//temp
- if (strstr(xen_caps, "xen-3.0-x86_32p")) {
- if (dsi->pae_kernel == PAEKERN_bimodal) {
- dsi->pae_kernel = PAEKERN_extended_cr3;
- } else if (dsi->pae_kernel == PAEKERN_no) {
- xc_set_error(XC_INVALID_KERNEL,
- "Non PAE-kernel on PAE host.");
- return 0;
- }
- } else {
- if (dsi->pae_kernel == PAEKERN_bimodal) {
- dsi->pae_kernel = PAEKERN_no;
- } else if (dsi->pae_kernel != PAEKERN_no) {
- xc_set_error(XC_INVALID_KERNEL,
- "PAE-kernel on non-PAE host.");
- return 0;
- }
- }
-#endif
-
- return 1;
-}
-
-static inline int increment_ulong(unsigned long *pval, unsigned long inc)
-{
- if ( inc >= -*pval )
- {
- ERROR("Value wrapped to zero: image too large?");
- return 0;
- }
- *pval += inc;
- return 1;
-}
-
-static int setup_guest(int xc_handle,
- uint32_t dom,
- const char *image, unsigned long image_size,
- struct initrd_info *initrd,
- unsigned long nr_pages,
- unsigned long *pvsi, unsigned long *pvke,
- unsigned long *pvss, vcpu_guest_context_t *ctxt,
- const char *cmdline,
- unsigned long shared_info_frame,
- unsigned long flags,
- unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn,
- uint32_t required_features[XENFEAT_NR_SUBMAPS])
-{
- xen_pfn_t *page_array = NULL;
- unsigned long count, i;
- unsigned long long hypercall_page;
- int hypercall_page_defined;
- start_info_t *start_info;
- shared_info_t *shared_info;
- const char *p;
- DECLARE_DOMCTL;
- int rc;
-
- unsigned long nr_pt_pages;
- unsigned long physmap_pfn;
- xen_pfn_t *physmap, *physmap_e;
-
- struct load_funcs load_funcs;
- struct domain_setup_info dsi;
- unsigned long vinitrd_start;
- unsigned long vphysmap_start;
- unsigned long vstartinfo_start;
- unsigned long vstoreinfo_start;
- unsigned long vconsole_start;
- unsigned long vsharedinfo_start = 0; /* XXX gcc */
- unsigned long vstack_start;
- unsigned long vstack_end;
- unsigned long vpt_start;
- unsigned long vpt_end;
- unsigned long v_end;
- unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
- unsigned long shadow_mode_enabled;
- uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
-
- rc = probeimageformat(image, image_size, &load_funcs);
- if ( rc != 0 )
- goto error_out;
-
- memset(&dsi, 0, sizeof(struct domain_setup_info));
-
- rc = (load_funcs.parseimage)(image, image_size, &dsi);
- if ( rc != 0 )
- goto error_out;
-
- if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
- {
- PERROR("Guest OS must load to a page boundary.");
- goto error_out;
- }
-
- if ( !compat_check(xc_handle, &dsi) )
- goto error_out;
-
- /* Parse and validate kernel features. */
- if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
- {
- if ( !parse_features(p, supported_features, required_features) )
- {
- ERROR("Failed to parse guest kernel features.");
- goto error_out;
- }
-
- IPRINTF("Supported features = { %08x }.\n", supported_features[0]);
- IPRINTF("Required features = { %08x }.\n", required_features[0]);
- }
-
- for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
- {
- if ( (supported_features[i] & required_features[i]) !=
- required_features[i] )
- {
- ERROR("Guest kernel does not support a required feature.");
- goto error_out;
- }
- }
-
- shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
- required_features);
-
- if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
- {
- PERROR("Could not allocate memory");
- goto error_out;
- }
-
- for ( i = 0; i < nr_pages; i++ )
- page_array[i] = i;
-
- if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
- 0, 0, page_array) )
- {
- PERROR("Could not allocate memory for PV guest.\n");
- goto error_out;
- }
-
-
- if ( shadow_mode_enabled )
- {
- /*
- * Enable shadow translate mode. This must happen after
- * populate physmap because the p2m reservation is based on
- * the domain's current memory allocation.
- */
- if ( xc_shadow_control(xc_handle, dom,
- XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE,
- NULL, 0, NULL, 0, NULL) < 0 )
- {
- PERROR("Could not enable translation mode");
- goto error_out;
- }
-
- /* Reinitialise the gpfn->gmfn array. */
- for ( i = 0; i < nr_pages; i++ )
- page_array[i] = i;
- }
-
- rc = (load_funcs.loadimage)(image, image_size,
- xc_handle, dom, page_array,
- &dsi);
- if ( rc != 0 )
- goto error_out;
-
- /*
- * Why do we need this? The number of page-table frames depends on the
- * size of the bootstrap address space. But the size of the address space
- * depends on the number of page-table frames (since each one is mapped
- * read-only). We have a pair of simultaneous equations in two unknowns,
- * which we solve by exhaustive search.
- */
- v_end = round_pgup(dsi.v_end);
- if ( v_end == 0 )
- {
- ERROR("End of mapped kernel image too close to end of memory");
- goto error_out;
- }
-
- vinitrd_start = v_end;
- if ( load_initrd(xc_handle, dom, initrd,
- vinitrd_start - dsi.v_start, page_array) )
- goto error_out;
- if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
- goto error_out;
-
- vphysmap_start = v_end;
- if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
- goto error_out;
- vstartinfo_start = v_end;
- if ( !increment_ulong(&v_end, PAGE_SIZE) )
- goto error_out;
- vstoreinfo_start = v_end;
- if ( !increment_ulong(&v_end, PAGE_SIZE) )
- goto error_out;
- vconsole_start = v_end;
- if ( !increment_ulong(&v_end, PAGE_SIZE) )
- goto error_out;
- if ( shadow_mode_enabled ) {
- vsharedinfo_start = v_end;
- if ( !increment_ulong(&v_end, PAGE_SIZE) )
- goto error_out;
- }
- vpt_start = v_end;
-
- for ( nr_pt_pages = 2; ; nr_pt_pages++ )
- {
- /* vpt_end = vpt_staret + (nr_pt_pages * PAGE_SIZE); */
- vpt_end = vpt_start;
- if ( !increment_ulong(&vpt_end, nr_pt_pages * PAGE_SIZE) )
- goto error_out;
-
- vstack_start = vpt_end;
- /* vstack_end = vstack_start + PAGE_SIZE; */
- vstack_end = vstack_start;
- if ( !increment_ulong(&vstack_end, PAGE_SIZE) )
- goto error_out;
-
- /* v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); */
- v_end = vstack_end;
- if ( !increment_ulong(&v_end, (1UL<<22)-1) )
- goto error_out;
- v_end &= ~((1UL<<22)-1);
-
- if ( (v_end - vstack_end) < (512UL << 10) )
- {
- /* Add extra 4MB to get >= 512kB padding. */
- if ( !increment_ulong(&v_end, 1UL << 22) )
- goto error_out;
- }
-
-#define NR(_l,_h,_s) \
- (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
- ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
-#if defined(__i386__)
- if ( dsi.pae_kernel != PAEKERN_no )
- {
- if ( (1 + /* # L3 */
- NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */
- NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT_PAE) + /* # L1 */
- /* Include a fourth mid-level page directory for Xen. */
- (v_end <= (3 << L3_PAGETABLE_SHIFT_PAE)))
- <= nr_pt_pages )
- break;
- }
- else
- {
- if ( (1 + /* # L2 */
- NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
- <= nr_pt_pages )
- break;
- }
-#elif defined(__x86_64__)
- if ( (1 + /* # L4 */
- NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
- NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
- NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
- <= nr_pt_pages )
- break;
-#endif
- }
-
- IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
- IPRINTF(" Loaded kernel: %p->%p\n", _p(dsi.v_kernstart),
- _p(dsi.v_kernend));
- if ( initrd->len )
- IPRINTF(" Initial ramdisk: %p->%p\n", _p(vinitrd_start),
- _p(vinitrd_start + initrd->len));
- IPRINTF(" Phys-Mach map: %p\n", _p(vphysmap_start));
- IPRINTF(" Start info: %p\n", _p(vstartinfo_start));
- IPRINTF(" Store page: %p\n", _p(vstoreinfo_start));
- IPRINTF(" Console page: %p\n", _p(vconsole_start));
- if ( shadow_mode_enabled )
- IPRINTF(" Shared Info page: %p\n", _p(vsharedinfo_start));
- IPRINTF(" Page tables: %p\n", _p(vpt_start));
- IPRINTF(" Boot stack: %p\n", _p(vstack_start));
- IPRINTF(" TOTAL: %p->%p\n", _p(dsi.v_start), _p(v_end));
- IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
-
- if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
- {
- PERROR("Initial guest OS requires too much space\n"
- "(%pMB is greater than %luMB limit)\n",
- _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
- goto error_out;
- }
-
-#if defined(__i386__)
- if ( dsi.pae_kernel != PAEKERN_no )
- rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
- dsi.v_start, v_end,
- page_array, vpt_start, vpt_end,
- shadow_mode_enabled, dsi.pae_kernel);
- else
- rc = setup_pg_tables(xc_handle, dom, ctxt,
- dsi.v_start, v_end,
- page_array, vpt_start, vpt_end,
- shadow_mode_enabled);
-#endif
-#if defined(__x86_64__)
- rc = setup_pg_tables_64(xc_handle, dom, ctxt,
- dsi.v_start, v_end,
- page_array, vpt_start, vpt_end,
- shadow_mode_enabled);
-#endif
- if ( rc != 0 )
- goto error_out;
-
- /*
- * Pin down l2tab addr as page dir page - causes hypervisor to provide
- * correct protection for the page
- */
- if ( !shadow_mode_enabled )
- {
-#if defined(__i386__)
- if ( dsi.pae_kernel != PAEKERN_no )
- {
- if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
- xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
- goto error_out;
- }
- else
- {
- if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
- xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
- goto error_out;
- }
-#elif defined(__x86_64__)
- /*
- * Pin down l4tab addr as page dir page - causes hypervisor to provide
- * correct protection for the page
- */
- if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
- xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
- goto error_out;
-#endif
- }
-
- /* Write the phys->machine table entries (machine->phys already done). */
- physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
- physmap = physmap_e = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- page_array[physmap_pfn++]);
- for ( count = 0; count < nr_pages; count++ )
- {
- *physmap_e++ = page_array[count];
- if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 )
- {
- munmap(physmap, PAGE_SIZE);
- physmap = physmap_e = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- page_array[physmap_pfn++]);
- }
- }
- munmap(physmap, PAGE_SIZE);
-
- if ( shadow_mode_enabled )
- {
- struct xen_add_to_physmap xatp;
-
- guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT;
-
- /* Map shared info frame into guest physmap. */
- xatp.domid = dom;
- xatp.space = XENMAPSPACE_shared_info;
- xatp.idx = 0;
- xatp.gpfn = guest_shared_info_mfn;
- rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
- if ( rc != 0 )
- {
- PERROR("Cannot map shared info pfn");
- goto error_out;
- }
-
- /* Map grant table frames into guest physmap. */
- for ( i = 0; ; i++ )
- {
- xatp.domid = dom;
- xatp.space = XENMAPSPACE_grant_table;
- xatp.idx = i;
- xatp.gpfn = nr_pages + i;
- rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
- if ( rc != 0 )
- {
- if ( errno == EINVAL )
- break; /* done all grant tables */
- PERROR("Cannot map grant table pfn");
- goto error_out;
- }
- }
- }
- else
- {
- guest_shared_info_mfn = shared_info_frame;
- }
-
- *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT];
- *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT];
- if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ||
- xc_clear_domain_page(xc_handle, dom, *console_mfn) )
- goto error_out;
- if ( shadow_mode_enabled )
- {
- guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT;
- guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT;
- }
- else
- {
- guest_store_mfn = *store_mfn;
- guest_console_mfn = *console_mfn;
- }
-
- start_info = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
- page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
- /*shared_info, start_info */
- memset(start_info, 0, sizeof(*start_info));
- rc = xc_version(xc_handle, XENVER_version, NULL);
- sprintf(start_info->magic, "xen-%i.%i-x86_%d%s",
- rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8,
- (dsi.pae_kernel != PAEKERN_no) ? "p" : "");
- start_info->nr_pages = nr_pages;
- start_info->shared_info = guest_shared_info_mfn << PAGE_SHIFT;
- start_info->flags = flags;
- start_info->pt_base = vpt_start;
- start_info->nr_pt_frames = nr_pt_pages;
- start_info->mfn_list = vphysmap_start;
- start_info->store_mfn = guest_store_mfn;
- start_info->store_evtchn = store_evtchn;
- start_info->console.domU.mfn = guest_console_mfn;
- start_info->console.domU.evtchn = console_evtchn;
- if ( initrd->len != 0 )
- {
- start_info->mod_start = vinitrd_start;
- start_info->mod_len = initrd->len;
- }
- if ( cmdline != NULL )
- {
- strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
- start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
- }
- munmap(start_info, PAGE_SIZE);
-
- /* shared_info page starts its life empty. */
- shared_info = xc_map_foreign_range(
- xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
- memset(shared_info, 0, PAGE_SIZE);
- /* Mask all upcalls... */
- for ( i = 0; i < MAX_VIRT_CPUS; i++ )
- shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
-
- munmap(shared_info, PAGE_SIZE);
-
- hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
- &hypercall_page_defined);
- if ( hypercall_page_defined )
- {
- unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT;
- if ( pfn >= nr_pages )
- goto error_out;
- domctl.domain = (domid_t)dom;
- domctl.u.hypercall_init.gmfn = page_array[pfn];
- domctl.cmd = XEN_DOMCTL_hypercall_init;
- if ( xc_domctl(xc_handle, &domctl) )
- goto error_out;
- }
-
- free(page_array);
-
- *pvsi = vstartinfo_start;
- *pvss = vstack_start;
- *pvke = dsi.v_kernentry;
-
- return 0;
-
- error_out:
- free(page_array);
- return -1;
-}
-#endif
-
-static int xc_linux_build_internal(int xc_handle,
- uint32_t domid,
- unsigned int mem_mb,
- const char *image,
- unsigned long image_size,
- struct initrd_info *initrd,
- const char *cmdline,
- const char *features,
- unsigned long flags,
- unsigned int store_evtchn,
- unsigned long *store_mfn,
- unsigned int console_evtchn,
- unsigned long *console_mfn)
-{
- struct xen_domctl launch_domctl;
- DECLARE_DOMCTL;
- int rc;
- struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt;
- unsigned long vstartinfo_start, vkern_entry, vstack_start;
- uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
-
- if ( features != NULL )
- {
- if ( !parse_features(features, features_bitmap, NULL) )
- {
- PERROR("Failed to parse configured features\n");
- goto error_out;
- }
- }
-
- memset(ctxt, 0, sizeof(*ctxt));
-
- if ( lock_pages(ctxt, sizeof(*ctxt) ) )
- {
- PERROR("%s: ctxt lock failed", __func__);
- return 1;
- }
-
- domctl.cmd = XEN_DOMCTL_getdomaininfo;
- domctl.domain = (domid_t)domid;
- if ( (xc_domctl(xc_handle, &domctl) < 0) ||
- ((uint16_t)domctl.domain != domid) )
- {
- PERROR("Could not get info on domain");
- goto error_out;
- }
-
- if ( setup_guest(xc_handle, domid, image, image_size,
- initrd,
- mem_mb << (20 - PAGE_SHIFT),
- &vstartinfo_start, &vkern_entry,
- &vstack_start, ctxt, cmdline,
- domctl.u.getdomaininfo.shared_info_frame,
- flags, store_evtchn, store_mfn,
- console_evtchn, console_mfn,
- features_bitmap) < 0 )
- {
- goto error_out;
- }
-
-#ifdef __ia64__
- /* based on new_thread in xen/arch/ia64/domain.c */
- ctxt->user_regs.cr_iip = vkern_entry;
- ctxt->user_regs.cr_ifs = 1UL << 63;
- ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default();
-#else /* x86 */
- /*
- * Initial register values:
- * DS,ES,FS,GS = FLAT_KERNEL_DS
- * CS:EIP = FLAT_KERNEL_CS:start_pc
- * SS:ESP = FLAT_KERNEL_DS:start_stack
- * ESI = start_info
- * [EAX,EBX,ECX,EDX,EDI,EBP are zero]
- * EFLAGS = IF | 2 (bit 1 is reserved and should always be 1)
- */
- ctxt->user_regs.ds = FLAT_KERNEL_DS;
- ctxt->user_regs.es = FLAT_KERNEL_DS;
- ctxt->user_regs.fs = FLAT_KERNEL_DS;
- ctxt->user_regs.gs = FLAT_KERNEL_DS;
- ctxt->user_regs.ss = FLAT_KERNEL_SS;
- ctxt->user_regs.cs = FLAT_KERNEL_CS;
- ctxt->user_regs.eip = vkern_entry;
- ctxt->user_regs.esp = vstack_start + PAGE_SIZE;
- ctxt->user_regs.esi = vstartinfo_start;
- ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
-
- ctxt->flags = VGCF_IN_KERNEL;
-
- ctxt->kernel_ss = ctxt->user_regs.ss;
- ctxt->kernel_sp = ctxt->user_regs.esp;
-#endif /* x86 */
-
- memset(&launch_domctl, 0, sizeof(launch_domctl));
-
- launch_domctl.domain = (domid_t)domid;
- launch_domctl.u.vcpucontext.vcpu = 0;
- set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
-
- launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
- rc = xc_domctl(xc_handle, &launch_domctl);
-
- return rc;
-
- error_out:
- return -1;
-}
-
-int xc_linux_build_mem(int xc_handle,
- uint32_t domid,
- unsigned int mem_mb,
- const char *image_buffer,
- unsigned long image_size,
- const char *initrd,
- unsigned long initrd_len,
- const char *cmdline,
- const char *features,
- unsigned long flags,
- unsigned int store_evtchn,
- unsigned long *store_mfn,
- unsigned int console_evtchn,
- unsigned long *console_mfn)
-{
- int sts;
- char *img_buf;
- unsigned long img_len;
- struct initrd_info initrd_info = { .type = INITRD_none };
-
- /* A kernel buffer is required */
- if ( (image_buffer == NULL) || (image_size == 0) )
- {
- ERROR("kernel image buffer not present");
- return -1;
- }
-
- /* If it's gzipped, inflate it; otherwise, use as is */
- /* xc_inflate_buffer may return the same buffer pointer if */
- /* the buffer is already inflated */
- img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len);
- if ( img_buf == NULL )
- {
- ERROR("unable to inflate kernel image buffer");
- return -1;
- }
-
- /* RAM disks are optional; if we get one, inflate it */
- if ( initrd != NULL )
- {
- initrd_info.type = INITRD_mem;
- initrd_info.u.mem_addr = xc_inflate_buffer(
- initrd, initrd_len, &initrd_info.len);
- if ( initrd_info.u.mem_addr == NULL )
- {
- ERROR("unable to inflate ram disk buffer");
- sts = -1;
- goto out;
- }
- }
-
- sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len,
- &initrd_info, cmdline, features, flags,
- store_evtchn, store_mfn,
- console_evtchn, console_mfn);
-
- out:
- /* The inflation routines may pass back the same buffer so be */
- /* sure that we have a buffer and that it's not the one passed in. */
- /* Don't unnecessarily annoy/surprise/confound the caller */
- if ( (img_buf != NULL) && (img_buf != image_buffer) )
- free(img_buf);
- if ( (initrd_info.u.mem_addr != NULL) &&
- (initrd_info.u.mem_addr != initrd) )
- free(initrd_info.u.mem_addr);
-
- return sts;
-}
-
-int xc_linux_build(int xc_handle,
- uint32_t domid,
- unsigned int mem_mb,
- const char *image_name,
- const char *initrd_name,
- const char *cmdline,
- const char *features,
- unsigned long flags,
- unsigned int store_evtchn,
- unsigned long *store_mfn,
- unsigned int console_evtchn,
- unsigned long *console_mfn)
-{
- char *image = NULL;
- unsigned long image_size;
- struct initrd_info initrd_info = { .type = INITRD_none };
- int fd = -1, sts = -1;
-
- if ( (image_name == NULL) ||
- ((image = xc_read_image(image_name, &image_size)) == NULL ))
- return -1;
-
- if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) )
- {
- initrd_info.type = INITRD_file;
-
- if ( (fd = open(initrd_name, O_RDONLY)) < 0 )
- {
- PERROR("Could not open the initial ramdisk image");
- goto error_out;
- }
-
- if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
- {
- PERROR("Could not allocate decompression state for initrd");
- goto error_out;
- }
- }
-
- sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size,
- &initrd_info, cmdline, features, flags,
- store_evtchn, store_mfn,
- console_evtchn, console_mfn);
-
- error_out:
- free(image);
- if ( initrd_info.type == INITRD_file && initrd_info.u.file_handle )
- gzclose(initrd_info.u.file_handle);
- else if ( fd >= 0 )
- close(fd);
-
- return sts;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_linux_restore.c Tue Feb 20 12:58:22 2007 -0700
@@ -82,7 +82,7 @@ static int uncanonicalize_pagetable(int
if(!(pte & _PAGE_PRESENT))
continue;
- pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
+ pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
if(pfn >= max_pfn) {
/* This "page table page" is probably not one; bail. */
@@ -120,12 +120,12 @@ static int uncanonicalize_pagetable(int
if(!(pte & _PAGE_PRESENT))
continue;
- pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
+ pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
if(p2m[pfn] == INVALID_P2M_ENTRY)
p2m[pfn] = p2m_batch[nr_mfns++];
- pte &= 0xffffff0000000fffULL;
+ pte &= ~MADDR_MASK_X86;
pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
if(pt_levels == 2)
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_linux_save.c Tue Feb 20 12:58:22 2007 -0700
@@ -495,7 +495,7 @@ static int canonicalize_pagetable(unsign
hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
he = ((const uint64_t *) spage)[hstart];
- if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) {
+ if ( ((he >> PAGE_SHIFT) & MFN_MASK_X86) == m2p_mfn0 ) {
/* hvirt starts with xen stuff... */
xen_start = hstart;
} else if ( hvirt_start != 0xf5800000 ) {
@@ -503,7 +503,7 @@ static int canonicalize_pagetable(unsign
hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
he = ((const uint64_t *) spage)[hstart];
- if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 )
+ if( ((he >> PAGE_SHIFT) & MFN_MASK_X86) == m2p_mfn0 )
xen_start = hstart;
}
}
@@ -532,7 +532,7 @@ static int canonicalize_pagetable(unsign
if (pte & _PAGE_PRESENT) {
- mfn = (pte >> PAGE_SHIFT) & 0xfffffff;
+ mfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) {
/* This will happen if the type info is stale which
is quite feasible under live migration */
@@ -541,7 +541,7 @@ static int canonicalize_pagetable(unsign
} else
pfn = mfn_to_pfn(mfn);
- pte &= 0xffffff0000000fffULL;
+ pte &= ~MADDR_MASK_X86;
pte |= (uint64_t)pfn << PAGE_SHIFT;
}
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_load_bin.c
--- a/tools/libxc/xc_load_bin.c Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/******************************************************************************
- * xc_bin_load.c
- *
- * Based on xc_elf_load.c
- *
- * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are
- * present. The only requirement is that it must have a xen_bin_image table
- * somewhere in the first 8192 bytes, starting on a 32-bit aligned address.
- * Those familiar with the multiboot specification should recognize this, it's
- * (almost) the same as the multiboot header.
- * The layout of the xen_bin_image table is:
- *
- * Offset Type Name Note
- * 0 uint32_t magic required
- * 4 uint32_t flags required
- * 8 uint32_t checksum required
- * 12 uint32_t header_addr required
- * 16 uint32_t load_addr required
- * 20 uint32_t load_end_addr required
- * 24 uint32_t bss_end_addr required
- * 28 uint32_t entry_addr required
- *
- * - magic
- * Magic number identifying the table. For images to be loaded by Xen 3, the
- * magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set).
- * - flags
- * bit 0: indicates whether the image needs to be loaded on a page boundary
- * bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate
- * that memory info should be passed to the image)
- * bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate
- * that the bootloader should pass video mode info to the image)
- * bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate
- * that the values in the fields header_addr - entry_addr are
- * valid)
- * All other bits should be set to 0.
- * - checksum
- * When added to "magic" and "flags", the resulting value should be 0.
- * - header_addr
- * Contains the virtual address corresponding to the beginning of the
- * table - the memory location at which the magic value is supposed to be
- * loaded. This field serves to synchronize the mapping between OS image
- * offsets and virtual memory addresses.
- * - load_addr
- * Contains the virtual address of the beginning of the text segment. The
- * offset in the OS image file at which to start loading is defined by the
- * offset at which the table was found, minus (header addr - load addr).
- * load addr must be less than or equal to header addr.
- * - load_end_addr
- * Contains the virtual address of the end of the data segment.
- * (load_end_addr - load_addr) specifies how much data to load. This implies
- * that the text and data segments must be consecutive in the OS image. If
- * this field is zero, the domain builder assumes that the text and data
- * segments occupy the whole OS image file.
- * - bss_end_addr
- * Contains the virtual address of the end of the bss segment. The domain
- * builder initializes this area to zero, and reserves the memory it occupies
- * to avoid placing boot modules and other data relevant to the loaded image
- * in that area. If this field is zero, the domain builder assumes that no
bss
- * segment is present.
- * - entry_addr
- * The virtual address at which to start execution of the loaded image.
- *
- * Some of the field descriptions were copied from "The Multiboot
- * Specification", Copyright 1995, 96 Bryan Ford <baford@xxxxxxxxxxx>,
- * Erich Stefan Boleyn <erich@xxxxxxxx> Copyright 1999, 2000, 2001, 2002
- * Free Software Foundation, Inc.
- */
-
-#include "xg_private.h"
-#include <stdlib.h>
-
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-
-#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-#define round_pgdown(_p) ((_p)&PAGE_MASK)
-
-struct xen_bin_image_table
-{
- unsigned long magic;
- unsigned long flags;
- unsigned long checksum;
- unsigned long header_addr;
- unsigned long load_addr;
- unsigned long load_end_addr;
- unsigned long bss_end_addr;
- unsigned long entry_addr;
-};
-
-#define XEN_REACTOS_MAGIC3 0x336ec578
-
-#define XEN_REACTOS_FLAG_ALIGN4K 0x00000001
-#define XEN_REACTOS_FLAG_NEEDMEMINFO 0x00000002
-#define XEN_REACTOS_FLAG_NEEDVIDINFO 0x00000004
-#define XEN_REACTOS_FLAG_ADDRSVALID 0x00010000
-
-/* Flags we test for */
-#define FLAGS_MASK ((~ 0) & (~ XEN_REACTOS_FLAG_ALIGN4K))
-#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID
-
-static const struct xen_bin_image_table *
-findtable(const char *image, unsigned long image_size);
-static int
-parsebinimage(
- const char *image, unsigned long image_size,
- struct domain_setup_info *dsi);
-static int
-loadbinimage(
- const char *image, unsigned long image_size, int xch, uint32_t dom,
- xen_pfn_t *parray, struct domain_setup_info *dsi);
-
-int probe_bin(const char *image,
- unsigned long image_size,
- struct load_funcs *load_funcs)
-{
- if ( findtable(image, image_size) == NULL )
- return -EINVAL;
-
- load_funcs->parseimage = parsebinimage;
- load_funcs->loadimage = loadbinimage;
-
- return 0;
-}
-
-static const struct xen_bin_image_table *
-findtable(const char *image, unsigned long image_size)
-{
- const struct xen_bin_image_table *table;
- const unsigned long *probe_ptr;
- unsigned probe_index;
- unsigned probe_count;
-
- /* Don't go outside the image */
- if ( image_size < sizeof(struct xen_bin_image_table) )
- return NULL;
-
- probe_count = image_size;
- /* Restrict to first 8k */
- if ( probe_count > 8192 )
- probe_count = 8192;
- probe_count = (probe_count - sizeof(struct xen_bin_image_table)) /
- sizeof(unsigned long);
-
- /* Search for the magic header */
- probe_ptr = (const unsigned long *) image;
- table = NULL;
- for ( probe_index = 0; probe_index < probe_count; probe_index++ )
- {
- if ( XEN_REACTOS_MAGIC3 == *probe_ptr )
- {
- table = (const struct xen_bin_image_table *) probe_ptr;
- /* Checksum correct? */
- if ( 0 == table->magic + table->flags + table->checksum )
- {
- return table;
- }
- }
- probe_ptr++;
- }
-
- return NULL;
-}
-
-static int parsebinimage(const char *image,
- unsigned long image_size,
- struct domain_setup_info *dsi)
-{
- const struct xen_bin_image_table *image_info;
- unsigned long start_addr;
- unsigned long end_addr;
-
- image_info = findtable(image, image_size);
- if ( NULL == image_info )
- {
- ERROR("Image does not have a valid xen_bin_image_table table.");
- return -EINVAL;
- }
-
- /* Check the flags */
- if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) )
- {
- ERROR("xen_bin_image_table flags required 0x%08x found 0x%08lx",
- FLAGS_REQUIRED, image_info->flags & FLAGS_MASK);
- return -EINVAL;
- }
-
- /* Sanity check on the addresses */
- if ( image_info->header_addr < image_info->load_addr ||
- ((const char *) image_info - image) <
- (image_info->header_addr - image_info->load_addr) )
- {
- ERROR("Invalid header_addr.");
- return -EINVAL;
- }
- start_addr = image_info->header_addr - ((const char *) image_info - image);
- if ( 0 != image_info->load_end_addr &&
- ( image_info->load_end_addr < image_info->load_end_addr ||
- start_addr + image_size < image_info->load_end_addr ) )
- {
- ERROR("Invalid load_end_addr");
- return -EINVAL;
- }
- end_addr = (0 == image_info->load_end_addr ? start_addr + image_size :
- image_info->load_end_addr);
- if ( 0 != image_info->bss_end_addr &&
- image_info->bss_end_addr < end_addr )
- {
- ERROR("Invalid bss_end_addr");
- return -EINVAL;
- }
-
- dsi->v_start = image_info->load_addr;
- if ( 0 != image_info->bss_end_addr )
- {
- dsi->v_end = image_info->bss_end_addr;
- }
- else if ( 0 != image_info->load_end_addr )
- {
- dsi->v_end = image_info->load_end_addr;
- }
- else
- {
- dsi->v_end = image_info->load_addr + image_size -
- (((const char *) image_info - image) -
- (image_info->header_addr - image_info->load_addr));
- }
- dsi->v_kernstart = dsi->v_start;
- dsi->v_kernend = dsi->v_end;
- dsi->v_kernentry = image_info->entry_addr;
- dsi->__xen_guest_string = NULL;
-
- return 0;
-}
-
-static int
-loadbinimage(
- const char *image, unsigned long image_size, int xch, uint32_t dom,
- xen_pfn_t *parray, struct domain_setup_info *dsi)
-{
- unsigned long size;
- char *va;
- unsigned long done, chunksz;
- const struct xen_bin_image_table *image_info;
-
- image_info = findtable(image, image_size);
- if ( NULL == image_info )
- {
- ERROR("Image does not have a valid xen_bin_image_table table.");
- return -EINVAL;
- }
-
- /* Determine image size */
- if ( 0 == image_info->load_end_addr )
- {
- size = image_size - (((const char *)image_info - image) -
- (image_info->header_addr -
- image_info->load_addr));
- }
- else
- {
- size = image_info->load_end_addr - image_info->load_addr;
- }
-
- /* It's possible that we need to skip the first part of the image */
- image += ((const char *)image_info - image) -
- (image_info->header_addr - image_info->load_addr);
-
- for ( done = 0; done < size; done += chunksz )
- {
- va = xc_map_foreign_range(
- xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
- chunksz = size - done;
- if ( chunksz > PAGE_SIZE )
- chunksz = PAGE_SIZE;
- memcpy(va, image + done, chunksz);
- munmap(va, PAGE_SIZE);
- }
-
- if ( 0 != image_info->bss_end_addr &&
- image_info->load_addr + size < image_info->bss_end_addr )
- {
- size = image_info->bss_end_addr - image_info->load_addr;
- }
- for ( ; done < size; done += chunksz )
- {
- va = xc_map_foreign_range(
- xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
- chunksz = size - done;
- if ( chunksz > (PAGE_SIZE - (done & (PAGE_SIZE-1))) )
- chunksz = PAGE_SIZE - (done & (PAGE_SIZE-1));
- memset(va + (done & (PAGE_SIZE-1)), 0, chunksz);
- munmap(va, PAGE_SIZE);
- }
-
- return 0;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,684 +0,0 @@
-/******************************************************************************
- * xc_elf_load.c
- */
-
-#include "xg_private.h"
-#include "xc_elf.h"
-#include <stdlib.h>
-#include <inttypes.h>
-
-#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-#define round_pgdown(_p) ((_p)&PAGE_MASK)
-
-static int
-parseelfimage(
- const char *image, unsigned long image_size,
- struct domain_setup_info *dsi);
-static int
-loadelfimage(
- const char *image, unsigned long image_size, int xch, uint32_t dom,
- xen_pfn_t *parray, struct domain_setup_info *dsi);
-static int
-loadelfsymtab(
- const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
- struct domain_setup_info *dsi);
-
-/*
- * Elf header attributes we require for each supported host platform.
- * These are checked in parseelfimage().
- */
-#if defined(__ia64__)
-#define ELFCLASS ELFCLASS64
-#define ELFCLASS_DESC "64-bit"
-
-#define ELFDATA ELFDATA2LSB
-#define ELFDATA_DESC "Little-Endian"
-
-#define ELFMACHINE EM_IA_64
-#define ELFMACHINE_DESC "ia64"
-
-
-#elif defined(__i386__)
-#define ELFCLASS ELFCLASS32
-#define ELFCLASS_DESC "32-bit"
-
-#define ELFDATA ELFDATA2LSB
-#define ELFDATA_DESC "Little-Endian"
-
-#define ELFMACHINE EM_386
-#define ELFMACHINE_DESC "i386"
-
-
-#elif defined(__x86_64__)
-#define ELFCLASS ELFCLASS64
-#define ELFCLASS_DESC "64-bit"
-
-#define ELFDATA ELFDATA2LSB
-#define ELFDATA_DESC "Little-Endian"
-
-#define ELFMACHINE EM_X86_64
-#define ELFMACHINE_DESC "x86_64"
-
-
-#elif defined(__powerpc__)
-#define ELFCLASS ELFCLASS64
-#define ELFCLASS_DESC "64-bit"
-
-#define ELFDATA ELFDATA2MSB
-#define ELFDATA_DESC "Big-Endian"
-
-#define ELFMACHINE EM_PPC64
-#define ELFMACHINE_DESC "ppc64"
-#endif
-
-int probe_elf(const char *image,
- unsigned long image_size,
- struct load_funcs *load_funcs)
-{
- const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
-
- if ( !IS_ELF(*ehdr) )
- return -EINVAL;
-
- load_funcs->parseimage = parseelfimage;
- load_funcs->loadimage = loadelfimage;
-
- return 0;
-}
-
-static inline int is_loadable_phdr(const Elf_Phdr *phdr)
-{
- return ((phdr->p_type == PT_LOAD) &&
- ((phdr->p_flags & (PF_W|PF_X)) != 0));
-}
-
-/*
- * Fallback for kernels containing only the legacy __xen_guest string
- * and no ELF notes.
- */
-static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab)
-{
- return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
-}
-
-static const char *xen_guest_lookup(
- const struct domain_setup_info *dsi, int type)
-{
- const char *xenguest_fallbacks[] = {
- [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
- [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
- [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
- [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
- [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
- [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
- [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
- [XEN_ELFNOTE_LOADER] = "LOADER=",
- [XEN_ELFNOTE_PAE_MODE] = "PAE=",
- [XEN_ELFNOTE_FEATURES] = "FEATURES=",
- [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
- };
- const char *fallback;
- const char *p;
-
- if ( !dsi->__xen_guest_string )
- return NULL;
-
- if ( type > sizeof(xenguest_fallbacks) )
- return NULL;
-
- if ( (fallback = xenguest_fallbacks[type]) == NULL )
- return NULL;
-
- if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
- return NULL;
-
- return p + strlen(fallback);
-}
-
-static const char *xen_guest_string(
- const struct domain_setup_info *dsi, int type)
-{
- const char *p = xen_guest_lookup(dsi, type);
-
- /*
- * We special case this since the __xen_guest_section treats the
- * mere precense of the BSD_SYMTAB string as true or false.
- */
- if ( type == XEN_ELFNOTE_BSD_SYMTAB )
- return p ? "yes" : "no";
-
- return p;
-}
-
-static unsigned long long xen_guest_numeric(
- const struct domain_setup_info *dsi, int type, int *defined)
-{
- const char *p = xen_guest_lookup(dsi, type);
- unsigned long long value;
-
- if ( p == NULL )
- return 0;
-
- errno = 0;
- value = strtoull(p, NULL, 0);
- if ( errno < 0 )
- return 0;
-
- /* We special case this since __xen_guest_section contains a PFN
- * for this field not a virtual address.
- */
- if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
- value = dsi->v_start + (value<<PAGE_SHIFT);
-
- *defined = 1;
- return value;
-}
-
-/*
- * Interface to the Xen ELF notes.
- */
-#define ELFNOTE_NAME(_n_) ((const char*)(_n_) + sizeof(*(_n_)))
-#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
-#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
-
-static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr)
-{
- const Elf_Note *note;
-
- if ( shdr->sh_type != SHT_NOTE )
- return 0;
-
- for ( note = (const Elf_Note *)(image + shdr->sh_offset);
- note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
- note = (const Elf_Note *)ELFNOTE_NEXT(note) )
- {
- if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
- return 1;
- }
-
- return 0;
-}
-
-static const Elf_Note *xen_elfnote_lookup(
- const struct domain_setup_info *dsi, int type)
-{
- const Elf_Note *note;
-
- if ( !dsi->__elfnote_section )
- return NULL;
-
- for ( note = (const Elf_Note *)dsi->__elfnote_section;
- note < (const Elf_Note *)dsi->__elfnote_section_end;
- note = (const Elf_Note *)ELFNOTE_NEXT(note) )
- {
- if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
- continue;
-
- if ( note->type == type )
- return note;
- }
-
- return NULL;
-}
-
-const char *xen_elfnote_string(const struct domain_setup_info *dsi, int type)
-{
- const Elf_Note *note;
-
- if ( !dsi->__elfnote_section )
- return xen_guest_string(dsi, type);
-
- note = xen_elfnote_lookup(dsi, type);
- if ( note == NULL )
- return NULL;
-
- return (const char *)ELFNOTE_DESC(note);
-}
-
-unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi,
- int type, int *defined)
-{
- const Elf_Note *note;
-
- *defined = 0;
-
- if ( !dsi->__elfnote_section )
- return xen_guest_numeric(dsi, type, defined);
-
- note = xen_elfnote_lookup(dsi, type);
- if ( note == NULL )
- {
- return 0;
- }
-
- switch ( note->descsz )
- {
- case 4:
- *defined = 1;
- return *(const uint32_t*)ELFNOTE_DESC(note);
- case 8:
- *defined = 1;
- return *(const uint64_t*)ELFNOTE_DESC(note);
- default:
- xc_set_error(XC_INVALID_KERNEL,
- "elfnotes: unknown data size %#x for numeric type note
%#x\n",
- note->descsz, type);
- return 0;
- }
-}
-
-static int parseelfimage(const char *image,
- unsigned long image_len,
- struct domain_setup_info *dsi)
-{
- const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
- const Elf_Phdr *phdr;
- const Elf_Shdr *shdr;
- Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
- const char *shstrtab, *p;
- int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
-
- if ( !IS_ELF(*ehdr) )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Kernel image does not have an ELF header.");
- return -EINVAL;
- }
-
- if (ehdr->e_machine != ELFMACHINE)
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Kernel ELF architecture '%d' does not match Xen
architecture '%d' (%s)",
- ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
- return -EINVAL;
- }
- if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Kernel ELF wordsize '%d' does not match Xen wordsize
'%d' (%s)",
- ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
- return -EINVAL;
- }
- if (ehdr->e_ident[EI_DATA] != ELFDATA)
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Kernel ELF endianness '%d' does not match Xen endianness
'%d' (%s)",
- ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
- return -EINVAL;
- }
- if (ehdr->e_type != ET_EXEC)
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Kernel ELF type '%d' does not match Xen type '%d'",
- ehdr->e_type, ET_EXEC);
- return -EINVAL;
- }
-
- if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "ELF program headers extend beyond end of image.");
- return -EINVAL;
- }
-
- if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "ELF section headers extend beyond end of image.");
- return -EINVAL;
- }
-
- dsi->__elfnote_section = NULL;
- dsi->__xen_guest_string = NULL;
-
- /* Look for .notes segment containing at least one Xen note */
- for ( h = 0; h < ehdr->e_shnum; h++ )
- {
- shdr = (const Elf_Shdr *)(
- image + ehdr->e_shoff + (h*ehdr->e_shentsize));
- if ( !is_xen_elfnote_section(image, shdr) )
- continue;
- dsi->__elfnote_section = (const char *)image + shdr->sh_offset;
- dsi->__elfnote_section_end =
- (const char *)image + shdr->sh_offset + shdr->sh_size;
- break;
- }
-
- /* Fall back to looking for the special '__xen_guest' section. */
- if ( dsi->__elfnote_section == NULL )
- {
- /* Find the section-header strings table. */
- if ( ehdr->e_shstrndx == SHN_UNDEF )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "ELF image has no section-header strings table.");
- return -EINVAL;
- }
- shdr = (const Elf_Shdr *)(image + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = image + shdr->sh_offset;
-
- for ( h = 0; h < ehdr->e_shnum; h++ )
- {
- shdr = (const Elf_Shdr *)(
- image + ehdr->e_shoff + (h*ehdr->e_shentsize));
- if ( is_xen_guest_section(shdr, shstrtab) )
- {
- dsi->__xen_guest_string =
- (const char *)image + shdr->sh_offset;
- break;
- }
- }
- }
-
- /* Check the contents of the Xen notes or guest string. */
- if ( dsi->__elfnote_section || dsi->__xen_guest_string )
- {
- const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
- const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
- const char *xen_version =
- xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
-
- if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
- ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Will only load images built for the generic loader "
- "or Linux images");
- return -EINVAL;
- }
-
- if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "Will only load images built for Xen v3.0");
- return -EINVAL;
- }
- }
- else
- {
-#if defined(__x86_64__) || defined(__i386__)
- xc_set_error(XC_INVALID_KERNEL,
- "Not a Xen-ELF image: "
- "No ELF notes or '__xen_guest' section found.");
- return -EINVAL;
-#endif
- }
-
- /*
- * A "bimodal" ELF note indicates the kernel will adjust to the current
- * paging mode, including handling extended cr3 syntax. If we have ELF
- * notes then PAE=yes implies that we must support the extended cr3 syntax.
- * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest
- * string. We use strstr() to look for "bimodal" to allow guests to use
- * "yes,bimodal" or "no,bimodal" for compatibility reasons.
- */
-
- dsi->pae_kernel = PAEKERN_no;
- if ( dsi->__elfnote_section )
- {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|