WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 03 Jul 2006 10:20:50 +0000
Delivery-date: Mon, 03 Jul 2006 03:29:06 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 856caf975abd50b78c15f41cc8ab52372059fcf3
# Parent  4b51d081378d6783cce48255ffb7655931f26d63
# Parent  3f8d9b128d711e5e2f6e7af2a236272aad3c5817
Merge with xen-ia64-unstable.hg
---
 buildconfigs/linux-defconfig_xen_x86_32                           |    1 
 buildconfigs/linux-defconfig_xen_x86_64                           |    1 
 docs/man/xm.pod.1                                                 |   93 -
 docs/misc/vtpm.txt                                                |   47 
 linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c                   |    1 
 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c                  |    7 
 linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c                   |   12 
 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c                    |   29 
 linux-2.6-xen-sparse/drivers/char/tpm/Kconfig                     |   13 
 linux-2.6-xen-sparse/drivers/char/tpm/Makefile                    |    1 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm.c                       |  873 
++++++++--
 linux-2.6-xen-sparse/drivers/char/tpm/tpm.h                       |   74 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c                  |  183 +-
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h                  |   42 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c                   |   60 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c                |   42 
 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c                 |   83 
 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c                    |    5 
 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c                    |    4 
 linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c                 |   39 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c                |   67 
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c                 |    2 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c              |   56 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c            |   71 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h |    2 
 linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h              |    2 
 patches/linux-2.6.16.13/fix-hz-suspend.patch                      |    9 
 patches/linux-2.6.16.13/net-gso.patch                             |    8 
 patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch                   |  704 
++++++++
 patches/linux-2.6.16.13/xenoprof-generic.patch                    |    9 
 tools/examples/Makefile                                           |    2 
 tools/examples/vtpm-addtodb                                       |   10 
 tools/examples/vtpm-common.sh                                     |   13 
 tools/firmware/hvmloader/Makefile                                 |    6 
 tools/firmware/hvmloader/acpi_madt.c                              |    2 
 tools/firmware/hvmloader/hvmloader.c                              |    8 
 tools/firmware/hvmloader/mp_tables.c                              |  426 ++++
 tools/firmware/rombios/Makefile                                   |   36 
 tools/firmware/rombios/rombios.c                                  |   30 
 tools/libxc/xc_hvm_build.c                                        |    9 
 tools/libxc/xc_linux_build.c                                      |   17 
 tools/libxc/xc_linux_save.c                                       |   23 
 tools/libxc/xc_load_elf.c                                         |   29 
 tools/libxc/xg_private.h                                          |   14 
 tools/python/xen/xend/XendLogging.py                              |    2 
 tools/python/xen/xm/cfgbootpolicy.py                              |    2 
 tools/python/xen/xm/create.py                                     |    3 
 tools/python/xen/xm/dumppolicy.py                                 |    4 
 tools/python/xen/xm/labels.py                                     |    3 
 tools/python/xen/xm/loadpolicy.py                                 |    4 
 tools/python/xen/xm/main.py                                       |    2 
 tools/python/xen/xm/makepolicy.py                                 |    4 
 tools/python/xen/xm/shutdown.py                                   |    5 
 tools/xenstat/libxenstat/src/xenstat.c                            |  174 +
 tools/xenstat/libxenstat/src/xenstat.h                            |   22 
 tools/xenstat/xentop/xentop.c                                     |  154 +
 tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py                      |   11 
 tools/xm-test/tests/vtpm/03_vtpm-susp_res.py                      |   94 -
 tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py                      |   24 
 tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py                      |   24 
 tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py                 |  139 +
 tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py                      |  132 +
 tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py                      |  132 +
 tools/xm-test/tests/vtpm/Makefile.am                              |    5 
 tools/xm-test/tests/vtpm/vtpm_utils.py                            |    2 
 xen/arch/x86/domain.c                                             |    7 
 xen/arch/x86/hvm/svm/svm.c                                        |    2 
 xen/arch/x86/hvm/vmx/vmcs.c                                       |    7 
 xen/arch/x86/smpboot.c                                            |    3 
 xen/arch/x86/x86_emulate.c                                        |    2 
 xen/common/elf.c                                                  |   23 
 xen/common/grant_table.c                                          |   12 
 xen/common/memory.c                                               |    9 
 xen/common/page_alloc.c                                           |    4 
 xen/common/sched_credit.c                                         |    7 
 xen/common/schedule.c                                             |   21 
 xen/common/softirq.c                                              |   16 
 xen/common/timer.c                                                |    9 
 xen/drivers/char/console.c                                        |   12 
 xen/include/asm-ia64/grant_table.h                                |    5 
 xen/include/asm-x86/grant_table.h                                 |    5 
 xen/include/public/arch-ia64.h                                    |    2 
 xen/include/public/arch-x86_32.h                                  |    2 
 xen/include/public/arch-x86_64.h                                  |    2 
 xen/include/public/io/netif.h                                     |   53 
 xen/include/public/memory.h                                       |   12 
 xen/include/xen/lib.h                                             |   18 
 xen/include/xen/timer.h                                           |    6 
 88 files changed, 3632 insertions(+), 714 deletions(-)

diff -r 4b51d081378d -r 856caf975abd buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Wed Jun 28 07:52:21 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Mon Jul 03 08:35:12 2006 +0100
@@ -1902,6 +1902,7 @@ CONFIG_HANGCHECK_TIMER=m
 # TPM devices
 #
 CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
 CONFIG_TCG_NSC=m
 CONFIG_TCG_ATMEL=m
 CONFIG_TCG_INFINEON=m
diff -r 4b51d081378d -r 856caf975abd buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Wed Jun 28 07:52:21 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Mon Jul 03 08:35:12 2006 +0100
@@ -1765,6 +1765,7 @@ CONFIG_HANGCHECK_TIMER=m
 # TPM devices
 #
 CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
 CONFIG_TCG_NSC=m
 CONFIG_TCG_ATMEL=m
 CONFIG_TCG_INFINEON=m
diff -r 4b51d081378d -r 856caf975abd docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Wed Jun 28 07:52:21 2006 -0600
+++ b/docs/man/xm.pod.1 Mon Jul 03 08:35:12 2006 +0100
@@ -875,13 +875,42 @@ the currently enforced access control po
 the currently enforced access control policy. The default for I<type>
 is 'dom'. The labels are arranged in alphabetical order.
 
-=item B<addlabel> I<configfile> I<label> [I<policy>]
+=item B<addlabel> I<label> dom I<configfile> [I<policy>]
+
+=item B<addlabel> I<label> res I<resource> [I<policy>]
 
 Adds the security label with name I<label> to a domain
-I<configfile>. Unless specified, the default I<policy> is the
+I<configfile> (dom) or to the global resource label file for the
+given I<resource> (res). Unless specified, the default I<policy> is the
 currently enforced access control policy. This subcommand also
 verifies that the I<policy> definition supports the specified I<label>
 name.
+
+=item B<rmlabel> dom I<configfile>
+
+=item B<rmlabel> res I<resource>
+
+Works the same as the I<addlabel> command (above), except that this
+command will remove the label from the domain I<configfile> (dom) or
+the global resource label file (res).
+
+=item B<getlabel> dom I<configfile>
+
+=item B<getlabel> res I<resource>
+
+Shows the label for the given I<configfile> or I<resource>
+
+=item B<resources>
+
+Lists all resources in the global resource label file.  Each resource
+is listed with its associated label and policy name.
+
+=item B<dry-run> I<configfile>
+
+Determines if the specified I<configfile> describes a domain with a valid
+security configuration for type enforcement. The test shows the policy
+decision made for each resource label against the domain label as well as
+the overall decision.
 
 B<CONFIGURING SECURITY>
 
@@ -960,17 +989,18 @@ B<ATTACHING A SECURITY LABEL TO A DOMAIN
 
 =over 4
 
-This subcommand attaches a security label to a domain configuration
-file, here a HomeBanking label. The example policy ensures that this
-domain does not share information with other non-hombanking user
-domains (i.e., domains labeled as dom_Fun or dom_Boinc) and that it
-will not run simultaneously with domains labeled as dom_Fun.
+The I<addlabel> subcommand can attach a security label to a domain
+configuration file, here a HomeBanking label. The example policy
+ensures that this domain does not share information with other
+non-hombanking user domains (i.e., domains labeled as dom_Fun or
+dom_Boinc) and that it will not run simultaneously with domains
+labeled as dom_Fun.
 
 We assume that the specified myconfig.xm configuration file actually
 instantiates a domain that runs workloads related to home-banking,
 probably just a browser environment for online-banking.
 
-    xm addlabel myconfig.xm dom_HomeBanking
+    xm addlabel dom_HomeBanking dom myconfig.xm
 
 The very simple configuration file might now look as printed
 below. The I<addlabel> subcommand added the B<access_control> entry at
@@ -997,6 +1027,38 @@ permitted".
 
 =back
 
+B<ATTACHING A SECURITY LABEL TO A RESOURCE>
+
+=over 4
+
+The I<addlabel> subcommand can also be used to attach a security
+label to a resource. Following the home banking example from above,
+we can label a disk resource (e.g., a physical partition or a file)
+to make it accessible to the home banking domain. The example policy
+provides a resource label, res_LogicalDiskPartition1(hda1), that is
+compatible with the HomeBanking domain label.
+
+    xm addlabel "res_LogicalDiskPartition1(hda1)" res phy:hda6
+
+After labeling this disk resource, it can be attached to the domain
+by adding a line to the domain configuration file. The line below
+attaches this disk to the domain at boot time.
+
+    disk = [ 'phy:hda6,sda2,w' ]
+
+Alternatively, the resource can be attached after booting the domain
+by using the I<block-attach> subcommand.
+
+    xm block-attach homebanking phy:hda6 sda2 w
+
+Note that labeled resources cannot be used when security is turned
+off.  Any attempt to use labeled resources with security turned off
+will result in a failure with a corresponding error message.  The
+solution is to enable security or, if security is no longer desired,
+to remove the resource label using the I<rmlabel> subcommand.
+
+=back
+
 B<STARTING AND LISTING LABELED DOMAINS>
 
 =over 4
@@ -1008,6 +1070,21 @@ B<STARTING AND LISTING LABELED DOMAINS>
       Name         ID ...  Time(s)  Label
       homebanking  23 ...      4.4  dom_HomeBanking
       Domain-0      0 ...   2658.8  dom_SystemManagement
+
+=back
+
+B<LISTING LABELED RESOURCES>
+
+=over 4
+
+    xm resources
+
+      phy:hda6
+          policy: example.chwall_ste.client_v1
+          label:  res_LogicalDiskPartition1(hda1)
+      file:/xen/disk_image/disk.img
+          policy: example.chwall_ste.client_v1
+          label:  res_LogicalDiskPartition2(hda2)
 
 =back
 
diff -r 4b51d081378d -r 856caf975abd docs/misc/vtpm.txt
--- a/docs/misc/vtpm.txt        Wed Jun 28 07:52:21 2006 -0600
+++ b/docs/misc/vtpm.txt        Mon Jul 03 08:35:12 2006 +0100
@@ -1,5 +1,5 @@ Copyright: IBM Corporation (C), Intel Co
 Copyright: IBM Corporation (C), Intel Corporation
-17 August 2005
+29 June 2006
 Authors: Stefan Berger <stefanb@xxxxxxxxxx> (IBM), 
          Employees of Intel Corp
 
@@ -9,23 +9,33 @@ that the user is fairly familiar with co
 that the user is fairly familiar with compiling and installing XEN
 and Linux on a machine. 
  
-Production Prerequisites: An x86-based machine machine with an ATMEL or
-National Semiconductor (NSC) TPM on the motherboard.
+Production Prerequisites: An x86-based machine machine with a
+Linux-supported TPM on the motherboard (NSC, Atmel, Infineon, TPM V1.2).
 Development Prerequisites: An emulator for TESTING ONLY is provided
 
 
-Compiling XEN tree:
--------------------
+Compiling the XEN tree:
+-----------------------
 
 Compile the XEN tree as usual after the following lines set in the
 linux-2.6.??-xen/.config file:
 
-CONFIG_XEN_TPMDEV_BACKEND=y
+CONFIG_XEN_TPMDEV_BACKEND=m
+
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m      (supported after 2.6.17-rc4)
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+CONFIG_TCG_XEN=m
+<possible other TPM drivers supported by Linux>
+
+If the frontend driver needs to be compiled into the user domain
+kernel, then the following two lines should be changed.
 
 CONFIG_TCG_TPM=y
-CONFIG_TCG_NSC=m
-CONFIG_TCG_ATMEL=m
 CONFIG_TCG_XEN=y
+
 
 You must also enable the virtual TPM to be built:
 
@@ -63,7 +73,7 @@ available. It works similar to making a 
 available. It works similar to making a network interface
 available to a domain.
 
-kernel = "/boot/vmlinuz-2.6.12-xenU"
+kernel = "/boot/vmlinuz-2.6.x"
 ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
 memory = 32
 name = "TPMUserDomain0"
@@ -92,7 +102,7 @@ Running the TPM:
 Running the TPM:
 ----------------
 
-To run the vTPM, dev device /dev/vtpm must be available.
+To run the vTPM, the device /dev/vtpm must be available.
 Verify that 'ls -l /dev/vtpm' shows the following output:
 
 crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
@@ -101,16 +111,26 @@ mknod /dev/vtpm c 10 225
 mknod /dev/vtpm c 10 225
 
 Make sure that the vTPM is running in domain 0. To do this run the
-following
+following:
+
+modprobe tpmbk
 
 /usr/bin/vtpm_managerd
 
 Start a user domain using the 'xm create' command. Once you are in the
-shell of the user domain, you should be able to do the following:
+shell of the user domain, you should be able to do the following as
+user 'root':
 
-> cd /sys/devices/vtpm
+Insert the TPM frontend into the kernel if it has been compiled as a
+kernel module.
+
+> modprobe tpm_xenu
+
+Check the status of the TPM
+
+> cd /sys/devices/xen/vtpm-0
 > ls
-cancel  caps   pcrs    pubek
+[...]  cancel  caps   pcrs    pubek   [...]
 > cat pcrs
 PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c   Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c   Mon Jul 03 08:35:12 
2006 +0100
@@ -442,6 +442,7 @@ void flush_tlb_mm(struct mm_struct * mm)
 { xen_tlb_flush_mask(&mm->cpu_vm_mask); }
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
 { xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
+EXPORT_SYMBOL(flush_tlb_page);
 void flush_tlb_all(void)
 { xen_tlb_flush_all(); }
 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Mon Jul 03 08:35:12 
2006 +0100
@@ -989,12 +989,11 @@ static void stop_hz_timer(void)
 
        smp_mb();
 
-       /* Leave ourselves in 'tick mode' if rcu or softirq pending. */
-       if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
+       /* Leave ourselves in 'tick mode' if rcu or softirq or timer pending. */
+       if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
+           (j = next_timer_interrupt(), time_before_eq(j, jiffies))) {
                cpu_clear(cpu, nohz_cpu_mask);
                j = jiffies + 1;
-       } else {
-               j = next_timer_interrupt();
        }
 
        BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c   Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c   Mon Jul 03 08:35:12 
2006 +0100
@@ -60,7 +60,7 @@ void *kmap_atomic_pte(struct page *page,
 
 void kunmap_atomic(void *kvaddr, enum km_type type)
 {
-#ifdef CONFIG_DEBUG_HIGHMEM
+#if defined(CONFIG_DEBUG_HIGHMEM) || defined(CONFIG_XEN)
        unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
        enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
 
@@ -69,7 +69,9 @@ void kunmap_atomic(void *kvaddr, enum km
                preempt_check_resched();
                return;
        }
+#endif
 
+#if defined(CONFIG_DEBUG_HIGHMEM)
        if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
                BUG();
 
@@ -79,6 +81,14 @@ void kunmap_atomic(void *kvaddr, enum km
         */
        pte_clear(&init_mm, vaddr, kmap_pte-idx);
        __flush_tlb_one(vaddr);
+#elif defined(CONFIG_XEN)
+       /*
+        * We must ensure there are no dangling pagetable references when
+        * returning memory to Xen (decrease_reservation).
+        * XXX TODO: We could make this faster by only zapping when
+        * kmap_flush_unused is called but that is trickier and more invasive.
+        */
+       pte_clear(&init_mm, vaddr, kmap_pte-idx);
 #endif
 
        dec_preempt_count();
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Mon Jul 03 08:35:12 
2006 +0100
@@ -271,10 +271,6 @@ int xen_create_contiguous_region(
 int xen_create_contiguous_region(
        unsigned long vstart, unsigned int order, unsigned int address_bits)
 {
-       pgd_t         *pgd; 
-       pud_t         *pud; 
-       pmd_t         *pmd;
-       pte_t         *pte;
        unsigned long *in_frames = discontig_frames, out_frame;
        unsigned long  frame, i, flags;
        long           rc;
@@ -301,7 +297,7 @@ int xen_create_contiguous_region(
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return 0;
 
-       if (order > MAX_CONTIG_ORDER)
+       if (unlikely(order > MAX_CONTIG_ORDER))
                return -ENOMEM;
 
        set_xen_guest_handle(exchange.in.extent_start, in_frames);
@@ -313,11 +309,7 @@ int xen_create_contiguous_region(
 
        /* 1. Zap current PTEs, remembering MFNs. */
        for (i = 0; i < (1UL<<order); i++) {
-               pgd = pgd_offset_k(vstart + (i*PAGE_SIZE));
-               pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
-               pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
-               pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
-               in_frames[i] = pte_mfn(*pte);
+               in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
                if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
                                                 __pte_ma(0), 0))
                        BUG();
@@ -372,10 +364,6 @@ int xen_create_contiguous_region(
 
 void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
 {
-       pgd_t         *pgd; 
-       pud_t         *pud; 
-       pmd_t         *pmd;
-       pte_t         *pte;
        unsigned long *out_frames = discontig_frames, in_frame;
        unsigned long  frame, i, flags;
        long           rc;
@@ -397,7 +385,7 @@ void xen_destroy_contiguous_region(unsig
            !test_bit(__pa(vstart) >> PAGE_SHIFT, contiguous_bitmap))
                return;
 
-       if (order > MAX_CONTIG_ORDER)
+       if (unlikely(order > MAX_CONTIG_ORDER))
                return;
 
        set_xen_guest_handle(exchange.in.extent_start, &in_frame);
@@ -410,16 +398,13 @@ void xen_destroy_contiguous_region(unsig
        contiguous_bitmap_clear(__pa(vstart) >> PAGE_SHIFT, 1UL << order);
 
        /* 1. Find start MFN of contiguous extent. */
-       pgd = pgd_offset_k(vstart);
-       pud = pud_offset(pgd, vstart);
-       pmd = pmd_offset(pud, vstart);
-       pte = pte_offset_kernel(pmd, vstart);
-       in_frame = pte_mfn(*pte);
+       in_frame = pfn_to_mfn(__pa(vstart) >> PAGE_SHIFT);
 
        /* 2. Zap current PTEs. */
        for (i = 0; i < (1UL<<order); i++) {
                if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
-                                                __pte_ma(0), 0));
+                                                __pte_ma(0), 0))
+                       BUG();
                set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
                        INVALID_P2M_ENTRY);
                out_frames[i] = (__pa(vstart) >> PAGE_SHIFT) + i;
@@ -430,7 +415,7 @@ void xen_destroy_contiguous_region(unsig
        success = (exchange.nr_exchanged == 1);
        BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
        BUG_ON(success && (rc != 0));
-       if (rc == -ENOSYS) {
+       if (unlikely(rc == -ENOSYS)) {
                /* Compatibility when XENMEM_exchange is unsupported. */
                if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
                                         &exchange.in) != 1)
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Mon Jul 03 08:35:12 
2006 +0100
@@ -20,9 +20,18 @@ config TCG_TPM
          Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
          and CONFIG_PNPACPI.
 
+config TCG_TIS
+       tristate "TPM Interface Specification 1.2 Interface"
+       depends on TCG_TPM
+       ---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
+         from within Linux.  To compile this driver as a module, choose
+         M here; the module will be called tpm_tis.
+
 config TCG_NSC
        tristate "National Semiconductor TPM Interface"
-       depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
+       depends on TCG_TPM && PNPACPI
        ---help---
          If you have a TPM security chip from National Semicondutor 
          say Yes and it will be accessible from within Linux.  To 
@@ -31,7 +40,7 @@ config TCG_NSC
 
 config TCG_ATMEL
        tristate "Atmel TPM Interface"
-       depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
+       depends on TCG_TPM
        ---help---
          If you have a TPM security chip from Atmel say Yes and it 
          will be accessible from within Linux.  To compile this driver 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/Makefile
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Mon Jul 03 08:35:12 
2006 +0100
@@ -5,6 +5,7 @@ ifdef CONFIG_ACPI
 ifdef CONFIG_ACPI
        obj-$(CONFIG_TCG_TPM) += tpm_bios.o
 endif
+obj-$(CONFIG_TCG_TIS) += tpm_tis.o
 obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
 obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
 obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff -r 4b51d081378d -r 856caf975abd linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Mon Jul 03 08:35:12 
2006 +0100
@@ -30,15 +30,295 @@
 
 enum tpm_const {
        TPM_MINOR = 224,        /* officially assigned */
-       TPM_MIN_BUFSIZE = 2048,
-       TPM_MAX_BUFSIZE = 64 * 1024,
+#ifndef CONFIG_XEN
+       TPM_BUFSIZE = 2048,
+#endif
        TPM_NUM_DEVICES = 256,
-       TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
 };
+
+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 int dev_mask[TPM_NUM_MASK_ENTRIES];
+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)
 {
@@ -47,28 +327,58 @@ static void user_reader_timeout(unsigned
        schedule_work(&chip->work);
 }
 
-static void timeout_work(void * ptr)
+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,
+static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                            size_t bufsiz)
 {
        ssize_t rc;
-       u32 count;
+       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) {
@@ -79,21 +389,23 @@ static ssize_t tpm_transmit(struct tpm_c
 
        down(&chip->tpm_mutex);
 
-       if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+       if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
                dev_err(chip->dev,
                        "tpm_transmit: tpm_send: error %zd\n", rc);
                goto out;
        }
 
-       stop = jiffies + 2 * 60 * HZ;
+       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) {
+               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)) {
+
+               if ((status == chip->vendor.req_canceled)) {
                        dev_err(chip->dev, "Operation Canceled\n");
                        rc = -ECANCELED;
                        goto out;
@@ -103,14 +415,13 @@ static ssize_t tpm_transmit(struct tpm_c
                rmb();
        } while (time_before(jiffies, stop));
 
-
-       chip->vendor->cancel(chip);
+       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);
+       rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
        if (rc < 0)
                dev_err(chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
@@ -120,17 +431,247 @@ out:
 }
 
 #define TPM_DIGEST_SIZE 20
-#define CAP_PCR_RESULT_SIZE 18
-static const u8 cap_pcr[] = {
+#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, 5,
-       0, 0, 0, 4,
-       0, 0, 1, 1
+       0, 0, 0, 0,             /* TPM_CAP_<TYPE> */
+       0, 0, 0, 4,             /* TPM_CAP_SUB_<TYPE> size */
+       0, 0, 1, 0              /* TPM_CAP_SUB_<TYPE> */
 };
 
-#define READ_PCR_RESULT_SIZE 30
+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 */
@@ -141,8 +682,8 @@ ssize_t tpm_show_pcrs(struct device *dev
 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[READ_PCR_RESULT_SIZE];
-       ssize_t len;
+       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;
@@ -151,29 +692,24 @@ ssize_t tpm_show_pcrs(struct device *dev
        if (chip == NULL)
                return -ENODEV;
 
-       memcpy(data, cap_pcr, sizeof(cap_pcr));
-       if ((len = tpm_transmit(chip, data, sizeof(data)))
-           < CAP_PCR_RESULT_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                               "attempting to determine the number of PCRS\n",
-                       be32_to_cpu(*((__be32 *) (data + 6))));
+       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);
-               if ((len = tpm_transmit(chip, data, sizeof(data)))
-                   < READ_PCR_RESULT_SIZE){
-                       dev_dbg(chip->dev, "A TPM error (%d) occurred"
-                               " attempting to read PCR %d of %d\n",
-                               be32_to_cpu(*((__be32 *) (data + 6))),
-                               i, num_pcrs);
+               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));
@@ -195,7 +731,7 @@ ssize_t tpm_show_pubek(struct device *de
                       char *buf)
 {
        u8 *data;
-       ssize_t len;
+       ssize_t err;
        int i, rc;
        char *str = buf;
 
@@ -209,14 +745,10 @@ ssize_t tpm_show_pubek(struct device *de
 
        memcpy(data, readpubek, sizeof(readpubek));
 
-       if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
-           READ_PUBEK_RESULT_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                               "attempting to read the PUBEK\n",
-                           be32_to_cpu(*((__be32 *) (data + 6))));
-               rc = 0;
+       err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
+                       "attempting to read the PUBEK");
+       if (err)
                goto out;
-       }
 
        /* 
           ignore header 10 bytes
@@ -246,66 +778,109 @@ ssize_t tpm_show_pubek(struct device *de
                if ((i + 1) % 16 == 0)
                        str += sprintf(str, "\n");
        }
+out:
        rc = str - buf;
-out:
        kfree(data);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
-#define CAP_VER_RESULT_SIZE 18
+#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, 6,
+       0, 0, 0, 0,
        0, 0, 0, 0
 };
 
-#define CAP_MANUFACTURER_RESULT_SIZE 18
-static const u8 cap_manufacturer[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 22,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 5,
-       0, 0, 0, 4,
-       0, 0, 1, 3
-};
-
 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[sizeof(cap_manufacturer)];
-       ssize_t len;
+       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, cap_manufacturer, sizeof(cap_manufacturer));
-
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <
-           CAP_MANUFACTURER_RESULT_SIZE)
-               return len;
+       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 + 14))));
+                      be32_to_cpu(*((__be32 *) (data + 
TPM_GET_CAP_RET_UINT32_1_IDX))));
 
        memcpy(data, cap_version, sizeof(cap_version));
-
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <
-           CAP_VER_RESULT_SIZE)
-               return len;
-
-       str +=
-           sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
-                   (int) data[14], (int) data[15], (int) data[16],
-                   (int) data[17]);
-
+       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)
@@ -314,7 +889,7 @@ ssize_t tpm_store_cancel(struct device *
        if (chip == NULL)
                return 0;
 
-       chip->vendor->cancel(chip);
+       chip->vendor.cancel(chip);
        return count;
 }
 EXPORT_SYMBOL_GPL(tpm_store_cancel);
@@ -330,7 +905,7 @@ int tpm_open(struct inode *inode, struct
        spin_lock(&driver_lock);
 
        list_for_each_entry(pos, &tpm_chip_list, list) {
-               if (pos->vendor->miscdev.minor == minor) {
+               if (pos->vendor.miscdev.minor == minor) {
                        chip = pos;
                        break;
                }
@@ -352,7 +927,12 @@ int tpm_open(struct inode *inode, struct
 
        spin_unlock(&driver_lock);
 
-       chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8), 
GFP_KERNEL);
+#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);
@@ -388,7 +968,7 @@ EXPORT_SYMBOL_GPL(tpm_release);
 EXPORT_SYMBOL_GPL(tpm_release);
 
 ssize_t tpm_write(struct file *file, const char __user *buf,
-                 size_t size, loff_t * off)
+                 size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
        int in_size = size, out_size;
@@ -400,8 +980,13 @@ ssize_t tpm_write(struct file *file, con
 
        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)) {
@@ -410,11 +995,17 @@ ssize_t tpm_write(struct file *file, con
        }
 
        /* atomic tpm command send and result receive */
-       out_size = tpm_transmit(chip, chip->data_buffer, 
+#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 */
@@ -422,42 +1013,59 @@ ssize_t tpm_write(struct file *file, con
 
        return in_size;
 }
-
 EXPORT_SYMBOL_GPL(tpm_write);
 
-ssize_t tpm_read(struct file * file, char __user *buf,
-                size_t size, loff_t * off)
+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 
);
+                               atomic_set(&chip->data_pending, pending);
+                               atomic_set(&chip->data_position,
+                                          pos+ret_size);
                        }
                }
+#endif
                up(&chip->buffer_mutex);
        }
-       
-       if ( ret_size <= 0 || pending == 0 ) {
-               atomic_set( &chip->data_pending, 0 );
+
+#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);
@@ -478,14 +1086,13 @@ void tpm_remove_hardware(struct device *
        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);
+       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);
 
-       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
-               ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+       clear_bit(chip->dev_num, dev_mask);
 
        kfree(chip);
 
@@ -536,18 +1143,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
  * upon errant exit from this function specific probe function should call
  * pci_disable_device
  */
-int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific 
*entry)
+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;
-       int i, j;
 
        /* Driver specific per-device data */
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (chip == NULL)
-               return -ENOMEM;
+               return NULL;
 
        init_MUTEX(&chip->buffer_mutex);
        init_MUTEX(&chip->tpm_mutex);
