ia64/xen-unstable

changeset 10637:856caf975abd

Merge with xen-ia64-unstable.hg
author kaf24@firebug.cl.cam.ac.uk
date Mon Jul 03 08:35:12 2006 +0100 (2006-07-03)
parents 4b51d081378d 3f8d9b128d71
children 9fd92e7e91a5
files tools/libxc/xc_linux_build.c xen/include/public/arch-ia64.h
line diff
     1.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Wed Jun 28 07:52:21 2006 -0600
     1.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Mon Jul 03 08:35:12 2006 +0100
     1.3 @@ -1902,6 +1902,7 @@ CONFIG_HANGCHECK_TIMER=m
     1.4  # TPM devices
     1.5  #
     1.6  CONFIG_TCG_TPM=m
     1.7 +CONFIG_TCG_TIS=m
     1.8  CONFIG_TCG_NSC=m
     1.9  CONFIG_TCG_ATMEL=m
    1.10  CONFIG_TCG_INFINEON=m
     2.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Wed Jun 28 07:52:21 2006 -0600
     2.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Mon Jul 03 08:35:12 2006 +0100
     2.3 @@ -1765,6 +1765,7 @@ CONFIG_HANGCHECK_TIMER=m
     2.4  # TPM devices
     2.5  #
     2.6  CONFIG_TCG_TPM=m
     2.7 +CONFIG_TCG_TIS=m
     2.8  CONFIG_TCG_NSC=m
     2.9  CONFIG_TCG_ATMEL=m
    2.10  CONFIG_TCG_INFINEON=m
     3.1 --- a/docs/man/xm.pod.1	Wed Jun 28 07:52:21 2006 -0600
     3.2 +++ b/docs/man/xm.pod.1	Mon Jul 03 08:35:12 2006 +0100
     3.3 @@ -875,14 +875,43 @@ defined in the I<policy>. Unless specifi
     3.4  the currently enforced access control policy. The default for I<type>
     3.5  is 'dom'. The labels are arranged in alphabetical order.
     3.6  
     3.7 -=item B<addlabel> I<configfile> I<label> [I<policy>]
     3.8 +=item B<addlabel> I<label> dom I<configfile> [I<policy>]
     3.9 +
    3.10 +=item B<addlabel> I<label> res I<resource> [I<policy>]
    3.11  
    3.12  Adds the security label with name I<label> to a domain
    3.13 -I<configfile>. Unless specified, the default I<policy> is the
    3.14 +I<configfile> (dom) or to the global resource label file for the
    3.15 +given I<resource> (res). Unless specified, the default I<policy> is the
    3.16  currently enforced access control policy. This subcommand also
    3.17  verifies that the I<policy> definition supports the specified I<label>
    3.18  name.
    3.19  
    3.20 +=item B<rmlabel> dom I<configfile>
    3.21 +
    3.22 +=item B<rmlabel> res I<resource>
    3.23 +
    3.24 +Works the same as the I<addlabel> command (above), except that this
    3.25 +command will remove the label from the domain I<configfile> (dom) or
    3.26 +the global resource label file (res).
    3.27 +
    3.28 +=item B<getlabel> dom I<configfile>
    3.29 +
    3.30 +=item B<getlabel> res I<resource>
    3.31 +
    3.32 +Shows the label for the given I<configfile> or I<resource>
    3.33 +
    3.34 +=item B<resources>
    3.35 +
    3.36 +Lists all resources in the global resource label file.  Each resource
    3.37 +is listed with its associated label and policy name.
    3.38 +
    3.39 +=item B<dry-run> I<configfile>
    3.40 +
    3.41 +Determines if the specified I<configfile> describes a domain with a valid
    3.42 +security configuration for type enforcement. The test shows the policy
    3.43 +decision made for each resource label against the domain label as well as
    3.44 +the overall decision.
    3.45 +
    3.46  B<CONFIGURING SECURITY>
    3.47  
    3.48  =over 4
    3.49 @@ -960,17 +989,18 @@ B<ATTACHING A SECURITY LABEL TO A DOMAIN
    3.50  
    3.51  =over 4
    3.52  
    3.53 -This subcommand attaches a security label to a domain configuration
    3.54 -file, here a HomeBanking label. The example policy ensures that this
    3.55 -domain does not share information with other non-hombanking user
    3.56 -domains (i.e., domains labeled as dom_Fun or dom_Boinc) and that it
    3.57 -will not run simultaneously with domains labeled as dom_Fun.
    3.58 +The I<addlabel> subcommand can attach a security label to a domain
    3.59 +configuration file, here a HomeBanking label. The example policy
    3.60 +ensures that this domain does not share information with other
    3.61 +non-hombanking user domains (i.e., domains labeled as dom_Fun or
    3.62 +dom_Boinc) and that it will not run simultaneously with domains
    3.63 +labeled as dom_Fun.
    3.64  
    3.65  We assume that the specified myconfig.xm configuration file actually
    3.66  instantiates a domain that runs workloads related to home-banking,
    3.67  probably just a browser environment for online-banking.
    3.68  
    3.69 -    xm addlabel myconfig.xm dom_HomeBanking
    3.70 +    xm addlabel dom_HomeBanking dom myconfig.xm
    3.71  
    3.72  The very simple configuration file might now look as printed
    3.73  below. The I<addlabel> subcommand added the B<access_control> entry at
    3.74 @@ -997,6 +1027,38 @@ permitted".
    3.75  
    3.76  =back
    3.77  
    3.78 +B<ATTACHING A SECURITY LABEL TO A RESOURCE>
    3.79 +
    3.80 +=over 4
    3.81 +
    3.82 +The I<addlabel> subcommand can also be used to attach a security
    3.83 +label to a resource. Following the home banking example from above,
    3.84 +we can label a disk resource (e.g., a physical partition or a file)
    3.85 +to make it accessible to the home banking domain. The example policy
    3.86 +provides a resource label, res_LogicalDiskPartition1(hda1), that is
    3.87 +compatible with the HomeBanking domain label.
    3.88 +
    3.89 +    xm addlabel "res_LogicalDiskPartition1(hda1)" res phy:hda6
    3.90 +
    3.91 +After labeling this disk resource, it can be attached to the domain
    3.92 +by adding a line to the domain configuration file. The line below
    3.93 +attaches this disk to the domain at boot time.
    3.94 +
    3.95 +    disk = [ 'phy:hda6,sda2,w' ]
    3.96 +
    3.97 +Alternatively, the resource can be attached after booting the domain
    3.98 +by using the I<block-attach> subcommand.
    3.99 +
   3.100 +    xm block-attach homebanking phy:hda6 sda2 w
   3.101 +
   3.102 +Note that labeled resources cannot be used when security is turned
   3.103 +off.  Any attempt to use labeled resources with security turned off
   3.104 +will result in a failure with a corresponding error message.  The
   3.105 +solution is to enable security or, if security is no longer desired,
   3.106 +to remove the resource label using the I<rmlabel> subcommand.
   3.107 +
   3.108 +=back
   3.109 +
   3.110  B<STARTING AND LISTING LABELED DOMAINS>
   3.111  
   3.112  =over 4
   3.113 @@ -1011,6 +1073,21 @@ B<STARTING AND LISTING LABELED DOMAINS>
   3.114  
   3.115  =back
   3.116  
   3.117 +B<LISTING LABELED RESOURCES>
   3.118 +
   3.119 +=over 4
   3.120 +
   3.121 +    xm resources
   3.122 +
   3.123 +      phy:hda6
   3.124 +          policy: example.chwall_ste.client_v1
   3.125 +          label:  res_LogicalDiskPartition1(hda1)
   3.126 +      file:/xen/disk_image/disk.img
   3.127 +          policy: example.chwall_ste.client_v1
   3.128 +          label:  res_LogicalDiskPartition2(hda2)
   3.129 +
   3.130 +=back
   3.131 +
   3.132  B<POLICY REPRESENTATIONS>
   3.133  
   3.134  =over 4
     4.1 --- a/docs/misc/vtpm.txt	Wed Jun 28 07:52:21 2006 -0600
     4.2 +++ b/docs/misc/vtpm.txt	Mon Jul 03 08:35:12 2006 +0100
     4.3 @@ -1,5 +1,5 @@
     4.4  Copyright: IBM Corporation (C), Intel Corporation
     4.5 -17 August 2005
     4.6 +29 June 2006
     4.7  Authors: Stefan Berger <stefanb@us.ibm.com> (IBM), 
     4.8           Employees of Intel Corp
     4.9  
    4.10 @@ -9,24 +9,34 @@ instance and doing a short test to verif
    4.11  that the user is fairly familiar with compiling and installing XEN
    4.12  and Linux on a machine. 
    4.13   
    4.14 -Production Prerequisites: An x86-based machine machine with an ATMEL or
    4.15 -National Semiconductor (NSC) TPM on the motherboard.
    4.16 +Production Prerequisites: An x86-based machine machine with a
    4.17 +Linux-supported TPM on the motherboard (NSC, Atmel, Infineon, TPM V1.2).
    4.18  Development Prerequisites: An emulator for TESTING ONLY is provided
    4.19  
    4.20  
    4.21 -Compiling XEN tree:
    4.22 --------------------
    4.23 +Compiling the XEN tree:
    4.24 +-----------------------
    4.25  
    4.26  Compile the XEN tree as usual after the following lines set in the
    4.27  linux-2.6.??-xen/.config file:
    4.28  
    4.29 -CONFIG_XEN_TPMDEV_BACKEND=y
    4.30 +CONFIG_XEN_TPMDEV_BACKEND=m
    4.31 +
    4.32 +CONFIG_TCG_TPM=m
    4.33 +CONFIG_TCG_TIS=m      (supported after 2.6.17-rc4)
    4.34 +CONFIG_TCG_NSC=m
    4.35 +CONFIG_TCG_ATMEL=m
    4.36 +CONFIG_TCG_INFINEON=m
    4.37 +CONFIG_TCG_XEN=m
    4.38 +<possible other TPM drivers supported by Linux>
    4.39 +
    4.40 +If the frontend driver needs to be compiled into the user domain
    4.41 +kernel, then the following two lines should be changed.
    4.42  
    4.43  CONFIG_TCG_TPM=y
    4.44 -CONFIG_TCG_NSC=m
    4.45 -CONFIG_TCG_ATMEL=m
    4.46  CONFIG_TCG_XEN=y
    4.47  
    4.48 +
    4.49  You must also enable the virtual TPM to be built:
    4.50  
    4.51  In Config.mk in the Xen root directory set the line
    4.52 @@ -63,7 +73,7 @@ an example of how a user domain can be c
    4.53  available. It works similar to making a network interface
    4.54  available to a domain.
    4.55  
    4.56 -kernel = "/boot/vmlinuz-2.6.12-xenU"
    4.57 +kernel = "/boot/vmlinuz-2.6.x"
    4.58  ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
    4.59  memory = 32
    4.60  name = "TPMUserDomain0"
    4.61 @@ -92,7 +102,7 @@ leave out the 'vtpm' line in the configu
    4.62  Running the TPM:
    4.63  ----------------
    4.64  
    4.65 -To run the vTPM, dev device /dev/vtpm must be available.
    4.66 +To run the vTPM, the device /dev/vtpm must be available.
    4.67  Verify that 'ls -l /dev/vtpm' shows the following output:
    4.68  
    4.69  crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
    4.70 @@ -101,16 +111,26 @@ If it is not available, run the followin
    4.71  mknod /dev/vtpm c 10 225
    4.72  
    4.73  Make sure that the vTPM is running in domain 0. To do this run the
    4.74 -following
    4.75 +following:
    4.76 +
    4.77 +modprobe tpmbk
    4.78  
    4.79  /usr/bin/vtpm_managerd
    4.80  
    4.81  Start a user domain using the 'xm create' command. Once you are in the
    4.82 -shell of the user domain, you should be able to do the following:
    4.83 +shell of the user domain, you should be able to do the following as
    4.84 +user 'root':
    4.85  
    4.86 -> cd /sys/devices/vtpm
    4.87 +Insert the TPM frontend into the kernel if it has been compiled as a
    4.88 +kernel module.
    4.89 +
    4.90 +> modprobe tpm_xenu
    4.91 +
    4.92 +Check the status of the TPM
    4.93 +
    4.94 +> cd /sys/devices/xen/vtpm-0
    4.95  > ls
    4.96 -cancel  caps   pcrs    pubek
    4.97 +[...]  cancel  caps   pcrs    pubek   [...]
    4.98  > cat pcrs
    4.99  PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
   4.100  PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     5.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c	Wed Jun 28 07:52:21 2006 -0600
     5.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c	Mon Jul 03 08:35:12 2006 +0100
     5.3 @@ -442,6 +442,7 @@ void flush_tlb_mm(struct mm_struct * mm)
     5.4  { xen_tlb_flush_mask(&mm->cpu_vm_mask); }
     5.5  void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
     5.6  { xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
     5.7 +EXPORT_SYMBOL(flush_tlb_page);
     5.8  void flush_tlb_all(void)
     5.9  { xen_tlb_flush_all(); }
    5.10  
     6.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Jun 28 07:52:21 2006 -0600
     6.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Mon Jul 03 08:35:12 2006 +0100
     6.3 @@ -989,12 +989,11 @@ static void stop_hz_timer(void)
     6.4  
     6.5  	smp_mb();
     6.6  
     6.7 -	/* Leave ourselves in 'tick mode' if rcu or softirq pending. */
     6.8 -	if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
     6.9 +	/* Leave ourselves in 'tick mode' if rcu or softirq or timer pending. */
    6.10 +	if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
    6.11 +	    (j = next_timer_interrupt(), time_before_eq(j, jiffies))) {
    6.12  		cpu_clear(cpu, nohz_cpu_mask);
    6.13  		j = jiffies + 1;
    6.14 -	} else {
    6.15 -		j = next_timer_interrupt();
    6.16  	}
    6.17  
    6.18  	BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
     7.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Wed Jun 28 07:52:21 2006 -0600
     7.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c	Mon Jul 03 08:35:12 2006 +0100
     7.3 @@ -60,7 +60,7 @@ void *kmap_atomic_pte(struct page *page,
     7.4  
     7.5  void kunmap_atomic(void *kvaddr, enum km_type type)
     7.6  {
     7.7 -#ifdef CONFIG_DEBUG_HIGHMEM
     7.8 +#if defined(CONFIG_DEBUG_HIGHMEM) || defined(CONFIG_XEN)
     7.9  	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
    7.10  	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
    7.11  
    7.12 @@ -69,7 +69,9 @@ void kunmap_atomic(void *kvaddr, enum km
    7.13  		preempt_check_resched();
    7.14  		return;
    7.15  	}
    7.16 +#endif
    7.17  
    7.18 +#if defined(CONFIG_DEBUG_HIGHMEM)
    7.19  	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
    7.20  		BUG();
    7.21  
    7.22 @@ -79,6 +81,14 @@ void kunmap_atomic(void *kvaddr, enum km
    7.23  	 */
    7.24  	pte_clear(&init_mm, vaddr, kmap_pte-idx);
    7.25  	__flush_tlb_one(vaddr);
    7.26 +#elif defined(CONFIG_XEN)
    7.27 +	/*
    7.28 +	 * We must ensure there are no dangling pagetable references when
    7.29 +	 * returning memory to Xen (decrease_reservation).
    7.30 +	 * XXX TODO: We could make this faster by only zapping when
    7.31 +	 * kmap_flush_unused is called but that is trickier and more invasive.
    7.32 +	 */
    7.33 +	pte_clear(&init_mm, vaddr, kmap_pte-idx);
    7.34  #endif
    7.35  
    7.36  	dec_preempt_count();
     8.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Jun 28 07:52:21 2006 -0600
     8.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Mon Jul 03 08:35:12 2006 +0100
     8.3 @@ -271,10 +271,6 @@ static unsigned long discontig_frames[1<
     8.4  int xen_create_contiguous_region(
     8.5  	unsigned long vstart, unsigned int order, unsigned int address_bits)
     8.6  {
     8.7 -	pgd_t         *pgd; 
     8.8 -	pud_t         *pud; 
     8.9 -	pmd_t         *pmd;
    8.10 -	pte_t         *pte;
    8.11  	unsigned long *in_frames = discontig_frames, out_frame;
    8.12  	unsigned long  frame, i, flags;
    8.13  	long           rc;
    8.14 @@ -301,7 +297,7 @@ int xen_create_contiguous_region(
    8.15  	if (xen_feature(XENFEAT_auto_translated_physmap))
    8.16  		return 0;
    8.17  
    8.18 -	if (order > MAX_CONTIG_ORDER)
    8.19 +	if (unlikely(order > MAX_CONTIG_ORDER))
    8.20  		return -ENOMEM;
    8.21  
    8.22  	set_xen_guest_handle(exchange.in.extent_start, in_frames);
    8.23 @@ -313,11 +309,7 @@ int xen_create_contiguous_region(
    8.24  
    8.25  	/* 1. Zap current PTEs, remembering MFNs. */
    8.26  	for (i = 0; i < (1UL<<order); i++) {
    8.27 -		pgd = pgd_offset_k(vstart + (i*PAGE_SIZE));
    8.28 -		pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
    8.29 -		pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
    8.30 -		pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
    8.31 -		in_frames[i] = pte_mfn(*pte);
    8.32 +		in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
    8.33  		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
    8.34  						 __pte_ma(0), 0))
    8.35  			BUG();
    8.36 @@ -372,10 +364,6 @@ int xen_create_contiguous_region(
    8.37  
    8.38  void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
    8.39  {
    8.40 -	pgd_t         *pgd; 
    8.41 -	pud_t         *pud; 
    8.42 -	pmd_t         *pmd;
    8.43 -	pte_t         *pte;
    8.44  	unsigned long *out_frames = discontig_frames, in_frame;
    8.45  	unsigned long  frame, i, flags;
    8.46  	long           rc;
    8.47 @@ -397,7 +385,7 @@ void xen_destroy_contiguous_region(unsig
    8.48  	    !test_bit(__pa(vstart) >> PAGE_SHIFT, contiguous_bitmap))
    8.49  		return;
    8.50  
    8.51 -	if (order > MAX_CONTIG_ORDER)
    8.52 +	if (unlikely(order > MAX_CONTIG_ORDER))
    8.53  		return;
    8.54  
    8.55  	set_xen_guest_handle(exchange.in.extent_start, &in_frame);
    8.56 @@ -410,16 +398,13 @@ void xen_destroy_contiguous_region(unsig
    8.57  	contiguous_bitmap_clear(__pa(vstart) >> PAGE_SHIFT, 1UL << order);
    8.58  
    8.59  	/* 1. Find start MFN of contiguous extent. */
    8.60 -	pgd = pgd_offset_k(vstart);
    8.61 -	pud = pud_offset(pgd, vstart);
    8.62 -	pmd = pmd_offset(pud, vstart);
    8.63 -	pte = pte_offset_kernel(pmd, vstart);
    8.64 -	in_frame = pte_mfn(*pte);
    8.65 +	in_frame = pfn_to_mfn(__pa(vstart) >> PAGE_SHIFT);
    8.66  
    8.67  	/* 2. Zap current PTEs. */
    8.68  	for (i = 0; i < (1UL<<order); i++) {
    8.69  		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
    8.70 -						 __pte_ma(0), 0));
    8.71 +						 __pte_ma(0), 0))
    8.72 +			BUG();
    8.73  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
    8.74  			INVALID_P2M_ENTRY);
    8.75  		out_frames[i] = (__pa(vstart) >> PAGE_SHIFT) + i;
    8.76 @@ -430,7 +415,7 @@ void xen_destroy_contiguous_region(unsig
    8.77  	success = (exchange.nr_exchanged == 1);
    8.78  	BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
    8.79  	BUG_ON(success && (rc != 0));
    8.80 -	if (rc == -ENOSYS) {
    8.81 +	if (unlikely(rc == -ENOSYS)) {
    8.82  		/* Compatibility when XENMEM_exchange is unsupported. */
    8.83  		if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
    8.84  					 &exchange.in) != 1)
     9.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Wed Jun 28 07:52:21 2006 -0600
     9.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Mon Jul 03 08:35:12 2006 +0100
     9.3 @@ -20,9 +20,18 @@ config TCG_TPM
     9.4  	  Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
     9.5  	  and CONFIG_PNPACPI.
     9.6  
     9.7 +config TCG_TIS
     9.8 +	tristate "TPM Interface Specification 1.2 Interface"
     9.9 +	depends on TCG_TPM
    9.10 +	---help---
    9.11 +	  If you have a TPM security chip that is compliant with the
    9.12 +	  TCG TIS 1.2 TPM specification say Yes and it will be accessible
    9.13 +	  from within Linux.  To compile this driver as a module, choose
    9.14 +	  M here; the module will be called tpm_tis.
    9.15 +
    9.16  config TCG_NSC
    9.17  	tristate "National Semiconductor TPM Interface"
    9.18 -	depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
    9.19 +	depends on TCG_TPM && PNPACPI
    9.20  	---help---
    9.21  	  If you have a TPM security chip from National Semicondutor 
    9.22  	  say Yes and it will be accessible from within Linux.  To 
    9.23 @@ -31,7 +40,7 @@ config TCG_NSC
    9.24  
    9.25  config TCG_ATMEL
    9.26  	tristate "Atmel TPM Interface"
    9.27 -	depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
    9.28 +	depends on TCG_TPM
    9.29  	---help---
    9.30  	  If you have a TPM security chip from Atmel say Yes and it 
    9.31  	  will be accessible from within Linux.  To compile this driver 
    10.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Wed Jun 28 07:52:21 2006 -0600
    10.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Mon Jul 03 08:35:12 2006 +0100
    10.3 @@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o
    10.4  ifdef CONFIG_ACPI
    10.5  	obj-$(CONFIG_TCG_TPM) += tpm_bios.o
    10.6  endif
    10.7 +obj-$(CONFIG_TCG_TIS) += tpm_tis.o
    10.8  obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
    10.9  obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
   10.10  obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
    11.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Wed Jun 28 07:52:21 2006 -0600
    11.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Mon Jul 03 08:35:12 2006 +0100
    11.3 @@ -30,15 +30,295 @@
    11.4  
    11.5  enum tpm_const {
    11.6  	TPM_MINOR = 224,	/* officially assigned */
    11.7 -	TPM_MIN_BUFSIZE = 2048,
    11.8 -	TPM_MAX_BUFSIZE = 64 * 1024,
    11.9 +#ifndef CONFIG_XEN
   11.10 +	TPM_BUFSIZE = 2048,
   11.11 +#endif
   11.12  	TPM_NUM_DEVICES = 256,
   11.13 -	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
   11.14  };
   11.15  
   11.16 +enum tpm_duration {
   11.17 +	TPM_SHORT = 0,
   11.18 +	TPM_MEDIUM = 1,
   11.19 +	TPM_LONG = 2,
   11.20 +	TPM_UNDEFINED,
   11.21 +};
   11.22 +
   11.23 +#define TPM_MAX_ORDINAL 243
   11.24 +#define TPM_MAX_PROTECTED_ORDINAL 12
   11.25 +#define TPM_PROTECTED_ORDINAL_MASK 0xFF
   11.26 +
   11.27  static LIST_HEAD(tpm_chip_list);
   11.28  static DEFINE_SPINLOCK(driver_lock);
   11.29 -static int dev_mask[TPM_NUM_MASK_ENTRIES];
   11.30 +static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
   11.31 +
   11.32 +/*
   11.33 + * Array with one entry per ordinal defining the maximum amount
   11.34 + * of time the chip could take to return the result.  The ordinal
   11.35 + * designation of short, medium or long is defined in a table in
   11.36 + * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
   11.37 + * values of the SHORT, MEDIUM, and LONG durations are retrieved
   11.38 + * from the chip during initialization with a call to tpm_get_timeouts.
   11.39 + */
   11.40 +static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
   11.41 +	TPM_UNDEFINED,		/* 0 */
   11.42 +	TPM_UNDEFINED,
   11.43 +	TPM_UNDEFINED,
   11.44 +	TPM_UNDEFINED,
   11.45 +	TPM_UNDEFINED,
   11.46 +	TPM_UNDEFINED,		/* 5 */
   11.47 +	TPM_UNDEFINED,
   11.48 +	TPM_UNDEFINED,
   11.49 +	TPM_UNDEFINED,
   11.50 +	TPM_UNDEFINED,
   11.51 +	TPM_SHORT,		/* 10 */
   11.52 +	TPM_SHORT,
   11.53 +};
   11.54 +
   11.55 +static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
   11.56 +	TPM_UNDEFINED,		/* 0 */
   11.57 +	TPM_UNDEFINED,
   11.58 +	TPM_UNDEFINED,
   11.59 +	TPM_UNDEFINED,
   11.60 +	TPM_UNDEFINED,
   11.61 +	TPM_UNDEFINED,		/* 5 */
   11.62 +	TPM_UNDEFINED,
   11.63 +	TPM_UNDEFINED,
   11.64 +	TPM_UNDEFINED,
   11.65 +	TPM_UNDEFINED,
   11.66 +	TPM_SHORT,		/* 10 */
   11.67 +	TPM_SHORT,
   11.68 +	TPM_MEDIUM,
   11.69 +	TPM_LONG,
   11.70 +	TPM_LONG,
   11.71 +	TPM_MEDIUM,		/* 15 */
   11.72 +	TPM_SHORT,
   11.73 +	TPM_SHORT,
   11.74 +	TPM_MEDIUM,
   11.75 +	TPM_LONG,
   11.76 +	TPM_SHORT,		/* 20 */
   11.77 +	TPM_SHORT,
   11.78 +	TPM_MEDIUM,
   11.79 +	TPM_MEDIUM,
   11.80 +	TPM_MEDIUM,
   11.81 +	TPM_SHORT,		/* 25 */
   11.82 +	TPM_SHORT,
   11.83 +	TPM_MEDIUM,
   11.84 +	TPM_SHORT,
   11.85 +	TPM_SHORT,
   11.86 +	TPM_MEDIUM,		/* 30 */
   11.87 +	TPM_LONG,
   11.88 +	TPM_MEDIUM,
   11.89 +	TPM_SHORT,
   11.90 +	TPM_SHORT,
   11.91 +	TPM_SHORT,		/* 35 */
   11.92 +	TPM_MEDIUM,
   11.93 +	TPM_MEDIUM,
   11.94 +	TPM_UNDEFINED,
   11.95 +	TPM_UNDEFINED,
   11.96 +	TPM_MEDIUM,		/* 40 */
   11.97 +	TPM_LONG,
   11.98 +	TPM_MEDIUM,
   11.99 +	TPM_SHORT,
  11.100 +	TPM_SHORT,
  11.101 +	TPM_SHORT,		/* 45 */
  11.102 +	TPM_SHORT,
  11.103 +	TPM_SHORT,
  11.104 +	TPM_SHORT,
  11.105 +	TPM_LONG,
  11.106 +	TPM_MEDIUM,		/* 50 */
  11.107 +	TPM_MEDIUM,
  11.108 +	TPM_UNDEFINED,
  11.109 +	TPM_UNDEFINED,
  11.110 +	TPM_UNDEFINED,
  11.111 +	TPM_UNDEFINED,		/* 55 */
  11.112 +	TPM_UNDEFINED,
  11.113 +	TPM_UNDEFINED,
  11.114 +	TPM_UNDEFINED,
  11.115 +	TPM_UNDEFINED,
  11.116 +	TPM_MEDIUM,		/* 60 */
  11.117 +	TPM_MEDIUM,
  11.118 +	TPM_MEDIUM,
  11.119 +	TPM_SHORT,
  11.120 +	TPM_SHORT,
  11.121 +	TPM_MEDIUM,		/* 65 */
  11.122 +	TPM_UNDEFINED,
  11.123 +	TPM_UNDEFINED,
  11.124 +	TPM_UNDEFINED,
  11.125 +	TPM_UNDEFINED,
  11.126 +	TPM_SHORT,		/* 70 */
  11.127 +	TPM_SHORT,
  11.128 +	TPM_UNDEFINED,
  11.129 +	TPM_UNDEFINED,
  11.130 +	TPM_UNDEFINED,
  11.131 +	TPM_UNDEFINED,		/* 75 */
  11.132 +	TPM_UNDEFINED,
  11.133 +	TPM_UNDEFINED,
  11.134 +	TPM_UNDEFINED,
  11.135 +	TPM_UNDEFINED,
  11.136 +	TPM_LONG,		/* 80 */
  11.137 +	TPM_UNDEFINED,
  11.138 +	TPM_MEDIUM,
  11.139 +	TPM_LONG,
  11.140 +	TPM_SHORT,
  11.141 +	TPM_UNDEFINED,		/* 85 */
  11.142 +	TPM_UNDEFINED,
  11.143 +	TPM_UNDEFINED,
  11.144 +	TPM_UNDEFINED,
  11.145 +	TPM_UNDEFINED,
  11.146 +	TPM_SHORT,		/* 90 */
  11.147 +	TPM_SHORT,
  11.148 +	TPM_SHORT,
  11.149 +	TPM_SHORT,
  11.150 +	TPM_SHORT,
  11.151 +	TPM_UNDEFINED,		/* 95 */
  11.152 +	TPM_UNDEFINED,
  11.153 +	TPM_UNDEFINED,
  11.154 +	TPM_UNDEFINED,
  11.155 +	TPM_UNDEFINED,
  11.156 +	TPM_MEDIUM,		/* 100 */
  11.157 +	TPM_SHORT,
  11.158 +	TPM_SHORT,
  11.159 +	TPM_UNDEFINED,
  11.160 +	TPM_UNDEFINED,
  11.161 +	TPM_UNDEFINED,		/* 105 */
  11.162 +	TPM_UNDEFINED,
  11.163 +	TPM_UNDEFINED,
  11.164 +	TPM_UNDEFINED,
  11.165 +	TPM_UNDEFINED,
  11.166 +	TPM_SHORT,		/* 110 */
  11.167 +	TPM_SHORT,
  11.168 +	TPM_SHORT,
  11.169 +	TPM_SHORT,
  11.170 +	TPM_SHORT,
  11.171 +	TPM_SHORT,		/* 115 */
  11.172 +	TPM_SHORT,
  11.173 +	TPM_SHORT,
  11.174 +	TPM_UNDEFINED,
  11.175 +	TPM_UNDEFINED,
  11.176 +	TPM_LONG,		/* 120 */
  11.177 +	TPM_LONG,
  11.178 +	TPM_MEDIUM,
  11.179 +	TPM_UNDEFINED,
  11.180 +	TPM_SHORT,
  11.181 +	TPM_SHORT,		/* 125 */
  11.182 +	TPM_SHORT,
  11.183 +	TPM_LONG,
  11.184 +	TPM_SHORT,
  11.185 +	TPM_SHORT,
  11.186 +	TPM_SHORT,		/* 130 */
  11.187 +	TPM_MEDIUM,
  11.188 +	TPM_UNDEFINED,
  11.189 +	TPM_SHORT,
  11.190 +	TPM_MEDIUM,
  11.191 +	TPM_UNDEFINED,		/* 135 */
  11.192 +	TPM_UNDEFINED,
  11.193 +	TPM_UNDEFINED,
  11.194 +	TPM_UNDEFINED,
  11.195 +	TPM_UNDEFINED,
  11.196 +	TPM_SHORT,		/* 140 */
  11.197 +	TPM_SHORT,
  11.198 +	TPM_UNDEFINED,
  11.199 +	TPM_UNDEFINED,
  11.200 +	TPM_UNDEFINED,
  11.201 +	TPM_UNDEFINED,		/* 145 */
  11.202 +	TPM_UNDEFINED,
  11.203 +	TPM_UNDEFINED,
  11.204 +	TPM_UNDEFINED,
  11.205 +	TPM_UNDEFINED,
  11.206 +	TPM_SHORT,		/* 150 */
  11.207 +	TPM_MEDIUM,
  11.208 +	TPM_MEDIUM,
  11.209 +	TPM_SHORT,
  11.210 +	TPM_SHORT,
  11.211 +	TPM_UNDEFINED,		/* 155 */
  11.212 +	TPM_UNDEFINED,
  11.213 +	TPM_UNDEFINED,
  11.214 +	TPM_UNDEFINED,
  11.215 +	TPM_UNDEFINED,
  11.216 +	TPM_SHORT,		/* 160 */
  11.217 +	TPM_SHORT,
  11.218 +	TPM_SHORT,
  11.219 +	TPM_SHORT,
  11.220 +	TPM_UNDEFINED,
  11.221 +	TPM_UNDEFINED,		/* 165 */
  11.222 +	TPM_UNDEFINED,
  11.223 +	TPM_UNDEFINED,
  11.224 +	TPM_UNDEFINED,
  11.225 +	TPM_UNDEFINED,
  11.226 +	TPM_LONG,		/* 170 */
  11.227 +	TPM_UNDEFINED,
  11.228 +	TPM_UNDEFINED,
  11.229 +	TPM_UNDEFINED,
  11.230 +	TPM_UNDEFINED,
  11.231 +	TPM_UNDEFINED,		/* 175 */
  11.232 +	TPM_UNDEFINED,
  11.233 +	TPM_UNDEFINED,
  11.234 +	TPM_UNDEFINED,
  11.235 +	TPM_UNDEFINED,
  11.236 +	TPM_MEDIUM,		/* 180 */
  11.237 +	TPM_SHORT,
  11.238 +	TPM_MEDIUM,
  11.239 +	TPM_MEDIUM,
  11.240 +	TPM_MEDIUM,
  11.241 +	TPM_MEDIUM,		/* 185 */
  11.242 +	TPM_SHORT,
  11.243 +	TPM_UNDEFINED,
  11.244 +	TPM_UNDEFINED,
  11.245 +	TPM_UNDEFINED,
  11.246 +	TPM_UNDEFINED,		/* 190 */
  11.247 +	TPM_UNDEFINED,
  11.248 +	TPM_UNDEFINED,
  11.249 +	TPM_UNDEFINED,
  11.250 +	TPM_UNDEFINED,
  11.251 +	TPM_UNDEFINED,		/* 195 */
  11.252 +	TPM_UNDEFINED,
  11.253 +	TPM_UNDEFINED,
  11.254 +	TPM_UNDEFINED,
  11.255 +	TPM_UNDEFINED,
  11.256 +	TPM_SHORT,		/* 200 */
  11.257 +	TPM_UNDEFINED,
  11.258 +	TPM_UNDEFINED,
  11.259 +	TPM_UNDEFINED,
  11.260 +	TPM_SHORT,
  11.261 +	TPM_SHORT,		/* 205 */
  11.262 +	TPM_SHORT,
  11.263 +	TPM_SHORT,
  11.264 +	TPM_SHORT,
  11.265 +	TPM_SHORT,
  11.266 +	TPM_MEDIUM,		/* 210 */
  11.267 +	TPM_UNDEFINED,
  11.268 +	TPM_MEDIUM,
  11.269 +	TPM_MEDIUM,
  11.270 +	TPM_MEDIUM,
  11.271 +	TPM_UNDEFINED,		/* 215 */
  11.272 +	TPM_MEDIUM,
  11.273 +	TPM_UNDEFINED,
  11.274 +	TPM_UNDEFINED,
  11.275 +	TPM_SHORT,
  11.276 +	TPM_SHORT,		/* 220 */
  11.277 +	TPM_SHORT,
  11.278 +	TPM_SHORT,
  11.279 +	TPM_SHORT,
  11.280 +	TPM_SHORT,
  11.281 +	TPM_UNDEFINED,		/* 225 */
  11.282 +	TPM_UNDEFINED,
  11.283 +	TPM_UNDEFINED,
  11.284 +	TPM_UNDEFINED,
  11.285 +	TPM_UNDEFINED,
  11.286 +	TPM_SHORT,		/* 230 */
  11.287 +	TPM_LONG,
  11.288 +	TPM_MEDIUM,
  11.289 +	TPM_UNDEFINED,
  11.290 +	TPM_UNDEFINED,
  11.291 +	TPM_UNDEFINED,		/* 235 */
  11.292 +	TPM_UNDEFINED,
  11.293 +	TPM_UNDEFINED,
  11.294 +	TPM_UNDEFINED,
  11.295 +	TPM_UNDEFINED,
  11.296 +	TPM_SHORT,		/* 240 */
  11.297 +	TPM_UNDEFINED,
  11.298 +	TPM_MEDIUM,
  11.299 +};
  11.300  
  11.301  static void user_reader_timeout(unsigned long ptr)
  11.302  {
  11.303 @@ -47,28 +327,58 @@ static void user_reader_timeout(unsigned
  11.304  	schedule_work(&chip->work);
  11.305  }
  11.306  
  11.307 -static void timeout_work(void * ptr)
  11.308 +static void timeout_work(void *ptr)
  11.309  {
  11.310  	struct tpm_chip *chip = ptr;
  11.311  
  11.312  	down(&chip->buffer_mutex);
  11.313  	atomic_set(&chip->data_pending, 0);
  11.314 +#ifndef CONFIG_XEN
  11.315 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
  11.316 +#else
  11.317  	memset(chip->data_buffer, 0, get_chip_buffersize(chip));
  11.318 +#endif
  11.319  	up(&chip->buffer_mutex);
  11.320  }
  11.321  
  11.322  /*
  11.323 + * Returns max number of jiffies to wait
  11.324 + */
  11.325 +unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  11.326 +					   u32 ordinal)
  11.327 +{
  11.328 +	int duration_idx = TPM_UNDEFINED;
  11.329 +	int duration = 0;
  11.330 +
  11.331 +	if (ordinal < TPM_MAX_ORDINAL)
  11.332 +		duration_idx = tpm_ordinal_duration[ordinal];
  11.333 +	else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
  11.334 +		 TPM_MAX_PROTECTED_ORDINAL)
  11.335 +		duration_idx =
  11.336 +		    tpm_protected_ordinal_duration[ordinal &
  11.337 +						   TPM_PROTECTED_ORDINAL_MASK];
  11.338 +
  11.339 +	if (duration_idx != TPM_UNDEFINED)
  11.340 +		duration = chip->vendor.duration[duration_idx];
  11.341 +	if (duration <= 0)
  11.342 +		return 2 * 60 * HZ;
  11.343 +	else
  11.344 +		return duration;
  11.345 +}
  11.346 +EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
  11.347 +
  11.348 +/*
  11.349   * Internal kernel interface to transmit TPM commands
  11.350   */
  11.351 -static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
  11.352 +static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
  11.353  			    size_t bufsiz)
  11.354  {
  11.355  	ssize_t rc;
  11.356 -	u32 count;
  11.357 +	u32 count, ordinal;
  11.358  	unsigned long stop;
  11.359  
  11.360  	count = be32_to_cpu(*((__be32 *) (buf + 2)));
  11.361 -
  11.362 +	ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
  11.363  	if (count == 0)
  11.364  		return -ENODATA;
  11.365  	if (count > bufsiz) {
  11.366 @@ -79,21 +389,23 @@ static ssize_t tpm_transmit(struct tpm_c
  11.367  
  11.368  	down(&chip->tpm_mutex);
  11.369  
  11.370 -	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
  11.371 +	if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
  11.372  		dev_err(chip->dev,
  11.373  			"tpm_transmit: tpm_send: error %zd\n", rc);
  11.374  		goto out;
  11.375  	}
  11.376  
  11.377 -	stop = jiffies + 2 * 60 * HZ;
  11.378 +	if (chip->vendor.irq)
  11.379 +		goto out_recv;
  11.380 +
  11.381 +	stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
  11.382  	do {
  11.383 -		u8 status = chip->vendor->status(chip);
  11.384 -		if ((status & chip->vendor->req_complete_mask) ==
  11.385 -		    chip->vendor->req_complete_val) {
  11.386 +		u8 status = chip->vendor.status(chip);
  11.387 +		if ((status & chip->vendor.req_complete_mask) ==
  11.388 +		    chip->vendor.req_complete_val)
  11.389  			goto out_recv;
  11.390 -		}
  11.391  
  11.392 -		if ((status == chip->vendor->req_canceled)) {
  11.393 +		if ((status == chip->vendor.req_canceled)) {
  11.394  			dev_err(chip->dev, "Operation Canceled\n");
  11.395  			rc = -ECANCELED;
  11.396  			goto out;
  11.397 @@ -103,14 +415,13 @@ static ssize_t tpm_transmit(struct tpm_c
  11.398  		rmb();
  11.399  	} while (time_before(jiffies, stop));
  11.400  
  11.401 -
  11.402 -	chip->vendor->cancel(chip);
  11.403 +	chip->vendor.cancel(chip);
  11.404  	dev_err(chip->dev, "Operation Timed out\n");
  11.405  	rc = -ETIME;
  11.406  	goto out;
  11.407  
  11.408  out_recv:
  11.409 -	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
  11.410 +	rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
  11.411  	if (rc < 0)
  11.412  		dev_err(chip->dev,
  11.413  			"tpm_transmit: tpm_recv: error %zd\n", rc);
  11.414 @@ -120,17 +431,247 @@ out:
  11.415  }
  11.416  
  11.417  #define TPM_DIGEST_SIZE 20
  11.418 -#define CAP_PCR_RESULT_SIZE 18
  11.419 -static const u8 cap_pcr[] = {
  11.420 +#define TPM_ERROR_SIZE 10
  11.421 +#define TPM_RET_CODE_IDX 6
  11.422 +#define TPM_GET_CAP_RET_SIZE_IDX 10
  11.423 +#define TPM_GET_CAP_RET_UINT32_1_IDX 14
  11.424 +#define TPM_GET_CAP_RET_UINT32_2_IDX 18
  11.425 +#define TPM_GET_CAP_RET_UINT32_3_IDX 22
  11.426 +#define TPM_GET_CAP_RET_UINT32_4_IDX 26
  11.427 +#define TPM_GET_CAP_PERM_DISABLE_IDX 16
  11.428 +#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
  11.429 +#define TPM_GET_CAP_RET_BOOL_1_IDX 14
  11.430 +#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
  11.431 +
  11.432 +#define TPM_CAP_IDX 13
  11.433 +#define TPM_CAP_SUBCAP_IDX 21
  11.434 +
  11.435 +enum tpm_capabilities {
  11.436 +	TPM_CAP_FLAG = 4,
  11.437 +	TPM_CAP_PROP = 5,
  11.438 +};
  11.439 +
  11.440 +enum tpm_sub_capabilities {
  11.441 +	TPM_CAP_PROP_PCR = 0x1,
  11.442 +	TPM_CAP_PROP_MANUFACTURER = 0x3,
  11.443 +	TPM_CAP_FLAG_PERM = 0x8,
  11.444 +	TPM_CAP_FLAG_VOL = 0x9,
  11.445 +	TPM_CAP_PROP_OWNER = 0x11,
  11.446 +	TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
  11.447 +	TPM_CAP_PROP_TIS_DURATION = 0x20,
  11.448 +};
  11.449 +
  11.450 +/*
  11.451 + * This is a semi generic GetCapability command for use
  11.452 + * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
  11.453 + * and their associated sub_capabilities.
  11.454 + */
  11.455 +
  11.456 +static const u8 tpm_cap[] = {
  11.457  	0, 193,			/* TPM_TAG_RQU_COMMAND */
  11.458  	0, 0, 0, 22,		/* length */
  11.459  	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  11.460 -	0, 0, 0, 5,
  11.461 -	0, 0, 0, 4,
  11.462 -	0, 0, 1, 1
  11.463 +	0, 0, 0, 0,		/* TPM_CAP_<TYPE> */
  11.464 +	0, 0, 0, 4,		/* TPM_CAP_SUB_<TYPE> size */
  11.465 +	0, 0, 1, 0		/* TPM_CAP_SUB_<TYPE> */
  11.466  };
  11.467  
  11.468 -#define READ_PCR_RESULT_SIZE 30
  11.469 +static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
  11.470 +			    char *desc)
  11.471 +{
  11.472 +	int err;
  11.473 +
  11.474 +	len = tpm_transmit(chip, data, len);
  11.475 +	if (len <  0)
  11.476 +		return len;
  11.477 +	if (len == TPM_ERROR_SIZE) {
  11.478 +		err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
  11.479 +		dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
  11.480 +		return err;
  11.481 +	}
  11.482 +	return 0;
  11.483 +}
  11.484 +
  11.485 +void tpm_gen_interrupt(struct tpm_chip *chip)
  11.486 +{
  11.487 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
  11.488 +	ssize_t rc;
  11.489 +
  11.490 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.491 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.492 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
  11.493 +
  11.494 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.495 +			"attempting to determine the timeouts");
  11.496 +}
  11.497 +EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
  11.498 +
  11.499 +void tpm_get_timeouts(struct tpm_chip *chip)
  11.500 +{
  11.501 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
  11.502 +	ssize_t rc;
  11.503 +	u32 timeout;
  11.504 +
  11.505 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.506 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.507 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
  11.508 +
  11.509 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.510 +			"attempting to determine the timeouts");
  11.511 +	if (rc)
  11.512 +		goto duration;
  11.513 +
  11.514 +	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
  11.515 +	    != 4 * sizeof(u32))
  11.516 +		goto duration;
  11.517 +
  11.518 +	/* Don't overwrite default if value is 0 */
  11.519 +	timeout =
  11.520 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
  11.521 +	if (timeout)
  11.522 +		chip->vendor.timeout_a = msecs_to_jiffies(timeout);
  11.523 +	timeout =
  11.524 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
  11.525 +	if (timeout)
  11.526 +		chip->vendor.timeout_b = msecs_to_jiffies(timeout);
  11.527 +	timeout =
  11.528 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
  11.529 +	if (timeout)
  11.530 +		chip->vendor.timeout_c = msecs_to_jiffies(timeout);
  11.531 +	timeout =
  11.532 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
  11.533 +	if (timeout)
  11.534 +		chip->vendor.timeout_d = msecs_to_jiffies(timeout);
  11.535 +
  11.536 +duration:
  11.537 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.538 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.539 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
  11.540 +
  11.541 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.542 +			"attempting to determine the durations");
  11.543 +	if (rc)
  11.544 +		return;
  11.545 +
  11.546 +	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
  11.547 +	    != 3 * sizeof(u32))
  11.548 +		return;
  11.549 +
  11.550 +	chip->vendor.duration[TPM_SHORT] =
  11.551 +	    msecs_to_jiffies(be32_to_cpu
  11.552 +			     (*((__be32 *) (data +
  11.553 +					    TPM_GET_CAP_RET_UINT32_1_IDX))));
  11.554 +	chip->vendor.duration[TPM_MEDIUM] =
  11.555 +	    msecs_to_jiffies(be32_to_cpu
  11.556 +			     (*((__be32 *) (data +
  11.557 +					    TPM_GET_CAP_RET_UINT32_2_IDX))));
  11.558 +	chip->vendor.duration[TPM_LONG] =
  11.559 +	    msecs_to_jiffies(be32_to_cpu
  11.560 +			     (*((__be32 *) (data +
  11.561 +					    TPM_GET_CAP_RET_UINT32_3_IDX))));
  11.562 +}
  11.563 +EXPORT_SYMBOL_GPL(tpm_get_timeouts);
  11.564 +
  11.565 +void tpm_continue_selftest(struct tpm_chip *chip)
  11.566 +{
  11.567 +	u8 data[] = {
  11.568 +		0, 193,			/* TPM_TAG_RQU_COMMAND */
  11.569 +		0, 0, 0, 10,		/* length */
  11.570 +		0, 0, 0, 83,		/* TPM_ORD_GetCapability */
  11.571 +	};
  11.572 +
  11.573 +	tpm_transmit(chip, data, sizeof(data));
  11.574 +}
  11.575 +EXPORT_SYMBOL_GPL(tpm_continue_selftest);
  11.576 +
  11.577 +ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
  11.578 +			char *buf)
  11.579 +{
  11.580 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
  11.581 +	ssize_t rc;
  11.582 +
  11.583 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  11.584 +	if (chip == NULL)
  11.585 +		return -ENODEV;
  11.586 +
  11.587 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.588 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  11.589 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
  11.590 +
  11.591 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.592 +			"attemtping to determine the permanent state");
  11.593 +	if (rc)
  11.594 +		return 0;
  11.595 +	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
  11.596 +}
  11.597 +EXPORT_SYMBOL_GPL(tpm_show_enabled);
  11.598 +
  11.599 +ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
  11.600 +			char *buf)
  11.601 +{
  11.602 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
  11.603 +	ssize_t rc;
  11.604 +
  11.605 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  11.606 +	if (chip == NULL)
  11.607 +		return -ENODEV;
  11.608 +
  11.609 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.610 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  11.611 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
  11.612 +
  11.613 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.614 +			"attemtping to determine the permanent state");
  11.615 +	if (rc)
  11.616 +		return 0;
  11.617 +	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
  11.618 +}
  11.619 +EXPORT_SYMBOL_GPL(tpm_show_active);
  11.620 +
  11.621 +ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
  11.622 +			char *buf)
  11.623 +{
  11.624 +	u8 data[sizeof(tpm_cap)];
  11.625 +	ssize_t rc;
  11.626 +
  11.627 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  11.628 +	if (chip == NULL)
  11.629 +		return -ENODEV;
  11.630 +
  11.631 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.632 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.633 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
  11.634 +
  11.635 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.636 +			"attempting to determine the owner state");
  11.637 +	if (rc)
  11.638 +		return 0;
  11.639 +	return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
  11.640 +}
  11.641 +EXPORT_SYMBOL_GPL(tpm_show_owned);
  11.642 +
  11.643 +ssize_t tpm_show_temp_deactivated(struct device * dev,
  11.644 +				struct device_attribute * attr, char *buf)
  11.645 +{
  11.646 +	u8 data[sizeof(tpm_cap)];
  11.647 +	ssize_t rc;
  11.648 +
  11.649 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  11.650 +	if (chip == NULL)
  11.651 +		return -ENODEV;
  11.652 +
  11.653 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.654 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
  11.655 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
  11.656 +
  11.657 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.658 +			"attempting to determine the temporary state");
  11.659 +	if (rc)
  11.660 +		return 0;
  11.661 +	return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
  11.662 +}
  11.663 +EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
  11.664 +
  11.665  static const u8 pcrread[] = {
  11.666  	0, 193,			/* TPM_TAG_RQU_COMMAND */
  11.667  	0, 0, 0, 14,		/* length */
  11.668 @@ -141,8 +682,8 @@ static const u8 pcrread[] = {
  11.669  ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
  11.670  		      char *buf)
  11.671  {
  11.672 -	u8 data[READ_PCR_RESULT_SIZE];
  11.673 -	ssize_t len;
  11.674 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
  11.675 +	ssize_t rc;
  11.676  	int i, j, num_pcrs;
  11.677  	__be32 index;
  11.678  	char *str = buf;
  11.679 @@ -151,29 +692,24 @@ ssize_t tpm_show_pcrs(struct device *dev
  11.680  	if (chip == NULL)
  11.681  		return -ENODEV;
  11.682  
  11.683 -	memcpy(data, cap_pcr, sizeof(cap_pcr));
  11.684 -	if ((len = tpm_transmit(chip, data, sizeof(data)))
  11.685 -	    < CAP_PCR_RESULT_SIZE) {
  11.686 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  11.687 -				"attempting to determine the number of PCRS\n",
  11.688 -			be32_to_cpu(*((__be32 *) (data + 6))));
  11.689 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.690 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.691 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
  11.692 +
  11.693 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.694 +			"attempting to determine the number of PCRS");
  11.695 +	if (rc)
  11.696  		return 0;
  11.697 -	}
  11.698  
  11.699  	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
  11.700 -
  11.701  	for (i = 0; i < num_pcrs; i++) {
  11.702  		memcpy(data, pcrread, sizeof(pcrread));
  11.703  		index = cpu_to_be32(i);
  11.704  		memcpy(data + 10, &index, 4);
  11.705 -		if ((len = tpm_transmit(chip, data, sizeof(data)))
  11.706 -		    < READ_PCR_RESULT_SIZE){
  11.707 -			dev_dbg(chip->dev, "A TPM error (%d) occurred"
  11.708 -				" attempting to read PCR %d of %d\n",
  11.709 -				be32_to_cpu(*((__be32 *) (data + 6))),
  11.710 -				i, num_pcrs);
  11.711 +		rc = transmit_cmd(chip, data, sizeof(data),
  11.712 +				"attempting to read a PCR");
  11.713 +		if (rc)
  11.714  			goto out;
  11.715 -		}
  11.716  		str += sprintf(str, "PCR-%02d: ", i);
  11.717  		for (j = 0; j < TPM_DIGEST_SIZE; j++)
  11.718  			str += sprintf(str, "%02X ", *(data + 10 + j));
  11.719 @@ -195,7 +731,7 @@ ssize_t tpm_show_pubek(struct device *de
  11.720  		       char *buf)
  11.721  {
  11.722  	u8 *data;
  11.723 -	ssize_t len;
  11.724 +	ssize_t err;
  11.725  	int i, rc;
  11.726  	char *str = buf;
  11.727  
  11.728 @@ -209,14 +745,10 @@ ssize_t tpm_show_pubek(struct device *de
  11.729  
  11.730  	memcpy(data, readpubek, sizeof(readpubek));
  11.731  
  11.732 -	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
  11.733 -	    READ_PUBEK_RESULT_SIZE) {
  11.734 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  11.735 -				"attempting to read the PUBEK\n",
  11.736 -			    be32_to_cpu(*((__be32 *) (data + 6))));
  11.737 -		rc = 0;
  11.738 +	err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
  11.739 +			"attempting to read the PUBEK");
  11.740 +	if (err)
  11.741  		goto out;
  11.742 -	}
  11.743  
  11.744  	/* 
  11.745  	   ignore header 10 bytes
  11.746 @@ -246,36 +778,68 @@ ssize_t tpm_show_pubek(struct device *de
  11.747  		if ((i + 1) % 16 == 0)
  11.748  			str += sprintf(str, "\n");
  11.749  	}
  11.750 +out:
  11.751  	rc = str - buf;
  11.752 -out:
  11.753  	kfree(data);
  11.754  	return rc;
  11.755  }
  11.756  EXPORT_SYMBOL_GPL(tpm_show_pubek);
  11.757  
  11.758 -#define CAP_VER_RESULT_SIZE 18
  11.759 +#define CAP_VERSION_1_1 6
  11.760 +#define CAP_VERSION_1_2 0x1A
  11.761 +#define CAP_VERSION_IDX 13
  11.762  static const u8 cap_version[] = {
  11.763  	0, 193,			/* TPM_TAG_RQU_COMMAND */
  11.764  	0, 0, 0, 18,		/* length */
  11.765  	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  11.766 -	0, 0, 0, 6,
  11.767 +	0, 0, 0, 0,
  11.768  	0, 0, 0, 0
  11.769  };
  11.770  
  11.771 -#define CAP_MANUFACTURER_RESULT_SIZE 18
  11.772 -static const u8 cap_manufacturer[] = {
  11.773 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
  11.774 -	0, 0, 0, 22,		/* length */
  11.775 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
  11.776 -	0, 0, 0, 5,
  11.777 -	0, 0, 0, 4,
  11.778 -	0, 0, 1, 3
  11.779 -};
  11.780 -
  11.781  ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
  11.782  		      char *buf)
  11.783  {
  11.784 -	u8 data[sizeof(cap_manufacturer)];
  11.785 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
  11.786 +	ssize_t rc;
  11.787 +	char *str = buf;
  11.788 +
  11.789 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  11.790 +	if (chip == NULL)
  11.791 +		return -ENODEV;
  11.792 +
  11.793 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.794 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.795 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
  11.796 +
  11.797 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.798 +			"attempting to determine the manufacturer");
  11.799 +	if (rc)
  11.800 +		return 0;
  11.801 +
  11.802 +	str += sprintf(str, "Manufacturer: 0x%x\n",
  11.803 +		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
  11.804 +
  11.805 +	memcpy(data, cap_version, sizeof(cap_version));
  11.806 +	data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
  11.807 +	rc = transmit_cmd(chip, data, sizeof(data),
  11.808 +			"attempting to determine the 1.1 version");
  11.809 +	if (rc)
  11.810 +		goto out;
  11.811 +
  11.812 +	str += sprintf(str,
  11.813 +		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
  11.814 +		       (int) data[14], (int) data[15], (int) data[16],
  11.815 +		       (int) data[17]);
  11.816 +
  11.817 +out:
  11.818 +	return str - buf;
  11.819 +}
  11.820 +EXPORT_SYMBOL_GPL(tpm_show_caps);
  11.821 +
  11.822 +ssize_t tpm_show_caps_1_2(struct device * dev,
  11.823 +			  struct device_attribute * attr, char *buf)
  11.824 +{
  11.825 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
  11.826  	ssize_t len;
  11.827  	char *str = buf;
  11.828  
  11.829 @@ -283,29 +847,40 @@ ssize_t tpm_show_caps(struct device *dev
  11.830  	if (chip == NULL)
  11.831  		return -ENODEV;
  11.832  
  11.833 -	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
  11.834 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
  11.835 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
  11.836 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
  11.837  
  11.838 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  11.839 -	    CAP_MANUFACTURER_RESULT_SIZE)
  11.840 -		return len;
  11.841 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
  11.842 +	    TPM_ERROR_SIZE) {
  11.843 +		dev_dbg(chip->dev, "A TPM error (%d) occurred "
  11.844 +			"attempting to determine the manufacturer\n",
  11.845 +			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
  11.846 +		return 0;
  11.847 +	}
  11.848  
  11.849  	str += sprintf(str, "Manufacturer: 0x%x\n",
  11.850 -		       be32_to_cpu(*((__be32 *) (data + 14))));
  11.851 +		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
  11.852  
  11.853  	memcpy(data, cap_version, sizeof(cap_version));
  11.854 -
  11.855 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
  11.856 -	    CAP_VER_RESULT_SIZE)
  11.857 -		return len;
  11.858 +	data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
  11.859  
  11.860 -	str +=
  11.861 -	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
  11.862 -		    (int) data[14], (int) data[15], (int) data[16],
  11.863 -		    (int) data[17]);
  11.864 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
  11.865 +	    TPM_ERROR_SIZE) {
  11.866 +		dev_err(chip->dev, "A TPM error (%d) occurred "
  11.867 +			"attempting to determine the 1.2 version\n",
  11.868 +			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
  11.869 +		goto out;
  11.870 +	}
  11.871 +	str += sprintf(str,
  11.872 +		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
  11.873 +		       (int) data[16], (int) data[17], (int) data[18],
  11.874 +		       (int) data[19]);
  11.875  
  11.876 +out:
  11.877  	return str - buf;
  11.878  }
  11.879 -EXPORT_SYMBOL_GPL(tpm_show_caps);
  11.880 +EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
  11.881  
  11.882  ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
  11.883  			const char *buf, size_t count)
  11.884 @@ -314,7 +889,7 @@ ssize_t tpm_store_cancel(struct device *
  11.885  	if (chip == NULL)
  11.886  		return 0;
  11.887  
  11.888 -	chip->vendor->cancel(chip);
  11.889 +	chip->vendor.cancel(chip);
  11.890  	return count;
  11.891  }
  11.892  EXPORT_SYMBOL_GPL(tpm_store_cancel);
  11.893 @@ -330,7 +905,7 @@ int tpm_open(struct inode *inode, struct
  11.894  	spin_lock(&driver_lock);
  11.895  
  11.896  	list_for_each_entry(pos, &tpm_chip_list, list) {
  11.897 -		if (pos->vendor->miscdev.minor == minor) {
  11.898 +		if (pos->vendor.miscdev.minor == minor) {
  11.899  			chip = pos;
  11.900  			break;
  11.901  		}
  11.902 @@ -352,7 +927,12 @@ int tpm_open(struct inode *inode, struct
  11.903  
  11.904  	spin_unlock(&driver_lock);
  11.905  
  11.906 -	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8), GFP_KERNEL);
  11.907 +#ifndef CONFIG_XEN
  11.908 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
  11.909 +#else
  11.910 +	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
  11.911 +	                            GFP_KERNEL);
  11.912 +#endif
  11.913  	if (chip->data_buffer == NULL) {
  11.914  		chip->num_opens--;
  11.915  		put_device(chip->dev);
  11.916 @@ -388,7 +968,7 @@ int tpm_release(struct inode *inode, str
  11.917  EXPORT_SYMBOL_GPL(tpm_release);
  11.918  
  11.919  ssize_t tpm_write(struct file *file, const char __user *buf,
  11.920 -		  size_t size, loff_t * off)
  11.921 +		  size_t size, loff_t *off)
  11.922  {
  11.923  	struct tpm_chip *chip = file->private_data;
  11.924  	int in_size = size, out_size;
  11.925 @@ -400,8 +980,13 @@ ssize_t tpm_write(struct file *file, con
  11.926  
  11.927  	down(&chip->buffer_mutex);
  11.928  
  11.929 +#ifndef CONFIG_XEN
  11.930 +	if (in_size > TPM_BUFSIZE)
  11.931 +		in_size = TPM_BUFSIZE;
  11.932 +#else
  11.933  	if (in_size > get_chip_buffersize(chip))
  11.934  		in_size = get_chip_buffersize(chip);
  11.935 +#endif
  11.936  
  11.937  	if (copy_from_user
  11.938  	    (chip->data_buffer, (void __user *) buf, in_size)) {
  11.939 @@ -410,11 +995,17 @@ ssize_t tpm_write(struct file *file, con
  11.940  	}
  11.941  
  11.942  	/* atomic tpm command send and result receive */
  11.943 -	out_size = tpm_transmit(chip, chip->data_buffer, 
  11.944 +#ifndef CONFIG_XEN
  11.945 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
  11.946 +#else
  11.947 +	out_size = tpm_transmit(chip, chip->data_buffer,
  11.948  	                        get_chip_buffersize(chip));
  11.949 +#endif
  11.950  
  11.951  	atomic_set(&chip->data_pending, out_size);
  11.952 +#ifdef CONFIG_XEN
  11.953  	atomic_set(&chip->data_position, 0);
  11.954 +#endif
  11.955  	up(&chip->buffer_mutex);
  11.956  
  11.957  	/* Set a timeout by which the reader must come claim the result */
  11.958 @@ -422,42 +1013,59 @@ ssize_t tpm_write(struct file *file, con
  11.959  
  11.960  	return in_size;
  11.961  }
  11.962 -
  11.963  EXPORT_SYMBOL_GPL(tpm_write);
  11.964  
  11.965 -ssize_t tpm_read(struct file * file, char __user *buf,
  11.966 -		 size_t size, loff_t * off)
  11.967 +ssize_t tpm_read(struct file *file, char __user *buf,
  11.968 +		 size_t size, loff_t *off)
  11.969  {
  11.970  	struct tpm_chip *chip = file->private_data;
  11.971  	int ret_size;
  11.972 +#ifdef CONFIG_XEN
  11.973  	int pos, pending = 0;
  11.974 +#endif
  11.975  
  11.976 +#ifndef CONFIG_XEN
  11.977 +	del_singleshot_timer_sync(&chip->user_read_timer);
  11.978 +	flush_scheduled_work();
  11.979 +#endif
  11.980  	ret_size = atomic_read(&chip->data_pending);
  11.981 +#ifndef CONFIG_XEN
  11.982 +	atomic_set(&chip->data_pending, 0);
  11.983 +#endif
  11.984  	if (ret_size > 0) {	/* relay data */
  11.985  		if (size < ret_size)
  11.986  			ret_size = size;
  11.987  
  11.988 +#ifdef CONFIG_XEN
  11.989  		pos = atomic_read(&chip->data_position);
  11.990 -
  11.991 +#endif
  11.992  		down(&chip->buffer_mutex);
  11.993 +#ifndef CONFIG_XEN
  11.994 +		if (copy_to_user(buf, chip->data_buffer, ret_size))
  11.995 +#else
  11.996  		if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
  11.997 +#endif
  11.998  			ret_size = -EFAULT;
  11.999 +#ifdef CONFIG_XEN
 11.1000  		} else {
 11.1001  			pending = atomic_read(&chip->data_pending) - ret_size;
 11.1002  			if ( pending ) {
 11.1003 -				atomic_set( &chip->data_pending, pending );
 11.1004 -				atomic_set( &chip->data_position, pos+ret_size );
 11.1005 +				atomic_set(&chip->data_pending, pending);
 11.1006 +				atomic_set(&chip->data_position,
 11.1007 +				           pos+ret_size);
 11.1008  			}
 11.1009  		}
 11.1010 +#endif
 11.1011  		up(&chip->buffer_mutex);
 11.1012  	}
 11.1013 -	
 11.1014 -	if ( ret_size <= 0 || pending == 0 ) {
 11.1015 -		atomic_set( &chip->data_pending, 0 );
 11.1016 +
 11.1017 +#ifdef CONFIG_XEN
 11.1018 + 	if ( ret_size <= 0 || pending == 0 ) {
 11.1019 +		atomic_set(&chip->data_pending, 0);
 11.1020  		del_singleshot_timer_sync(&chip->user_read_timer);
 11.1021  		flush_scheduled_work();
 11.1022  	}
 11.1023 -
 11.1024 +#endif
 11.1025  	return ret_size;
 11.1026  }
 11.1027  EXPORT_SYMBOL_GPL(tpm_read);
 11.1028 @@ -478,14 +1086,13 @@ void tpm_remove_hardware(struct device *
 11.1029  	spin_unlock(&driver_lock);
 11.1030  
 11.1031  	dev_set_drvdata(dev, NULL);
 11.1032 -	misc_deregister(&chip->vendor->miscdev);
 11.1033 -	kfree(chip->vendor->miscdev.name);
 11.1034 +	misc_deregister(&chip->vendor.miscdev);
 11.1035 +	kfree(chip->vendor.miscdev.name);
 11.1036  
 11.1037 -	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
 11.1038 +	sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
 11.1039  	tpm_bios_log_teardown(chip->bios_dir);
 11.1040  
 11.1041 -	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
 11.1042 -		~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
 11.1043 +	clear_bit(chip->dev_num, dev_mask);
 11.1044  
 11.1045  	kfree(chip);
 11.1046  
 11.1047 @@ -536,18 +1143,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
 11.1048   * upon errant exit from this function specific probe function should call
 11.1049   * pci_disable_device
 11.1050   */
 11.1051 -int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
 11.1052 +struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
 11.1053 +				       *entry)
 11.1054  {
 11.1055  #define DEVNAME_SIZE 7
 11.1056  
 11.1057  	char *devname;
 11.1058  	struct tpm_chip *chip;
 11.1059 -	int i, j;
 11.1060  
 11.1061  	/* Driver specific per-device data */
 11.1062  	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 11.1063  	if (chip == NULL)
 11.1064 -		return -ENOMEM;
 11.1065 +		return NULL;
 11.1066  
 11.1067  	init_MUTEX(&chip->buffer_mutex);
 11.1068  	init_MUTEX(&chip->tpm_mutex);
 11.1069 @@ -559,51 +1166,37 @@ int tpm_register_hardware(struct device 
 11.1070  	chip->user_read_timer.function = user_reader_timeout;
 11.1071  	chip->user_read_timer.data = (unsigned long) chip;
 11.1072  
 11.1073 -	chip->vendor = entry;
 11.1074 -	
 11.1075 -	if (entry->buffersize < TPM_MIN_BUFSIZE) {
 11.1076 -		entry->buffersize = TPM_MIN_BUFSIZE;
 11.1077 -	} else if (entry->buffersize > TPM_MAX_BUFSIZE) {
 11.1078 -		entry->buffersize = TPM_MAX_BUFSIZE;
 11.1079 -	}
 11.1080 -
 11.1081 -	chip->dev_num = -1;
 11.1082 +	memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
 11.1083  
 11.1084 -	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
 11.1085 -		for (j = 0; j < 8 * sizeof(int); j++)
 11.1086 -			if ((dev_mask[i] & (1 << j)) == 0) {
 11.1087 -				chip->dev_num =
 11.1088 -				    i * TPM_NUM_MASK_ENTRIES + j;
 11.1089 -				dev_mask[i] |= 1 << j;
 11.1090 -				goto dev_num_search_complete;
 11.1091 -			}
 11.1092 +	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
 11.1093  
 11.1094 -dev_num_search_complete:
 11.1095 -	if (chip->dev_num < 0) {
 11.1096 +	if (chip->dev_num >= TPM_NUM_DEVICES) {
 11.1097  		dev_err(dev, "No available tpm device numbers\n");
 11.1098  		kfree(chip);
 11.1099 -		return -ENODEV;
 11.1100 +		return NULL;
 11.1101  	} else if (chip->dev_num == 0)
 11.1102 -		chip->vendor->miscdev.minor = TPM_MINOR;
 11.1103 +		chip->vendor.miscdev.minor = TPM_MINOR;
 11.1104  	else
 11.1105 -		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
 11.1106 +		chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
 11.1107 +
 11.1108 +	set_bit(chip->dev_num, dev_mask);
 11.1109  
 11.1110  	devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
 11.1111  	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
 11.1112 -	chip->vendor->miscdev.name = devname;
 11.1113 +	chip->vendor.miscdev.name = devname;
 11.1114  
 11.1115 -	chip->vendor->miscdev.dev = dev;
 11.1116 +	chip->vendor.miscdev.dev = dev;
 11.1117  	chip->dev = get_device(dev);
 11.1118  
 11.1119 -	if (misc_register(&chip->vendor->miscdev)) {
 11.1120 +	if (misc_register(&chip->vendor.miscdev)) {
 11.1121  		dev_err(chip->dev,
 11.1122  			"unable to misc_register %s, minor %d\n",
 11.1123 -			chip->vendor->miscdev.name,
 11.1124 -			chip->vendor->miscdev.minor);
 11.1125 +			chip->vendor.miscdev.name,
 11.1126 +			chip->vendor.miscdev.minor);
 11.1127  		put_device(dev);
 11.1128 +		clear_bit(chip->dev_num, dev_mask);
 11.1129  		kfree(chip);
 11.1130 -		dev_mask[i] &= !(1 << j);
 11.1131 -		return -ENODEV;
 11.1132 +		return NULL;
 11.1133  	}
 11.1134  
 11.1135  	spin_lock(&driver_lock);
 11.1136 @@ -614,11 +1207,11 @@ dev_num_search_complete:
 11.1137  
 11.1138  	spin_unlock(&driver_lock);
 11.1139  
 11.1140 -	sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
 11.1141 +	sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
 11.1142  
 11.1143  	chip->bios_dir = tpm_bios_log_setup(devname);
 11.1144  
 11.1145 -	return 0;
 11.1146 +	return chip;
 11.1147  }
 11.1148  EXPORT_SYMBOL_GPL(tpm_register_hardware);
 11.1149  
    12.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Wed Jun 28 07:52:21 2006 -0600
    12.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Mon Jul 03 08:35:12 2006 +0100
    12.3 @@ -24,6 +24,14 @@
    12.4  #include <linux/fs.h>
    12.5  #include <linux/miscdevice.h>
    12.6  #include <linux/platform_device.h>
    12.7 +#include <linux/io.h>
    12.8 +
    12.9 +#ifdef CONFIG_XEN
   12.10 +enum tpm_bufsize {
   12.11 +	TPM_MIN_BUFFERSIZE = 2048,
   12.12 +	TPM_MAX_BUFFERSIZE = 64 * 1024,
   12.13 +};
   12.14 +#endif
   12.15  
   12.16  enum tpm_timeout {
   12.17  	TPM_TIMEOUT = 5,	/* msecs */
   12.18 @@ -41,19 +49,33 @@ extern ssize_t tpm_show_pcrs(struct devi
   12.19  				char *);
   12.20  extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
   12.21  				char *);
   12.22 +extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
   12.23 +				char *);
   12.24  extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
   12.25  				const char *, size_t);
   12.26 +extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
   12.27 +				char *);
   12.28 +extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
   12.29 +				char *);
   12.30 +extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
   12.31 +				char *);
   12.32 +extern ssize_t tpm_show_temp_deactivated(struct device *,
   12.33 +					 struct device_attribute *attr, char *);
   12.34  
   12.35  struct tpm_chip;
   12.36  
   12.37  struct tpm_vendor_specific {
   12.38 -	u8 req_complete_mask;
   12.39 -	u8 req_complete_val;
   12.40 -	u8 req_canceled;
   12.41 +	const u8 req_complete_mask;
   12.42 +	const u8 req_complete_val;
   12.43 +	const u8 req_canceled;
   12.44 +#ifdef CONFIG_XEN
   12.45  	u32 buffersize;
   12.46 +#endif
   12.47  	void __iomem *iobase;		/* ioremapped address */
   12.48  	unsigned long base;		/* TPM base address */
   12.49  
   12.50 +	int irq;
   12.51 +
   12.52  	int region_size;
   12.53  	int have_region;
   12.54  
   12.55 @@ -63,6 +85,13 @@ struct tpm_vendor_specific {
   12.56  	u8 (*status) (struct tpm_chip *);
   12.57  	struct miscdevice miscdev;
   12.58  	struct attribute_group *attr_group;
   12.59 +	struct list_head list;
   12.60 +	int locality;
   12.61 +	unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
   12.62 +	unsigned long duration[3]; /* jiffies */
   12.63 +
   12.64 +	wait_queue_head_t read_queue;
   12.65 +	wait_queue_head_t int_queue;
   12.66  };
   12.67  
   12.68  struct tpm_chip {
   12.69 @@ -75,20 +104,27 @@ struct tpm_chip {
   12.70  	/* Data passed to and from the tpm via the read/write calls */
   12.71  	u8 *data_buffer;
   12.72  	atomic_t data_pending;
   12.73 +#ifdef CONFIG_XEN
   12.74  	atomic_t data_position;
   12.75 +#endif
   12.76  	struct semaphore buffer_mutex;
   12.77  
   12.78  	struct timer_list user_read_timer;	/* user needs to claim result */
   12.79  	struct work_struct work;
   12.80  	struct semaphore tpm_mutex;	/* tpm is processing */
   12.81  
   12.82 -	struct tpm_vendor_specific *vendor;
   12.83 +	struct tpm_vendor_specific vendor;
   12.84  
   12.85  	struct dentry **bios_dir;
   12.86  
   12.87  	struct list_head list;
   12.88 +#ifdef CONFIG_XEN
   12.89 +	void *priv;
   12.90 +#endif
   12.91  };
   12.92  
   12.93 +#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
   12.94 +
   12.95  static inline int tpm_read_index(int base, int index)
   12.96  {
   12.97  	outb(index, base);
   12.98 @@ -101,13 +137,35 @@ static inline void tpm_write_index(int b
   12.99  	outb(value & 0xFF, base+1);
  12.100  }
  12.101  
  12.102 +#ifdef CONFIG_XEN
  12.103  static inline u32 get_chip_buffersize(struct tpm_chip *chip)
  12.104  {
  12.105 -	return chip->vendor->buffersize;
  12.106 +	u32 size = chip->vendor.buffersize;
  12.107 +	if (size > TPM_MAX_BUFFERSIZE) {
  12.108 +		return TPM_MAX_BUFFERSIZE;
  12.109 +	} else if (size < TPM_MIN_BUFFERSIZE) {
  12.110 +		return TPM_MIN_BUFFERSIZE;
  12.111 +	}
  12.112 +	return size;
  12.113  }
  12.114  
  12.115 -extern int tpm_register_hardware(struct device *,
  12.116 -				 struct tpm_vendor_specific *);
  12.117 +static inline void *chip_get_private(const struct tpm_chip *chip)
  12.118 +{
  12.119 +	return chip->priv;
  12.120 +}
  12.121 +
  12.122 +static inline void chip_set_private(struct tpm_chip *chip, void *priv)
  12.123 +{
  12.124 +	chip->priv = priv;
  12.125 +}
  12.126 +#endif
  12.127 +
  12.128 +extern void tpm_get_timeouts(struct tpm_chip *);
  12.129 +extern void tpm_gen_interrupt(struct tpm_chip *);
  12.130 +extern void tpm_continue_selftest(struct tpm_chip *);
  12.131 +extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
  12.132 +extern struct tpm_chip* tpm_register_hardware(struct device *,
  12.133 +				 const struct tpm_vendor_specific *);
  12.134  extern int tpm_open(struct inode *, struct file *);
  12.135  extern int tpm_release(struct inode *, struct file *);
  12.136  extern ssize_t tpm_write(struct file *, const char __user *, size_t,
  12.137 @@ -121,7 +179,7 @@ extern int tpm_pm_resume(struct device *
  12.138  extern struct dentry ** tpm_bios_log_setup(char *);
  12.139  extern void tpm_bios_log_teardown(struct dentry **);
  12.140  #else
  12.141 -static inline struct dentry* tpm_bios_log_setup(char *name)
  12.142 +static inline struct dentry ** tpm_bios_log_setup(char *name)
  12.143  {
  12.144  	return NULL;
  12.145  }
    13.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Jun 28 07:52:21 2006 -0600
    13.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Mon Jul 03 08:35:12 2006 +0100
    13.3 @@ -29,8 +29,6 @@ enum {
    13.4  	STATUS_READY = 0x04
    13.5  };
    13.6  
    13.7 -#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
    13.8 -
    13.9  struct transmission {
   13.10  	struct list_head next;
   13.11  
   13.12 @@ -49,26 +47,6 @@ enum {
   13.13  	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
   13.14  };
   13.15  
   13.16 -struct vtpm_state {
   13.17 -	struct transmission *current_request;
   13.18 -	spinlock_t           req_list_lock;
   13.19 -	wait_queue_head_t    req_wait_queue;
   13.20 -
   13.21 -	struct list_head     queued_requests;
   13.22 -
   13.23 -	struct transmission *current_response;
   13.24 -	spinlock_t           resp_list_lock;
   13.25 -	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
   13.26 -
   13.27 -	struct transmission *req_cancelled;       // if a cancellation was encounterd
   13.28 -
   13.29 -	u8                   vd_status;
   13.30 -	u8                   flags;
   13.31 -
   13.32 -	unsigned long        disconnect_time;
   13.33 -
   13.34 -	struct tpm_virtual_device *tpmvd;
   13.35 -};
   13.36  
   13.37  enum {
   13.38  	DATAEX_FLAG_QUEUED_ONLY = 0x1
   13.39 @@ -76,7 +54,6 @@ enum {
   13.40  
   13.41  
   13.42  /* local variables */
   13.43 -static struct vtpm_state *vtpms;
   13.44  
   13.45  /* local function prototypes */
   13.46  static int _vtpm_send_queued(struct tpm_chip *chip);
   13.47 @@ -160,11 +137,16 @@ static inline void transmission_free(str
   13.48  /*
   13.49   * Lower layer uses this function to make a response available.
   13.50   */
   13.51 -int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
   13.52 +int vtpm_vd_recv(const struct tpm_chip *chip,
   13.53 +                 const unsigned char *buffer, size_t count,
   13.54 +                 void *ptr)
   13.55  {
   13.56  	unsigned long flags;
   13.57  	int ret_size = 0;
   13.58  	struct transmission *t;
   13.59 +	struct vtpm_state *vtpms;
   13.60 +
   13.61 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   13.62  
   13.63  	/*
   13.64  	 * The list with requests must contain one request
   13.65 @@ -173,26 +155,11 @@ int vtpm_vd_recv(const unsigned char *bu
   13.66  	 */
   13.67  	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
   13.68  	if (vtpms->current_request != ptr) {
   13.69 -		printk("WARNING: The request pointer is different than the "
   13.70 -		       "pointer the shared memory driver returned to me. "
   13.71 -		       "%p != %p\n",
   13.72 -		       vtpms->current_request, ptr);
   13.73 -	}
   13.74 -
   13.75 -	/*
   13.76 -	 * If the request has been cancelled, just quit here
   13.77 -	 */
   13.78 -	if (vtpms->req_cancelled == (struct transmission *)ptr) {
   13.79 -		if (vtpms->current_request == vtpms->req_cancelled) {
   13.80 -			vtpms->current_request = NULL;
   13.81 -		}
   13.82 -		transmission_free(vtpms->req_cancelled);
   13.83 -		vtpms->req_cancelled = NULL;
   13.84  		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
   13.85  		return 0;
   13.86  	}
   13.87  
   13.88 -	if (NULL != (t = vtpms->current_request)) {
   13.89 +	if ((t = vtpms->current_request)) {
   13.90  		transmission_free(t);
   13.91  		vtpms->current_request = NULL;
   13.92  	}
   13.93 @@ -217,8 +184,12 @@ int vtpm_vd_recv(const unsigned char *bu
   13.94  /*
   13.95   * Lower layer indicates its status (connected/disconnected)
   13.96   */
   13.97 -void vtpm_vd_status(u8 vd_status)
   13.98 +void vtpm_vd_status(const struct tpm_chip *chip, u8 vd_status)
   13.99  {
  13.100 +	struct vtpm_state *vtpms;
  13.101 +
  13.102 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  13.103 +
  13.104  	vtpms->vd_status = vd_status;
  13.105  	if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
  13.106  		vtpms->disconnect_time = jiffies;
  13.107 @@ -233,6 +204,9 @@ static int vtpm_recv(struct tpm_chip *ch
  13.108  {
  13.109  	int rc = 0;
  13.110  	unsigned long flags;
  13.111 +	struct vtpm_state *vtpms;
  13.112 +
  13.113 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  13.114  
  13.115  	/*
  13.116  	 * Check if the previous operation only queued the command
  13.117 @@ -251,7 +225,7 @@ static int vtpm_recv(struct tpm_chip *ch
  13.118  		 * Return a response of up to 30 '0's.
  13.119  		 */
  13.120  
  13.121 -		count = MIN(count, 30);
  13.122 +		count = min_t(size_t, count, 30);
  13.123  		memset(buf, 0x0, count);
  13.124  		return count;
  13.125  	}
  13.126 @@ -270,7 +244,7 @@ static int vtpm_recv(struct tpm_chip *ch
  13.127  	if (vtpms->current_response) {
  13.128  		struct transmission *t = vtpms->current_response;
  13.129  		vtpms->current_response = NULL;
  13.130 -		rc = MIN(count, t->response_len);
  13.131 +		rc = min(count, t->response_len);
  13.132  		memcpy(buf, t->response, rc);
  13.133  		transmission_free(t);
  13.134  	}
  13.135 @@ -284,6 +258,9 @@ static int vtpm_send(struct tpm_chip *ch
  13.136  	int rc = 0;
  13.137  	unsigned long flags;
  13.138  	struct transmission *t = transmission_alloc();
  13.139 +	struct vtpm_state *vtpms;
  13.140 +
  13.141 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  13.142  
  13.143  	if (!t)
  13.144  		return -ENOMEM;
  13.145 @@ -327,8 +304,7 @@ static int vtpm_send(struct tpm_chip *ch
  13.146  
  13.147  			vtpms->current_request = t;
  13.148  
  13.149 -			rc = vtpm_vd_send(chip,
  13.150 -			                  vtpms->tpmvd->tpm_private,
  13.151 +			rc = vtpm_vd_send(vtpms->tpm_private,
  13.152  			                  buf,
  13.153  			                  count,
  13.154  			                  t);
  13.155 @@ -373,6 +349,8 @@ static int _vtpm_send_queued(struct tpm_
  13.156  	int error = 0;
  13.157  	long flags;
  13.158  	unsigned char buffer[1];
  13.159 +	struct vtpm_state *vtpms;
  13.160 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  13.161  
  13.162  	spin_lock_irqsave(&vtpms->req_list_lock, flags);
  13.163  
  13.164 @@ -387,8 +365,7 @@ static int _vtpm_send_queued(struct tpm_
  13.165  		vtpms->current_request = qt;
  13.166  		spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
  13.167  
  13.168 -		rc = vtpm_vd_send(chip,
  13.169 -		                  vtpms->tpmvd->tpm_private,
  13.170 +		rc = vtpm_vd_send(vtpms->tpm_private,
  13.171  		                  qt->request,
  13.172  		                  qt->request_len,
  13.173  		                  qt);
  13.174 @@ -427,9 +404,21 @@ static int _vtpm_send_queued(struct tpm_
  13.175  static void vtpm_cancel(struct tpm_chip *chip)
  13.176  {
  13.177  	unsigned long flags;
  13.178 +	struct vtpm_state *vtpms = (struct vtpm_state *)chip_get_private(chip);
  13.179 +
  13.180  	spin_lock_irqsave(&vtpms->resp_list_lock,flags);
  13.181  
  13.182 -	vtpms->req_cancelled = vtpms->current_request;
  13.183 +	if (!vtpms->current_response && vtpms->current_request) {
  13.184 +		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  13.185 +		interruptible_sleep_on(&vtpms->resp_wait_queue);
  13.186 +		spin_lock_irqsave(&vtpms->resp_list_lock,flags);
  13.187 +	}
  13.188 +
  13.189 +	if (vtpms->current_response) {
  13.190 +		struct transmission *t = vtpms->current_response;
  13.191 +		vtpms->current_response = NULL;
  13.192 +		transmission_free(t);
  13.193 +	}
  13.194  
  13.195  	spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
  13.196  }
  13.197 @@ -438,6 +427,9 @@ static u8 vtpm_status(struct tpm_chip *c
  13.198  {
  13.199  	u8 rc = 0;
  13.200  	unsigned long flags;
  13.201 +	struct vtpm_state *vtpms;
  13.202 +
  13.203 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
  13.204  
  13.205  	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
  13.206  	/*
  13.207 @@ -449,7 +441,10 @@ static u8 vtpm_status(struct tpm_chip *c
  13.208  	if (vtpms->current_response ||
  13.209  	    0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
  13.210  		rc = STATUS_DATA_AVAIL;
  13.211 +	} else if (!vtpms->current_response && !vtpms->current_request) {
  13.212 +		rc = STATUS_READY;
  13.213  	}
  13.214 +
  13.215  	spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
  13.216  	return rc;
  13.217  }
  13.218 @@ -465,12 +460,21 @@ static struct file_operations vtpm_ops =
  13.219  
  13.220  static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  13.221  static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
  13.222 +static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
  13.223 +static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
  13.224 +static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
  13.225 +static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
  13.226 +		   NULL);
  13.227  static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
  13.228  static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
  13.229  
  13.230  static struct attribute *vtpm_attrs[] = {
  13.231  	&dev_attr_pubek.attr,
  13.232  	&dev_attr_pcrs.attr,
  13.233 +	&dev_attr_enabled.attr,
  13.234 +	&dev_attr_active.attr,
  13.235 +	&dev_attr_owned.attr,
  13.236 +	&dev_attr_temp_deactivated.attr,
  13.237  	&dev_attr_caps.attr,
  13.238  	&dev_attr_cancel.attr,
  13.239  	NULL,
  13.240 @@ -478,6 +482,8 @@ static struct attribute *vtpm_attrs[] = 
  13.241  
  13.242  static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
  13.243  
  13.244 +#define TPM_LONG_TIMEOUT   (10 * 60 * HZ)
  13.245 +
  13.246  static struct tpm_vendor_specific tpm_vtpm = {
  13.247  	.recv = vtpm_recv,
  13.248  	.send = vtpm_send,
  13.249 @@ -486,61 +492,56 @@ static struct tpm_vendor_specific tpm_vt
  13.250  	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
  13.251  	.req_complete_val  = STATUS_DATA_AVAIL,
  13.252  	.req_canceled = STATUS_READY,
  13.253 -	.base = 0,
  13.254  	.attr_group = &vtpm_attr_grp,
  13.255  	.miscdev = {
  13.256  		.fops = &vtpm_ops,
  13.257  	},
  13.258 +	.duration = {
  13.259 +		TPM_LONG_TIMEOUT,
  13.260 +		TPM_LONG_TIMEOUT,
  13.261 +		TPM_LONG_TIMEOUT,
  13.262 +	},
  13.263  };
  13.264  
  13.265 -static struct platform_device *pdev;
  13.266 -
  13.267 -int __init init_vtpm(struct tpm_virtual_device *tvd)
  13.268 +struct tpm_chip *init_vtpm(struct device *dev,
  13.269 +                           struct tpm_virtual_device *tvd,
  13.270 +                           struct tpm_private *tp)
  13.271  {
  13.272 -	int rc;
  13.273 -
  13.274 -	/* vtpms is global - only allow one user */
  13.275 -	if (vtpms)
  13.276 -		return -EBUSY;
  13.277 +	long rc;
  13.278 +	struct tpm_chip *chip;
  13.279 +	struct vtpm_state *vtpms;
  13.280  
  13.281  	vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
  13.282  	if (!vtpms)
  13.283 -		return -ENOMEM;
  13.284 +		return ERR_PTR(-ENOMEM);
  13.285  
  13.286  	vtpm_state_init(vtpms);
  13.287  	vtpms->tpmvd = tvd;
  13.288 -
  13.289 -	pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
  13.290 -	if (IS_ERR(pdev)) {
  13.291 -		rc = PTR_ERR(pdev);
  13.292 -		goto err_free_mem;
  13.293 -	}
  13.294 +	vtpms->tpm_private = tp;
  13.295  
  13.296  	if (tvd)
  13.297  		tpm_vtpm.buffersize = tvd->max_tx_size;
  13.298  
  13.299 -	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
  13.300 -		goto err_unreg_pdev;
  13.301 +	chip = tpm_register_hardware(dev, &tpm_vtpm);
  13.302 +	if (!chip) {
  13.303 +		rc = -ENODEV;
  13.304 +		goto err_free_mem;
  13.305  	}
  13.306  
  13.307 -	return 0;
  13.308 +	chip_set_private(chip, vtpms);
  13.309  
  13.310 -err_unreg_pdev:
  13.311 -	platform_device_unregister(pdev);
  13.312 +	return chip;
  13.313 +
  13.314  err_free_mem:
  13.315  	kfree(vtpms);
  13.316 -	vtpms = NULL;
  13.317  
  13.318 -	return rc;
  13.319 +	return ERR_PTR(rc);
  13.320  }
  13.321  
  13.322 -void __exit cleanup_vtpm(void)
  13.323 +void cleanup_vtpm(struct device *dev)
  13.324  {
  13.325 -	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
  13.326 -	if (chip) {
  13.327 -		tpm_remove_hardware(chip->dev);
  13.328 -		platform_device_unregister(pdev);
  13.329 -	}
  13.330 +	struct tpm_chip *chip = dev_get_drvdata(dev);
  13.331 +	struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip);
  13.332 +	tpm_remove_hardware(dev);
  13.333  	kfree(vtpms);
  13.334 -	vtpms = NULL;
  13.335  }
    14.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Jun 28 07:52:21 2006 -0600
    14.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Mon Jul 03 08:35:12 2006 +0100
    14.3 @@ -12,6 +12,26 @@ struct tpm_virtual_device {
    14.4  	 * for allocation of buffers.
    14.5  	 */
    14.6  	unsigned int max_tx_size;
    14.7 +};
    14.8 +
    14.9 +struct vtpm_state {
   14.10 +	struct transmission *current_request;
   14.11 +	spinlock_t           req_list_lock;
   14.12 +	wait_queue_head_t    req_wait_queue;
   14.13 +
   14.14 +	struct list_head     queued_requests;
   14.15 +
   14.16 +	struct transmission *current_response;
   14.17 +	spinlock_t           resp_list_lock;
   14.18 +	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
   14.19 +
   14.20 +	u8                   vd_status;
   14.21 +	u8                   flags;
   14.22 +
   14.23 +	unsigned long        disconnect_time;
   14.24 +
   14.25 +	struct tpm_virtual_device *tpmvd;
   14.26 +
   14.27  	/*
   14.28  	 * The following is a private structure of the underlying
   14.29  	 * driver. It is passed as parameter in the send function.
   14.30 @@ -19,20 +39,30 @@ struct tpm_virtual_device {
   14.31  	struct tpm_private *tpm_private;
   14.32  };
   14.33  
   14.34 +
   14.35  enum vdev_status {
   14.36  	TPM_VD_STATUS_DISCONNECTED = 0x0,
   14.37  	TPM_VD_STATUS_CONNECTED = 0x1
   14.38  };
   14.39  
   14.40  /* this function is called from tpm_vtpm.c */
   14.41 -int vtpm_vd_send(struct tpm_chip *tc,
   14.42 -                 struct tpm_private * tp,
   14.43 +int vtpm_vd_send(struct tpm_private * tp,
   14.44                   const u8 * buf, size_t count, void *ptr);
   14.45  
   14.46  /* these functions are offered by tpm_vtpm.c */
   14.47 -int __init init_vtpm(struct tpm_virtual_device *);
   14.48 -void __exit cleanup_vtpm(void);
   14.49 -int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
   14.50 -void vtpm_vd_status(u8 status);
   14.51 +struct tpm_chip *init_vtpm(struct device *,
   14.52 +                           struct tpm_virtual_device *,
   14.53 +                           struct tpm_private *);
   14.54 +void cleanup_vtpm(struct device *);
   14.55 +int vtpm_vd_recv(const struct tpm_chip* chip,
   14.56 +                 const unsigned char *buffer, size_t count, void *ptr);
   14.57 +void vtpm_vd_status(const struct tpm_chip *, u8 status);
   14.58 +
   14.59 +static inline struct tpm_private *tpm_private_from_dev(struct device *dev)
   14.60 +{
   14.61 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   14.62 +	struct vtpm_state *vtpms = chip_get_private(chip);
   14.63 +	return vtpms->tpm_private;
   14.64 +}
   14.65  
   14.66  #endif
    15.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Jun 28 07:52:21 2006 -0600
    15.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Mon Jul 03 08:35:12 2006 +0100
    15.3 @@ -34,6 +34,7 @@
    15.4   */
    15.5  
    15.6  #include <linux/errno.h>
    15.7 +#include <linux/err.h>
    15.8  #include <linux/interrupt.h>
    15.9  #include <linux/mutex.h>
   15.10  #include <asm/uaccess.h>
   15.11 @@ -41,12 +42,15 @@
   15.12  #include <xen/interface/grant_table.h>
   15.13  #include <xen/interface/io/tpmif.h>
   15.14  #include <xen/xenbus.h>
   15.15 +#include "tpm.h"
   15.16  #include "tpm_vtpm.h"
   15.17  
   15.18  #undef DEBUG
   15.19  
   15.20  /* local structures */
   15.21  struct tpm_private {
   15.22 +	struct tpm_chip *chip;
   15.23 +
   15.24  	tpmif_tx_interface_t *tx;
   15.25  	atomic_t refcnt;
   15.26  	unsigned int evtchn;
   15.27 @@ -60,6 +64,7 @@ struct tpm_private {
   15.28  
   15.29  	atomic_t tx_busy;
   15.30  	void *tx_remember;
   15.31 +
   15.32  	domid_t backend_id;
   15.33  	wait_queue_head_t wait_q;
   15.34  
   15.35 @@ -95,6 +100,7 @@ static int tpm_xmit(struct tpm_private *
   15.36                      const u8 * buf, size_t count, int userbuffer,
   15.37                      void *remember);
   15.38  static void destroy_tpmring(struct tpm_private *tp);
   15.39 +void __exit tpmif_exit(void);
   15.40  
   15.41  #define DPRINTK(fmt, args...) \
   15.42      pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
   15.43 @@ -199,8 +205,7 @@ static DEFINE_MUTEX(suspend_lock);
   15.44  /*
   15.45   * Send data via this module by calling this function
   15.46   */
   15.47 -int vtpm_vd_send(struct tpm_chip *chip,
   15.48 -                 struct tpm_private *tp,
   15.49 +int vtpm_vd_send(struct tpm_private *tp,
   15.50                   const u8 * buf, size_t count, void *ptr)
   15.51  {
   15.52  	int sent;
   15.53 @@ -331,7 +336,7 @@ out:
   15.54  static void backend_changed(struct xenbus_device *dev,
   15.55  			    enum xenbus_state backend_state)
   15.56  {
   15.57 -	struct tpm_private *tp = dev->dev.driver_data;
   15.58 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   15.59  	DPRINTK("\n");
   15.60  
   15.61  	switch (backend_state) {
   15.62 @@ -358,6 +363,9 @@ static void backend_changed(struct xenbu
   15.63  	}
   15.64  }
   15.65  
   15.66 +struct tpm_virtual_device tvd = {
   15.67 +	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
   15.68 +};
   15.69  
   15.70  static int tpmfront_probe(struct xenbus_device *dev,
   15.71                            const struct xenbus_device_id *id)
   15.72 @@ -369,6 +377,12 @@ static int tpmfront_probe(struct xenbus_
   15.73  	if (!tp)
   15.74  		return -ENOMEM;
   15.75  
   15.76 +	tp->chip = init_vtpm(&dev->dev, &tvd, tp);
   15.77 +
   15.78 +	if (IS_ERR(tp->chip)) {
   15.79 +		return PTR_ERR(tp->chip);
   15.80 +	}
   15.81 +
   15.82  	err = xenbus_scanf(XBT_NIL, dev->nodename,
   15.83  	                   "handle", "%i", &handle);
   15.84  	if (XENBUS_EXIST_ERR(err))
   15.85 @@ -380,12 +394,10 @@ static int tpmfront_probe(struct xenbus_
   15.86  	}
   15.87  
   15.88  	tp->dev = dev;
   15.89 -	dev->dev.driver_data = tp;
   15.90  
   15.91  	err = talk_to_backend(dev, tp);
   15.92  	if (err) {
   15.93  		tpm_private_put();
   15.94 -		dev->dev.driver_data = NULL;
   15.95  		return err;
   15.96  	}
   15.97  	return 0;
   15.98 @@ -394,16 +406,16 @@ static int tpmfront_probe(struct xenbus_
   15.99  
  15.100  static int tpmfront_remove(struct xenbus_device *dev)
  15.101  {
  15.102 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
  15.103 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
  15.104  	destroy_tpmring(tp);
  15.105 +	cleanup_vtpm(&dev->dev);
  15.106  	return 0;
  15.107  }
  15.108  
  15.109  static int tpmfront_suspend(struct xenbus_device *dev)
  15.110  {
  15.111 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
  15.112 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
  15.113  	u32 ctr;
  15.114 -
  15.115  	/* lock, so no app can send */
  15.116  	mutex_lock(&suspend_lock);
  15.117  	tp->is_suspended = 1;
  15.118 @@ -431,7 +443,7 @@ static int tpmfront_suspend(struct xenbu
  15.119  
  15.120  static int tpmfront_resume(struct xenbus_device *dev)
  15.121  {
  15.122 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
  15.123 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
  15.124  	destroy_tpmring(tp);
  15.125  	return talk_to_backend(dev, tp);
  15.126  }
  15.127 @@ -548,7 +560,7 @@ static void tpmif_rx_action(unsigned lon
  15.128  		offset += tocopy;
  15.129  	}
  15.130  
  15.131 -	vtpm_vd_recv(buffer, received, tp->tx_remember);
  15.132 +	vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
  15.133  	kfree(buffer);
  15.134  
  15.135  exit:
  15.136 @@ -638,6 +650,7 @@ static int tpm_xmit(struct tpm_private *
  15.137  
  15.138  	atomic_set(&tp->tx_busy, 1);
  15.139  	tp->tx_remember = remember;
  15.140 +
  15.141  	mb();
  15.142  
  15.143  	DPRINTK("Notifying backend via event channel %d\n",
  15.144 @@ -657,9 +670,9 @@ static void tpmif_notify_upperlayer(stru
  15.145  	 * to the BE.
  15.146  	 */
  15.147  	if (tp->is_connected) {
  15.148 -		vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
  15.149 +		vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
  15.150  	} else {
  15.151 -		vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
  15.152 +		vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
  15.153  	}
  15.154  }
  15.155  
  15.156 @@ -699,13 +712,10 @@ static void tpmif_set_connected_state(st
  15.157   * =================================================================
  15.158   */
  15.159  
  15.160 -struct tpm_virtual_device tvd = {
  15.161 -	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
  15.162 -};
  15.163  
  15.164  static int __init tpmif_init(void)
  15.165  {
  15.166 -	int rc;
  15.167 +	long rc = 0;
  15.168  	struct tpm_private *tp;
  15.169  
  15.170  	if ((xen_start_info->flags & SIF_INITDOMAIN)) {
  15.171 @@ -718,11 +728,6 @@ static int __init tpmif_init(void)
  15.172  		goto failexit;
  15.173  	}
  15.174  
  15.175 -	tvd.tpm_private = tp;
  15.176 -	rc = init_vtpm(&tvd);
  15.177 -	if (rc)
  15.178 -		goto init_vtpm_failed;
  15.179 -
  15.180  	IPRINTK("Initialising the vTPM driver.\n");
  15.181  	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
  15.182  	                                     &gref_head ) < 0) {
  15.183 @@ -734,19 +739,16 @@ static int __init tpmif_init(void)
  15.184  	return 0;
  15.185  
  15.186  gnttab_alloc_failed:
  15.187 -	cleanup_vtpm();
  15.188 -init_vtpm_failed:
  15.189  	tpm_private_put();
  15.190  failexit:
  15.191  
  15.192 -	return rc;
  15.193 +	return (int)rc;
  15.194  }
  15.195  
  15.196  
  15.197 -static void __exit tpmif_exit(void)
  15.198 +void __exit tpmif_exit(void)
  15.199  {
  15.200  	exit_tpm_xenbus();
  15.201 -	cleanup_vtpm();
  15.202  	tpm_private_put();
  15.203  	gnttab_free_grant_references(gref_head);
  15.204  }
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Jun 28 07:52:21 2006 -0600
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Mon Jul 03 08:35:12 2006 +0100
    16.3 @@ -75,6 +75,9 @@ DEFINE_SPINLOCK(balloon_lock);
    16.4  static unsigned long current_pages;
    16.5  static unsigned long target_pages;
    16.6  
    16.7 +/* We increase/decrease in batches which fit in a page */
    16.8 +static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; 
    16.9 +
   16.10  /* VM /proc information for memory */
   16.11  extern unsigned long totalram_pages;
   16.12  
   16.13 @@ -96,6 +99,11 @@ static void balloon_process(void *unused
   16.14  static DECLARE_WORK(balloon_worker, balloon_process, NULL);
   16.15  static struct timer_list balloon_timer;
   16.16  
   16.17 +/* When ballooning out (allocating memory to return to Xen) we don't really 
   16.18 +   want the kernel to try too hard since that can trigger the oom killer. */
   16.19 +#define GFP_BALLOON \
   16.20 +	(GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
   16.21 +
   16.22  #define PAGE_TO_LIST(p) (&(p)->lru)
   16.23  #define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
   16.24  #define UNLIST_PAGE(p)				\
   16.25 @@ -172,7 +180,7 @@ static unsigned long current_target(void
   16.26  
   16.27  static int increase_reservation(unsigned long nr_pages)
   16.28  {
   16.29 -	unsigned long *frame_list, frame, pfn, i, flags;
   16.30 +	unsigned long  pfn, i, flags;
   16.31  	struct page   *page;
   16.32  	long           rc;
   16.33  	struct xen_memory_reservation reservation = {
   16.34 @@ -181,15 +189,8 @@ static int increase_reservation(unsigned
   16.35  		.domid        = DOMID_SELF
   16.36  	};
   16.37  
   16.38 -	if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
   16.39 -		nr_pages = PAGE_SIZE / sizeof(unsigned long);
   16.40 -
   16.41 -	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
   16.42 -	if (frame_list == NULL) {
   16.43 -		frame_list = &frame;
   16.44 -		if (nr_pages > 1)
   16.45 -			nr_pages = 1;
   16.46 -	}
   16.47 +	if (nr_pages > ARRAY_SIZE(frame_list))
   16.48 +		nr_pages = ARRAY_SIZE(frame_list);
   16.49  
   16.50  	balloon_lock(flags);
   16.51  
   16.52 @@ -253,15 +254,12 @@ static int increase_reservation(unsigned
   16.53   out:
   16.54  	balloon_unlock(flags);
   16.55  
   16.56 -	if (frame_list != &frame)
   16.57 -		free_page((unsigned long)frame_list);
   16.58 -
   16.59  	return 0;
   16.60  }
   16.61  
   16.62  static int decrease_reservation(unsigned long nr_pages)
   16.63  {
   16.64 -	unsigned long *frame_list, frame, pfn, i, flags;
   16.65 +	unsigned long  pfn, i, flags;
   16.66  	struct page   *page;
   16.67  	void          *v;
   16.68  	int            need_sleep = 0;
   16.69 @@ -272,18 +270,11 @@ static int decrease_reservation(unsigned
   16.70  		.domid        = DOMID_SELF
   16.71  	};
   16.72  
   16.73 -	if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
   16.74 -		nr_pages = PAGE_SIZE / sizeof(unsigned long);
   16.75 -
   16.76 -	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
   16.77 -	if (frame_list == NULL) {
   16.78 -		frame_list = &frame;
   16.79 -		if (nr_pages > 1)
   16.80 -			nr_pages = 1;
   16.81 -	}
   16.82 +	if (nr_pages > ARRAY_SIZE(frame_list))
   16.83 +		nr_pages = ARRAY_SIZE(frame_list);
   16.84  
   16.85  	for (i = 0; i < nr_pages; i++) {
   16.86 -		if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
   16.87 +		if ((page = alloc_page(GFP_BALLOON)) == NULL) {
   16.88  			nr_pages = i;
   16.89  			need_sleep = 1;
   16.90  			break;
   16.91 @@ -331,9 +322,6 @@ static int decrease_reservation(unsigned
   16.92  
   16.93  	balloon_unlock(flags);
   16.94  
   16.95 -	if (frame_list != &frame)
   16.96 -		free_page((unsigned long)frame_list);
   16.97 -
   16.98  	return need_sleep;
   16.99  }
  16.100  
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Wed Jun 28 07:52:21 2006 -0600
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Mon Jul 03 08:35:12 2006 +0100
    17.3 @@ -76,8 +76,6 @@ static void update_blkif_status(blkif_t 
    17.4   *  sysfs interface for VBD I/O requests
    17.5   */
    17.6  
    17.7 -#ifdef CONFIG_SYSFS
    17.8 -
    17.9  #define VBD_SHOW(name, format, args...)					\
   17.10  	static ssize_t show_##name(struct device *_dev,			\
   17.11  				   struct device_attribute *attr,	\
   17.12 @@ -106,57 +104,40 @@ static struct attribute_group vbdstat_gr
   17.13  	.attrs = vbdstat_attrs,
   17.14  };
   17.15  
   17.16 +VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
   17.17 +VBD_SHOW(mode, "%s\n", be->mode);
   17.18 +
   17.19  int xenvbd_sysfs_addif(struct xenbus_device *dev)
   17.20  {
   17.21 -	int error = 0;
   17.22 +	int error;
   17.23  	
   17.24 -	error = sysfs_create_group(&dev->dev.kobj,
   17.25 -				   &vbdstat_group);
   17.26 +	error = device_create_file(&dev->dev, &dev_attr_physical_device);
   17.27 + 	if (error)
   17.28 +		goto fail1;
   17.29 +
   17.30 +	error = device_create_file(&dev->dev, &dev_attr_mode);
   17.31  	if (error)
   17.32 -		goto fail;
   17.33 -	
   17.34 +		goto fail2;
   17.35 +
   17.36 +	error = sysfs_create_group(&dev->dev.kobj, &vbdstat_group);
   17.37 +	if (error)
   17.38 +		goto fail3;
   17.39 +
   17.40  	return 0;
   17.41 -	
   17.42 -fail:
   17.43 -	sysfs_remove_group(&dev->dev.kobj,
   17.44 -			   &vbdstat_group);
   17.45 +
   17.46 +fail3:	sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
   17.47 +fail2:	device_remove_file(&dev->dev, &dev_attr_mode);
   17.48 +fail1:	device_remove_file(&dev->dev, &dev_attr_physical_device);
   17.49  	return error;
   17.50  }
   17.51  
   17.52  void xenvbd_sysfs_delif(struct xenbus_device *dev)
   17.53  {
   17.54 -	sysfs_remove_group(&dev->dev.kobj,
   17.55 -			   &vbdstat_group);
   17.56 +	sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
   17.57 +	device_remove_file(&dev->dev, &dev_attr_mode);
   17.58 +	device_remove_file(&dev->dev, &dev_attr_physical_device);
   17.59  }
   17.60  
   17.61 -#else
   17.62 -
   17.63 -#define xenvbd_sysfs_addif(dev) (0)
   17.64 -#define xenvbd_sysfs_delif(dev) ((void)0)
   17.65 -
   17.66 -#endif /* CONFIG_SYSFS */
   17.67 -
   17.68 -static ssize_t show_physical_device(struct device *_dev,
   17.69 -				    struct device_attribute *attr, char *buf)
   17.70 -{
   17.71 -	struct xenbus_device *dev = to_xenbus_device(_dev);
   17.72 -	struct backend_info *be = dev->dev.driver_data;
   17.73 -	return sprintf(buf, "%x:%x\n", be->major, be->minor);
   17.74 -}
   17.75 -DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
   17.76 -	    show_physical_device, NULL);
   17.77 -
   17.78 -
   17.79 -static ssize_t show_mode(struct device *_dev, struct device_attribute *attr,
   17.80 -			 char *buf)
   17.81 -{
   17.82 -	struct xenbus_device *dev = to_xenbus_device(_dev);
   17.83 -	struct backend_info *be = dev->dev.driver_data;
   17.84 -	return sprintf(buf, "%s\n", be->mode);
   17.85 -}
   17.86 -DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
   17.87 -
   17.88 -
   17.89  static int blkback_remove(struct xenbus_device *dev)
   17.90  {
   17.91  	struct backend_info *be = dev->dev.driver_data;
   17.92 @@ -176,9 +157,8 @@ static int blkback_remove(struct xenbus_
   17.93  		be->blkif = NULL;
   17.94  	}
   17.95  
   17.96 -	device_remove_file(&dev->dev, &dev_attr_physical_device);
   17.97 -	device_remove_file(&dev->dev, &dev_attr_mode);
   17.98 -	xenvbd_sysfs_delif(dev);
   17.99 +	if (be->major || be->minor)
  17.100 +		xenvbd_sysfs_delif(dev);
  17.101  
  17.102  	kfree(be);
  17.103  	dev->dev.driver_data = NULL;
  17.104 @@ -293,15 +273,18 @@ static void backend_changed(struct xenbu
  17.105  		err = vbd_create(be->blkif, handle, major, minor,
  17.106  				 (NULL == strchr(be->mode, 'w')));
  17.107  		if (err) {
  17.108 -			be->major = 0;
  17.109 -			be->minor = 0;
  17.110 +			be->major = be->minor = 0;
  17.111  			xenbus_dev_fatal(dev, err, "creating vbd structure");
  17.112  			return;
  17.113  		}
  17.114  
  17.115 -		device_create_file(&dev->dev, &dev_attr_physical_device);
  17.116 -		device_create_file(&dev->dev, &dev_attr_mode);
  17.117 -		xenvbd_sysfs_addif(dev);
  17.118 +		err = xenvbd_sysfs_addif(dev);
  17.119 +		if (err) {
  17.120 +			vbd_free(&be->blkif->vbd);
  17.121 +			be->major = be->minor = 0;
  17.122 +			xenbus_dev_fatal(dev, err, "creating sysfs entries");
  17.123 +			return;
  17.124 +		}
  17.125  
  17.126  		/* We're potentially connected now */
  17.127  		update_blkif_status(be->blkif); 
    18.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Wed Jun 28 07:52:21 2006 -0600
    18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Mon Jul 03 08:35:12 2006 +0100
    18.3 @@ -219,7 +219,10 @@ asmlinkage void evtchn_do_upcall(struct 
    18.4  
    18.5  	vcpu_info->evtchn_upcall_pending = 0;
    18.6  
    18.7 -	/* NB. No need for a barrier here -- XCHG is a barrier on x86. */
    18.8 +#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
    18.9 +	/* Clear master pending flag /before/ clearing selector flag. */
   18.10 +	rmb();
   18.11 +#endif
   18.12  	l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
   18.13  	while (l1 != 0) {
   18.14  		l1i = __ffs(l1);
    19.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Wed Jun 28 07:52:21 2006 -0600
    19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Mon Jul 03 08:35:12 2006 +0100
    19.3 @@ -169,7 +169,7 @@ int gnttab_end_foreign_access_ref(grant_
    19.4  			printk(KERN_ALERT "WARNING: g.e. still in use!\n");
    19.5  			return 0;
    19.6  		}
    19.7 -	} while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
    19.8 +	} while ((nflags = synch_cmpxchg_subword(&shared[ref].flags, flags, 0)) !=
    19.9  		 flags);
   19.10  
   19.11  	return 1;
   19.12 @@ -224,7 +224,7 @@ unsigned long gnttab_end_foreign_transfe
   19.13  	 * reference and return failure (== 0).
   19.14  	 */
   19.15  	while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
   19.16 -		if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
   19.17 +		if (synch_cmpxchg_subword(&shared[ref].flags, flags, 0) == flags)
   19.18  			return 0;
   19.19  		cpu_relax();
   19.20  	}
    20.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c	Wed Jun 28 07:52:21 2006 -0600
    20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c	Mon Jul 03 08:35:12 2006 +0100
    20.3 @@ -8,12 +8,14 @@
    20.4   */
    20.5  
    20.6  #include <linux/config.h>
    20.7 +#include <linux/err.h>
    20.8  #include <linux/kernel.h>
    20.9  #include <linux/module.h>
   20.10  #include <linux/init.h>
   20.11  #include <asm/hypervisor.h>
   20.12  #include <xen/features.h>
   20.13  #include <xen/hypervisor_sysfs.h>
   20.14 +#include <xen/xenbus.h>
   20.15  
   20.16  MODULE_LICENSE("GPL");
   20.17  MODULE_AUTHOR("Mike D. Day <ncmike@us.ibm.com>");
   20.18 @@ -97,6 +99,37 @@ static void xen_sysfs_version_destroy(vo
   20.19  	sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group);
   20.20  }
   20.21  
   20.22 +/* UUID */
   20.23 +
   20.24 +static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
   20.25 +{
   20.26 +	char *vm, *val;
   20.27 +	int ret;
   20.28 +
   20.29 +	vm = xenbus_read(XBT_NIL, "vm", "", NULL);
   20.30 +	if (IS_ERR(vm))
   20.31 +		return PTR_ERR(vm);
   20.32 +	val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
   20.33 +	kfree(vm);
   20.34 +	if (IS_ERR(val))
   20.35 +		return PTR_ERR(val);
   20.36 +	ret = sprintf(buffer, "%s\n", val);
   20.37 +	kfree(val);
   20.38 +	return ret;
   20.39 +}
   20.40 +
   20.41 +HYPERVISOR_ATTR_RO(uuid);
   20.42 +
   20.43 +static int __init xen_sysfs_uuid_init(void)
   20.44 +{
   20.45 +	return sysfs_create_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
   20.46 +}
   20.47 +
   20.48 +static void xen_sysfs_uuid_destroy(void)
   20.49 +{
   20.50 +	sysfs_remove_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
   20.51 +}
   20.52 +
   20.53  /* xen compilation attributes */
   20.54  
   20.55  static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
   20.56 @@ -314,10 +347,15 @@ static int __init hyper_sysfs_init(void)
   20.57  	ret = xen_compilation_init();
   20.58  	if (ret)
   20.59  		goto comp_out;
   20.60 +	ret = xen_sysfs_uuid_init();
   20.61 +	if (ret)
   20.62 +		goto uuid_out;
   20.63  	ret = xen_properties_init();
   20.64  	if (!ret)
   20.65  		goto out;
   20.66  
   20.67 +	xen_sysfs_uuid_destroy();
   20.68 +uuid_out:
   20.69  	xen_compilation_destroy();
   20.70  comp_out:
   20.71  	xen_sysfs_version_destroy();
   20.72 @@ -331,6 +369,7 @@ static void hyper_sysfs_exit(void)
   20.73  {
   20.74  	xen_properties_destroy();
   20.75  	xen_compilation_destroy();
   20.76 +	xen_sysfs_uuid_destroy();
   20.77  	xen_sysfs_version_destroy();
   20.78  	xen_sysfs_type_destroy();
   20.79  
    21.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Jun 28 07:52:21 2006 -0600
    21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Mon Jul 03 08:35:12 2006 +0100
    21.3 @@ -663,6 +663,34 @@ static void netbk_fill_frags(struct sk_b
    21.4  	}
    21.5  }
    21.6  
    21.7 +int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
    21.8 +		     int work_to_do)
    21.9 +{
   21.10 +	struct netif_extra_info *extra;
   21.11 +	RING_IDX cons = netif->tx.req_cons;
   21.12 +
   21.13 +	do {
   21.14 +		if (unlikely(work_to_do-- <= 0)) {
   21.15 +			DPRINTK("Missing extra info\n");
   21.16 +			return -EBADR;
   21.17 +		}
   21.18 +
   21.19 +		extra = (struct netif_extra_info *)
   21.20 +			RING_GET_REQUEST(&netif->tx, cons);
   21.21 +		if (unlikely(!extra->type ||
   21.22 +			     extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
   21.23 +			netif->tx.req_cons = ++cons;
   21.24 +			DPRINTK("Invalid extra type: %d\n", extra->type);
   21.25 +			return -EINVAL;
   21.26 +		}
   21.27 +
   21.28 +		memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
   21.29 +		netif->tx.req_cons = ++cons;
   21.30 +	} while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
   21.31 +
   21.32 +	return work_to_do;
   21.33 +}
   21.34 +
   21.35  /* Called after netfront has transmitted */
   21.36  static void net_tx_action(unsigned long unused)
   21.37  {
   21.38 @@ -670,7 +698,7 @@ static void net_tx_action(unsigned long 
   21.39  	struct sk_buff *skb;
   21.40  	netif_t *netif;
   21.41  	netif_tx_request_t txreq;
   21.42 -	struct netif_tx_extra txtra;
   21.43 +	struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
   21.44  	u16 pending_idx;
   21.45  	RING_IDX i;
   21.46  	gnttab_map_grant_ref_t *mop;
   21.47 @@ -732,16 +760,15 @@ static void net_tx_action(unsigned long 
   21.48  		work_to_do--;
   21.49  		netif->tx.req_cons = ++i;
   21.50  
   21.51 +		memset(extras, 0, sizeof(extras));
   21.52  		if (txreq.flags & NETTXF_extra_info) {
   21.53 -			if (work_to_do-- <= 0) {
   21.54 -				DPRINTK("Missing extra info\n");
   21.55 -				netbk_tx_err(netif, &txreq, i);
   21.56 +			work_to_do = netbk_get_extras(netif, extras,
   21.57 +						      work_to_do);
   21.58 +			if (unlikely(work_to_do < 0)) {
   21.59 +				netbk_tx_err(netif, &txreq, 0);
   21.60  				continue;
   21.61  			}
   21.62 -
   21.63 -			memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
   21.64 -			       sizeof(txtra));
   21.65 -			netif->tx.req_cons = ++i;
   21.66 +			i = netif->tx.req_cons;
   21.67  		}
   21.68  
   21.69  		ret = netbk_count_requests(netif, &txreq, work_to_do);
   21.70 @@ -751,7 +778,7 @@ static void net_tx_action(unsigned long 
   21.71  		}
   21.72  		i += ret;
   21.73  
   21.74 -		if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
   21.75 +		if (unlikely(ret > MAX_SKB_FRAGS)) {
   21.76  			DPRINTK("Too many frags\n");
   21.77  			netbk_tx_err(netif, &txreq, i);
   21.78  			continue;
   21.79 @@ -788,10 +815,24 @@ static void net_tx_action(unsigned long 
   21.80  		/* Packets passed to netif_rx() must have some headroom. */
   21.81  		skb_reserve(skb, 16);
   21.82  
   21.83 -		if (txreq.flags & NETTXF_gso) {
   21.84 -			skb_shinfo(skb)->gso_size = txtra.u.gso.size;
   21.85 -			skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
   21.86 -			skb_shinfo(skb)->gso_type = txtra.u.gso.type;
   21.87 +		if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
   21.88 +			struct netif_extra_info *gso;
   21.89 +			gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
   21.90 +
   21.91 +			/* Currently on TCPv4 S.O. is supported. */
   21.92 +			if (gso->u.gso.type != XEN_NETIF_GSO_TCPV4) {
   21.93 +				DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
   21.94 +				kfree_skb(skb);
   21.95 +				netbk_tx_err(netif, &txreq, i);
   21.96 +				break;
   21.97 +			}
   21.98 +
   21.99 +			skb_shinfo(skb)->gso_size = gso->u.gso.size;
  21.100 +			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
  21.101 +
  21.102 +			/* Header must be checked, and gso_segs computed. */
  21.103 +			skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
  21.104 +			skb_shinfo(skb)->gso_segs = 0;
  21.105  		}
  21.106  
  21.107  		gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
    22.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Wed Jun 28 07:52:21 2006 -0600
    22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Mon Jul 03 08:35:12 2006 +0100
    22.3 @@ -101,11 +101,13 @@ static int netback_probe(struct xenbus_d
    22.4  			goto abort_transaction;
    22.5  		}
    22.6  
    22.7 +#if 0 /* KAF: After the protocol is finalised. */
    22.8  		err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
    22.9  		if (err) {
   22.10  			message = "writing feature-tso";
   22.11  			goto abort_transaction;
   22.12  		}
   22.13 +#endif
   22.14  
   22.15  		err = xenbus_transaction_end(xbt, 0);
   22.16  	} while (err == -EAGAIN);
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Jun 28 07:52:21 2006 -0600
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Mon Jul 03 08:35:12 2006 +0100
    23.3 @@ -463,7 +463,7 @@ static int network_open(struct net_devic
    23.4  
    23.5  static inline int netfront_tx_slot_available(struct netfront_info *np)
    23.6  {
    23.7 -	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
    23.8 +	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
    23.9  }
   23.10  
   23.11  static inline void network_maybe_wake_tx(struct net_device *dev)
   23.12 @@ -491,7 +491,13 @@ static void network_tx_buf_gc(struct net
   23.13  		rmb(); /* Ensure we see responses up to 'rp'. */
   23.14  
   23.15  		for (cons = np->tx.rsp_cons; cons != prod; cons++) {
   23.16 -			id  = RING_GET_RESPONSE(&np->tx, cons)->id;
   23.17 +			struct netif_tx_response *txrsp;
   23.18 +
   23.19 +			txrsp = RING_GET_RESPONSE(&np->tx, cons);
   23.20 +			if (txrsp->status == NETIF_RSP_NULL)
   23.21 +				continue;
   23.22 +
   23.23 +			id  = txrsp->id;
   23.24  			skb = np->tx_skbs[id];
   23.25  			if (unlikely(gnttab_query_foreign_access(
   23.26  				np->grant_tx_ref[id]) != 0)) {
   23.27 @@ -719,6 +725,7 @@ static int network_start_xmit(struct sk_
   23.28  	unsigned short id;
   23.29  	struct netfront_info *np = netdev_priv(dev);
   23.30  	struct netif_tx_request *tx;
   23.31 +	struct netif_extra_info *extra;
   23.32  	char *data = skb->data;
   23.33  	RING_IDX i;
   23.34  	grant_ref_t ref;
   23.35 @@ -739,7 +746,8 @@ static int network_start_xmit(struct sk_
   23.36  	spin_lock_irq(&np->tx_lock);
   23.37  
   23.38  	if (unlikely(!netif_carrier_ok(dev) ||
   23.39 -		     (frags > 1 && !xennet_can_sg(dev)))) {
   23.40 +		     (frags > 1 && !xennet_can_sg(dev)) ||
   23.41 +		     netif_needs_gso(dev, skb))) {
   23.42  		spin_unlock_irq(&np->tx_lock);
   23.43  		goto drop;
   23.44  	}
   23.45 @@ -762,11 +770,30 @@ static int network_start_xmit(struct sk_
   23.46  	tx->size = len;
   23.47  
   23.48  	tx->flags = 0;
   23.49 +	extra = NULL;
   23.50 +
   23.51  	if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
   23.52  		tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
   23.53  	if (skb->proto_data_valid) /* remote but checksummed? */
   23.54  		tx->flags |= NETTXF_data_validated;
   23.55  
   23.56 +	if (skb_shinfo(skb)->gso_size) {
   23.57 +		struct netif_extra_info *gso = (struct netif_extra_info *)
   23.58 +			RING_GET_REQUEST(&np->tx, ++i);
   23.59 +
   23.60 +		if (extra)
   23.61 +			extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
   23.62 +		else
   23.63 +			tx->flags |= NETTXF_extra_info;
   23.64 +
   23.65 +		gso->u.gso.size = skb_shinfo(skb)->gso_size;
   23.66 +		gso->u.gso.type = XEN_NETIF_GSO_TCPV4;
   23.67 +
   23.68 +		gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
   23.69 +		gso->flags = 0;
   23.70 +		extra = gso;
   23.71 +	}
   23.72 +
   23.73  	np->tx.req_prod_pvt = i + 1;
   23.74  
   23.75  	xennet_make_frags(skb, dev, tx);
   23.76 @@ -1065,9 +1092,28 @@ static int xennet_set_sg(struct net_devi
   23.77  	return ethtool_op_set_sg(dev, data);
   23.78  }
   23.79  
   23.80 +static int xennet_set_tso(struct net_device *dev, u32 data)
   23.81 +{
   23.82 +	if (data) {
   23.83 +		struct netfront_info *np = netdev_priv(dev);
   23.84 +		int val;
   23.85 +
   23.86 +		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-tso",
   23.87 +				 "%d", &val) < 0)
   23.88 +			val = 0;
   23.89 +#if 0 /* KAF: After the protocol is finalised. */
   23.90 +		if (!val)
   23.91 +#endif
   23.92 +			return -ENOSYS;
   23.93 +	}
   23.94 +
   23.95 +	return ethtool_op_set_tso(dev, data);
   23.96 +}
   23.97 +
   23.98  static void xennet_set_features(struct net_device *dev)
   23.99  {
  23.100 -	xennet_set_sg(dev, 1);
  23.101 +	if (!xennet_set_sg(dev, 1))
  23.102 +		xennet_set_tso(dev, 1);
  23.103  }
  23.104  
  23.105  static void network_connect(struct net_device *dev)
  23.106 @@ -1148,6 +1194,8 @@ static struct ethtool_ops network_ethtoo
  23.107  	.set_tx_csum = ethtool_op_set_tx_csum,
  23.108  	.get_sg = ethtool_op_get_sg,
  23.109  	.set_sg = xennet_set_sg,
  23.110 +	.get_tso = ethtool_op_get_tso,
  23.111 +	.set_tso = xennet_set_tso,
  23.112  };
  23.113  
  23.114  #ifdef CONFIG_SYSFS
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Jun 28 07:52:21 2006 -0600
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Mon Jul 03 08:35:12 2006 +0100
    24.3 @@ -886,29 +886,6 @@ void unregister_xenstore_notifier(struct
    24.4  EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
    24.5  
    24.6  
    24.7 -static int all_devices_ready_(struct device *dev, void *data)
    24.8 -{
    24.9 -	struct xenbus_device *xendev = to_xenbus_device(dev);
   24.10 -	int *result = data;
   24.11 -
   24.12 -	if (xendev->state != XenbusStateConnected) {
   24.13 -		*result = 0;
   24.14 -		return 1;
   24.15 -	}
   24.16 -
   24.17 -	return 0;
   24.18 -}
   24.19 -
   24.20 -
   24.21 -static int all_devices_ready(void)
   24.22 -{
   24.23 -	int ready = 1;
   24.24 -	bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
   24.25 -			 all_devices_ready_);
   24.26 -	return ready;
   24.27 -}
   24.28 -
   24.29 -
   24.30  void xenbus_probe(void *unused)
   24.31  {
   24.32  	BUG_ON((xenstored_ready <= 0));
   24.33 @@ -1060,6 +1037,43 @@ static int __init xenbus_probe_init(void
   24.34  postcore_initcall(xenbus_probe_init);
   24.35  
   24.36  
   24.37 +static int is_disconnected_device(struct device *dev, void *data)
   24.38 +{
   24.39 +	struct xenbus_device *xendev = to_xenbus_device(dev);
   24.40 +
   24.41 +	/*
   24.42 +	 * A device with no driver will never connect. We care only about
   24.43 +	 * devices which should currently be in the process of connecting.
   24.44 +	 */
   24.45 +	if (!dev->driver)
   24.46 +		return 0;
   24.47 +
   24.48 +	return (xendev->state != XenbusStateConnected);
   24.49 +}
   24.50 +
   24.51 +static int exists_disconnected_device(void)
   24.52 +{
   24.53 +	return bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
   24.54 +				is_disconnected_device);
   24.55 +}
   24.56 +
   24.57 +static int print_device_status(struct device *dev, void *data)
   24.58 +{
   24.59 +	struct xenbus_device *xendev = to_xenbus_device(dev);
   24.60 +
   24.61 +	if (!dev->driver) {
   24.62 +		/* Information only: is this too noisy? */
   24.63 +		printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
   24.64 +		       xendev->nodename);
   24.65 +	} else if (xendev->state != XenbusStateConnected) {
   24.66 +		printk(KERN_WARNING "XENBUS: Timeout connecting "
   24.67 +		       "to device: %s (state %d)\n",
   24.68 +		       xendev->nodename, xendev->state);
   24.69 +	}
   24.70 +
   24.71 +	return 0;
   24.72 +}
   24.73 +
   24.74  /*
   24.75   * On a 10 second timeout, wait for all devices currently configured.  We need
   24.76   * to do this to guarantee that the filesystems and / or network devices
   24.77 @@ -1081,13 +1095,12 @@ static int __init wait_for_devices(void)
   24.78  	if (!is_running_on_xen())
   24.79  		return -ENODEV;
   24.80  
   24.81 -	while (time_before(jiffies, timeout)) {
   24.82 -		if (all_devices_ready())
   24.83 -			return 0;
   24.84 +	while (time_before(jiffies, timeout) && exists_disconnected_device())
   24.85  		schedule_timeout_interruptible(HZ/10);
   24.86 -	}
   24.87  
   24.88 -	printk(KERN_WARNING "XENBUS: Timeout connecting to devices!\n");
   24.89 +	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
   24.90 +			 print_device_status);
   24.91 +
   24.92  	return 0;
   24.93  }
   24.94  
    25.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h	Wed Jun 28 07:52:21 2006 -0600
    25.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h	Mon Jul 03 08:35:12 2006 +0100
    25.3 @@ -138,4 +138,6 @@ static __inline__ int synch_var_test_bit
    25.4   synch_const_test_bit((nr),(addr)) : \
    25.5   synch_var_test_bit((nr),(addr)))
    25.6  
    25.7 +#define synch_cmpxchg_subword synch_cmpxchg
    25.8 +
    25.9  #endif /* __XEN_SYNCH_BITOPS_H__ */
    26.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h	Wed Jun 28 07:52:21 2006 -0600
    26.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h	Mon Jul 03 08:35:12 2006 +0100
    26.3 @@ -58,4 +58,6 @@ static __inline__ int synch_var_test_bit
    26.4   synch_const_test_bit((nr),(addr)) : \
    26.5   synch_var_test_bit((nr),(addr)))
    26.6  
    26.7 +#define synch_cmpxchg_subword synch_cmpxchg
    26.8 +
    26.9  #endif /* __XEN_SYNCH_BITOPS_H__ */
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/patches/linux-2.6.16.13/fix-hz-suspend.patch	Mon Jul 03 08:35:12 2006 +0100
    27.3 @@ -0,0 +1,26 @@
    27.4 +diff -pruN ../pristine-linux-2.6.16.13/kernel/timer.c ./kernel/timer.c
    27.5 +--- ../pristine-linux-2.6.16.13/kernel/timer.c	2006-05-02 22:38:44.000000000 +0100
    27.6 ++++ ./kernel/timer.c	2006-06-29 14:34:12.788957720 +0100
    27.7 +@@ -555,6 +555,22 @@ found:
    27.8 + 	}
    27.9 + 	spin_unlock(&base->t_base.lock);
   27.10 + 
   27.11 ++	/*
   27.12 ++	 * It can happen that other CPUs service timer IRQs and increment
   27.13 ++	 * jiffies, but we have not yet got a local timer tick to process
   27.14 ++	 * the timer wheels.  In that case, the expiry time can be before
   27.15 ++	 * jiffies, but since the high-resolution timer here is relative to
   27.16 ++	 * jiffies, the default expression when high-resolution timers are
   27.17 ++	 * not active,
   27.18 ++	 *
   27.19 ++	 *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
   27.20 ++	 *
   27.21 ++	 * would falsely evaluate to true.  If that is the case, just
   27.22 ++	 * return jiffies so that we can immediately fire the local timer
   27.23 ++	 */
   27.24 ++	if (time_before(expires, jiffies))
   27.25 ++		return jiffies;
   27.26 ++
   27.27 + 	if (time_before(hr_expires, expires))
   27.28 + 		return hr_expires;
   27.29 + 
    28.1 --- a/patches/linux-2.6.16.13/net-gso.patch	Wed Jun 28 07:52:21 2006 -0600
    28.2 +++ b/patches/linux-2.6.16.13/net-gso.patch	Mon Jul 03 08:35:12 2006 +0100
    28.3 @@ -2225,7 +2225,7 @@ index d64e2ec..7494823 100644
    28.4   	err = ipcomp_compress(x, skb);
    28.5   	iph = skb->nh.iph;
    28.6  diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
    28.7 -index 00aa80e..84130c9 100644
    28.8 +index 00aa80e..30c81a8 100644
    28.9  --- a/net/ipv4/tcp.c
   28.10  +++ b/net/ipv4/tcp.c
   28.11  @@ -257,6 +257,7 @@ #include <linux/smp_lock.h>
   28.12 @@ -2281,7 +2281,7 @@ index 00aa80e..84130c9 100644
   28.13   
   28.14   			from += copy;
   28.15   			copied += copy;
   28.16 -@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 
   28.17 +@@ -2026,6 +2021,77 @@ int tcp_getsockopt(struct sock *sk, int 
   28.18   }
   28.19   
   28.20   
   28.21 @@ -2306,13 +2306,19 @@ index 00aa80e..84130c9 100644
   28.22  +	if (!pskb_may_pull(skb, thlen))
   28.23  +		goto out;
   28.24  +
   28.25 -+	segs = NULL;
   28.26 -+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
   28.27 -+		goto out;
   28.28 -+
   28.29  +	oldlen = (u16)~skb->len;
   28.30  +	__skb_pull(skb, thlen);
   28.31  +
   28.32 ++	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
   28.33 ++		/* Packet is from an untrusted source, reset gso_segs. */
   28.34 ++		int mss = skb_shinfo(skb)->gso_size;
   28.35 ++
   28.36 ++		skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
   28.37 ++
   28.38 ++		segs = NULL;
   28.39 ++		goto out;
   28.40 ++	}
   28.41 ++
   28.42  +	segs = skb_segment(skb, features);
   28.43  +	if (IS_ERR(segs))
   28.44  +		goto out;
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch	Mon Jul 03 08:35:12 2006 +0100
    29.3 @@ -0,0 +1,1546 @@
    29.4 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c ./drivers/char/tpm/tpm_atmel.c
    29.5 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c	2006-06-26 18:05:03.000000000 -0400
    29.6 ++++ ./drivers/char/tpm/tpm_atmel.c	2006-06-26 18:16:33.000000000 -0400
    29.7 +@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
    29.8 + 		return -EIO;
    29.9 + 
   29.10 + 	for (i = 0; i < 6; i++) {
   29.11 +-		status = ioread8(chip->vendor->iobase + 1);
   29.12 ++		status = ioread8(chip->vendor.iobase + 1);
   29.13 + 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   29.14 + 			dev_err(chip->dev, "error reading header\n");
   29.15 + 			return -EIO;
   29.16 + 		}
   29.17 +-		*buf++ = ioread8(chip->vendor->iobase);
   29.18 ++		*buf++ = ioread8(chip->vendor.iobase);
   29.19 + 	}
   29.20 + 
   29.21 + 	/* size of the data received */
   29.22 +@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
   29.23 + 		dev_err(chip->dev,
   29.24 + 			"Recv size(%d) less than available space\n", size);
   29.25 + 		for (; i < size; i++) {	/* clear the waiting data anyway */
   29.26 +-			status = ioread8(chip->vendor->iobase + 1);
   29.27 ++			status = ioread8(chip->vendor.iobase + 1);
   29.28 + 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   29.29 + 				dev_err(chip->dev, "error reading data\n");
   29.30 + 				return -EIO;
   29.31 +@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
   29.32 + 
   29.33 + 	/* read all the data available */
   29.34 + 	for (; i < size; i++) {
   29.35 +-		status = ioread8(chip->vendor->iobase + 1);
   29.36 ++		status = ioread8(chip->vendor.iobase + 1);
   29.37 + 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   29.38 + 			dev_err(chip->dev, "error reading data\n");
   29.39 + 			return -EIO;
   29.40 + 		}
   29.41 +-		*buf++ = ioread8(chip->vendor->iobase);
   29.42 ++		*buf++ = ioread8(chip->vendor.iobase);
   29.43 + 	}
   29.44 + 
   29.45 + 	/* make sure data available is gone */
   29.46 +-	status = ioread8(chip->vendor->iobase + 1);
   29.47 ++	status = ioread8(chip->vendor.iobase + 1);
   29.48 + 
   29.49 + 	if (status & ATML_STATUS_DATA_AVAIL) {
   29.50 + 		dev_err(chip->dev, "data available is stuck\n");
   29.51 +@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
   29.52 + 	dev_dbg(chip->dev, "tpm_atml_send:\n");
   29.53 + 	for (i = 0; i < count; i++) {
   29.54 + 		dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
   29.55 +- 		iowrite8(buf[i], chip->vendor->iobase);
   29.56 ++ 		iowrite8(buf[i], chip->vendor.iobase);
   29.57 + 	}
   29.58 + 
   29.59 + 	return count;
   29.60 +@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
   29.61 + 
   29.62 + static void tpm_atml_cancel(struct tpm_chip *chip)
   29.63 + {
   29.64 +-	iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
   29.65 ++	iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
   29.66 + }
   29.67 + 
   29.68 + static u8 tpm_atml_status(struct tpm_chip *chip)
   29.69 + {
   29.70 +-	return ioread8(chip->vendor->iobase + 1);
   29.71 ++	return ioread8(chip->vendor.iobase + 1);
   29.72 + }
   29.73 + 
   29.74 + static struct file_operations atmel_ops = {
   29.75 +@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
   29.76 + 
   29.77 + static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
   29.78 + 
   29.79 +-static struct tpm_vendor_specific tpm_atmel = {
   29.80 ++static const struct tpm_vendor_specific tpm_atmel = {
   29.81 + 	.recv = tpm_atml_recv,
   29.82 + 	.send = tpm_atml_send,
   29.83 + 	.cancel = tpm_atml_cancel,
   29.84 +@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
   29.85 + 	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
   29.86 + 
   29.87 + 	if (chip) {
   29.88 +-		if (chip->vendor->have_region)
   29.89 +-			atmel_release_region(chip->vendor->base,
   29.90 +-					     chip->vendor->region_size);
   29.91 +-		atmel_put_base_addr(chip->vendor);
   29.92 ++		if (chip->vendor.have_region)
   29.93 ++			atmel_release_region(chip->vendor.base,
   29.94 ++					     chip->vendor.region_size);
   29.95 ++		atmel_put_base_addr(chip->vendor.iobase);
   29.96 + 		tpm_remove_hardware(chip->dev);
   29.97 + 		platform_device_unregister(pdev);
   29.98 + 	}
   29.99 +@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
  29.100 + static int __init init_atmel(void)
  29.101 + {
  29.102 + 	int rc = 0;
  29.103 ++	void __iomem *iobase = NULL;
  29.104 ++	int have_region, region_size;
  29.105 ++	unsigned long base;
  29.106 ++	struct  tpm_chip *chip;
  29.107 + 
  29.108 + 	driver_register(&atml_drv);
  29.109 + 
  29.110 +-	if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
  29.111 ++	if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
  29.112 + 		rc = -ENODEV;
  29.113 + 		goto err_unreg_drv;
  29.114 + 	}
  29.115 + 
  29.116 +-	tpm_atmel.have_region =
  29.117 ++	have_region =
  29.118 + 	    (atmel_request_region
  29.119 +-	     (tpm_atmel.base, tpm_atmel.region_size,
  29.120 +-	      "tpm_atmel0") == NULL) ? 0 : 1;
  29.121 ++	     (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
  29.122 ++
  29.123 + 
  29.124 + 	if (IS_ERR
  29.125 + 	    (pdev =
  29.126 +@@ -199,17 +203,25 @@ static int __init init_atmel(void)
  29.127 + 		goto err_rel_reg;
  29.128 + 	}
  29.129 + 
  29.130 +-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
  29.131 ++	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
  29.132 ++		rc = -ENODEV;
  29.133 + 		goto err_unreg_dev;
  29.134 ++	}
  29.135 ++
  29.136 ++	chip->vendor.iobase = iobase;
  29.137 ++	chip->vendor.base = base;
  29.138 ++	chip->vendor.have_region = have_region;
  29.139 ++	chip->vendor.region_size = region_size;
  29.140 ++
  29.141 + 	return 0;
  29.142 + 
  29.143 + err_unreg_dev:
  29.144 + 	platform_device_unregister(pdev);
  29.145 + err_rel_reg:
  29.146 +-	atmel_put_base_addr(&tpm_atmel);
  29.147 +-	if (tpm_atmel.have_region)
  29.148 +-		atmel_release_region(tpm_atmel.base,
  29.149 +-				     tpm_atmel.region_size);
  29.150 ++	atmel_put_base_addr(iobase);
  29.151 ++	if (have_region)
  29.152 ++		atmel_release_region(base,
  29.153 ++				     region_size);
  29.154 + err_unreg_drv:
  29.155 + 	driver_unregister(&atml_drv);
  29.156 + 	return rc;
  29.157 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h ./drivers/char/tpm/tpm_atmel.h
  29.158 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h	2006-06-26 18:05:03.000000000 -0400
  29.159 ++++ ./drivers/char/tpm/tpm_atmel.h	2006-06-26 18:16:33.000000000 -0400
  29.160 +@@ -28,13 +28,12 @@
  29.161 + #define atmel_request_region request_mem_region
  29.162 + #define atmel_release_region release_mem_region
  29.163 + 
  29.164 +-static inline void atmel_put_base_addr(struct tpm_vendor_specific
  29.165 +-					 *vendor)
  29.166 ++static inline void atmel_put_base_addr(void __iomem *iobase)
  29.167 + {
  29.168 +-	iounmap(vendor->iobase);
  29.169 ++	iounmap(iobase);
  29.170 + }
  29.171 + 
  29.172 +-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
  29.173 ++static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  29.174 + {
  29.175 + 	struct device_node *dn;
  29.176 + 	unsigned long address, size;
  29.177 +@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
  29.178 + 	else
  29.179 + 		size = reg[naddrc];
  29.180 + 
  29.181 +-	vendor->base = address;
  29.182 +-	vendor->region_size = size;
  29.183 +-	return ioremap(vendor->base, vendor->region_size);
  29.184 ++	*base = address;
  29.185 ++	*region_size = size;
  29.186 ++	return ioremap(*base, *region_size);
  29.187 + }
  29.188 + #else
  29.189 + #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
  29.190 +@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
  29.191 + 	return 0;
  29.192 + }
  29.193 + 
  29.194 +-static inline void atmel_put_base_addr(struct tpm_vendor_specific
  29.195 +-					 *vendor)
  29.196 ++static inline void atmel_put_base_addr(void __iomem *iobase)
  29.197 + {
  29.198 + }
  29.199 + 
  29.200 + /* Determine where to talk to device */
  29.201 +-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
  29.202 +-					 *vendor)
  29.203 ++static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  29.204 + {
  29.205 + 	int lo, hi;
  29.206 + 
  29.207 +@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
  29.208 + 	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
  29.209 + 	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
  29.210 + 
  29.211 +-	vendor->base = (hi << 8) | lo;
  29.212 +-	vendor->region_size = 2;
  29.213 ++	*base = (hi << 8) | lo;
  29.214 ++	*region_size = 2;
  29.215 + 
  29.216 +-	return ioport_map(vendor->base, vendor->region_size);
  29.217 ++	return ioport_map(*base, *region_size);
  29.218 + }
  29.219 + #endif
  29.220 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c ./drivers/char/tpm/tpm_bios.c
  29.221 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c	2006-06-26 18:05:03.000000000 -0400
  29.222 ++++ ./drivers/char/tpm/tpm_bios.c	2006-06-26 18:16:33.000000000 -0400
  29.223 +@@ -29,6 +29,11 @@
  29.224 + #define MAX_TEXT_EVENT		1000	/* Max event string length */
  29.225 + #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
  29.226 + 
  29.227 ++enum bios_platform_class {
  29.228 ++	BIOS_CLIENT = 0x00,
  29.229 ++	BIOS_SERVER = 0x01,
  29.230 ++};
  29.231 ++
  29.232 + struct tpm_bios_log {
  29.233 + 	void *bios_event_log;
  29.234 + 	void *bios_event_log_end;
  29.235 +@@ -36,9 +41,18 @@ struct tpm_bios_log {
  29.236 + 
  29.237 + struct acpi_tcpa {
  29.238 + 	struct acpi_table_header hdr;
  29.239 +-	u16 reserved;
  29.240 +-	u32 log_max_len __attribute__ ((packed));
  29.241 +-	u32 log_start_addr __attribute__ ((packed));
  29.242 ++	u16 platform_class;
  29.243 ++	union {
  29.244 ++		struct client_hdr {
  29.245 ++			u32 log_max_len __attribute__ ((packed));
  29.246 ++			u64 log_start_addr __attribute__ ((packed));
  29.247 ++		} client;
  29.248 ++		struct server_hdr {
  29.249 ++			u16 reserved;
  29.250 ++			u64 log_max_len __attribute__ ((packed));
  29.251 ++			u64 log_start_addr __attribute__ ((packed));
  29.252 ++		} server;
  29.253 ++	};
  29.254 + };
  29.255 + 
  29.256 + struct tcpa_event {
  29.257 +@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
  29.258 + 	"Non-Host Info"
  29.259 + };
  29.260 + 
  29.261 ++struct tcpa_pc_event {
  29.262 ++	u32 event_id;
  29.263 ++	u32 event_size;
  29.264 ++	u8 event_data[0];
  29.265 ++};
  29.266 ++
  29.267 + enum tcpa_pc_event_ids {
  29.268 + 	SMBIOS = 1,
  29.269 + 	BIS_CERT,
  29.270 +@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
  29.271 + 	NVRAM,
  29.272 + 	OPTION_ROM_EXEC,
  29.273 + 	OPTION_ROM_CONFIG,
  29.274 +-	OPTION_ROM_MICROCODE,
  29.275 ++	OPTION_ROM_MICROCODE = 10,
  29.276 + 	S_CRTM_VERSION,
  29.277 + 	S_CRTM_CONTENTS,
  29.278 + 	POST_CONTENTS,
  29.279 ++	HOST_TABLE_OF_DEVICES,
  29.280 + };
  29.281 + 
  29.282 + static const char* tcpa_pc_event_id_strings[] = {
  29.283 +-	""
  29.284 ++	"",
  29.285 + 	"SMBIOS",
  29.286 + 	"BIS Certificate",
  29.287 + 	"POST BIOS ",
  29.288 +@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
  29.289 + 	"NVRAM",
  29.290 + 	"Option ROM",
  29.291 + 	"Option ROM config",
  29.292 +-	"Option ROM microcode",
  29.293 ++	"",
  29.294 ++	"Option ROM microcode ",
  29.295 + 	"S-CRTM Version",
  29.296 +-	"S-CRTM Contents",
  29.297 +-	"S-CRTM POST Contents",
  29.298 ++	"S-CRTM Contents ",
  29.299 ++	"POST Contents ",
  29.300 ++	"Table of Devices",
  29.301 + };
  29.302 + 
  29.303 + /* returns pointer to start of pos. entry of tcg log */
  29.304 +@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
  29.305 + 	const char *name = "";
  29.306 + 	char data[40] = "";
  29.307 + 	int i, n_len = 0, d_len = 0;
  29.308 +-	u32 event_id;
  29.309 ++	struct tcpa_pc_event *pc_event;
  29.310 + 
  29.311 + 	switch(event->event_type) {
  29.312 + 	case PREBOOT:
  29.313 +@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
  29.314 + 		}
  29.315 + 		break;
  29.316 + 	case EVENT_TAG:
  29.317 +-		event_id = be32_to_cpu(*((u32 *)event_entry));
  29.318 ++		pc_event = (struct tcpa_pc_event *)event_entry;
  29.319 + 
  29.320 + 		/* ToDo Row data -> Base64 */
  29.321 + 
  29.322 +-		switch (event_id) {
  29.323 ++		switch (pc_event->event_id) {
  29.324 + 		case SMBIOS:
  29.325 + 		case BIS_CERT:
  29.326 + 		case CMOS:
  29.327 + 		case NVRAM:
  29.328 + 		case OPTION_ROM_EXEC:
  29.329 + 		case OPTION_ROM_CONFIG:
  29.330 +-		case OPTION_ROM_MICROCODE:
  29.331 + 		case S_CRTM_VERSION:
  29.332 +-		case S_CRTM_CONTENTS:
  29.333 +-		case POST_CONTENTS:
  29.334 +-			name = tcpa_pc_event_id_strings[event_id];
  29.335 ++			name = tcpa_pc_event_id_strings[pc_event->event_id];
  29.336 + 			n_len = strlen(name);
  29.337 + 			break;
  29.338 ++		/* hash data */
  29.339 + 		case POST_BIOS_ROM:
  29.340 + 		case ESCD:
  29.341 +-			name = tcpa_pc_event_id_strings[event_id];
  29.342 ++		case OPTION_ROM_MICROCODE:
  29.343 ++		case S_CRTM_CONTENTS:
  29.344 ++		case POST_CONTENTS:
  29.345 ++			name = tcpa_pc_event_id_strings[pc_event->event_id];
  29.346 + 			n_len = strlen(name);
  29.347 + 			for (i = 0; i < 20; i++)
  29.348 +-				d_len += sprintf(data, "%02x",
  29.349 +-						event_entry[8 + i]);
  29.350 ++				d_len += sprintf(&data[2*i], "%02x",
  29.351 ++						pc_event->event_data[i]);
  29.352 + 			break;
  29.353 + 		default:
  29.354 + 			break;
  29.355 +@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
  29.356 + 
  29.357 + static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
  29.358 + {
  29.359 ++	struct tcpa_event *event = v;
  29.360 ++	char *data = v;
  29.361 ++	int i;
  29.362 + 
  29.363 +-	char *eventname;
  29.364 +-	char data[4];
  29.365 +-	u32 help;
  29.366 +-	int i, len;
  29.367 +-	struct tcpa_event *event = (struct tcpa_event *) v;
  29.368 +-	unsigned char *event_entry =
  29.369 +-	    (unsigned char *) (v + sizeof(struct tcpa_event));
  29.370 +-
  29.371 +-	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
  29.372 +-	if (!eventname) {
  29.373 +-		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
  29.374 +-		       __func__);
  29.375 +-		return -ENOMEM;
  29.376 +-	}
  29.377 +-
  29.378 +-	/* 1st: PCR used is in little-endian format (4 bytes) */
  29.379 +-	help = le32_to_cpu(event->pcr_index);
  29.380 +-	memcpy(data, &help, 4);
  29.381 +-	for (i = 0; i < 4; i++)
  29.382 +-		seq_putc(m, data[i]);
  29.383 +-
  29.384 +-	/* 2nd: SHA1 (20 bytes) */
  29.385 +-	for (i = 0; i < 20; i++)
  29.386 +-		seq_putc(m, event->pcr_value[i]);
  29.387 +-
  29.388 +-	/* 3rd: event type identifier (4 bytes) */
  29.389 +-	help = le32_to_cpu(event->event_type);
  29.390 +-	memcpy(data, &help, 4);
  29.391 +-	for (i = 0; i < 4; i++)
  29.392 ++	for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
  29.393 + 		seq_putc(m, data[i]);
  29.394 + 
  29.395 +-	len = 0;
  29.396 +-
  29.397 +-	len += get_event_name(eventname, event, event_entry);
  29.398 +-
  29.399 +-	/* 4th:  filename <= 255 + \'0' delimiter */
  29.400 +-	if (len > TCG_EVENT_NAME_LEN_MAX)
  29.401 +-		len = TCG_EVENT_NAME_LEN_MAX;
  29.402 +-
  29.403 +-	for (i = 0; i < len; i++)
  29.404 +-		seq_putc(m, eventname[i]);
  29.405 +-
  29.406 +-	/* 5th: delimiter */
  29.407 +-	seq_putc(m, '\0');
  29.408 +-
  29.409 + 	return 0;
  29.410 + }
  29.411 + 
  29.412 +@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
  29.413 + 	/* 4th: eventname <= max + \'0' delimiter */
  29.414 + 	seq_printf(m, " %s\n", eventname);
  29.415 + 
  29.416 ++	kfree(eventname);
  29.417 + 	return 0;
  29.418 + }
  29.419 + 
  29.420 +@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
  29.421 + 	struct acpi_tcpa *buff;
  29.422 + 	acpi_status status;
  29.423 + 	struct acpi_table_header *virt;
  29.424 ++	u64 len, start;
  29.425 + 
  29.426 + 	if (log->bios_event_log != NULL) {
  29.427 + 		printk(KERN_ERR
  29.428 +@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
  29.429 + 		return -EIO;
  29.430 + 	}
  29.431 + 
  29.432 +-	if (buff->log_max_len == 0) {
  29.433 ++	switch(buff->platform_class) {
  29.434 ++	case BIOS_SERVER:
  29.435 ++		len = buff->server.log_max_len;
  29.436 ++		start = buff->server.log_start_addr;
  29.437 ++		break;
  29.438 ++	case BIOS_CLIENT:
  29.439 ++	default:
  29.440 ++		len = buff->client.log_max_len;
  29.441 ++		start = buff->client.log_start_addr;
  29.442 ++		break;
  29.443 ++	}
  29.444 ++	if (!len) {
  29.445 + 		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
  29.446 + 		return -EIO;
  29.447 + 	}
  29.448 + 
  29.449 + 	/* malloc EventLog space */
  29.450 +-	log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
  29.451 ++	log->bios_event_log = kmalloc(len, GFP_KERNEL);
  29.452 + 	if (!log->bios_event_log) {
  29.453 +-		printk
  29.454 +-		    ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
  29.455 +-		     __func__);
  29.456 ++		printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
  29.457 ++			__func__);
  29.458 + 		return -ENOMEM;
  29.459 + 	}
  29.460 + 
  29.461 +-	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
  29.462 ++	log->bios_event_log_end = log->bios_event_log + len;
  29.463 + 
  29.464 +-	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
  29.465 ++	acpi_os_map_memory(start, len, (void *) &virt);
  29.466 + 
  29.467 +-	memcpy(log->bios_event_log, virt, buff->log_max_len);
  29.468 ++	memcpy(log->bios_event_log, virt, len);
  29.469 + 
  29.470 +-	acpi_os_unmap_memory(virt, buff->log_max_len);
  29.471 ++	acpi_os_unmap_memory(virt, len);
  29.472 + 	return 0;
  29.473 + }
  29.474 + 
  29.475 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c ./drivers/char/tpm/tpm_infineon.c
  29.476 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c	2006-06-26 18:05:03.000000000 -0400
  29.477 ++++ ./drivers/char/tpm/tpm_infineon.c	2006-06-26 18:16:33.000000000 -0400
  29.478 +@@ -15,6 +15,7 @@
  29.479 +  * License.
  29.480 +  */
  29.481 + 
  29.482 ++#include <linux/init.h>
  29.483 + #include <linux/pnp.h>
  29.484 + #include "tpm.h"
  29.485 + 
  29.486 +@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
  29.487 + 
  29.488 + 	if (clear_wrfifo) {
  29.489 + 		for (i = 0; i < 4096; i++) {
  29.490 +-			status = inb(chip->vendor->base + WRFIFO);
  29.491 ++			status = inb(chip->vendor.base + WRFIFO);
  29.492 + 			if (status == 0xff) {
  29.493 + 				if (check == 5)
  29.494 + 					break;
  29.495 +@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
  29.496 + 	 */
  29.497 + 	i = 0;
  29.498 + 	do {
  29.499 +-		status = inb(chip->vendor->base + RDFIFO);
  29.500 +-		status = inb(chip->vendor->base + STAT);
  29.501 ++		status = inb(chip->vendor.base + RDFIFO);
  29.502 ++		status = inb(chip->vendor.base + STAT);
  29.503 + 		i++;
  29.504 + 		if (i == TPM_MAX_TRIES)
  29.505 + 			return -EIO;
  29.506 +@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
  29.507 + 	int status;
  29.508 + 	int i;
  29.509 + 	for (i = 0; i < TPM_MAX_TRIES; i++) {
  29.510 +-		status = inb(chip->vendor->base + STAT);
  29.511 ++		status = inb(chip->vendor.base + STAT);
  29.512 + 		/* check the status-register if wait_for_bit is set */
  29.513 + 		if (status & 1 << wait_for_bit)
  29.514 + 			break;
  29.515 +@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
  29.516 + static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
  29.517 + {
  29.518 + 	wait(chip, STAT_XFE);
  29.519 +-	outb(sendbyte, chip->vendor->base + WRFIFO);
  29.520 ++	outb(sendbyte, chip->vendor.base + WRFIFO);
  29.521 + }
  29.522 + 
  29.523 +     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
  29.524 +@@ -204,7 +205,7 @@ recv_begin:
  29.525 + 		ret = wait(chip, STAT_RDA);
  29.526 + 		if (ret)
  29.527 + 			return -EIO;
  29.528 +-		buf[i] = inb(chip->vendor->base + RDFIFO);
  29.529 ++		buf[i] = inb(chip->vendor.base + RDFIFO);
  29.530 + 	}
  29.531 + 
  29.532 + 	if (buf[0] != TPM_VL_VER) {
  29.533 +@@ -219,7 +220,7 @@ recv_begin:
  29.534 + 
  29.535 + 		for (i = 0; i < size; i++) {
  29.536 + 			wait(chip, STAT_RDA);
  29.537 +-			buf[i] = inb(chip->vendor->base + RDFIFO);
  29.538 ++			buf[i] = inb(chip->vendor.base + RDFIFO);
  29.539 + 		}
  29.540 + 
  29.541 + 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
  29.542 +@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
  29.543 + 	u8 count_high, count_low, count_4, count_3, count_2, count_1;
  29.544 + 
  29.545 + 	/* Disabling Reset, LP and IRQC */
  29.546 +-	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
  29.547 ++	outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
  29.548 + 
  29.549 + 	ret = empty_fifo(chip, 1);
  29.550 + 	if (ret) {
  29.551 +@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
  29.552 + 
  29.553 + static u8 tpm_inf_status(struct tpm_chip *chip)
  29.554 + {
  29.555 +-	return inb(chip->vendor->base + STAT);
  29.556 ++	return inb(chip->vendor.base + STAT);
  29.557 + }
  29.558 + 
  29.559 + static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  29.560 +@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
  29.561 + 	.release = tpm_release,
  29.562 + };
  29.563 + 
  29.564 +-static struct tpm_vendor_specific tpm_inf = {
  29.565 ++static const struct tpm_vendor_specific tpm_inf = {
  29.566 + 	.recv = tpm_inf_recv,
  29.567 + 	.send = tpm_inf_send,
  29.568 + 	.cancel = tpm_inf_cancel,
  29.569 +@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
  29.570 + 	int version[2];
  29.571 + 	int productid[2];
  29.572 + 	char chipname[20];
  29.573 ++	struct tpm_chip *chip;
  29.574 + 
  29.575 + 	/* read IO-ports through PnP */
  29.576 + 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
  29.577 +@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
  29.578 + 			goto err_last;
  29.579 + 		}
  29.580 + 		/* publish my base address and request region */
  29.581 +-		tpm_inf.base = TPM_INF_BASE;
  29.582 + 		if (request_region
  29.583 +-		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
  29.584 ++		    (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
  29.585 + 			rc = -EINVAL;
  29.586 + 			goto err_last;
  29.587 + 		}
  29.588 +-		if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
  29.589 +-				"tpm_infineon0") == NULL) {
  29.590 ++		if (request_region
  29.591 ++		    (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
  29.592 + 			rc = -EINVAL;
  29.593 + 			goto err_last;
  29.594 + 		}
  29.595 +@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
  29.596 + 
  29.597 + 		/* configure TPM with IO-ports */
  29.598 + 		outb(IOLIMH, TPM_INF_ADDR);
  29.599 +-		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
  29.600 ++		outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
  29.601 + 		outb(IOLIML, TPM_INF_ADDR);
  29.602 +-		outb((tpm_inf.base & 0xff), TPM_INF_DATA);
  29.603 ++		outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
  29.604 + 
  29.605 + 		/* control if IO-ports are set correctly */
  29.606 + 		outb(IOLIMH, TPM_INF_ADDR);
  29.607 +@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
  29.608 + 		outb(IOLIML, TPM_INF_ADDR);
  29.609 + 		iol = inb(TPM_INF_DATA);
  29.610 + 
  29.611 +-		if ((ioh << 8 | iol) != tpm_inf.base) {
  29.612 ++		if ((ioh << 8 | iol) != TPM_INF_BASE) {
  29.613 + 			dev_err(&dev->dev,
  29.614 +-				"Could not set IO-ports to 0x%lx\n",
  29.615 +-				tpm_inf.base);
  29.616 ++				"Could not set IO-ports to 0x%x\n",
  29.617 ++				TPM_INF_BASE);
  29.618 + 			rc = -EIO;
  29.619 + 			goto err_release_region;
  29.620 + 		}
  29.621 +@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
  29.622 + 		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
  29.623 + 
  29.624 + 		/* disable RESET, LP and IRQC */
  29.625 +-		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
  29.626 ++		outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
  29.627 + 
  29.628 + 		/* Finally, we're done, print some infos */
  29.629 + 		dev_info(&dev->dev, "TPM found: "
  29.630 + 			 "config base 0x%x, "
  29.631 + 			 "io base 0x%x, "
  29.632 +-			 "chip version %02x%02x, "
  29.633 +-			 "vendor id %x%x (Infineon), "
  29.634 +-			 "product id %02x%02x"
  29.635 ++			 "chip version 0x%02x%02x, "
  29.636 ++			 "vendor id 0x%x%x (Infineon), "
  29.637 ++			 "product id 0x%02x%02x"
  29.638 + 			 "%s\n",
  29.639 + 			 TPM_INF_ADDR,
  29.640 + 			 TPM_INF_BASE,
  29.641 +@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
  29.642 + 			 vendorid[0], vendorid[1],
  29.643 + 			 productid[0], productid[1], chipname);
  29.644 + 
  29.645 +-		rc = tpm_register_hardware(&dev->dev, &tpm_inf);
  29.646 +-		if (rc < 0) {
  29.647 +-			rc = -ENODEV;
  29.648 ++		if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
  29.649 + 			goto err_release_region;
  29.650 + 		}
  29.651 ++		chip->vendor.base = TPM_INF_BASE;
  29.652 + 		return 0;
  29.653 + 	} else {
  29.654 + 		rc = -ENODEV;
  29.655 +@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
  29.656 + 	}
  29.657 + 
  29.658 + err_release_region:
  29.659 +-	release_region(tpm_inf.base, TPM_INF_PORT_LEN);
  29.660 ++	release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
  29.661 + 	release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
  29.662 + 
  29.663 + err_last:
  29.664 +@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
  29.665 + 	struct tpm_chip *chip = pnp_get_drvdata(dev);
  29.666 + 
  29.667 + 	if (chip) {
  29.668 +-		release_region(chip->vendor->base, TPM_INF_PORT_LEN);
  29.669 ++		release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
  29.670 ++		release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
  29.671 + 		tpm_remove_hardware(chip->dev);
  29.672 + 	}
  29.673 + }
  29.674 +@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
  29.675 + 	},
  29.676 + 	.id_table = tpm_pnp_tbl,
  29.677 + 	.probe = tpm_inf_pnp_probe,
  29.678 +-	.remove = tpm_inf_pnp_remove,
  29.679 ++	.remove = __devexit_p(tpm_inf_pnp_remove),
  29.680 + };
  29.681 + 
  29.682 + static int __init init_inf(void)
  29.683 +@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
  29.684 + 
  29.685 + MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
  29.686 + MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
  29.687 +-MODULE_VERSION("1.7");
  29.688 ++MODULE_VERSION("1.8");
  29.689 + MODULE_LICENSE("GPL");
  29.690 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c ./drivers/char/tpm/tpm_nsc.c
  29.691 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c	2006-06-26 18:05:03.000000000 -0400
  29.692 ++++ ./drivers/char/tpm/tpm_nsc.c	2006-06-26 18:16:33.000000000 -0400
  29.693 +@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
  29.694 + 	unsigned long stop;
  29.695 + 
  29.696 + 	/* status immediately available check */
  29.697 +-	*data = inb(chip->vendor->base + NSC_STATUS);
  29.698 ++	*data = inb(chip->vendor.base + NSC_STATUS);
  29.699 + 	if ((*data & mask) == val)
  29.700 + 		return 0;
  29.701 + 
  29.702 +@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
  29.703 + 	stop = jiffies + 10 * HZ;
  29.704 + 	do {
  29.705 + 		msleep(TPM_TIMEOUT);
  29.706 +-		*data = inb(chip->vendor->base + 1);
  29.707 ++		*data = inb(chip->vendor.base + 1);
  29.708 + 		if ((*data & mask) == val)
  29.709 + 			return 0;
  29.710 + 	}
  29.711 +@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
  29.712 + 	unsigned long stop;
  29.713 + 
  29.714 + 	/* status immediately available check */
  29.715 +-	status = inb(chip->vendor->base + NSC_STATUS);
  29.716 ++	status = inb(chip->vendor.base + NSC_STATUS);
  29.717 + 	if (status & NSC_STATUS_OBF)
  29.718 +-		status = inb(chip->vendor->base + NSC_DATA);
  29.719 ++		status = inb(chip->vendor.base + NSC_DATA);
  29.720 + 	if (status & NSC_STATUS_RDY)
  29.721 + 		return 0;
  29.722 + 
  29.723 +@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
  29.724 + 	stop = jiffies + 100;
  29.725 + 	do {
  29.726 + 		msleep(TPM_TIMEOUT);
  29.727 +-		status = inb(chip->vendor->base + NSC_STATUS);
  29.728 ++		status = inb(chip->vendor.base + NSC_STATUS);
  29.729 + 		if (status & NSC_STATUS_OBF)
  29.730 +-			status = inb(chip->vendor->base + NSC_DATA);
  29.731 ++			status = inb(chip->vendor.base + NSC_DATA);
  29.732 + 		if (status & NSC_STATUS_RDY)
  29.733 + 			return 0;
  29.734 + 	}
  29.735 +@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  29.736 + 		return -EIO;
  29.737 + 	}
  29.738 + 	if ((data =
  29.739 +-	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  29.740 ++	     inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  29.741 + 		dev_err(chip->dev, "not in normal mode (0x%x)\n",
  29.742 + 			data);
  29.743 + 		return -EIO;
  29.744 +@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  29.745 + 		}
  29.746 + 		if (data & NSC_STATUS_F0)
  29.747 + 			break;
  29.748 +-		*p = inb(chip->vendor->base + NSC_DATA);
  29.749 ++		*p = inb(chip->vendor.base + NSC_DATA);
  29.750 + 	}
  29.751 + 
  29.752 + 	if ((data & NSC_STATUS_F0) == 0 &&
  29.753 +@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  29.754 + 		dev_err(chip->dev, "F0 not set\n");
  29.755 + 		return -EIO;
  29.756 + 	}
  29.757 +-	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
  29.758 ++	if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
  29.759 + 		dev_err(chip->dev,
  29.760 + 			"expected end of command(0x%x)\n", data);
  29.761 + 		return -EIO;
  29.762 +@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
  29.763 + 	 * fix it. Not sure why this is needed, we followed the flow
  29.764 + 	 * chart in the manual to the letter.
  29.765 + 	 */
  29.766 +-	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  29.767 ++	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
  29.768 + 
  29.769 + 	if (nsc_wait_for_ready(chip) != 0)
  29.770 + 		return -EIO;
  29.771 +@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
  29.772 + 		return -EIO;
  29.773 + 	}
  29.774 + 
  29.775 +-	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
  29.776 ++	outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
  29.777 + 	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
  29.778 + 		dev_err(chip->dev, "IBR timeout\n");
  29.779 + 		return -EIO;
  29.780 +@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
  29.781 + 				"IBF timeout (while writing data)\n");
  29.782 + 			return -EIO;
  29.783 + 		}
  29.784 +-		outb(buf[i], chip->vendor->base + NSC_DATA);
  29.785 ++		outb(buf[i], chip->vendor.base + NSC_DATA);
  29.786 + 	}
  29.787 + 
  29.788 + 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
  29.789 + 		dev_err(chip->dev, "IBF timeout\n");
  29.790 + 		return -EIO;
  29.791 + 	}
  29.792 +-	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
  29.793 ++	outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
  29.794 + 
  29.795 + 	return count;
  29.796 + }
  29.797 + 
  29.798 + static void tpm_nsc_cancel(struct tpm_chip *chip)
  29.799 + {
  29.800 +-	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  29.801 ++	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
  29.802 + }
  29.803 + 
  29.804 + static u8 tpm_nsc_status(struct tpm_chip *chip)
  29.805 + {
  29.806 +-	return inb(chip->vendor->base + NSC_STATUS);
  29.807 ++	return inb(chip->vendor.base + NSC_STATUS);
  29.808 + }
  29.809 + 
  29.810 + static struct file_operations nsc_ops = {
  29.811 +@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
  29.812 + 
  29.813 + static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
  29.814 + 
  29.815 +-static struct tpm_vendor_specific tpm_nsc = {
  29.816 ++static const struct tpm_vendor_specific tpm_nsc = {
  29.817 + 	.recv = tpm_nsc_recv,
  29.818 + 	.send = tpm_nsc_send,
  29.819 + 	.cancel = tpm_nsc_cancel,
  29.820 +@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
  29.821 + {
  29.822 + 	struct tpm_chip *chip = dev_get_drvdata(dev);
  29.823 + 	if ( chip ) {
  29.824 +-		release_region(chip->vendor->base, 2);
  29.825 ++		release_region(chip->vendor.base, 2);
  29.826 + 		tpm_remove_hardware(chip->dev);
  29.827 + 	}
  29.828 + }
  29.829 +@@ -286,7 +286,8 @@ static int __init init_nsc(void)
  29.830 + 	int rc = 0;
  29.831 + 	int lo, hi;
  29.832 + 	int nscAddrBase = TPM_ADDR;
  29.833 +-
  29.834 ++	struct tpm_chip *chip;
  29.835 ++	unsigned long base;
  29.836 + 
  29.837 + 	/* verify that it is a National part (SID) */
  29.838 + 	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
  29.839 +@@ -300,7 +301,7 @@ static int __init init_nsc(void)
  29.840 + 
  29.841 + 	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
  29.842 + 	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
  29.843 +-	tpm_nsc.base = (hi<<8) | lo;
  29.844 ++	base = (hi<<8) | lo;
  29.845 + 
  29.846 + 	/* enable the DPM module */
  29.847 + 	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
  29.848 +@@ -320,13 +321,15 @@ static int __init init_nsc(void)
  29.849 + 	if ((rc = platform_device_register(pdev)) < 0)
  29.850 + 		goto err_free_dev;
  29.851 + 
  29.852 +-	if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
  29.853 ++	if (request_region(base, 2, "tpm_nsc0") == NULL ) {
  29.854 + 		rc = -EBUSY;
  29.855 + 		goto err_unreg_dev;
  29.856 + 	}
  29.857 + 
  29.858 +-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
  29.859 ++	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
  29.860 ++		rc = -ENODEV;
  29.861 + 		goto err_rel_reg;
  29.862 ++	}
  29.863 + 
  29.864 + 	dev_dbg(&pdev->dev, "NSC TPM detected\n");
  29.865 + 	dev_dbg(&pdev->dev,
  29.866 +@@ -361,10 +364,12 @@ static int __init init_nsc(void)
  29.867 + 		 "NSC TPM revision %d\n",
  29.868 + 		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
  29.869 + 
  29.870 ++	chip->vendor.base = base;
  29.871 ++
  29.872 + 	return 0;
  29.873 + 
  29.874 + err_rel_reg:
  29.875 +-	release_region(tpm_nsc.base, 2);
  29.876 ++	release_region(base, 2);
  29.877 + err_unreg_dev:
  29.878 + 	platform_device_unregister(pdev);
  29.879 + err_free_dev:
  29.880 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c ./drivers/char/tpm/tpm_tis.c
  29.881 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c	1969-12-31 19:00:00.000000000 -0500
  29.882 ++++ ./drivers/char/tpm/tpm_tis.c	2006-06-26 18:16:33.000000000 -0400
  29.883 +@@ -0,0 +1,665 @@
  29.884 ++/*
  29.885 ++ * Copyright (C) 2005, 2006 IBM Corporation
  29.886 ++ *
  29.887 ++ * Authors:
  29.888 ++ * Leendert van Doorn <leendert@watson.ibm.com>
  29.889 ++ * Kylene Hall <kjhall@us.ibm.com>
  29.890 ++ *
  29.891 ++ * Device driver for TCG/TCPA TPM (trusted platform module).
  29.892 ++ * Specifications at www.trustedcomputinggroup.org
  29.893 ++ *
  29.894 ++ * This device driver implements the TPM interface as defined in
  29.895 ++ * the TCG TPM Interface Spec version 1.2, revision 1.0.
  29.896 ++ *
  29.897 ++ * This program is free software; you can redistribute it and/or
  29.898 ++ * modify it under the terms of the GNU General Public License as
  29.899 ++ * published by the Free Software Foundation, version 2 of the
  29.900 ++ * License.
  29.901 ++ */
  29.902 ++#include <linux/init.h>
  29.903 ++#include <linux/module.h>
  29.904 ++#include <linux/moduleparam.h>
  29.905 ++#include <linux/pnp.h>
  29.906 ++#include <linux/interrupt.h>
  29.907 ++#include <linux/wait.h>
  29.908 ++#include "tpm.h"
  29.909 ++
  29.910 ++#define TPM_HEADER_SIZE 10
  29.911 ++
  29.912 ++enum tis_access {
  29.913 ++	TPM_ACCESS_VALID = 0x80,
  29.914 ++	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
  29.915 ++	TPM_ACCESS_REQUEST_PENDING = 0x04,
  29.916 ++	TPM_ACCESS_REQUEST_USE = 0x02,
  29.917 ++};
  29.918 ++
  29.919 ++enum tis_status {
  29.920 ++	TPM_STS_VALID = 0x80,
  29.921 ++	TPM_STS_COMMAND_READY = 0x40,
  29.922 ++	TPM_STS_GO = 0x20,
  29.923 ++	TPM_STS_DATA_AVAIL = 0x10,
  29.924 ++	TPM_STS_DATA_EXPECT = 0x08,
  29.925 ++};
  29.926 ++
  29.927 ++enum tis_int_flags {
  29.928 ++	TPM_GLOBAL_INT_ENABLE = 0x80000000,
  29.929 ++	TPM_INTF_BURST_COUNT_STATIC = 0x100,
  29.930 ++	TPM_INTF_CMD_READY_INT = 0x080,
  29.931 ++	TPM_INTF_INT_EDGE_FALLING = 0x040,
  29.932 ++	TPM_INTF_INT_EDGE_RISING = 0x020,
  29.933 ++	TPM_INTF_INT_LEVEL_LOW = 0x010,
  29.934 ++	TPM_INTF_INT_LEVEL_HIGH = 0x008,
  29.935 ++	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
  29.936 ++	TPM_INTF_STS_VALID_INT = 0x002,
  29.937 ++	TPM_INTF_DATA_AVAIL_INT = 0x001,
  29.938 ++};
  29.939 ++
  29.940 ++enum tis_defaults {
  29.941 ++	TIS_MEM_BASE = 0xFED40000,
  29.942 ++	TIS_MEM_LEN = 0x5000,
  29.943 ++	TIS_SHORT_TIMEOUT = 750,	/* ms */
  29.944 ++	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
  29.945 ++};
  29.946 ++
  29.947 ++#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
  29.948 ++#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
  29.949 ++#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
  29.950 ++#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
  29.951 ++#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
  29.952 ++#define	TPM_STS(l)			(0x0018 | ((l) << 12))
  29.953 ++#define	TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
  29.954 ++
  29.955 ++#define	TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
  29.956 ++#define	TPM_RID(l)			(0x0F04 | ((l) << 12))
  29.957 ++
  29.958 ++static LIST_HEAD(tis_chips);
  29.959 ++static DEFINE_SPINLOCK(tis_lock);
  29.960 ++
  29.961 ++static int check_locality(struct tpm_chip *chip, int l)
  29.962 ++{
  29.963 ++	if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
  29.964 ++	     (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
  29.965 ++	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
  29.966 ++		return chip->vendor.locality = l;
  29.967 ++
  29.968 ++	return -1;
  29.969 ++}
  29.970 ++
  29.971 ++static void release_locality(struct tpm_chip *chip, int l, int force)
  29.972 ++{
  29.973 ++	if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
  29.974 ++		      (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
  29.975 ++	    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
  29.976 ++		iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
  29.977 ++			 chip->vendor.iobase + TPM_ACCESS(l));
  29.978 ++}
  29.979 ++
  29.980 ++static int request_locality(struct tpm_chip *chip, int l)
  29.981 ++{
  29.982 ++	unsigned long stop;
  29.983 ++	long rc;
  29.984 ++
  29.985 ++	if (check_locality(chip, l) >= 0)
  29.986 ++		return l;
  29.987 ++
  29.988 ++	iowrite8(TPM_ACCESS_REQUEST_USE,
  29.989 ++		 chip->vendor.iobase + TPM_ACCESS(l));
  29.990 ++
  29.991 ++	if (chip->vendor.irq) {
  29.992 ++		rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
  29.993 ++						      (check_locality
  29.994 ++						       (chip, l) >= 0),
  29.995 ++						      chip->vendor.timeout_a);
  29.996 ++		if (rc > 0)
  29.997 ++			return l;
  29.998 ++
  29.999 ++	} else {
 29.1000 ++		/* wait for burstcount */
 29.1001 ++		stop = jiffies + chip->vendor.timeout_a;
 29.1002 ++		do {
 29.1003 ++			if (check_locality(chip, l) >= 0)
 29.1004 ++				return l;
 29.1005 ++			msleep(TPM_TIMEOUT);
 29.1006 ++		}
 29.1007 ++		while (time_before(jiffies, stop));
 29.1008 ++	}
 29.1009 ++	return -1;
 29.1010 ++}
 29.1011 ++
 29.1012 ++static u8 tpm_tis_status(struct tpm_chip *chip)
 29.1013 ++{
 29.1014 ++	return ioread8(chip->vendor.iobase +
 29.1015 ++		       TPM_STS(chip->vendor.locality));
 29.1016 ++}
 29.1017 ++
 29.1018 ++static void tpm_tis_ready(struct tpm_chip *chip)
 29.1019 ++{
 29.1020 ++	/* this causes the current command to be aborted */
 29.1021 ++	iowrite8(TPM_STS_COMMAND_READY,
 29.1022 ++		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
 29.1023 ++}
 29.1024 ++
 29.1025 ++static int get_burstcount(struct tpm_chip *chip)
 29.1026 ++{
 29.1027 ++	unsigned long stop;
 29.1028 ++	int burstcnt;
 29.1029 ++
 29.1030 ++	/* wait for burstcount */
 29.1031 ++	/* which timeout value, spec has 2 answers (c & d) */
 29.1032 ++	stop = jiffies + chip->vendor.timeout_d;
 29.1033 ++	do {
 29.1034 ++		burstcnt = ioread8(chip->vendor.iobase +
 29.1035 ++				   TPM_STS(chip->vendor.locality) + 1);
 29.1036 ++		burstcnt += ioread8(chip->vendor.iobase +
 29.1037 ++				    TPM_STS(chip->vendor.locality) +
 29.1038 ++				    2) << 8;
 29.1039 ++		if (burstcnt)
 29.1040 ++			return burstcnt;
 29.1041 ++		msleep(TPM_TIMEOUT);
 29.1042 ++	} while (time_before(jiffies, stop));
 29.1043 ++	return -EBUSY;
 29.1044 ++}
 29.1045 ++
 29.1046 ++static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
 29.1047 ++			 wait_queue_head_t *queue)
 29.1048 ++{
 29.1049 ++	unsigned long stop;
 29.1050 ++	long rc;
 29.1051 ++	u8 status;
 29.1052 ++
 29.1053 ++	/* check current status */
 29.1054 ++	status = tpm_tis_status(chip);
 29.1055 ++	if ((status & mask) == mask)
 29.1056 ++		return 0;
 29.1057 ++
 29.1058 ++	if (chip->vendor.irq) {
 29.1059 ++		rc = wait_event_interruptible_timeout(*queue,
 29.1060 ++						      ((tpm_tis_status
 29.1061 ++							(chip) & mask) ==
 29.1062 ++						       mask), timeout);
 29.1063 ++		if (rc > 0)
 29.1064 ++			return 0;
 29.1065 ++	} else {
 29.1066 ++		stop = jiffies + timeout;
 29.1067 ++		do {
 29.1068 ++			msleep(TPM_TIMEOUT);
 29.1069 ++			status = tpm_tis_status(chip);
 29.1070 ++			if ((status & mask) == mask)
 29.1071 ++				return 0;
 29.1072 ++		} while (time_before(jiffies, stop));
 29.1073 ++	}
 29.1074 ++	return -ETIME;
 29.1075 ++}
 29.1076 ++
 29.1077 ++static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 29.1078 ++{
 29.1079 ++	int size = 0, burstcnt;
 29.1080 ++	while (size < count &&
 29.1081 ++	       wait_for_stat(chip,
 29.1082 ++			     TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 29.1083 ++			     chip->vendor.timeout_c,
 29.1084 ++			     &chip->vendor.read_queue)
 29.1085 ++	       == 0) {
 29.1086 ++		burstcnt = get_burstcount(chip);
 29.1087 ++		for (; burstcnt > 0 && size < count; burstcnt--)
 29.1088 ++			buf[size++] = ioread8(chip->vendor.iobase +
 29.1089 ++					      TPM_DATA_FIFO(chip->vendor.
 29.1090 ++							    locality));
 29.1091 ++	}
 29.1092 ++	return size;
 29.1093 ++}
 29.1094 ++
 29.1095 ++static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 29.1096 ++{
 29.1097 ++	int size = 0;
 29.1098 ++	int expected, status;
 29.1099 ++
 29.1100 ++	if (count < TPM_HEADER_SIZE) {
 29.1101 ++		size = -EIO;
 29.1102 ++		goto out;
 29.1103 ++	}
 29.1104 ++
 29.1105 ++	/* read first 10 bytes, including tag, paramsize, and result */
 29.1106 ++	if ((size =
 29.1107 ++	     recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
 29.1108 ++		dev_err(chip->dev, "Unable to read header\n");
 29.1109 ++		goto out;
 29.1110 ++	}
 29.1111 ++
 29.1112 ++	expected = be32_to_cpu(*(__be32 *) (buf + 2));
 29.1113 ++	if (expected > count) {
 29.1114 ++		size = -EIO;
 29.1115 ++		goto out;
 29.1116 ++	}
 29.1117 ++
 29.1118 ++	if ((size +=
 29.1119 ++	     recv_data(chip, &buf[TPM_HEADER_SIZE],
 29.1120 ++		       expected - TPM_HEADER_SIZE)) < expected) {
 29.1121 ++		dev_err(chip->dev, "Unable to read remainder of result\n");
 29.1122 ++		size = -ETIME;
 29.1123 ++		goto out;
 29.1124 ++	}
 29.1125 ++
 29.1126 ++	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 29.1127 ++		      &chip->vendor.int_queue);
 29.1128 ++	status = tpm_tis_status(chip);
 29.1129 ++	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
 29.1130 ++		dev_err(chip->dev, "Error left over data\n");
 29.1131 ++		size = -EIO;
 29.1132 ++		goto out;
 29.1133 ++	}
 29.1134 ++
 29.1135 ++out:
 29.1136 ++	tpm_tis_ready(chip);
 29.1137 ++	release_locality(chip, chip->vendor.locality, 0);
 29.1138 ++	return size;
 29.1139 ++}
 29.1140 ++
 29.1141 ++/*
 29.1142 ++ * If interrupts are used (signaled by an irq set in the vendor structure)
 29.1143 ++ * tpm.c can skip polling for the data to be available as the interrupt is
 29.1144 ++ * waited for here
 29.1145 ++ */
 29.1146 ++static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
 29.1147 ++{
 29.1148 ++	int rc, status, burstcnt;
 29.1149 ++	size_t count = 0;
 29.1150 ++	u32 ordinal;
 29.1151 ++
 29.1152 ++	if (request_locality(chip, 0) < 0)
 29.1153 ++		return -EBUSY;
 29.1154 ++
 29.1155 ++	status = tpm_tis_status(chip);
 29.1156 ++	if ((status & TPM_STS_COMMAND_READY) == 0) {
 29.1157 ++		tpm_tis_ready(chip);
 29.1158 ++		if (wait_for_stat
 29.1159 ++		    (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
 29.1160 ++		     &chip->vendor.int_queue) < 0) {
 29.1161 ++			rc = -ETIME;
 29.1162 ++			goto out_err;
 29.1163 ++		}
 29.1164 ++	}
 29.1165 ++
 29.1166 ++	while (count < len - 1) {
 29.1167 ++		burstcnt = get_burstcount(chip);
 29.1168 ++		for (; burstcnt > 0 && count < len - 1; burstcnt--) {
 29.1169 ++			iowrite8(buf[count], chip->vendor.iobase +
 29.1170 ++				 TPM_DATA_FIFO(chip->vendor.locality));
 29.1171 ++			count++;
 29.1172 ++		}
 29.1173 ++
 29.1174 ++		wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 29.1175 ++			      &chip->vendor.int_queue);
 29.1176 ++		status = tpm_tis_status(chip);
 29.1177 ++		if ((status & TPM_STS_DATA_EXPECT) == 0) {
 29.1178 ++			rc = -EIO;
 29.1179 ++			goto out_err;
 29.1180 ++		}
 29.1181 ++	}
 29.1182 ++
 29.1183 ++	/* write last byte */
 29.1184 ++	iowrite8(buf[count],
 29.1185 ++		 chip->vendor.iobase +
 29.1186 ++		 TPM_DATA_FIFO(chip->vendor.locality));
 29.1187 ++	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 29.1188 ++		      &chip->vendor.int_queue);
 29.1189 ++	status = tpm_tis_status(chip);
 29.1190 ++	if ((status & TPM_STS_DATA_EXPECT) != 0) {
 29.1191 ++		rc = -EIO;
 29.1192 ++		goto out_err;
 29.1193 ++	}
 29.1194 ++
 29.1195 ++	/* go and do it */
 29.1196 ++	iowrite8(TPM_STS_GO,
 29.1197 ++		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
 29.1198 ++
 29.1199 ++	if (chip->vendor.irq) {
 29.1200 ++		ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
 29.1201 ++		if (wait_for_stat
 29.1202 ++		    (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 29.1203 ++		     tpm_calc_ordinal_duration(chip, ordinal),
 29.1204 ++		     &chip->vendor.read_queue) < 0) {
 29.1205 ++			rc = -ETIME;
 29.1206 ++			goto out_err;
 29.1207 ++		}
 29.1208 ++	}
 29.1209 ++	return len;
 29.1210 ++out_err:
 29.1211 ++	tpm_tis_ready(chip);
 29.1212 ++	release_locality(chip, chip->vendor.locality, 0);
 29.1213 ++	return rc;
 29.1214 ++}
 29.1215 ++
 29.1216 ++static struct file_operations tis_ops = {
 29.1217 ++	.owner = THIS_MODULE,
 29.1218 ++	.llseek = no_llseek,
 29.1219 ++	.open = tpm_open,
 29.1220 ++	.read = tpm_read,
 29.1221 ++	.write = tpm_write,
 29.1222 ++	.release = tpm_release,
 29.1223 ++};
 29.1224 ++
 29.1225 ++static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
 29.1226 ++static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
 29.1227 ++static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
 29.1228 ++static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
 29.1229 ++static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
 29.1230 ++static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
 29.1231 ++		   NULL);
 29.1232 ++static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
 29.1233 ++static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
 29.1234 ++
 29.1235 ++static struct attribute *tis_attrs[] = {
 29.1236 ++	&dev_attr_pubek.attr,
 29.1237 ++	&dev_attr_pcrs.attr,
 29.1238 ++	&dev_attr_enabled.attr,
 29.1239 ++	&dev_attr_active.attr,
 29.1240 ++	&dev_attr_owned.attr,
 29.1241 ++	&dev_attr_temp_deactivated.attr,
 29.1242 ++	&dev_attr_caps.attr,
 29.1243 ++	&dev_attr_cancel.attr, NULL,
 29.1244 ++};
 29.1245 ++
 29.1246 ++static struct attribute_group tis_attr_grp = {
 29.1247 ++	.attrs = tis_attrs
 29.1248 ++};
 29.1249 ++
 29.1250 ++static struct tpm_vendor_specific tpm_tis = {
 29.1251 ++	.status = tpm_tis_status,
 29.1252 ++	.recv = tpm_tis_recv,
 29.1253 ++	.send = tpm_tis_send,
 29.1254 ++	.cancel = tpm_tis_ready,
 29.1255 ++	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 29.1256 ++	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 29.1257 ++	.req_canceled = TPM_STS_COMMAND_READY,
 29.1258 ++	.attr_group = &tis_attr_grp,
 29.1259 ++	.miscdev = {
 29.1260 ++		    .fops = &tis_ops,},
 29.1261 ++};
 29.1262 ++
 29.1263 ++static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
 29.1264 ++{
 29.1265 ++	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
 29.1266 ++	u32 interrupt;
 29.1267 ++
 29.1268 ++	interrupt = ioread32(chip->vendor.iobase +
 29.1269 ++			     TPM_INT_STATUS(chip->vendor.locality));
 29.1270 ++
 29.1271 ++	if (interrupt == 0)
 29.1272 ++		return IRQ_NONE;
 29.1273 ++
 29.1274 ++	chip->vendor.irq = irq;
 29.1275 ++
 29.1276 ++	/* Clear interrupts handled with TPM_EOI */
 29.1277 ++	iowrite32(interrupt,
 29.1278 ++		  chip->vendor.iobase +
 29.1279 ++		  TPM_INT_STATUS(chip->vendor.locality));
 29.1280 ++	return IRQ_HANDLED;
 29.1281 ++}
 29.1282 ++
 29.1283 ++static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 29.1284 ++{
 29.1285 ++	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
 29.1286 ++	u32 interrupt;
 29.1287 ++	int i;
 29.1288 ++
 29.1289 ++	interrupt = ioread32(chip->vendor.iobase +
 29.1290 ++			     TPM_INT_STATUS(chip->vendor.locality));
 29.1291 ++
 29.1292 ++	if (interrupt == 0)
 29.1293 ++		return IRQ_NONE;
 29.1294 ++
 29.1295 ++	if (interrupt & TPM_INTF_DATA_AVAIL_INT)
 29.1296 ++		wake_up_interruptible(&chip->vendor.read_queue);
 29.1297 ++	if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
 29.1298 ++		for (i = 0; i < 5; i++)
 29.1299 ++			if (check_locality(chip, i) >= 0)
 29.1300 ++				break;
 29.1301 ++	if (interrupt &
 29.1302 ++	    (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
 29.1303 ++	     TPM_INTF_CMD_READY_INT))
 29.1304 ++		wake_up_interruptible(&chip->vendor.int_queue);
 29.1305 ++
 29.1306 ++	/* Clear interrupts handled with TPM_EOI */
 29.1307 ++	iowrite32(interrupt,
 29.1308 ++		  chip->vendor.iobase +
 29.1309 ++		  TPM_INT_STATUS(chip->vendor.locality));
 29.1310 ++	return IRQ_HANDLED;
 29.1311 ++}
 29.1312 ++
 29.1313 ++static int interrupts = 1;
 29.1314 ++module_param(interrupts, bool, 0444);
 29.1315 ++MODULE_PARM_DESC(interrupts, "Enable interrupts");
 29.1316 ++
 29.1317 ++static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
 29.1318 ++				      const struct pnp_device_id *pnp_id)
 29.1319 ++{
 29.1320 ++	u32 vendor, intfcaps, intmask;
 29.1321 ++	int rc, i;
 29.1322 ++	unsigned long start, len;
 29.1323 ++	struct tpm_chip *chip;
 29.1324 ++
 29.1325 ++	start = pnp_mem_start(pnp_dev, 0);
 29.1326 ++	len = pnp_mem_len(pnp_dev, 0);
 29.1327 ++
 29.1328 ++	if (!start)
 29.1329 ++		start = TIS_MEM_BASE;
 29.1330 ++	if (!len)
 29.1331 ++		len = TIS_MEM_LEN;
 29.1332 ++
 29.1333 ++	if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
 29.1334 ++		return -ENODEV;
 29.1335 ++
 29.1336 ++	chip->vendor.iobase = ioremap(start, len);
 29.1337 ++	if (!chip->vendor.iobase) {
 29.1338 ++		rc = -EIO;
 29.1339 ++		goto out_err;
 29.1340 ++	}
 29.1341 ++
 29.1342 ++	vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
 29.1343 ++
 29.1344 ++	/* Default timeouts */
 29.1345 ++	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 29.1346 ++	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
 29.1347 ++	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 29.1348 ++	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 29.1349 ++
 29.1350 ++	dev_info(&pnp_dev->dev,
 29.1351 ++		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 29.1352 ++		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 29.1353 ++
 29.1354 ++	/* Figure out the capabilities */
 29.1355 ++	intfcaps =
 29.1356 ++	    ioread32(chip->vendor.iobase +
 29.1357 ++		     TPM_INTF_CAPS(chip->vendor.locality));
 29.1358 ++	dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
 29.1359 ++		intfcaps);
 29.1360 ++	if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
 29.1361 ++		dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
 29.1362 ++	if (intfcaps & TPM_INTF_CMD_READY_INT)
 29.1363 ++		dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
 29.1364 ++	if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
 29.1365 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
 29.1366 ++	if (intfcaps & TPM_INTF_INT_EDGE_RISING)
 29.1367 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
 29.1368 ++	if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
 29.1369 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
 29.1370 ++	if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
 29.1371 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
 29.1372 ++	if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
 29.1373 ++		dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
 29.1374 ++	if (intfcaps & TPM_INTF_STS_VALID_INT)
 29.1375 ++		dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
 29.1376 ++	if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
 29.1377 ++		dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
 29.1378 ++
 29.1379 ++	if (request_locality(chip, 0) != 0) {
 29.1380 ++		rc = -ENODEV;
 29.1381 ++		goto out_err;
 29.1382 ++	}
 29.1383 ++
 29.1384 ++	/* INTERRUPT Setup */
 29.1385 ++	init_waitqueue_head(&chip->vendor.read_queue);
 29.1386 ++	init_waitqueue_head(&chip->vendor.int_queue);
 29.1387 ++
 29.1388 ++	intmask =
 29.1389 ++	    ioread32(chip->vendor.iobase +
 29.1390 ++		     TPM_INT_ENABLE(chip->vendor.locality));
 29.1391 ++
 29.1392 ++	intmask |= TPM_INTF_CMD_READY_INT
 29.1393 ++	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
 29.1394 ++	    | TPM_INTF_STS_VALID_INT;
 29.1395 ++
 29.1396 ++	iowrite32(intmask,
 29.1397 ++		  chip->vendor.iobase +
 29.1398 ++		  TPM_INT_ENABLE(chip->vendor.locality));
 29.1399 ++	if (interrupts) {
 29.1400 ++		chip->vendor.irq =
 29.1401 ++		    ioread8(chip->vendor.iobase +
 29.1402 ++			    TPM_INT_VECTOR(chip->vendor.locality));
 29.1403 ++
 29.1404 ++		for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
 29.1405 ++			iowrite8(i, chip->vendor.iobase +
 29.1406 ++				    TPM_INT_VECTOR(chip->vendor.locality));
 29.1407 ++			if (request_irq
 29.1408 ++			    (i, tis_int_probe, SA_SHIRQ,
 29.1409 ++			     chip->vendor.miscdev.name, chip) != 0) {
 29.1410 ++				dev_info(chip->dev,
 29.1411 ++					 "Unable to request irq: %d for probe\n",
 29.1412 ++					 i);
 29.1413 ++				continue;
 29.1414 ++			}
 29.1415 ++
 29.1416 ++			/* Clear all existing */
 29.1417 ++			iowrite32(ioread32
 29.1418 ++				  (chip->vendor.iobase +
 29.1419 ++				   TPM_INT_STATUS(chip->vendor.locality)),
 29.1420 ++				  chip->vendor.iobase +
 29.1421 ++				  TPM_INT_STATUS(chip->vendor.locality));
 29.1422 ++
 29.1423 ++			/* Turn on */
 29.1424 ++			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
 29.1425 ++				  chip->vendor.iobase +
 29.1426 ++				  TPM_INT_ENABLE(chip->vendor.locality));
 29.1427 ++
 29.1428 ++			/* Generate Interrupts */
 29.1429 ++			tpm_gen_interrupt(chip);
 29.1430 ++
 29.1431 ++			/* Turn off */
 29.1432 ++			iowrite32(intmask,
 29.1433 ++				  chip->vendor.iobase +
 29.1434 ++				  TPM_INT_ENABLE(chip->vendor.locality));
 29.1435 ++			free_irq(i, chip);
 29.1436 ++		}
 29.1437 ++	}
 29.1438 ++	if (chip->vendor.irq) {
 29.1439 ++		iowrite8(chip->vendor.irq,
 29.1440 ++			 chip->vendor.iobase +
 29.1441 ++			 TPM_INT_VECTOR(chip->vendor.locality));
 29.1442 ++		if (request_irq
 29.1443 ++		    (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
 29.1444 ++		     chip->vendor.miscdev.name, chip) != 0) {
 29.1445 ++			dev_info(chip->dev,
 29.1446 ++				 "Unable to request irq: %d for use\n",
 29.1447 ++				 chip->vendor.irq);
 29.1448 ++			chip->vendor.irq = 0;
 29.1449 ++		} else {
 29.1450 ++			/* Clear all existing */
 29.1451 ++			iowrite32(ioread32
 29.1452 ++				  (chip->vendor.iobase +
 29.1453 ++				   TPM_INT_STATUS(chip->vendor.locality)),
 29.1454 ++				  chip->vendor.iobase +
 29.1455 ++				  TPM_INT_STATUS(chip->vendor.locality));
 29.1456 ++
 29.1457 ++			/* Turn on */
 29.1458 ++			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
 29.1459 ++				  chip->vendor.iobase +
 29.1460 ++				  TPM_INT_ENABLE(chip->vendor.locality));
 29.1461 ++		}
 29.1462 ++	}
 29.1463 ++
 29.1464 ++	INIT_LIST_HEAD(&chip->vendor.list);
 29.1465 ++	spin_lock(&tis_lock);
 29.1466 ++	list_add(&chip->vendor.list, &tis_chips);
 29.1467 ++	spin_unlock(&tis_lock);
 29.1468 ++
 29.1469 ++	tpm_get_timeouts(chip);
 29.1470 ++	tpm_continue_selftest(chip);
 29.1471 ++
 29.1472 ++	return 0;
 29.1473 ++out_err:
 29.1474 ++	if (chip->vendor.iobase)
 29.1475 ++		iounmap(chip->vendor.iobase);
 29.1476 ++	tpm_remove_hardware(chip->dev);
 29.1477 ++	return rc;
 29.1478 ++}
 29.1479 ++
 29.1480 ++static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
 29.1481 ++{
 29.1482 ++	return tpm_pm_suspend(&dev->dev, msg);
 29.1483 ++}
 29.1484 ++
 29.1485 ++static int tpm_tis_pnp_resume(struct pnp_dev *dev)
 29.1486 ++{
 29.1487 ++	return tpm_pm_resume(&dev->dev);
 29.1488 ++}
 29.1489 ++
 29.1490 ++static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
 29.1491 ++	{"PNP0C31", 0},		/* TPM */
 29.1492 ++	{"ATM1200", 0},		/* Atmel */
 29.1493 ++	{"IFX0102", 0},		/* Infineon */
 29.1494 ++	{"BCM0101", 0},		/* Broadcom */
 29.1495 ++	{"NSC1200", 0},		/* National */
 29.1496 ++	/* Add new here */
 29.1497 ++	{"", 0},		/* User Specified */
 29.1498 ++	{"", 0}			/* Terminator */
 29.1499 ++};
 29.1500 ++
 29.1501 ++static struct pnp_driver tis_pnp_driver = {
 29.1502 ++	.name = "tpm_tis",
 29.1503 ++	.id_table = tpm_pnp_tbl,
 29.1504 ++	.probe = tpm_tis_pnp_init,
 29.1505 ++	.suspend = tpm_tis_pnp_suspend,
 29.1506 ++	.resume = tpm_tis_pnp_resume,
 29.1507 ++};
 29.1508 ++
 29.1509 ++#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
 29.1510 ++module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
 29.1511 ++		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 29.1512 ++MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 29.1513 ++
 29.1514 ++static int __init init_tis(void)
 29.1515 ++{
 29.1516 ++	return pnp_register_driver(&tis_pnp_driver);
 29.1517 ++}
 29.1518 ++
 29.1519 ++static void __exit cleanup_tis(void)
 29.1520 ++{
 29.1521 ++	struct tpm_vendor_specific *i, *j;
 29.1522 ++	struct tpm_chip *chip;
 29.1523 ++	spin_lock(&tis_lock);
 29.1524 ++	list_for_each_entry_safe(i, j, &tis_chips, list) {
 29.1525 ++		chip = to_tpm_chip(i);
 29.1526 ++		iowrite32(~TPM_GLOBAL_INT_ENABLE &
 29.1527 ++			  ioread32(chip->vendor.iobase +
 29.1528 ++				   TPM_INT_ENABLE(chip->vendor.
 29.1529 ++						  locality)),
 29.1530 ++			  chip->vendor.iobase +
 29.1531 ++			  TPM_INT_ENABLE(chip->vendor.locality));
 29.1532 ++		release_locality(chip, chip->vendor.locality, 1);
 29.1533 ++		if (chip->vendor.irq)
 29.1534 ++			free_irq(chip->vendor.irq, chip);
 29.1535 ++		iounmap(i->iobase);
 29.1536 ++		list_del(&i->list);
 29.1537 ++		tpm_remove_hardware(chip->dev);
 29.1538 ++	}
 29.1539 ++	spin_unlock(&tis_lock);
 29.1540 ++	pnp_unregister_driver(&tis_pnp_driver);
 29.1541 ++}
 29.1542 ++
 29.1543 ++module_init(init_tis);
 29.1544 ++module_exit(cleanup_tis);
 29.1545 ++MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 29.1546 ++MODULE_DESCRIPTION("TPM Driver");
 29.1547 ++MODULE_VERSION("2.0");
 29.1548 ++MODULE_LICENSE("GPL");
 29.1549 +
    30.1 --- a/patches/linux-2.6.16.13/xenoprof-generic.patch	Wed Jun 28 07:52:21 2006 -0600
    30.2 +++ b/patches/linux-2.6.16.13/xenoprof-generic.patch	Mon Jul 03 08:35:12 2006 +0100
    30.3 @@ -123,6 +123,21 @@ diff -pru ../pristine-linux-2.6.16.13/dr
    30.4   				}
    30.5   			}
    30.6   		}
    30.7 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h ./drivers/oprofile/buffer_sync.h
    30.8 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h	2006-05-03 05:38:44.000000000 +0800
    30.9 ++++ ./drivers/oprofile/buffer_sync.h	2006-06-27 12:12:09.000000000 +0800
   30.10 +@@ -9,6 +9,11 @@
   30.11 + 
   30.12 + #ifndef OPROFILE_BUFFER_SYNC_H
   30.13 + #define OPROFILE_BUFFER_SYNC_H
   30.14 ++
   30.15 ++#define NO_DOMAIN_SWITCH		-1
   30.16 ++#define DOMAIN_SWITCH_START_EVENT1	0
   30.17 ++#define DOMAIN_SWITCH_START_EVENT2	1
   30.18 ++#define DOMAIN_SWITCH_STOP_EVENT1	2
   30.19 +  
   30.20 + /* add the necessary profiling hooks */
   30.21 + int sync_start(void);
   30.22  diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
   30.23  --- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c	2006-05-03 05:38:44.000000000 +0800
   30.24  +++ ./drivers/oprofile/cpu_buffer.c	2006-06-19 22:43:53.000000000 +0800
    31.1 --- a/tools/examples/Makefile	Wed Jun 28 07:52:21 2006 -0600
    31.2 +++ b/tools/examples/Makefile	Mon Jul 03 08:35:12 2006 +0100
    31.3 @@ -26,7 +26,7 @@ XEN_SCRIPTS += network-route vif-route
    31.4  XEN_SCRIPTS += network-nat vif-nat
    31.5  XEN_SCRIPTS += block
    31.6  XEN_SCRIPTS += block-enbd block-nbd
    31.7 -XEN_SCRIPTS += vtpm vtpm-delete
    31.8 +XEN_SCRIPTS += vtpm vtpm-delete vtpm-addtodb
    31.9  XEN_SCRIPTS += xen-hotplug-cleanup
   31.10  XEN_SCRIPTS += external-device-migrate
   31.11  XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/examples/vtpm-addtodb	Mon Jul 03 08:35:12 2006 +0100
    32.3 @@ -0,0 +1,10 @@
    32.4 +#!/bin/sh
    32.5 +
    32.6 +# This script must be called with the following parameters to have
    32.7 +# an entry added to the TPM-to-domain associations table in /etc/xen/vtpm.db
    32.8 +# vtpm-addtodb <dom name> <instance number>
    32.9 +
   32.10 +dir=$(dirname "$0")
   32.11 +. "$dir/vtpm-common.sh"
   32.12 +
   32.13 +vtpmdb_add_instance $1 $2
    33.1 --- a/tools/examples/vtpm-common.sh	Wed Jun 28 07:52:21 2006 -0600
    33.2 +++ b/tools/examples/vtpm-common.sh	Mon Jul 03 08:35:12 2006 +0100
    33.3 @@ -347,16 +347,9 @@ function isLocalAddress() {
    33.4  # 2nd: name of the domain to migrate
    33.5  # 3rd: the migration step to perform
    33.6  function vtpm_migration_step() {
    33.7 -	local instance res
    33.8 -	instance=$(vtpmdb_find_instance $2)
    33.9 -	if [ "$instance" == "" ]; then
   33.10 -		echo "Error: Translation of domain name ($2) to instance failed. Check /etc/xen/vtpm.db"
   33.11 -		log err "Error during translation of domain name"
   33.12 -	else
   33.13 -		res=$(isLocalAddress $1)
   33.14 -		if [ "$res" == "0" ]; then
   33.15 -			vtpm_migrate $1 $2 $3
   33.16 -		fi
   33.17 +	local res=$(isLocalAddress $1)
   33.18 +	if [ "$res" == "0" ]; then
   33.19 +		vtpm_migrate $1 $2 $3
   33.20  	fi
   33.21  }
   33.22  
    34.1 --- a/tools/firmware/hvmloader/Makefile	Wed Jun 28 07:52:21 2006 -0600
    34.2 +++ b/tools/firmware/hvmloader/Makefile	Mon Jul 03 08:35:12 2006 +0100
    34.3 @@ -45,9 +45,9 @@ LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Tt
    34.4  .PHONY: all
    34.5  all: hvmloader
    34.6  
    34.7 -hvmloader: roms.h hvmloader.c acpi_madt.c
    34.8 -	$(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c
    34.9 -	$(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o
   34.10 +hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c
   34.11 +	$(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c
   34.12 +	$(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o
   34.13  	$(OBJCOPY) hvmloader.tmp hvmloader
   34.14  	rm -f hvmloader.tmp
   34.15  
    35.1 --- a/tools/firmware/hvmloader/acpi_madt.c	Wed Jun 28 07:52:21 2006 -0600
    35.2 +++ b/tools/firmware/hvmloader/acpi_madt.c	Mon Jul 03 08:35:12 2006 +0100
    35.3 @@ -51,7 +51,7 @@ static int validate_hvm_info(struct hvm_
    35.4  }
    35.5  
    35.6  /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
    35.7 -static struct hvm_info_table *
    35.8 +struct hvm_info_table *
    35.9  get_hvm_info_table(void)
   35.10  {
   35.11  	struct hvm_info_table *t;
    36.1 --- a/tools/firmware/hvmloader/hvmloader.c	Wed Jun 28 07:52:21 2006 -0600
    36.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Mon Jul 03 08:35:12 2006 +0100
    36.3 @@ -23,6 +23,7 @@
    36.4   */
    36.5  #include "roms.h"
    36.6  #include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
    36.7 +#include <xen/hvm/hvm_info_table.h>
    36.8  
    36.9  /* memory map */
   36.10  #define VGABIOS_PHYSICAL_ADDRESS	0x000C0000
   36.11 @@ -71,6 +72,8 @@ asm(
   36.12  
   36.13  extern int get_acpi_enabled(void);
   36.14  extern int acpi_madt_update(unsigned char* acpi_start);
   36.15 +extern void create_mp_tables(void);
   36.16 +struct hvm_info_table *get_hvm_info_table(void);
   36.17  
   36.18  static inline void
   36.19  outw(unsigned short addr, unsigned short val)
   36.20 @@ -162,10 +165,15 @@ check_amd(void)
   36.21  int
   36.22  main(void)
   36.23  {
   36.24 +	struct hvm_info_table *t = get_hvm_info_table();
   36.25 +
   36.26  	puts("HVM Loader\n");
   36.27  
   36.28  	puts("Loading ROMBIOS ...\n");
   36.29  	memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
   36.30 +	if (t->apic_enabled)
   36.31 +		create_mp_tables();
   36.32 +	
   36.33  	if (cirrus_check()) {
   36.34  		puts("Loading Cirrus VGABIOS ...\n");
   36.35  		memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/firmware/hvmloader/mp_tables.c	Mon Jul 03 08:35:12 2006 +0100
    37.3 @@ -0,0 +1,426 @@
    37.4 +/*
    37.5 + * mp_tables.c: Dynamically writes MP table info into the ROMBIOS.
    37.6 + *
    37.7 + * In order to work with various VCPU counts, this code reads the VCPU count
    37.8 + * for the HVM partition and creates the correct MP tables for the VCPU count
    37.9 + * and places the information into a predetermined location set aside in the
   37.10 + * ROMBIOS during build time.
   37.11 + *
   37.12 + * Please note that many of the values, such as the CPU's
   37.13 + * family/model/stepping, are hard-coded based upon the values that were used
   37.14 + * in the ROMBIOS and may need to be modified or calculated dynamically to
   37.15 + * correspond with what an HVM guest's CPUID returns.
   37.16 + *
   37.17 + * Travis Betak, travis.betak@amd.com
   37.18 + * Copyright (c) 2006, AMD.
   37.19 + *
   37.20 + * This program is free software; you can redistribute it and/or modify it
   37.21 + * under the terms and conditions of the GNU General Public License,
   37.22 + * version 2, as published by the Free Software Foundation.
   37.23 + *
   37.24 + * This program is distributed in the hope it will be useful, but WITHOUT
   37.25 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.26 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   37.27 + * more details.
   37.28 + *
   37.29 + * You should have received a copy of the GNU General Public License along with
   37.30 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   37.31 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   37.32 + */
   37.33 +
   37.34 +
   37.35 +/* FIXME find a header that already has types defined!!! */
   37.36 +typedef unsigned char  uint8_t;
   37.37 +typedef   signed char  int8_t;
   37.38 +typedef unsigned short uint16_t;
   37.39 +typedef   signed short int16_t;
   37.40 +typedef unsigned int   uint32_t;
   37.41 +typedef   signed int   int32_t;
   37.42 +#ifdef __i386__
   37.43 +typedef unsigned long long uint64_t;
   37.44 +typedef   signed long long int64_t;
   37.45 +#else
   37.46 +typedef unsigned long uint64_t;
   37.47 +typedef   signed long int64_t;
   37.48 +#endif
   37.49 +
   37.50 +#define ROMBIOS_SEG              0xF000
   37.51 +#define ROMBIOS_BEGIN            0x000F0000
   37.52 +#define ROMBIOS_SIZE             0x00010000 
   37.53 +#define ROMBIOS_MAXOFFSET        0x0000FFFF
   37.54 +#define ROMBIOS_END             (ROMBIOS_BEGIN + ROMBIOS_SIZE)
   37.55 +
   37.56 +/* number of non-processor MP table entries */
   37.57 +#define NR_NONPROC_ENTRIES     18
   37.58 +
   37.59 +#define ENTRY_TYPE_PROCESSOR   0
   37.60 +#define ENTRY_TYPE_BUS         1
   37.61 +#define ENTRY_TYPE_IOAPIC      2
   37.62 +#define ENTRY_TYPE_IO_INTR     3
   37.63 +#define ENTRY_TYPE_LOCAL_INTR  4
   37.64 +
   37.65 +#define CPU_FLAG_ENABLED       0x01
   37.66 +#define CPU_FLAG_BSP           0x02
   37.67 +
   37.68 +/* TODO change this to correspond with what the guest's see's from CPUID */
   37.69 +#define CPU_SIG_FAMILY         0x06
   37.70 +#define CPU_SIG_MODEL          0x00
   37.71 +#define CPU_SIG_STEPPING       0x00
   37.72 +#define CPU_SIGNATURE        ((CPU_SIG_FAMILY << 8)  \
   37.73 +                             | (CPU_SIG_MODEL << 4)  \
   37.74 +                             | (CPU_SIG_STEPPING))
   37.75 +#define CPU_FEATURE_FPU       (1U << 0)
   37.76 +#define CPU_FEATURE_MCE       (1U << 7)
   37.77 +#define CPU_FEATURE_CX8       (1U << 8)
   37.78 +#define CPU_FEATURE_APIC      (1U << 9)
   37.79 +#define CPU_FEATURES          (CPU_FEATURE_FPU | CPU_FEATURE_APIC)
   37.80 +
   37.81 +#define BUS_TYPE_LENGTH        6
   37.82 +#define BUS_TYPE_STR_ISA       "ISA   "
   37.83 +
   37.84 +#define LAPIC_BASE_ADDR        0xFEE00000
   37.85 +
   37.86 +#define IOAPIC_VERSION         0x11
   37.87 +#define IOAPIC_BASE_ADDR       0xFEC00000
   37.88 +#define IOAPIC_FLAG_ENABLED   (1U << 0)
   37.89 +
   37.90 +#define INTR_TYPE_INT          0
   37.91 +#define INTR_TYPE_NMI          1
   37.92 +#define INTR_TYPE_SMI          2
   37.93 +#define INTR_TYPE_EXTINT       3
   37.94 +
   37.95 +#define INTR_FLAGS             0
   37.96 +
   37.97 +#define INTR_MAX_NR            16
   37.98 +
   37.99 +extern int puts(const char *); /* for printing */
  37.100 +extern int get_vcpu_nr(void);  /* for the guest's VCPU count */
  37.101 +
  37.102 +/*
  37.103 + * The following structures are defined in the MuliProcessor Specifiation v1.4
  37.104 + */
  37.105 +
  37.106 +/* MP Floating Pointer Structure */
  37.107 +struct mp_floating_pointer_struct {
  37.108 +	uint8_t signature[4];
  37.109 +	uint32_t mp_table;
  37.110 +	uint8_t length;
  37.111 +	uint8_t revision;
  37.112 +	uint8_t checksum;
  37.113 +	uint8_t feature[5];
  37.114 +};
  37.115 +
  37.116 +/* MP Configuration Table */
  37.117 +struct mp_config_table {
  37.118 +	uint8_t signature[4];
  37.119 +	uint16_t length;
  37.120 +	uint8_t revision;
  37.121 +	uint8_t checksum;
  37.122 +	uint8_t oem_id[8];
  37.123 +	uint8_t vendor_id[12];
  37.124 +	uint32_t oem_table;
  37.125 +	uint16_t oem_table_sz;
  37.126 +	uint16_t nr_entries;
  37.127 +	uint32_t lapic;
  37.128 +	uint16_t extended_length;
  37.129 +	uint8_t extended_checksum;
  37.130 +	uint8_t reserved;
  37.131 +};
  37.132 +
  37.133 +/* MP Processor Entry */
  37.134 +struct mp_proc_entry {
  37.135 +	uint8_t type;
  37.136 +	uint8_t lapic_id;
  37.137 +	uint8_t lapic_version;
  37.138 +	uint8_t cpu_flags;
  37.139 +	uint32_t cpu_signature;
  37.140 +	uint32_t feature_flags;
  37.141 +	uint8_t reserved[8];
  37.142 +};
  37.143 +
  37.144 +/* MP Bus Entry */
  37.145 +struct mp_bus_entry {
  37.146 +	uint8_t type;
  37.147 +	uint8_t bus_id;
  37.148 +	uint8_t bus_type_str[6];
  37.149 +};
  37.150 +
  37.151 +/* MP IOAPIC Entry */
  37.152 +struct mp_ioapic_entry {
  37.153 +	uint8_t type;
  37.154 +	uint8_t ioapic_id;
  37.155 +	uint8_t ioapic_version;
  37.156 +	uint8_t ioapic_flags;
  37.157 +	uint32_t ioapic_addr;
  37.158 +};
  37.159 +
  37.160 +/* MP IO Interrupt Entry */
  37.161 +struct mp_io_intr_entry {
  37.162 +	uint8_t type;
  37.163 +	uint8_t intr_type;
  37.164 +	uint16_t io_intr_flags;
  37.165 +	uint8_t src_bus_id;
  37.166 +	uint8_t src_bus_irq;
  37.167 +	uint8_t dst_ioapic_id;
  37.168 +	uint8_t dst_ioapic_intin;
  37.169 +};
  37.170 +
  37.171 +/* MP Local Interrupt Entry */
  37.172 +struct mp_local_intr_entry {
  37.173 +	uint8_t type;
  37.174 +	uint8_t intr_type;
  37.175 +	uint16_t local_intr_flags;
  37.176 +	uint8_t src_bus_id;
  37.177 +	uint8_t src_bus_irq;
  37.178 +	uint8_t dst_lapic_id;
  37.179 +	uint8_t dst_lapic_lintin;
  37.180 +};
  37.181 +
  37.182 +
  37.183 +/* 
  37.184 + * fill_mp_config_table - fills in the information for the MP config table
  37.185 + *    
  37.186 + * When calculating the length and nr_entries fields, keep in mind that there
  37.187 + * are always 18 non-processor entries and N processor entries
  37.188 + * 
  37.189 + *    N vcpu entries
  37.190 + *    1 bus entry 
  37.191 + *    1 IOAPIC entry 
  37.192 + * + 16 IO intr. entries
  37.193 + * ----------------------
  37.194 + * 18 + N total entries
  37.195 + */
  37.196 +void fill_mp_config_table(struct mp_config_table *mpct)
  37.197 +{
  37.198 +	int vcpu_nr;
  37.199 +
  37.200 +	vcpu_nr = get_vcpu_nr();
  37.201 +
  37.202 +	/* fill in the MP configuration table signature, "PCMP" */
  37.203 +	mpct->signature[0] = 'P';
  37.204 +	mpct->signature[1] = 'C';
  37.205 +	mpct->signature[2] = 'M';
  37.206 +	mpct->signature[3] = 'P';
  37.207 +
  37.208 +	mpct->length =    sizeof(struct mp_config_table)
  37.209 +			+ vcpu_nr * sizeof(struct mp_proc_entry)
  37.210 +			+ sizeof(struct mp_ioapic_entry)
  37.211 +			+ sizeof(struct mp_bus_entry)
  37.212 +			+ 16 * sizeof(struct mp_local_intr_entry);
  37.213 +
  37.214 +	mpct->revision = 4;
  37.215 +
  37.216 +	/* 
  37.217 +	 * We'll fill in the checksum later after all of the 
  37.218 +	 * entries have been created
  37.219 +	 */
  37.220 +	mpct->checksum = 0;
  37.221 +
  37.222 +	/* fill in the OEM ID string, "_HVMCPU_" */
  37.223 +	mpct->oem_id[0] = '_'; mpct->oem_id[3] = 'M'; mpct->oem_id[6] = 'U';
  37.224 +	mpct->oem_id[1] = 'H'; mpct->oem_id[4] = 'C'; mpct->oem_id[7] = '_';
  37.225 +	mpct->oem_id[2] = 'V'; mpct->oem_id[5] = 'P';
  37.226 +
  37.227 +	/* fill in the Vendor ID string, "XEN         " */
  37.228 +	mpct->vendor_id[0] = 'X'; mpct->vendor_id[6] =  ' ';
  37.229 +	mpct->vendor_id[1] = 'E'; mpct->vendor_id[7] =  ' ';
  37.230 +	mpct->vendor_id[2] = 'N'; mpct->vendor_id[8] =  ' ';
  37.231 +	mpct->vendor_id[3] = ' '; mpct->vendor_id[9] =  ' ';
  37.232 +	mpct->vendor_id[4] = ' '; mpct->vendor_id[10] = ' ';
  37.233 +	mpct->vendor_id[5] = ' '; mpct->vendor_id[11] = ' ';
  37.234 +
  37.235 +	mpct->oem_table = 0;
  37.236 +	mpct->oem_table_sz = 0;
  37.237 +
  37.238 +	mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
  37.239 +
  37.240 +	mpct->lapic = LAPIC_BASE_ADDR;
  37.241 +	mpct->extended_length = 0;
  37.242 +	mpct->extended_checksum = 0;
  37.243 +}
  37.244 +
  37.245 +
  37.246 +/* calculates the checksum for the MP configuration table */
  37.247 +void fill_mp_config_table_checksum(struct mp_config_table *mpct)
  37.248 +{
  37.249 +	int i;
  37.250 +	uint8_t checksum;
  37.251 +
  37.252 +	checksum = 0;
  37.253 +	for (i = 0; i < mpct->length; ++i)
  37.254 +		checksum += ((uint8_t *)(mpct))[i];
  37.255 +	mpct->checksum = -checksum;
  37.256 +}
  37.257 +
  37.258 +
  37.259 +/* fills in an MP processor entry for VCPU 'vcpu_id' */
  37.260 +void fill_mp_proc_entry(struct mp_proc_entry *mppe, int vcpu_id)
  37.261 +{
  37.262 +	mppe->type = ENTRY_TYPE_PROCESSOR;
  37.263 +	mppe->lapic_id = vcpu_id;
  37.264 +	mppe->lapic_version = 0x11;
  37.265 +	mppe->cpu_flags = CPU_FLAG_ENABLED;
  37.266 +	if (vcpu_id == 0)
  37.267 +		mppe->cpu_flags |= CPU_FLAG_BSP;
  37.268 +	mppe->cpu_signature = CPU_SIGNATURE;
  37.269 +	mppe->feature_flags = CPU_FEATURES;
  37.270 +}
  37.271 +
  37.272 +
  37.273 +/* fills in an MP bus entry of type 'type' and bus ID 'bus_id' */
  37.274 +void fill_mp_bus_entry(struct mp_bus_entry *mpbe, int bus_id, const char *type)
  37.275 +{
  37.276 +	int i;
  37.277 +
  37.278 +	mpbe->type = ENTRY_TYPE_BUS;
  37.279 +	mpbe->bus_id = bus_id;
  37.280 +	for (i = 0; i < BUS_TYPE_LENGTH; ++i)
  37.281 +		mpbe->bus_type_str[i] = type[i]; /* FIXME length check? */
  37.282 +}
  37.283 +
  37.284 +
  37.285 +/* fills in an MP IOAPIC entry for IOAPIC 'ioapic_id' */
  37.286 +void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie, int ioapic_id)
  37.287 +{
  37.288 +	mpie->type = ENTRY_TYPE_IOAPIC;
  37.289 +	mpie->ioapic_id = ioapic_id;
  37.290 +	mpie->ioapic_version = IOAPIC_VERSION;
  37.291 +	mpie->ioapic_flags = IOAPIC_FLAG_ENABLED;
  37.292 +	mpie->ioapic_addr = IOAPIC_BASE_ADDR;
  37.293 +}
  37.294 +
  37.295 +
  37.296 +/* fills in an IO interrupt entry for IOAPIC 'ioapic_id' */
  37.297 +void fill_mp_io_intr_entry(struct mp_io_intr_entry *mpiie,
  37.298 +		int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
  37.299 +{
  37.300 +	mpiie->type = ENTRY_TYPE_IO_INTR;
  37.301 +	mpiie->intr_type = INTR_TYPE_INT;
  37.302 +	mpiie->io_intr_flags = INTR_FLAGS;
  37.303 +	mpiie->src_bus_id = 0;
  37.304 +	mpiie->src_bus_irq = src_bus_irq;
  37.305 +	mpiie->dst_ioapic_id = ioapic_id;
  37.306 +	mpiie->dst_ioapic_intin = dst_ioapic_intin;
  37.307 +}
  37.308 +
  37.309 +
  37.310 +/* fill in the mp floating processor structure */
  37.311 +void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t mpct)
  37.312 +{
  37.313 +	int i;
  37.314 +	uint8_t checksum;
  37.315 +
  37.316 +
  37.317 +	mpfps->signature[0] = '_';
  37.318 +	mpfps->signature[1] = 'M';
  37.319 +	mpfps->signature[2] = 'P';
  37.320 +	mpfps->signature[3] = '_';
  37.321 +
  37.322 +	mpfps->mp_table = mpct; 
  37.323 +	mpfps->length = 1;
  37.324 +	mpfps->revision = 4;
  37.325 +	mpfps->checksum = 0;
  37.326 +	for (i = 0; i < 5; ++i)
  37.327 +		mpfps->feature[i] = 0;
  37.328 +
  37.329 +	/* compute the checksum for our new table */
  37.330 +	checksum = 0;
  37.331 +	for (i = 0; i < sizeof(struct mp_floating_pointer_struct); ++i)
  37.332 +		checksum += ((uint8_t *)(mpfps))[i];
  37.333 +	mpfps->checksum = -checksum;
  37.334 +}
  37.335 +
  37.336 +
  37.337 +/*
  37.338 + * find_mp_table_start - searchs through BIOS memory for '___HVMMP' signature
  37.339 + *
  37.340 + * The '___HVMMP' signature is created by the ROMBIOS and designates a chunk
  37.341 + * of space inside the ROMBIOS that is safe for us to write our MP table info
  37.342 + */
  37.343 +void* get_mp_table_start(void)
  37.344 +{
  37.345 +	char *bios_mem;
  37.346 +	for (bios_mem = (char *)ROMBIOS_BEGIN; 
  37.347 +	     bios_mem != (char *)ROMBIOS_END; 
  37.348 +	     ++bios_mem)
  37.349 +		if (bios_mem[0] == '_' && bios_mem[1] == '_' &&
  37.350 +		    bios_mem[2] == '_' && bios_mem[3] == 'H' &&
  37.351 +		    bios_mem[4] == 'V' && bios_mem[5] == 'M' &&
  37.352 +		    bios_mem[6] == 'M' && bios_mem[7] == 'P')
  37.353 +			return bios_mem;
  37.354 +
  37.355 +	return (void *)-1;
  37.356 +}
  37.357 +
  37.358 +
  37.359 +/* recalculate the new ROMBIOS checksum after adding MP tables */
  37.360 +void reset_bios_checksum(void)
  37.361 +{
  37.362 +	uint32_t i;
  37.363 +	uint8_t checksum;
  37.364 +
  37.365 +	checksum = 0;
  37.366 +	for (i = 0; i < ROMBIOS_MAXOFFSET; ++i)
  37.367 +		checksum += ((uint8_t *)(ROMBIOS_BEGIN))[i];
  37.368 +	
  37.369 +	*((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
  37.370 +}
  37.371 +
  37.372 +
  37.373 +/* create_mp_tables - creates MP tables for the guest based upon config data */
  37.374 +void create_mp_tables(void)
  37.375 +{
  37.376 +	void *mp_table_base;
  37.377 +	char *p;
  37.378 +	struct mp_config_table *mp_config_table;
  37.379 +	int vcpu_nr;
  37.380 +	int i;
  37.381 +
  37.382 +	vcpu_nr = get_vcpu_nr();
  37.383 +	
  37.384 +	puts("Creating MP tables ...\n");
  37.385 +
  37.386 +	/* find the 'safe' place in ROMBIOS for the MP tables */
  37.387 +	mp_table_base = get_mp_table_start();
  37.388 +	if (mp_table_base == (void *)-1) {
  37.389 +		puts("Couldn't find start point for MP tables\n");
  37.390 +		return;
  37.391 +	}
  37.392 +	p = mp_table_base;
  37.393 +
  37.394 +	fill_mp_config_table((struct mp_config_table *)p);
  37.395 +
  37.396 + 	/* save the location of the MP config table for a little later*/
  37.397 +	mp_config_table = (struct mp_config_table *)p;
  37.398 +	p += sizeof(struct mp_config_table);
  37.399 +
  37.400 +	for (i = 0; i < vcpu_nr; ++i) {
  37.401 +		fill_mp_proc_entry((struct mp_proc_entry *)p, i);
  37.402 +		p += sizeof(struct mp_proc_entry);
  37.403 +	}
  37.404 +
  37.405 +	fill_mp_bus_entry((struct mp_bus_entry *)p, 0, BUS_TYPE_STR_ISA);
  37.406 +	p += sizeof(struct mp_bus_entry);
  37.407 +
  37.408 +	fill_mp_ioapic_entry((struct mp_ioapic_entry *)p, vcpu_nr);
  37.409 +	p += sizeof(struct mp_ioapic_entry);
  37.410 +
  37.411 +	for (i = 0; i < INTR_MAX_NR; ++i) {
  37.412 +		fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 
  37.413 +				i, vcpu_nr, i);
  37.414 +		p += sizeof(struct mp_io_intr_entry);
  37.415 +	}
  37.416 +
  37.417 +	/* find the next 16-byte boundary to place the mp floating pointer */
  37.418 +	while ((unsigned long)p & 0xF)
  37.419 +		++p;
  37.420 +	
  37.421 +	fill_mpfps((struct mp_floating_pointer_struct *)p, 
  37.422 +			(uint32_t)mp_table_base);
  37.423 +
  37.424 +	/* calculate the MP configuration table's checksum */
  37.425 +	fill_mp_config_table_checksum(mp_config_table);
  37.426 +
  37.427 +	/* finally, recalculate the ROMBIOS checksum */
  37.428 +	reset_bios_checksum();
  37.429 +}
    38.1 --- a/tools/firmware/rombios/Makefile	Wed Jun 28 07:52:21 2006 -0600
    38.2 +++ b/tools/firmware/rombios/Makefile	Mon Jul 03 08:35:12 2006 +0100
    38.3 @@ -1,13 +1,9 @@
    38.4 -BIOS_BUILDS = BIOS-bochs-latest
    38.5 -#BIOS_BUILDS += BIOS-bochs-2-processors
    38.6 -#BIOS_BUILDS += BIOS-bochs-4-processors
    38.7 -#BIOS_BUILDS += BIOS-bochs-8-processors
    38.8  
    38.9  .PHONY: all
   38.10  all: bios
   38.11  
   38.12  .PHONY: bios
   38.13 -bios: biossums ${BIOS_BUILDS}
   38.14 +bios: biossums BIOS-bochs-latest
   38.15  
   38.16  .PHONY: clean
   38.17  clean:
   38.18 @@ -26,36 +22,6 @@ BIOS-bochs-latest: rombios.c biossums
   38.19  	./biossums BIOS-bochs-latest
   38.20  	rm -f _rombios_.s
   38.21  
   38.22 -BIOS-bochs-2-processors: rombios.c biossums
   38.23 -	gcc -DBX_SMP_PROCESSORS=2 -E -P $< > _rombios2_.c
   38.24 -	bcc -o rombios2.s -C-c -D__i86__ -0 -S _rombios2_.c
   38.25 -	sed -e 's/^\.text//' -e 's/^\.data//' rombios2.s > _rombios2_.s
   38.26 -	as86 _rombios2_.s -b tmp2.bin -u- -w- -g -0 -j -O -l rombios2.txt
   38.27 -	-perl makesym.perl < rombios2.txt > rombios2.sym
   38.28 -	mv tmp2.bin BIOS-bochs-2-processors
   38.29 -	./biossums BIOS-bochs-2-processors
   38.30 -	rm -f _rombios2_.s
   38.31 -
   38.32 -BIOS-bochs-4-processors: rombios.c biossums
   38.33 -	gcc -DBX_SMP_PROCESSORS=4 -E -P $< > _rombios4_.c
   38.34 -	bcc -o rombios4.s -C-c -D__i86__ -0 -S _rombios4_.c
   38.35 -	sed -e 's/^\.text//' -e 's/^\.data//' rombios4.s > _rombios4_.s
   38.36 -	as86 _rombios4_.s -b tmp4.bin -u- -w- -g -0 -j -O -l rombios4.txt
   38.37 -	-perl makesym.perl < rombios4.txt > rombios4.sym
   38.38 -	mv tmp4.bin BIOS-bochs-4-processors
   38.39 -	./biossums BIOS-bochs-4-processors
   38.40 -	rm -f _rombios4_.s
   38.41 -
   38.42 -BIOS-bochs-8-processors: rombios.c biossums
   38.43 -	gcc -DBX_SMP_PROCESSORS=8 -E -P $< > _rombios8_.c
   38.44 -	bcc -o rombios8.s -C-c -D__i86__ -0 -S _rombios8_.c
   38.45 -	sed -e 's/^\.text//' -e 's/^\.data//' rombios8.s > _rombios8_.s
   38.46 -	as86 _rombios8_.s -b tmp8.bin -u- -w- -g -0 -j -O -l rombios8.txt
   38.47 -	-perl makesym.perl < rombios8.txt > rombios8.sym
   38.48 -	mv tmp8.bin BIOS-bochs-8-processors
   38.49 -	./biossums BIOS-bochs-8-processors
   38.50 -	rm -f _rombios8_.s
   38.51 -
   38.52  biossums: biossums.c
   38.53  	gcc -o biossums biossums.c
   38.54  
    39.1 --- a/tools/firmware/rombios/rombios.c	Wed Jun 28 07:52:21 2006 -0600
    39.2 +++ b/tools/firmware/rombios/rombios.c	Mon Jul 03 08:35:12 2006 +0100
    39.3 @@ -10514,6 +10514,34 @@ static Bit8u vgafont8[128*8]=
    39.4   0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
    39.5  };
    39.6  
    39.7 +#ifdef HVMASSIST
    39.8 +//
    39.9 +// MP Tables
   39.10 +// just carve out some blank space for HVMLOADER to write the MP tables to
   39.11 +//
   39.12 +// NOTE: There should be enough space for a 32 processor entry MP table
   39.13 +//
   39.14 +ASM_START
   39.15 +.org 0xcc00
   39.16 +db 0x5F, 0x5F, 0x5F, 0x48, 0x56, 0x4D, 0x4D, 0x50 ;; ___HVMMP
   39.17 +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
   39.18 +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
   39.19 +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
   39.20 +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
   39.21 +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
   39.22 +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
   39.23 +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
   39.24 +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
   39.25 +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
   39.26 +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
   39.27 +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
   39.28 +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
   39.29 +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
   39.30 +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
   39.31 +ASM_END
   39.32 +
   39.33 +#else // !HVMASSIST
   39.34 +
   39.35  ASM_START
   39.36  .org 0xcc00
   39.37  // bcc-generated data will be placed here
   39.38 @@ -10835,3 +10863,5 @@ db 0,0,0,0     ;; MP feature bytes 2-5.
   39.39  #endif
   39.40  
   39.41  ASM_END
   39.42 +
   39.43 +#endif // HVMASSIST
    40.1 --- a/tools/libxc/xc_hvm_build.c	Wed Jun 28 07:52:21 2006 -0600
    40.2 +++ b/tools/libxc/xc_hvm_build.c	Mon Jul 03 08:35:12 2006 +0100
    40.3 @@ -4,6 +4,7 @@
    40.4  
    40.5  #define ELFSIZE 32
    40.6  #include <stddef.h>
    40.7 +#include <inttypes.h>
    40.8  #include "xg_private.h"
    40.9  #include "xc_elf.h"
   40.10  #include <stdlib.h>
   40.11 @@ -188,7 +189,7 @@ static int setup_guest(int xc_handle,
   40.12      unsigned char e820_map_nr;
   40.13  
   40.14      struct domain_setup_info dsi;
   40.15 -    unsigned long long v_end;
   40.16 +    uint64_t v_end;
   40.17  
   40.18      unsigned long shared_page_frame = 0;
   40.19      shared_iopage_t *sp;
   40.20 @@ -208,11 +209,11 @@ static int setup_guest(int xc_handle,
   40.21      v_end = (unsigned long long)memsize << 20;
   40.22  
   40.23      IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
   40.24 -           "  Loaded HVM loader:    %08lx->%08lx\n"
   40.25 -           "  TOTAL:                %08lx->%016llx\n",
   40.26 +           "  Loaded HVM loader:    %016"PRIx64"->%016"PRIx64"\n"
   40.27 +           "  TOTAL:                %016"PRIx64"->%016"PRIx64"\n",
   40.28             dsi.v_kernstart, dsi.v_kernend,
   40.29             dsi.v_start, v_end);
   40.30 -    IPRINTF("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
   40.31 +    IPRINTF("  ENTRY ADDRESS:        %016"PRIx64"\n", dsi.v_kernentry);
   40.32  
   40.33      if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
   40.34      {
    41.1 --- a/tools/libxc/xc_linux_build.c	Wed Jun 28 07:52:21 2006 -0600
    41.2 +++ b/tools/libxc/xc_linux_build.c	Mon Jul 03 08:35:12 2006 +0100
    41.3 @@ -12,6 +12,9 @@
    41.4  #include <inttypes.h>
    41.5  #include <zlib.h>
    41.6  
    41.7 +/* Handy for printing out '0' prepended values at native pointer size */
    41.8 +#define _p(a) ((void *) ((ulong)a))
    41.9 +
   41.10  #if defined(__i386__)
   41.11  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   41.12  #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   41.13 @@ -502,8 +505,6 @@ static int setup_guest(int xc_handle,
   41.14          goto error_out;
   41.15      }
   41.16  
   41.17 -#define _p(a) ((void *) (a))
   41.18 -
   41.19      IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
   41.20             " Loaded kernel: %p->%p\n"
   41.21             " Init. ramdisk: %p->%p\n"
   41.22 @@ -766,9 +767,9 @@ static int setup_guest(int xc_handle,
   41.23                  goto error_out;
   41.24          }
   41.25  
   41.26 -#define NR(_l,_h,_s) \
   41.27 -    (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
   41.28 -    ((_l) & ~((1UL<<(_s))-1))) >> (_s))
   41.29 +#define NR(_l,_h,_s)                                                    \
   41.30 +    (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) -    \
   41.31 +    ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
   41.32  #if defined(__i386__)
   41.33          if ( dsi.pae_kernel != PAEKERN_no )
   41.34          {
   41.35 @@ -797,8 +798,6 @@ static int setup_guest(int xc_handle,
   41.36  #endif
   41.37      }
   41.38  
   41.39 -#define _p(a) ((void *) (a))
   41.40 -
   41.41      IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
   41.42      IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
   41.43             _p(dsi.v_kernend));
   41.44 @@ -819,8 +818,8 @@ static int setup_guest(int xc_handle,
   41.45      if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
   41.46      {
   41.47          PERROR("Initial guest OS requires too much space\n"
   41.48 -               "(%luMB is greater than %luMB limit)\n",
   41.49 -               (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT));
   41.50 +               "(%pMB is greater than %luMB limit)\n",
   41.51 +               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
   41.52          goto error_out;
   41.53      }
   41.54  
    42.1 --- a/tools/libxc/xc_linux_save.c	Wed Jun 28 07:52:21 2006 -0600
    42.2 +++ b/tools/libxc/xc_linux_save.c	Mon Jul 03 08:35:12 2006 +0100
    42.3 @@ -415,11 +415,11 @@ static int suspend_and_state(int (*suspe
    42.4  ** which entries do not require canonicalization (in particular, those
    42.5  ** entries which map the virtual address reserved for the hypervisor).
    42.6  */
    42.7 -void canonicalize_pagetable(unsigned long type, unsigned long pfn,
    42.8 -                             const void *spage, void *dpage)
    42.9 +int canonicalize_pagetable(unsigned long type, unsigned long pfn,
   42.10 +                           const void *spage, void *dpage)
   42.11  {
   42.12  
   42.13 -    int i, pte_last, xen_start, xen_end;
   42.14 +    int i, pte_last, xen_start, xen_end, race = 0; 
   42.15      uint64_t pte;
   42.16  
   42.17      /*
   42.18 @@ -481,7 +481,8 @@ void canonicalize_pagetable(unsigned lon
   42.19                     is quite feasible under live migration */
   42.20                  DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
   42.21                          type, i, (unsigned long long)pte, mfn);
   42.22 -                pfn = 0; /* zap it - we'll retransmit this page later */
   42.23 +                pfn  = 0;  /* zap it - we'll retransmit this page later */
   42.24 +                race = 1;  /* inform the caller of race; fatal if !live */ 
   42.25              } else
   42.26                  pfn = mfn_to_pfn(mfn);
   42.27  
   42.28 @@ -496,7 +497,7 @@ void canonicalize_pagetable(unsigned lon
   42.29  
   42.30      }
   42.31  
   42.32 -    return;
   42.33 +    return race; 
   42.34  }
   42.35  
   42.36  
   42.37 @@ -567,7 +568,7 @@ int xc_linux_save(int xc_handle, int io_
   42.38      int rc = 1, i, j, last_iter, iter = 0;
   42.39      int live  = (flags & XCFLAGS_LIVE);
   42.40      int debug = (flags & XCFLAGS_DEBUG);
   42.41 -    int sent_last_iter, skip_this_iter;
   42.42 +    int race = 0, sent_last_iter, skip_this_iter;
   42.43  
   42.44      /* The new domain's shared-info frame number. */
   42.45      unsigned long shared_info_frame;
   42.46 @@ -1000,7 +1001,11 @@ int xc_linux_save(int xc_handle, int io_
   42.47                  if (pagetype >= L1TAB && pagetype <= L4TAB) {
   42.48  
   42.49                      /* We have a pagetable page: need to rewrite it. */
   42.50 -                    canonicalize_pagetable(pagetype, pfn, spage, page);
   42.51 +                    race = 
   42.52 +                        canonicalize_pagetable(pagetype, pfn, spage, page); 
   42.53 +
   42.54 +                    if(race && !live) 
   42.55 +                        goto out; 
   42.56  
   42.57                      if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
   42.58                          ERR("Error when writing to state file (4)");
    43.1 --- a/tools/libxc/xc_load_elf.c	Wed Jun 28 07:52:21 2006 -0600
    43.2 +++ b/tools/libxc/xc_load_elf.c	Mon Jul 03 08:35:12 2006 +0100
    43.3 @@ -68,7 +68,7 @@ static int parseelfimage(const char *ima
    43.4      Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
    43.5      Elf_Phdr *phdr;
    43.6      Elf_Shdr *shdr;
    43.7 -    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
    43.8 +    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
    43.9      const char *shstrtab;
   43.10      char *guestinfo=NULL, *p;
   43.11      int h, virt_base_defined, elf_pa_off_defined;
   43.12 @@ -162,15 +162,19 @@ static int parseelfimage(const char *ima
   43.13      /* Initial guess for virt_base is 0 if it is not explicitly defined. */
   43.14      p = strstr(guestinfo, "VIRT_BASE=");
   43.15      virt_base_defined = (p != NULL);
   43.16 -    virt_base = virt_base_defined ? strtoul(p+10, &p, 0) : 0;
   43.17 +    virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0;
   43.18  
   43.19      /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
   43.20      p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
   43.21      elf_pa_off_defined = (p != NULL);
   43.22 -    elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
   43.23 +    elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base;
   43.24  
   43.25      if ( elf_pa_off_defined && !virt_base_defined )
   43.26 -        goto bad_image;
   43.27 +    {
   43.28 +        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest"
   43.29 +              " section.");
   43.30 +        return -EINVAL;
   43.31 +    }
   43.32  
   43.33      for ( h = 0; h < ehdr->e_phnum; h++ )
   43.34      {
   43.35 @@ -179,7 +183,11 @@ static int parseelfimage(const char *ima
   43.36              continue;
   43.37          vaddr = phdr->p_paddr - elf_pa_off + virt_base;
   43.38          if ( (vaddr + phdr->p_memsz) < vaddr )
   43.39 -            goto bad_image;
   43.40 +        {
   43.41 +            ERROR("ELF program header %d is too large.", h);
   43.42 +            return -EINVAL;
   43.43 +        }
   43.44 +
   43.45          if ( vaddr < kernstart )
   43.46              kernstart = vaddr;
   43.47          if ( (vaddr + phdr->p_memsz) > kernend )
   43.48 @@ -196,13 +204,16 @@ static int parseelfimage(const char *ima
   43.49  
   43.50      dsi->v_kernentry = ehdr->e_entry;
   43.51      if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
   43.52 -        dsi->v_kernentry = strtoul(p+11, &p, 0);
   43.53 +        dsi->v_kernentry = strtoull(p+11, &p, 0);
   43.54  
   43.55      if ( (kernstart > kernend) ||
   43.56           (dsi->v_kernentry < kernstart) ||
   43.57           (dsi->v_kernentry > kernend) ||
   43.58           (dsi->v_start > kernstart) )
   43.59 -        goto bad_image;
   43.60 +    {
   43.61 +        ERROR("ELF start or entries are out of bounds.");
   43.62 +        return -EINVAL;
   43.63 +    }
   43.64  
   43.65      if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   43.66          dsi->load_symtab = 1;
   43.67 @@ -214,10 +225,6 @@ static int parseelfimage(const char *ima
   43.68      loadelfsymtab(image, 0, 0, NULL, dsi);
   43.69  
   43.70      return 0;
   43.71 -
   43.72 - bad_image:
   43.73 -    ERROR("Malformed ELF image.");
   43.74 -    return -EINVAL;
   43.75  }
   43.76  
   43.77  static int
    44.1 --- a/tools/libxc/xg_private.h	Wed Jun 28 07:52:21 2006 -0600
    44.2 +++ b/tools/libxc/xg_private.h	Mon Jul 03 08:35:12 2006 +0100
    44.3 @@ -132,13 +132,13 @@ typedef unsigned long l4_pgentry_t;
    44.4  
    44.5  struct domain_setup_info
    44.6  {
    44.7 -    unsigned long v_start;
    44.8 -    unsigned long v_end;
    44.9 -    unsigned long v_kernstart;
   44.10 -    unsigned long v_kernend;
   44.11 -    unsigned long v_kernentry;
   44.12 +    uint64_t v_start;
   44.13 +    uint64_t v_end;
   44.14 +    uint64_t v_kernstart;
   44.15 +    uint64_t v_kernend;
   44.16 +    uint64_t v_kernentry;
   44.17  
   44.18 -    unsigned long elf_paddr_offset;
   44.19 +    uint64_t elf_paddr_offset;
   44.20  
   44.21  #define PAEKERN_no           0
   44.22  #define PAEKERN_yes          1
    45.1 --- a/tools/python/xen/xend/XendLogging.py	Wed Jun 28 07:52:21 2006 -0600
    45.2 +++ b/tools/python/xen/xend/XendLogging.py	Mon Jul 03 08:35:12 2006 +0100
    45.3 @@ -43,7 +43,7 @@ MAX_BYTES = 1 << 20  # 1MB
    45.4  BACKUP_COUNT = 5
    45.5  
    45.6  STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
    45.7 -LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
    45.8 +LOGFILE_FORMAT = "[%(asctime)s %(name)s %(process)d] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
    45.9  DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
   45.10  
   45.11  
    46.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Wed Jun 28 07:52:21 2006 -0600
    46.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Mon Jul 03 08:35:12 2006 +0100
    46.3 @@ -22,8 +22,6 @@ import sys
    46.4  import traceback
    46.5  import tempfile
    46.6  import os, stat
    46.7 -import re
    46.8 -import commands
    46.9  import shutil
   46.10  import string
   46.11  from xen.util.security import ACMError, err
    47.1 --- a/tools/python/xen/xm/create.py	Wed Jun 28 07:52:21 2006 -0600
    47.2 +++ b/tools/python/xen/xm/create.py	Mon Jul 03 08:35:12 2006 +0100
    47.3 @@ -21,11 +21,8 @@
    47.4  """
    47.5  import os
    47.6  import os.path
    47.7 -import string
    47.8  import sys
    47.9  import socket
   47.10 -import commands
   47.11 -import time
   47.12  import re
   47.13  import xmlrpclib
   47.14  
    48.1 --- a/tools/python/xen/xm/dumppolicy.py	Wed Jun 28 07:52:21 2006 -0600
    48.2 +++ b/tools/python/xen/xm/dumppolicy.py	Mon Jul 03 08:35:12 2006 +0100
    48.3 @@ -19,10 +19,6 @@
    48.4  """
    48.5  import sys
    48.6  import traceback
    48.7 -import os
    48.8 -import commands
    48.9 -import shutil
   48.10 -import string
   48.11  from xen.util.security import ACMError, err, dump_policy
   48.12  
   48.13  
    49.1 --- a/tools/python/xen/xm/labels.py	Wed Jun 28 07:52:21 2006 -0600
    49.2 +++ b/tools/python/xen/xm/labels.py	Mon Jul 03 08:35:12 2006 +0100
    49.3 @@ -20,9 +20,6 @@
    49.4  """
    49.5  import sys
    49.6  import traceback
    49.7 -import os
    49.8 -import commands
    49.9 -import shutil
   49.10  import string
   49.11  from xen.util.security import ACMError, err, list_labels, active_policy
   49.12  from xen.util.security import vm_label_re, res_label_re, all_label_re
    50.1 --- a/tools/python/xen/xm/loadpolicy.py	Wed Jun 28 07:52:21 2006 -0600
    50.2 +++ b/tools/python/xen/xm/loadpolicy.py	Mon Jul 03 08:35:12 2006 +0100
    50.3 @@ -20,10 +20,6 @@
    50.4  """
    50.5  import sys
    50.6  import traceback
    50.7 -import os
    50.8 -import commands
    50.9 -import shutil
   50.10 -import string
   50.11  from xen.util.security import ACMError, err, load_policy
   50.12  
   50.13  
    51.1 --- a/tools/python/xen/xm/main.py	Wed Jun 28 07:52:21 2006 -0600
    51.2 +++ b/tools/python/xen/xm/main.py	Mon Jul 03 08:35:12 2006 +0100
    51.3 @@ -556,7 +556,7 @@ def xm_vcpu_list(args):
    51.4  
    51.5  
    51.6  def xm_reboot(args):
    51.7 -    arg_check(args, "reboot", 1, 4)
    51.8 +    arg_check(args, "reboot", 1, 3)
    51.9      from xen.xm import shutdown
   51.10      shutdown.main(["shutdown", "-R"] + args)
   51.11  
    52.1 --- a/tools/python/xen/xm/makepolicy.py	Wed Jun 28 07:52:21 2006 -0600
    52.2 +++ b/tools/python/xen/xm/makepolicy.py	Mon Jul 03 08:35:12 2006 +0100
    52.3 @@ -19,10 +19,6 @@
    52.4  """
    52.5  import sys
    52.6  import traceback
    52.7 -import os
    52.8 -import commands
    52.9 -import shutil
   52.10 -import string
   52.11  from xen.util.security import ACMError, err, make_policy
   52.12  
   52.13  
    53.1 --- a/tools/python/xen/xm/shutdown.py	Wed Jun 28 07:52:21 2006 -0600
    53.2 +++ b/tools/python/xen/xm/shutdown.py	Mon Jul 03 08:35:12 2006 +0100
    53.3 @@ -17,8 +17,6 @@
    53.4  
    53.5  """Domain shutdown.
    53.6  """
    53.7 -import string
    53.8 -import sys
    53.9  import time
   53.10  
   53.11  from xen.xend.XendClient import server
   53.12 @@ -92,7 +90,8 @@ def main_all(opts, args):
   53.13      shutdown(opts, None, mode, opts.vals.wait)
   53.14  
   53.15  def main_dom(opts, args):
   53.16 -    if len(args) < 1: opts.err('Missing domain')
   53.17 +    if len(args) == 0: opts.err('No domain parameter given')
   53.18 +    if len(args) >  1: opts.err('No multiple domain parameters allowed')
   53.19      dom = args[0]
   53.20      mode = shutdown_mode(opts)  
   53.21      shutdown(opts, [ dom ], mode, opts.vals.wait)
    54.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Wed Jun 28 07:52:21 2006 -0600
    54.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Mon Jul 03 08:35:12 2006 +0100
    54.3 @@ -20,6 +20,11 @@
    54.4  #include <stdio.h>
    54.5  #include <string.h>
    54.6  #include <unistd.h>
    54.7 +#include <linux/compiler.h>
    54.8 +#include <fcntl.h>
    54.9 +#include <dirent.h>
   54.10 +#include <sys/types.h>
   54.11 +#include <sys/stat.h>
   54.12  #include <xs.h>
   54.13  #include "xenstat.h"
   54.14  
   54.15 @@ -36,6 +41,7 @@ struct xenstat_handle {
   54.16  	struct xs_handle *xshandle; /* xenstore handle */
   54.17  	int page_size;
   54.18  	FILE *procnetdev;
   54.19 +	DIR *sysfsvbd;
   54.20  	char xen_version[VERSION_SIZE]; /* xen version running on this node */
   54.21  };
   54.22  
   54.23 @@ -62,6 +68,8 @@ struct xenstat_domain {
   54.24  	unsigned int ssid;
   54.25  	unsigned int num_networks;
   54.26  	xenstat_network *networks;	/* Array of length num_networks */
   54.27 +	unsigned int num_vbds;
   54.28 +	xenstat_vbd *vbds;
   54.29  };
   54.30  
   54.31  struct xenstat_vcpu {
   54.32 @@ -83,6 +91,15 @@ struct xenstat_network {
   54.33  	unsigned long long tdrop;
   54.34  };
   54.35  
   54.36 +struct xenstat_vbd {
   54.37 +       unsigned int dev;
   54.38 +       unsigned long long oo_reqs;
   54.39 +       unsigned long long rd_reqs;
   54.40 +       unsigned long long wr_reqs;
   54.41 +};
   54.42 +#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
   54.43 +
   54.44 +
   54.45  /*
   54.46   * Data-collection types
   54.47   */
   54.48 @@ -108,12 +125,15 @@ typedef struct xenstat_collector {
   54.49  static int  xenstat_collect_vcpus(xenstat_node * node);
   54.50  static int  xenstat_collect_networks(xenstat_node * node);
   54.51  static int  xenstat_collect_xen_version(xenstat_node * node);
   54.52 +static int  xenstat_collect_vbds(xenstat_node * node);
   54.53  static void xenstat_free_vcpus(xenstat_node * node);
   54.54  static void xenstat_free_networks(xenstat_node * node);
   54.55  static void xenstat_free_xen_version(xenstat_node * node);
   54.56 +static void xenstat_free_vbds(xenstat_node * node);
   54.57  static void xenstat_uninit_vcpus(xenstat_handle * handle);
   54.58  static void xenstat_uninit_networks(xenstat_handle * handle);
   54.59  static void xenstat_uninit_xen_version(xenstat_handle * handle);
   54.60 +static void xenstat_uninit_vbds(xenstat_handle * handle);
   54.61  static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int domain_id);
   54.62  
   54.63  static xenstat_collector collectors[] = {
   54.64 @@ -122,7 +142,9 @@ static xenstat_collector collectors[] = 
   54.65  	{ XENSTAT_NETWORK, xenstat_collect_networks,
   54.66  	  xenstat_free_networks, xenstat_uninit_networks },
   54.67  	{ XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
   54.68 -	  xenstat_free_xen_version, xenstat_uninit_xen_version }
   54.69 +	  xenstat_free_xen_version, xenstat_uninit_xen_version },
   54.70 +	{ XENSTAT_VBD, xenstat_collect_vbds,
   54.71 +	  xenstat_free_vbds, xenstat_uninit_vbds }
   54.72  };
   54.73  
   54.74  #define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
   54.75 @@ -259,6 +281,8 @@ xenstat_node *xenstat_get_node(xenstat_h
   54.76  			domain->ssid = domaininfo[i].ssidref;
   54.77  			domain->num_networks = 0;
   54.78  			domain->networks = NULL;
   54.79 +			domain->num_vbds = 0;
   54.80 +			domain->vbds = NULL;
   54.81  
   54.82  			domain++;
   54.83  		}
   54.84 @@ -451,6 +475,21 @@ xenstat_network *xenstat_domain_network(
   54.85  	return NULL;
   54.86  }
   54.87  
   54.88 +/* Get the number of VBDs for a given domain */
   54.89 +unsigned int xenstat_domain_num_vbds(xenstat_domain * domain)
   54.90 +{
   54.91 +	return domain->num_vbds;
   54.92 +}
   54.93 +
   54.94 +/* Get the VBD handle to obtain VBD stats */
   54.95 +xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
   54.96 +				unsigned int vbd)
   54.97 +{
   54.98 +	if (domain->vbds && 0 <= vbd && vbd < domain->num_vbds)
   54.99 +		return &(domain->vbds[vbd]);
  54.100 +	return NULL;
  54.101 +}
  54.102 +
  54.103  /*
  54.104   * VCPU functions
  54.105   */
  54.106 @@ -710,6 +749,139 @@ static void xenstat_uninit_xen_version(x
  54.107  {
  54.108  }
  54.109  
  54.110 +/*
  54.111 + * VBD functions
  54.112 + */
  54.113 +
  54.114 +static int read_attributes_vbd(const char *vbd_directory, const char *what, char *ret, int cap)
  54.115 +{
  54.116 +	static char file_name[80];
  54.117 +	int fd, num_read;
  54.118 +
  54.119 +	sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
  54.120 +	fd = open(file_name, O_RDONLY, 0);
  54.121 +	if (fd==-1) return -1;
  54.122 +	num_read = read(fd, ret, cap - 1);
  54.123 +	close(fd);
  54.124 +	if (num_read<=0) return -1;
  54.125 +	ret[num_read] = '\0';
  54.126 +	return num_read;
  54.127 +}
  54.128 +
  54.129 +/* Collect information about VBDs */
  54.130 +static int xenstat_collect_vbds(xenstat_node * node)
  54.131 +{
  54.132 +	struct dirent *dp;
  54.133 +
  54.134 +	if (node->handle->sysfsvbd == NULL) {
  54.135 +		node->handle->sysfsvbd = opendir(SYSFS_VBD_PATH);
  54.136 +		if (node->handle->sysfsvbd == NULL) {
  54.137 +			perror("Error opening " SYSFS_VBD_PATH);
  54.138 +			return 0;
  54.139 +		}
  54.140 +	}
  54.141 +
  54.142 +	rewinddir(node->handle->sysfsvbd);
  54.143 +
  54.144 +	for(dp = readdir(node->handle->sysfsvbd); dp != NULL ;
  54.145 +	    dp = readdir(node->handle->sysfsvbd)) {
  54.146 +		xenstat_domain *domain;
  54.147 +		xenstat_vbd vbd;
  54.148 +		unsigned int domid;
  54.149 +		int ret;
  54.150 +		char buf[256];
  54.151 +
  54.152 +
  54.153 +		ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
  54.154 +		if (ret != 2) {
  54.155 +			continue;
  54.156 +		}
  54.157 +		printf("%s is VBD.\n",dp->d_name);
  54.158 +
  54.159 +		domain = xenstat_node_domain(node, domid);
  54.160 +		if (domain == NULL) {
  54.161 +			fprintf(stderr,
  54.162 +				"Found interface vbd-%u-%u but domain %u"
  54.163 +				" does not exist.\n",
  54.164 +				domid, vbd.dev, domid);
  54.165 +			continue;
  54.166 +		}
  54.167 +
  54.168 +		if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 256)<=0)
  54.169 +		   || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
  54.170 +		{
  54.171 +			continue;
  54.172 +		}
  54.173 +
  54.174 +		if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 256)<=0)
  54.175 +		   || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
  54.176 +		{
  54.177 +			continue;
  54.178 +		}
  54.179 +
  54.180 +		if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 256)<=0)
  54.181 +		   || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
  54.182 +		{
  54.183 +			continue;
  54.184 +		}
  54.185 +
  54.186 +
  54.187 +		if (domain->vbds == NULL) {
  54.188 +			domain->num_vbds = 1;
  54.189 +			domain->vbds = malloc(sizeof(xenstat_vbd));
  54.190 +		} else {
  54.191 +			domain->num_vbds++;
  54.192 +			domain->vbds = realloc(domain->vbds,
  54.193 +					       domain->num_vbds *
  54.194 +					       sizeof(xenstat_vbd));
  54.195 +		}
  54.196 +		if (domain->vbds == NULL)
  54.197 +			return 0;
  54.198 +		domain->vbds[domain->num_vbds - 1] = vbd;
  54.199 +	}
  54.200 +
  54.201 +	return 1;	
  54.202 +}
  54.203 +
  54.204 +/* Free VBD information */
  54.205 +static void xenstat_free_vbds(xenstat_node * node)
  54.206 +{
  54.207 +	unsigned int i;
  54.208 +	for (i = 0; i < node->num_domains; i++)
  54.209 +		free(node->domains[i].vbds);
  54.210 +}
  54.211 +
  54.212 +/* Free VBD information in handle */
  54.213 +static void xenstat_uninit_vbds(xenstat_handle * handle)
  54.214 +{
  54.215 +	if (handle->sysfsvbd)
  54.216 +		closedir(handle->sysfsvbd);
  54.217 +}
  54.218 +
  54.219 +/* Get the major number of VBD device */
  54.220 +unsigned int xenstat_vbd_dev(xenstat_vbd * vbd)
  54.221 +{
  54.222 +	return vbd->dev;
  54.223 +}
  54.224 +
  54.225 +/* Get the number of OO(Out of) requests */
  54.226 +unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd)
  54.227 +{
  54.228 +	return vbd->oo_reqs;
  54.229 +}
  54.230 +
  54.231 +/* Get the number of READ requests */
  54.232 +unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd)
  54.233 +{
  54.234 +	return vbd->rd_reqs;
  54.235 +}
  54.236 +
  54.237 +/* Get the number of WRITE requests */
  54.238 +unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd)
  54.239 +{
  54.240 +	return vbd->wr_reqs;
  54.241 +}
  54.242 +
  54.243  static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int domain_id)
  54.244  {
  54.245  	char path[80];
    55.1 --- a/tools/xenstat/libxenstat/src/xenstat.h	Wed Jun 28 07:52:21 2006 -0600
    55.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h	Mon Jul 03 08:35:12 2006 +0100
    55.3 @@ -23,6 +23,7 @@ typedef struct xenstat_domain xenstat_do
    55.4  typedef struct xenstat_node xenstat_node;
    55.5  typedef struct xenstat_vcpu xenstat_vcpu;
    55.6  typedef struct xenstat_network xenstat_network;
    55.7 +typedef struct xenstat_vbd xenstat_vbd;
    55.8  
    55.9  /* Initialize the xenstat library.  Returns a handle to be used with
   55.10   * subsequent calls to the xenstat library, or NULL if an error occurs. */
   55.11 @@ -35,7 +36,8 @@ void xenstat_uninit(xenstat_handle * han
   55.12  #define XENSTAT_VCPU 0x1
   55.13  #define XENSTAT_NETWORK 0x2
   55.14  #define XENSTAT_XEN_VERSION 0x4
   55.15 -#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION)
   55.16 +#define XENSTAT_VBD 0x8
   55.17 +#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION|XENSTAT_VBD)
   55.18  
   55.19  /* Get all available information about a node */
   55.20  xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
   55.21 @@ -117,6 +119,13 @@ unsigned int xenstat_domain_num_networks
   55.22  xenstat_network *xenstat_domain_network(xenstat_domain * domain,
   55.23  					unsigned int network);
   55.24  
   55.25 +/* Get the number of VBDs for a given domain */
   55.26 +unsigned int xenstat_domain_num_vbds(xenstat_domain *);
   55.27 +
   55.28 +/* Get the VBD handle to obtain VBD stats */
   55.29 +xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
   55.30 +				    unsigned int vbd);
   55.31 +
   55.32  /*
   55.33   * VCPU functions - extract information from a xenstat_vcpu
   55.34   */
   55.35 @@ -156,3 +165,14 @@ unsigned long long xenstat_network_terrs
   55.36  
   55.37  /* Get the number of transmit drops for this network */
   55.38  unsigned long long xenstat_network_tdrop(xenstat_network * network);
   55.39 +
   55.40 +/*
   55.41 + * VBD functions - extract information from a xen_vbd
   55.42 + */
   55.43 +/* Get the device number for Virtual Block Device */
   55.44 +unsigned int xenstat_vbd_dev(xenstat_vbd * vbd);
   55.45 +
   55.46 +/* Get the number of OO/RD/WR requests for vbd */
   55.47 +unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd);
   55.48 +unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd);
   55.49 +unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd);
    56.1 --- a/tools/xenstat/xentop/xentop.c	Wed Jun 28 07:52:21 2006 -0600
    56.2 +++ b/tools/xenstat/xentop/xentop.c	Mon Jul 03 08:35:12 2006 +0100
    56.3 @@ -27,6 +27,7 @@
    56.4  #include <sys/time.h>
    56.5  #include <time.h>
    56.6  #include <unistd.h>
    56.7 +#include <linux/kdev_t.h>
    56.8  
    56.9  #include <xenstat.h>
   56.10  
   56.11 @@ -65,6 +66,7 @@ static int handle_key(int);
   56.12  static int compare(unsigned long long, unsigned long long);
   56.13  static int compare_domains(xenstat_domain **, xenstat_domain **);
   56.14  static unsigned long long tot_net_bytes( xenstat_domain *, int);
   56.15 +static unsigned long long tot_vbd_reqs( xenstat_domain *, int);
   56.16  
   56.17  /* Field functions */
   56.18  static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
   56.19 @@ -91,6 +93,15 @@ static int compare_ssid(xenstat_domain *
   56.20  static void print_ssid(xenstat_domain *domain);
   56.21  static int compare_name(xenstat_domain *domain1, xenstat_domain *domain2);
   56.22  static void print_name(xenstat_domain *domain);
   56.23 +static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2);
   56.24 +static void print_vbds(xenstat_domain *domain);
   56.25 +static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2);
   56.26 +static void print_vbd_oo(xenstat_domain *domain);
   56.27 +static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2);
   56.28 +static void print_vbd_rd(xenstat_domain *domain);
   56.29 +static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2);
   56.30 +static void print_vbd_wr(xenstat_domain *domain);
   56.31 +
   56.32  
   56.33  /* Section printing functions */
   56.34  static void do_summary(void);
   56.35 @@ -99,6 +110,7 @@ static void do_bottom_line(void);
   56.36  static void do_domain(xenstat_domain *);
   56.37  static void do_vcpu(xenstat_domain *);
   56.38  static void do_network(xenstat_domain *);
   56.39 +static void do_vbd(xenstat_domain *);
   56.40  static void top(void);
   56.41  
   56.42  /* Field types */
   56.43 @@ -116,6 +128,10 @@ typedef enum field_id {
   56.44  	FIELD_NETS,
   56.45  	FIELD_NET_TX,
   56.46  	FIELD_NET_RX,
   56.47 +	FIELD_VBDS,
   56.48 +	FIELD_VBD_OO,
   56.49 +	FIELD_VBD_RD,
   56.50 +	FIELD_VBD_WR,
   56.51  	FIELD_SSID
   56.52  } field_id;
   56.53  
   56.54 @@ -140,7 +156,11 @@ field fields[] = {
   56.55  	{ FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
   56.56  	{ FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
   56.57  	{ FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
   56.58 -	{ FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
   56.59 +	{ FIELD_NET_RX,  "VBDS",       8, compare_vbds,    print_vbds    },
   56.60 +	{ FIELD_NET_RX,  "VBD_OO",     8, compare_vbd_oo,  print_vbd_oo  },
   56.61 +	{ FIELD_NET_RX,  "VBD_RD",     8, compare_vbd_rd,  print_vbd_rd  },
   56.62 +	{ FIELD_NET_RX,  "VBD_WR",     8, compare_vbd_wr,  print_vbd_wr  },
   56.63 +       	{ FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
   56.64  };
   56.65  
   56.66  const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field);
   56.67 @@ -158,6 +178,7 @@ unsigned int loop = 1;
   56.68  unsigned int iterations = 0;
   56.69  int show_vcpus = 0;
   56.70  int show_networks = 0;
   56.71 +int show_vbds = 0;
   56.72  int repeat_header = 0;
   56.73  #define PROMPT_VAL_LEN 80
   56.74  char *prompt = NULL;
   56.75 @@ -180,6 +201,7 @@ static void usage(const char *program)
   56.76  	       "-V, --version        output version information and exit\n"
   56.77  	       "-d, --delay=SECONDS  seconds between updates (default 3)\n"
   56.78  	       "-n, --networks       output vif network data\n"
   56.79 +	       "-b, --vbds           output vbd block device data\n"
   56.80  	       "-r, --repeat-header  repeat table header before each domain\n"
   56.81  	       "-v, --vcpus          output vcpu data\n"
   56.82  	       "-b, --batch	     output in batch mode, no user input accepted\n"
   56.83 @@ -290,6 +312,9 @@ static int handle_key(int ch)
   56.84  		case 'n': case 'N':
   56.85  			show_networks ^= 1;
   56.86  			break;
   56.87 +		case 'b': case 'B':
   56.88 +			show_vbds ^= 1;
   56.89 +			break;
   56.90  		case 'r': case 'R':
   56.91  			repeat_header ^= 1;
   56.92  			break;
   56.93 @@ -585,6 +610,96 @@ static unsigned long long tot_net_bytes(
   56.94  	return total;
   56.95  }
   56.96  
   56.97 +/* Compares number of virtual block devices of two domains,
   56.98 +   returning -1,0,1 for * <,=,> */
   56.99 +static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2)
  56.100 +{
  56.101 +	return -compare(xenstat_domain_num_vbds(domain1),
  56.102 +	                xenstat_domain_num_vbds(domain2));
  56.103 +}
  56.104 +
  56.105 +/* Prints number of virtual block devices statistic */
  56.106 +static void print_vbds(xenstat_domain *domain)
  56.107 +{
  56.108 +	print("%4u", xenstat_domain_num_vbds(domain));
  56.109 +}
  56.110 +
  56.111 +/* Compares number of total VBD OO requests of two domains,
  56.112 +   returning -1,0,1 * for <,=,> */
  56.113 +static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2)
  56.114 +{
  56.115 +  return -compare(tot_vbd_reqs(domain1, FIELD_VBD_OO),
  56.116 +		  tot_vbd_reqs(domain2, FIELD_VBD_OO));
  56.117 +}
  56.118 +
  56.119 +/* Prints number of total VBD OO requests statistic */
  56.120 +static void print_vbd_oo(xenstat_domain *domain)
  56.121 +{
  56.122 +	print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_OO));
  56.123 +}
  56.124 +
  56.125 +/* Compares number of total VBD READ requests of two domains,
  56.126 +   returning -1,0,1 * for <,=,> */
  56.127 +static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2)
  56.128 +{
  56.129 +	return -compare(tot_vbd_reqs(domain1, FIELD_VBD_RD),
  56.130 +			tot_vbd_reqs(domain2, FIELD_VBD_RD));
  56.131 +}
  56.132 +
  56.133 +/* Prints number of total VBD READ requests statistic */
  56.134 +static void print_vbd_rd(xenstat_domain *domain)
  56.135 +{
  56.136 +	print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_RD));
  56.137 +}
  56.138 +
  56.139 +/* Compares number of total VBD WRITE requests of two domains,
  56.140 +   returning -1,0,1 * for <,=,> */
  56.141 +static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2)
  56.142 +{
  56.143 +	return -compare(tot_vbd_reqs(domain1,FIELD_VBD_WR),
  56.144 +			tot_vbd_reqs(domain2,FIELD_VBD_WR));
  56.145 +}
  56.146 +
  56.147 +/* Prints number of total VBD WRITE requests statistic */
  56.148 +static void print_vbd_wr(xenstat_domain *domain)
  56.149 +{
  56.150 +	print("%8llu", tot_vbd_reqs(domain,FIELD_VBD_WR));
  56.151 +}
  56.152 +
  56.153 +/* Gets number of total VBD requests statistic, 
  56.154 + *   if flag is FIELD_VBD_OO, then OO requests,
  56.155 + *   if flag is FIELD_VBD_RD, then READ requests and
  56.156 + *   if flag is FIELD_VBD_WR, then WRITE requests.
  56.157 + */
  56.158 +static unsigned long long tot_vbd_reqs(xenstat_domain *domain, int flag)
  56.159 +{
  56.160 +	int i = 0;
  56.161 +	xenstat_vbd *vbd;
  56.162 +	unsigned num_vbds = 0;
  56.163 +	unsigned long long total = 0;
  56.164 +	
  56.165 +	num_vbds = xenstat_domain_num_vbds(domain);
  56.166 +	
  56.167 +	for ( i=0 ; i < num_vbds ; i++) {
  56.168 +		vbd = xenstat_domain_vbd(domain,i);
  56.169 +		switch(flag) {
  56.170 +		case FIELD_VBD_OO:
  56.171 +			total += xenstat_vbd_oo_reqs(vbd);
  56.172 +			break;
  56.173 +		case FIELD_VBD_RD:
  56.174 +			total += xenstat_vbd_rd_reqs(vbd);
  56.175 +			break;
  56.176 +		case FIELD_VBD_WR:
  56.177 +			total += xenstat_vbd_wr_reqs(vbd);
  56.178 +			break;
  56.179 +		default:
  56.180 +			break;
  56.181 +		}
  56.182 +	}
  56.183 +	
  56.184 +	return total;
  56.185 +}
  56.186 +
  56.187  /* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
  56.188  static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
  56.189  {
  56.190 @@ -680,6 +795,13 @@ void do_bottom_line(void)
  56.191  		addch(A_REVERSE | 'N');
  56.192  		attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
  56.193  		addstr("  ");
  56.194 +		
  56.195 +		/* VBDs */
  56.196 +		attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "v");
  56.197 +		addch(A_REVERSE | 'B');
  56.198 +		attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "ds");
  56.199 +		addstr("  ");
  56.200 +
  56.201  
  56.202  		/* vcpus */
  56.203  		addch(A_REVERSE | 'V');
  56.204 @@ -769,6 +891,28 @@ void do_network(xenstat_domain *domain)
  56.205  	}
  56.206  }
  56.207  
  56.208 +
  56.209 +/* Output all VBD information */
  56.210 +void do_vbd(xenstat_domain *domain)
  56.211 +{
  56.212 +	int i = 0;
  56.213 +	xenstat_vbd *vbd;
  56.214 +	unsigned num_vbds = 0;
  56.215 +
  56.216 +	num_vbds = xenstat_domain_num_vbds(domain);
  56.217 +
  56.218 +	for (i=0 ; i< num_vbds; i++) {
  56.219 +		vbd = xenstat_domain_vbd(domain,i);
  56.220 +				
  56.221 +		print("VBD %4u [%2x:%2x]  OO: %8llu   RD: %8llu   WR: %8llu\n",
  56.222 +		      xenstat_vbd_dev(vbd),
  56.223 +		      MAJOR(xenstat_vbd_dev(vbd)), MINOR(xenstat_vbd_dev(vbd)),
  56.224 +		      xenstat_vbd_oo_reqs(vbd),
  56.225 +		      xenstat_vbd_rd_reqs(vbd),
  56.226 +		      xenstat_vbd_wr_reqs(vbd));
  56.227 +	}
  56.228 +}
  56.229 +
  56.230  static void top(void)
  56.231  {
  56.232  	xenstat_domain **domains;
  56.233 @@ -812,6 +956,8 @@ static void top(void)
  56.234  			do_vcpu(domains[i]);
  56.235  		if (show_networks)
  56.236  			do_network(domains[i]);
  56.237 +		if (show_vbds)
  56.238 +			do_vbd(domains[i]);
  56.239  	}
  56.240  
  56.241  	if(!batch)
  56.242 @@ -827,6 +973,7 @@ int main(int argc, char **argv)
  56.243  		{ "help",          no_argument,       NULL, 'h' },
  56.244  		{ "version",       no_argument,       NULL, 'V' },
  56.245  		{ "networks",      no_argument,       NULL, 'n' },
  56.246 + 		{ "vbds",          no_argument,       NULL, 'x' },
  56.247  		{ "repeat-header", no_argument,       NULL, 'r' },
  56.248  		{ "vcpus",         no_argument,       NULL, 'v' },
  56.249  		{ "delay",         required_argument, NULL, 'd' },
  56.250 @@ -834,7 +981,7 @@ int main(int argc, char **argv)
  56.251  		{ "iterations",	   required_argument, NULL, 'i' },
  56.252  		{ 0, 0, 0, 0 },
  56.253  	};
  56.254 -	const char *sopts = "hVbnvd:bi:";
  56.255 +	const char *sopts = "hVnxrvd:bi:";
  56.256  
  56.257  	if (atexit(cleanup) != 0)
  56.258  		fail("Failed to install cleanup handler.\n");
  56.259 @@ -852,6 +999,9 @@ int main(int argc, char **argv)
  56.260  		case 'n':
  56.261  			show_networks = 1;
  56.262  			break;
  56.263 +		case 'x':
  56.264 +			show_vbds = 1;
  56.265 +			break;
  56.266  		case 'r':
  56.267  			repeat_header = 1;
  56.268  			break;
    57.1 --- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py	Wed Jun 28 07:52:21 2006 -0600
    57.2 +++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py	Mon Jul 03 08:35:12 2006 +0100
    57.3 @@ -14,16 +14,15 @@ import os.path
    57.4  
    57.5  config = {"vtpm":"instance=1,backend=0"}
    57.6  domain = XmTestDomain(extraConfig=config)
    57.7 +domName = domain.getName()
    57.8  
    57.9  try:
   57.10      console = domain.start()
   57.11  except DomainError, e:
   57.12      if verbose:
   57.13          print e.extra
   57.14 -    vtpm_cleanup(domain.getName())
   57.15 -    FAIL("Unable to create domain")
   57.16 -
   57.17 -domName = domain.getName()
   57.18 +    vtpm_cleanup(domName)
   57.19 +    FAIL("Unable to create domain (%s)" % domName)
   57.20  
   57.21  try:
   57.22      console.sendInput("input")
   57.23 @@ -33,11 +32,11 @@ except ConsoleError, e:
   57.24      FAIL(str(e))
   57.25  
   57.26  try:
   57.27 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   57.28 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   57.29  except ConsoleError, e:
   57.30      saveLog(console.getHistory())
   57.31      vtpm_cleanup(domName)
   57.32 -    FAIL(str(e))
   57.33 +    FAIL("No result from dumping the PCRs")
   57.34  
   57.35  if re.search("No such file",run["output"]):
   57.36      vtpm_cleanup(domName)
    58.1 --- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py	Wed Jun 28 07:52:21 2006 -0600
    58.2 +++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py	Mon Jul 03 08:35:12 2006 +0100
    58.3 @@ -15,6 +15,7 @@ import os.path
    58.4  
    58.5  config = {"vtpm":"instance=1,backend=0"}
    58.6  domain = XmTestDomain(extraConfig=config)
    58.7 +domName = domain.getName()
    58.8  consoleHistory = ""
    58.9  
   58.10  try:
   58.11 @@ -22,10 +23,8 @@ try:
   58.12  except DomainError, e:
   58.13      if verbose:
   58.14          print e.extra
   58.15 -    vtpm_cleanup(domain.getName())
   58.16 -    FAIL("Unable to create domain")
   58.17 -
   58.18 -domName = domain.getName()
   58.19 +    vtpm_cleanup(domName)
   58.20 +    FAIL("Unable to create domain (%s)" % domName)
   58.21  
   58.22  try:
   58.23      console.sendInput("input")
   58.24 @@ -35,11 +34,11 @@ except ConsoleError, e:
   58.25      FAIL(str(e))
   58.26  
   58.27  try:
   58.28 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   58.29 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   58.30  except ConsoleError, e:
   58.31      saveLog(console.getHistory())
   58.32      vtpm_cleanup(domName)
   58.33 -    FAIL(str(e))
   58.34 +    FAIL("No result from dumping the PCRs")
   58.35  
   58.36  if re.search("No such file",run["output"]):
   58.37      vtpm_cleanup(domName)
   58.38 @@ -48,50 +47,59 @@ if re.search("No such file",run["output"
   58.39  consoleHistory = console.getHistory()
   58.40  domain.closeConsole()
   58.41  
   58.42 -try:
   58.43 -    status, ouptut = traceCommand("xm save %s %s.save" %
   58.44 -                                  (domName, domName),
   58.45 -                                  timeout=30)
   58.46 -
   58.47 -except TimeoutError, e:
   58.48 -    saveLog(consoleHistory)
   58.49 -    vtpm_cleanup(domName)
   58.50 -    FAIL(str(e))
   58.51 +loop = 0
   58.52 +while loop < 3:
   58.53 +    try:
   58.54 +        status, ouptut = traceCommand("xm save %s %s.save" %
   58.55 +                                      (domName, domName),
   58.56 +                                      timeout=30)
   58.57  
   58.58 -if status != 0:
   58.59 -    saveLog(consoleHistory)
   58.60 -    vtpm_cleanup(domName)
   58.61 -    FAIL("xm save did not succeed")
   58.62 +    except TimeoutError, e:
   58.63 +        saveLog(consoleHistory)
   58.64 +        vtpm_cleanup(domName)
   58.65 +        FAIL(str(e))
   58.66  
   58.67 -try:
   58.68 -    status, ouptut = traceCommand("xm restore %s.save" %
   58.69 -                                  (domName),
   58.70 -                                  timeout=30)
   58.71 -except TimeoutError, e:
   58.72 +    if status != 0:
   58.73 +        saveLog(consoleHistory)
   58.74 +        vtpm_cleanup(domName)
   58.75 +        FAIL("xm save did not succeed")
   58.76 +
   58.77 +    try:
   58.78 +        status, ouptut = traceCommand("xm restore %s.save" %
   58.79 +                                      (domName),
   58.80 +                                      timeout=30)
   58.81 +    except TimeoutError, e:
   58.82 +        os.remove("%s.save" % domName)
   58.83 +        saveLog(consoleHistory)
   58.84 +        vtpm_cleanup(domName)
   58.85 +        FAIL(str(e))
   58.86 +
   58.87      os.remove("%s.save" % domName)
   58.88 -    saveLog(consoleHistory)
   58.89 -    vtpm_cleanup(domName)
   58.90 -    FAIL(str(e))
   58.91 -
   58.92 -os.remove("%s.save" % domName)
   58.93 -
   58.94 -if status != 0:
   58.95 -    saveLog(consoleHistory)
   58.96 -    vtpm_cleanup(domName)
   58.97 -    FAIL("xm restore did not succeed")
   58.98  
   58.99 -try:
  58.100 -    console = domain.getConsole()
  58.101 -except ConsoleError, e:
  58.102 -    vtpm_cleanup(domName)
  58.103 -    FAIL(str(e))
  58.104 +    if status != 0:
  58.105 +        saveLog(consoleHistory)
  58.106 +        vtpm_cleanup(domName)
  58.107 +        FAIL("xm restore did not succeed")
  58.108  
  58.109 -try:
  58.110 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
  58.111 -except ConsoleError, e:
  58.112 -    saveLog(console.getHistory())
  58.113 -    vtpm_cleanup(domName)
  58.114 -    FAIL(str(e))
  58.115 +    try:
  58.116 +        console = domain.getConsole()
  58.117 +    except ConsoleError, e:
  58.118 +        vtpm_cleanup(domName)
  58.119 +        FAIL(str(e))
  58.120 +
  58.121 +    try:
  58.122 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  58.123 +    except ConsoleError, e:
  58.124 +        saveLog(console.getHistory())
  58.125 +        vtpm_cleanup(domName)
  58.126 +        FAIL(str(e))
  58.127 +
  58.128 +    if not re.search("PCR-00:",run["output"]):
  58.129 +        saveLog(console.getHistory())
  58.130 +        vtpm_cleanup(domName)
  58.131 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  58.132 +
  58.133 +    loop += 1
  58.134  
  58.135  domain.closeConsole()
  58.136  
  58.137 @@ -99,5 +107,3 @@ domain.stop()
  58.138  
  58.139  vtpm_cleanup(domName)
  58.140  
  58.141 -if not re.search("PCR-00:",run["output"]):
  58.142 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    59.1 --- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py	Wed Jun 28 07:52:21 2006 -0600
    59.2 +++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py	Mon Jul 03 08:35:12 2006 +0100
    59.3 @@ -16,6 +16,7 @@ import os.path
    59.4  
    59.5  config = {"vtpm":"instance=1,backend=0"}
    59.6  domain = XmTestDomain(extraConfig=config)
    59.7 +domName = domain.getName()
    59.8  consoleHistory = ""
    59.9  
   59.10  try:
   59.11 @@ -23,10 +24,8 @@ try:
   59.12  except DomainError, e:
   59.13      if verbose:
   59.14          print e.extra
   59.15 -    vtpm_cleanup(domain.getName())
   59.16 -    FAIL("Unable to create domain")
   59.17 -
   59.18 -domName = domain.getName()
   59.19 +    vtpm_cleanup(domName)
   59.20 +    FAIL("Unable to create domain (%s)" % domName)
   59.21  
   59.22  try:
   59.23      console.sendInput("input")
   59.24 @@ -36,11 +35,11 @@ except ConsoleError, e:
   59.25      FAIL(str(e))
   59.26  
   59.27  try:
   59.28 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   59.29 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   59.30  except ConsoleError, e:
   59.31      saveLog(console.getHistory())
   59.32      vtpm_cleanup(domName)
   59.33 -    FAIL(str(e))
   59.34 +    FAIL("No result from dumping the PCRs")
   59.35  
   59.36  if re.search("No such file",run["output"]):
   59.37      vtpm_cleanup(domName)
   59.38 @@ -83,11 +82,17 @@ while loop < 3:
   59.39          FAIL(str(e))
   59.40  
   59.41      try:
   59.42 -        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   59.43 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   59.44      except ConsoleError, e:
   59.45          saveLog(console.getHistory())
   59.46          vtpm_cleanup(domName)
   59.47 -        FAIL(str(e))
   59.48 +        FAIL("No result from dumping the PCRs")
   59.49 +
   59.50 +    if not re.search("PCR-00:",run["output"]):
   59.51 +        saveLog(console.getHistory())
   59.52 +        vtpm_cleanup(domName)
   59.53 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
   59.54 +
   59.55      loop += 1
   59.56  
   59.57  domain.closeConsole()
   59.58 @@ -95,6 +100,3 @@ domain.closeConsole()
   59.59  domain.stop()
   59.60  
   59.61  vtpm_cleanup(domName)
   59.62 -
   59.63 -if not re.search("PCR-00:",run["output"]):
   59.64 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    60.1 --- a/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py	Wed Jun 28 07:52:21 2006 -0600
    60.2 +++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py	Mon Jul 03 08:35:12 2006 +0100
    60.3 @@ -16,6 +16,7 @@ import os.path
    60.4  
    60.5  config = {"vtpm":"instance=1,backend=0"}
    60.6  domain = XmTestDomain(extraConfig=config)
    60.7 +domName = domain.getName()
    60.8  consoleHistory = ""
    60.9  
   60.10  try:
   60.11 @@ -23,10 +24,8 @@ try:
   60.12  except DomainError, e:
   60.13      if verbose:
   60.14          print e.extra
   60.15 -    vtpm_cleanup(domain.getName())
   60.16 -    FAIL("Unable to create domain")
   60.17 -
   60.18 -domName = domain.getName()
   60.19 +    vtpm_cleanup(domName)
   60.20 +    FAIL("Unable to create domain (%s)" % domName)
   60.21  
   60.22  try:
   60.23      console.sendInput("input")
   60.24 @@ -36,11 +35,11 @@ except ConsoleError, e:
   60.25      FAIL(str(e))
   60.26  
   60.27  try:
   60.28 -    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   60.29 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   60.30  except ConsoleError, e:
   60.31      saveLog(console.getHistory())
   60.32      vtpm_cleanup(domName)
   60.33 -    FAIL(str(e))
   60.34 +    FAIL("No result from dumping the PCRs")
   60.35  
   60.36  if re.search("No such file",run["output"]):
   60.37      vtpm_cleanup(domName)
   60.38 @@ -83,11 +82,17 @@ while loop < 3:
   60.39          FAIL(str(e))
   60.40  
   60.41      try:
   60.42 -        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
   60.43 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   60.44      except ConsoleError, e:
   60.45          saveLog(console.getHistory())
   60.46          vtpm_cleanup(domName)
   60.47 -        FAIL(str(e))
   60.48 +        FAIL("No result from dumping the PCRs")
   60.49 +
   60.50 +    if not re.search("PCR-00:",run["output"]):
   60.51 +        saveLog(console.getHistory())
   60.52 +        vtpm_cleanup(domName)
   60.53 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
   60.54 +
   60.55      loop += 1
   60.56  
   60.57  domain.closeConsole()
   60.58 @@ -95,6 +100,3 @@ domain.closeConsole()
   60.59  domain.stop()
   60.60  
   60.61  vtpm_cleanup(domName)
   60.62 -
   60.63 -if not re.search("PCR-00:",run["output"]):
   60.64 -	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py	Mon Jul 03 08:35:12 2006 +0100
    61.3 @@ -0,0 +1,139 @@
    61.4 +#!/usr/bin/python
    61.5 +
    61.6 +# Copyright (C) International Business Machines Corp., 2006
    61.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    61.8 +
    61.9 +# Positive Test: create domain with virtual TPM attached at build time,
   61.10 +#                extend a pcr
   61.11 +#                check list of pcrs; suspend and resume the domain and
   61.12 +#                check list of pcrs again and validate extended pcr
   61.13 +
   61.14 +from XmTestLib import *
   61.15 +from vtpm_utils import *
   61.16 +import commands
   61.17 +import os
   61.18 +import os.path
   61.19 +
   61.20 +config = {"vtpm":"instance=1,backend=0"}
   61.21 +domain = XmTestDomain(extraConfig=config)
   61.22 +domName = domain.getName()
   61.23 +consoleHistory = ""
   61.24 +
   61.25 +try:
   61.26 +    console = domain.start()
   61.27 +except DomainError, e:
   61.28 +    if verbose:
   61.29 +        print e.extra
   61.30 +    vtpm_cleanup(domName)
   61.31 +    FAIL("Unable to create domain (%s)" % domName)
   61.32 +
   61.33 +try:
   61.34 +    console.sendInput("input")
   61.35 +except ConsoleError, e:
   61.36 +    saveLog(console.getHistory())
   61.37 +    vtpm_cleanup(domName)
   61.38 +    FAIL(str(e))
   61.39 +
   61.40 +try:
   61.41 +    run = console.runCmd("mknod /dev/tpm0 c 10 224")
   61.42 +except ConsoleError, e:
   61.43 +    saveLog(console.getHistory())
   61.44 +    vtpm_cleanup(domName)
   61.45 +    FAIL("Error while creating /dev/tpm0")
   61.46 +
   61.47 +try:
   61.48 +    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")
   61.49 +except ConsoleError, e:
   61.50 +    saveLog(console.getHistory())
   61.51 +    vtpm_cleanup(domName)
   61.52 +    FAIL("Error while extending PCR 0")
   61.53 +
   61.54 +try:
   61.55 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   61.56 +except ConsoleError, e:
   61.57 +    saveLog(console.getHistory())
   61.58 +    vtpm_cleanup(domName)
   61.59 +    FAIL("No result from dumping the PCRs")
   61.60 +
   61.61 +
   61.62 +if re.search("No such file",run["output"]):
   61.63 +    vtpm_cleanup(domName)
   61.64 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
   61.65 +
   61.66 +if not re.search("PCR-00:",run["output"]):
   61.67 +    saveLog(console.getHistory())
   61.68 +    vtpm_cleanup(domName)
   61.69 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
   61.70 +
   61.71 +if not re.search("PCR-00: 1E A7 BD",run["output"]):
   61.72 +    saveLog(console.getHistory())
   61.73 +    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
   61.74 +
   61.75 +consoleHistory = console.getHistory()
   61.76 +domain.closeConsole()
   61.77 +
   61.78 +loop = 0
   61.79 +while loop < 3:
   61.80 +    try:
   61.81 +        status, ouptut = traceCommand("xm save %s %s.save" %
   61.82 +                                      (domName, domName),
   61.83 +                                      timeout=30)
   61.84 +
   61.85 +    except TimeoutError, e:
   61.86 +        saveLog(consoleHistory)
   61.87 +        vtpm_cleanup(domName)
   61.88 +        FAIL(str(e))
   61.89 +
   61.90 +    if status != 0:
   61.91 +        saveLog(consoleHistory)
   61.92 +        vtpm_cleanup(domName)
   61.93 +        FAIL("xm save did not succeed")
   61.94 +
   61.95 +    try:
   61.96 +        status, ouptut = traceCommand("xm restore %s.save" %
   61.97 +                                      (domName),
   61.98 +                                      timeout=30)
   61.99 +    except TimeoutError, e:
  61.100 +        os.remove("%s.save" % domName)
  61.101 +        saveLog(consoleHistory)
  61.102 +        vtpm_cleanup(domName)
  61.103 +        FAIL(str(e))
  61.104 +
  61.105 +    os.remove("%s.save" % domName)
  61.106 +
  61.107 +    if status != 0:
  61.108 +        saveLog(consoleHistory)
  61.109 +        vtpm_cleanup(domName)
  61.110 +        FAIL("xm restore did not succeed")
  61.111 +
  61.112 +    try:
  61.113 +        console = domain.getConsole()
  61.114 +    except ConsoleError, e:
  61.115 +        vtpm_cleanup(domName)
  61.116 +        FAIL(str(e))
  61.117 +
  61.118 +    try:
  61.119 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  61.120 +    except ConsoleError, e:
  61.121 +        saveLog(console.getHistory())
  61.122 +        vtpm_cleanup(domName)
  61.123 +        FAIL(str(e))
  61.124 +
  61.125 +    if not re.search("PCR-00:",run["output"]):
  61.126 +        saveLog(console.getHistory())
  61.127 +        vtpm_cleanup(domName)
  61.128 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  61.129 +
  61.130 +    if not re.search("PCR-00: 1E A7 BD",run["output"]):
  61.131 +        saveLog(console.getHistory())
  61.132 +        vtpm_cleanup(domName)
  61.133 +	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
  61.134 +
  61.135 +    loop += 1
  61.136 +
  61.137 +domain.closeConsole()
  61.138 +
  61.139 +domain.stop()
  61.140 +
  61.141 +vtpm_cleanup(domName)
  61.142 +
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py	Mon Jul 03 08:35:12 2006 +0100
    62.3 @@ -0,0 +1,132 @@
    62.4 +#!/usr/bin/python
    62.5 +
    62.6 +# Copyright (C) International Business Machines Corp., 2006
    62.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    62.8 +
    62.9 +# Positive Test: create domain with virtual TPM attached at build time,
   62.10 +#                extend a pcr
   62.11 +#                check list of pcrs; locally migrate the domain and
   62.12 +#                check list of pcrs again and validate extended pcr
   62.13 +#                This test does local live migration.
   62.14 +
   62.15 +from XmTestLib import *
   62.16 +from vtpm_utils import *
   62.17 +import commands
   62.18 +import os
   62.19 +import os.path
   62.20 +
   62.21 +config = {"vtpm":"instance=1,backend=0"}
   62.22 +domain = XmTestDomain(extraConfig=config)
   62.23 +domName = domain.getName()
   62.24 +consoleHistory = ""
   62.25 +
   62.26 +try:
   62.27 +    console = domain.start()
   62.28 +except DomainError, e:
   62.29 +    if verbose:
   62.30 +        print e.extra
   62.31 +    vtpm_cleanup(domName)
   62.32 +    FAIL("Unable to create domain (%s)" % domName)
   62.33 +
   62.34 +try:
   62.35 +    console.sendInput("input")
   62.36 +except ConsoleError, e:
   62.37 +    saveLog(console.getHistory())
   62.38 +    vtpm_cleanup(domName)
   62.39 +    FAIL(str(e))
   62.40 +
   62.41 +try:
   62.42 +    run = console.runCmd("mknod /dev/tpm0 c 10 224")
   62.43 +except ConsoleError, e:
   62.44 +    saveLog(console.getHistory())
   62.45 +    vtpm_cleanup(domName)
   62.46 +    FAIL("Error while creating /dev/tpm0")
   62.47 +
   62.48 +try:
   62.49 +    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")
   62.50 +except ConsoleError, e:
   62.51 +    saveLog(console.getHistory())
   62.52 +    vtpm_cleanup(domName)
   62.53 +    FAIL("Error while extending PCR 0")
   62.54 +
   62.55 +try:
   62.56 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   62.57 +except ConsoleError, e:
   62.58 +    saveLog(console.getHistory())
   62.59 +    vtpm_cleanup(domName)
   62.60 +    FAIL("No result from dumping the PCRs")
   62.61 +
   62.62 +
   62.63 +if re.search("No such file",run["output"]):
   62.64 +    vtpm_cleanup(domName)
   62.65 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
   62.66 +
   62.67 +if not re.search("PCR-00:",run["output"]):
   62.68 +    saveLog(console.getHistory())
   62.69 +    vtpm_cleanup(domName)
   62.70 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
   62.71 +
   62.72 +if not re.search("PCR-00: 1E A7 BD",run["output"]):
   62.73 +    saveLog(console.getHistory())
   62.74 +    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
   62.75 +
   62.76 +consoleHistory = console.getHistory()
   62.77 +domain.closeConsole()
   62.78 +
   62.79 +old_domid = domid(domName)
   62.80 +
   62.81 +loop = 0
   62.82 +while loop < 3:
   62.83 +    try:
   62.84 +        status, ouptut = traceCommand("xm migrate -l %s localhost" %
   62.85 +                                      domName,
   62.86 +                                      timeout=90)
   62.87 +    except TimeoutError, e:
   62.88 +        saveLog(consoleHistory)
   62.89 +        vtpm_cleanup(domName)
   62.90 +        FAIL(str(e))
   62.91 +
   62.92 +    if status != 0:
   62.93 +        saveLog(consoleHistory)
   62.94 +        vtpm_cleanup(domName)
   62.95 +        FAIL("xm migrate did not succeed. External device migration activated?")
   62.96 +
   62.97 +
   62.98 +    domName = domain.getName()
   62.99 +    new_domid = domid(domName)
  62.100 +
  62.101 +    if (old_domid == new_domid):
  62.102 +        vtpm_cleanup(domName)
  62.103 +        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
  62.104 +             (old_domid,loop))
  62.105 +
  62.106 +    try:
  62.107 +        console = domain.getConsole()
  62.108 +    except ConsoleError, e:
  62.109 +        vtpm_cleanup(domName)
  62.110 +        FAIL(str(e))
  62.111 +
  62.112 +    try:
  62.113 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  62.114 +    except ConsoleError, e:
  62.115 +        saveLog(console.getHistory())
  62.116 +        vtpm_cleanup(domName)
  62.117 +        FAIL("No result from dumping the PCRs")
  62.118 +
  62.119 +    if not re.search("PCR-00:",run["output"]):
  62.120 +        saveLog(console.getHistory())
  62.121 +        vtpm_cleanup(domName)
  62.122 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  62.123 +
  62.124 +    if not re.search("PCR-00: 1E A7 BD",run["output"]):
  62.125 +        saveLog(console.getHistory())
  62.126 +        vtpm_cleanup(domName)
  62.127 +	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
  62.128 +
  62.129 +    loop += 1
  62.130 +
  62.131 +domain.closeConsole()
  62.132 +
  62.133 +domain.stop()
  62.134 +
  62.135 +vtpm_cleanup(domName)
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py	Mon Jul 03 08:35:12 2006 +0100
    63.3 @@ -0,0 +1,132 @@
    63.4 +#!/usr/bin/python
    63.5 +
    63.6 +# Copyright (C) International Business Machines Corp., 2006
    63.7 +# Author: Stefan Berger <stefanb@us.ibm.com>
    63.8 +
    63.9 +# Positive Test: create domain with virtual TPM attached at build time,
   63.10 +#                extend a pcr
   63.11 +#                check list of pcrs; locally migrate the domain and
   63.12 +#                check list of pcrs again and validate extended pcr
   63.13 +#                This test does local (non-live) migration.
   63.14 +
   63.15 +from XmTestLib import *
   63.16 +from vtpm_utils import *
   63.17 +import commands
   63.18 +import os
   63.19 +import os.path
   63.20 +
   63.21 +config = {"vtpm":"instance=1,backend=0"}
   63.22 +domain = XmTestDomain(extraConfig=config)
   63.23 +domName = domain.getName()
   63.24 +consoleHistory = ""
   63.25 +
   63.26 +try:
   63.27 +    console = domain.start()
   63.28 +except DomainError, e:
   63.29 +    if verbose:
   63.30 +        print e.extra
   63.31 +    vtpm_cleanup(domName)
   63.32 +    FAIL("Unable to create domain (%s)" % domName)
   63.33 +
   63.34 +try:
   63.35 +    console.sendInput("input")
   63.36 +except ConsoleError, e:
   63.37 +    saveLog(console.getHistory())
   63.38 +    vtpm_cleanup(domName)
   63.39 +    FAIL(str(e))
   63.40 +
   63.41 +try:
   63.42 +    run = console.runCmd("mknod /dev/tpm0 c 10 224")
   63.43 +except ConsoleError, e:
   63.44 +    saveLog(console.getHistory())
   63.45 +    vtpm_cleanup(domName)
   63.46 +    FAIL("Error while creating /dev/tpm0")
   63.47 +
   63.48 +try:
   63.49 +    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")
   63.50 +except ConsoleError, e:
   63.51 +    saveLog(console.getHistory())
   63.52 +    vtpm_cleanup(domName)
   63.53 +    FAIL("Error while extending PCR 0")
   63.54 +
   63.55 +try:
   63.56 +    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
   63.57 +except ConsoleError, e:
   63.58 +    saveLog(console.getHistory())
   63.59 +    vtpm_cleanup(domName)
   63.60 +    FAIL("No result from dumping the PCRs")
   63.61 +
   63.62 +
   63.63 +if re.search("No such file",run["output"]):
   63.64 +    vtpm_cleanup(domName)
   63.65 +    FAIL("TPM frontend support not compiled into (domU?) kernel")
   63.66 +
   63.67 +if not re.search("PCR-00:",run["output"]):
   63.68 +    saveLog(console.getHistory())
   63.69 +    vtpm_cleanup(domName)
   63.70 +    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
   63.71 +
   63.72 +if not re.search("PCR-00: 1E A7 BD",run["output"]):
   63.73 +    saveLog(console.getHistory())
   63.74 +    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
   63.75 +
   63.76 +consoleHistory = console.getHistory()
   63.77 +domain.closeConsole()
   63.78 +
   63.79 +old_domid = domid(domName)
   63.80 +
   63.81 +loop = 0
   63.82 +while loop < 3:
   63.83 +    try:
   63.84 +        status, ouptut = traceCommand("xm migrate %s localhost" %
   63.85 +                                      domName,
   63.86 +                                      timeout=90)
   63.87 +    except TimeoutError, e:
   63.88 +        saveLog(consoleHistory)
   63.89 +        vtpm_cleanup(domName)
   63.90 +        FAIL(str(e))
   63.91 +
   63.92 +    if status != 0:
   63.93 +        saveLog(consoleHistory)
   63.94 +        vtpm_cleanup(domName)
   63.95 +        FAIL("xm migrate did not succeed. External device migration activated?")
   63.96 +
   63.97 +
   63.98 +    domName = domain.getName()
   63.99 +    new_domid = domid(domName)
  63.100 +
  63.101 +    if (old_domid == new_domid):
  63.102 +        vtpm_cleanup(domName)
  63.103 +        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
  63.104 +             (old_domid,loop))
  63.105 +
  63.106 +    try:
  63.107 +        console = domain.getConsole()
  63.108 +    except ConsoleError, e:
  63.109 +        vtpm_cleanup(domName)
  63.110 +        FAIL(str(e))
  63.111 +
  63.112 +    try:
  63.113 +        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
  63.114 +    except ConsoleError, e:
  63.115 +        saveLog(console.getHistory())
  63.116 +        vtpm_cleanup(domName)
  63.117 +        FAIL("No result from dumping the PCRs")
  63.118 +
  63.119 +    if not re.search("PCR-00:",run["output"]):
  63.120 +        saveLog(console.getHistory())
  63.121 +        vtpm_cleanup(domName)
  63.122 +	FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
  63.123 +
  63.124 +    if not re.search("PCR-00: 1E A7 BD",run["output"]):
  63.125 +        saveLog(console.getHistory())
  63.126 +        vtpm_cleanup(domName)
  63.127 +	FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
  63.128 +
  63.129 +    loop += 1
  63.130 +
  63.131 +domain.closeConsole()
  63.132 +
  63.133 +domain.stop()
  63.134 +
  63.135 +vtpm_cleanup(domName)
    64.1 --- a/tools/xm-test/tests/vtpm/Makefile.am	Wed Jun 28 07:52:21 2006 -0600
    64.2 +++ b/tools/xm-test/tests/vtpm/Makefile.am	Mon Jul 03 08:35:12 2006 +0100
    64.3 @@ -4,7 +4,10 @@ TESTS = 01_vtpm-list_pos.test \
    64.4          02_vtpm-cat_pcrs.test \
    64.5          03_vtpm-susp_res.test \
    64.6          04_vtpm-loc_migr.test \
    64.7 -        05_vtpm-loc_migr.test
    64.8 +        05_vtpm-loc_migr.test \
    64.9 +        06_vtpm-susp_res_pcrs.test \
   64.10 +        07_vtpm-mig_pcrs.test \
   64.11 +        08_vtpm-mig_pcrs.test
   64.12  
   64.13  XFAIL_TESTS =
   64.14  
    65.1 --- a/tools/xm-test/tests/vtpm/vtpm_utils.py	Wed Jun 28 07:52:21 2006 -0600
    65.2 +++ b/tools/xm-test/tests/vtpm/vtpm_utils.py	Mon Jul 03 08:35:12 2006 +0100
    65.3 @@ -16,4 +16,4 @@ if output == "":
    65.4      FAIL("virtual TPM manager must be started to run this test")
    65.5  
    65.6  def vtpm_cleanup(domName):
    65.7 -	traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
    65.8 +    traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
    66.1 --- a/xen/arch/x86/domain.c	Wed Jun 28 07:52:21 2006 -0600
    66.2 +++ b/xen/arch/x86/domain.c	Mon Jul 03 08:35:12 2006 +0100
    66.3 @@ -67,16 +67,11 @@ static void default_idle(void)
    66.4  
    66.5  void idle_loop(void)
    66.6  {
    66.7 -    int cpu = smp_processor_id();
    66.8 -
    66.9      for ( ; ; )
   66.10      {
   66.11          page_scrub_schedule_work();
   66.12 -
   66.13          default_idle();
   66.14 -
   66.15 -        if ( softirq_pending(cpu) )
   66.16 -            do_softirq();
   66.17 +        do_softirq();
   66.18      }
   66.19  }
   66.20  
    67.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Jun 28 07:52:21 2006 -0600
    67.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Jul 03 08:35:12 2006 +0100
    67.3 @@ -2697,9 +2697,9 @@ asmlinkage void svm_vmexit_handler(struc
    67.4  
    67.5      if (exit_reason == -1)
    67.6      {
    67.7 +        svm_dump_vmcb(__func__, vmcb);
    67.8          printk("%s: exit_reason == -1 - Did someone clobber the VMCB\n", 
    67.9                  __func__);
   67.10 -        BUG();
   67.11          domain_crash_synchronous();
   67.12      }
   67.13  
    68.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Wed Jun 28 07:52:21 2006 -0600
    68.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Mon Jul 03 08:35:12 2006 +0100
    68.3 @@ -36,6 +36,7 @@
    68.4  #include <xen/kernel.h>
    68.5  #include <asm/shadow.h>
    68.6  #include <xen/keyhandler.h>
    68.7 +
    68.8  #if CONFIG_PAGING_LEVELS >= 3
    68.9  #include <asm/shadow_64.h>
   68.10  #endif
   68.11 @@ -440,7 +441,6 @@ static int construct_vmcs(struct vcpu *v
   68.12      memset(arch_vmx, 0, sizeof(struct arch_vmx_struct));
   68.13  
   68.14      spin_lock_init(&arch_vmx->vmcs_lock);
   68.15 -    arch_vmx->active_cpu = -1;
   68.16  
   68.17      /*
   68.18       * Create a new VMCS
   68.19 @@ -450,7 +450,7 @@ static int construct_vmcs(struct vcpu *v
   68.20          return -ENOMEM;
   68.21      }
   68.22  
   68.23 -    vmx_clear_vmcs(v);
   68.24 +    __vmx_clear_vmcs(v);
   68.25      vmx_load_vmcs(v);
   68.26  
   68.27      if ((error = construct_vmcs_controls(arch_vmx))) {
   68.28 @@ -496,6 +496,9 @@ void vmx_destroy_vmcs(struct vcpu *v)
   68.29  {
   68.30      struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
   68.31  
   68.32 +    if ( arch_vmx->vmcs == NULL )
   68.33 +        return;
   68.34 +
   68.35      vmx_clear_vmcs(v);
   68.36  
   68.37      free_vmcs(arch_vmx->vmcs);
    69.1 --- a/xen/arch/x86/smpboot.c	Wed Jun 28 07:52:21 2006 -0600
    69.2 +++ b/xen/arch/x86/smpboot.c	Mon Jul 03 08:35:12 2006 +0100
    69.3 @@ -1197,8 +1197,7 @@ int __devinit __cpu_up(unsigned int cpu)
    69.4  	cpu_set(cpu, smp_commenced_mask);
    69.5  	while (!cpu_isset(cpu, cpu_online_map)) {
    69.6  		mb();
    69.7 -		if (softirq_pending(0))
    69.8 -			do_softirq();
    69.9 +		process_pending_timers();
   69.10  	}
   69.11  	return 0;
   69.12  }
    70.1 --- a/xen/arch/x86/x86_emulate.c	Wed Jun 28 07:52:21 2006 -0600
    70.2 +++ b/xen/arch/x86/x86_emulate.c	Mon Jul 03 08:35:12 2006 +0100
    70.3 @@ -118,7 +118,7 @@ static uint8_t opcode_table[256] = {
    70.4      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    70.5      /* 0xC0 - 0xC7 */
    70.6      ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
    70.7 -    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
    70.8 +    0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
    70.9      /* 0xC8 - 0xCF */
   70.10      0, 0, 0, 0, 0, 0, 0, 0,
   70.11      /* 0xD0 - 0xD7 */
    71.1 --- a/xen/common/elf.c	Wed Jun 28 07:52:21 2006 -0600
    71.2 +++ b/xen/common/elf.c	Mon Jul 03 08:35:12 2006 +0100
    71.3 @@ -23,7 +23,7 @@ int parseelfimage(struct domain_setup_in
    71.4      Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
    71.5      Elf_Phdr *phdr;
    71.6      Elf_Shdr *shdr;
    71.7 -    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
    71.8 +    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
    71.9      char *shstrtab, *guestinfo=NULL, *p;
   71.10      char *elfbase = (char *)dsi->image_addr;
   71.11      int h, virt_base_defined, elf_pa_off_defined;
   71.12 @@ -95,7 +95,11 @@ int parseelfimage(struct domain_setup_in
   71.13      elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
   71.14  
   71.15      if ( elf_pa_off_defined && !virt_base_defined )
   71.16 -        goto bad_image;
   71.17 +    {
   71.18 +        printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in"
   71.19 +               " __xen_guest section.\n");
   71.20 +        return -EINVAL;
   71.21 +    }
   71.22  
   71.23      for ( h = 0; h < ehdr->e_phnum; h++ )
   71.24      {
   71.25 @@ -104,7 +108,11 @@ int parseelfimage(struct domain_setup_in
   71.26              continue;
   71.27          vaddr = phdr->p_paddr - elf_pa_off + virt_base;
   71.28          if ( (vaddr + phdr->p_memsz) < vaddr )
   71.29 -            goto bad_image;
   71.30 +        {
   71.31 +            printk("ERROR: ELF program header %d is too large.\n", h);
   71.32 +            return -EINVAL;
   71.33 +        }
   71.34 +
   71.35          if ( vaddr < kernstart )
   71.36              kernstart = vaddr;
   71.37          if ( (vaddr + phdr->p_memsz) > kernend )
   71.38 @@ -127,7 +135,10 @@ int parseelfimage(struct domain_setup_in
   71.39           (dsi->v_kernentry < kernstart) ||
   71.40           (dsi->v_kernentry > kernend) ||
   71.41           (dsi->v_start > kernstart) )
   71.42 -        goto bad_image;
   71.43 +    {
   71.44 +        printk("ERROR: ELF start or entries are out of bounds.\n");
   71.45 +        return -EINVAL;
   71.46 +    }
   71.47  
   71.48      if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   71.49              dsi->load_symtab = 1;
   71.50 @@ -139,10 +150,6 @@ int parseelfimage(struct domain_setup_in
   71.51      loadelfsymtab(dsi, 0);
   71.52  
   71.53      return 0;
   71.54 -
   71.55 - bad_image:
   71.56 -    printk("Malformed ELF image.\n");
   71.57 -    return -EINVAL;
   71.58  }
   71.59  
   71.60  int loadelfimage(struct domain_setup_info *dsi)
    72.1 --- a/xen/common/grant_table.c	Wed Jun 28 07:52:21 2006 -0600
    72.2 +++ b/xen/common/grant_table.c	Mon Jul 03 08:35:12 2006 +0100
    72.3 @@ -287,10 +287,10 @@ static void
    72.4  
    72.5      if ( !(op->flags & GNTMAP_readonly) &&
    72.6           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
    72.7 -        clear_bit(_GTF_writing, &sha->flags);
    72.8 +        gnttab_clear_flag(_GTF_writing, &sha->flags);
    72.9  
   72.10      if ( !act->pin )
   72.11 -        clear_bit(_GTF_reading, &sha->flags);
   72.12 +        gnttab_clear_flag(_GTF_reading, &sha->flags);
   72.13  
   72.14   unlock_out:
   72.15      spin_unlock(&rd->grant_table->lock);
   72.16 @@ -425,10 +425,10 @@ static void
   72.17  
   72.18      if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
   72.19           !(flags & GNTMAP_readonly) )
   72.20 -        clear_bit(_GTF_writing, &sha->flags);
   72.21 +        gnttab_clear_flag(_GTF_writing, &sha->flags);
   72.22  
   72.23      if ( act->pin == 0 )
   72.24 -        clear_bit(_GTF_reading, &sha->flags);
   72.25 +        gnttab_clear_flag(_GTF_reading, &sha->flags);
   72.26  
   72.27   unmap_out:
   72.28      op->status = rc;
   72.29 @@ -889,11 +889,11 @@ gnttab_release_mappings(
   72.30              }
   72.31  
   72.32              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
   72.33 -                clear_bit(_GTF_writing, &sha->flags);
   72.34 +                gnttab_clear_flag(_GTF_writing, &sha->flags);
   72.35          }
   72.36  
   72.37          if ( act->pin == 0 )
   72.38 -            clear_bit(_GTF_reading, &sha->flags);
   72.39 +            gnttab_clear_flag(_GTF_reading, &sha->flags);
   72.40  
   72.41          spin_unlock(&rd->grant_table->lock);
   72.42  
    73.1 --- a/xen/common/memory.c	Wed Jun 28 07:52:21 2006 -0600
    73.2 +++ b/xen/common/memory.c	Mon Jul 03 08:35:12 2006 +0100
    73.3 @@ -170,6 +170,15 @@ guest_remove_page(
    73.4      if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
    73.5          put_page(page);
    73.6  
    73.7 +    if ( unlikely((page->count_info & PGC_count_mask) != 1) )
    73.8 +    {
    73.9 +        /* We'll make this a guest-visible error in future, so take heed! */
   73.10 +        DPRINTK("Dom%d freeing in-use page %lx (pseudophys %lx):"
   73.11 +                " count=%x type=%lx\n",
   73.12 +                d->domain_id, mfn, get_gpfn_from_mfn(mfn),
   73.13 +                page->count_info, page->u.inuse.type_info);
   73.14 +    }
   73.15 +
   73.16      guest_physmap_remove_page(d, gmfn, mfn);
   73.17  
   73.18      put_page(page);
    74.1 --- a/xen/common/page_alloc.c	Wed Jun 28 07:52:21 2006 -0600
    74.2 +++ b/xen/common/page_alloc.c	Mon Jul 03 08:35:12 2006 +0100
    74.3 @@ -388,7 +388,6 @@ void scrub_heap_pages(void)
    74.4  {
    74.5      void *p;
    74.6      unsigned long pfn;
    74.7 -    int cpu = smp_processor_id();
    74.8  
    74.9      printk("Scrubbing Free RAM: ");
   74.10  
   74.11 @@ -398,8 +397,7 @@ void scrub_heap_pages(void)
   74.12          if ( (pfn % ((100*1024*1024)/PAGE_SIZE)) == 0 )
   74.13              printk(".");
   74.14  
   74.15 -        if ( unlikely(softirq_pending(cpu)) )
   74.16 -            do_softirq();
   74.17 +        process_pending_timers();
   74.18  
   74.19          /* Quick lock-free check. */
   74.20          if ( allocated_in_map(pfn) )
    75.1 --- a/xen/common/sched_credit.c	Wed Jun 28 07:52:21 2006 -0600
    75.2 +++ b/xen/common/sched_credit.c	Mon Jul 03 08:35:12 2006 +0100
    75.3 @@ -622,9 +622,12 @@ csched_dom_cntl(
    75.4  
    75.5          if ( cmd->u.credit.weight != 0 )
    75.6          {
    75.7 -            csched_priv.weight -= sdom->weight;
    75.8 +            if ( !list_empty(&sdom->active_sdom_elem) )
    75.9 +            {
   75.10 +                csched_priv.weight -= sdom->weight;
   75.11 +                csched_priv.weight += cmd->u.credit.weight;
   75.12 +            }
   75.13              sdom->weight = cmd->u.credit.weight;
   75.14 -            csched_priv.weight += sdom->weight;
   75.15          }
   75.16  
   75.17          if ( cmd->u.credit.cap != (uint16_t)~0U )
    76.1 --- a/xen/common/schedule.c	Wed Jun 28 07:52:21 2006 -0600
    76.2 +++ b/xen/common/schedule.c	Mon Jul 03 08:35:12 2006 +0100
    76.3 @@ -389,11 +389,32 @@ long do_sched_op(int cmd, XEN_GUEST_HAND
    76.4  long do_set_timer_op(s_time_t timeout)
    76.5  {
    76.6      struct vcpu *v = current;
    76.7 +    s_time_t offset = timeout - NOW();
    76.8  
    76.9      if ( timeout == 0 )
   76.10 +    {
   76.11          stop_timer(&v->timer);
   76.12 +    }
   76.13 +    else if ( unlikely(timeout < 0) || /* overflow into 64th bit? */
   76.14 +              unlikely((offset > 0) && ((uint32_t)(offset >> 50) != 0)) )
   76.15 +    {
   76.16 +        /*
   76.17 +         * Linux workaround: occasionally we will see timeouts a long way in 
   76.18 +         * the future due to wrapping in Linux's jiffy time handling. We check 
   76.19 +         * for timeouts wrapped negative, and for positive timeouts more than 
   76.20 +         * about 13 days in the future (2^50ns). The correct fix is to trigger 
   76.21 +         * an interrupt immediately (since Linux in fact has pending work to 
   76.22 +         * do in this situation).
   76.23 +         */
   76.24 +        DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):"
   76.25 +                " %"PRIx64"\n",
   76.26 +                v->domain->domain_id, v->vcpu_id, (uint64_t)timeout);
   76.27 +        send_timer_event(v);
   76.28 +    }
   76.29      else
   76.30 +    {
   76.31          set_timer(&v->timer, timeout);
   76.32 +    }
   76.33  
   76.34      return 0;
   76.35  }
    77.1 --- a/xen/common/softirq.c	Wed Jun 28 07:52:21 2006 -0600
    77.2 +++ b/xen/common/softirq.c	Mon Jul 03 08:35:12 2006 +0100
    77.3 @@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[
    77.4  
    77.5  asmlinkage void do_softirq(void)
    77.6  {
    77.7 -    unsigned int i, cpu = smp_processor_id();
    77.8 +    unsigned int i, cpu;
    77.9      unsigned long pending;
   77.10  
   77.11 -    pending = softirq_pending(cpu);
   77.12 -    ASSERT(pending != 0);
   77.13 +    for ( ; ; )
   77.14 +    {
   77.15 +        /*
   77.16 +         * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
   77.17 +         * us to another processor.
   77.18 +         */
   77.19 +        cpu = smp_processor_id();
   77.20 +        if ( (pending = softirq_pending(cpu)) == 0 )
   77.21 +            break;
   77.22  
   77.23 -    do {
   77.24          i = find_first_set_bit(pending);
   77.25          clear_bit(i, &softirq_pending(cpu));
   77.26          (*softirq_handlers[i])();
   77.27 -    } while ( (pending = softirq_pending(cpu)) != 0 );
   77.28 +    }
   77.29  }
   77.30  
   77.31  void open_softirq(int nr, softirq_handler handler)
    78.1 --- a/xen/common/timer.c	Wed Jun 28 07:52:21 2006 -0600
    78.2 +++ b/xen/common/timer.c	Mon Jul 03 08:35:12 2006 +0100
    78.3 @@ -327,6 +327,15 @@ static void timer_softirq_action(void)
    78.4  }
    78.5  
    78.6  
    78.7 +void process_pending_timers(void)
    78.8 +{
    78.9 +    unsigned int cpu = smp_processor_id();
   78.10 +    ASSERT(!in_irq() && local_irq_is_enabled());
   78.11 +    if ( test_and_clear_bit(TIMER_SOFTIRQ, &softirq_pending(cpu)) )
   78.12 +        timer_softirq_action();
   78.13 +}
   78.14 +
   78.15 +
   78.16  static void dump_timerq(unsigned char key)
   78.17  {
   78.18      struct timer *t;
    79.1 --- a/xen/drivers/char/console.c	Wed Jun 28 07:52:21 2006 -0600
    79.2 +++ b/xen/drivers/char/console.c	Mon Jul 03 08:35:12 2006 +0100
    79.3 @@ -528,8 +528,7 @@ void console_endboot(void)
    79.4              printk("%d... ", 3-i);
    79.5              for ( j = 0; j < 100; j++ )
    79.6              {
    79.7 -                if ( softirq_pending(smp_processor_id()) )
    79.8 -                    do_softirq();
    79.9 +                process_pending_timers();
   79.10                  mdelay(10);
   79.11              }
   79.12          }
   79.13 @@ -741,6 +740,15 @@ void panic(const char *fmt, ...)
   79.14      machine_restart(0);
   79.15  }
   79.16  
   79.17 +void __bug(char *file, int line)
   79.18 +{
   79.19 +    console_start_sync();
   79.20 +    debugtrace_dump();
   79.21 +    printk("BUG at %s:%d\n", file, line);
   79.22 +    FORCE_CRASH();
   79.23 +    for ( ; ; ) ;
   79.24 +}
   79.25 +
   79.26  /*
   79.27   * Local variables:
   79.28   * mode: C
    80.1 --- a/xen/include/asm-ia64/grant_table.h	Wed Jun 28 07:52:21 2006 -0600
    80.2 +++ b/xen/include/asm-ia64/grant_table.h	Mon Jul 03 08:35:12 2006 +0100
    80.3 @@ -55,4 +55,9 @@ void guest_physmap_add_page(struct domai
    80.4  
    80.5  #define gnttab_log_dirty(d, f) ((void)0)
    80.6  
    80.7 +static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
    80.8 +{
    80.9 +	clear_bit(nr, addr);
   80.10 +}
   80.11 +
   80.12  #endif /* __ASM_GRANT_TABLE_H__ */
    81.1 --- a/xen/include/asm-x86/grant_table.h	Wed Jun 28 07:52:21 2006 -0600
    81.2 +++ b/xen/include/asm-x86/grant_table.h	Mon Jul 03 08:35:12 2006 +0100
    81.3 @@ -33,4 +33,9 @@ int destroy_grant_host_mapping(
    81.4  
    81.5  #define gnttab_log_dirty(d, f) mark_dirty((d), (f))
    81.6  
    81.7 +static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
    81.8 +{
    81.9 +	clear_bit(nr, addr);
   81.10 +}
   81.11 +
   81.12  #endif /* __ASM_GRANT_TABLE_H__ */
    82.1 --- a/xen/include/public/arch-ia64.h	Wed Jun 28 07:52:21 2006 -0600
    82.2 +++ b/xen/include/public/arch-ia64.h	Mon Jul 03 08:35:12 2006 +0100
    82.3 @@ -40,6 +40,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
    82.4  
    82.5  #ifndef __ASSEMBLY__
    82.6  
    82.7 +typedef unsigned long xen_ulong_t;
    82.8 +
    82.9  #define MAX_NR_SECTION  32  /* at most 32 memory holes */
   82.10  struct mm_section {
   82.11      unsigned long start;  /* start of memory hole */
    83.1 --- a/xen/include/public/arch-x86_32.h	Wed Jun 28 07:52:21 2006 -0600
    83.2 +++ b/xen/include/public/arch-x86_32.h	Mon Jul 03 08:35:12 2006 +0100
    83.3 @@ -98,6 +98,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
    83.4  
    83.5  #ifndef __ASSEMBLY__
    83.6  
    83.7 +typedef unsigned long xen_ulong_t;
    83.8 +
    83.9  /*
   83.10   * Send an array of these to HYPERVISOR_set_trap_table()
   83.11   */
    84.1 --- a/xen/include/public/arch-x86_64.h	Wed Jun 28 07:52:21 2006 -0600
    84.2 +++ b/xen/include/public/arch-x86_64.h	Mon Jul 03 08:35:12 2006 +0100
    84.3 @@ -105,6 +105,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
    84.4  
    84.5  #ifndef __ASSEMBLY__
    84.6  
    84.7 +typedef unsigned long xen_ulong_t;
    84.8 +
    84.9  /*
   84.10   * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
   84.11   *  @which == SEGBASE_*  ;  @base == 64-bit base address
    85.1 --- a/xen/include/public/io/netif.h	Wed Jun 28 07:52:21 2006 -0600
    85.2 +++ b/xen/include/public/io/netif.h	Mon Jul 03 08:35:12 2006 +0100
    85.3 @@ -23,8 +23,9 @@
    85.4   * This is the 'wire' format for packets:
    85.5   *  Request 1: netif_tx_request -- NETTXF_* (any flags)
    85.6   * [Request 2: netif_tx_extra]  (only if request 1 has NETTXF_extra_info)
    85.7 - *  Request 3: netif_tx_request -- NETTXF_more_data
    85.8 + * [Request 3: netif_tx_extra]  (only if request 2 has XEN_NETIF_EXTRA_MORE)
    85.9   *  Request 4: netif_tx_request -- NETTXF_more_data
   85.10 + *  Request 5: netif_tx_request -- NETTXF_more_data
   85.11   *  ...
   85.12   *  Request N: netif_tx_request -- 0
   85.13   */
   85.14 @@ -41,12 +42,9 @@
   85.15  #define _NETTXF_more_data      (2)
   85.16  #define  NETTXF_more_data      (1U<<_NETTXF_more_data)
   85.17  
   85.18 -/* Packet has GSO fields in the following descriptor (netif_tx_extra.u.gso). */
   85.19 -#define _NETTXF_gso            (3)
   85.20 -#define  NETTXF_gso            (1U<<_NETTXF_gso)
   85.21 -
   85.22 -/* This descriptor is followed by an extra-info descriptor (netif_tx_extra). */
   85.23 -#define  NETTXF_extra_info     (NETTXF_gso)
   85.24 +/* Packet to be followed by extra descriptor(s). */
   85.25 +#define _NETTXF_extra_info     (3)
   85.26 +#define  NETTXF_extra_info     (1U<<_NETTXF_extra_info)
   85.27  
   85.28  struct netif_tx_request {
   85.29      grant_ref_t gref;      /* Reference to buffer page */
   85.30 @@ -57,15 +55,42 @@ struct netif_tx_request {
   85.31  };
   85.32  typedef struct netif_tx_request netif_tx_request_t;
   85.33  
   85.34 -/* This structure needs to fit within netif_tx_request for compatibility. */
   85.35 -struct netif_tx_extra {
   85.36 +/* Types of netif_extra_info descriptors. */
   85.37 +#define XEN_NETIF_EXTRA_TYPE_NONE  (0)  /* Never used - invalid */
   85.38 +#define XEN_NETIF_EXTRA_TYPE_GSO   (1)  /* u.gso */
   85.39 +#define XEN_NETIF_EXTRA_TYPE_MAX   (2)
   85.40 +
   85.41 +/* netif_extra_info flags. */
   85.42 +#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
   85.43 +#define XEN_NETIF_EXTRA_FLAG_MORE  (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
   85.44 +
   85.45 +/* GSO types - only TCPv4 currently supported. */
   85.46 +#define XEN_NETIF_GSO_TCPV4        (1)
   85.47 +
   85.48 +/*
   85.49 + * This structure needs to fit within both netif_tx_request and
   85.50 + * netif_rx_response for compatibility.
   85.51 + */
   85.52 +struct netif_extra_info {
   85.53 +    uint8_t type;  /* XEN_NETIF_EXTRA_TYPE_* */
   85.54 +    uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
   85.55 +
   85.56      union {
   85.57 -        /* NETTXF_gso: Generic Segmentation Offload. */
   85.58 -        struct netif_tx_gso {
   85.59 -            uint16_t size;	   /* GSO MSS. */
   85.60 -            uint16_t segs;	   /* GSO segment count. */
   85.61 -            uint16_t type;	   /* GSO type. */
   85.62 +        struct {
   85.63 +            /*
   85.64 +             * Maximum payload size of each segment. For example, for TCP this
   85.65 +             * is just the path MSS.
   85.66 +             */
   85.67 +            uint16_t size;
   85.68 +
   85.69 +            /*
   85.70 +             * GSO type. This determines the protocol of the packet and any
   85.71 +             * extra features required to segment the packet properly.
   85.72 +             */
   85.73 +            uint16_t type; /* XEN_NETIF_GSO_* */
   85.74          } gso;
   85.75 +
   85.76 +        uint16_t pad[3];
   85.77      } u;
   85.78  };
   85.79  
    86.1 --- a/xen/include/public/memory.h	Wed Jun 28 07:52:21 2006 -0600
    86.2 +++ b/xen/include/public/memory.h	Mon Jul 03 08:35:12 2006 +0100
    86.3 @@ -32,7 +32,7 @@ struct xen_memory_reservation {
    86.4      XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
    86.5  
    86.6      /* Number of extents, and size/alignment of each (2^extent_order pages). */
    86.7 -    unsigned long  nr_extents;
    86.8 +    xen_ulong_t    nr_extents;
    86.9      unsigned int   extent_order;
   86.10  
   86.11      /*
   86.12 @@ -90,7 +90,7 @@ struct xen_memory_exchange {
   86.13       *     command will be non-zero.
   86.14       *  5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
   86.15       */
   86.16 -    unsigned long nr_exchanged;
   86.17 +    xen_ulong_t nr_exchanged;
   86.18  };
   86.19  typedef struct xen_memory_exchange xen_memory_exchange_t;
   86.20  DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
   86.21 @@ -148,8 +148,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn
   86.22   */
   86.23  #define XENMEM_machphys_mapping     12
   86.24  struct xen_machphys_mapping {
   86.25 -    unsigned long v_start, v_end; /* Start and end virtual addresses.   */
   86.26 -    unsigned long max_mfn;        /* Maximum MFN that can be looked up. */
   86.27 +    xen_ulong_t v_start, v_end; /* Start and end virtual addresses.   */
   86.28 +    xen_ulong_t max_mfn;        /* Maximum MFN that can be looked up. */
   86.29  };
   86.30  typedef struct xen_machphys_mapping xen_machphys_mapping_t;
   86.31  DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
   86.32 @@ -170,7 +170,7 @@ struct xen_add_to_physmap {
   86.33      unsigned int space;
   86.34  
   86.35      /* Index into source mapping space. */
   86.36 -    unsigned long idx;
   86.37 +    xen_ulong_t idx;
   86.38  
   86.39      /* GPFN where the source mapping page should appear. */
   86.40      xen_pfn_t     gpfn;
   86.41 @@ -188,7 +188,7 @@ struct xen_translate_gpfn_list {
   86.42      domid_t domid;
   86.43  
   86.44      /* Length of list. */
   86.45 -    unsigned long nr_gpfns;
   86.46 +    xen_ulong_t nr_gpfns;
   86.47  
   86.48      /* List of GPFNs to translate. */
   86.49      XEN_GUEST_HANDLE(xen_pfn_t) gpfn_list;
    87.1 --- a/xen/include/xen/lib.h	Wed Jun 28 07:52:21 2006 -0600
    87.2 +++ b/xen/include/xen/lib.h	Mon Jul 03 08:35:12 2006 +0100
    87.3 @@ -8,19 +8,23 @@
    87.4  #include <xen/xmalloc.h>
    87.5  #include <xen/string.h>
    87.6  
    87.7 -#define BUG() do {					\
    87.8 -    debugtrace_dump();                                  \
    87.9 -    printk("BUG at %s:%d\n", __FILE__, __LINE__);	\
   87.10 -    FORCE_CRASH();                                      \
   87.11 -} while ( 0 )
   87.12 -
   87.13 +extern void __bug(char *file, int line) __attribute__((noreturn));
   87.14 +#define BUG() __bug(__FILE__, __LINE__)
   87.15  #define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
   87.16  
   87.17  /* Force a compilation error if condition is true */
   87.18  #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
   87.19  
   87.20  #ifndef NDEBUG
   87.21 -#define ASSERT(_p) { if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s\n", #_p , __LINE__, __FILE__); BUG(); } }
   87.22 +#define ASSERT(_p)                                                      \
   87.23 +    do {                                                                \
   87.24 +        if ( !(_p) )                                                    \
   87.25 +        {                                                               \
   87.26 +            printk("Assertion '%s' failed, line %d, file %s\n", #_p ,   \
   87.27 +                   __LINE__, __FILE__);                                 \
   87.28 +            BUG();                                                      \
   87.29 +        }                                                               \
   87.30 +    } while ( 0 )
   87.31  #else
   87.32  #define ASSERT(_p) ((void)0)
   87.33  #endif
    88.1 --- a/xen/include/xen/timer.h	Wed Jun 28 07:52:21 2006 -0600
    88.2 +++ b/xen/include/xen/timer.h	Mon Jul 03 08:35:12 2006 +0100
    88.3 @@ -89,6 +89,12 @@ extern void migrate_timer(struct timer *
    88.4  extern void kill_timer(struct timer *timer);
    88.5  
    88.6  /*
    88.7 + * Process pending timers on this CPU. This should be called periodically
    88.8 + * when performing work that prevents softirqs from running in a timely manner.
    88.9 + */
   88.10 +extern void process_pending_timers(void);
   88.11 +
   88.12 +/*
   88.13   * Bootstrap initialisation. Must be called before any other timer function.
   88.14   */
   88.15  extern void timer_init(void);