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 +Insert the TPM frontend into the kernel if it has been compiled as a 4.87 +kernel module. 4.88 4.89 -> cd /sys/devices/vtpm 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, ®ion_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 +loop = 0 58.47 +while loop < 3: 58.48 + try: 58.49 + status, ouptut = traceCommand("xm save %s %s.save" % 58.50 + (domName, domName), 58.51 + timeout=30) 58.52 58.53 -except TimeoutError, e: 58.54 - saveLog(consoleHistory) 58.55 - vtpm_cleanup(domName) 58.56 - FAIL(str(e)) 58.57 + except TimeoutError, e: 58.58 + saveLog(consoleHistory) 58.59 + vtpm_cleanup(domName) 58.60 + FAIL(str(e)) 58.61 58.62 -if status != 0: 58.63 - saveLog(consoleHistory) 58.64 - vtpm_cleanup(domName) 58.65 - FAIL("xm save did not succeed") 58.66 + if status != 0: 58.67 + saveLog(consoleHistory) 58.68 + vtpm_cleanup(domName) 58.69 + FAIL("xm save did not succeed") 58.70 58.71 -try: 58.72 - status, ouptut = traceCommand("xm restore %s.save" % 58.73 - (domName), 58.74 - timeout=30) 58.75 -except TimeoutError, e: 58.76 + try: 58.77 + status, ouptut = traceCommand("xm restore %s.save" % 58.78 + (domName), 58.79 + timeout=30) 58.80 + except TimeoutError, e: 58.81 + os.remove("%s.save" % domName) 58.82 + saveLog(consoleHistory) 58.83 + vtpm_cleanup(domName) 58.84 + FAIL(str(e)) 58.85 + 58.86 os.remove("%s.save" % domName) 58.87 - saveLog(consoleHistory) 58.88 - vtpm_cleanup(domName) 58.89 - FAIL(str(e)) 58.90 + 58.91 + if status != 0: 58.92 + saveLog(consoleHistory) 58.93 + vtpm_cleanup(domName) 58.94 + FAIL("xm restore did not succeed") 58.95 58.96 -os.remove("%s.save" % domName) 58.97 - 58.98 -if status != 0: 58.99 - saveLog(consoleHistory) 58.100 - vtpm_cleanup(domName) 58.101 - FAIL("xm restore did not succeed") 58.102 + try: 58.103 + console = domain.getConsole() 58.104 + except ConsoleError, e: 58.105 + vtpm_cleanup(domName) 58.106 + FAIL(str(e)) 58.107 58.108 -try: 58.109 - console = domain.getConsole() 58.110 -except ConsoleError, e: 58.111 - vtpm_cleanup(domName) 58.112 - FAIL(str(e)) 58.113 + try: 58.114 + run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs") 58.115 + except ConsoleError, e: 58.116 + saveLog(console.getHistory()) 58.117 + vtpm_cleanup(domName) 58.118 + FAIL(str(e)) 58.119 58.120 -try: 58.121 - run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs") 58.122 -except ConsoleError, e: 58.123 - saveLog(console.getHistory()) 58.124 - vtpm_cleanup(domName) 58.125 - FAIL(str(e)) 58.126 + if not re.search("PCR-00:",run["output"]): 58.127 + saveLog(console.getHistory()) 58.128 + vtpm_cleanup(domName) 58.129 + FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side") 58.130 + 58.131 + loop += 1 58.132 58.133 domain.closeConsole() 58.134 58.135 @@ -99,5 +107,3 @@ domain.stop() 58.136 58.137 vtpm_cleanup(domName) 58.138 58.139 -if not re.search("PCR-00:",run["output"]): 58.140 - 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);