@@ -559,51 +1166,37 @@ int tpm_register_hardware(struct device 
        chip->user_read_timer.function = user_reader_timeout;
        chip->user_read_timer.data = (unsigned long) chip;
 
-       chip->vendor = entry;
-       
-       if (entry->buffersize < TPM_MIN_BUFSIZE) {
-               entry->buffersize = TPM_MIN_BUFSIZE;
-       } else if (entry->buffersize > TPM_MAX_BUFSIZE) {
-               entry->buffersize = TPM_MAX_BUFSIZE;
-       }
-
-       chip->dev_num = -1;
-
-       for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
-               for (j = 0; j < 8 * sizeof(int); j++)
-                       if ((dev_mask[i] & (1 << j)) == 0) {
-                               chip->dev_num =
-                                   i * TPM_NUM_MASK_ENTRIES + j;
-                               dev_mask[i] |= 1 << j;
-                               goto dev_num_search_complete;
-                       }
-
-dev_num_search_complete:
-       if (chip->dev_num < 0) {
+       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 -ENODEV;
+               return NULL;
        } else if (chip->dev_num == 0)
-               chip->vendor->miscdev.minor = TPM_MINOR;
+               chip->vendor.miscdev.minor = TPM_MINOR;
        else
-               chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+               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->vendor.miscdev.name = devname;
+
+       chip->vendor.miscdev.dev = dev;
        chip->dev = get_device(dev);
 
-       if (misc_register(&chip->vendor->miscdev)) {
+       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);
+                       chip->vendor.miscdev.name,
+                       chip->vendor.miscdev.minor);
                put_device(dev);
+               clear_bit(chip->dev_num, dev_mask);
                kfree(chip);
-               dev_mask[i] &= !(1 << j);
-               return -ENODEV;
+               return NULL;
        }
 
        spin_lock(&driver_lock);
@@ -614,11 +1207,11 @@ dev_num_search_complete:
 
        spin_unlock(&driver_lock);
 
-       sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
+       sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
 
        chip->bios_dir = tpm_bios_log_setup(devname);
 
-       return 0;
+       return chip;
 }
 EXPORT_SYMBOL_GPL(tpm_register_hardware);
 
diff -r 4b51d081378d -r 856caf975abd linux-2.6-xen-sparse/drivers/char/tpm/tpm.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Mon Jul 03 08:35:12 
2006 +0100
@@ -24,6 +24,14 @@
 #include <linux/fs.h>
 #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 */
@@ -41,18 +49,32 @@ extern ssize_t tpm_show_pcrs(struct devi
                                char *);
 extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
                                char *);
+extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute 
*attr,
+                               char *);
 extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
                                const char *, size_t);
+extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_temp_deactivated(struct device *,
+                                        struct device_attribute *attr, char *);
 
 struct tpm_chip;
 
 struct tpm_vendor_specific {
-       u8 req_complete_mask;
-       u8 req_complete_val;
-       u8 req_canceled;
+       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 */
+
+       int irq;
 
        int region_size;
        int have_region;
@@ -63,6 +85,13 @@ struct tpm_vendor_specific {
        u8 (*status) (struct tpm_chip *);
        struct miscdevice miscdev;
        struct attribute_group *attr_group;
+       struct list_head list;
+       int locality;
+       unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
+       unsigned long duration[3]; /* jiffies */
+
+       wait_queue_head_t read_queue;
+       wait_queue_head_t int_queue;
 };
 
 struct tpm_chip {
@@ -75,19 +104,26 @@ 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 */
        struct work_struct work;
        struct semaphore tpm_mutex;     /* tpm is processing */
 
-       struct tpm_vendor_specific *vendor;
+       struct tpm_vendor_specific vendor;
 
        struct dentry **bios_dir;
 
        struct list_head list;
+#ifdef CONFIG_XEN
+       void *priv;
+#endif
 };
+
+#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
 
 static inline int tpm_read_index(int base, int index)
 {
@@ -101,13 +137,35 @@ static inline void tpm_write_index(int b
        outb(value & 0xFF, base+1);
 }
 
+#ifdef CONFIG_XEN
 static inline u32 get_chip_buffersize(struct tpm_chip *chip)
 {
-       return chip->vendor->buffersize;
+       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;
 }
 
-extern int tpm_register_hardware(struct device *,
-                                struct tpm_vendor_specific *);
+static inline void *chip_get_private(const struct tpm_chip *chip)
+{
+       return chip->priv;
+}
+
+static inline void chip_set_private(struct tpm_chip *chip, void *priv)
+{
+       chip->priv = priv;
+}
+#endif
+
+extern void tpm_get_timeouts(struct tpm_chip *);
+extern void tpm_gen_interrupt(struct tpm_chip *);
+extern void tpm_continue_selftest(struct tpm_chip *);
+extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
+extern struct tpm_chip* tpm_register_hardware(struct device *,
+                                const struct tpm_vendor_specific *);
 extern int tpm_open(struct inode *, struct file *);
 extern int tpm_release(struct inode *, struct file *);
 extern ssize_t tpm_write(struct file *, const char __user *, size_t,
@@ -121,7 +179,7 @@ extern struct dentry ** tpm_bios_log_set
 extern struct dentry ** tpm_bios_log_setup(char *);
 extern void tpm_bios_log_teardown(struct dentry **);
 #else
-static inline struct dentry* tpm_bios_log_setup(char *name)
+static inline struct dentry ** tpm_bios_log_setup(char *name)
 {
        return NULL;
 }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c  Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c  Mon Jul 03 08:35:12 
2006 +0100
@@ -29,8 +29,6 @@ enum {
        STATUS_READY = 0x04
 };
 
-#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
-
 struct transmission {
        struct list_head next;
 
@@ -49,26 +47,6 @@ enum {
        TRANSMISSION_FLAG_WAS_QUEUED = 0x1
 };
 
-struct vtpm_state {
-       struct transmission *current_request;
-       spinlock_t           req_list_lock;
-       wait_queue_head_t    req_wait_queue;
-
-       struct list_head     queued_requests;
-
-       struct transmission *current_response;
-       spinlock_t           resp_list_lock;
-       wait_queue_head_t    resp_wait_queue;     // processes waiting for 
responses
-
-       struct transmission *req_cancelled;       // if a cancellation was 
encounterd
-
-       u8                   vd_status;
-       u8                   flags;
-
-       unsigned long        disconnect_time;
-
-       struct tpm_virtual_device *tpmvd;
-};
 
 enum {
        DATAEX_FLAG_QUEUED_ONLY = 0x1
@@ -76,7 +54,6 @@ enum {
 
 
 /* local variables */
-static struct vtpm_state *vtpms;
 
 /* local function prototypes */
 static int _vtpm_send_queued(struct tpm_chip *chip);
@@ -160,11 +137,16 @@ static inline void transmission_free(str
 /*
  * Lower layer uses this function to make a response available.
  */
-int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
+int vtpm_vd_recv(const struct tpm_chip *chip,
+                 const unsigned char *buffer, size_t count,
+                 void *ptr)
 {
        unsigned long flags;
        int ret_size = 0;
        struct transmission *t;
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        /*
         * The list with requests must contain one request
@@ -173,26 +155,11 @@ int vtpm_vd_recv(const unsigned char *bu
         */
        spin_lock_irqsave(&vtpms->resp_list_lock, flags);
        if (vtpms->current_request != ptr) {
-               printk("WARNING: The request pointer is different than the "
-                      "pointer the shared memory driver returned to me. "
-                      "%p != %p\n",
-                      vtpms->current_request, ptr);
-       }
-
-       /*
-        * If the request has been cancelled, just quit here
-        */
-       if (vtpms->req_cancelled == (struct transmission *)ptr) {
-               if (vtpms->current_request == vtpms->req_cancelled) {
-                       vtpms->current_request = NULL;
-               }
-               transmission_free(vtpms->req_cancelled);
-               vtpms->req_cancelled = NULL;
                spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
                return 0;
        }
 
-       if (NULL != (t = vtpms->current_request)) {
+       if ((t = vtpms->current_request)) {
                transmission_free(t);
                vtpms->current_request = NULL;
        }
@@ -217,8 +184,12 @@ int vtpm_vd_recv(const unsigned char *bu
 /*
  * Lower layer indicates its status (connected/disconnected)
  */
-void vtpm_vd_status(u8 vd_status)
-{
+void vtpm_vd_status(const struct tpm_chip *chip, u8 vd_status)
+{
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
+
        vtpms->vd_status = vd_status;
        if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
                vtpms->disconnect_time = jiffies;
@@ -233,6 +204,9 @@ static int vtpm_recv(struct tpm_chip *ch
 {
        int rc = 0;
        unsigned long flags;
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        /*
         * Check if the previous operation only queued the command
@@ -251,7 +225,7 @@ static int vtpm_recv(struct tpm_chip *ch
                 * Return a response of up to 30 '0's.
                 */
 
-               count = MIN(count, 30);
+               count = min_t(size_t, count, 30);
                memset(buf, 0x0, count);
                return count;
        }
@@ -270,7 +244,7 @@ static int vtpm_recv(struct tpm_chip *ch
        if (vtpms->current_response) {
                struct transmission *t = vtpms->current_response;
                vtpms->current_response = NULL;
-               rc = MIN(count, t->response_len);
+               rc = min(count, t->response_len);
                memcpy(buf, t->response, rc);
                transmission_free(t);
        }
@@ -284,6 +258,9 @@ static int vtpm_send(struct tpm_chip *ch
        int rc = 0;
        unsigned long flags;
        struct transmission *t = transmission_alloc();
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        if (!t)
                return -ENOMEM;
@@ -327,8 +304,7 @@ static int vtpm_send(struct tpm_chip *ch
 
                        vtpms->current_request = t;
 
-                       rc = vtpm_vd_send(chip,
-                                         vtpms->tpmvd->tpm_private,
+                       rc = vtpm_vd_send(vtpms->tpm_private,
                                          buf,
                                          count,
                                          t);
@@ -373,6 +349,8 @@ static int _vtpm_send_queued(struct tpm_
        int error = 0;
        long flags;
        unsigned char buffer[1];
+       struct vtpm_state *vtpms;
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        spin_lock_irqsave(&vtpms->req_list_lock, flags);
 
@@ -387,8 +365,7 @@ static int _vtpm_send_queued(struct tpm_
                vtpms->current_request = qt;
                spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
 
-               rc = vtpm_vd_send(chip,
-                                 vtpms->tpmvd->tpm_private,
+               rc = vtpm_vd_send(vtpms->tpm_private,
                                  qt->request,
                                  qt->request_len,
                                  qt);
@@ -427,9 +404,21 @@ static void vtpm_cancel(struct tpm_chip 
 static void vtpm_cancel(struct tpm_chip *chip)
 {
        unsigned long flags;
+       struct vtpm_state *vtpms = (struct vtpm_state *)chip_get_private(chip);
+
        spin_lock_irqsave(&vtpms->resp_list_lock,flags);
 
-       vtpms->req_cancelled = vtpms->current_request;
+       if (!vtpms->current_response && vtpms->current_request) {
+               spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+               interruptible_sleep_on(&vtpms->resp_wait_queue);
+               spin_lock_irqsave(&vtpms->resp_list_lock,flags);
+       }
+
+       if (vtpms->current_response) {
+               struct transmission *t = vtpms->current_response;
+               vtpms->current_response = NULL;
+               transmission_free(t);
+       }
 
        spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
 }
@@ -438,6 +427,9 @@ static u8 vtpm_status(struct tpm_chip *c
 {
        u8 rc = 0;
        unsigned long flags;
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        spin_lock_irqsave(&vtpms->resp_list_lock, flags);
        /*
@@ -449,7 +441,10 @@ static u8 vtpm_status(struct tpm_chip *c
        if (vtpms->current_response ||
            0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
                rc = STATUS_DATA_AVAIL;
-       }
+       } else if (!vtpms->current_response && !vtpms->current_request) {
+               rc = STATUS_READY;
+       }
+
        spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
        return rc;
 }
@@ -465,18 +460,29 @@ static struct file_operations vtpm_ops =
 
 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
 static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
+                  NULL);
 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
 static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
 
 static struct attribute *vtpm_attrs[] = {
        &dev_attr_pubek.attr,
        &dev_attr_pcrs.attr,
+       &dev_attr_enabled.attr,
+       &dev_attr_active.attr,
+       &dev_attr_owned.attr,
+       &dev_attr_temp_deactivated.attr,
        &dev_attr_caps.attr,
        &dev_attr_cancel.attr,
        NULL,
 };
 
 static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
+
+#define TPM_LONG_TIMEOUT   (10 * 60 * HZ)
 
 static struct tpm_vendor_specific tpm_vtpm = {
        .recv = vtpm_recv,
@@ -486,61 +492,56 @@ static struct tpm_vendor_specific tpm_vt
        .req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
        .req_complete_val  = STATUS_DATA_AVAIL,
        .req_canceled = STATUS_READY,
-       .base = 0,
        .attr_group = &vtpm_attr_grp,
        .miscdev = {
                .fops = &vtpm_ops,
        },
-};
-
-static struct platform_device *pdev;
-
-int __init init_vtpm(struct tpm_virtual_device *tvd)
-{
-       int rc;
-
-       /* vtpms is global - only allow one user */
-       if (vtpms)
-               return -EBUSY;
+       .duration = {
+               TPM_LONG_TIMEOUT,
+               TPM_LONG_TIMEOUT,
+               TPM_LONG_TIMEOUT,
+       },
+};
+
+struct tpm_chip *init_vtpm(struct device *dev,
+                           struct tpm_virtual_device *tvd,
+                           struct tpm_private *tp)
+{
+       long rc;
+       struct tpm_chip *chip;
+       struct vtpm_state *vtpms;
 
        vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
        if (!vtpms)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        vtpm_state_init(vtpms);
        vtpms->tpmvd = tvd;
-
-       pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
-       if (IS_ERR(pdev)) {
-               rc = PTR_ERR(pdev);
-               goto err_free_mem;
-       }
+       vtpms->tpm_private = tp;
 
        if (tvd)
                tpm_vtpm.buffersize = tvd->max_tx_size;
 
-       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
-               goto err_unreg_pdev;
-       }
-
-       return 0;
-
-err_unreg_pdev:
-       platform_device_unregister(pdev);
+       chip = tpm_register_hardware(dev, &tpm_vtpm);
+       if (!chip) {
+               rc = -ENODEV;
+               goto err_free_mem;
+       }
+
+       chip_set_private(chip, vtpms);
+
+       return chip;
+
 err_free_mem:
        kfree(vtpms);
-       vtpms = NULL;
-
-       return rc;
-}
-
-void __exit cleanup_vtpm(void)
-{
-       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
-       if (chip) {
-               tpm_remove_hardware(chip->dev);
-               platform_device_unregister(pdev);
-       }
+
+       return ERR_PTR(rc);
+}
+
+void cleanup_vtpm(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip);
+       tpm_remove_hardware(dev);
        kfree(vtpms);
-       vtpms = NULL;
-}
+}
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h  Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h  Mon Jul 03 08:35:12 
2006 +0100
@@ -12,6 +12,26 @@ struct tpm_virtual_device {
         * for allocation of buffers.
         */
        unsigned int max_tx_size;
+};
+
+struct vtpm_state {
+       struct transmission *current_request;
+       spinlock_t           req_list_lock;
+       wait_queue_head_t    req_wait_queue;
+
+       struct list_head     queued_requests;
+
+       struct transmission *current_response;
+       spinlock_t           resp_list_lock;
+       wait_queue_head_t    resp_wait_queue;     // processes waiting for 
responses
+
+       u8                   vd_status;
+       u8                   flags;
+
+       unsigned long        disconnect_time;
+
+       struct tpm_virtual_device *tpmvd;
+
        /*
         * The following is a private structure of the underlying
         * driver. It is passed as parameter in the send function.
@@ -19,20 +39,30 @@ struct tpm_virtual_device {
        struct tpm_private *tpm_private;
 };
 
+
 enum vdev_status {
        TPM_VD_STATUS_DISCONNECTED = 0x0,
        TPM_VD_STATUS_CONNECTED = 0x1
 };
 
 /* this function is called from tpm_vtpm.c */
-int vtpm_vd_send(struct tpm_chip *tc,
-                 struct tpm_private * tp,
+int vtpm_vd_send(struct tpm_private * tp,
                  const u8 * buf, size_t count, void *ptr);
 
 /* these functions are offered by tpm_vtpm.c */
-int __init init_vtpm(struct tpm_virtual_device *);
-void __exit cleanup_vtpm(void);
-int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
-void vtpm_vd_status(u8 status);
+struct tpm_chip *init_vtpm(struct device *,
+                           struct tpm_virtual_device *,
+                           struct tpm_private *);
+void cleanup_vtpm(struct device *);
+int vtpm_vd_recv(const struct tpm_chip* chip,
+                 const unsigned char *buffer, size_t count, void *ptr);
+void vtpm_vd_status(const struct tpm_chip *, u8 status);
+
+static inline struct tpm_private *tpm_private_from_dev(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       struct vtpm_state *vtpms = chip_get_private(chip);
+       return vtpms->tpm_private;
+}
 
 #endif
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Mon Jul 03 08:35:12 
2006 +0100
@@ -34,6 +34,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
@@ -41,12 +42,15 @@
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/tpmif.h>
 #include <xen/xenbus.h>
+#include "tpm.h"
 #include "tpm_vtpm.h"
 
 #undef DEBUG
 
 /* local structures */
 struct tpm_private {
+       struct tpm_chip *chip;
+
        tpmif_tx_interface_t *tx;
        atomic_t refcnt;
        unsigned int evtchn;
@@ -60,6 +64,7 @@ struct tpm_private {
 
        atomic_t tx_busy;
        void *tx_remember;
+
        domid_t backend_id;
        wait_queue_head_t wait_q;
 
@@ -95,6 +100,7 @@ static int tpm_xmit(struct tpm_private *
                     const u8 * buf, size_t count, int userbuffer,
                     void *remember);
 static void destroy_tpmring(struct tpm_private *tp);
+void __exit tpmif_exit(void);
 
 #define DPRINTK(fmt, args...) \
     pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
@@ -199,8 +205,7 @@ static DEFINE_MUTEX(suspend_lock);
 /*
  * Send data via this module by calling this function
  */
-int vtpm_vd_send(struct tpm_chip *chip,
-                 struct tpm_private *tp,
+int vtpm_vd_send(struct tpm_private *tp,
                  const u8 * buf, size_t count, void *ptr)
 {
        int sent;
@@ -331,7 +336,7 @@ static void backend_changed(struct xenbu
 static void backend_changed(struct xenbus_device *dev,
                            enum xenbus_state backend_state)
 {
-       struct tpm_private *tp = dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        DPRINTK("\n");
 
        switch (backend_state) {
@@ -358,6 +363,9 @@ static void backend_changed(struct xenbu
        }
 }
 
+struct tpm_virtual_device tvd = {
+       .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
+};
 
 static int tpmfront_probe(struct xenbus_device *dev,
                           const struct xenbus_device_id *id)
@@ -368,6 +376,12 @@ static int tpmfront_probe(struct xenbus_
 
        if (!tp)
                return -ENOMEM;
+
+       tp->chip = init_vtpm(&dev->dev, &tvd, tp);
+
+       if (IS_ERR(tp->chip)) {
+               return PTR_ERR(tp->chip);
+       }
 
        err = xenbus_scanf(XBT_NIL, dev->nodename,
                           "handle", "%i", &handle);
@@ -380,12 +394,10 @@ static int tpmfront_probe(struct xenbus_
        }
 
        tp->dev = dev;
-       dev->dev.driver_data = tp;
 
        err = talk_to_backend(dev, tp);
        if (err) {
                tpm_private_put();
-               dev->dev.driver_data = NULL;
                return err;
        }
        return 0;
@@ -394,16 +406,16 @@ static int tpmfront_probe(struct xenbus_
 
 static int tpmfront_remove(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        destroy_tpmring(tp);
+       cleanup_vtpm(&dev->dev);
        return 0;
 }
 
 static int tpmfront_suspend(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        u32 ctr;
-
        /* lock, so no app can send */
        mutex_lock(&suspend_lock);
        tp->is_suspended = 1;
@@ -431,7 +443,7 @@ static int tpmfront_suspend(struct xenbu
 
 static int tpmfront_resume(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        destroy_tpmring(tp);
        return talk_to_backend(dev, tp);
 }
@@ -548,7 +560,7 @@ static void tpmif_rx_action(unsigned lon
                offset += tocopy;
        }
 
-       vtpm_vd_recv(buffer, received, tp->tx_remember);
+       vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
        kfree(buffer);
 
 exit:
@@ -638,6 +650,7 @@ static int tpm_xmit(struct tpm_private *
 
        atomic_set(&tp->tx_busy, 1);
        tp->tx_remember = remember;
+
        mb();
 
        DPRINTK("Notifying backend via event channel %d\n",
@@ -657,9 +670,9 @@ static void tpmif_notify_upperlayer(stru
         * to the BE.
         */
        if (tp->is_connected) {
-               vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
+               vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
        } else {
-               vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
+               vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
        }
 }
 
@@ -699,13 +712,10 @@ static void tpmif_set_connected_state(st
  * =================================================================
  */
 
-struct tpm_virtual_device tvd = {
-       .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
-};
 
 static int __init tpmif_init(void)
 {
-       int rc;
+       long rc = 0;
        struct tpm_private *tp;
 
        if ((xen_start_info->flags & SIF_INITDOMAIN)) {
@@ -717,11 +727,6 @@ static int __init tpmif_init(void)
                rc = -ENOMEM;
                goto failexit;
        }
-
-       tvd.tpm_private = tp;
-       rc = init_vtpm(&tvd);
-       if (rc)
-               goto init_vtpm_failed;
 
        IPRINTK("Initialising the vTPM driver.\n");
        if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
@@ -734,19 +739,16 @@ static int __init tpmif_init(void)
        return 0;
 
 gnttab_alloc_failed:
-       cleanup_vtpm();
-init_vtpm_failed:
        tpm_private_put();
 failexit:
 
-       return rc;
-}
-
-
-static void __exit tpmif_exit(void)
+       return (int)rc;
+}
+
+
+void __exit tpmif_exit(void)
 {
        exit_tpm_xenbus();
-       cleanup_vtpm();
        tpm_private_put();
        gnttab_free_grant_references(gref_head);
 }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Mon Jul 03 
08:35:12 2006 +0100
@@ -75,6 +75,9 @@ static unsigned long current_pages;
 static unsigned long current_pages;
 static unsigned long target_pages;
 
+/* We increase/decrease in batches which fit in a page */
+static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; 
+
 /* VM /proc information for memory */
 extern unsigned long totalram_pages;
 
@@ -95,6 +98,11 @@ static void balloon_process(void *unused
 static void balloon_process(void *unused);
 static DECLARE_WORK(balloon_worker, balloon_process, NULL);
 static struct timer_list balloon_timer;
+
+/* When ballooning out (allocating memory to return to Xen) we don't really 
+   want the kernel to try too hard since that can trigger the oom killer. */
+#define GFP_BALLOON \
+       (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
 
 #define PAGE_TO_LIST(p) (&(p)->lru)
 #define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
@@ -172,7 +180,7 @@ static unsigned long current_target(void
 
 static int increase_reservation(unsigned long nr_pages)
 {
-       unsigned long *frame_list, frame, pfn, i, flags;
+       unsigned long  pfn, i, flags;
        struct page   *page;
        long           rc;
        struct xen_memory_reservation reservation = {
@@ -181,15 +189,8 @@ static int increase_reservation(unsigned
                .domid        = DOMID_SELF
        };
 
-       if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
-               nr_pages = PAGE_SIZE / sizeof(unsigned long);
-
-       frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
-       if (frame_list == NULL) {
-               frame_list = &frame;
-               if (nr_pages > 1)
-                       nr_pages = 1;
-       }
+       if (nr_pages > ARRAY_SIZE(frame_list))
+               nr_pages = ARRAY_SIZE(frame_list);
 
        balloon_lock(flags);
 
@@ -253,15 +254,12 @@ static int increase_reservation(unsigned
  out:
        balloon_unlock(flags);
 
-       if (frame_list != &frame)
-               free_page((unsigned long)frame_list);
-
        return 0;
 }
 
 static int decrease_reservation(unsigned long nr_pages)
 {
-       unsigned long *frame_list, frame, pfn, i, flags;
+       unsigned long  pfn, i, flags;
        struct page   *page;
        void          *v;
        int            need_sleep = 0;
@@ -272,18 +270,11 @@ static int decrease_reservation(unsigned
                .domid        = DOMID_SELF
        };
 
-       if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
-               nr_pages = PAGE_SIZE / sizeof(unsigned long);
-
-       frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
-       if (frame_list == NULL) {
-               frame_list = &frame;
-               if (nr_pages > 1)
-                       nr_pages = 1;
-       }
+       if (nr_pages > ARRAY_SIZE(frame_list))
+               nr_pages = ARRAY_SIZE(frame_list);
 
        for (i = 0; i < nr_pages; i++) {
-               if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
+               if ((page = alloc_page(GFP_BALLOON)) == NULL) {
                        nr_pages = i;
                        need_sleep = 1;
                        break;
@@ -330,9 +321,6 @@ static int decrease_reservation(unsigned
        totalram_pages = current_pages;
 
        balloon_unlock(flags);
-
-       if (frame_list != &frame)
-               free_page((unsigned long)frame_list);
 
        return need_sleep;
 }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon Jul 03 08:35:12 
2006 +0100
@@ -75,8 +75,6 @@ static void update_blkif_status(blkif_t 
 /****************************************************************
  *  sysfs interface for VBD I/O requests
  */
-
-#ifdef CONFIG_SYSFS
 
 #define VBD_SHOW(name, format, args...)                                        
\
        static ssize_t show_##name(struct device *_dev,                 \
@@ -106,56 +104,39 @@ static struct attribute_group vbdstat_gr
        .attrs = vbdstat_attrs,
 };
 
+VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
+VBD_SHOW(mode, "%s\n", be->mode);
+
 int xenvbd_sysfs_addif(struct xenbus_device *dev)
 {
-       int error = 0;
+       int error;
        
-       error = sysfs_create_group(&dev->dev.kobj,
-                                  &vbdstat_group);
+       error = device_create_file(&dev->dev, &dev_attr_physical_device);
+       if (error)
+               goto fail1;
+
+       error = device_create_file(&dev->dev, &dev_attr_mode);
        if (error)
-               goto fail;
-       
+               goto fail2;
+
+       error = sysfs_create_group(&dev->dev.kobj, &vbdstat_group);
+       if (error)
+               goto fail3;
+
        return 0;
-       
-fail:
-       sysfs_remove_group(&dev->dev.kobj,
-                          &vbdstat_group);
+
+fail3: sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
+fail2: device_remove_file(&dev->dev, &dev_attr_mode);
+fail1: device_remove_file(&dev->dev, &dev_attr_physical_device);
        return error;
 }
 
 void xenvbd_sysfs_delif(struct xenbus_device *dev)
 {
-       sysfs_remove_group(&dev->dev.kobj,
-                          &vbdstat_group);
-}
-
-#else
-
-#define xenvbd_sysfs_addif(dev) (0)
-#define xenvbd_sysfs_delif(dev) ((void)0)
-
-#endif /* CONFIG_SYSFS */
-
-static ssize_t show_physical_device(struct device *_dev,
-                                   struct device_attribute *attr, char *buf)
-{
-       struct xenbus_device *dev = to_xenbus_device(_dev);
-       struct backend_info *be = dev->dev.driver_data;
-       return sprintf(buf, "%x:%x\n", be->major, be->minor);
-}
-DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
-           show_physical_device, NULL);
-
-
-static ssize_t show_mode(struct device *_dev, struct device_attribute *attr,
-                        char *buf)
-{
-       struct xenbus_device *dev = to_xenbus_device(_dev);
-       struct backend_info *be = dev->dev.driver_data;
-       return sprintf(buf, "%s\n", be->mode);
-}
-DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
-
+       sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
+       device_remove_file(&dev->dev, &dev_attr_mode);
+       device_remove_file(&dev->dev, &dev_attr_physical_device);
+}
 
 static int blkback_remove(struct xenbus_device *dev)
 {
@@ -176,9 +157,8 @@ static int blkback_remove(struct xenbus_
                be->blkif = NULL;
        }
 
-       device_remove_file(&dev->dev, &dev_attr_physical_device);
-       device_remove_file(&dev->dev, &dev_attr_mode);
-       xenvbd_sysfs_delif(dev);
+       if (be->major || be->minor)
+               xenvbd_sysfs_delif(dev);
 
        kfree(be);
        dev->dev.driver_data = NULL;
@@ -293,15 +273,18 @@ static void backend_changed(struct xenbu
                err = vbd_create(be->blkif, handle, major, minor,
                                 (NULL == strchr(be->mode, 'w')));
                if (err) {
-                       be->major = 0;
-                       be->minor = 0;
+                       be->major = be->minor = 0;
                        xenbus_dev_fatal(dev, err, "creating vbd structure");
                        return;
                }
 
-               device_create_file(&dev->dev, &dev_attr_physical_device);
-               device_create_file(&dev->dev, &dev_attr_mode);
-               xenvbd_sysfs_addif(dev);
+               err = xenvbd_sysfs_addif(dev);
+               if (err) {
+                       vbd_free(&be->blkif->vbd);
+                       be->major = be->minor = 0;
+                       xenbus_dev_fatal(dev, err, "creating sysfs entries");
+                       return;
+               }
 
                /* We're potentially connected now */
                update_blkif_status(be->blkif); 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Mon Jul 03 08:35:12 
2006 +0100
@@ -219,7 +219,10 @@ asmlinkage void evtchn_do_upcall(struct 
 
        vcpu_info->evtchn_upcall_pending = 0;
 
-       /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
+       /* Clear master pending flag /before/ clearing selector flag. */
+       rmb();
+#endif
        l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
        while (l1 != 0) {
                l1i = __ffs(l1);
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Mon Jul 03 08:35:12 
2006 +0100
@@ -169,7 +169,7 @@ int gnttab_end_foreign_access_ref(grant_
                        printk(KERN_ALERT "WARNING: g.e. still in use!\n");
                        return 0;
                }
-       } while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
+       } while ((nflags = synch_cmpxchg_subword(&shared[ref].flags, flags, 0)) 
!=
                 flags);
 
        return 1;
@@ -224,7 +224,7 @@ unsigned long gnttab_end_foreign_transfe
         * reference and return failure (== 0).
         */
        while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
-               if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
+               if (synch_cmpxchg_subword(&shared[ref].flags, flags, 0) == 
flags)
                        return 0;
                cpu_relax();
        }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Mon Jul 03 08:35:12 
2006 +0100
@@ -8,12 +8,14 @@
  */
 
 #include <linux/config.h>
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <asm/hypervisor.h>
 #include <xen/features.h>
 #include <xen/hypervisor_sysfs.h>
+#include <xen/xenbus.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mike D. Day <ncmike@xxxxxxxxxx>");
@@ -95,6 +97,37 @@ static void xen_sysfs_version_destroy(vo
 static void xen_sysfs_version_destroy(void)
 {
        sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group);
+}
+
+/* UUID */
+
+static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+       char *vm, *val;
+       int ret;
+
+       vm = xenbus_read(XBT_NIL, "vm", "", NULL);
+       if (IS_ERR(vm))
+               return PTR_ERR(vm);
+       val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
+       kfree(vm);
+       if (IS_ERR(val))
+               return PTR_ERR(val);
+       ret = sprintf(buffer, "%s\n", val);
+       kfree(val);
+       return ret;
+}
+
+HYPERVISOR_ATTR_RO(uuid);
+
+static int __init xen_sysfs_uuid_init(void)
+{
+       return sysfs_create_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
+}
+
+static void xen_sysfs_uuid_destroy(void)
+{
+       sysfs_remove_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
 }
 
 /* xen compilation attributes */
@@ -314,10 +347,15 @@ static int __init hyper_sysfs_init(void)
        ret = xen_compilation_init();
        if (ret)
                goto comp_out;
+       ret = xen_sysfs_uuid_init();
+       if (ret)
+               goto uuid_out;
        ret = xen_properties_init();
        if (!ret)
                goto out;
 
+       xen_sysfs_uuid_destroy();
+uuid_out:
        xen_compilation_destroy();
 comp_out:
        xen_sysfs_version_destroy();
@@ -331,6 +369,7 @@ static void hyper_sysfs_exit(void)
 {
        xen_properties_destroy();
        xen_compilation_destroy();
+       xen_sysfs_uuid_destroy();
        xen_sysfs_version_destroy();
        xen_sysfs_type_destroy();
 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Jul 03 
08:35:12 2006 +0100
@@ -663,6 +663,34 @@ static void netbk_fill_frags(struct sk_b
        }
 }
 
+int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
+                    int work_to_do)
+{
+       struct netif_extra_info *extra;
+       RING_IDX cons = netif->tx.req_cons;
+
+       do {
+               if (unlikely(work_to_do-- <= 0)) {
+                       DPRINTK("Missing extra info\n");
+                       return -EBADR;
+               }
+
+               extra = (struct netif_extra_info *)
+                       RING_GET_REQUEST(&netif->tx, cons);
+               if (unlikely(!extra->type ||
+                            extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+                       netif->tx.req_cons = ++cons;
+                       DPRINTK("Invalid extra type: %d\n", extra->type);
+                       return -EINVAL;
+               }
+
+               memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+               netif->tx.req_cons = ++cons;
+       } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+
+       return work_to_do;
+}
+
 /* Called after netfront has transmitted */
 static void net_tx_action(unsigned long unused)
 {
@@ -670,7 +698,7 @@ static void net_tx_action(unsigned long 
        struct sk_buff *skb;
        netif_t *netif;
        netif_tx_request_t txreq;
-       struct netif_tx_extra txtra;
+       struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
        u16 pending_idx;
        RING_IDX i;
        gnttab_map_grant_ref_t *mop;
@@ -732,16 +760,15 @@ static void net_tx_action(unsigned long 
                work_to_do--;
                netif->tx.req_cons = ++i;
 
+               memset(extras, 0, sizeof(extras));
                if (txreq.flags & NETTXF_extra_info) {
-                       if (work_to_do-- <= 0) {
-                               DPRINTK("Missing extra info\n");
-                               netbk_tx_err(netif, &txreq, i);
+                       work_to_do = netbk_get_extras(netif, extras,
+                                                     work_to_do);
+                       if (unlikely(work_to_do < 0)) {
+                               netbk_tx_err(netif, &txreq, 0);
                                continue;
                        }
-
-                       memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
-                              sizeof(txtra));
-                       netif->tx.req_cons = ++i;
+                       i = netif->tx.req_cons;
                }
 
                ret = netbk_count_requests(netif, &txreq, work_to_do);
@@ -751,7 +778,7 @@ static void net_tx_action(unsigned long 
                }
                i += ret;
 
-               if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
+               if (unlikely(ret > MAX_SKB_FRAGS)) {
                        DPRINTK("Too many frags\n");
                        netbk_tx_err(netif, &txreq, i);
                        continue;
@@ -788,10 +815,24 @@ static void net_tx_action(unsigned long 
                /* Packets passed to netif_rx() must have some headroom. */
                skb_reserve(skb, 16);
 
-               if (txreq.flags & NETTXF_gso) {
-                       skb_shinfo(skb)->gso_size = txtra.u.gso.size;
-                       skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
-                       skb_shinfo(skb)->gso_type = txtra.u.gso.type;
+               if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
+                       struct netif_extra_info *gso;
+                       gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
+
+                       /* Currently on TCPv4 S.O. is supported. */
+                       if (gso->u.gso.type != XEN_NETIF_GSO_TCPV4) {
+                               DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
+                               kfree_skb(skb);
+                               netbk_tx_err(netif, &txreq, i);
+                               break;
+                       }
+
+                       skb_shinfo(skb)->gso_size = gso->u.gso.size;
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+
+                       /* Header must be checked, and gso_segs computed. */
+                       skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+                       skb_shinfo(skb)->gso_segs = 0;
                }
 
                gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Mon Jul 03 08:35:12 
2006 +0100
@@ -101,11 +101,13 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
+#if 0 /* KAF: After the protocol is finalised. */
                err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
                if (err) {
                        message = "writing feature-tso";
                        goto abort_transaction;
                }
+#endif
 
                err = xenbus_transaction_end(xbt, 0);
        } while (err == -EAGAIN);
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon Jul 03 
08:35:12 2006 +0100
@@ -463,7 +463,7 @@ static int network_open(struct net_devic
 
 static inline int netfront_tx_slot_available(struct netfront_info *np)
 {
-       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
+       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
 }
 
 static inline void network_maybe_wake_tx(struct net_device *dev)
@@ -491,7 +491,13 @@ static void network_tx_buf_gc(struct net
                rmb(); /* Ensure we see responses up to 'rp'. */
 
                for (cons = np->tx.rsp_cons; cons != prod; cons++) {
-                       id  = RING_GET_RESPONSE(&np->tx, cons)->id;
+                       struct netif_tx_response *txrsp;
+
+                       txrsp = RING_GET_RESPONSE(&np->tx, cons);
+                       if (txrsp->status == NETIF_RSP_NULL)
+                               continue;
+
+                       id  = txrsp->id;
                        skb = np->tx_skbs[id];
                        if (unlikely(gnttab_query_foreign_access(
                                np->grant_tx_ref[id]) != 0)) {
@@ -719,6 +725,7 @@ static int network_start_xmit(struct sk_
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        struct netif_tx_request *tx;
+       struct netif_extra_info *extra;
        char *data = skb->data;
        RING_IDX i;
        grant_ref_t ref;
@@ -739,7 +746,8 @@ static int network_start_xmit(struct sk_
        spin_lock_irq(&np->tx_lock);
 
        if (unlikely(!netif_carrier_ok(dev) ||
-                    (frags > 1 && !xennet_can_sg(dev)))) {
+                    (frags > 1 && !xennet_can_sg(dev)) ||
+                    netif_needs_gso(dev, skb))) {
                spin_unlock_irq(&np->tx_lock);
                goto drop;
        }
@@ -762,10 +770,29 @@ static int network_start_xmit(struct sk_
        tx->size = len;
 
        tx->flags = 0;
+       extra = NULL;
+
        if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
                tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
        if (skb->proto_data_valid) /* remote but checksummed? */
                tx->flags |= NETTXF_data_validated;
+
+       if (skb_shinfo(skb)->gso_size) {
+               struct netif_extra_info *gso = (struct netif_extra_info *)
+                       RING_GET_REQUEST(&np->tx, ++i);
+
+               if (extra)
+                       extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
+               else
+                       tx->flags |= NETTXF_extra_info;
+
+               gso->u.gso.size = skb_shinfo(skb)->gso_size;
+               gso->u.gso.type = XEN_NETIF_GSO_TCPV4;
+
+               gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
+               gso->flags = 0;
+               extra = gso;
+       }
 
        np->tx.req_prod_pvt = i + 1;
 
@@ -1065,9 +1092,28 @@ static int xennet_set_sg(struct net_devi
        return ethtool_op_set_sg(dev, data);
 }
 
+static int xennet_set_tso(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct netfront_info *np = netdev_priv(dev);
+               int val;
+
+               if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-tso",
+                                "%d", &val) < 0)
+                       val = 0;
+#if 0 /* KAF: After the protocol is finalised. */
+               if (!val)
+#endif
+                       return -ENOSYS;
+       }
+
+       return ethtool_op_set_tso(dev, data);
+}
+
 static void xennet_set_features(struct net_device *dev)
 {
-       xennet_set_sg(dev, 1);
+       if (!xennet_set_sg(dev, 1))
+               xennet_set_tso(dev, 1);
 }
 
 static void network_connect(struct net_device *dev)
@@ -1148,6 +1194,8 @@ static struct ethtool_ops network_ethtoo
        .set_tx_csum = ethtool_op_set_tx_csum,
        .get_sg = ethtool_op_get_sg,
        .set_sg = xennet_set_sg,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = xennet_set_tso,
 };
 
 #ifdef CONFIG_SYSFS
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Jul 03 
08:35:12 2006 +0100
@@ -886,29 +886,6 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_no
 EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
 
 
-static int all_devices_ready_(struct device *dev, void *data)
-{
-       struct xenbus_device *xendev = to_xenbus_device(dev);
-       int *result = data;
-
-       if (xendev->state != XenbusStateConnected) {
-               *result = 0;
-               return 1;
-       }
-
-       return 0;
-}
-
-
-static int all_devices_ready(void)
-{
-       int ready = 1;
-       bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
-                        all_devices_ready_);
-       return ready;
-}
-
-
 void xenbus_probe(void *unused)
 {
        BUG_ON((xenstored_ready <= 0));
@@ -1060,6 +1037,43 @@ postcore_initcall(xenbus_probe_init);
 postcore_initcall(xenbus_probe_init);
 
 
+static int is_disconnected_device(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+
+       /*
+        * A device with no driver will never connect. We care only about
+        * devices which should currently be in the process of connecting.
+        */
+       if (!dev->driver)
+               return 0;
+
+       return (xendev->state != XenbusStateConnected);
+}
+
+static int exists_disconnected_device(void)
+{
+       return bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
+                               is_disconnected_device);
+}
+
+static int print_device_status(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+
+       if (!dev->driver) {
+               /* Information only: is this too noisy? */
+               printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
+                      xendev->nodename);
+       } else if (xendev->state != XenbusStateConnected) {
+               printk(KERN_WARNING "XENBUS: Timeout connecting "
+                      "to device: %s (state %d)\n",
+                      xendev->nodename, xendev->state);
+       }
+
+       return 0;
+}
+
 /*
  * On a 10 second timeout, wait for all devices currently configured.  We need
  * to do this to guarantee that the filesystems and / or network devices
@@ -1081,13 +1095,12 @@ static int __init wait_for_devices(void)
        if (!is_running_on_xen())
                return -ENODEV;
 
-       while (time_before(jiffies, timeout)) {
-               if (all_devices_ready())
-                       return 0;
+       while (time_before(jiffies, timeout) && exists_disconnected_device())
                schedule_timeout_interruptible(HZ/10);
-       }
-
-       printk(KERN_WARNING "XENBUS: Timeout connecting to devices!\n");
+
+       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
+                        print_device_status);
+
        return 0;
 }
 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Wed Jun 
28 07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Mon Jul 
03 08:35:12 2006 +0100
@@ -138,4 +138,6 @@ static __inline__ int synch_var_test_bit
  synch_const_test_bit((nr),(addr)) : \
  synch_var_test_bit((nr),(addr)))
 
+#define synch_cmpxchg_subword synch_cmpxchg
+
 #endif /* __XEN_SYNCH_BITOPS_H__ */
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h      Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h      Mon Jul 03 
08:35:12 2006 +0100
@@ -58,4 +58,6 @@ static __inline__ int synch_var_test_bit
  synch_const_test_bit((nr),(addr)) : \
  synch_var_test_bit((nr),(addr)))
 
+#define synch_cmpxchg_subword synch_cmpxchg
+
 #endif /* __XEN_SYNCH_BITOPS_H__ */
diff -r 4b51d081378d -r 856caf975abd patches/linux-2.6.16.13/net-gso.patch
--- a/patches/linux-2.6.16.13/net-gso.patch     Wed Jun 28 07:52:21 2006 -0600
+++ b/patches/linux-2.6.16.13/net-gso.patch     Mon Jul 03 08:35:12 2006 +0100
@@ -2225,7 +2225,7 @@ index d64e2ec..7494823 100644
        err = ipcomp_compress(x, skb);
        iph = skb->nh.iph;
 diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 00aa80e..84130c9 100644
+index 00aa80e..30c81a8 100644
 --- a/net/ipv4/tcp.c
 +++ b/net/ipv4/tcp.c
 @@ -257,6 +257,7 @@ #include <linux/smp_lock.h>
@@ -2281,7 +2281,7 @@ index 00aa80e..84130c9 100644
  
                        from += copy;
                        copied += copy;
-@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 
+@@ -2026,6 +2021,77 @@ int tcp_getsockopt(struct sock *sk, int 
  }
  
  
@@ -2306,12 +2306,18 @@ index 00aa80e..84130c9 100644
 +      if (!pskb_may_pull(skb, thlen))
 +              goto out;
 +
-+      segs = NULL;
-+      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
-+              goto out;
-+
 +      oldlen = (u16)~skb->len;
 +      __skb_pull(skb, thlen);
++
++      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
++              /* Packet is from an untrusted source, reset gso_segs. */
++              int mss = skb_shinfo(skb)->gso_size;
++
++              skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
++
++              segs = NULL;
++              goto out;
++      }
 +
 +      segs = skb_segment(skb, features);
 +      if (IS_ERR(segs))
diff -r 4b51d081378d -r 856caf975abd 
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch    Wed Jun 28 07:52:21 
2006 -0600
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch    Mon Jul 03 08:35:12 
2006 +0100
@@ -123,6 +123,21 @@ diff -pru ../pristine-linux-2.6.16.13/dr
                                }
                        }
                }
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h 
./drivers/oprofile/buffer_sync.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h 2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/buffer_sync.h   2006-06-27 12:12:09.000000000 +0800
+@@ -9,6 +9,11 @@
+ 
+ #ifndef OPROFILE_BUFFER_SYNC_H
+ #define OPROFILE_BUFFER_SYNC_H
++
++#define NO_DOMAIN_SWITCH              -1
++#define DOMAIN_SWITCH_START_EVENT1    0
++#define DOMAIN_SWITCH_START_EVENT2    1
++#define DOMAIN_SWITCH_STOP_EVENT1     2
+  
+ /* add the necessary profiling hooks */
+ int sync_start(void);
 diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
 --- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c  2006-05-03 
05:38:44.000000000 +0800
 +++ ./drivers/oprofile/cpu_buffer.c    2006-06-19 22:43:53.000000000 +0800
diff -r 4b51d081378d -r 856caf975abd tools/examples/Makefile
--- a/tools/examples/Makefile   Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/examples/Makefile   Mon Jul 03 08:35:12 2006 +0100
@@ -26,7 +26,7 @@ XEN_SCRIPTS += network-nat vif-nat
 XEN_SCRIPTS += network-nat vif-nat
 XEN_SCRIPTS += block
 XEN_SCRIPTS += block-enbd block-nbd
-XEN_SCRIPTS += vtpm vtpm-delete
+XEN_SCRIPTS += vtpm vtpm-delete vtpm-addtodb
 XEN_SCRIPTS += xen-hotplug-cleanup
 XEN_SCRIPTS += external-device-migrate
 XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
diff -r 4b51d081378d -r 856caf975abd tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/examples/vtpm-common.sh     Mon Jul 03 08:35:12 2006 +0100
@@ -347,16 +347,9 @@ function isLocalAddress() {
 # 2nd: name of the domain to migrate
 # 3rd: the migration step to perform
 function vtpm_migration_step() {
-       local instance res
-       instance=$(vtpmdb_find_instance $2)
-       if [ "$instance" == "" ]; then
-               echo "Error: Translation of domain name ($2) to instance 
failed. Check /etc/xen/vtpm.db"
-               log err "Error during translation of domain name"
-       else
-               res=$(isLocalAddress $1)
-               if [ "$res" == "0" ]; then
-                       vtpm_migrate $1 $2 $3
-               fi
+       local res=$(isLocalAddress $1)
+       if [ "$res" == "0" ]; then
+               vtpm_migrate $1 $2 $3
        fi
 }
 
diff -r 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/hvmloader/Makefile Mon Jul 03 08:35:12 2006 +0100
@@ -45,9 +45,9 @@ LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Tt
 .PHONY: all
 all: hvmloader
 
-hvmloader: roms.h hvmloader.c acpi_madt.c
-       $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c
-       $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o
+hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c
+       $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c
+       $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
diff -r 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/hvmloader/acpi_madt.c      Mon Jul 03 08:35:12 2006 +0100
@@ -51,7 +51,7 @@ static int validate_hvm_info(struct hvm_
 }
 
 /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
-static struct hvm_info_table *
+struct hvm_info_table *
 get_hvm_info_table(void)
 {
        struct hvm_info_table *t;
diff -r 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/hvmloader/hvmloader.c      Mon Jul 03 08:35:12 2006 +0100
@@ -23,6 +23,7 @@
  */
 #include "roms.h"
 #include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include <xen/hvm/hvm_info_table.h>
 
 /* memory map */
 #define VGABIOS_PHYSICAL_ADDRESS       0x000C0000
@@ -71,6 +72,8 @@ asm(
 
 extern int get_acpi_enabled(void);
 extern int acpi_madt_update(unsigned char* acpi_start);
+extern void create_mp_tables(void);
+struct hvm_info_table *get_hvm_info_table(void);
 
 static inline void
 outw(unsigned short addr, unsigned short val)
@@ -162,10 +165,15 @@ int
 int
 main(void)
 {
+       struct hvm_info_table *t = get_hvm_info_table();
+
        puts("HVM Loader\n");
 
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
+       if (t->apic_enabled)
+               create_mp_tables();
+       
        if (cirrus_check()) {
                puts("Loading Cirrus VGABIOS ...\n");
                memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
diff -r 4b51d081378d -r 856caf975abd tools/firmware/rombios/Makefile
--- a/tools/firmware/rombios/Makefile   Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/rombios/Makefile   Mon Jul 03 08:35:12 2006 +0100
@@ -1,13 +1,9 @@ BIOS_BUILDS = BIOS-bochs-latest
-BIOS_BUILDS = BIOS-bochs-latest
-#BIOS_BUILDS += BIOS-bochs-2-processors
-#BIOS_BUILDS += BIOS-bochs-4-processors
-#BIOS_BUILDS += BIOS-bochs-8-processors
 
 .PHONY: all
 all: bios
 
 .PHONY: bios
-bios: biossums ${BIOS_BUILDS}
+bios: biossums BIOS-bochs-latest
 
 .PHONY: clean
 clean:
@@ -26,36 +22,6 @@ BIOS-bochs-latest: rombios.c biossums
        ./biossums BIOS-bochs-latest
        rm -f _rombios_.s
 
-BIOS-bochs-2-processors: rombios.c biossums
-       gcc -DBX_SMP_PROCESSORS=2 -E -P $< > _rombios2_.c
-       bcc -o rombios2.s -C-c -D__i86__ -0 -S _rombios2_.c
-       sed -e 's/^\.text//' -e 's/^\.data//' rombios2.s > _rombios2_.s
-       as86 _rombios2_.s -b tmp2.bin -u- -w- -g -0 -j -O -l rombios2.txt
-       -perl makesym.perl < rombios2.txt > rombios2.sym
-       mv tmp2.bin BIOS-bochs-2-processors
-       ./biossums BIOS-bochs-2-processors
-       rm -f _rombios2_.s
-
-BIOS-bochs-4-processors: rombios.c biossums
-       gcc -DBX_SMP_PROCESSORS=4 -E -P $< > _rombios4_.c
-       bcc -o rombios4.s -C-c -D__i86__ -0 -S _rombios4_.c
-       sed -e 's/^\.text//' -e 's/^\.data//' rombios4.s > _rombios4_.s
-       as86 _rombios4_.s -b tmp4.bin -u- -w- -g -0 -j -O -l rombios4.txt
-       -perl makesym.perl < rombios4.txt > rombios4.sym
-       mv tmp4.bin BIOS-bochs-4-processors
-       ./biossums BIOS-bochs-4-processors
-       rm -f _rombios4_.s
-
-BIOS-bochs-8-processors: rombios.c biossums
-       gcc -DBX_SMP_PROCESSORS=8 -E -P $< > _rombios8_.c
-       bcc -o rombios8.s -C-c -D__i86__ -0 -S _rombios8_.c
-       sed -e 's/^\.text//' -e 's/^\.data//' rombios8.s > _rombios8_.s
-       as86 _rombios8_.s -b tmp8.bin -u- -w- -g -0 -j -O -l rombios8.txt
-       -perl makesym.perl < rombios8.txt > rombios8.sym
-       mv tmp8.bin BIOS-bochs-8-processors
-       ./biossums BIOS-bochs-8-processors
-       rm -f _rombios8_.s
-
 biossums: biossums.c
        gcc -o biossums biossums.c
 
diff -r 4b51d081378d -r 856caf975abd tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/rombios/rombios.c  Mon Jul 03 08:35:12 2006 +0100
@@ -10514,6 +10514,34 @@ static Bit8u vgafont8[128*8]=
  0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
 };
 
+#ifdef HVMASSIST
+//
+// MP Tables
+// just carve out some blank space for HVMLOADER to write the MP tables to
+//
+// NOTE: There should be enough space for a 32 processor entry MP table
+//
+ASM_START
+.org 0xcc00
+db 0x5F, 0x5F, 0x5F, 0x48, 0x56, 0x4D, 0x4D, 0x50 ;; ___HVMMP
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;;  64 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 128 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 192 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 256 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 320 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 384 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 448 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 512 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 576 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 640 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 704 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 768 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 832 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 896 bytes
+ASM_END
+
+#else // !HVMASSIST
+
 ASM_START
 .org 0xcc00
 // bcc-generated data will be placed here
@@ -10835,3 +10863,5 @@ db 0,0,0,0     ;; MP feature bytes 2-5.
 #endif
 
 ASM_END
+
+#endif // HVMASSIST
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_hvm_build.c        Mon Jul 03 08:35:12 2006 +0100
@@ -4,6 +4,7 @@
 
 #define ELFSIZE 32
 #include <stddef.h>
+#include <inttypes.h>
 #include "xg_private.h"
 #include "xc_elf.h"
 #include <stdlib.h>
@@ -188,7 +189,7 @@ static int setup_guest(int xc_handle,
     unsigned char e820_map_nr;
 
     struct domain_setup_info dsi;
-    unsigned long long v_end;
+    uint64_t v_end;
 
     unsigned long shared_page_frame = 0;
     shared_iopage_t *sp;
@@ -208,11 +209,11 @@ static int setup_guest(int xc_handle,
     v_end = (unsigned long long)memsize << 20;
 
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
-           "  Loaded HVM loader:    %08lx->%08lx\n"
-           "  TOTAL:                %08lx->%016llx\n",
+           "  Loaded HVM loader:    %016"PRIx64"->%016"PRIx64"\n"
+           "  TOTAL:                %016"PRIx64"->%016"PRIx64"\n",
            dsi.v_kernstart, dsi.v_kernend,
            dsi.v_start, v_end);
-    IPRINTF("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
+    IPRINTF("  ENTRY ADDRESS:        %016"PRIx64"\n", dsi.v_kernentry);
 
     if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
     {
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_linux_build.c      Mon Jul 03 08:35:12 2006 +0100
@@ -11,6 +11,9 @@
 #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))
 
 #if defined(__i386__)
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
@@ -502,8 +505,6 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-#define _p(a) ((void *) (a))
-
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
            " Loaded kernel: %p->%p\n"
            " Init. ramdisk: %p->%p\n"
@@ -766,9 +767,9 @@ static int setup_guest(int xc_handle,
                 goto error_out;
         }
 
-#define NR(_l,_h,_s) \
-    (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
-    ((_l) & ~((1UL<<(_s))-1))) >> (_s))
+#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 )
         {
@@ -796,8 +797,6 @@ static int setup_guest(int xc_handle,
             break;
 #endif
     }
-
-#define _p(a) ((void *) (a))
 
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
     IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
@@ -819,8 +818,8 @@ static int setup_guest(int xc_handle,
     if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
     {
         PERROR("Initial guest OS requires too much space\n"
-               "(%luMB is greater than %luMB limit)\n",
-               (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT));
+               "(%pMB is greater than %luMB limit)\n",
+               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
         goto error_out;
     }
 
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_linux_save.c       Mon Jul 03 08:35:12 2006 +0100
@@ -415,11 +415,11 @@ static int suspend_and_state(int (*suspe
 ** which entries do not require canonicalization (in particular, those
 ** entries which map the virtual address reserved for the hypervisor).
 */
-void canonicalize_pagetable(unsigned long type, unsigned long pfn,
-                             const void *spage, void *dpage)
-{
-
-    int i, pte_last, xen_start, xen_end;
+int canonicalize_pagetable(unsigned long type, unsigned long pfn,
+                           const void *spage, void *dpage)
+{
+
+    int i, pte_last, xen_start, xen_end, race = 0; 
     uint64_t pte;
 
     /*
@@ -481,7 +481,8 @@ void canonicalize_pagetable(unsigned lon
                    is quite feasible under live migration */
                 DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
                         type, i, (unsigned long long)pte, mfn);
-                pfn = 0; /* zap it - we'll retransmit this page later */
+                pfn  = 0;  /* zap it - we'll retransmit this page later */
+                race = 1;  /* inform the caller of race; fatal if !live */ 
             } else
                 pfn = mfn_to_pfn(mfn);
 
@@ -496,7 +497,7 @@ void canonicalize_pagetable(unsigned lon
 
     }
 
-    return;
+    return race; 
 }
 
 
@@ -567,7 +568,7 @@ int xc_linux_save(int xc_handle, int io_
     int rc = 1, i, j, last_iter, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
-    int sent_last_iter, skip_this_iter;
+    int race = 0, sent_last_iter, skip_this_iter;
 
     /* The new domain's shared-info frame number. */
     unsigned long shared_info_frame;
@@ -1000,7 +1001,11 @@ int xc_linux_save(int xc_handle, int io_
                 if (pagetype >= L1TAB && pagetype <= L4TAB) {
 
                     /* We have a pagetable page: need to rewrite it. */
-                    canonicalize_pagetable(pagetype, pfn, spage, page);
+                    race = 
+                        canonicalize_pagetable(pagetype, pfn, spage, page); 
+
+                    if(race && !live) 
+                        goto out; 
 
                     if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
                         ERR("Error when writing to state file (4)");
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_load_elf.c Mon Jul 03 08:35:12 2006 +0100
@@ -68,7 +68,7 @@ static int parseelfimage(const char *ima
     Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
     Elf_Phdr *phdr;
     Elf_Shdr *shdr;
-    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
+    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
     const char *shstrtab;
     char *guestinfo=NULL, *p;
     int h, virt_base_defined, elf_pa_off_defined;
@@ -162,15 +162,19 @@ static int parseelfimage(const char *ima
     /* Initial guess for virt_base is 0 if it is not explicitly defined. */
     p = strstr(guestinfo, "VIRT_BASE=");
     virt_base_defined = (p != NULL);
-    virt_base = virt_base_defined ? strtoul(p+10, &p, 0) : 0;
+    virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0;
 
     /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
     p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
     elf_pa_off_defined = (p != NULL);
-    elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
+    elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base;
 
     if ( elf_pa_off_defined && !virt_base_defined )
-        goto bad_image;
+    {
+        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest"
+              " section.");
+        return -EINVAL;
+    }
 
     for ( h = 0; h < ehdr->e_phnum; h++ )
     {
@@ -179,7 +183,11 @@ static int parseelfimage(const char *ima
             continue;
         vaddr = phdr->p_paddr - elf_pa_off + virt_base;
         if ( (vaddr + phdr->p_memsz) < vaddr )
-            goto bad_image;
+        {
+            ERROR("ELF program header %d is too large.", h);
+            return -EINVAL;
+        }
+
         if ( vaddr < kernstart )
             kernstart = vaddr;
         if ( (vaddr + phdr->p_memsz) > kernend )
@@ -196,13 +204,16 @@ static int parseelfimage(const char *ima
 
     dsi->v_kernentry = ehdr->e_entry;
     if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
-        dsi->v_kernentry = strtoul(p+11, &p, 0);
+        dsi->v_kernentry = strtoull(p+11, &p, 0);
 
     if ( (kernstart > kernend) ||
          (dsi->v_kernentry < kernstart) ||
          (dsi->v_kernentry > kernend) ||
          (dsi->v_start > kernstart) )
-        goto bad_image;
+    {
+        ERROR("ELF start or entries are out of bounds.");
+        return -EINVAL;
+    }
 
     if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
         dsi->load_symtab = 1;
@@ -214,10 +225,6 @@ static int parseelfimage(const char *ima
     loadelfsymtab(image, 0, 0, NULL, dsi);
 
     return 0;
-
- bad_image:
-    ERROR("Malformed ELF image.");
-    return -EINVAL;
 }
 
 static int
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xg_private.h  Mon Jul 03 08:35:12 2006 +0100
@@ -132,13 +132,13 @@ typedef unsigned long l4_pgentry_t;
 
 struct domain_setup_info
 {
-    unsigned long v_start;
-    unsigned long v_end;
-    unsigned long v_kernstart;
-    unsigned long v_kernend;
-    unsigned long v_kernentry;
-
-    unsigned long elf_paddr_offset;
+    uint64_t v_start;
+    uint64_t v_end;
+    uint64_t v_kernstart;
+    uint64_t v_kernend;
+    uint64_t v_kernentry;
+
+    uint64_t elf_paddr_offset;
 
 #define PAEKERN_no           0
 #define PAEKERN_yes          1
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xend/XendLogging.py      Mon Jul 03 08:35:12 2006 +0100
@@ -43,7 +43,7 @@ BACKUP_COUNT = 5
 BACKUP_COUNT = 5
 
 STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
-LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) 
%(message)s"
+LOGFILE_FORMAT = "[%(asctime)s %(name)s %(process)d] %(levelname)s 
(%(module)s:%(lineno)d) %(message)s"
 DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Mon Jul 03 08:35:12 2006 +0100
@@ -22,8 +22,6 @@ import traceback
 import traceback
 import tempfile
 import os, stat
-import re
-import commands
 import shutil
 import string
 from xen.util.security import ACMError, err
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/create.py     Mon Jul 03 08:35:12 2006 +0100
@@ -21,11 +21,8 @@
 """
 import os
 import os.path
-import string
 import sys
 import socket
-import commands
-import time
 import re
 import xmlrpclib
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/dumppolicy.py Mon Jul 03 08:35:12 2006 +0100
@@ -19,10 +19,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
-import string
 from xen.util.security import ACMError, err, dump_policy
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/labels.py     Mon Jul 03 08:35:12 2006 +0100
@@ -20,9 +20,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
 import string
 from xen.util.security import ACMError, err, list_labels, active_policy
 from xen.util.security import vm_label_re, res_label_re, all_label_re
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/loadpolicy.py Mon Jul 03 08:35:12 2006 +0100
@@ -20,10 +20,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
-import string
 from xen.util.security import ACMError, err, load_policy
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/main.py       Mon Jul 03 08:35:12 2006 +0100
@@ -556,7 +556,7 @@ def xm_vcpu_list(args):
 
 
 def xm_reboot(args):
-    arg_check(args, "reboot", 1, 4)
+    arg_check(args, "reboot", 1, 3)
     from xen.xm import shutdown
     shutdown.main(["shutdown", "-R"] + args)
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/makepolicy.py Mon Jul 03 08:35:12 2006 +0100
@@ -19,10 +19,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
-import string
 from xen.util.security import ACMError, err, make_policy
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/shutdown.py   Mon Jul 03 08:35:12 2006 +0100
@@ -17,8 +17,6 @@
 
 """Domain shutdown.
 """
-import string
-import sys
 import time
 
 from xen.xend.XendClient import server
@@ -92,7 +90,8 @@ def main_all(opts, args):
     shutdown(opts, None, mode, opts.vals.wait)
 
 def main_dom(opts, args):
-    if len(args) < 1: opts.err('Missing domain')
+    if len(args) == 0: opts.err('No domain parameter given')
+    if len(args) >  1: opts.err('No multiple domain parameters allowed')
     dom = args[0]
     mode = shutdown_mode(opts)  
     shutdown(opts, [ dom ], mode, opts.vals.wait)
diff -r 4b51d081378d -r 856caf975abd tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c    Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xenstat/libxenstat/src/xenstat.c    Mon Jul 03 08:35:12 2006 +0100
@@ -20,6 +20,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <linux/compiler.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <xs.h>
 #include "xenstat.h"
 
@@ -36,6 +41,7 @@ struct xenstat_handle {
        struct xs_handle *xshandle; /* xenstore handle */
        int page_size;
        FILE *procnetdev;
+       DIR *sysfsvbd;
        char xen_version[VERSION_SIZE]; /* xen version running on this node */
 };
 
@@ -62,6 +68,8 @@ struct xenstat_domain {
        unsigned int ssid;
        unsigned int num_networks;
        xenstat_network *networks;      /* Array of length num_networks */
+       unsigned int num_vbds;
+       xenstat_vbd *vbds;
 };
 
 struct xenstat_vcpu {
@@ -82,6 +90,15 @@ struct xenstat_network {
        unsigned long long terrs;
        unsigned long long tdrop;
 };
+
+struct xenstat_vbd {
+       unsigned int dev;
+       unsigned long long oo_reqs;
+       unsigned long long rd_reqs;
+       unsigned long long wr_reqs;
+};
+#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
+
 
 /*
  * Data-collection types
@@ -108,12 +125,15 @@ static int  xenstat_collect_vcpus(xensta
 static int  xenstat_collect_vcpus(xenstat_node * node);
 static int  xenstat_collect_networks(xenstat_node * node);
 static int  xenstat_collect_xen_version(xenstat_node * node);
+static int  xenstat_collect_vbds(xenstat_node * node);
 static void xenstat_free_vcpus(xenstat_node * node);
 static void xenstat_free_networks(xenstat_node * node);
 static void xenstat_free_xen_version(xenstat_node * node);
+static void xenstat_free_vbds(xenstat_node * node);
 static void xenstat_uninit_vcpus(xenstat_handle * handle);
 static void xenstat_uninit_networks(xenstat_handle * handle);
 static void xenstat_uninit_xen_version(xenstat_handle * handle);
+static void xenstat_uninit_vbds(xenstat_handle * handle);
 static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int 
domain_id);
 
 static xenstat_collector collectors[] = {
@@ -122,7 +142,9 @@ static xenstat_collector collectors[] = 
        { XENSTAT_NETWORK, xenstat_collect_networks,
          xenstat_free_networks, xenstat_uninit_networks },
        { XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
-         xenstat_free_xen_version, xenstat_uninit_xen_version }
+         xenstat_free_xen_version, xenstat_uninit_xen_version },
+       { XENSTAT_VBD, xenstat_collect_vbds,
+         xenstat_free_vbds, xenstat_uninit_vbds }
 };
 
 #define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
@@ -259,6 +281,8 @@ xenstat_node *xenstat_get_node(xenstat_h
                        domain->ssid = domaininfo[i].ssidref;
                        domain->num_networks = 0;
                        domain->networks = NULL;
+                       domain->num_vbds = 0;
+                       domain->vbds = NULL;
 
                        domain++;
                }
@@ -448,6 +472,21 @@ xenstat_network *xenstat_domain_network(
 {
        if (domain->networks && 0 <= network && network < domain->num_networks)
                return &(domain->networks[network]);
+       return NULL;
+}
+
+/* Get the number of VBDs for a given domain */
+unsigned int xenstat_domain_num_vbds(xenstat_domain * domain)
+{
+       return domain->num_vbds;
+}
+
+/* Get the VBD handle to obtain VBD stats */
+xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
+                               unsigned int vbd)
+{
+       if (domain->vbds && 0 <= vbd && vbd < domain->num_vbds)
+               return &(domain->vbds[vbd]);
        return NULL;
 }
 
@@ -710,6 +749,139 @@ static void xenstat_uninit_xen_version(x
 {
 }
 
+/*
+ * VBD functions
+ */
+
+static int read_attributes_vbd(const char *vbd_directory, const char *what, 
char *ret, int cap)
+{
+       static char file_name[80];
+       int fd, num_read;
+
+       sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
+       fd = open(file_name, O_RDONLY, 0);
+       if (fd==-1) return -1;
+       num_read = read(fd, ret, cap - 1);
+       close(fd);
+       if (num_read<=0) return -1;
+       ret[num_read] = '\0';
+       return num_read;
+}
+
+/* Collect information about VBDs */
+static int xenstat_collect_vbds(xenstat_node * node)
+{
+       struct dirent *dp;
+
+       if (node->handle->sysfsvbd == NULL) {
+               node->handle->sysfsvbd = opendir(SYSFS_VBD_PATH);
+               if (node->handle->sysfsvbd == NULL) {
+                       perror("Error opening " SYSFS_VBD_PATH);
+                       return 0;
+               }
+       }
+
+       rewinddir(node->handle->sysfsvbd);
+
+       for(dp = readdir(node->handle->sysfsvbd); dp != NULL ;
+           dp = readdir(node->handle->sysfsvbd)) {
+               xenstat_domain *domain;
+               xenstat_vbd vbd;
+               unsigned int domid;
+               int ret;
+               char buf[256];
+
+
+               ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
+               if (ret != 2) {
+                       continue;
+               }
+               printf("%s is VBD.\n",dp->d_name);
+
+               domain = xenstat_node_domain(node, domid);
+               if (domain == NULL) {
+                       fprintf(stderr,
+                               "Found interface vbd-%u-%u but domain %u"
+                               " does not exist.\n",
+                               domid, vbd.dev, domid);
+                       continue;
+               }
+
+               if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 
256)<=0)
+                  || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
+               {
+                       continue;
+               }
+
+               if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 
256)<=0)
+                  || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
+               {
+                       continue;
+               }
+
+               if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 
256)<=0)
+                  || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
+               {
+                       continue;
+               }
+
+
+               if (domain->vbds == NULL) {
+                       domain->num_vbds = 1;
+                       domain->vbds = malloc(sizeof(xenstat_vbd));
+               } else {
+                       domain->num_vbds++;
+                       domain->vbds = realloc(domain->vbds,
+                                              domain->num_vbds *
+                                              sizeof(xenstat_vbd));
+               }
+               if (domain->vbds == NULL)
+                       return 0;
+               domain->vbds[domain->num_vbds - 1] = vbd;
+       }
+
+       return 1;       
+}
+
+/* Free VBD information */
+static void xenstat_free_vbds(xenstat_node * node)
+{
+       unsigned int i;
+       for (i = 0; i < node->num_domains; i++)
+               free(node->domains[i].vbds);
+}
+
+/* Free VBD information in handle */
+static void xenstat_uninit_vbds(xenstat_handle * handle)
+{
+       if (handle->sysfsvbd)
+               closedir(handle->sysfsvbd);
+}
+
+/* Get the major number of VBD device */
+unsigned int xenstat_vbd_dev(xenstat_vbd * vbd)
+{
+       return vbd->dev;
+}
+
+/* Get the number of OO(Out of) requests */
+unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd)
+{
+       return vbd->oo_reqs;
+}
+
+/* Get the number of READ requests */
+unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd)
+{
+       return vbd->rd_reqs;
+}
+
+/* Get the number of WRITE requests */
+unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd)
+{
+       return vbd->wr_reqs;
+}
+
 static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int 
domain_id)
 {
        char path[80];
diff -r 4b51d081378d -r 856caf975abd tools/xenstat/libxenstat/src/xenstat.h
--- a/tools/xenstat/libxenstat/src/xenstat.h    Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xenstat/libxenstat/src/xenstat.h    Mon Jul 03 08:35:12 2006 +0100
@@ -23,6 +23,7 @@ typedef struct xenstat_node xenstat_node
 typedef struct xenstat_node xenstat_node;
 typedef struct xenstat_vcpu xenstat_vcpu;
 typedef struct xenstat_network xenstat_network;
+typedef struct xenstat_vbd xenstat_vbd;
 
 /* Initialize the xenstat library.  Returns a handle to be used with
  * subsequent calls to the xenstat library, or NULL if an error occurs. */
@@ -35,7 +36,8 @@ void xenstat_uninit(xenstat_handle * han
 #define XENSTAT_VCPU 0x1
 #define XENSTAT_NETWORK 0x2
 #define XENSTAT_XEN_VERSION 0x4
-#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION)
+#define XENSTAT_VBD 0x8
+#define XENSTAT_ALL 
(XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION|XENSTAT_VBD)
 
 /* Get all available information about a node */
 xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
@@ -117,6 +119,13 @@ xenstat_network *xenstat_domain_network(
 xenstat_network *xenstat_domain_network(xenstat_domain * domain,
                                        unsigned int network);
 
+/* Get the number of VBDs for a given domain */
+unsigned int xenstat_domain_num_vbds(xenstat_domain *);
+
+/* Get the VBD handle to obtain VBD stats */
+xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
+                                   unsigned int vbd);
+
 /*
  * VCPU functions - extract information from a xenstat_vcpu
  */
@@ -156,3 +165,14 @@ unsigned long long xenstat_network_terrs
 
 /* Get the number of transmit drops for this network */
 unsigned long long xenstat_network_tdrop(xenstat_network * network);
+
+/*
+ * VBD functions - extract information from a xen_vbd
+ */
+/* Get the device number for Virtual Block Device */
+unsigned int xenstat_vbd_dev(xenstat_vbd * vbd);
+
+/* Get the number of OO/RD/WR requests for vbd */
+unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd);
+unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd);
+unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd);
diff -r 4b51d081378d -r 856caf975abd tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xenstat/xentop/xentop.c     Mon Jul 03 08:35:12 2006 +0100
@@ -27,6 +27,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
+#include <linux/kdev_t.h>
 
 #include <xenstat.h>
 
@@ -65,6 +66,7 @@ static int compare(unsigned long long, u
 static int compare(unsigned long long, unsigned long long);
 static int compare_domains(xenstat_domain **, xenstat_domain **);
 static unsigned long long tot_net_bytes( xenstat_domain *, int);
+static unsigned long long tot_vbd_reqs( xenstat_domain *, int);
 
 /* Field functions */
 static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
@@ -91,6 +93,15 @@ static void print_ssid(xenstat_domain *d
 static void print_ssid(xenstat_domain *domain);
 static int compare_name(xenstat_domain *domain1, xenstat_domain *domain2);
 static void print_name(xenstat_domain *domain);
+static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbds(xenstat_domain *domain);
+static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbd_oo(xenstat_domain *domain);
+static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbd_rd(xenstat_domain *domain);
+static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbd_wr(xenstat_domain *domain);
+
 
 /* Section printing functions */
 static void do_summary(void);
@@ -99,6 +110,7 @@ static void do_domain(xenstat_domain *);
 static void do_domain(xenstat_domain *);
 static void do_vcpu(xenstat_domain *);
 static void do_network(xenstat_domain *);
+static void do_vbd(xenstat_domain *);
 static void top(void);
 
 /* Field types */
@@ -116,6 +128,10 @@ typedef enum field_id {
        FIELD_NETS,
        FIELD_NET_TX,
        FIELD_NET_RX,
+       FIELD_VBDS,
+       FIELD_VBD_OO,
+       FIELD_VBD_RD,
+       FIELD_VBD_WR,
        FIELD_SSID
 } field_id;
 
@@ -140,7 +156,11 @@ field fields[] = {
        { FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
        { FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
        { FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
-       { FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
+       { FIELD_NET_RX,  "VBDS",       8, compare_vbds,    print_vbds    },
+       { FIELD_NET_RX,  "VBD_OO",     8, compare_vbd_oo,  print_vbd_oo  },
+       { FIELD_NET_RX,  "VBD_RD",     8, compare_vbd_rd,  print_vbd_rd  },
+       { FIELD_NET_RX,  "VBD_WR",     8, compare_vbd_wr,  print_vbd_wr  },
+               { FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid   
 }
 };
 
 const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field);
@@ -158,6 +178,7 @@ unsigned int iterations = 0;
 unsigned int iterations = 0;
 int show_vcpus = 0;
 int show_networks = 0;
+int show_vbds = 0;
 int repeat_header = 0;
 #define PROMPT_VAL_LEN 80
 char *prompt = NULL;
@@ -180,6 +201,7 @@ static void usage(const char *program)
               "-V, --version        output version information and exit\n"
               "-d, --delay=SECONDS  seconds between updates (default 3)\n"
               "-n, --networks       output vif network data\n"
+              "-b, --vbds           output vbd block device data\n"
               "-r, --repeat-header  repeat table header before each domain\n"
               "-v, --vcpus          output vcpu data\n"
               "-b, --batch          output in batch mode, no user input 
accepted\n"
@@ -289,6 +311,9 @@ static int handle_key(int ch)
                switch(ch) {
                case 'n': case 'N':
                        show_networks ^= 1;
+                       break;
+               case 'b': case 'B':
+                       show_vbds ^= 1;
                        break;
                case 'r': case 'R':
                        repeat_header ^= 1;
@@ -585,6 +610,96 @@ static unsigned long long tot_net_bytes(
        return total;
 }
 
+/* Compares number of virtual block devices of two domains,
+   returning -1,0,1 for * <,=,> */
+static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_num_vbds(domain1),
+                       xenstat_domain_num_vbds(domain2));
+}
+
+/* Prints number of virtual block devices statistic */
+static void print_vbds(xenstat_domain *domain)
+{
+       print("%4u", xenstat_domain_num_vbds(domain));
+}
+
+/* Compares number of total VBD OO requests of two domains,
+   returning -1,0,1 * for <,=,> */
+static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+  return -compare(tot_vbd_reqs(domain1, FIELD_VBD_OO),
+                 tot_vbd_reqs(domain2, FIELD_VBD_OO));
+}
+
+/* Prints number of total VBD OO requests statistic */
+static void print_vbd_oo(xenstat_domain *domain)
+{
+       print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_OO));
+}
+
+/* Compares number of total VBD READ requests of two domains,
+   returning -1,0,1 * for <,=,> */
+static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(tot_vbd_reqs(domain1, FIELD_VBD_RD),
+                       tot_vbd_reqs(domain2, FIELD_VBD_RD));
+}
+
+/* Prints number of total VBD READ requests statistic */
+static void print_vbd_rd(xenstat_domain *domain)
+{
+       print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_RD));
+}
+
+/* Compares number of total VBD WRITE requests of two domains,
+   returning -1,0,1 * for <,=,> */
+static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(tot_vbd_reqs(domain1,FIELD_VBD_WR),
+                       tot_vbd_reqs(domain2,FIELD_VBD_WR));
+}
+
+/* Prints number of total VBD WRITE requests statistic */
+static void print_vbd_wr(xenstat_domain *domain)
+{
+       print("%8llu", tot_vbd_reqs(domain,FIELD_VBD_WR));
+}
+
+/* Gets number of total VBD requests statistic, 
+ *   if flag is FIELD_VBD_OO, then OO requests,
+ *   if flag is FIELD_VBD_RD, then READ requests and
+ *   if flag is FIELD_VBD_WR, then WRITE requests.
+ */
+static unsigned long long tot_vbd_reqs(xenstat_domain *domain, int flag)
+{
+       int i = 0;
+       xenstat_vbd *vbd;
+       unsigned num_vbds = 0;
+       unsigned long long total = 0;
+       
+       num_vbds = xenstat_domain_num_vbds(domain);
+       
+       for ( i=0 ; i < num_vbds ; i++) {
+               vbd = xenstat_domain_vbd(domain,i);
+               switch(flag) {
+               case FIELD_VBD_OO:
+                       total += xenstat_vbd_oo_reqs(vbd);
+                       break;
+               case FIELD_VBD_RD:
+                       total += xenstat_vbd_rd_reqs(vbd);
+                       break;
+               case FIELD_VBD_WR:
+                       total += xenstat_vbd_wr_reqs(vbd);
+                       break;
+               default:
+                       break;
+               }
+       }
+       
+       return total;
+}
+
 /* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
 static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
 {
@@ -680,6 +795,13 @@ void do_bottom_line(void)
                addch(A_REVERSE | 'N');
                attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
                addstr("  ");
+               
+               /* VBDs */
+               attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "v");
+               addch(A_REVERSE | 'B');
+               attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "ds");
+               addstr("  ");
+
 
                /* vcpus */
                addch(A_REVERSE | 'V');
@@ -769,6 +891,28 @@ void do_network(xenstat_domain *domain)
        }
 }
 
+
+/* Output all VBD information */
+void do_vbd(xenstat_domain *domain)
+{
+       int i = 0;
+       xenstat_vbd *vbd;
+       unsigned num_vbds = 0;
+
+       num_vbds = xenstat_domain_num_vbds(domain);
+
+       for (i=0 ; i< num_vbds; i++) {
+               vbd = xenstat_domain_vbd(domain,i);
+                               
+               print("VBD %4u [%2x:%2x]  OO: %8llu   RD: %8llu   WR: %8llu\n",
+                     xenstat_vbd_dev(vbd),
+                     MAJOR(xenstat_vbd_dev(vbd)), MINOR(xenstat_vbd_dev(vbd)),
+                     xenstat_vbd_oo_reqs(vbd),
+                     xenstat_vbd_rd_reqs(vbd),
+                     xenstat_vbd_wr_reqs(vbd));
+       }
+}
+
 static void top(void)
 {
        xenstat_domain **domains;
@@ -812,6 +956,8 @@ static void top(void)
                        do_vcpu(domains[i]);
                if (show_networks)
                        do_network(domains[i]);
+               if (show_vbds)
+                       do_vbd(domains[i]);
        }
 
        if(!batch)
@@ -827,6 +973,7 @@ int main(int argc, char **argv)
                { "help",          no_argument,       NULL, 'h' },
                { "version",       no_argument,       NULL, 'V' },
                { "networks",      no_argument,       NULL, 'n' },
+               { "vbds",          no_argument,       NULL, 'x' },
                { "repeat-header", no_argument,       NULL, 'r' },
                { "vcpus",         no_argument,       NULL, 'v' },
                { "delay",         required_argument, NULL, 'd' },
@@ -834,7 +981,7 @@ int main(int argc, char **argv)
                { "iterations",    required_argument, NULL, 'i' },
                { 0, 0, 0, 0 },
        };
-       const char *sopts = "hVbnvd:bi:";
+       const char *sopts = "hVnxrvd:bi:";
 
        if (atexit(cleanup) != 0)
                fail("Failed to install cleanup handler.\n");
@@ -851,6 +998,9 @@ int main(int argc, char **argv)
                        exit(0);
                case 'n':
                        show_networks = 1;
+                       break;
+               case 'x':
+                       show_vbds = 1;
                        break;
                case 'r':
                        repeat_header = 1;
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py
--- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -14,16 +14,15 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 
 try:
     console = domain.start()
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -33,11 +32,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/03_vtpm-susp_res.py
--- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -15,6 +15,7 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 consoleHistory = ""
 
 try:
@@ -22,10 +23,8 @@ except DomainError, e:
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -35,11 +34,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
@@ -48,50 +47,59 @@ consoleHistory = console.getHistory()
 consoleHistory = console.getHistory()
 domain.closeConsole()
 
-try:
-    status, ouptut = traceCommand("xm save %s %s.save" %
-                                  (domName, domName),
-                                  timeout=30)
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm save %s %s.save" %
+                                      (domName, domName),
+                                      timeout=30)
 
-except TimeoutError, e:
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL(str(e))
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
 
-if status != 0:
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL("xm save did not succeed")
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm save did not succeed")
 
-try:
-    status, ouptut = traceCommand("xm restore %s.save" %
-                                  (domName),
-                                  timeout=30)
-except TimeoutError, e:
+    try:
+        status, ouptut = traceCommand("xm restore %s.save" %
+                                      (domName),
+                                      timeout=30)
+    except TimeoutError, e:
+        os.remove("%s.save" % domName)
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
     os.remove("%s.save" % domName)
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL(str(e))
 
-os.remove("%s.save" % domName)
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm restore did not succeed")
 
-if status != 0:
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL("xm restore did not succeed")
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
 
-try:
-    console = domain.getConsole()
-except ConsoleError, e:
-    vtpm_cleanup(domName)
-    FAIL(str(e))
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL(str(e))
 
-try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
-except ConsoleError, e:
-    saveLog(console.getHistory())
-    vtpm_cleanup(domName)
-    FAIL(str(e))
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    loop += 1
 
 domain.closeConsole()
 
@@ -99,5 +107,3 @@ domain.stop()
 
 vtpm_cleanup(domName)
 
-if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -16,6 +16,7 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 consoleHistory = ""
 
 try:
@@ -23,10 +24,8 @@ except DomainError, e:
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -36,11 +35,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
@@ -83,11 +82,17 @@ while loop < 3:
         FAIL(str(e))
 
     try:
-        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
     except ConsoleError, e:
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-        FAIL(str(e))
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
     loop += 1
 
 domain.closeConsole()
@@ -95,6 +100,3 @@ domain.stop()
 domain.stop()
 
 vtpm_cleanup(domName)
-
-if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -16,6 +16,7 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 consoleHistory = ""
 
 try:
@@ -23,10 +24,8 @@ except DomainError, e:
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -36,11 +35,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
@@ -83,11 +82,17 @@ while loop < 3:
         FAIL(str(e))
 
     try:
-        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
     except ConsoleError, e:
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-        FAIL(str(e))
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
     loop += 1
 
 domain.closeConsole()
@@ -95,6 +100,3 @@ domain.stop()
 domain.stop()
 
 vtpm_cleanup(domName)
-
-if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
diff -r 4b51d081378d -r 856caf975abd tools/xm-test/tests/vtpm/Makefile.am
--- a/tools/xm-test/tests/vtpm/Makefile.am      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xm-test/tests/vtpm/Makefile.am      Mon Jul 03 08:35:12 2006 +0100
@@ -4,7 +4,10 @@ TESTS = 01_vtpm-list_pos.test \
         02_vtpm-cat_pcrs.test \
         03_vtpm-susp_res.test \
         04_vtpm-loc_migr.test \
-        05_vtpm-loc_migr.test
+        05_vtpm-loc_migr.test \
+        06_vtpm-susp_res_pcrs.test \
+        07_vtpm-mig_pcrs.test \
+        08_vtpm-mig_pcrs.test
 
 XFAIL_TESTS =
 
diff -r 4b51d081378d -r 856caf975abd tools/xm-test/tests/vtpm/vtpm_utils.py
--- a/tools/xm-test/tests/vtpm/vtpm_utils.py    Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xm-test/tests/vtpm/vtpm_utils.py    Mon Jul 03 08:35:12 2006 +0100
@@ -16,4 +16,4 @@ if output == "":
     FAIL("virtual TPM manager must be started to run this test")
 
 def vtpm_cleanup(domName):
-       traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
+    traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/domain.c     Mon Jul 03 08:35:12 2006 +0100
@@ -67,16 +67,11 @@ static void default_idle(void)
 
 void idle_loop(void)
 {
-    int cpu = smp_processor_id();
-
     for ( ; ; )
     {
         page_scrub_schedule_work();
-
         default_idle();
-
-        if ( softirq_pending(cpu) )
-            do_softirq();
+        do_softirq();
     }
 }
 
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Jul 03 08:35:12 2006 +0100
@@ -2697,9 +2697,9 @@ asmlinkage void svm_vmexit_handler(struc
 
     if (exit_reason == -1)
     {
+        svm_dump_vmcb(__func__, vmcb);
         printk("%s: exit_reason == -1 - Did someone clobber the VMCB\n", 
                 __func__);
-        BUG();
         domain_crash_synchronous();
     }
 
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Mon Jul 03 08:35:12 2006 +0100
@@ -36,6 +36,7 @@
 #include <xen/kernel.h>
 #include <asm/shadow.h>
 #include <xen/keyhandler.h>
+
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/shadow_64.h>
 #endif
@@ -440,7 +441,6 @@ static int construct_vmcs(struct vcpu *v
     memset(arch_vmx, 0, sizeof(struct arch_vmx_struct));
 
     spin_lock_init(&arch_vmx->vmcs_lock);
-    arch_vmx->active_cpu = -1;
 
     /*
      * Create a new VMCS
@@ -450,7 +450,7 @@ static int construct_vmcs(struct vcpu *v
         return -ENOMEM;
     }
 
-    vmx_clear_vmcs(v);
+    __vmx_clear_vmcs(v);
     vmx_load_vmcs(v);
 
     if ((error = construct_vmcs_controls(arch_vmx))) {
@@ -495,6 +495,9 @@ void vmx_destroy_vmcs(struct vcpu *v)
 void vmx_destroy_vmcs(struct vcpu *v)
 {
     struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
+
+    if ( arch_vmx->vmcs == NULL )
+        return;
 
     vmx_clear_vmcs(v);
 
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/smpboot.c    Mon Jul 03 08:35:12 2006 +0100
@@ -1197,8 +1197,7 @@ int __devinit __cpu_up(unsigned int cpu)
        cpu_set(cpu, smp_commenced_mask);
        while (!cpu_isset(cpu, cpu_online_map)) {
                mb();
-               if (softirq_pending(0))
-                       do_softirq();
+               process_pending_timers();
        }
        return 0;
 }
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c        Mon Jul 03 08:35:12 2006 +0100
@@ -118,7 +118,7 @@ static uint8_t opcode_table[256] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xC0 - 0xC7 */
     ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
-    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
+    0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
     /* 0xC8 - 0xCF */
     0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xD0 - 0xD7 */
diff -r 4b51d081378d -r 856caf975abd xen/common/elf.c
--- a/xen/common/elf.c  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/elf.c  Mon Jul 03 08:35:12 2006 +0100
@@ -23,7 +23,7 @@ int parseelfimage(struct domain_setup_in
     Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
     Elf_Phdr *phdr;
     Elf_Shdr *shdr;
-    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
+    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
     char *shstrtab, *guestinfo=NULL, *p;
     char *elfbase = (char *)dsi->image_addr;
     int h, virt_base_defined, elf_pa_off_defined;
@@ -95,7 +95,11 @@ int parseelfimage(struct domain_setup_in
     elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
 
     if ( elf_pa_off_defined && !virt_base_defined )
-        goto bad_image;
+    {
+        printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in"
+               " __xen_guest section.\n");
+        return -EINVAL;
+    }
 
     for ( h = 0; h < ehdr->e_phnum; h++ )
     {
@@ -104,7 +108,11 @@ int parseelfimage(struct domain_setup_in
             continue;
         vaddr = phdr->p_paddr - elf_pa_off + virt_base;
         if ( (vaddr + phdr->p_memsz) < vaddr )
-            goto bad_image;
+        {
+            printk("ERROR: ELF program header %d is too large.\n", h);
+            return -EINVAL;
+        }
+
         if ( vaddr < kernstart )
             kernstart = vaddr;
         if ( (vaddr + phdr->p_memsz) > kernend )
@@ -127,7 +135,10 @@ int parseelfimage(struct domain_setup_in
          (dsi->v_kernentry < kernstart) ||
          (dsi->v_kernentry > kernend) ||
          (dsi->v_start > kernstart) )
-        goto bad_image;
+    {
+        printk("ERROR: ELF start or entries are out of bounds.\n");
+        return -EINVAL;
+    }
 
     if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
             dsi->load_symtab = 1;
@@ -139,10 +150,6 @@ int parseelfimage(struct domain_setup_in
     loadelfsymtab(dsi, 0);
 
     return 0;
-
- bad_image:
-    printk("Malformed ELF image.\n");
-    return -EINVAL;
 }
 
 int loadelfimage(struct domain_setup_info *dsi)
diff -r 4b51d081378d -r 856caf975abd xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/grant_table.c  Mon Jul 03 08:35:12 2006 +0100
@@ -287,10 +287,10 @@ __gnttab_map_grant_ref(
 
     if ( !(op->flags & GNTMAP_readonly) &&
          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
-        clear_bit(_GTF_writing, &sha->flags);
+        gnttab_clear_flag(_GTF_writing, &sha->flags);
 
     if ( !act->pin )
-        clear_bit(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, &sha->flags);
 
  unlock_out:
     spin_unlock(&rd->grant_table->lock);
@@ -425,10 +425,10 @@ __gnttab_unmap_grant_ref(
 
     if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
          !(flags & GNTMAP_readonly) )
-        clear_bit(_GTF_writing, &sha->flags);
+        gnttab_clear_flag(_GTF_writing, &sha->flags);
 
     if ( act->pin == 0 )
-        clear_bit(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, &sha->flags);
 
  unmap_out:
     op->status = rc;
@@ -889,11 +889,11 @@ gnttab_release_mappings(
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
-                clear_bit(_GTF_writing, &sha->flags);
+                gnttab_clear_flag(_GTF_writing, &sha->flags);
         }
 
         if ( act->pin == 0 )
-            clear_bit(_GTF_reading, &sha->flags);
+            gnttab_clear_flag(_GTF_reading, &sha->flags);
 
         spin_unlock(&rd->grant_table->lock);
 
diff -r 4b51d081378d -r 856caf975abd xen/common/memory.c
--- a/xen/common/memory.c       Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/memory.c       Mon Jul 03 08:35:12 2006 +0100
@@ -169,6 +169,15 @@ guest_remove_page(
             
     if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
         put_page(page);
+
+    if ( unlikely((page->count_info & PGC_count_mask) != 1) )
+    {
+        /* We'll make this a guest-visible error in future, so take heed! */
+        DPRINTK("Dom%d freeing in-use page %lx (pseudophys %lx):"
+                " count=%x type=%lx\n",
+                d->domain_id, mfn, get_gpfn_from_mfn(mfn),
+                page->count_info, page->u.inuse.type_info);
+    }
 
     guest_physmap_remove_page(d, gmfn, mfn);
 
diff -r 4b51d081378d -r 856caf975abd xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/page_alloc.c   Mon Jul 03 08:35:12 2006 +0100
@@ -388,7 +388,6 @@ void scrub_heap_pages(void)
 {
     void *p;
     unsigned long pfn;
-    int cpu = smp_processor_id();
 
     printk("Scrubbing Free RAM: ");
 
@@ -398,8 +397,7 @@ void scrub_heap_pages(void)
         if ( (pfn % ((100*1024*1024)/PAGE_SIZE)) == 0 )
             printk(".");
 
-        if ( unlikely(softirq_pending(cpu)) )
-            do_softirq();
+        process_pending_timers();
 
         /* Quick lock-free check. */
         if ( allocated_in_map(pfn) )
diff -r 4b51d081378d -r 856caf975abd xen/common/sched_credit.c
--- a/xen/common/sched_credit.c Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/sched_credit.c Mon Jul 03 08:35:12 2006 +0100
@@ -622,9 +622,12 @@ csched_dom_cntl(
 
         if ( cmd->u.credit.weight != 0 )
         {
-            csched_priv.weight -= sdom->weight;
+            if ( !list_empty(&sdom->active_sdom_elem) )
+            {
+                csched_priv.weight -= sdom->weight;
+                csched_priv.weight += cmd->u.credit.weight;
+            }
             sdom->weight = cmd->u.credit.weight;
-            csched_priv.weight += sdom->weight;
         }
 
         if ( cmd->u.credit.cap != (uint16_t)~0U )
diff -r 4b51d081378d -r 856caf975abd xen/common/schedule.c
--- a/xen/common/schedule.c     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/schedule.c     Mon Jul 03 08:35:12 2006 +0100
@@ -389,11 +389,32 @@ long do_set_timer_op(s_time_t timeout)
 long do_set_timer_op(s_time_t timeout)
 {
     struct vcpu *v = current;
+    s_time_t offset = timeout - NOW();
 
     if ( timeout == 0 )
+    {
         stop_timer(&v->timer);
+    }
+    else if ( unlikely(timeout < 0) || /* overflow into 64th bit? */
+              unlikely((offset > 0) && ((uint32_t)(offset >> 50) != 0)) )
+    {
+        /*
+         * Linux workaround: occasionally we will see timeouts a long way in 
+         * the future due to wrapping in Linux's jiffy time handling. We check 
+         * for timeouts wrapped negative, and for positive timeouts more than 
+         * about 13 days in the future (2^50ns). The correct fix is to trigger 
+         * an interrupt immediately (since Linux in fact has pending work to 
+         * do in this situation).
+         */
+        DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):"
+                " %"PRIx64"\n",
+                v->domain->domain_id, v->vcpu_id, (uint64_t)timeout);
+        send_timer_event(v);
+    }
     else
+    {
         set_timer(&v->timer, timeout);
+    }
 
     return 0;
 }
diff -r 4b51d081378d -r 856caf975abd xen/common/softirq.c
--- a/xen/common/softirq.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/softirq.c      Mon Jul 03 08:35:12 2006 +0100
@@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[
 
 asmlinkage void do_softirq(void)
 {
-    unsigned int i, cpu = smp_processor_id();
+    unsigned int i, cpu;
     unsigned long pending;
 
-    pending = softirq_pending(cpu);
-    ASSERT(pending != 0);
+    for ( ; ; )
+    {
+        /*
+         * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
+         * us to another processor.
+         */
+        cpu = smp_processor_id();
+        if ( (pending = softirq_pending(cpu)) == 0 )
+            break;
 
-    do {
         i = find_first_set_bit(pending);
         clear_bit(i, &softirq_pending(cpu));
         (*softirq_handlers[i])();
-    } while ( (pending = softirq_pending(cpu)) != 0 );
+    }
 }
 
 void open_softirq(int nr, softirq_handler handler)
diff -r 4b51d081378d -r 856caf975abd xen/common/timer.c
--- a/xen/common/timer.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/timer.c        Mon Jul 03 08:35:12 2006 +0100
@@ -327,6 +327,15 @@ static void timer_softirq_action(void)
 }
 
 
+void process_pending_timers(void)
+{
+    unsigned int cpu = smp_processor_id();
+    ASSERT(!in_irq() && local_irq_is_enabled());
+    if ( test_and_clear_bit(TIMER_SOFTIRQ, &softirq_pending(cpu)) )
+        timer_softirq_action();
+}
+
+
 static void dump_timerq(unsigned char key)
 {
     struct timer *t;
diff -r 4b51d081378d -r 856caf975abd xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/drivers/char/console.c        Mon Jul 03 08:35:12 2006 +0100
@@ -528,8 +528,7 @@ void console_endboot(void)
             printk("%d... ", 3-i);
             for ( j = 0; j < 100; j++ )
             {
-                if ( softirq_pending(smp_processor_id()) )
-                    do_softirq();
+                process_pending_timers();
                 mdelay(10);
             }
         }
@@ -741,6 +740,15 @@ void panic(const char *fmt, ...)
     machine_restart(0);
 }
 
+void __bug(char *file, int line)
+{
+    console_start_sync();
+    debugtrace_dump();
+    printk("BUG at %s:%d\n", file, line);
+    FORCE_CRASH();
+    for ( ; ; ) ;
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 4b51d081378d -r 856caf975abd xen/include/asm-ia64/grant_table.h
--- a/xen/include/asm-ia64/grant_table.h        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/asm-ia64/grant_table.h        Mon Jul 03 08:35:12 2006 +0100
@@ -55,4 +55,9 @@ void guest_physmap_add_page(struct domai
 
 #define gnttab_log_dirty(d, f) ((void)0)
 
+static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
+{
+       clear_bit(nr, addr);
+}
+
 #endif /* __ASM_GRANT_TABLE_H__ */
diff -r 4b51d081378d -r 856caf975abd xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/asm-x86/grant_table.h Mon Jul 03 08:35:12 2006 +0100
@@ -33,4 +33,9 @@ int destroy_grant_host_mapping(
 
 #define gnttab_log_dirty(d, f) mark_dirty((d), (f))
 
+static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
+{
+       clear_bit(nr, addr);
+}
+
 #endif /* __ASM_GRANT_TABLE_H__ */
diff -r 4b51d081378d -r 856caf975abd xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/arch-ia64.h    Mon Jul 03 08:35:12 2006 +0100
@@ -39,6 +39,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define MAX_VIRT_CPUS 64
 
 #ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
 
 #define MAX_NR_SECTION  32  /* at most 32 memory holes */
 struct mm_section {
diff -r 4b51d081378d -r 856caf975abd xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/arch-x86_32.h  Mon Jul 03 08:35:12 2006 +0100
@@ -97,6 +97,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define MAX_VIRT_CPUS 32
 
 #ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
 
 /*
  * Send an array of these to HYPERVISOR_set_trap_table()
diff -r 4b51d081378d -r 856caf975abd xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/arch-x86_64.h  Mon Jul 03 08:35:12 2006 +0100
@@ -104,6 +104,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define MAX_VIRT_CPUS 32
 
 #ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
 
 /*
  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
diff -r 4b51d081378d -r 856caf975abd xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/io/netif.h     Mon Jul 03 08:35:12 2006 +0100
@@ -23,8 +23,9 @@
  * This is the 'wire' format for packets:
  *  Request 1: netif_tx_request -- NETTXF_* (any flags)
  * [Request 2: netif_tx_extra]  (only if request 1 has NETTXF_extra_info)
- *  Request 3: netif_tx_request -- NETTXF_more_data
+ * [Request 3: netif_tx_extra]  (only if request 2 has XEN_NETIF_EXTRA_MORE)
  *  Request 4: netif_tx_request -- NETTXF_more_data
+ *  Request 5: netif_tx_request -- NETTXF_more_data
  *  ...
  *  Request N: netif_tx_request -- 0
  */
@@ -41,12 +42,9 @@
 #define _NETTXF_more_data      (2)
 #define  NETTXF_more_data      (1U<<_NETTXF_more_data)
 
-/* Packet has GSO fields in the following descriptor (netif_tx_extra.u.gso). */
-#define _NETTXF_gso            (3)
-#define  NETTXF_gso            (1U<<_NETTXF_gso)
-
-/* This descriptor is followed by an extra-info descriptor (netif_tx_extra). */
-#define  NETTXF_extra_info     (NETTXF_gso)
+/* Packet to be followed by extra descriptor(s). */
+#define _NETTXF_extra_info     (3)
+#define  NETTXF_extra_info     (1U<<_NETTXF_extra_info)
 
 struct netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
@@ -57,15 +55,42 @@ struct netif_tx_request {
 };
 typedef struct netif_tx_request netif_tx_request_t;
 
-/* This structure needs to fit within netif_tx_request for compatibility. */
-struct netif_tx_extra {
+/* Types of netif_extra_info descriptors. */
+#define XEN_NETIF_EXTRA_TYPE_NONE  (0)  /* Never used - invalid */
+#define XEN_NETIF_EXTRA_TYPE_GSO   (1)  /* u.gso */
+#define XEN_NETIF_EXTRA_TYPE_MAX   (2)
+
+/* netif_extra_info flags. */
+#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
+#define XEN_NETIF_EXTRA_FLAG_MORE  (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
+
+/* GSO types - only TCPv4 currently supported. */
+#define XEN_NETIF_GSO_TCPV4        (1)
+
+/*
+ * This structure needs to fit within both netif_tx_request and
+ * netif_rx_response for compatibility.
+ */
+struct netif_extra_info {
+    uint8_t type;  /* XEN_NETIF_EXTRA_TYPE_* */
+    uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
+
     union {
-        /* NETTXF_gso: Generic Segmentation Offload. */
-        struct netif_tx_gso {
-            uint16_t size;        /* GSO MSS. */
-            uint16_t segs;        /* GSO segment count. */
-            uint16_t type;        /* GSO type. */
+        struct {
+            /*
+             * Maximum payload size of each segment. For example, for TCP this
+             * is just the path MSS.
+             */
+            uint16_t size;
+
+            /*
+             * GSO type. This determines the protocol of the packet and any
+             * extra features required to segment the packet properly.
+             */
+            uint16_t type; /* XEN_NETIF_GSO_* */
         } gso;
+
+        uint16_t pad[3];
     } u;
 };
 
diff -r 4b51d081378d -r 856caf975abd xen/include/public/memory.h
--- a/xen/include/public/memory.h       Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/memory.h       Mon Jul 03 08:35:12 2006 +0100
@@ -32,7 +32,7 @@ struct xen_memory_reservation {
     XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
-    unsigned long  nr_extents;
+    xen_ulong_t    nr_extents;
     unsigned int   extent_order;
 
     /*
@@ -90,7 +90,7 @@ struct xen_memory_exchange {
      *     command will be non-zero.
      *  5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
      */
-    unsigned long nr_exchanged;
+    xen_ulong_t nr_exchanged;
 };
 typedef struct xen_memory_exchange xen_memory_exchange_t;
 DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
@@ -148,8 +148,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn
  */
 #define XENMEM_machphys_mapping     12
 struct xen_machphys_mapping {
-    unsigned long v_start, v_end; /* Start and end virtual addresses.   */
-    unsigned long max_mfn;        /* Maximum MFN that can be looked up. */
+    xen_ulong_t v_start, v_end; /* Start and end virtual addresses.   */
+    xen_ulong_t max_mfn;        /* Maximum MFN that can be looked up. */
 };
 typedef struct xen_machphys_mapping xen_machphys_mapping_t;
 DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
@@ -170,7 +170,7 @@ struct xen_add_to_physmap {
     unsigned int space;
 
     /* Index into source mapping space. */
-    unsigned long idx;
+    xen_ulong_t idx;
 
     /* GPFN where the source mapping page should appear. */
     xen_pfn_t     gpfn;
@@ -188,7 +188,7 @@ struct xen_translate_gpfn_list {
     domid_t domid;
 
     /* Length of list. */
-    unsigned long nr_gpfns;
+    xen_ulong_t nr_gpfns;
 
     /* List of GPFNs to translate. */
     XEN_GUEST_HANDLE(xen_pfn_t) gpfn_list;
diff -r 4b51d081378d -r 856caf975abd xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/xen/lib.h     Mon Jul 03 08:35:12 2006 +0100
@@ -8,19 +8,23 @@
 #include <xen/xmalloc.h>
 #include <xen/string.h>
 
-#define BUG() do {                                     \
-    debugtrace_dump();                                  \
-    printk("BUG at %s:%d\n", __FILE__, __LINE__);      \
-    FORCE_CRASH();                                      \
-} while ( 0 )
-
+extern void __bug(char *file, int line) __attribute__((noreturn));
+#define BUG() __bug(__FILE__, __LINE__)
 #define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
 
 /* Force a compilation error if condition is true */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
 
 #ifndef NDEBUG
-#define ASSERT(_p) { if ( !(_p) ) { printk("Assertion '%s' failed, line %d, 
file %s\n", #_p , __LINE__, __FILE__); BUG(); } }
+#define ASSERT(_p)                                                      \
+    do {                                                                \
+        if ( !(_p) )                                                    \
+        {                                                               \
+            printk("Assertion '%s' failed, line %d, file %s\n", #_p ,   \
+                   __LINE__, __FILE__);                                 \
+            BUG();                                                      \
+        }                                                               \
+    } while ( 0 )
 #else
 #define ASSERT(_p) ((void)0)
 #endif
diff -r 4b51d081378d -r 856caf975abd xen/include/xen/timer.h
--- a/xen/include/xen/timer.h   Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/xen/timer.h   Mon Jul 03 08:35:12 2006 +0100
@@ -89,6 +89,12 @@ extern void kill_timer(struct timer *tim
 extern void kill_timer(struct timer *timer);
 
 /*
+ * Process pending timers on this CPU. This should be called periodically
+ * when performing work that prevents softirqs from running in a timely manner.
+ */
+extern void process_pending_timers(void);
+
+/*
  * Bootstrap initialisation. Must be called before any other timer function.
  */
 extern void timer_init(void);
diff -r 4b51d081378d -r 856caf975abd 
patches/linux-2.6.16.13/fix-hz-suspend.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/fix-hz-suspend.patch      Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,26 @@
+diff -pruN ../pristine-linux-2.6.16.13/kernel/timer.c ./kernel/timer.c
+--- ../pristine-linux-2.6.16.13/kernel/timer.c 2006-05-02 22:38:44.000000000 
+0100
++++ ./kernel/timer.c   2006-06-29 14:34:12.788957720 +0100
+@@ -555,6 +555,22 @@ found:
+       }
+       spin_unlock(&base->t_base.lock);
+ 
++      /*
++       * It can happen that other CPUs service timer IRQs and increment
++       * jiffies, but we have not yet got a local timer tick to process
++       * the timer wheels.  In that case, the expiry time can be before
++       * jiffies, but since the high-resolution timer here is relative to
++       * jiffies, the default expression when high-resolution timers are
++       * not active,
++       *
++       *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
++       *
++       * would falsely evaluate to true.  If that is the case, just
++       * return jiffies so that we can immediately fire the local timer
++       */
++      if (time_before(expires, jiffies))
++              return jiffies;
++
+       if (time_before(hr_expires, expires))
+               return hr_expires;
+ 
diff -r 4b51d081378d -r 856caf975abd 
patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch   Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,1546 @@
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c 
./drivers/char/tpm/tpm_atmel.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c   2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_atmel.c     2006-06-26 18:16:33.000000000 -0400
+@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
+               return -EIO;
+ 
+       for (i = 0; i < 6; i++) {
+-              status = ioread8(chip->vendor->iobase + 1);
++              status = ioread8(chip->vendor.iobase + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(chip->dev, "error reading header\n");
+                       return -EIO;
+               }
+-              *buf++ = ioread8(chip->vendor->iobase);
++              *buf++ = ioread8(chip->vendor.iobase);
+       }
+ 
+       /* size of the data received */
+@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
+               dev_err(chip->dev,
+                       "Recv size(%d) less than available space\n", size);
+               for (; i < size; i++) { /* clear the waiting data anyway */
+-                      status = ioread8(chip->vendor->iobase + 1);
++                      status = ioread8(chip->vendor.iobase + 1);
+                       if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                               dev_err(chip->dev, "error reading data\n");
+                               return -EIO;
+@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
+ 
+       /* read all the data available */
+       for (; i < size; i++) {
+-              status = ioread8(chip->vendor->iobase + 1);
++              status = ioread8(chip->vendor.iobase + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(chip->dev, "error reading data\n");
+                       return -EIO;
+               }
+-              *buf++ = ioread8(chip->vendor->iobase);
++              *buf++ = ioread8(chip->vendor.iobase);
+       }
+ 
+       /* make sure data available is gone */
+-      status = ioread8(chip->vendor->iobase + 1);
++      status = ioread8(chip->vendor.iobase + 1);
+ 
+       if (status & ATML_STATUS_DATA_AVAIL) {
+               dev_err(chip->dev, "data available is stuck\n");
+@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
+       dev_dbg(chip->dev, "tpm_atml_send:\n");
+       for (i = 0; i < count; i++) {
+               dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
+-              iowrite8(buf[i], chip->vendor->iobase);
++              iowrite8(buf[i], chip->vendor.iobase);
+       }
+ 
+       return count;
+@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
+ 
+ static void tpm_atml_cancel(struct tpm_chip *chip)
+ {
+-      iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
++      iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
+ }
+ 
+ static u8 tpm_atml_status(struct tpm_chip *chip)
+ {
+-      return ioread8(chip->vendor->iobase + 1);
++      return ioread8(chip->vendor.iobase + 1);
+ }
+ 
+ static struct file_operations atmel_ops = {
+@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
+ 
+ static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
+ 
+-static struct tpm_vendor_specific tpm_atmel = {
++static const struct tpm_vendor_specific tpm_atmel = {
+       .recv = tpm_atml_recv,
+       .send = tpm_atml_send,
+       .cancel = tpm_atml_cancel,
+@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
+       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+ 
+       if (chip) {
+-              if (chip->vendor->have_region)
+-                      atmel_release_region(chip->vendor->base,
+-                                           chip->vendor->region_size);
+-              atmel_put_base_addr(chip->vendor);
++              if (chip->vendor.have_region)
++                      atmel_release_region(chip->vendor.base,
++                                           chip->vendor.region_size);
++              atmel_put_base_addr(chip->vendor.iobase);
+               tpm_remove_hardware(chip->dev);
+               platform_device_unregister(pdev);
+       }
+@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
+ static int __init init_atmel(void)
+ {
+       int rc = 0;
++      void __iomem *iobase = NULL;
++      int have_region, region_size;
++      unsigned long base;
++      struct  tpm_chip *chip;
+ 
+       driver_register(&atml_drv);
+ 
+-      if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
++      if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
+               rc = -ENODEV;
+               goto err_unreg_drv;
+       }
+ 
+-      tpm_atmel.have_region =
++      have_region =
+           (atmel_request_region
+-           (tpm_atmel.base, tpm_atmel.region_size,
+-            "tpm_atmel0") == NULL) ? 0 : 1;
++           (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
++
+ 
+       if (IS_ERR
+           (pdev =
+@@ -199,17 +203,25 @@ static int __init init_atmel(void)
+               goto err_rel_reg;
+       }
+ 
+-      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
++      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
++              rc = -ENODEV;
+               goto err_unreg_dev;
++      }
++
++      chip->vendor.iobase = iobase;
++      chip->vendor.base = base;
++      chip->vendor.have_region = have_region;
++      chip->vendor.region_size = region_size;
++
+       return 0;
+ 
+ err_unreg_dev:
+       platform_device_unregister(pdev);
+ err_rel_reg:
+-      atmel_put_base_addr(&tpm_atmel);
+-      if (tpm_atmel.have_region)
+-              atmel_release_region(tpm_atmel.base,
+-                                   tpm_atmel.region_size);
++      atmel_put_base_addr(iobase);
++      if (have_region)
++              atmel_release_region(base,
++                                   region_size);
+ err_unreg_drv:
+       driver_unregister(&atml_drv);
+       return rc;
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h 
./drivers/char/tpm/tpm_atmel.h
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h   2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_atmel.h     2006-06-26 18:16:33.000000000 -0400
+@@ -28,13 +28,12 @@
+ #define atmel_request_region request_mem_region
+ #define atmel_release_region release_mem_region
+ 
+-static inline void atmel_put_base_addr(struct tpm_vendor_specific
+-                                       *vendor)
++static inline void atmel_put_base_addr(void __iomem *iobase)
+ {
+-      iounmap(vendor->iobase);
++      iounmap(iobase);
+ }
+ 
+-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
++static void __iomem * atmel_get_base_addr(unsigned long *base, int 
*region_size)
+ {
+       struct device_node *dn;
+       unsigned long address, size;
+@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
+       else
+               size = reg[naddrc];
+ 
+-      vendor->base = address;
+-      vendor->region_size = size;
+-      return ioremap(vendor->base, vendor->region_size);
++      *base = address;
++      *region_size = size;
++      return ioremap(*base, *region_size);
+ }
+ #else
+ #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
+@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
+       return 0;
+ }
+ 
+-static inline void atmel_put_base_addr(struct tpm_vendor_specific
+-                                       *vendor)
++static inline void atmel_put_base_addr(void __iomem *iobase)
+ {
+ }
+ 
+ /* Determine where to talk to device */
+-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
+-                                       *vendor)
++static void __iomem * atmel_get_base_addr(unsigned long *base, int 
*region_size)
+ {
+       int lo, hi;
+ 
+@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
+       lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+       hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+ 
+-      vendor->base = (hi << 8) | lo;
+-      vendor->region_size = 2;
++      *base = (hi << 8) | lo;
++      *region_size = 2;
+ 
+-      return ioport_map(vendor->base, vendor->region_size);
++      return ioport_map(*base, *region_size);
+ }
+ #endif
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c 
./drivers/char/tpm/tpm_bios.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c    2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_bios.c      2006-06-26 18:16:33.000000000 -0400
+@@ -29,6 +29,11 @@
+ #define MAX_TEXT_EVENT                1000    /* Max event string length */
+ #define ACPI_TCPA_SIG         "TCPA"  /* 0x41504354 /'TCPA' */
+ 
++enum bios_platform_class {
++      BIOS_CLIENT = 0x00,
++      BIOS_SERVER = 0x01,
++};
++
+ struct tpm_bios_log {
+       void *bios_event_log;
+       void *bios_event_log_end;
+@@ -36,9 +41,18 @@ struct tpm_bios_log {
+ 
+ struct acpi_tcpa {
+       struct acpi_table_header hdr;
+-      u16 reserved;
+-      u32 log_max_len __attribute__ ((packed));
+-      u32 log_start_addr __attribute__ ((packed));
++      u16 platform_class;
++      union {
++              struct client_hdr {
++                      u32 log_max_len __attribute__ ((packed));
++                      u64 log_start_addr __attribute__ ((packed));
++              } client;
++              struct server_hdr {
++                      u16 reserved;
++                      u64 log_max_len __attribute__ ((packed));
++                      u64 log_start_addr __attribute__ ((packed));
++              } server;
++      };
+ };
+ 
+ struct tcpa_event {
+@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
+       "Non-Host Info"
+ };
+ 
++struct tcpa_pc_event {
++      u32 event_id;
++      u32 event_size;
++      u8 event_data[0];
++};
++
+ enum tcpa_pc_event_ids {
+       SMBIOS = 1,
+       BIS_CERT,
+@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
+       NVRAM,
+       OPTION_ROM_EXEC,
+       OPTION_ROM_CONFIG,
+-      OPTION_ROM_MICROCODE,
++      OPTION_ROM_MICROCODE = 10,
+       S_CRTM_VERSION,
+       S_CRTM_CONTENTS,
+       POST_CONTENTS,
++      HOST_TABLE_OF_DEVICES,
+ };
+ 
+ static const char* tcpa_pc_event_id_strings[] = {
+-      ""
++      "",
+       "SMBIOS",
+       "BIS Certificate",
+       "POST BIOS ",
+@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
+       "NVRAM",
+       "Option ROM",
+       "Option ROM config",
+-      "Option ROM microcode",
++      "",
++      "Option ROM microcode ",
+       "S-CRTM Version",
+-      "S-CRTM Contents",
+-      "S-CRTM POST Contents",
++      "S-CRTM Contents ",
++      "POST Contents ",
++      "Table of Devices",
+ };
+ 
+ /* returns pointer to start of pos. entry of tcg log */
+@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
+       const char *name = "";
+       char data[40] = "";
+       int i, n_len = 0, d_len = 0;
+-      u32 event_id;
++      struct tcpa_pc_event *pc_event;
+ 
+       switch(event->event_type) {
+       case PREBOOT:
+@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
+               }
+               break;
+       case EVENT_TAG:
+-              event_id = be32_to_cpu(*((u32 *)event_entry));
++              pc_event = (struct tcpa_pc_event *)event_entry;
+ 
+               /* ToDo Row data -> Base64 */
+ 
+-              switch (event_id) {
++              switch (pc_event->event_id) {
+               case SMBIOS:
+               case BIS_CERT:
+               case CMOS:
+               case NVRAM:
+               case OPTION_ROM_EXEC:
+               case OPTION_ROM_CONFIG:
+-              case OPTION_ROM_MICROCODE:
+               case S_CRTM_VERSION:
+-              case S_CRTM_CONTENTS:
+-              case POST_CONTENTS:
+-                      name = tcpa_pc_event_id_strings[event_id];
++                      name = tcpa_pc_event_id_strings[pc_event->event_id];
+                       n_len = strlen(name);
+                       break;
++              /* hash data */
+               case POST_BIOS_ROM:
+               case ESCD:
+-                      name = tcpa_pc_event_id_strings[event_id];
++              case OPTION_ROM_MICROCODE:
++              case S_CRTM_CONTENTS:
++              case POST_CONTENTS:
++                      name = tcpa_pc_event_id_strings[pc_event->event_id];
+                       n_len = strlen(name);
+                       for (i = 0; i < 20; i++)
+-                              d_len += sprintf(data, "%02x",
+-                                              event_entry[8 + i]);
++                              d_len += sprintf(&data[2*i], "%02x",
++                                              pc_event->event_data[i]);
+                       break;
+               default:
+                       break;
+@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
+ 
+ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
+ {
++      struct tcpa_event *event = v;
++      char *data = v;
++      int i;
+ 
+-      char *eventname;
+-      char data[4];
+-      u32 help;
+-      int i, len;
+-      struct tcpa_event *event = (struct tcpa_event *) v;
+-      unsigned char *event_entry =
+-          (unsigned char *) (v + sizeof(struct tcpa_event));
+-
+-      eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
+-      if (!eventname) {
+-              printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
+-                     __func__);
+-              return -ENOMEM;
+-      }
+-
+-      /* 1st: PCR used is in little-endian format (4 bytes) */
+-      help = le32_to_cpu(event->pcr_index);
+-      memcpy(data, &help, 4);
+-      for (i = 0; i < 4; i++)
+-              seq_putc(m, data[i]);
+-
+-      /* 2nd: SHA1 (20 bytes) */
+-      for (i = 0; i < 20; i++)
+-              seq_putc(m, event->pcr_value[i]);
+-
+-      /* 3rd: event type identifier (4 bytes) */
+-      help = le32_to_cpu(event->event_type);
+-      memcpy(data, &help, 4);
+-      for (i = 0; i < 4; i++)
++      for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
+               seq_putc(m, data[i]);
+ 
+-      len = 0;
+-
+-      len += get_event_name(eventname, event, event_entry);
+-
+-      /* 4th:  filename <= 255 + \'0' delimiter */
+-      if (len > TCG_EVENT_NAME_LEN_MAX)
+-              len = TCG_EVENT_NAME_LEN_MAX;
+-
+-      for (i = 0; i < len; i++)
+-              seq_putc(m, eventname[i]);
+-
+-      /* 5th: delimiter */
+-      seq_putc(m, '\0');
+-
+       return 0;
+ }
+ 
+@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
+       /* 4th: eventname <= max + \'0' delimiter */
+       seq_printf(m, " %s\n", eventname);
+ 
++      kfree(eventname);
+       return 0;
+ }
+ 
+@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
+       struct acpi_tcpa *buff;
+       acpi_status status;
+       struct acpi_table_header *virt;
++      u64 len, start;
+ 
+       if (log->bios_event_log != NULL) {
+               printk(KERN_ERR
+@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
+               return -EIO;
+       }
+ 
+-      if (buff->log_max_len == 0) {
++      switch(buff->platform_class) {
++      case BIOS_SERVER:
++              len = buff->server.log_max_len;
++              start = buff->server.log_start_addr;
++              break;
++      case BIOS_CLIENT:
++      default:
++              len = buff->client.log_max_len;
++              start = buff->client.log_start_addr;
++              break;
++      }
++      if (!len) {
+               printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
+               return -EIO;
+       }
+ 
+       /* malloc EventLog space */
+-      log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
++      log->bios_event_log = kmalloc(len, GFP_KERNEL);
+       if (!log->bios_event_log) {
+-              printk
+-                  ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
+-                   __func__);
++              printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
++                      __func__);
+               return -ENOMEM;
+       }
+ 
+-      log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
++      log->bios_event_log_end = log->bios_event_log + len;
+ 
+-      acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) 
&virt);
++      acpi_os_map_memory(start, len, (void *) &virt);
+ 
+-      memcpy(log->bios_event_log, virt, buff->log_max_len);
++      memcpy(log->bios_event_log, virt, len);
+ 
+-      acpi_os_unmap_memory(virt, buff->log_max_len);
++      acpi_os_unmap_memory(virt, len);
+       return 0;
+ }
+ 
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c 
./drivers/char/tpm/tpm_infineon.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c        
2006-06-26 18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_infineon.c  2006-06-26 18:16:33.000000000 -0400
+@@ -15,6 +15,7 @@
+  * License.
+  */
+ 
++#include <linux/init.h>
+ #include <linux/pnp.h>
+ #include "tpm.h"
+ 
+@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
+ 
+       if (clear_wrfifo) {
+               for (i = 0; i < 4096; i++) {
+-                      status = inb(chip->vendor->base + WRFIFO);
++                      status = inb(chip->vendor.base + WRFIFO);
+                       if (status == 0xff) {
+                               if (check == 5)
+                                       break;
+@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
+        */
+       i = 0;
+       do {
+-              status = inb(chip->vendor->base + RDFIFO);
+-              status = inb(chip->vendor->base + STAT);
++              status = inb(chip->vendor.base + RDFIFO);
++              status = inb(chip->vendor.base + STAT);
+               i++;
+               if (i == TPM_MAX_TRIES)
+                       return -EIO;
+@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
+       int status;
+       int i;
+       for (i = 0; i < TPM_MAX_TRIES; i++) {
+-              status = inb(chip->vendor->base + STAT);
++              status = inb(chip->vendor.base + STAT);
+               /* check the status-register if wait_for_bit is set */
+               if (status & 1 << wait_for_bit)
+                       break;
+@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
+ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
+ {
+       wait(chip, STAT_XFE);
+-      outb(sendbyte, chip->vendor->base + WRFIFO);
++      outb(sendbyte, chip->vendor.base + WRFIFO);
+ }
+ 
+     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
+@@ -204,7 +205,7 @@ recv_begin:
+               ret = wait(chip, STAT_RDA);
+               if (ret)
+                       return -EIO;
+-              buf[i] = inb(chip->vendor->base + RDFIFO);
++              buf[i] = inb(chip->vendor.base + RDFIFO);
+       }
+ 
+       if (buf[0] != TPM_VL_VER) {
+@@ -219,7 +220,7 @@ recv_begin:
+ 
+               for (i = 0; i < size; i++) {
+                       wait(chip, STAT_RDA);
+-                      buf[i] = inb(chip->vendor->base + RDFIFO);
++                      buf[i] = inb(chip->vendor.base + RDFIFO);
+               }
+ 
+               if ((size == 0x6D00) && (buf[1] == 0x80)) {
+@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
+       u8 count_high, count_low, count_4, count_3, count_2, count_1;
+ 
+       /* Disabling Reset, LP and IRQC */
+-      outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
++      outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
+ 
+       ret = empty_fifo(chip, 1);
+       if (ret) {
+@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
+ 
+ static u8 tpm_inf_status(struct tpm_chip *chip)
+ {
+-      return inb(chip->vendor->base + STAT);
++      return inb(chip->vendor.base + STAT);
+ }
+ 
+ static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
+       .release = tpm_release,
+ };
+ 
+-static struct tpm_vendor_specific tpm_inf = {
++static const struct tpm_vendor_specific tpm_inf = {
+       .recv = tpm_inf_recv,
+       .send = tpm_inf_send,
+       .cancel = tpm_inf_cancel,
+@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
+       int version[2];
+       int productid[2];
+       char chipname[20];
++      struct tpm_chip *chip;
+ 
+       /* read IO-ports through PnP */
+       if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
+                       goto err_last;
+               }
+               /* publish my base address and request region */
+-              tpm_inf.base = TPM_INF_BASE;
+               if (request_region
+-                  (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
++                  (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+                       rc = -EINVAL;
+                       goto err_last;
+               }
+-              if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
+-                              "tpm_infineon0") == NULL) {
++              if (request_region
++                  (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
+                       rc = -EINVAL;
+                       goto err_last;
+               }
+@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
+ 
+               /* configure TPM with IO-ports */
+               outb(IOLIMH, TPM_INF_ADDR);
+-              outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
++              outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
+               outb(IOLIML, TPM_INF_ADDR);
+-              outb((tpm_inf.base & 0xff), TPM_INF_DATA);
++              outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
+ 
+               /* control if IO-ports are set correctly */
+               outb(IOLIMH, TPM_INF_ADDR);
+@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
+               outb(IOLIML, TPM_INF_ADDR);
+               iol = inb(TPM_INF_DATA);
+ 
+-              if ((ioh << 8 | iol) != tpm_inf.base) {
++              if ((ioh << 8 | iol) != TPM_INF_BASE) {
+                       dev_err(&dev->dev,
+-                              "Could not set IO-ports to 0x%lx\n",
+-                              tpm_inf.base);
++                              "Could not set IO-ports to 0x%x\n",
++                              TPM_INF_BASE);
+                       rc = -EIO;
+                       goto err_release_region;
+               }
+@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
+               outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+ 
+               /* disable RESET, LP and IRQC */
+-              outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
++              outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
+ 
+               /* Finally, we're done, print some infos */
+               dev_info(&dev->dev, "TPM found: "
+                        "config base 0x%x, "
+                        "io base 0x%x, "
+-                       "chip version %02x%02x, "
+-                       "vendor id %x%x (Infineon), "
+-                       "product id %02x%02x"
++                       "chip version 0x%02x%02x, "
++                       "vendor id 0x%x%x (Infineon), "
++                       "product id 0x%02x%02x"
+                        "%s\n",
+                        TPM_INF_ADDR,
+                        TPM_INF_BASE,
+@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
+                        vendorid[0], vendorid[1],
+                        productid[0], productid[1], chipname);
+ 
+-              rc = tpm_register_hardware(&dev->dev, &tpm_inf);
+-              if (rc < 0) {
+-                      rc = -ENODEV;
++              if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
+                       goto err_release_region;
+               }
++              chip->vendor.base = TPM_INF_BASE;
+               return 0;
+       } else {
+               rc = -ENODEV;
+@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
+       }
+ 
+ err_release_region:
+-      release_region(tpm_inf.base, TPM_INF_PORT_LEN);
++      release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
+       release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+ 
+ err_last:
+@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
+       struct tpm_chip *chip = pnp_get_drvdata(dev);
+ 
+       if (chip) {
+-              release_region(chip->vendor->base, TPM_INF_PORT_LEN);
++              release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
++              release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+               tpm_remove_hardware(chip->dev);
+       }
+ }
+@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
+       },
+       .id_table = tpm_pnp_tbl,
+       .probe = tpm_inf_pnp_probe,
+-      .remove = tpm_inf_pnp_remove,
++      .remove = __devexit_p(tpm_inf_pnp_remove),
+ };
+ 
+ static int __init init_inf(void)
+@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
+ 
+ MODULE_AUTHOR("Marcel Selhorst <selhorst@xxxxxxxxxxxxx>");
+ MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 
1.2");
+-MODULE_VERSION("1.7");
++MODULE_VERSION("1.8");
+ MODULE_LICENSE("GPL");
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c 
./drivers/char/tpm/tpm_nsc.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c     2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_nsc.c       2006-06-26 18:16:33.000000000 -0400
+@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
+       unsigned long stop;
+ 
+       /* status immediately available check */
+-      *data = inb(chip->vendor->base + NSC_STATUS);
++      *data = inb(chip->vendor.base + NSC_STATUS);
+       if ((*data & mask) == val)
+               return 0;
+ 
+@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
+       stop = jiffies + 10 * HZ;
+       do {
+               msleep(TPM_TIMEOUT);
+-              *data = inb(chip->vendor->base + 1);
++              *data = inb(chip->vendor.base + 1);
+               if ((*data & mask) == val)
+                       return 0;
+       }
+@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
+       unsigned long stop;
+ 
+       /* status immediately available check */
+-      status = inb(chip->vendor->base + NSC_STATUS);
++      status = inb(chip->vendor.base + NSC_STATUS);
+       if (status & NSC_STATUS_OBF)
+-              status = inb(chip->vendor->base + NSC_DATA);
++              status = inb(chip->vendor.base + NSC_DATA);
+       if (status & NSC_STATUS_RDY)
+               return 0;
+ 
+@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
+       stop = jiffies + 100;
+       do {
+               msleep(TPM_TIMEOUT);
+-              status = inb(chip->vendor->base + NSC_STATUS);
++              status = inb(chip->vendor.base + NSC_STATUS);
+               if (status & NSC_STATUS_OBF)
+-                      status = inb(chip->vendor->base + NSC_DATA);
++                      status = inb(chip->vendor.base + NSC_DATA);
+               if (status & NSC_STATUS_RDY)
+                       return 0;
+       }
+@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+               return -EIO;
+       }
+       if ((data =
+-           inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
++           inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+               dev_err(chip->dev, "not in normal mode (0x%x)\n",
+                       data);
+               return -EIO;
+@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+               }
+               if (data & NSC_STATUS_F0)
+                       break;
+-              *p = inb(chip->vendor->base + NSC_DATA);
++              *p = inb(chip->vendor.base + NSC_DATA);
+       }
+ 
+       if ((data & NSC_STATUS_F0) == 0 &&
+@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+               dev_err(chip->dev, "F0 not set\n");
+               return -EIO;
+       }
+-      if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
++      if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
+               dev_err(chip->dev,
+                       "expected end of command(0x%x)\n", data);
+               return -EIO;
+@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
+        * fix it. Not sure why this is needed, we followed the flow
+        * chart in the manual to the letter.
+        */
+-      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
+ 
+       if (nsc_wait_for_ready(chip) != 0)
+               return -EIO;
+@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
+               return -EIO;
+       }
+ 
+-      outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
+       if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
+               dev_err(chip->dev, "IBR timeout\n");
+               return -EIO;
+@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
+                               "IBF timeout (while writing data)\n");
+                       return -EIO;
+               }
+-              outb(buf[i], chip->vendor->base + NSC_DATA);
++              outb(buf[i], chip->vendor.base + NSC_DATA);
+       }
+ 
+       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+               dev_err(chip->dev, "IBF timeout\n");
+               return -EIO;
+       }
+-      outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
+ 
+       return count;
+ }
+ 
+ static void tpm_nsc_cancel(struct tpm_chip *chip)
+ {
+-      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
+ }
+ 
+ static u8 tpm_nsc_status(struct tpm_chip *chip)
+ {
+-      return inb(chip->vendor->base + NSC_STATUS);
++      return inb(chip->vendor.base + NSC_STATUS);
+ }
+ 
+ static struct file_operations nsc_ops = {
+@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
+ 
+ static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
+ 
+-static struct tpm_vendor_specific tpm_nsc = {
++static const struct tpm_vendor_specific tpm_nsc = {
+       .recv = tpm_nsc_recv,
+       .send = tpm_nsc_send,
+       .cancel = tpm_nsc_cancel,
+@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
+ {
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if ( chip ) {
+-              release_region(chip->vendor->base, 2);
++              release_region(chip->vendor.base, 2);
+               tpm_remove_hardware(chip->dev);
+       }
+ }
+@@ -286,7 +286,8 @@ static int __init init_nsc(void)
+       int rc = 0;
+       int lo, hi;
+       int nscAddrBase = TPM_ADDR;
+-
++      struct tpm_chip *chip;
++      unsigned long base;
+ 
+       /* verify that it is a National part (SID) */
+       if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+@@ -300,7 +301,7 @@ static int __init init_nsc(void)
+ 
+       hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+       lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+-      tpm_nsc.base = (hi<<8) | lo;
++      base = (hi<<8) | lo;
+ 
+       /* enable the DPM module */
+       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+@@ -320,13 +321,15 @@ static int __init init_nsc(void)
+       if ((rc = platform_device_register(pdev)) < 0)
+               goto err_free_dev;
+ 
+-      if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
++      if (request_region(base, 2, "tpm_nsc0") == NULL ) {
+               rc = -EBUSY;
+               goto err_unreg_dev;
+       }
+ 
+-      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
++      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
++              rc = -ENODEV;
+               goto err_rel_reg;
++      }
+ 
+       dev_dbg(&pdev->dev, "NSC TPM detected\n");
+       dev_dbg(&pdev->dev,
+@@ -361,10 +364,12 @@ static int __init init_nsc(void)
+                "NSC TPM revision %d\n",
+                tpm_read_index(nscAddrBase, 0x27) & 0x1F);
+ 
++      chip->vendor.base = base;
++
+       return 0;
+ 
+ err_rel_reg:
+-      release_region(tpm_nsc.base, 2);
++      release_region(base, 2);
+ err_unreg_dev:
+       platform_device_unregister(pdev);
+ err_free_dev:
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c 
./drivers/char/tpm/tpm_tis.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c     1969-12-31 
19:00:00.000000000 -0500
++++ ./drivers/char/tpm/tpm_tis.c       2006-06-26 18:16:33.000000000 -0400
+@@ -0,0 +1,665 @@
++/*
++ * Copyright (C) 2005, 2006 IBM Corporation
++ *
++ * Authors:
++ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
++ * Kylene Hall <kjhall@xxxxxxxxxx>
++ *
++ * Device driver for TCG/TCPA TPM (trusted platform module).
++ * Specifications at www.trustedcomputinggroup.org
++ *
++ * This device driver implements the TPM interface as defined in
++ * the TCG TPM Interface Spec version 1.2, revision 1.0.
++ *
++ * 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.
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pnp.h>
++#include <linux/interrupt.h>
++#include <linux/wait.h>
++#include "tpm.h"
++
++#define TPM_HEADER_SIZE 10
++
++enum tis_access {
++      TPM_ACCESS_VALID = 0x80,
++      TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
++      TPM_ACCESS_REQUEST_PENDING = 0x04,
++      TPM_ACCESS_REQUEST_USE = 0x02,
++};
++
++enum tis_status {
++      TPM_STS_VALID = 0x80,
++      TPM_STS_COMMAND_READY = 0x40,
++      TPM_STS_GO = 0x20,
++      TPM_STS_DATA_AVAIL = 0x10,
++      TPM_STS_DATA_EXPECT = 0x08,
++};
++
++enum tis_int_flags {
++      TPM_GLOBAL_INT_ENABLE = 0x80000000,
++      TPM_INTF_BURST_COUNT_STATIC = 0x100,
++      TPM_INTF_CMD_READY_INT = 0x080,
++      TPM_INTF_INT_EDGE_FALLING = 0x040,
++      TPM_INTF_INT_EDGE_RISING = 0x020,
++      TPM_INTF_INT_LEVEL_LOW = 0x010,
++      TPM_INTF_INT_LEVEL_HIGH = 0x008,
++      TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
++      TPM_INTF_STS_VALID_INT = 0x002,
++      TPM_INTF_DATA_AVAIL_INT = 0x001,
++};
++
++enum tis_defaults {
++      TIS_MEM_BASE = 0xFED40000,
++      TIS_MEM_LEN = 0x5000,
++      TIS_SHORT_TIMEOUT = 750,        /* ms */
++      TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
++};
++
++#define       TPM_ACCESS(l)                   (0x0000 | ((l) << 12))
++#define       TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
++#define       TPM_INT_VECTOR(l)               (0x000C | ((l) << 12))
++#define       TPM_INT_STATUS(l)               (0x0010 | ((l) << 12))
++#define       TPM_INTF_CAPS(l)                (0x0014 | ((l) << 12))
++#define       TPM_STS(l)                      (0x0018 | ((l) << 12))
++#define       TPM_DATA_FIFO(l)                (0x0024 | ((l) << 12))
++
++#define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
++#define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
++
++static LIST_HEAD(tis_chips);
++static DEFINE_SPINLOCK(tis_lock);
++
++static int check_locality(struct tpm_chip *chip, int l)
++{
++      if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
++           (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
++          (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
++              return chip->vendor.locality = l;
++
++      return -1;
++}
++
++static void release_locality(struct tpm_chip *chip, int l, int force)
++{
++      if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
++                    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
++          (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
++              iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
++                       chip->vendor.iobase + TPM_ACCESS(l));
++}
++
++static int request_locality(struct tpm_chip *chip, int l)
++{
++      unsigned long stop;
++      long rc;
++
++      if (check_locality(chip, l) >= 0)
++              return l;
++
++      iowrite8(TPM_ACCESS_REQUEST_USE,
++               chip->vendor.iobase + TPM_ACCESS(l));
++
++      if (chip->vendor.irq) {
++              rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
++                                                    (check_locality
++                                                     (chip, l) >= 0),
++                                                    chip->vendor.timeout_a);
++              if (rc > 0)
++                      return l;
++
++      } else {
++              /* wait for burstcount */
++              stop = jiffies + chip->vendor.timeout_a;
++              do {
++                      if (check_locality(chip, l) >= 0)
++                              return l;
++                      msleep(TPM_TIMEOUT);
++              }
++              while (time_before(jiffies, stop));
++      }
++      return -1;
++}
++
++static u8 tpm_tis_status(struct tpm_chip *chip)
++{
++      return ioread8(chip->vendor.iobase +
++                     TPM_STS(chip->vendor.locality));
++}
++
++static void tpm_tis_ready(struct tpm_chip *chip)
++{
++      /* this causes the current command to be aborted */
++      iowrite8(TPM_STS_COMMAND_READY,
++               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
++}
++
++static int get_burstcount(struct tpm_chip *chip)
++{
++      unsigned long stop;
++      int burstcnt;
++
++      /* wait for burstcount */
++      /* which timeout value, spec has 2 answers (c & d) */
++      stop = jiffies + chip->vendor.timeout_d;
++      do {
++              burstcnt = ioread8(chip->vendor.iobase +
++                                 TPM_STS(chip->vendor.locality) + 1);
++              burstcnt += ioread8(chip->vendor.iobase +
++                                  TPM_STS(chip->vendor.locality) +
++                                  2) << 8;
++              if (burstcnt)
++                      return burstcnt;
++              msleep(TPM_TIMEOUT);
++      } while (time_before(jiffies, stop));
++      return -EBUSY;
++}
++
++static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long 
timeout,
++                       wait_queue_head_t *queue)
++{
++      unsigned long stop;
++      long rc;
++      u8 status;
++
++      /* check current status */
++      status = tpm_tis_status(chip);
++      if ((status & mask) == mask)
++              return 0;
++
++      if (chip->vendor.irq) {
++              rc = wait_event_interruptible_timeout(*queue,
++                                                    ((tpm_tis_status
++                                                      (chip) & mask) ==
++                                                     mask), timeout);
++              if (rc > 0)
++                      return 0;
++      } else {
++              stop = jiffies + timeout;
++              do {
++                      msleep(TPM_TIMEOUT);
++                      status = tpm_tis_status(chip);
++                      if ((status & mask) == mask)
++                              return 0;
++              } while (time_before(jiffies, stop));
++      }
++      return -ETIME;
++}
++
++static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
++{
++      int size = 0, burstcnt;
++      while (size < count &&
++             wait_for_stat(chip,
++                           TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++                           chip->vendor.timeout_c,
++                           &chip->vendor.read_queue)
++             == 0) {
++              burstcnt = get_burstcount(chip);
++              for (; burstcnt > 0 && size < count; burstcnt--)
++                      buf[size++] = ioread8(chip->vendor.iobase +
++                                            TPM_DATA_FIFO(chip->vendor.
++                                                          locality));
++      }
++      return size;
++}
++
++static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
++{
++      int size = 0;
++      int expected, status;
++
++      if (count < TPM_HEADER_SIZE) {
++              size = -EIO;
++              goto out;
++      }
++
++      /* read first 10 bytes, including tag, paramsize, and result */
++      if ((size =
++           recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
++              dev_err(chip->dev, "Unable to read header\n");
++              goto out;
++      }
++
++      expected = be32_to_cpu(*(__be32 *) (buf + 2));
++      if (expected > count) {
++              size = -EIO;
++              goto out;
++      }
++
++      if ((size +=
++           recv_data(chip, &buf[TPM_HEADER_SIZE],
++                     expected - TPM_HEADER_SIZE)) < expected) {
++              dev_err(chip->dev, "Unable to read remainder of result\n");
++              size = -ETIME;
++              goto out;
++      }
++
++      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
++                    &chip->vendor.int_queue);
++      status = tpm_tis_status(chip);
++      if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
++              dev_err(chip->dev, "Error left over data\n");
++              size = -EIO;
++              goto out;
++      }
++
++out:
++      tpm_tis_ready(chip);
++      release_locality(chip, chip->vendor.locality, 0);
++      return size;
++}
++
++/*
++ * If interrupts are used (signaled by an irq set in the vendor structure)
++ * tpm.c can skip polling for the data to be available as the interrupt is
++ * waited for here
++ */
++static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
++{
++      int rc, status, burstcnt;
++      size_t count = 0;
++      u32 ordinal;
++
++      if (request_locality(chip, 0) < 0)
++              return -EBUSY;
++
++      status = tpm_tis_status(chip);
++      if ((status & TPM_STS_COMMAND_READY) == 0) {
++              tpm_tis_ready(chip);
++              if (wait_for_stat
++                  (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
++                   &chip->vendor.int_queue) < 0) {
++                      rc = -ETIME;
++                      goto out_err;
++              }
++      }
++
++      while (count < len - 1) {
++              burstcnt = get_burstcount(chip);
++              for (; burstcnt > 0 && count < len - 1; burstcnt--) {
++                      iowrite8(buf[count], chip->vendor.iobase +
++                               TPM_DATA_FIFO(chip->vendor.locality));
++                      count++;
++              }
++
++              wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
++                            &chip->vendor.int_queue);
++              status = tpm_tis_status(chip);
++              if ((status & TPM_STS_DATA_EXPECT) == 0) {
++                      rc = -EIO;
++                      goto out_err;
++              }
++      }
++
++      /* write last byte */
++      iowrite8(buf[count],
++               chip->vendor.iobase +
++               TPM_DATA_FIFO(chip->vendor.locality));
++      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
++                    &chip->vendor.int_queue);
++      status = tpm_tis_status(chip);
++      if ((status & TPM_STS_DATA_EXPECT) != 0) {
++              rc = -EIO;
++              goto out_err;
++      }
++
++      /* go and do it */
++      iowrite8(TPM_STS_GO,
++               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
++
++      if (chip->vendor.irq) {
++              ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
++              if (wait_for_stat
++                  (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++                   tpm_calc_ordinal_duration(chip, ordinal),
++                   &chip->vendor.read_queue) < 0) {
++                      rc = -ETIME;
++                      goto out_err;
++              }
++      }
++      return len;
++out_err:
++      tpm_tis_ready(chip);
++      release_locality(chip, chip->vendor.locality, 0);
++      return rc;
++}
++
++static struct file_operations tis_ops = {
++      .owner = THIS_MODULE,
++      .llseek = no_llseek,
++      .open = tpm_open,
++      .read = tpm_read,
++      .write = tpm_write,
++      .release = tpm_release,
++};
++
++static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
++static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
++static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
++static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
++static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
++static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
++                 NULL);
++static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
++static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
++
++static struct attribute *tis_attrs[] = {
++      &dev_attr_pubek.attr,
++      &dev_attr_pcrs.attr,
++      &dev_attr_enabled.attr,
++      &dev_attr_active.attr,
++      &dev_attr_owned.attr,
++      &dev_attr_temp_deactivated.attr,
++      &dev_attr_caps.attr,
++      &dev_attr_cancel.attr, NULL,
++};
++
++static struct attribute_group tis_attr_grp = {
++      .attrs = tis_attrs
++};
++
++static struct tpm_vendor_specific tpm_tis = {
++      .status = tpm_tis_status,
++      .recv = tpm_tis_recv,
++      .send = tpm_tis_send,
++      .cancel = tpm_tis_ready,
++      .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++      .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++      .req_canceled = TPM_STS_COMMAND_READY,
++      .attr_group = &tis_attr_grp,
++      .miscdev = {
++                  .fops = &tis_ops,},
++};
++
++static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
++      u32 interrupt;
++
++      interrupt = ioread32(chip->vendor.iobase +
++                           TPM_INT_STATUS(chip->vendor.locality));
++
++      if (interrupt == 0)
++              return IRQ_NONE;
++
++      chip->vendor.irq = irq;
++
++      /* Clear interrupts handled with TPM_EOI */
++      iowrite32(interrupt,
++                chip->vendor.iobase +
++                TPM_INT_STATUS(chip->vendor.locality));
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs 
*regs)
++{
++      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
++      u32 interrupt;
++      int i;
++
++      interrupt = ioread32(chip->vendor.iobase +
++                           TPM_INT_STATUS(chip->vendor.locality));
++
++      if (interrupt == 0)
++              return IRQ_NONE;
++
++      if (interrupt & TPM_INTF_DATA_AVAIL_INT)
++              wake_up_interruptible(&chip->vendor.read_queue);
++      if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
++              for (i = 0; i < 5; i++)
++                      if (check_locality(chip, i) >= 0)
++                              break;
++      if (interrupt &
++          (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
++           TPM_INTF_CMD_READY_INT))
++              wake_up_interruptible(&chip->vendor.int_queue);
++
++      /* Clear interrupts handled with TPM_EOI */
++      iowrite32(interrupt,
++                chip->vendor.iobase +
++                TPM_INT_STATUS(chip->vendor.locality));
++      return IRQ_HANDLED;
++}
++
++static int interrupts = 1;
++module_param(interrupts, bool, 0444);
++MODULE_PARM_DESC(interrupts, "Enable interrupts");
++
++static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
++                                    const struct pnp_device_id *pnp_id)
++{
++      u32 vendor, intfcaps, intmask;
++      int rc, i;
++      unsigned long start, len;
++      struct tpm_chip *chip;
++
++      start = pnp_mem_start(pnp_dev, 0);
++      len = pnp_mem_len(pnp_dev, 0);
++
++      if (!start)
++              start = TIS_MEM_BASE;
++      if (!len)
++              len = TIS_MEM_LEN;
++
++      if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
++              return -ENODEV;
++
++      chip->vendor.iobase = ioremap(start, len);
++      if (!chip->vendor.iobase) {
++              rc = -EIO;
++              goto out_err;
++      }
++
++      vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
++
++      /* Default timeouts */
++      chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
++      chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
++      chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
++      chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
++
++      dev_info(&pnp_dev->dev,
++               "1.2 TPM (device-id 0x%X, rev-id %d)\n",
++               vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
++
++      /* Figure out the capabilities */
++      intfcaps =
++          ioread32(chip->vendor.iobase +
++                   TPM_INTF_CAPS(chip->vendor.locality));
++      dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
++              intfcaps);
++      if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
++              dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
++      if (intfcaps & TPM_INTF_CMD_READY_INT)
++              dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
++      if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
++      if (intfcaps & TPM_INTF_INT_EDGE_RISING)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
++      if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
++      if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
++      if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
++              dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
++      if (intfcaps & TPM_INTF_STS_VALID_INT)
++              dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
++      if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
++              dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
++
++      if (request_locality(chip, 0) != 0) {
++              rc = -ENODEV;
++              goto out_err;
++      }
++
++      /* INTERRUPT Setup */
++      init_waitqueue_head(&chip->vendor.read_queue);
++      init_waitqueue_head(&chip->vendor.int_queue);
++
++      intmask =
++          ioread32(chip->vendor.iobase +
++                   TPM_INT_ENABLE(chip->vendor.locality));
++
++      intmask |= TPM_INTF_CMD_READY_INT
++          | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
++          | TPM_INTF_STS_VALID_INT;
++
++      iowrite32(intmask,
++                chip->vendor.iobase +
++                TPM_INT_ENABLE(chip->vendor.locality));
++      if (interrupts) {
++              chip->vendor.irq =
++                  ioread8(chip->vendor.iobase +
++                          TPM_INT_VECTOR(chip->vendor.locality));
++
++              for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
++                      iowrite8(i, chip->vendor.iobase +
++                                  TPM_INT_VECTOR(chip->vendor.locality));
++                      if (request_irq
++                          (i, tis_int_probe, SA_SHIRQ,
++                           chip->vendor.miscdev.name, chip) != 0) {
++                              dev_info(chip->dev,
++                                       "Unable to request irq: %d for 
probe\n",
++                                       i);
++                              continue;
++                      }
++
++                      /* Clear all existing */
++                      iowrite32(ioread32
++                                (chip->vendor.iobase +
++                                 TPM_INT_STATUS(chip->vendor.locality)),
++                                chip->vendor.iobase +
++                                TPM_INT_STATUS(chip->vendor.locality));
++
++                      /* Turn on */
++                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
++                                chip->vendor.iobase +
++                                TPM_INT_ENABLE(chip->vendor.locality));
++
++                      /* Generate Interrupts */
++                      tpm_gen_interrupt(chip);
++
++                      /* Turn off */
++                      iowrite32(intmask,
++                                chip->vendor.iobase +
++                                TPM_INT_ENABLE(chip->vendor.locality));
++                      free_irq(i, chip);
++              }
++      }
++      if (chip->vendor.irq) {
++              iowrite8(chip->vendor.irq,
++                       chip->vendor.iobase +
++                       TPM_INT_VECTOR(chip->vendor.locality));
++              if (request_irq
++                  (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
++                   chip->vendor.miscdev.name, chip) != 0) {
++                      dev_info(chip->dev,
++                               "Unable to request irq: %d for use\n",
++                               chip->vendor.irq);
++                      chip->vendor.irq = 0;
++              } else {
++                      /* Clear all existing */
++                      iowrite32(ioread32
++                                (chip->vendor.iobase +
++                                 TPM_INT_STATUS(chip->vendor.locality)),
++                                chip->vendor.iobase +
++                                TPM_INT_STATUS(chip->vendor.locality));
++
++                      /* Turn on */
++                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
++                                chip->vendor.iobase +
++                                TPM_INT_ENABLE(chip->vendor.locality));
++              }
++      }
++
++      INIT_LIST_HEAD(&chip->vendor.list);
++      spin_lock(&tis_lock);
++      list_add(&chip->vendor.list, &tis_chips);
++      spin_unlock(&tis_lock);
++
++      tpm_get_timeouts(chip);
++      tpm_continue_selftest(chip);
++
++      return 0;
++out_err:
++      if (chip->vendor.iobase)
++              iounmap(chip->vendor.iobase);
++      tpm_remove_hardware(chip->dev);
++      return rc;
++}
++
++static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
++{
++      return tpm_pm_suspend(&dev->dev, msg);
++}
++
++static int tpm_tis_pnp_resume(struct pnp_dev *dev)
++{
++      return tpm_pm_resume(&dev->dev);
++}
++
++static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
++      {"PNP0C31", 0},         /* TPM */
++      {"ATM1200", 0},         /* Atmel */
++      {"IFX0102", 0},         /* Infineon */
++      {"BCM0101", 0},         /* Broadcom */
++      {"NSC1200", 0},         /* National */
++      /* Add new here */
++      {"", 0},                /* User Specified */
++      {"", 0}                 /* Terminator */
++};
++
++static struct pnp_driver tis_pnp_driver = {
++      .name = "tpm_tis",
++      .id_table = tpm_pnp_tbl,
++      .probe = tpm_tis_pnp_init,
++      .suspend = tpm_tis_pnp_suspend,
++      .resume = tpm_tis_pnp_resume,
++};
++
++#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
++module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
++                  sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
++MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
++
++static int __init init_tis(void)
++{
++      return pnp_register_driver(&tis_pnp_driver);
++}
++
++static void __exit cleanup_tis(void)
++{
++      struct tpm_vendor_specific *i, *j;
++      struct tpm_chip *chip;
++      spin_lock(&tis_lock);
++      list_for_each_entry_safe(i, j, &tis_chips, list) {
++              chip = to_tpm_chip(i);
++              iowrite32(~TPM_GLOBAL_INT_ENABLE &
++                        ioread32(chip->vendor.iobase +
++                                 TPM_INT_ENABLE(chip->vendor.
++                                                locality)),
++                        chip->vendor.iobase +
++                        TPM_INT_ENABLE(chip->vendor.locality));
++              release_locality(chip, chip->vendor.locality, 1);
++              if (chip->vendor.irq)
++                      free_irq(chip->vendor.irq, chip);
++              iounmap(i->iobase);
++              list_del(&i->list);
++              tpm_remove_hardware(chip->dev);
++      }
++      spin_unlock(&tis_lock);
++      pnp_unregister_driver(&tis_pnp_driver);
++}
++
++module_init(init_tis);
++module_exit(cleanup_tis);
++MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
++MODULE_DESCRIPTION("TPM Driver");
++MODULE_VERSION("2.0");
++MODULE_LICENSE("GPL");
+
diff -r 4b51d081378d -r 856caf975abd tools/examples/vtpm-addtodb
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/vtpm-addtodb       Mon Jul 03 08:35:12 2006 +0100
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# This script must be called with the following parameters to have
+# an entry added to the TPM-to-domain associations table in /etc/xen/vtpm.db
+# vtpm-addtodb <dom name> <instance number>
+
+dir=$(dirname "$0")
+. "$dir/vtpm-common.sh"
+
+vtpmdb_add_instance $1 $2
diff -r 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/mp_tables.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/mp_tables.c      Mon Jul 03 08:35:12 2006 +0100
@@ -0,0 +1,426 @@
+/*
+ * mp_tables.c: Dynamically writes MP table info into the ROMBIOS.
+ *
+ * In order to work with various VCPU counts, this code reads the VCPU count
+ * for the HVM partition and creates the correct MP tables for the VCPU count
+ * and places the information into a predetermined location set aside in the
+ * ROMBIOS during build time.
+ *
+ * Please note that many of the values, such as the CPU's
+ * family/model/stepping, are hard-coded based upon the values that were used
+ * in the ROMBIOS and may need to be modified or calculated dynamically to
+ * correspond with what an HVM guest's CPUID returns.
+ *
+ * Travis Betak, travis.betak@xxxxxxx
+ * Copyright (c) 2006, AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+
+/* FIXME find a header that already has types defined!!! */
+typedef unsigned char  uint8_t;
+typedef   signed char  int8_t;
+typedef unsigned short uint16_t;
+typedef   signed short int16_t;
+typedef unsigned int   uint32_t;
+typedef   signed int   int32_t;
+#ifdef __i386__
+typedef unsigned long long uint64_t;
+typedef   signed long long int64_t;
+#else
+typedef unsigned long uint64_t;
+typedef   signed long int64_t;
+#endif
+
+#define ROMBIOS_SEG              0xF000
+#define ROMBIOS_BEGIN            0x000F0000
+#define ROMBIOS_SIZE             0x00010000 
+#define ROMBIOS_MAXOFFSET        0x0000FFFF
+#define ROMBIOS_END             (ROMBIOS_BEGIN + ROMBIOS_SIZE)
+
+/* number of non-processor MP table entries */
+#define NR_NONPROC_ENTRIES     18
+
+#define ENTRY_TYPE_PROCESSOR   0
+#define ENTRY_TYPE_BUS         1
+#define ENTRY_TYPE_IOAPIC      2
+#define ENTRY_TYPE_IO_INTR     3
+#define ENTRY_TYPE_LOCAL_INTR  4
+
+#define CPU_FLAG_ENABLED       0x01
+#define CPU_FLAG_BSP           0x02
+
+/* TODO change this to correspond with what the guest's see's from CPUID */
+#define CPU_SIG_FAMILY         0x06
+#define CPU_SIG_MODEL          0x00
+#define CPU_SIG_STEPPING       0x00
+#define CPU_SIGNATURE        ((CPU_SIG_FAMILY << 8)  \
+                             | (CPU_SIG_MODEL << 4)  \
+                             | (CPU_SIG_STEPPING))
+#define CPU_FEATURE_FPU       (1U << 0)
+#define CPU_FEATURE_MCE       (1U << 7)
+#define CPU_FEATURE_CX8       (1U << 8)
+#define CPU_FEATURE_APIC      (1U << 9)
+#define CPU_FEATURES          (CPU_FEATURE_FPU | CPU_FEATURE_APIC)
+
+#define BUS_TYPE_LENGTH        6
+#define BUS_TYPE_STR_ISA       "ISA   "
+
+#define LAPIC_BASE_ADDR        0xFEE00000
+
+#define IOAPIC_VERSION         0x11
+#define IOAPIC_BASE_ADDR       0xFEC00000
+#define IOAPIC_FLAG_ENABLED   (1U << 0)
+
+#define INTR_TYPE_INT          0
+#define INTR_TYPE_NMI          1
+#define INTR_TYPE_SMI          2
+#define INTR_TYPE_EXTINT       3
+
+#define INTR_FLAGS             0
+
+#define INTR_MAX_NR            16
+
+extern int puts(const char *); /* for printing */
+extern int get_vcpu_nr(void);  /* for the guest's VCPU count */
+
+/*
+ * The following structures are defined in the MuliProcessor Specifiation v1.4
+ */
+
+/* MP Floating Pointer Structure */
+struct mp_floating_pointer_struct {
+       uint8_t signature[4];
+       uint32_t mp_table;
+       uint8_t length;
+       uint8_t revision;
+       uint8_t checksum;
+       uint8_t feature[5];
+};
+
+/* MP Configuration Table */
+struct mp_config_table {
+       uint8_t signature[4];
+       uint16_t length;
+       uint8_t revision;
+       uint8_t checksum;
+       uint8_t oem_id[8];
+       uint8_t vendor_id[12];
+       uint32_t oem_table;
+       uint16_t oem_table_sz;
+       uint16_t nr_entries;
+       uint32_t lapic;
+       uint16_t extended_length;
+       uint8_t extended_checksum;
+       uint8_t reserved;
+};
+
+/* MP Processor Entry */
+struct mp_proc_entry {
+       uint8_t type;
+       uint8_t lapic_id;
+       uint8_t lapic_version;
+       uint8_t cpu_flags;
+       uint32_t cpu_signature;
+       uint32_t feature_flags;
+       uint8_t reserved[8];
+};
+
+/* MP Bus Entry */
+struct mp_bus_entry {
+       uint8_t type;
+       uint8_t bus_id;
+       uint8_t bus_type_str[6];
+};
+
+/* MP IOAPIC Entry */
+struct mp_ioapic_entry {
+       uint8_t type;
+       uint8_t ioapic_id;
+       uint8_t ioapic_version;
+       uint8_t ioapic_flags;
+       uint32_t ioapic_addr;
+};
+
+/* MP IO Interrupt Entry */
+struct mp_io_intr_entry {
+       uint8_t type;
+       uint8_t intr_type;
+       uint16_t io_intr_flags;
+       uint8_t src_bus_id;
+       uint8_t src_bus_irq;
+       uint8_t dst_ioapic_id;
+       uint8_t dst_ioapic_intin;
+};
+
+/* MP Local Interrupt Entry */
+struct mp_local_intr_entry {
+       uint8_t type;
+       uint8_t intr_type;
+       uint16_t local_intr_flags;
+       uint8_t src_bus_id;
+       uint8_t src_bus_irq;
+       uint8_t dst_lapic_id;
+       uint8_t dst_lapic_lintin;
+};
+
+
+/* 
+ * fill_mp_config_table - fills in the information for the MP config table
+ *    
+ * When calculating the length and nr_entries fields, keep in mind that there
+ * are always 18 non-processor entries and N processor entries
+ * 
+ *    N vcpu entries
+ *    1 bus entry 
+ *    1 IOAPIC entry 
+ * + 16 IO intr. entries
+ * ----------------------
+ * 18 + N total entries
+ */
+void fill_mp_config_table(struct mp_config_table *mpct)
+{
+       int vcpu_nr;
+
+       vcpu_nr = get_vcpu_nr();
+
+       /* fill in the MP configuration table signature, "PCMP" */
+       mpct->signature[0] = 'P';
+       mpct->signature[1] = 'C';
+       mpct->signature[2] = 'M';
+       mpct->signature[3] = 'P';
+
+       mpct->length =    sizeof(struct mp_config_table)
+                       + vcpu_nr * sizeof(struct mp_proc_entry)
+                       + sizeof(struct mp_ioapic_entry)
+                       + sizeof(struct mp_bus_entry)
+                       + 16 * sizeof(struct mp_local_intr_entry);
+
+       mpct->revision = 4;
+
+       /* 
+        * We'll fill in the checksum later after all of the 
+        * entries have been created
+        */
+       mpct->checksum = 0;
+
+       /* fill in the OEM ID string, "_HVMCPU_" */
+       mpct->oem_id[0] = '_'; mpct->oem_id[3] = 'M'; mpct->oem_id[6] = 'U';
+       mpct->oem_id[1] = 'H'; mpct->oem_id[4] = 'C'; mpct->oem_id[7] = '_';
+       mpct->oem_id[2] = 'V'; mpct->oem_id[5] = 'P';
+
+       /* fill in the Vendor ID string, "XEN         " */
+       mpct->vendor_id[0] = 'X'; mpct->vendor_id[6] =  ' ';
+       mpct->vendor_id[1] = 'E'; mpct->vendor_id[7] =  ' ';
+       mpct->vendor_id[2] = 'N'; mpct->vendor_id[8] =  ' ';
+       mpct->vendor_id[3] = ' '; mpct->vendor_id[9] =  ' ';
+       mpct->vendor_id[4] = ' '; mpct->vendor_id[10] = ' ';
+       mpct->vendor_id[5] = ' '; mpct->vendor_id[11] = ' ';
+
+       mpct->oem_table = 0;
+       mpct->oem_table_sz = 0;
+
+       mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
+
+       mpct->lapic = LAPIC_BASE_ADDR;
+       mpct->extended_length = 0;
+       mpct->extended_checksum = 0;
+}
+
+
+/* calculates the checksum for the MP configuration table */
+void fill_mp_config_table_checksum(struct mp_config_table *mpct)
+{
+       int i;
+       uint8_t checksum;
+
+       checksum = 0;
+       for (i = 0; i < mpct->length; ++i)
+               checksum += ((uint8_t *)(mpct))[i];
+       mpct->checksum = -checksum;
+}
+
+
+/* fills in an MP processor entry for VCPU 'vcpu_id' */
+void fill_mp_proc_entry(struct mp_proc_entry *mppe, int vcpu_id)
+{
+       mppe->type = ENTRY_TYPE_PROCESSOR;
+       mppe->lapic_id = vcpu_id;
+       mppe->lapic_version = 0x11;
+       mppe->cpu_flags = CPU_FLAG_ENABLED;
+       if (vcpu_id == 0)
+               mppe->cpu_flags |= CPU_FLAG_BSP;
+       mppe->cpu_signature = CPU_SIGNATURE;
+       mppe->feature_flags = CPU_FEATURES;
+}
+
+
+/* fills in an MP bus entry of type 'type' and bus ID 'bus_id' */
+void fill_mp_bus_entry(struct mp_bus_entry *mpbe, int bus_id, const char *type)
+{
+       int i;
+
+       mpbe->type = ENTRY_TYPE_BUS;
+       mpbe->bus_id = bus_id;
+       for (i = 0; i < BUS_TYPE_LENGTH; ++i)
+               mpbe->bus_type_str[i] = type[i]; /* FIXME length check? */
+}
+
+
+/* fills in an MP IOAPIC entry for IOAPIC 'ioapic_id' */
+void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie, int ioapic_id)
+{
+       mpie->type = ENTRY_TYPE_IOAPIC;
+       mpie->ioapic_id = ioapic_id;
+       mpie->ioapic_version = IOAPIC_VERSION;
+       mpie->ioapic_flags = IOAPIC_FLAG_ENABLED;
+       mpie->ioapic_addr = IOAPIC_BASE_ADDR;
+}
+
+
+/* fills in an IO interrupt entry for IOAPIC 'ioapic_id' */
+void fill_mp_io_intr_entry(struct mp_io_intr_entry *mpiie,
+               int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
+{
+       mpiie->type = ENTRY_TYPE_IO_INTR;
+       mpiie->intr_type = INTR_TYPE_INT;
+       mpiie->io_intr_flags = INTR_FLAGS;
+       mpiie->src_bus_id = 0;
+       mpiie->src_bus_irq = src_bus_irq;
+       mpiie->dst_ioapic_id = ioapic_id;
+       mpiie->dst_ioapic_intin = dst_ioapic_intin;
+}
+
+
+/* fill in the mp floating processor structure */
+void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t mpct)
+{
+       int i;
+       uint8_t checksum;
+
+
+       mpfps->signature[0] = '_';
+       mpfps->signature[1] = 'M';
+       mpfps->signature[2] = 'P';
+       mpfps->signature[3] = '_';
+
+       mpfps->mp_table = mpct; 
+       mpfps->length = 1;
+       mpfps->revision = 4;
+       mpfps->checksum = 0;
+       for (i = 0; i < 5; ++i)
+               mpfps->feature[i] = 0;
+
+       /* compute the checksum for our new table */
+       checksum = 0;
+       for (i = 0; i < sizeof(struct mp_floating_pointer_struct); ++i)
+               checksum += ((uint8_t *)(mpfps))[i];
+       mpfps->checksum = -checksum;
+}
+
+
+/*
+ * find_mp_table_start - searchs through BIOS memory for '___HVMMP' signature
+ *
+ * The '___HVMMP' signature is created by the ROMBIOS and designates a chunk
+ * of space inside the ROMBIOS that is safe for us to write our MP table info
+ */
+void* get_mp_table_start(void)
+{
+       char *bios_mem;
+       for (bios_mem = (char *)ROMBIOS_BEGIN; 
+            bios_mem != (char *)ROMBIOS_END; 
+            ++bios_mem)
+               if (bios_mem[0] == '_' && bios_mem[1] == '_' &&
+                   bios_mem[2] == '_' && bios_mem[3] == 'H' &&
+                   bios_mem[4] == 'V' && bios_mem[5] == 'M' &&
+                   bios_mem[6] == 'M' && bios_mem[7] == 'P')
+                       return bios_mem;
+
+       return (void *)-1;
+}
+
+
+/* recalculate the new ROMBIOS checksum after adding MP tables */
+void reset_bios_checksum(void)
+{
+       uint32_t i;
+       uint8_t checksum;
+
+       checksum = 0;
+       for (i = 0; i < ROMBIOS_MAXOFFSET; ++i)
+               checksum += ((uint8_t *)(ROMBIOS_BEGIN))[i];
+       
+       *((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
+}
+
+
+/* create_mp_tables - creates MP tables for the guest based upon config data */
+void create_mp_tables(void)
+{
+       void *mp_table_base;
+       char *p;
+       struct mp_config_table *mp_config_table;
+       int vcpu_nr;
+       int i;
+
+       vcpu_nr = get_vcpu_nr();
+       
+       puts("Creating MP tables ...\n");
+
+       /* find the 'safe' place in ROMBIOS for the MP tables */
+       mp_table_base = get_mp_table_start();
+       if (mp_table_base == (void *)-1) {
+               puts("Couldn't find start point for MP tables\n");
+               return;
+       }
+       p = mp_table_base;
+
+       fill_mp_config_table((struct mp_config_table *)p);
+
+       /* save the location of the MP config table for a little later*/
+       mp_config_table = (struct mp_config_table *)p;
+       p += sizeof(struct mp_config_table);
+
+       for (i = 0; i < vcpu_nr; ++i) {
+               fill_mp_proc_entry((struct mp_proc_entry *)p, i);
+               p += sizeof(struct mp_proc_entry);
+       }
+
+       fill_mp_bus_entry((struct mp_bus_entry *)p, 0, BUS_TYPE_STR_ISA);
+       p += sizeof(struct mp_bus_entry);
+
+       fill_mp_ioapic_entry((struct mp_ioapic_entry *)p, vcpu_nr);
+       p += sizeof(struct mp_ioapic_entry);
+
+       for (i = 0; i < INTR_MAX_NR; ++i) {
+               fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 
+                               i, vcpu_nr, i);
+               p += sizeof(struct mp_io_intr_entry);
+       }
+
+       /* find the next 16-byte boundary to place the mp floating pointer */
+       while ((unsigned long)p & 0xF)
+               ++p;
+       
+       fill_mpfps((struct mp_floating_pointer_struct *)p, 
+                       (uint32_t)mp_table_base);
+
+       /* calculate the MP configuration table's checksum */
+       fill_mp_config_table_checksum(mp_config_table);
+
+       /* finally, recalculate the ROMBIOS checksum */
+       reset_bios_checksum();
+}
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+#                extend a pcr
+#                check list of pcrs; suspend and resume the domain and
+#                check list of pcrs again and validate extended pcr
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
+consoleHistory = ""
+
+try:
+    console = domain.start()
+except DomainError, e:
+    if verbose:
+        print e.extra
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
+
+try:
+    console.sendInput("input")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL(str(e))
+
+try:
+    run = console.runCmd("mknod /dev/tpm0 c 10 224")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while creating /dev/tpm0")
+
+try:
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while extending PCR 0")
+
+try:
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("No result from dumping the PCRs")
+
+
+if re.search("No such file",run["output"]):
+    vtpm_cleanup(domName)
+    FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+if not re.search("PCR-00:",run["output"]):
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: 
\n%s" % run["output"])
+
+if not re.search("PCR-00: 1E A7 BD",run["output"]):
+    saveLog(console.getHistory())
+    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % 
run["output"])
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm save %s %s.save" %
+                                      (domName, domName),
+                                      timeout=30)
+
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm save did not succeed")
+
+    try:
+        status, ouptut = traceCommand("xm restore %s.save" %
+                                      (domName),
+                                      timeout=30)
+    except TimeoutError, e:
+        os.remove("%s.save" % domName)
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    os.remove("%s.save" % domName)
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm restore did not succeed")
+
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    if not re.search("PCR-00: 1E A7 BD",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+
+    loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)
+
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+#                extend a pcr
+#                check list of pcrs; locally migrate the domain and
+#                check list of pcrs again and validate extended pcr
+#                This test does local live migration.
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
+consoleHistory = ""
+
+try:
+    console = domain.start()
+except DomainError, e:
+    if verbose:
+        print e.extra
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
+
+try:
+    console.sendInput("input")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL(str(e))
+
+try:
+    run = console.runCmd("mknod /dev/tpm0 c 10 224")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while creating /dev/tpm0")
+
+try:
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while extending PCR 0")
+
+try:
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("No result from dumping the PCRs")
+
+
+if re.search("No such file",run["output"]):
+    vtpm_cleanup(domName)
+    FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+if not re.search("PCR-00:",run["output"]):
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: 
\n%s" % run["output"])
+
+if not re.search("PCR-00: 1E A7 BD",run["output"]):
+    saveLog(console.getHistory())
+    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % 
run["output"])
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+old_domid = domid(domName)
+
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm migrate -l %s localhost" %
+                                      domName,
+                                      timeout=90)
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm migrate did not succeed. External device migration 
activated?")
+
+
+    domName = domain.getName()
+    new_domid = domid(domName)
+
+    if (old_domid == new_domid):
+        vtpm_cleanup(domName)
+        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
+             (old_domid,loop))
+
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    if not re.search("PCR-00: 1E A7 BD",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+
+    loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+#                extend a pcr
+#                check list of pcrs; locally migrate the domain and
+#                check list of pcrs again and validate extended pcr
+#                This test does local (non-live) migration.
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
+consoleHistory = ""
+
+try:
+    console = domain.start()
+except DomainError, e:
+    if verbose:
+        print e.extra
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
+
+try:
+    console.sendInput("input")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL(str(e))
+
+try:
+    run = console.runCmd("mknod /dev/tpm0 c 10 224")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while creating /dev/tpm0")
+
+try:
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while extending PCR 0")
+
+try:
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("No result from dumping the PCRs")
+
+
+if re.search("No such file",run["output"]):
+    vtpm_cleanup(domName)
+    FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+if not re.search("PCR-00:",run["output"]):
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: 
\n%s" % run["output"])
+
+if not re.search("PCR-00: 1E A7 BD",run["output"]):
+    saveLog(console.getHistory())
+    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % 
run["output"])
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+old_domid = domid(domName)
+
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm migrate %s localhost" %
+                                      domName,
+                                      timeout=90)
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm migrate did not succeed. External device migration 
activated?")
+
+
+    domName = domain.getName()
+    new_domid = domid(domName)
+
+    if (old_domid == new_domid):
+        vtpm_cleanup(domName)
+        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
+             (old_domid,loop))
+
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    if not re.search("PCR-00: 1E A7 BD",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+
+    loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg, Xen patchbot-unstable <=