ia64/xen-unstable
changeset 10559:4b51d081378d
merge with xen-unstable.hg
author | awilliam@xenbuild.aw |
---|---|
date | Wed Jun 28 07:52:21 2006 -0600 (2006-06-28) |
parents | c4b68afe97d3 224597479812 |
children | 75b23b6a7cb7 856caf975abd |
files | tools/libxc/xc_aout9.h tools/libxc/xc_ia64_stubs.c tools/libxc/xc_linux_build.c tools/libxc/xc_load_aout9.c |
line diff
1.1 --- a/Makefile Wed Jun 28 07:51:52 2006 -0600 1.2 +++ b/Makefile Wed Jun 28 07:52:21 2006 -0600 1.3 @@ -123,7 +123,10 @@ clean:: 1.4 1.5 # clean, but blow away kernel build tree plus tarballs 1.6 .PHONY: distclean 1.7 -distclean: clean 1.8 +distclean: 1.9 + $(MAKE) -C xen distclean 1.10 + $(MAKE) -C tools distclean 1.11 + $(MAKE) -C docs distclean 1.12 rm -rf dist patches/tmp 1.13 for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done 1.14 for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
2.1 --- a/docs/Makefile Wed Jun 28 07:51:52 2006 -0600 2.2 +++ b/docs/Makefile Wed Jun 28 07:52:21 2006 -0600 2.3 @@ -80,6 +80,9 @@ clean: 2.4 rm -rf man5 2.5 rm -rf man1 2.6 2.7 +.PHONY: distclean 2.8 +distclean: clean 2.9 + 2.10 .PHONY: install 2.11 install: all 2.12 rm -rf $(DESTDIR)$(pkgdocdir)
3.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Jun 28 07:51:52 2006 -0600 3.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c Wed Jun 28 07:52:21 2006 -0600 3.3 @@ -264,7 +264,7 @@ static void contiguous_bitmap_clear( 3.4 } 3.5 3.6 /* Protected by balloon_lock. */ 3.7 -#define MAX_CONTIG_ORDER 7 3.8 +#define MAX_CONTIG_ORDER 9 /* 2MB */ 3.9 static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER]; 3.10 3.11 /* Ensure multi-page extents are contiguous in machine memory. */
4.1 --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Jun 28 07:51:52 2006 -0600 4.2 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Jun 28 07:52:21 2006 -0600 4.3 @@ -28,6 +28,7 @@ 4.4 4.5 #include <xen/interface/xen.h> 4.6 #include <xen/interface/xenoprof.h> 4.7 +#include <../../../drivers/oprofile/cpu_buffer.h> 4.8 4.9 static int xenoprof_start(void); 4.10 static void xenoprof_stop(void); 4.11 @@ -50,6 +51,11 @@ int ovf_irq[NR_CPUS]; 4.12 /* cpu model type string - copied from Xen memory space on XENOPROF_init command */ 4.13 char cpu_type[XENOPROF_CPU_TYPE_SIZE]; 4.14 4.15 +/* Passive sample buffers shared with Xen */ 4.16 +xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS]; 4.17 +/* Passive shared buffer area */ 4.18 +char *p_shared_buffer[MAX_OPROF_DOMAINS]; 4.19 + 4.20 #ifdef CONFIG_PM 4.21 4.22 static int xenoprof_suspend(struct sys_device * dev, pm_message_t state) 4.23 @@ -102,16 +108,14 @@ static void __exit exit_driverfs(void) 4.24 #endif /* CONFIG_PM */ 4.25 4.26 unsigned long long oprofile_samples = 0; 4.27 +unsigned long long p_oprofile_samples = 0; 4.28 4.29 -static irqreturn_t 4.30 -xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs) 4.31 +unsigned int pdomains; 4.32 +struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS]; 4.33 + 4.34 +static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive) 4.35 { 4.36 int head, tail, size; 4.37 - struct xenoprof_buf * buf; 4.38 - int cpu; 4.39 - 4.40 - cpu = smp_processor_id(); 4.41 - buf = xenoprof_buf[cpu]; 4.42 4.43 head = buf->event_head; 4.44 tail = buf->event_tail; 4.45 @@ -122,7 +126,10 @@ xenoprof_ovf_interrupt(int irq, void * d 4.46 oprofile_add_pc(buf->event_log[tail].eip, 4.47 buf->event_log[tail].mode, 4.48 buf->event_log[tail].event); 4.49 - oprofile_samples++; 4.50 + if (!is_passive) 4.51 + oprofile_samples++; 4.52 + else 4.53 + p_oprofile_samples++; 4.54 tail++; 4.55 } 4.56 tail = 0; 4.57 @@ -131,11 +138,47 @@ xenoprof_ovf_interrupt(int irq, void * d 4.58 oprofile_add_pc(buf->event_log[tail].eip, 4.59 buf->event_log[tail].mode, 4.60 buf->event_log[tail].event); 4.61 - oprofile_samples++; 4.62 + if (!is_passive) 4.63 + oprofile_samples++; 4.64 + else 4.65 + p_oprofile_samples++; 4.66 tail++; 4.67 } 4.68 4.69 buf->event_tail = tail; 4.70 +} 4.71 + 4.72 +static void xenoprof_handle_passive(void) 4.73 +{ 4.74 + int i, j; 4.75 + 4.76 + for (i = 0; i < pdomains; i++) 4.77 + for (j = 0; j < passive_domains[i].nbuf; j++) { 4.78 + xenoprof_buf_t *buf = p_xenoprof_buf[i][j]; 4.79 + if (buf->event_head == buf->event_tail) 4.80 + continue; 4.81 + oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START, passive_domains[i].domain_id); 4.82 + xenoprof_add_pc(buf, 1); 4.83 + oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP, passive_domains[i].domain_id); 4.84 + } 4.85 +} 4.86 + 4.87 +static irqreturn_t 4.88 +xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs) 4.89 +{ 4.90 + struct xenoprof_buf * buf; 4.91 + int cpu; 4.92 + static unsigned long flag; 4.93 + 4.94 + cpu = smp_processor_id(); 4.95 + buf = xenoprof_buf[cpu]; 4.96 + 4.97 + xenoprof_add_pc(buf, 0); 4.98 + 4.99 + if (is_primary && !test_and_set_bit(0, &flag)) { 4.100 + xenoprof_handle_passive(); 4.101 + clear_bit(0, &flag); 4.102 + } 4.103 4.104 return IRQ_HANDLED; 4.105 } 4.106 @@ -312,6 +355,63 @@ out: 4.107 return ret; 4.108 } 4.109 4.110 +static int xenoprof_set_passive(int * p_domains, 4.111 + unsigned int pdoms) 4.112 +{ 4.113 + int ret; 4.114 + int i, j; 4.115 + int vm_size; 4.116 + int npages; 4.117 + struct xenoprof_buf *buf; 4.118 + pgprot_t prot = __pgprot(_KERNPG_TABLE); 4.119 + 4.120 + if (!is_primary) 4.121 + return 0; 4.122 + 4.123 + if (pdoms > MAX_OPROF_DOMAINS) 4.124 + return -E2BIG; 4.125 + 4.126 + ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL); 4.127 + if (ret) 4.128 + return ret; 4.129 + 4.130 + for (i = 0; i < pdoms; i++) { 4.131 + passive_domains[i].domain_id = p_domains[i]; 4.132 + passive_domains[i].max_samples = 2048; 4.133 + ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, &passive_domains[i]); 4.134 + if (ret) 4.135 + return ret; 4.136 + 4.137 + npages = (passive_domains[i].bufsize * passive_domains[i].nbuf - 1) / PAGE_SIZE + 1; 4.138 + vm_size = npages * PAGE_SIZE; 4.139 + 4.140 + p_shared_buffer[i] = (char *)vm_map_xen_pages(passive_domains[i].buf_maddr, 4.141 + vm_size, prot); 4.142 + if (!p_shared_buffer[i]) { 4.143 + ret = -ENOMEM; 4.144 + goto out; 4.145 + } 4.146 + 4.147 + for (j = 0; j < passive_domains[i].nbuf; j++) { 4.148 + buf = (struct xenoprof_buf *) 4.149 + &p_shared_buffer[i][j * passive_domains[i].bufsize]; 4.150 + BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS); 4.151 + p_xenoprof_buf[i][buf->vcpu_id] = buf; 4.152 + } 4.153 + 4.154 + } 4.155 + 4.156 + pdomains = pdoms; 4.157 + return 0; 4.158 + 4.159 +out: 4.160 + for (j = 0; j < i; j++) { 4.161 + vunmap(p_shared_buffer[j]); 4.162 + p_shared_buffer[j] = NULL; 4.163 + } 4.164 + 4.165 + return ret; 4.166 +} 4.167 4.168 struct op_counter_config counter_config[OP_MAX_COUNTER]; 4.169 4.170 @@ -346,6 +446,7 @@ static int xenoprof_create_files(struct 4.171 struct oprofile_operations xenoprof_ops = { 4.172 .create_files = xenoprof_create_files, 4.173 .set_active = xenoprof_set_active, 4.174 + .set_passive = xenoprof_set_passive, 4.175 .setup = xenoprof_setup, 4.176 .shutdown = xenoprof_shutdown, 4.177 .start = xenoprof_start, 4.178 @@ -420,6 +521,8 @@ int __init oprofile_arch_init(struct opr 4.179 4.180 void __exit oprofile_arch_exit(void) 4.181 { 4.182 + int i; 4.183 + 4.184 if (using_xenoprof) 4.185 exit_driverfs(); 4.186 4.187 @@ -427,6 +530,13 @@ void __exit oprofile_arch_exit(void) 4.188 vunmap(shared_buffer); 4.189 shared_buffer = NULL; 4.190 } 4.191 - if (is_primary) 4.192 + if (is_primary) { 4.193 + for (i = 0; i < pdomains; i++) 4.194 + if (p_shared_buffer[i]) { 4.195 + vunmap(p_shared_buffer[i]); 4.196 + p_shared_buffer[i] = NULL; 4.197 + } 4.198 HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL); 4.199 + } 4.200 + 4.201 }
5.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Jun 28 07:51:52 2006 -0600 5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Jun 28 07:52:21 2006 -0600 5.3 @@ -172,7 +172,7 @@ static unsigned long current_target(void 5.4 5.5 static int increase_reservation(unsigned long nr_pages) 5.6 { 5.7 - unsigned long *frame_list, pfn, i, flags; 5.8 + unsigned long *frame_list, frame, pfn, i, flags; 5.9 struct page *page; 5.10 long rc; 5.11 struct xen_memory_reservation reservation = { 5.12 @@ -185,8 +185,11 @@ static int increase_reservation(unsigned 5.13 nr_pages = PAGE_SIZE / sizeof(unsigned long); 5.14 5.15 frame_list = (unsigned long *)__get_free_page(GFP_KERNEL); 5.16 - if (frame_list == NULL) 5.17 - return -ENOMEM; 5.18 + if (frame_list == NULL) { 5.19 + frame_list = &frame; 5.20 + if (nr_pages > 1) 5.21 + nr_pages = 1; 5.22 + } 5.23 5.24 balloon_lock(flags); 5.25 5.26 @@ -202,14 +205,17 @@ static int increase_reservation(unsigned 5.27 rc = HYPERVISOR_memory_op( 5.28 XENMEM_populate_physmap, &reservation); 5.29 if (rc < nr_pages) { 5.30 - int ret; 5.31 - /* We hit the Xen hard limit: reprobe. */ 5.32 - set_xen_guest_handle(reservation.extent_start, frame_list); 5.33 - reservation.nr_extents = rc; 5.34 - ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 5.35 - &reservation); 5.36 - BUG_ON(ret != rc); 5.37 - hard_limit = current_pages + rc - driver_pages; 5.38 + if (rc > 0) { 5.39 + int ret; 5.40 + 5.41 + /* We hit the Xen hard limit: reprobe. */ 5.42 + reservation.nr_extents = rc; 5.43 + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 5.44 + &reservation); 5.45 + BUG_ON(ret != rc); 5.46 + } 5.47 + if (rc >= 0) 5.48 + hard_limit = current_pages + rc - driver_pages; 5.49 goto out; 5.50 } 5.51 5.52 @@ -247,14 +253,15 @@ static int increase_reservation(unsigned 5.53 out: 5.54 balloon_unlock(flags); 5.55 5.56 - free_page((unsigned long)frame_list); 5.57 + if (frame_list != &frame) 5.58 + free_page((unsigned long)frame_list); 5.59 5.60 return 0; 5.61 } 5.62 5.63 static int decrease_reservation(unsigned long nr_pages) 5.64 { 5.65 - unsigned long *frame_list, pfn, i, flags; 5.66 + unsigned long *frame_list, frame, pfn, i, flags; 5.67 struct page *page; 5.68 void *v; 5.69 int need_sleep = 0; 5.70 @@ -269,8 +276,11 @@ static int decrease_reservation(unsigned 5.71 nr_pages = PAGE_SIZE / sizeof(unsigned long); 5.72 5.73 frame_list = (unsigned long *)__get_free_page(GFP_KERNEL); 5.74 - if (frame_list == NULL) 5.75 - return -ENOMEM; 5.76 + if (frame_list == NULL) { 5.77 + frame_list = &frame; 5.78 + if (nr_pages > 1) 5.79 + nr_pages = 1; 5.80 + } 5.81 5.82 for (i = 0; i < nr_pages; i++) { 5.83 if ((page = alloc_page(GFP_HIGHUSER)) == NULL) { 5.84 @@ -321,7 +331,8 @@ static int decrease_reservation(unsigned 5.85 5.86 balloon_unlock(flags); 5.87 5.88 - free_page((unsigned long)frame_list); 5.89 + if (frame_list != &frame) 5.90 + free_page((unsigned long)frame_list); 5.91 5.92 return need_sleep; 5.93 }
6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Jun 28 07:51:52 2006 -0600 6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Jun 28 07:52:21 2006 -0600 6.3 @@ -95,6 +95,7 @@ typedef struct blkif_st { 6.4 } blkif_t; 6.5 6.6 blkif_t *blkif_alloc(domid_t domid); 6.7 +void blkif_disconnect(blkif_t *blkif); 6.8 void blkif_free(blkif_t *blkif); 6.9 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); 6.10
7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Wed Jun 28 07:51:52 2006 -0600 7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Wed Jun 28 07:52:21 2006 -0600 7.3 @@ -32,6 +32,7 @@ 7.4 7.5 #include "common.h" 7.6 #include <xen/evtchn.h> 7.7 +#include <linux/kthread.h> 7.8 7.9 static kmem_cache_t *blkif_cachep; 7.10 7.11 @@ -139,22 +140,33 @@ int blkif_map(blkif_t *blkif, unsigned l 7.12 return 0; 7.13 } 7.14 7.15 -void blkif_free(blkif_t *blkif) 7.16 +void blkif_disconnect(blkif_t *blkif) 7.17 { 7.18 + if (blkif->xenblkd) { 7.19 + kthread_stop(blkif->xenblkd); 7.20 + blkif->xenblkd = NULL; 7.21 + } 7.22 + 7.23 atomic_dec(&blkif->refcnt); 7.24 wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0); 7.25 + atomic_inc(&blkif->refcnt); 7.26 7.27 - /* Already disconnected? */ 7.28 - if (blkif->irq) 7.29 + if (blkif->irq) { 7.30 unbind_from_irqhandler(blkif->irq, blkif); 7.31 - 7.32 - vbd_free(&blkif->vbd); 7.33 + blkif->irq = 0; 7.34 + } 7.35 7.36 if (blkif->blk_ring.sring) { 7.37 unmap_frontend_page(blkif); 7.38 free_vm_area(blkif->blk_ring_area); 7.39 + blkif->blk_ring.sring = NULL; 7.40 } 7.41 +} 7.42 7.43 +void blkif_free(blkif_t *blkif) 7.44 +{ 7.45 + if (!atomic_dec_and_test(&blkif->refcnt)) 7.46 + BUG(); 7.47 kmem_cache_free(blkif_cachep, blkif); 7.48 } 7.49
8.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:51:52 2006 -0600 8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:52:21 2006 -0600 8.3 @@ -43,7 +43,6 @@ static int connect_ring(struct backend_i 8.4 static void backend_changed(struct xenbus_watch *, const char **, 8.5 unsigned int); 8.6 8.7 - 8.8 static void update_blkif_status(blkif_t *blkif) 8.9 { 8.10 int err; 8.11 @@ -73,6 +72,70 @@ static void update_blkif_status(blkif_t 8.12 } 8.13 8.14 8.15 +/**************************************************************** 8.16 + * sysfs interface for VBD I/O requests 8.17 + */ 8.18 + 8.19 +#ifdef CONFIG_SYSFS 8.20 + 8.21 +#define VBD_SHOW(name, format, args...) \ 8.22 + static ssize_t show_##name(struct device *_dev, \ 8.23 + struct device_attribute *attr, \ 8.24 + char *buf) \ 8.25 + { \ 8.26 + struct xenbus_device *dev = to_xenbus_device(_dev); \ 8.27 + struct backend_info *be = dev->dev.driver_data; \ 8.28 + \ 8.29 + return sprintf(buf, format, ##args); \ 8.30 + } \ 8.31 + DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) 8.32 + 8.33 +VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req); 8.34 +VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req); 8.35 +VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req); 8.36 + 8.37 +static struct attribute *vbdstat_attrs[] = { 8.38 + &dev_attr_oo_req.attr, 8.39 + &dev_attr_rd_req.attr, 8.40 + &dev_attr_wr_req.attr, 8.41 + NULL 8.42 +}; 8.43 + 8.44 +static struct attribute_group vbdstat_group = { 8.45 + .name = "statistics", 8.46 + .attrs = vbdstat_attrs, 8.47 +}; 8.48 + 8.49 +int xenvbd_sysfs_addif(struct xenbus_device *dev) 8.50 +{ 8.51 + int error = 0; 8.52 + 8.53 + error = sysfs_create_group(&dev->dev.kobj, 8.54 + &vbdstat_group); 8.55 + if (error) 8.56 + goto fail; 8.57 + 8.58 + return 0; 8.59 + 8.60 +fail: 8.61 + sysfs_remove_group(&dev->dev.kobj, 8.62 + &vbdstat_group); 8.63 + return error; 8.64 +} 8.65 + 8.66 +void xenvbd_sysfs_delif(struct xenbus_device *dev) 8.67 +{ 8.68 + sysfs_remove_group(&dev->dev.kobj, 8.69 + &vbdstat_group); 8.70 +} 8.71 + 8.72 +#else 8.73 + 8.74 +#define xenvbd_sysfs_addif(dev) (0) 8.75 +#define xenvbd_sysfs_delif(dev) ((void)0) 8.76 + 8.77 +#endif /* CONFIG_SYSFS */ 8.78 + 8.79 static ssize_t show_physical_device(struct device *_dev, 8.80 struct device_attribute *attr, char *buf) 8.81 { 8.82 @@ -105,15 +168,17 @@ static int blkback_remove(struct xenbus_ 8.83 kfree(be->backend_watch.node); 8.84 be->backend_watch.node = NULL; 8.85 } 8.86 + 8.87 if (be->blkif) { 8.88 - if (be->blkif->xenblkd) 8.89 - kthread_stop(be->blkif->xenblkd); 8.90 + blkif_disconnect(be->blkif); 8.91 + vbd_free(&be->blkif->vbd); 8.92 blkif_free(be->blkif); 8.93 be->blkif = NULL; 8.94 } 8.95 8.96 device_remove_file(&dev->dev, &dev_attr_physical_device); 8.97 device_remove_file(&dev->dev, &dev_attr_mode); 8.98 + xenvbd_sysfs_delif(dev); 8.99 8.100 kfree(be); 8.101 dev->dev.driver_data = NULL; 8.102 @@ -236,6 +301,7 @@ static void backend_changed(struct xenbu 8.103 8.104 device_create_file(&dev->dev, &dev_attr_physical_device); 8.105 device_create_file(&dev->dev, &dev_attr_mode); 8.106 + xenvbd_sysfs_addif(dev); 8.107 8.108 /* We're potentially connected now */ 8.109 update_blkif_status(be->blkif); 8.110 @@ -273,6 +339,7 @@ static void frontend_changed(struct xenb 8.111 break; 8.112 8.113 case XenbusStateClosing: 8.114 + blkif_disconnect(be->blkif); 8.115 xenbus_switch_state(dev, XenbusStateClosing); 8.116 break; 8.117
9.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:51:52 2006 -0600 9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:52:21 2006 -0600 9.3 @@ -58,15 +58,17 @@ HYPERVISOR_ATTR_RO(minor); 9.4 9.5 static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer) 9.6 { 9.7 - int ret; 9.8 - char *extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL); 9.9 + int ret = -ENOMEM; 9.10 + char *extra; 9.11 + 9.12 + extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL); 9.13 if (extra) { 9.14 ret = HYPERVISOR_xen_version(XENVER_extraversion, extra); 9.15 if (!ret) 9.16 - return sprintf(buffer, "%s\n", extra); 9.17 + ret = sprintf(buffer, "%s\n", extra); 9.18 kfree(extra); 9.19 - } else 9.20 - ret = -ENOMEM; 9.21 + } 9.22 + 9.23 return ret; 9.24 } 9.25 9.26 @@ -86,7 +88,8 @@ static struct attribute_group version_gr 9.27 9.28 static int __init xen_sysfs_version_init(void) 9.29 { 9.30 - return sysfs_create_group(&hypervisor_subsys.kset.kobj, &version_group); 9.31 + return sysfs_create_group(&hypervisor_subsys.kset.kobj, 9.32 + &version_group); 9.33 } 9.34 9.35 static void xen_sysfs_version_destroy(void) 9.36 @@ -98,16 +101,16 @@ static void xen_sysfs_version_destroy(vo 9.37 9.38 static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer) 9.39 { 9.40 - int ret; 9.41 - struct xen_compile_info *info = 9.42 - kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 9.43 + int ret = -ENOMEM; 9.44 + struct xen_compile_info *info; 9.45 + 9.46 + info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 9.47 if (info) { 9.48 ret = HYPERVISOR_xen_version(XENVER_compile_info, info); 9.49 if (!ret) 9.50 ret = sprintf(buffer, "%s\n", info->compiler); 9.51 kfree(info); 9.52 - } else 9.53 - ret = -ENOMEM; 9.54 + } 9.55 9.56 return ret; 9.57 } 9.58 @@ -116,7 +119,7 @@ HYPERVISOR_ATTR_RO(compiler); 9.59 9.60 static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer) 9.61 { 9.62 - int ret; 9.63 + int ret = -ENOMEM; 9.64 struct xen_compile_info *info; 9.65 9.66 info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 9.67 @@ -125,8 +128,8 @@ static ssize_t compiled_by_show(struct h 9.68 if (!ret) 9.69 ret = sprintf(buffer, "%s\n", info->compile_by); 9.70 kfree(info); 9.71 - } else 9.72 - ret = -ENOMEM; 9.73 + } 9.74 + 9.75 return ret; 9.76 } 9.77 9.78 @@ -134,7 +137,7 @@ HYPERVISOR_ATTR_RO(compiled_by); 9.79 9.80 static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer) 9.81 { 9.82 - int ret; 9.83 + int ret = -ENOMEM; 9.84 struct xen_compile_info *info; 9.85 9.86 info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 9.87 @@ -143,8 +146,8 @@ static ssize_t compile_date_show(struct 9.88 if (!ret) 9.89 ret = sprintf(buffer, "%s\n", info->compile_date); 9.90 kfree(info); 9.91 - } else 9.92 - ret = -ENOMEM; 9.93 + } 9.94 + 9.95 return ret; 9.96 } 9.97 9.98 @@ -178,15 +181,17 @@ static void xen_compilation_destroy(void 9.99 9.100 static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer) 9.101 { 9.102 - int ret; 9.103 - char *caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL); 9.104 + int ret = -ENOMEM; 9.105 + char *caps; 9.106 + 9.107 + caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL); 9.108 if (caps) { 9.109 ret = HYPERVISOR_xen_version(XENVER_capabilities, caps); 9.110 if (!ret) 9.111 ret = sprintf(buffer, "%s\n", caps); 9.112 kfree(caps); 9.113 - } else 9.114 - ret = -ENOMEM; 9.115 + } 9.116 + 9.117 return ret; 9.118 } 9.119 9.120 @@ -194,15 +199,17 @@ HYPERVISOR_ATTR_RO(capabilities); 9.121 9.122 static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer) 9.123 { 9.124 - int ret; 9.125 - char *cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL); 9.126 + int ret = -ENOMEM; 9.127 + char *cset; 9.128 + 9.129 + cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL); 9.130 if (cset) { 9.131 ret = HYPERVISOR_xen_version(XENVER_changeset, cset); 9.132 if (!ret) 9.133 ret = sprintf(buffer, "%s\n", cset); 9.134 kfree(cset); 9.135 - } else 9.136 - ret = -ENOMEM; 9.137 + } 9.138 + 9.139 return ret; 9.140 } 9.141 9.142 @@ -210,36 +217,51 @@ HYPERVISOR_ATTR_RO(changeset); 9.143 9.144 static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer) 9.145 { 9.146 - int ret; 9.147 - struct xen_platform_parameters *parms = 9.148 - kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL); 9.149 + int ret = -ENOMEM; 9.150 + struct xen_platform_parameters *parms; 9.151 + 9.152 + parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL); 9.153 if (parms) { 9.154 - ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms); 9.155 + ret = HYPERVISOR_xen_version(XENVER_platform_parameters, 9.156 + parms); 9.157 if (!ret) 9.158 ret = sprintf(buffer, "%lx\n", parms->virt_start); 9.159 kfree(parms); 9.160 - } else 9.161 - ret = -ENOMEM; 9.162 + } 9.163 + 9.164 return ret; 9.165 } 9.166 9.167 HYPERVISOR_ATTR_RO(virtual_start); 9.168 9.169 +static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer) 9.170 +{ 9.171 + int ret; 9.172 + 9.173 + ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL); 9.174 + if (ret > 0) 9.175 + ret = sprintf(buffer, "%x\n", ret); 9.176 + 9.177 + return ret; 9.178 +} 9.179 + 9.180 +HYPERVISOR_ATTR_RO(pagesize); 9.181 + 9.182 /* eventually there will be several more features to export */ 9.183 static ssize_t xen_feature_show(int index, char *buffer) 9.184 { 9.185 - int ret; 9.186 + int ret = -ENOMEM; 9.187 + struct xen_feature_info *info; 9.188 9.189 - struct xen_feature_info *info = 9.190 - kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL); 9.191 + info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL); 9.192 if (info) { 9.193 info->submap_idx = index; 9.194 ret = HYPERVISOR_xen_version(XENVER_get_features, info); 9.195 if (!ret) 9.196 ret = sprintf(buffer, "%d\n", info->submap); 9.197 kfree(info); 9.198 - } else 9.199 - ret = -ENOMEM; 9.200 + } 9.201 + 9.202 return ret; 9.203 } 9.204 9.205 @@ -254,6 +276,7 @@ static struct attribute *xen_properties_ 9.206 &capabilities_attr.attr, 9.207 &changeset_attr.attr, 9.208 &virtual_start_attr.attr, 9.209 + &pagesize_attr.attr, 9.210 &writable_pt_attr.attr, 9.211 NULL 9.212 }; 9.213 @@ -271,7 +294,8 @@ static int __init xen_properties_init(vo 9.214 9.215 static void xen_properties_destroy(void) 9.216 { 9.217 - sysfs_remove_group(&hypervisor_subsys.kset.kobj, &xen_properties_group); 9.218 + sysfs_remove_group(&hypervisor_subsys.kset.kobj, 9.219 + &xen_properties_group); 9.220 } 9.221 9.222 static int __init hyper_sysfs_init(void)
10.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Jun 28 07:51:52 2006 -0600 10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Jun 28 07:52:21 2006 -0600 10.3 @@ -37,9 +37,9 @@ 10.4 static void __netif_up(netif_t *netif) 10.5 { 10.6 struct net_device *dev = netif->dev; 10.7 - spin_lock_bh(&dev->xmit_lock); 10.8 + netif_tx_lock_bh(dev); 10.9 netif->active = 1; 10.10 - spin_unlock_bh(&dev->xmit_lock); 10.11 + netif_tx_unlock_bh(dev); 10.12 enable_irq(netif->irq); 10.13 netif_schedule_work(netif); 10.14 } 10.15 @@ -48,9 +48,9 @@ static void __netif_down(netif_t *netif) 10.16 { 10.17 struct net_device *dev = netif->dev; 10.18 disable_irq(netif->irq); 10.19 - spin_lock_bh(&dev->xmit_lock); 10.20 + netif_tx_lock_bh(dev); 10.21 netif->active = 0; 10.22 - spin_unlock_bh(&dev->xmit_lock); 10.23 + netif_tx_unlock_bh(dev); 10.24 netif_deschedule_work(netif); 10.25 } 10.26
11.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Jun 28 07:51:52 2006 -0600 11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Wed Jun 28 07:52:21 2006 -0600 11.3 @@ -125,6 +125,10 @@ static struct ethtool_ops network_ethtoo 11.4 { 11.5 .get_tx_csum = ethtool_op_get_tx_csum, 11.6 .set_tx_csum = ethtool_op_set_tx_csum, 11.7 + .get_sg = ethtool_op_get_sg, 11.8 + .set_sg = ethtool_op_set_sg, 11.9 + .get_tso = ethtool_op_get_tso, 11.10 + .set_tso = ethtool_op_set_tso, 11.11 }; 11.12 11.13 /* 11.14 @@ -152,6 +156,7 @@ static void loopback_construct(struct ne 11.15 11.16 dev->features = (NETIF_F_HIGHDMA | 11.17 NETIF_F_LLTX | 11.18 + NETIF_F_TSO | 11.19 NETIF_F_SG | 11.20 NETIF_F_IP_CSUM); 11.21
12.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Jun 28 07:51:52 2006 -0600 12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Jun 28 07:52:21 2006 -0600 12.3 @@ -43,7 +43,7 @@ 12.4 static void netif_idx_release(u16 pending_idx); 12.5 static void netif_page_release(struct page *page); 12.6 static void make_tx_response(netif_t *netif, 12.7 - u16 id, 12.8 + netif_tx_request_t *txp, 12.9 s8 st); 12.10 static int make_rx_response(netif_t *netif, 12.11 u16 id, 12.12 @@ -481,7 +481,7 @@ inline static void net_tx_action_dealloc 12.13 12.14 netif = pending_tx_info[pending_idx].netif; 12.15 12.16 - make_tx_response(netif, pending_tx_info[pending_idx].req.id, 12.17 + make_tx_response(netif, &pending_tx_info[pending_idx].req, 12.18 NETIF_RSP_OKAY); 12.19 12.20 pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; 12.21 @@ -490,14 +490,16 @@ inline static void net_tx_action_dealloc 12.22 } 12.23 } 12.24 12.25 -static void netbk_tx_err(netif_t *netif, RING_IDX end) 12.26 +static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end) 12.27 { 12.28 RING_IDX cons = netif->tx.req_cons; 12.29 12.30 do { 12.31 - netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons); 12.32 - make_tx_response(netif, txp->id, NETIF_RSP_ERROR); 12.33 - } while (++cons < end); 12.34 + make_tx_response(netif, txp, NETIF_RSP_ERROR); 12.35 + if (++cons >= end) 12.36 + break; 12.37 + txp = RING_GET_REQUEST(&netif->tx, cons); 12.38 + } while (1); 12.39 netif->tx.req_cons = cons; 12.40 netif_schedule_work(netif); 12.41 netif_put(netif); 12.42 @@ -508,7 +510,7 @@ static int netbk_count_requests(netif_t 12.43 { 12.44 netif_tx_request_t *first = txp; 12.45 RING_IDX cons = netif->tx.req_cons; 12.46 - int frags = 1; 12.47 + int frags = 0; 12.48 12.49 while (txp->flags & NETTXF_more_data) { 12.50 if (frags >= work_to_do) { 12.51 @@ -543,7 +545,7 @@ static gnttab_map_grant_ref_t *netbk_get 12.52 skb_frag_t *frags = shinfo->frags; 12.53 netif_tx_request_t *txp; 12.54 unsigned long pending_idx = *((u16 *)skb->data); 12.55 - RING_IDX cons = netif->tx.req_cons + 1; 12.56 + RING_IDX cons = netif->tx.req_cons; 12.57 int i, start; 12.58 12.59 /* Skip first skb fragment if it is on same page as header fragment. */ 12.60 @@ -581,7 +583,7 @@ static int netbk_tx_check_mop(struct sk_ 12.61 err = mop->status; 12.62 if (unlikely(err)) { 12.63 txp = &pending_tx_info[pending_idx].req; 12.64 - make_tx_response(netif, txp->id, NETIF_RSP_ERROR); 12.65 + make_tx_response(netif, txp, NETIF_RSP_ERROR); 12.66 pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; 12.67 netif_put(netif); 12.68 } else { 12.69 @@ -614,7 +616,7 @@ static int netbk_tx_check_mop(struct sk_ 12.70 12.71 /* Error on this fragment: respond to client with an error. */ 12.72 txp = &pending_tx_info[pending_idx].req; 12.73 - make_tx_response(netif, txp->id, NETIF_RSP_ERROR); 12.74 + make_tx_response(netif, txp, NETIF_RSP_ERROR); 12.75 pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; 12.76 netif_put(netif); 12.77 12.78 @@ -668,6 +670,7 @@ static void net_tx_action(unsigned long 12.79 struct sk_buff *skb; 12.80 netif_t *netif; 12.81 netif_tx_request_t txreq; 12.82 + struct netif_tx_extra txtra; 12.83 u16 pending_idx; 12.84 RING_IDX i; 12.85 gnttab_map_grant_ref_t *mop; 12.86 @@ -726,22 +729,37 @@ static void net_tx_action(unsigned long 12.87 } 12.88 netif->remaining_credit -= txreq.size; 12.89 12.90 + work_to_do--; 12.91 + netif->tx.req_cons = ++i; 12.92 + 12.93 + if (txreq.flags & NETTXF_extra_info) { 12.94 + if (work_to_do-- <= 0) { 12.95 + DPRINTK("Missing extra info\n"); 12.96 + netbk_tx_err(netif, &txreq, i); 12.97 + continue; 12.98 + } 12.99 + 12.100 + memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i), 12.101 + sizeof(txtra)); 12.102 + netif->tx.req_cons = ++i; 12.103 + } 12.104 + 12.105 ret = netbk_count_requests(netif, &txreq, work_to_do); 12.106 if (unlikely(ret < 0)) { 12.107 - netbk_tx_err(netif, i - ret); 12.108 + netbk_tx_err(netif, &txreq, i - ret); 12.109 continue; 12.110 } 12.111 i += ret; 12.112 12.113 if (unlikely(ret > MAX_SKB_FRAGS + 1)) { 12.114 DPRINTK("Too many frags\n"); 12.115 - netbk_tx_err(netif, i); 12.116 + netbk_tx_err(netif, &txreq, i); 12.117 continue; 12.118 } 12.119 12.120 if (unlikely(txreq.size < ETH_HLEN)) { 12.121 DPRINTK("Bad packet size: %d\n", txreq.size); 12.122 - netbk_tx_err(netif, i); 12.123 + netbk_tx_err(netif, &txreq, i); 12.124 continue; 12.125 } 12.126 12.127 @@ -750,26 +768,32 @@ static void net_tx_action(unsigned long 12.128 DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 12.129 txreq.offset, txreq.size, 12.130 (txreq.offset &~PAGE_MASK) + txreq.size); 12.131 - netbk_tx_err(netif, i); 12.132 + netbk_tx_err(netif, &txreq, i); 12.133 continue; 12.134 } 12.135 12.136 pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; 12.137 12.138 data_len = (txreq.size > PKT_PROT_LEN && 12.139 - ret < MAX_SKB_FRAGS + 1) ? 12.140 + ret < MAX_SKB_FRAGS) ? 12.141 PKT_PROT_LEN : txreq.size; 12.142 12.143 skb = alloc_skb(data_len+16, GFP_ATOMIC); 12.144 if (unlikely(skb == NULL)) { 12.145 DPRINTK("Can't allocate a skb in start_xmit.\n"); 12.146 - netbk_tx_err(netif, i); 12.147 + netbk_tx_err(netif, &txreq, i); 12.148 break; 12.149 } 12.150 12.151 /* Packets passed to netif_rx() must have some headroom. */ 12.152 skb_reserve(skb, 16); 12.153 12.154 + if (txreq.flags & NETTXF_gso) { 12.155 + skb_shinfo(skb)->gso_size = txtra.u.gso.size; 12.156 + skb_shinfo(skb)->gso_segs = txtra.u.gso.segs; 12.157 + skb_shinfo(skb)->gso_type = txtra.u.gso.type; 12.158 + } 12.159 + 12.160 gnttab_set_map_op(mop, MMAP_VADDR(pending_idx), 12.161 GNTMAP_host_map | GNTMAP_readonly, 12.162 txreq.gref, netif->domid); 12.163 @@ -782,7 +806,7 @@ static void net_tx_action(unsigned long 12.164 12.165 __skb_put(skb, data_len); 12.166 12.167 - skb_shinfo(skb)->nr_frags = ret - 1; 12.168 + skb_shinfo(skb)->nr_frags = ret; 12.169 if (data_len < txreq.size) { 12.170 skb_shinfo(skb)->nr_frags++; 12.171 skb_shinfo(skb)->frags[0].page = 12.172 @@ -898,7 +922,7 @@ irqreturn_t netif_be_int(int irq, void * 12.173 } 12.174 12.175 static void make_tx_response(netif_t *netif, 12.176 - u16 id, 12.177 + netif_tx_request_t *txp, 12.178 s8 st) 12.179 { 12.180 RING_IDX i = netif->tx.rsp_prod_pvt; 12.181 @@ -906,9 +930,12 @@ static void make_tx_response(netif_t *ne 12.182 int notify; 12.183 12.184 resp = RING_GET_RESPONSE(&netif->tx, i); 12.185 - resp->id = id; 12.186 + resp->id = txp->id; 12.187 resp->status = st; 12.188 12.189 + if (txp->flags & NETTXF_extra_info) 12.190 + RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL; 12.191 + 12.192 netif->tx.rsp_prod_pvt = ++i; 12.193 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify); 12.194 if (notify)
13.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:51:52 2006 -0600 13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:52:21 2006 -0600 13.3 @@ -101,6 +101,12 @@ static int netback_probe(struct xenbus_d 13.4 goto abort_transaction; 13.5 } 13.6 13.7 + err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1); 13.8 + if (err) { 13.9 + message = "writing feature-tso"; 13.10 + goto abort_transaction; 13.11 + } 13.12 + 13.13 err = xenbus_transaction_end(xbt, 0); 13.14 } while (err == -EAGAIN); 13.15
14.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Jun 28 07:51:52 2006 -0600 14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Jun 28 07:52:21 2006 -0600 14.3 @@ -21,6 +21,8 @@ 14.4 pr_debug("(file=%s, line=%d) " _f, \ 14.5 __FILE__ , __LINE__ , ## _a ) 14.6 14.7 +struct backend_info; 14.8 + 14.9 typedef struct tpmif_st { 14.10 struct list_head tpmif_list; 14.11 /* Unique identifier for this interface. */ 14.12 @@ -43,7 +45,7 @@ typedef struct tpmif_st { 14.13 struct list_head list; /* scheduling list */ 14.14 atomic_t refcnt; 14.15 14.16 - long int tpm_instance; 14.17 + struct backend_info *bi; 14.18 unsigned long mmap_vstart; 14.19 14.20 grant_handle_t shmem_handle; 14.21 @@ -54,7 +56,7 @@ typedef struct tpmif_st { 14.22 } tpmif_t; 14.23 14.24 void tpmif_disconnect_complete(tpmif_t * tpmif); 14.25 -tpmif_t *tpmif_find(domid_t domid, long int instance); 14.26 +tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi); 14.27 void tpmif_interface_init(void); 14.28 void tpmif_interface_exit(void); 14.29 void tpmif_schedule_work(tpmif_t * tpmif); 14.30 @@ -63,11 +65,12 @@ void tpmif_xenbus_init(void); 14.31 void tpmif_xenbus_exit(void); 14.32 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn); 14.33 irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs); 14.34 -int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance); 14.35 -int tpmif_vtpm_close(u32 instance); 14.36 + 14.37 +long int tpmback_get_instance(struct backend_info *bi); 14.38 14.39 int vtpm_release_packets(tpmif_t * tpmif, int send_msgs); 14.40 14.41 + 14.42 #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt)) 14.43 #define tpmif_put(_b) \ 14.44 do { \
15.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Wed Jun 28 07:51:52 2006 -0600 15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Wed Jun 28 07:52:21 2006 -0600 15.3 @@ -20,7 +20,7 @@ int num_frontends = 0; 15.4 15.5 LIST_HEAD(tpmif_list); 15.6 15.7 -static tpmif_t *alloc_tpmif(domid_t domid, long int instance) 15.8 +static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi) 15.9 { 15.10 tpmif_t *tpmif; 15.11 15.12 @@ -31,7 +31,7 @@ static tpmif_t *alloc_tpmif(domid_t domi 15.13 memset(tpmif, 0, sizeof (*tpmif)); 15.14 tpmif->domid = domid; 15.15 tpmif->status = DISCONNECTED; 15.16 - tpmif->tpm_instance = instance; 15.17 + tpmif->bi = bi; 15.18 snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid); 15.19 atomic_set(&tpmif->refcnt, 1); 15.20 15.21 @@ -54,12 +54,12 @@ static void free_tpmif(tpmif_t * tpmif) 15.22 kmem_cache_free(tpmif_cachep, tpmif); 15.23 } 15.24 15.25 -tpmif_t *tpmif_find(domid_t domid, long int instance) 15.26 +tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi) 15.27 { 15.28 tpmif_t *tpmif; 15.29 15.30 list_for_each_entry(tpmif, &tpmif_list, tpmif_list) { 15.31 - if (tpmif->tpm_instance == instance) { 15.32 + if (tpmif->bi == bi) { 15.33 if (tpmif->domid == domid) { 15.34 tpmif_get(tpmif); 15.35 return tpmif; 15.36 @@ -69,7 +69,7 @@ tpmif_t *tpmif_find(domid_t domid, long 15.37 } 15.38 } 15.39 15.40 - return alloc_tpmif(domid, instance); 15.41 + return alloc_tpmif(domid, bi); 15.42 } 15.43 15.44 static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
16.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Jun 28 07:51:52 2006 -0600 16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Wed Jun 28 07:52:21 2006 -0600 16.3 @@ -161,7 +161,7 @@ static struct packet *packet_alloc(tpmif 16.4 if (NULL != pak) { 16.5 if (tpmif) { 16.6 pak->tpmif = tpmif; 16.7 - pak->tpm_instance = tpmif->tpm_instance; 16.8 + pak->tpm_instance = tpmback_get_instance(tpmif->bi); 16.9 tpmif_get(tpmif); 16.10 } 16.11 pak->data_len = size; 16.12 @@ -685,95 +685,6 @@ static struct miscdevice vtpms_miscdevic 16.13 }; 16.14 16.15 /*************************************************************** 16.16 - Virtual TPM functions and data stuctures 16.17 -***************************************************************/ 16.18 - 16.19 -static u8 create_cmd[] = { 16.20 - 1, 193, /* 0: TPM_TAG_RQU_COMMAMD */ 16.21 - 0, 0, 0, 19, /* 2: length */ 16.22 - 0, 0, 0, 0x1, /* 6: VTPM_ORD_OPEN */ 16.23 - 0, /* 10: VTPM type */ 16.24 - 0, 0, 0, 0, /* 11: domain id */ 16.25 - 0, 0, 0, 0 /* 15: instance id */ 16.26 -}; 16.27 - 16.28 -int tpmif_vtpm_open(tpmif_t * tpmif, domid_t domid, u32 instance) 16.29 -{ 16.30 - int rc = 0; 16.31 - struct packet *pak; 16.32 - 16.33 - pak = packet_alloc(tpmif, 16.34 - sizeof (create_cmd), 16.35 - create_cmd[1], 16.36 - PACKET_FLAG_DISCARD_RESPONSE | 16.37 - PACKET_FLAG_CHECK_RESPONSESTATUS); 16.38 - if (pak) { 16.39 - u8 buf[sizeof (create_cmd)]; 16.40 - u32 domid_no = htonl((u32) domid); 16.41 - u32 instance_no = htonl(instance); 16.42 - 16.43 - memcpy(buf, create_cmd, sizeof (create_cmd)); 16.44 - 16.45 - memcpy(&buf[11], &domid_no, sizeof (u32)); 16.46 - memcpy(&buf[15], &instance_no, sizeof (u32)); 16.47 - 16.48 - /* copy the buffer into the packet */ 16.49 - rc = packet_set(pak, buf, sizeof (buf)); 16.50 - 16.51 - if (rc == 0) { 16.52 - pak->tpm_instance = 0; 16.53 - rc = vtpm_queue_packet(pak); 16.54 - } 16.55 - if (rc < 0) { 16.56 - /* could not be queued or built */ 16.57 - packet_free(pak); 16.58 - } 16.59 - } else { 16.60 - rc = -ENOMEM; 16.61 - } 16.62 - return rc; 16.63 -} 16.64 - 16.65 -static u8 destroy_cmd[] = { 16.66 - 1, 193, /* 0: TPM_TAG_RQU_COMMAMD */ 16.67 - 0, 0, 0, 14, /* 2: length */ 16.68 - 0, 0, 0, 0x2, /* 6: VTPM_ORD_CLOSE */ 16.69 - 0, 0, 0, 0 /* 10: instance id */ 16.70 -}; 16.71 - 16.72 -int tpmif_vtpm_close(u32 instid) 16.73 -{ 16.74 - int rc = 0; 16.75 - struct packet *pak; 16.76 - 16.77 - pak = packet_alloc(NULL, 16.78 - sizeof (destroy_cmd), 16.79 - destroy_cmd[1], PACKET_FLAG_DISCARD_RESPONSE); 16.80 - if (pak) { 16.81 - u8 buf[sizeof (destroy_cmd)]; 16.82 - u32 instid_no = htonl(instid); 16.83 - 16.84 - memcpy(buf, destroy_cmd, sizeof (destroy_cmd)); 16.85 - memcpy(&buf[10], &instid_no, sizeof (u32)); 16.86 - 16.87 - /* copy the buffer into the packet */ 16.88 - rc = packet_set(pak, buf, sizeof (buf)); 16.89 - 16.90 - if (rc == 0) { 16.91 - pak->tpm_instance = 0; 16.92 - rc = vtpm_queue_packet(pak); 16.93 - } 16.94 - if (rc < 0) { 16.95 - /* could not be queued or built */ 16.96 - packet_free(pak); 16.97 - } 16.98 - } else { 16.99 - rc = -ENOMEM; 16.100 - } 16.101 - return rc; 16.102 -} 16.103 - 16.104 -/*************************************************************** 16.105 Utility functions 16.106 ***************************************************************/ 16.107
17.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Jun 28 07:51:52 2006 -0600 17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Jun 28 07:52:21 2006 -0600 17.3 @@ -45,6 +45,14 @@ static void backend_changed(struct xenbu 17.4 static void frontend_changed(struct xenbus_device *dev, 17.5 enum xenbus_state frontend_state); 17.6 17.7 +long int tpmback_get_instance(struct backend_info *bi) 17.8 +{ 17.9 + long int res = -1; 17.10 + if (bi && bi->is_instance_set) 17.11 + res = bi->instance; 17.12 + return res; 17.13 +} 17.14 + 17.15 static int tpmback_remove(struct xenbus_device *dev) 17.16 { 17.17 struct backend_info *be = dev->dev.driver_data; 17.18 @@ -57,6 +65,7 @@ static int tpmback_remove(struct xenbus_ 17.19 be->backend_watch.node = NULL; 17.20 } 17.21 if (be->tpmif) { 17.22 + be->tpmif->bi = NULL; 17.23 vtpm_release_packets(be->tpmif, 0); 17.24 tpmif_put(be->tpmif); 17.25 be->tpmif = NULL; 17.26 @@ -150,15 +159,10 @@ static void frontend_changed(struct xenb 17.27 break; 17.28 17.29 case XenbusStateClosing: 17.30 - be->tpmif->tpm_instance = -1; 17.31 + be->instance = -1; 17.32 break; 17.33 17.34 case XenbusStateClosed: 17.35 - /* 17.36 - * Notify the vTPM manager about the front-end 17.37 - * having left. 17.38 - */ 17.39 - tpmif_vtpm_close(be->instance); 17.40 device_unregister(&be->dev->dev); 17.41 tpmback_remove(dev); 17.42 break; 17.43 @@ -177,28 +181,10 @@ static void frontend_changed(struct xenb 17.44 17.45 static void maybe_connect(struct backend_info *be) 17.46 { 17.47 - int err; 17.48 - 17.49 if (be->tpmif == NULL || be->tpmif->status == CONNECTED) 17.50 return; 17.51 17.52 connect(be); 17.53 - 17.54 - /* 17.55 - * Notify the vTPM manager about a new front-end. 17.56 - */ 17.57 - err = tpmif_vtpm_open(be->tpmif, 17.58 - be->frontend_id, 17.59 - be->instance); 17.60 - if (err) { 17.61 - xenbus_dev_error(be->dev, err, 17.62 - "queueing vtpm open packet"); 17.63 - /* 17.64 - * Should close down this device and notify FE 17.65 - * about closure. 17.66 - */ 17.67 - return; 17.68 - } 17.69 } 17.70 17.71 17.72 @@ -256,8 +242,7 @@ static int connect_ring(struct backend_i 17.73 } 17.74 17.75 if (!be->tpmif) { 17.76 - be->tpmif = tpmif_find(dev->otherend_id, 17.77 - be->instance); 17.78 + be->tpmif = tpmif_find(dev->otherend_id, be); 17.79 if (IS_ERR(be->tpmif)) { 17.80 err = PTR_ERR(be->tpmif); 17.81 be->tpmif = NULL;
18.1 --- a/linux-2.6-xen-sparse/include/linux/skbuff.h Wed Jun 28 07:51:52 2006 -0600 18.2 +++ b/linux-2.6-xen-sparse/include/linux/skbuff.h Wed Jun 28 07:52:21 2006 -0600 18.3 @@ -134,9 +134,10 @@ struct skb_frag_struct { 18.4 struct skb_shared_info { 18.5 atomic_t dataref; 18.6 unsigned short nr_frags; 18.7 - unsigned short tso_size; 18.8 - unsigned short tso_segs; 18.9 - unsigned short ufo_size; 18.10 + unsigned short gso_size; 18.11 + /* Warning: this field is not always filled in (UFO)! */ 18.12 + unsigned short gso_segs; 18.13 + unsigned short gso_type; 18.14 unsigned int ip6_frag_id; 18.15 struct sk_buff *frag_list; 18.16 skb_frag_t frags[MAX_SKB_FRAGS]; 18.17 @@ -168,6 +169,14 @@ enum { 18.18 SKB_FCLONE_CLONE, 18.19 }; 18.20 18.21 +enum { 18.22 + SKB_GSO_TCPV4 = 1 << 0, 18.23 + SKB_GSO_UDPV4 = 1 << 1, 18.24 + 18.25 + /* This indicates the skb is from an untrusted source. */ 18.26 + SKB_GSO_DODGY = 1 << 2, 18.27 +}; 18.28 + 18.29 /** 18.30 * struct sk_buff - socket buffer 18.31 * @next: Next buffer in list 18.32 @@ -1157,18 +1166,34 @@ static inline int skb_can_coalesce(struc 18.33 return 0; 18.34 } 18.35 18.36 +static inline int __skb_linearize(struct sk_buff *skb) 18.37 +{ 18.38 + return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM; 18.39 +} 18.40 + 18.41 /** 18.42 * skb_linearize - convert paged skb to linear one 18.43 * @skb: buffer to linarize 18.44 - * @gfp: allocation mode 18.45 * 18.46 * If there is no free memory -ENOMEM is returned, otherwise zero 18.47 * is returned and the old skb data released. 18.48 */ 18.49 -extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp); 18.50 -static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp) 18.51 +static inline int skb_linearize(struct sk_buff *skb) 18.52 { 18.53 - return __skb_linearize(skb, gfp); 18.54 + return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0; 18.55 +} 18.56 + 18.57 +/** 18.58 + * skb_linearize_cow - make sure skb is linear and writable 18.59 + * @skb: buffer to process 18.60 + * 18.61 + * If there is no free memory -ENOMEM is returned, otherwise zero 18.62 + * is returned and the old skb data released. 18.63 + */ 18.64 +static inline int skb_linearize_cow(struct sk_buff *skb) 18.65 +{ 18.66 + return skb_is_nonlinear(skb) || skb_cloned(skb) ? 18.67 + __skb_linearize(skb) : 0; 18.68 } 18.69 18.70 /** 18.71 @@ -1263,6 +1288,7 @@ extern void skb_split(struct sk_b 18.72 struct sk_buff *skb1, const u32 len); 18.73 18.74 extern void skb_release_data(struct sk_buff *skb); 18.75 +extern struct sk_buff *skb_segment(struct sk_buff *skb, int features); 18.76 18.77 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, 18.78 int len, void *buffer)
19.1 --- a/linux-2.6-xen-sparse/net/core/dev.c Wed Jun 28 07:51:52 2006 -0600 19.2 +++ b/linux-2.6-xen-sparse/net/core/dev.c Wed Jun 28 07:52:21 2006 -0600 19.3 @@ -115,6 +115,7 @@ 19.4 #include <net/iw_handler.h> 19.5 #endif /* CONFIG_NET_RADIO */ 19.6 #include <asm/current.h> 19.7 +#include <linux/err.h> 19.8 19.9 #ifdef CONFIG_XEN 19.10 #include <net/ip.h> 19.11 @@ -1038,7 +1039,7 @@ static inline void net_timestamp(struct 19.12 * taps currently in use. 19.13 */ 19.14 19.15 -void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) 19.16 +static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) 19.17 { 19.18 struct packet_type *ptype; 19.19 19.20 @@ -1112,6 +1113,45 @@ out: 19.21 return ret; 19.22 } 19.23 19.24 +/** 19.25 + * skb_gso_segment - Perform segmentation on skb. 19.26 + * @skb: buffer to segment 19.27 + * @features: features for the output path (see dev->features) 19.28 + * 19.29 + * This function segments the given skb and returns a list of segments. 19.30 + * 19.31 + * It may return NULL if the skb requires no segmentation. This is 19.32 + * only possible when GSO is used for verifying header integrity. 19.33 + */ 19.34 +struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) 19.35 +{ 19.36 + struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 19.37 + struct packet_type *ptype; 19.38 + int type = skb->protocol; 19.39 + 19.40 + BUG_ON(skb_shinfo(skb)->frag_list); 19.41 + BUG_ON(skb->ip_summed != CHECKSUM_HW); 19.42 + 19.43 + skb->mac.raw = skb->data; 19.44 + skb->mac_len = skb->nh.raw - skb->data; 19.45 + __skb_pull(skb, skb->mac_len); 19.46 + 19.47 + rcu_read_lock(); 19.48 + list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { 19.49 + if (ptype->type == type && !ptype->dev && ptype->gso_segment) { 19.50 + segs = ptype->gso_segment(skb, features); 19.51 + break; 19.52 + } 19.53 + } 19.54 + rcu_read_unlock(); 19.55 + 19.56 + __skb_push(skb, skb->data - skb->mac.raw); 19.57 + 19.58 + return segs; 19.59 +} 19.60 + 19.61 +EXPORT_SYMBOL(skb_gso_segment); 19.62 + 19.63 /* Take action when hardware reception checksum errors are detected. */ 19.64 #ifdef CONFIG_BUG 19.65 void netdev_rx_csum_fault(struct net_device *dev) 19.66 @@ -1148,75 +1188,108 @@ static inline int illegal_highdma(struct 19.67 #define illegal_highdma(dev, skb) (0) 19.68 #endif 19.69 19.70 -/* Keep head the same: replace data */ 19.71 -int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask) 19.72 +struct dev_gso_cb { 19.73 + void (*destructor)(struct sk_buff *skb); 19.74 +}; 19.75 + 19.76 +#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb) 19.77 + 19.78 +static void dev_gso_skb_destructor(struct sk_buff *skb) 19.79 +{ 19.80 + struct dev_gso_cb *cb; 19.81 + 19.82 + do { 19.83 + struct sk_buff *nskb = skb->next; 19.84 + 19.85 + skb->next = nskb->next; 19.86 + nskb->next = NULL; 19.87 + kfree_skb(nskb); 19.88 + } while (skb->next); 19.89 + 19.90 + cb = DEV_GSO_CB(skb); 19.91 + if (cb->destructor) 19.92 + cb->destructor(skb); 19.93 +} 19.94 + 19.95 +/** 19.96 + * dev_gso_segment - Perform emulated hardware segmentation on skb. 19.97 + * @skb: buffer to segment 19.98 + * 19.99 + * This function segments the given skb and stores the list of segments 19.100 + * in skb->next. 19.101 + */ 19.102 +static int dev_gso_segment(struct sk_buff *skb) 19.103 { 19.104 - unsigned int size; 19.105 - u8 *data; 19.106 - long offset; 19.107 - struct skb_shared_info *ninfo; 19.108 - int headerlen = skb->data - skb->head; 19.109 - int expand = (skb->tail + skb->data_len) - skb->end; 19.110 - 19.111 - if (skb_shared(skb)) 19.112 - BUG(); 19.113 - 19.114 - if (expand <= 0) 19.115 - expand = 0; 19.116 - 19.117 - size = skb->end - skb->head + expand; 19.118 - size = SKB_DATA_ALIGN(size); 19.119 - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); 19.120 - if (!data) 19.121 - return -ENOMEM; 19.122 - 19.123 - /* Copy entire thing */ 19.124 - if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len)) 19.125 - BUG(); 19.126 - 19.127 - /* Set up shinfo */ 19.128 - ninfo = (struct skb_shared_info*)(data + size); 19.129 - atomic_set(&ninfo->dataref, 1); 19.130 - ninfo->tso_size = skb_shinfo(skb)->tso_size; 19.131 - ninfo->tso_segs = skb_shinfo(skb)->tso_segs; 19.132 - ninfo->nr_frags = 0; 19.133 - ninfo->frag_list = NULL; 19.134 - 19.135 - /* Offset between the two in bytes */ 19.136 - offset = data - skb->head; 19.137 - 19.138 - /* Free old data. */ 19.139 - skb_release_data(skb); 19.140 - 19.141 - skb->head = data; 19.142 - skb->end = data + size; 19.143 - 19.144 - /* Set up new pointers */ 19.145 - skb->h.raw += offset; 19.146 - skb->nh.raw += offset; 19.147 - skb->mac.raw += offset; 19.148 - skb->tail += offset; 19.149 - skb->data += offset; 19.150 - 19.151 - /* We are no longer a clone, even if we were. */ 19.152 - skb->cloned = 0; 19.153 - 19.154 - skb->tail += skb->data_len; 19.155 - skb->data_len = 0; 19.156 + struct net_device *dev = skb->dev; 19.157 + struct sk_buff *segs; 19.158 + int features = dev->features & ~(illegal_highdma(dev, skb) ? 19.159 + NETIF_F_SG : 0); 19.160 + 19.161 + segs = skb_gso_segment(skb, features); 19.162 + 19.163 + /* Verifying header integrity only. */ 19.164 + if (!segs) 19.165 + return 0; 19.166 + 19.167 + if (unlikely(IS_ERR(segs))) 19.168 + return PTR_ERR(segs); 19.169 + 19.170 + skb->next = segs; 19.171 + DEV_GSO_CB(skb)->destructor = skb->destructor; 19.172 + skb->destructor = dev_gso_skb_destructor; 19.173 + 19.174 + return 0; 19.175 +} 19.176 + 19.177 +int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 19.178 +{ 19.179 + if (likely(!skb->next)) { 19.180 + if (netdev_nit) 19.181 + dev_queue_xmit_nit(skb, dev); 19.182 + 19.183 + if (netif_needs_gso(dev, skb)) { 19.184 + if (unlikely(dev_gso_segment(skb))) 19.185 + goto out_kfree_skb; 19.186 + if (skb->next) 19.187 + goto gso; 19.188 + } 19.189 + 19.190 + return dev->hard_start_xmit(skb, dev); 19.191 + } 19.192 + 19.193 +gso: 19.194 + do { 19.195 + struct sk_buff *nskb = skb->next; 19.196 + int rc; 19.197 + 19.198 + skb->next = nskb->next; 19.199 + nskb->next = NULL; 19.200 + rc = dev->hard_start_xmit(nskb, dev); 19.201 + if (unlikely(rc)) { 19.202 + nskb->next = skb->next; 19.203 + skb->next = nskb; 19.204 + return rc; 19.205 + } 19.206 + if (unlikely(netif_queue_stopped(dev) && skb->next)) 19.207 + return NETDEV_TX_BUSY; 19.208 + } while (skb->next); 19.209 + 19.210 + skb->destructor = DEV_GSO_CB(skb)->destructor; 19.211 + 19.212 +out_kfree_skb: 19.213 + kfree_skb(skb); 19.214 return 0; 19.215 } 19.216 19.217 #define HARD_TX_LOCK(dev, cpu) { \ 19.218 if ((dev->features & NETIF_F_LLTX) == 0) { \ 19.219 - spin_lock(&dev->xmit_lock); \ 19.220 - dev->xmit_lock_owner = cpu; \ 19.221 + netif_tx_lock(dev); \ 19.222 } \ 19.223 } 19.224 19.225 #define HARD_TX_UNLOCK(dev) { \ 19.226 if ((dev->features & NETIF_F_LLTX) == 0) { \ 19.227 - dev->xmit_lock_owner = -1; \ 19.228 - spin_unlock(&dev->xmit_lock); \ 19.229 + netif_tx_unlock(dev); \ 19.230 } \ 19.231 } 19.232 19.233 @@ -1289,9 +1362,19 @@ int dev_queue_xmit(struct sk_buff *skb) 19.234 struct Qdisc *q; 19.235 int rc = -ENOMEM; 19.236 19.237 + /* If a checksum-deferred packet is forwarded to a device that needs a 19.238 + * checksum, correct the pointers and force checksumming. 19.239 + */ 19.240 + if (skb_checksum_setup(skb)) 19.241 + goto out_kfree_skb; 19.242 + 19.243 + /* GSO will handle the following emulations directly. */ 19.244 + if (netif_needs_gso(dev, skb)) 19.245 + goto gso; 19.246 + 19.247 if (skb_shinfo(skb)->frag_list && 19.248 !(dev->features & NETIF_F_FRAGLIST) && 19.249 - __skb_linearize(skb, GFP_ATOMIC)) 19.250 + __skb_linearize(skb)) 19.251 goto out_kfree_skb; 19.252 19.253 /* Fragmented skb is linearized if device does not support SG, 19.254 @@ -1300,31 +1383,26 @@ int dev_queue_xmit(struct sk_buff *skb) 19.255 */ 19.256 if (skb_shinfo(skb)->nr_frags && 19.257 (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && 19.258 - __skb_linearize(skb, GFP_ATOMIC)) 19.259 + __skb_linearize(skb)) 19.260 goto out_kfree_skb; 19.261 19.262 - /* If a checksum-deferred packet is forwarded to a device that needs a 19.263 - * checksum, correct the pointers and force checksumming. 19.264 - */ 19.265 - if(skb_checksum_setup(skb)) 19.266 - goto out_kfree_skb; 19.267 - 19.268 /* If packet is not checksummed and device does not support 19.269 * checksumming for this protocol, complete checksumming here. 19.270 */ 19.271 if (skb->ip_summed == CHECKSUM_HW && 19.272 - (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) && 19.273 + (!(dev->features & NETIF_F_GEN_CSUM) && 19.274 (!(dev->features & NETIF_F_IP_CSUM) || 19.275 skb->protocol != htons(ETH_P_IP)))) 19.276 if (skb_checksum_help(skb, 0)) 19.277 goto out_kfree_skb; 19.278 19.279 +gso: 19.280 spin_lock_prefetch(&dev->queue_lock); 19.281 19.282 /* Disable soft irqs for various locks below. Also 19.283 * stops preemption for RCU. 19.284 */ 19.285 - local_bh_disable(); 19.286 + rcu_read_lock_bh(); 19.287 19.288 /* Updates of qdisc are serialized by queue_lock. 19.289 * The struct Qdisc which is pointed to by qdisc is now a 19.290 @@ -1358,8 +1436,8 @@ int dev_queue_xmit(struct sk_buff *skb) 19.291 /* The device has no queue. Common case for software devices: 19.292 loopback, all the sorts of tunnels... 19.293 19.294 - Really, it is unlikely that xmit_lock protection is necessary here. 19.295 - (f.e. loopback and IP tunnels are clean ignoring statistics 19.296 + Really, it is unlikely that netif_tx_lock protection is necessary 19.297 + here. (f.e. loopback and IP tunnels are clean ignoring statistics 19.298 counters.) 19.299 However, it is possible, that they rely on protection 19.300 made by us here. 19.301 @@ -1375,11 +1453,8 @@ int dev_queue_xmit(struct sk_buff *skb) 19.302 HARD_TX_LOCK(dev, cpu); 19.303 19.304 if (!netif_queue_stopped(dev)) { 19.305 - if (netdev_nit) 19.306 - dev_queue_xmit_nit(skb, dev); 19.307 - 19.308 rc = 0; 19.309 - if (!dev->hard_start_xmit(skb, dev)) { 19.310 + if (!dev_hard_start_xmit(skb, dev)) { 19.311 HARD_TX_UNLOCK(dev); 19.312 goto out; 19.313 } 19.314 @@ -1398,13 +1473,13 @@ int dev_queue_xmit(struct sk_buff *skb) 19.315 } 19.316 19.317 rc = -ENETDOWN; 19.318 - local_bh_enable(); 19.319 + rcu_read_unlock_bh(); 19.320 19.321 out_kfree_skb: 19.322 kfree_skb(skb); 19.323 return rc; 19.324 out: 19.325 - local_bh_enable(); 19.326 + rcu_read_unlock_bh(); 19.327 return rc; 19.328 } 19.329 19.330 @@ -2732,7 +2807,7 @@ int register_netdevice(struct net_device 19.331 BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); 19.332 19.333 spin_lock_init(&dev->queue_lock); 19.334 - spin_lock_init(&dev->xmit_lock); 19.335 + spin_lock_init(&dev->_xmit_lock); 19.336 dev->xmit_lock_owner = -1; 19.337 #ifdef CONFIG_NET_CLS_ACT 19.338 spin_lock_init(&dev->ingress_lock); 19.339 @@ -2776,9 +2851,7 @@ int register_netdevice(struct net_device 19.340 19.341 /* Fix illegal SG+CSUM combinations. */ 19.342 if ((dev->features & NETIF_F_SG) && 19.343 - !(dev->features & (NETIF_F_IP_CSUM | 19.344 - NETIF_F_NO_CSUM | 19.345 - NETIF_F_HW_CSUM))) { 19.346 + !(dev->features & NETIF_F_ALL_CSUM)) { 19.347 printk("%s: Dropping NETIF_F_SG since no checksum feature.\n", 19.348 dev->name); 19.349 dev->features &= ~NETIF_F_SG; 19.350 @@ -3330,7 +3403,6 @@ subsys_initcall(net_dev_init); 19.351 EXPORT_SYMBOL(__dev_get_by_index); 19.352 EXPORT_SYMBOL(__dev_get_by_name); 19.353 EXPORT_SYMBOL(__dev_remove_pack); 19.354 -EXPORT_SYMBOL(__skb_linearize); 19.355 EXPORT_SYMBOL(dev_valid_name); 19.356 EXPORT_SYMBOL(dev_add_pack); 19.357 EXPORT_SYMBOL(dev_alloc_name);
20.1 --- a/linux-2.6-xen-sparse/net/core/skbuff.c Wed Jun 28 07:51:52 2006 -0600 20.2 +++ b/linux-2.6-xen-sparse/net/core/skbuff.c Wed Jun 28 07:52:21 2006 -0600 20.3 @@ -165,9 +165,9 @@ struct sk_buff *__alloc_skb(unsigned int 20.4 shinfo = skb_shinfo(skb); 20.5 atomic_set(&shinfo->dataref, 1); 20.6 shinfo->nr_frags = 0; 20.7 - shinfo->tso_size = 0; 20.8 - shinfo->tso_segs = 0; 20.9 - shinfo->ufo_size = 0; 20.10 + shinfo->gso_size = 0; 20.11 + shinfo->gso_segs = 0; 20.12 + shinfo->gso_type = 0; 20.13 shinfo->ip6_frag_id = 0; 20.14 shinfo->frag_list = NULL; 20.15 20.16 @@ -237,9 +237,9 @@ struct sk_buff *alloc_skb_from_cache(kme 20.17 shinfo = skb_shinfo(skb); 20.18 atomic_set(&shinfo->dataref, 1); 20.19 shinfo->nr_frags = 0; 20.20 - shinfo->tso_size = 0; 20.21 - shinfo->tso_segs = 0; 20.22 - shinfo->ufo_size = 0; 20.23 + shinfo->gso_size = 0; 20.24 + shinfo->gso_segs = 0; 20.25 + shinfo->gso_type = 0; 20.26 shinfo->ip6_frag_id = 0; 20.27 shinfo->frag_list = NULL; 20.28 20.29 @@ -524,8 +524,9 @@ static void copy_skb_header(struct sk_bu 20.30 new->tc_index = old->tc_index; 20.31 #endif 20.32 atomic_set(&new->users, 1); 20.33 - skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size; 20.34 - skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs; 20.35 + skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; 20.36 + skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; 20.37 + skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; 20.38 } 20.39 20.40 /** 20.41 @@ -1800,6 +1801,133 @@ int skb_append_datato_frags(struct sock 20.42 return 0; 20.43 } 20.44 20.45 +/** 20.46 + * skb_segment - Perform protocol segmentation on skb. 20.47 + * @skb: buffer to segment 20.48 + * @features: features for the output path (see dev->features) 20.49 + * 20.50 + * This function performs segmentation on the given skb. It returns 20.51 + * the segment at the given position. It returns NULL if there are 20.52 + * no more segments to generate, or when an error is encountered. 20.53 + */ 20.54 +struct sk_buff *skb_segment(struct sk_buff *skb, int features) 20.55 +{ 20.56 + struct sk_buff *segs = NULL; 20.57 + struct sk_buff *tail = NULL; 20.58 + unsigned int mss = skb_shinfo(skb)->gso_size; 20.59 + unsigned int doffset = skb->data - skb->mac.raw; 20.60 + unsigned int offset = doffset; 20.61 + unsigned int headroom; 20.62 + unsigned int len; 20.63 + int sg = features & NETIF_F_SG; 20.64 + int nfrags = skb_shinfo(skb)->nr_frags; 20.65 + int err = -ENOMEM; 20.66 + int i = 0; 20.67 + int pos; 20.68 + 20.69 + __skb_push(skb, doffset); 20.70 + headroom = skb_headroom(skb); 20.71 + pos = skb_headlen(skb); 20.72 + 20.73 + do { 20.74 + struct sk_buff *nskb; 20.75 + skb_frag_t *frag; 20.76 + int hsize, nsize; 20.77 + int k; 20.78 + int size; 20.79 + 20.80 + len = skb->len - offset; 20.81 + if (len > mss) 20.82 + len = mss; 20.83 + 20.84 + hsize = skb_headlen(skb) - offset; 20.85 + if (hsize < 0) 20.86 + hsize = 0; 20.87 + nsize = hsize + doffset; 20.88 + if (nsize > len + doffset || !sg) 20.89 + nsize = len + doffset; 20.90 + 20.91 + nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); 20.92 + if (unlikely(!nskb)) 20.93 + goto err; 20.94 + 20.95 + if (segs) 20.96 + tail->next = nskb; 20.97 + else 20.98 + segs = nskb; 20.99 + tail = nskb; 20.100 + 20.101 + nskb->dev = skb->dev; 20.102 + nskb->priority = skb->priority; 20.103 + nskb->protocol = skb->protocol; 20.104 + nskb->dst = dst_clone(skb->dst); 20.105 + memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); 20.106 + nskb->pkt_type = skb->pkt_type; 20.107 + nskb->mac_len = skb->mac_len; 20.108 + 20.109 + skb_reserve(nskb, headroom); 20.110 + nskb->mac.raw = nskb->data; 20.111 + nskb->nh.raw = nskb->data + skb->mac_len; 20.112 + nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw); 20.113 + memcpy(skb_put(nskb, doffset), skb->data, doffset); 20.114 + 20.115 + if (!sg) { 20.116 + nskb->csum = skb_copy_and_csum_bits(skb, offset, 20.117 + skb_put(nskb, len), 20.118 + len, 0); 20.119 + continue; 20.120 + } 20.121 + 20.122 + frag = skb_shinfo(nskb)->frags; 20.123 + k = 0; 20.124 + 20.125 + nskb->ip_summed = CHECKSUM_HW; 20.126 + nskb->csum = skb->csum; 20.127 + memcpy(skb_put(nskb, hsize), skb->data + offset, hsize); 20.128 + 20.129 + while (pos < offset + len) { 20.130 + BUG_ON(i >= nfrags); 20.131 + 20.132 + *frag = skb_shinfo(skb)->frags[i]; 20.133 + get_page(frag->page); 20.134 + size = frag->size; 20.135 + 20.136 + if (pos < offset) { 20.137 + frag->page_offset += offset - pos; 20.138 + frag->size -= offset - pos; 20.139 + } 20.140 + 20.141 + k++; 20.142 + 20.143 + if (pos + size <= offset + len) { 20.144 + i++; 20.145 + pos += size; 20.146 + } else { 20.147 + frag->size -= pos + size - (offset + len); 20.148 + break; 20.149 + } 20.150 + 20.151 + frag++; 20.152 + } 20.153 + 20.154 + skb_shinfo(nskb)->nr_frags = k; 20.155 + nskb->data_len = len - hsize; 20.156 + nskb->len += nskb->data_len; 20.157 + nskb->truesize += nskb->data_len; 20.158 + } while ((offset += len) < skb->len); 20.159 + 20.160 + return segs; 20.161 + 20.162 +err: 20.163 + while ((skb = segs)) { 20.164 + segs = skb->next; 20.165 + kfree(skb); 20.166 + } 20.167 + return ERR_PTR(err); 20.168 +} 20.169 + 20.170 +EXPORT_SYMBOL_GPL(skb_segment); 20.171 + 20.172 void __init skb_init(void) 20.173 { 20.174 skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/patches/linux-2.6.16.13/net-gso.patch Wed Jun 28 07:52:21 2006 -0600 21.3 @@ -0,0 +1,2907 @@ 21.4 +diff --git a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt 21.5 +index 3c0a5ba..847cedb 100644 21.6 +--- a/Documentation/networking/netdevices.txt 21.7 ++++ b/Documentation/networking/netdevices.txt 21.8 +@@ -42,9 +42,9 @@ dev->get_stats: 21.9 + Context: nominally process, but don't sleep inside an rwlock 21.10 + 21.11 + dev->hard_start_xmit: 21.12 +- Synchronization: dev->xmit_lock spinlock. 21.13 ++ Synchronization: netif_tx_lock spinlock. 21.14 + When the driver sets NETIF_F_LLTX in dev->features this will be 21.15 +- called without holding xmit_lock. In this case the driver 21.16 ++ called without holding netif_tx_lock. In this case the driver 21.17 + has to lock by itself when needed. It is recommended to use a try lock 21.18 + for this and return -1 when the spin lock fails. 21.19 + The locking there should also properly protect against 21.20 +@@ -62,12 +62,12 @@ dev->hard_start_xmit: 21.21 + Only valid when NETIF_F_LLTX is set. 21.22 + 21.23 + dev->tx_timeout: 21.24 +- Synchronization: dev->xmit_lock spinlock. 21.25 ++ Synchronization: netif_tx_lock spinlock. 21.26 + Context: BHs disabled 21.27 + Notes: netif_queue_stopped() is guaranteed true 21.28 + 21.29 + dev->set_multicast_list: 21.30 +- Synchronization: dev->xmit_lock spinlock. 21.31 ++ Synchronization: netif_tx_lock spinlock. 21.32 + Context: BHs disabled 21.33 + 21.34 + dev->poll: 21.35 +diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c 21.36 +index 4be9769..2e7cac7 100644 21.37 +--- a/drivers/block/aoe/aoenet.c 21.38 ++++ b/drivers/block/aoe/aoenet.c 21.39 +@@ -95,9 +95,8 @@ mac_addr(char addr[6]) 21.40 + static struct sk_buff * 21.41 + skb_check(struct sk_buff *skb) 21.42 + { 21.43 +- if (skb_is_nonlinear(skb)) 21.44 + if ((skb = skb_share_check(skb, GFP_ATOMIC))) 21.45 +- if (skb_linearize(skb, GFP_ATOMIC) < 0) { 21.46 ++ if (skb_linearize(skb)) { 21.47 + dev_kfree_skb(skb); 21.48 + return NULL; 21.49 + } 21.50 +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 21.51 +index a2408d7..c90e620 100644 21.52 +--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 21.53 ++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 21.54 +@@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_ 21.55 + 21.56 + ipoib_mcast_stop_thread(dev, 0); 21.57 + 21.58 +- spin_lock_irqsave(&dev->xmit_lock, flags); 21.59 ++ local_irq_save(flags); 21.60 ++ netif_tx_lock(dev); 21.61 + spin_lock(&priv->lock); 21.62 + 21.63 + /* 21.64 +@@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_ 21.65 + } 21.66 + 21.67 + spin_unlock(&priv->lock); 21.68 +- spin_unlock_irqrestore(&dev->xmit_lock, flags); 21.69 ++ netif_tx_unlock(dev); 21.70 ++ local_irq_restore(flags); 21.71 + 21.72 + /* We have to cancel outside of the spinlock */ 21.73 + list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { 21.74 +diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c 21.75 +index 6711eb6..8d2351f 100644 21.76 +--- a/drivers/media/dvb/dvb-core/dvb_net.c 21.77 ++++ b/drivers/media/dvb/dvb-core/dvb_net.c 21.78 +@@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void 21.79 + 21.80 + dvb_net_feed_stop(dev); 21.81 + priv->rx_mode = RX_MODE_UNI; 21.82 +- spin_lock_bh(&dev->xmit_lock); 21.83 ++ netif_tx_lock_bh(dev); 21.84 + 21.85 + if (dev->flags & IFF_PROMISC) { 21.86 + dprintk("%s: promiscuous mode\n", dev->name); 21.87 +@@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void 21.88 + } 21.89 + } 21.90 + 21.91 +- spin_unlock_bh(&dev->xmit_lock); 21.92 ++ netif_tx_unlock_bh(dev); 21.93 + dvb_net_feed_start(dev); 21.94 + } 21.95 + 21.96 +diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c 21.97 +index dd41049..6615583 100644 21.98 +--- a/drivers/net/8139cp.c 21.99 ++++ b/drivers/net/8139cp.c 21.100 +@@ -794,7 +794,7 @@ #endif 21.101 + entry = cp->tx_head; 21.102 + eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; 21.103 + if (dev->features & NETIF_F_TSO) 21.104 +- mss = skb_shinfo(skb)->tso_size; 21.105 ++ mss = skb_shinfo(skb)->gso_size; 21.106 + 21.107 + if (skb_shinfo(skb)->nr_frags == 0) { 21.108 + struct cp_desc *txd = &cp->tx_ring[entry]; 21.109 +diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c 21.110 +index a24200d..b5e39a1 100644 21.111 +--- a/drivers/net/bnx2.c 21.112 ++++ b/drivers/net/bnx2.c 21.113 +@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp) 21.114 + skb = tx_buf->skb; 21.115 + #ifdef BCM_TSO 21.116 + /* partial BD completions possible with TSO packets */ 21.117 +- if (skb_shinfo(skb)->tso_size) { 21.118 ++ if (skb_shinfo(skb)->gso_size) { 21.119 + u16 last_idx, last_ring_idx; 21.120 + 21.121 + last_idx = sw_cons + 21.122 +@@ -1948,7 +1948,7 @@ bnx2_poll(struct net_device *dev, int *b 21.123 + return 1; 21.124 + } 21.125 + 21.126 +-/* Called with rtnl_lock from vlan functions and also dev->xmit_lock 21.127 ++/* Called with rtnl_lock from vlan functions and also netif_tx_lock 21.128 + * from set_multicast. 21.129 + */ 21.130 + static void 21.131 +@@ -4403,7 +4403,7 @@ bnx2_vlan_rx_kill_vid(struct net_device 21.132 + } 21.133 + #endif 21.134 + 21.135 +-/* Called with dev->xmit_lock. 21.136 ++/* Called with netif_tx_lock. 21.137 + * hard_start_xmit is pseudo-lockless - a lock is only required when 21.138 + * the tx queue is full. This way, we get the benefit of lockless 21.139 + * operations most of the time without the complexities to handle 21.140 +@@ -4441,7 +4441,7 @@ bnx2_start_xmit(struct sk_buff *skb, str 21.141 + (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); 21.142 + } 21.143 + #ifdef BCM_TSO 21.144 +- if ((mss = skb_shinfo(skb)->tso_size) && 21.145 ++ if ((mss = skb_shinfo(skb)->gso_size) && 21.146 + (skb->len > (bp->dev->mtu + ETH_HLEN))) { 21.147 + u32 tcp_opt_len, ip_tcp_len; 21.148 + 21.149 +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c 21.150 +index bcf9f17..e970921 100644 21.151 +--- a/drivers/net/bonding/bond_main.c 21.152 ++++ b/drivers/net/bonding/bond_main.c 21.153 +@@ -1145,8 +1145,7 @@ int bond_sethwaddr(struct net_device *bo 21.154 + } 21.155 + 21.156 + #define BOND_INTERSECT_FEATURES \ 21.157 +- (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ 21.158 +- NETIF_F_TSO|NETIF_F_UFO) 21.159 ++ (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) 21.160 + 21.161 + /* 21.162 + * Compute the common dev->feature set available to all slaves. Some 21.163 +@@ -1164,9 +1163,7 @@ static int bond_compute_features(struct 21.164 + features &= (slave->dev->features & BOND_INTERSECT_FEATURES); 21.165 + 21.166 + if ((features & NETIF_F_SG) && 21.167 +- !(features & (NETIF_F_IP_CSUM | 21.168 +- NETIF_F_NO_CSUM | 21.169 +- NETIF_F_HW_CSUM))) 21.170 ++ !(features & NETIF_F_ALL_CSUM)) 21.171 + features &= ~NETIF_F_SG; 21.172 + 21.173 + /* 21.174 +@@ -4147,7 +4144,7 @@ static int bond_init(struct net_device * 21.175 + */ 21.176 + bond_dev->features |= NETIF_F_VLAN_CHALLENGED; 21.177 + 21.178 +- /* don't acquire bond device's xmit_lock when 21.179 ++ /* don't acquire bond device's netif_tx_lock when 21.180 + * transmitting */ 21.181 + bond_dev->features |= NETIF_F_LLTX; 21.182 + 21.183 +diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c 21.184 +index 30ff8ea..7b7d360 100644 21.185 +--- a/drivers/net/chelsio/sge.c 21.186 ++++ b/drivers/net/chelsio/sge.c 21.187 +@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s 21.188 + struct cpl_tx_pkt *cpl; 21.189 + 21.190 + #ifdef NETIF_F_TSO 21.191 +- if (skb_shinfo(skb)->tso_size) { 21.192 ++ if (skb_shinfo(skb)->gso_size) { 21.193 + int eth_type; 21.194 + struct cpl_tx_pkt_lso *hdr; 21.195 + 21.196 +@@ -1434,7 +1434,7 @@ #ifdef NETIF_F_TSO 21.197 + hdr->ip_hdr_words = skb->nh.iph->ihl; 21.198 + hdr->tcp_hdr_words = skb->h.th->doff; 21.199 + hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type, 21.200 +- skb_shinfo(skb)->tso_size)); 21.201 ++ skb_shinfo(skb)->gso_size)); 21.202 + hdr->len = htonl(skb->len - sizeof(*hdr)); 21.203 + cpl = (struct cpl_tx_pkt *)hdr; 21.204 + sge->stats.tx_lso_pkts++; 21.205 +diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c 21.206 +index fa29402..681d284 100644 21.207 +--- a/drivers/net/e1000/e1000_main.c 21.208 ++++ b/drivers/net/e1000/e1000_main.c 21.209 +@@ -2526,7 +2526,7 @@ #ifdef NETIF_F_TSO 21.210 + uint8_t ipcss, ipcso, tucss, tucso, hdr_len; 21.211 + int err; 21.212 + 21.213 +- if (skb_shinfo(skb)->tso_size) { 21.214 ++ if (skb_shinfo(skb)->gso_size) { 21.215 + if (skb_header_cloned(skb)) { 21.216 + err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); 21.217 + if (err) 21.218 +@@ -2534,7 +2534,7 @@ #ifdef NETIF_F_TSO 21.219 + } 21.220 + 21.221 + hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); 21.222 +- mss = skb_shinfo(skb)->tso_size; 21.223 ++ mss = skb_shinfo(skb)->gso_size; 21.224 + if (skb->protocol == ntohs(ETH_P_IP)) { 21.225 + skb->nh.iph->tot_len = 0; 21.226 + skb->nh.iph->check = 0; 21.227 +@@ -2651,7 +2651,7 @@ #ifdef NETIF_F_TSO 21.228 + * tso gets written back prematurely before the data is fully 21.229 + * DMAd to the controller */ 21.230 + if (!skb->data_len && tx_ring->last_tx_tso && 21.231 +- !skb_shinfo(skb)->tso_size) { 21.232 ++ !skb_shinfo(skb)->gso_size) { 21.233 + tx_ring->last_tx_tso = 0; 21.234 + size -= 4; 21.235 + } 21.236 +@@ -2893,7 +2893,7 @@ #endif 21.237 + } 21.238 + 21.239 + #ifdef NETIF_F_TSO 21.240 +- mss = skb_shinfo(skb)->tso_size; 21.241 ++ mss = skb_shinfo(skb)->gso_size; 21.242 + /* The controller does a simple calculation to 21.243 + * make sure there is enough room in the FIFO before 21.244 + * initiating the DMA for each buffer. The calc is: 21.245 +@@ -2935,7 +2935,7 @@ #endif 21.246 + #ifdef NETIF_F_TSO 21.247 + /* Controller Erratum workaround */ 21.248 + if (!skb->data_len && tx_ring->last_tx_tso && 21.249 +- !skb_shinfo(skb)->tso_size) 21.250 ++ !skb_shinfo(skb)->gso_size) 21.251 + count++; 21.252 + #endif 21.253 + 21.254 +diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c 21.255 +index 3682ec6..c35f16e 100644 21.256 +--- a/drivers/net/forcedeth.c 21.257 ++++ b/drivers/net/forcedeth.c 21.258 +@@ -482,9 +482,9 @@ #define LPA_1000HALF 0x0400 21.259 + * critical parts: 21.260 + * - rx is (pseudo-) lockless: it relies on the single-threading provided 21.261 + * by the arch code for interrupts. 21.262 +- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission 21.263 ++ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission 21.264 + * needs dev->priv->lock :-( 21.265 +- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock. 21.266 ++ * - set_multicast_list: preparation lockless, relies on netif_tx_lock. 21.267 + */ 21.268 + 21.269 + /* in dev: base, irq */ 21.270 +@@ -1016,7 +1016,7 @@ static void drain_ring(struct net_device 21.271 + 21.272 + /* 21.273 + * nv_start_xmit: dev->hard_start_xmit function 21.274 +- * Called with dev->xmit_lock held. 21.275 ++ * Called with netif_tx_lock held. 21.276 + */ 21.277 + static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) 21.278 + { 21.279 +@@ -1105,8 +1105,8 @@ static int nv_start_xmit(struct sk_buff 21.280 + np->tx_skbuff[nr] = skb; 21.281 + 21.282 + #ifdef NETIF_F_TSO 21.283 +- if (skb_shinfo(skb)->tso_size) 21.284 +- tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); 21.285 ++ if (skb_shinfo(skb)->gso_size) 21.286 ++ tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); 21.287 + else 21.288 + #endif 21.289 + tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); 21.290 +@@ -1203,7 +1203,7 @@ static void nv_tx_done(struct net_device 21.291 + 21.292 + /* 21.293 + * nv_tx_timeout: dev->tx_timeout function 21.294 +- * Called with dev->xmit_lock held. 21.295 ++ * Called with netif_tx_lock held. 21.296 + */ 21.297 + static void nv_tx_timeout(struct net_device *dev) 21.298 + { 21.299 +@@ -1524,7 +1524,7 @@ static int nv_change_mtu(struct net_devi 21.300 + * Changing the MTU is a rare event, it shouldn't matter. 21.301 + */ 21.302 + disable_irq(dev->irq); 21.303 +- spin_lock_bh(&dev->xmit_lock); 21.304 ++ netif_tx_lock_bh(dev); 21.305 + spin_lock(&np->lock); 21.306 + /* stop engines */ 21.307 + nv_stop_rx(dev); 21.308 +@@ -1559,7 +1559,7 @@ static int nv_change_mtu(struct net_devi 21.309 + nv_start_rx(dev); 21.310 + nv_start_tx(dev); 21.311 + spin_unlock(&np->lock); 21.312 +- spin_unlock_bh(&dev->xmit_lock); 21.313 ++ netif_tx_unlock_bh(dev); 21.314 + enable_irq(dev->irq); 21.315 + } 21.316 + return 0; 21.317 +@@ -1594,7 +1594,7 @@ static int nv_set_mac_address(struct net 21.318 + memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN); 21.319 + 21.320 + if (netif_running(dev)) { 21.321 +- spin_lock_bh(&dev->xmit_lock); 21.322 ++ netif_tx_lock_bh(dev); 21.323 + spin_lock_irq(&np->lock); 21.324 + 21.325 + /* stop rx engine */ 21.326 +@@ -1606,7 +1606,7 @@ static int nv_set_mac_address(struct net 21.327 + /* restart rx engine */ 21.328 + nv_start_rx(dev); 21.329 + spin_unlock_irq(&np->lock); 21.330 +- spin_unlock_bh(&dev->xmit_lock); 21.331 ++ netif_tx_unlock_bh(dev); 21.332 + } else { 21.333 + nv_copy_mac_to_hw(dev); 21.334 + } 21.335 +@@ -1615,7 +1615,7 @@ static int nv_set_mac_address(struct net 21.336 + 21.337 + /* 21.338 + * nv_set_multicast: dev->set_multicast function 21.339 +- * Called with dev->xmit_lock held. 21.340 ++ * Called with netif_tx_lock held. 21.341 + */ 21.342 + static void nv_set_multicast(struct net_device *dev) 21.343 + { 21.344 +diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c 21.345 +index 102c1f0..d12605f 100644 21.346 +--- a/drivers/net/hamradio/6pack.c 21.347 ++++ b/drivers/net/hamradio/6pack.c 21.348 +@@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net 21.349 + { 21.350 + struct sockaddr_ax25 *sa = addr; 21.351 + 21.352 +- spin_lock_irq(&dev->xmit_lock); 21.353 ++ netif_tx_lock_bh(dev); 21.354 + memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); 21.355 +- spin_unlock_irq(&dev->xmit_lock); 21.356 ++ netif_tx_unlock_bh(dev); 21.357 + 21.358 + return 0; 21.359 + } 21.360 +@@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_stru 21.361 + break; 21.362 + } 21.363 + 21.364 +- spin_lock_irq(&dev->xmit_lock); 21.365 ++ netif_tx_lock_bh(dev); 21.366 + memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN); 21.367 +- spin_unlock_irq(&dev->xmit_lock); 21.368 ++ netif_tx_unlock_bh(dev); 21.369 + 21.370 + err = 0; 21.371 + break; 21.372 +diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c 21.373 +index dc5e9d5..5c66f5a 100644 21.374 +--- a/drivers/net/hamradio/mkiss.c 21.375 ++++ b/drivers/net/hamradio/mkiss.c 21.376 +@@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net 21.377 + { 21.378 + struct sockaddr_ax25 *sa = addr; 21.379 + 21.380 +- spin_lock_irq(&dev->xmit_lock); 21.381 ++ netif_tx_lock_bh(dev); 21.382 + memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); 21.383 +- spin_unlock_irq(&dev->xmit_lock); 21.384 ++ netif_tx_unlock_bh(dev); 21.385 + 21.386 + return 0; 21.387 + } 21.388 +@@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct 21.389 + break; 21.390 + } 21.391 + 21.392 +- spin_lock_irq(&dev->xmit_lock); 21.393 ++ netif_tx_lock_bh(dev); 21.394 + memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); 21.395 +- spin_unlock_irq(&dev->xmit_lock); 21.396 ++ netif_tx_unlock_bh(dev); 21.397 + 21.398 + err = 0; 21.399 + break; 21.400 +diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c 21.401 +index 31fb2d7..2e222ef 100644 21.402 +--- a/drivers/net/ifb.c 21.403 ++++ b/drivers/net/ifb.c 21.404 +@@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev 21.405 + dp->st_task_enter++; 21.406 + if ((skb = skb_peek(&dp->tq)) == NULL) { 21.407 + dp->st_txq_refl_try++; 21.408 +- if (spin_trylock(&_dev->xmit_lock)) { 21.409 ++ if (netif_tx_trylock(_dev)) { 21.410 + dp->st_rxq_enter++; 21.411 + while ((skb = skb_dequeue(&dp->rq)) != NULL) { 21.412 + skb_queue_tail(&dp->tq, skb); 21.413 + dp->st_rx2tx_tran++; 21.414 + } 21.415 +- spin_unlock(&_dev->xmit_lock); 21.416 ++ netif_tx_unlock(_dev); 21.417 + } else { 21.418 + /* reschedule */ 21.419 + dp->st_rxq_notenter++; 21.420 +@@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev 21.421 + } 21.422 + } 21.423 + 21.424 +- if (spin_trylock(&_dev->xmit_lock)) { 21.425 ++ if (netif_tx_trylock(_dev)) { 21.426 + dp->st_rxq_check++; 21.427 + if ((skb = skb_peek(&dp->rq)) == NULL) { 21.428 + dp->tasklet_pending = 0; 21.429 +@@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev 21.430 + netif_wake_queue(_dev); 21.431 + } else { 21.432 + dp->st_rxq_rsch++; 21.433 +- spin_unlock(&_dev->xmit_lock); 21.434 ++ netif_tx_unlock(_dev); 21.435 + goto resched; 21.436 + } 21.437 +- spin_unlock(&_dev->xmit_lock); 21.438 ++ netif_tx_unlock(_dev); 21.439 + } else { 21.440 + resched: 21.441 + dp->tasklet_pending = 1; 21.442 +diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c 21.443 +index a9f49f0..339d4a7 100644 21.444 +--- a/drivers/net/irda/vlsi_ir.c 21.445 ++++ b/drivers/net/irda/vlsi_ir.c 21.446 +@@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct s 21.447 + || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) 21.448 + break; 21.449 + udelay(100); 21.450 +- /* must not sleep here - we are called under xmit_lock! */ 21.451 ++ /* must not sleep here - called under netif_tx_lock! */ 21.452 + } 21.453 + } 21.454 + 21.455 +diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c 21.456 +index f9f77e4..bdab369 100644 21.457 +--- a/drivers/net/ixgb/ixgb_main.c 21.458 ++++ b/drivers/net/ixgb/ixgb_main.c 21.459 +@@ -1163,7 +1163,7 @@ #ifdef NETIF_F_TSO 21.460 + uint16_t ipcse, tucse, mss; 21.461 + int err; 21.462 + 21.463 +- if(likely(skb_shinfo(skb)->tso_size)) { 21.464 ++ if(likely(skb_shinfo(skb)->gso_size)) { 21.465 + if (skb_header_cloned(skb)) { 21.466 + err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); 21.467 + if (err) 21.468 +@@ -1171,7 +1171,7 @@ #ifdef NETIF_F_TSO 21.469 + } 21.470 + 21.471 + hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); 21.472 +- mss = skb_shinfo(skb)->tso_size; 21.473 ++ mss = skb_shinfo(skb)->gso_size; 21.474 + skb->nh.iph->tot_len = 0; 21.475 + skb->nh.iph->check = 0; 21.476 + skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, 21.477 +diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c 21.478 +index 690a1aa..9bcaa80 100644 21.479 +--- a/drivers/net/loopback.c 21.480 ++++ b/drivers/net/loopback.c 21.481 +@@ -74,7 +74,7 @@ static void emulate_large_send_offload(s 21.482 + struct iphdr *iph = skb->nh.iph; 21.483 + struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); 21.484 + unsigned int doffset = (iph->ihl + th->doff) * 4; 21.485 +- unsigned int mtu = skb_shinfo(skb)->tso_size + doffset; 21.486 ++ unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; 21.487 + unsigned int offset = 0; 21.488 + u32 seq = ntohl(th->seq); 21.489 + u16 id = ntohs(iph->id); 21.490 +@@ -139,7 +139,7 @@ #ifndef LOOPBACK_MUST_CHECKSUM 21.491 + #endif 21.492 + 21.493 + #ifdef LOOPBACK_TSO 21.494 +- if (skb_shinfo(skb)->tso_size) { 21.495 ++ if (skb_shinfo(skb)->gso_size) { 21.496 + BUG_ON(skb->protocol != htons(ETH_P_IP)); 21.497 + BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); 21.498 + 21.499 +diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c 21.500 +index c0998ef..0fac9d5 100644 21.501 +--- a/drivers/net/mv643xx_eth.c 21.502 ++++ b/drivers/net/mv643xx_eth.c 21.503 +@@ -1107,7 +1107,7 @@ static int mv643xx_eth_start_xmit(struct 21.504 + 21.505 + #ifdef MV643XX_CHECKSUM_OFFLOAD_TX 21.506 + if (has_tiny_unaligned_frags(skb)) { 21.507 +- if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { 21.508 ++ if (__skb_linearize(skb)) { 21.509 + stats->tx_dropped++; 21.510 + printk(KERN_DEBUG "%s: failed to linearize tiny " 21.511 + "unaligned fragment\n", dev->name); 21.512 +diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c 21.513 +index 9d6d254..c9ed624 100644 21.514 +--- a/drivers/net/natsemi.c 21.515 ++++ b/drivers/net/natsemi.c 21.516 +@@ -323,12 +323,12 @@ performance critical codepaths: 21.517 + The rx process only runs in the interrupt handler. Access from outside 21.518 + the interrupt handler is only permitted after disable_irq(). 21.519 + 21.520 +-The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap 21.521 ++The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap 21.522 + is set, then access is permitted under spin_lock_irq(&np->lock). 21.523 + 21.524 + Thus configuration functions that want to access everything must call 21.525 + disable_irq(dev->irq); 21.526 +- spin_lock_bh(dev->xmit_lock); 21.527 ++ netif_tx_lock_bh(dev); 21.528 + spin_lock_irq(&np->lock); 21.529 + 21.530 + IV. Notes 21.531 +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c 21.532 +index 8cc0d0b..e53b313 100644 21.533 +--- a/drivers/net/r8169.c 21.534 ++++ b/drivers/net/r8169.c 21.535 +@@ -2171,7 +2171,7 @@ static int rtl8169_xmit_frags(struct rtl 21.536 + static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) 21.537 + { 21.538 + if (dev->features & NETIF_F_TSO) { 21.539 +- u32 mss = skb_shinfo(skb)->tso_size; 21.540 ++ u32 mss = skb_shinfo(skb)->gso_size; 21.541 + 21.542 + if (mss) 21.543 + return LargeSend | ((mss & MSSMask) << MSSShift); 21.544 +diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c 21.545 +index b7f00d6..439f45f 100644 21.546 +--- a/drivers/net/s2io.c 21.547 ++++ b/drivers/net/s2io.c 21.548 +@@ -3522,8 +3522,8 @@ #endif 21.549 + txdp->Control_1 = 0; 21.550 + txdp->Control_2 = 0; 21.551 + #ifdef NETIF_F_TSO 21.552 +- mss = skb_shinfo(skb)->tso_size; 21.553 +- if (mss) { 21.554 ++ mss = skb_shinfo(skb)->gso_size; 21.555 ++ if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) { 21.556 + txdp->Control_1 |= TXD_TCP_LSO_EN; 21.557 + txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); 21.558 + } 21.559 +@@ -3543,10 +3543,10 @@ #endif 21.560 + } 21.561 + 21.562 + frg_len = skb->len - skb->data_len; 21.563 +- if (skb_shinfo(skb)->ufo_size) { 21.564 ++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) { 21.565 + int ufo_size; 21.566 + 21.567 +- ufo_size = skb_shinfo(skb)->ufo_size; 21.568 ++ ufo_size = skb_shinfo(skb)->gso_size; 21.569 + ufo_size &= ~7; 21.570 + txdp->Control_1 |= TXD_UFO_EN; 21.571 + txdp->Control_1 |= TXD_UFO_MSS(ufo_size); 21.572 +@@ -3572,7 +3572,7 @@ #endif 21.573 + txdp->Host_Control = (unsigned long) skb; 21.574 + txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); 21.575 + 21.576 +- if (skb_shinfo(skb)->ufo_size) 21.577 ++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) 21.578 + txdp->Control_1 |= TXD_UFO_EN; 21.579 + 21.580 + frg_cnt = skb_shinfo(skb)->nr_frags; 21.581 +@@ -3587,12 +3587,12 @@ #endif 21.582 + (sp->pdev, frag->page, frag->page_offset, 21.583 + frag->size, PCI_DMA_TODEVICE); 21.584 + txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); 21.585 +- if (skb_shinfo(skb)->ufo_size) 21.586 ++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) 21.587 + txdp->Control_1 |= TXD_UFO_EN; 21.588 + } 21.589 + txdp->Control_1 |= TXD_GATHER_CODE_LAST; 21.590 + 21.591 +- if (skb_shinfo(skb)->ufo_size) 21.592 ++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) 21.593 + frg_cnt++; /* as Txd0 was used for inband header */ 21.594 + 21.595 + tx_fifo = mac_control->tx_FIFO_start[queue]; 21.596 +@@ -3606,7 +3606,7 @@ #ifdef NETIF_F_TSO 21.597 + if (mss) 21.598 + val64 |= TX_FIFO_SPECIAL_FUNC; 21.599 + #endif 21.600 +- if (skb_shinfo(skb)->ufo_size) 21.601 ++ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) 21.602 + val64 |= TX_FIFO_SPECIAL_FUNC; 21.603 + writeq(val64, &tx_fifo->List_Control); 21.604 + 21.605 +diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c 21.606 +index 0618cd5..2a55eb3 100644 21.607 +--- a/drivers/net/sky2.c 21.608 ++++ b/drivers/net/sky2.c 21.609 +@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s 21.610 + count = sizeof(dma_addr_t) / sizeof(u32); 21.611 + count += skb_shinfo(skb)->nr_frags * count; 21.612 + 21.613 +- if (skb_shinfo(skb)->tso_size) 21.614 ++ if (skb_shinfo(skb)->gso_size) 21.615 + ++count; 21.616 + 21.617 + if (skb->ip_summed == CHECKSUM_HW) 21.618 +@@ -1197,7 +1197,7 @@ static int sky2_xmit_frame(struct sk_buf 21.619 + } 21.620 + 21.621 + /* Check for TCP Segmentation Offload */ 21.622 +- mss = skb_shinfo(skb)->tso_size; 21.623 ++ mss = skb_shinfo(skb)->gso_size; 21.624 + if (mss != 0) { 21.625 + /* just drop the packet if non-linear expansion fails */ 21.626 + if (skb_header_cloned(skb) && 21.627 +diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c 21.628 +index caf4102..fc9164a 100644 21.629 +--- a/drivers/net/tg3.c 21.630 ++++ b/drivers/net/tg3.c 21.631 +@@ -3664,7 +3664,7 @@ static int tg3_start_xmit(struct sk_buff 21.632 + #if TG3_TSO_SUPPORT != 0 21.633 + mss = 0; 21.634 + if (skb->len > (tp->dev->mtu + ETH_HLEN) && 21.635 +- (mss = skb_shinfo(skb)->tso_size) != 0) { 21.636 ++ (mss = skb_shinfo(skb)->gso_size) != 0) { 21.637 + int tcp_opt_len, ip_tcp_len; 21.638 + 21.639 + if (skb_header_cloned(skb) && 21.640 +diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c 21.641 +index 5b1af39..11de5af 100644 21.642 +--- a/drivers/net/tulip/winbond-840.c 21.643 ++++ b/drivers/net/tulip/winbond-840.c 21.644 +@@ -1605,11 +1605,11 @@ #ifdef CONFIG_PM 21.645 + * - get_stats: 21.646 + * spin_lock_irq(np->lock), doesn't touch hw if not present 21.647 + * - hard_start_xmit: 21.648 +- * netif_stop_queue + spin_unlock_wait(&dev->xmit_lock); 21.649 ++ * synchronize_irq + netif_tx_disable; 21.650 + * - tx_timeout: 21.651 +- * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); 21.652 ++ * netif_device_detach + netif_tx_disable; 21.653 + * - set_multicast_list 21.654 +- * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); 21.655 ++ * netif_device_detach + netif_tx_disable; 21.656 + * - interrupt handler 21.657 + * doesn't touch hw if not present, synchronize_irq waits for 21.658 + * running instances of the interrupt handler. 21.659 +@@ -1635,11 +1635,10 @@ static int w840_suspend (struct pci_dev 21.660 + netif_device_detach(dev); 21.661 + update_csr6(dev, 0); 21.662 + iowrite32(0, ioaddr + IntrEnable); 21.663 +- netif_stop_queue(dev); 21.664 + spin_unlock_irq(&np->lock); 21.665 + 21.666 +- spin_unlock_wait(&dev->xmit_lock); 21.667 + synchronize_irq(dev->irq); 21.668 ++ netif_tx_disable(dev); 21.669 + 21.670 + np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff; 21.671 + 21.672 +diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c 21.673 +index 4c76cb7..30c48c9 100644 21.674 +--- a/drivers/net/typhoon.c 21.675 ++++ b/drivers/net/typhoon.c 21.676 +@@ -340,7 +340,7 @@ #define typhoon_synchronize_irq(x) synch 21.677 + #endif 21.678 + 21.679 + #if defined(NETIF_F_TSO) 21.680 +-#define skb_tso_size(x) (skb_shinfo(x)->tso_size) 21.681 ++#define skb_tso_size(x) (skb_shinfo(x)->gso_size) 21.682 + #define TSO_NUM_DESCRIPTORS 2 21.683 + #define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT 21.684 + #else 21.685 +diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c 21.686 +index ed1f837..2eb6b5f 100644 21.687 +--- a/drivers/net/via-velocity.c 21.688 ++++ b/drivers/net/via-velocity.c 21.689 +@@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff 21.690 + 21.691 + int pktlen = skb->len; 21.692 + 21.693 ++#ifdef VELOCITY_ZERO_COPY_SUPPORT 21.694 ++ if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) { 21.695 ++ kfree_skb(skb); 21.696 ++ return 0; 21.697 ++ } 21.698 ++#endif 21.699 ++ 21.700 + spin_lock_irqsave(&vptr->lock, flags); 21.701 + 21.702 + index = vptr->td_curr[qnum]; 21.703 +@@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff 21.704 + */ 21.705 + if (pktlen < ETH_ZLEN) { 21.706 + /* Cannot occur until ZC support */ 21.707 +- if(skb_linearize(skb, GFP_ATOMIC)) 21.708 +- return 0; 21.709 + pktlen = ETH_ZLEN; 21.710 + memcpy(tdinfo->buf, skb->data, skb->len); 21.711 + memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); 21.712 +@@ -1933,7 +1938,6 @@ #ifdef VELOCITY_ZERO_COPY_SUPPORT 21.713 + int nfrags = skb_shinfo(skb)->nr_frags; 21.714 + tdinfo->skb = skb; 21.715 + if (nfrags > 6) { 21.716 +- skb_linearize(skb, GFP_ATOMIC); 21.717 + memcpy(tdinfo->buf, skb->data, skb->len); 21.718 + tdinfo->skb_dma[0] = tdinfo->buf_dma; 21.719 + td_ptr->tdesc0.pktsize = 21.720 +diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c 21.721 +index 6fd0bf7..75237c1 100644 21.722 +--- a/drivers/net/wireless/orinoco.c 21.723 ++++ b/drivers/net/wireless/orinoco.c 21.724 +@@ -1835,7 +1835,9 @@ static int __orinoco_program_rids(struct 21.725 + /* Set promiscuity / multicast*/ 21.726 + priv->promiscuous = 0; 21.727 + priv->mc_count = 0; 21.728 +- __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ 21.729 ++ 21.730 ++ /* FIXME: what about netif_tx_lock */ 21.731 ++ __orinoco_set_multicast_list(dev); 21.732 + 21.733 + return 0; 21.734 + } 21.735 +diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c 21.736 +index 82cb4af..57cec40 100644 21.737 +--- a/drivers/s390/net/qeth_eddp.c 21.738 ++++ b/drivers/s390/net/qeth_eddp.c 21.739 +@@ -421,7 +421,7 @@ #endif /* CONFIG_QETH_VLAN */ 21.740 + } 21.741 + tcph = eddp->skb->h.th; 21.742 + while (eddp->skb_offset < eddp->skb->len) { 21.743 +- data_len = min((int)skb_shinfo(eddp->skb)->tso_size, 21.744 ++ data_len = min((int)skb_shinfo(eddp->skb)->gso_size, 21.745 + (int)(eddp->skb->len - eddp->skb_offset)); 21.746 + /* prepare qdio hdr */ 21.747 + if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ 21.748 +@@ -516,20 +516,20 @@ qeth_eddp_calc_num_pages(struct qeth_edd 21.749 + 21.750 + QETH_DBF_TEXT(trace, 5, "eddpcanp"); 21.751 + /* can we put multiple skbs in one page? */ 21.752 +- skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); 21.753 ++ skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len); 21.754 + if (skbs_per_page > 1){ 21.755 +- ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) / 21.756 ++ ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) / 21.757 + skbs_per_page + 1; 21.758 + ctx->elements_per_skb = 1; 21.759 + } else { 21.760 + /* no -> how many elements per skb? */ 21.761 +- ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len + 21.762 ++ ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len + 21.763 + PAGE_SIZE) >> PAGE_SHIFT; 21.764 + ctx->num_pages = ctx->elements_per_skb * 21.765 +- (skb_shinfo(skb)->tso_segs + 1); 21.766 ++ (skb_shinfo(skb)->gso_segs + 1); 21.767 + } 21.768 + ctx->num_elements = ctx->elements_per_skb * 21.769 +- (skb_shinfo(skb)->tso_segs + 1); 21.770 ++ (skb_shinfo(skb)->gso_segs + 1); 21.771 + } 21.772 + 21.773 + static inline struct qeth_eddp_context * 21.774 +diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c 21.775 +index dba7f7f..d9cc997 100644 21.776 +--- a/drivers/s390/net/qeth_main.c 21.777 ++++ b/drivers/s390/net/qeth_main.c 21.778 +@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card, 21.779 + queue = card->qdio.out_qs 21.780 + [qeth_get_priority_queue(card, skb, ipv, cast_type)]; 21.781 + 21.782 +- if (skb_shinfo(skb)->tso_size) 21.783 ++ if (skb_shinfo(skb)->gso_size) 21.784 + large_send = card->options.large_send; 21.785 + 21.786 + /*are we able to do TSO ? If so ,prepare and send it from here */ 21.787 +@@ -4501,7 +4501,7 @@ qeth_send_packet(struct qeth_card *card, 21.788 + card->stats.tx_packets++; 21.789 + card->stats.tx_bytes += skb->len; 21.790 + #ifdef CONFIG_QETH_PERF_STATS 21.791 +- if (skb_shinfo(skb)->tso_size && 21.792 ++ if (skb_shinfo(skb)->gso_size && 21.793 + !(large_send == QETH_LARGE_SEND_NO)) { 21.794 + card->perf_stats.large_send_bytes += skb->len; 21.795 + card->perf_stats.large_send_cnt++; 21.796 +diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h 21.797 +index 1286dde..89cbf34 100644 21.798 +--- a/drivers/s390/net/qeth_tso.h 21.799 ++++ b/drivers/s390/net/qeth_tso.h 21.800 +@@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *c 21.801 + hdr->ext.hdr_version = 1; 21.802 + hdr->ext.hdr_len = 28; 21.803 + /*insert non-fix values */ 21.804 +- hdr->ext.mss = skb_shinfo(skb)->tso_size; 21.805 ++ hdr->ext.mss = skb_shinfo(skb)->gso_size; 21.806 + hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); 21.807 + hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - 21.808 + sizeof(struct qeth_hdr_tso)); 21.809 +diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h 21.810 +index 93535f0..9269df7 100644 21.811 +--- a/include/linux/ethtool.h 21.812 ++++ b/include/linux/ethtool.h 21.813 +@@ -408,6 +408,8 @@ #define ETHTOOL_STSO 0x0000001f /* Set 21.814 + #define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */ 21.815 + #define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */ 21.816 + #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ 21.817 ++#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ 21.818 ++#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ 21.819 + 21.820 + /* compatibility with older code */ 21.821 + #define SPARC_ETH_GSET ETHTOOL_GSET 21.822 +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h 21.823 +index 7fda03d..47b0965 100644 21.824 +--- a/include/linux/netdevice.h 21.825 ++++ b/include/linux/netdevice.h 21.826 +@@ -230,7 +230,8 @@ enum netdev_state_t 21.827 + __LINK_STATE_SCHED, 21.828 + __LINK_STATE_NOCARRIER, 21.829 + __LINK_STATE_RX_SCHED, 21.830 +- __LINK_STATE_LINKWATCH_PENDING 21.831 ++ __LINK_STATE_LINKWATCH_PENDING, 21.832 ++ __LINK_STATE_QDISC_RUNNING, 21.833 + }; 21.834 + 21.835 + 21.836 +@@ -306,9 +307,17 @@ #define NETIF_F_HW_VLAN_TX 128 /* Transm 21.837 + #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ 21.838 + #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ 21.839 + #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ 21.840 +-#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */ 21.841 ++#define NETIF_F_GSO 2048 /* Enable software GSO. */ 21.842 + #define NETIF_F_LLTX 4096 /* LockLess TX */ 21.843 +-#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/ 21.844 ++ 21.845 ++ /* Segmentation offload features */ 21.846 ++#define NETIF_F_GSO_SHIFT 16 21.847 ++#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) 21.848 ++#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT) 21.849 ++#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT) 21.850 ++ 21.851 ++#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) 21.852 ++#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM) 21.853 + 21.854 + struct net_device *next_sched; 21.855 + 21.856 +@@ -394,6 +403,9 @@ #define NETIF_F_UFO 8192 21.857 + struct list_head qdisc_list; 21.858 + unsigned long tx_queue_len; /* Max frames per queue allowed */ 21.859 + 21.860 ++ /* Partially transmitted GSO packet. */ 21.861 ++ struct sk_buff *gso_skb; 21.862 ++ 21.863 + /* ingress path synchronizer */ 21.864 + spinlock_t ingress_lock; 21.865 + struct Qdisc *qdisc_ingress; 21.866 +@@ -402,7 +414,7 @@ #define NETIF_F_UFO 8192 21.867 + * One part is mostly used on xmit path (device) 21.868 + */ 21.869 + /* hard_start_xmit synchronizer */ 21.870 +- spinlock_t xmit_lock ____cacheline_aligned_in_smp; 21.871 ++ spinlock_t _xmit_lock ____cacheline_aligned_in_smp; 21.872 + /* cpu id of processor entered to hard_start_xmit or -1, 21.873 + if nobody entered there. 21.874 + */ 21.875 +@@ -527,6 +539,8 @@ struct packet_type { 21.876 + struct net_device *, 21.877 + struct packet_type *, 21.878 + struct net_device *); 21.879 ++ struct sk_buff *(*gso_segment)(struct sk_buff *skb, 21.880 ++ int features); 21.881 + void *af_packet_priv; 21.882 + struct list_head list; 21.883 + }; 21.884 +@@ -693,7 +707,8 @@ extern int dev_change_name(struct net_d 21.885 + extern int dev_set_mtu(struct net_device *, int); 21.886 + extern int dev_set_mac_address(struct net_device *, 21.887 + struct sockaddr *); 21.888 +-extern void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev); 21.889 ++extern int dev_hard_start_xmit(struct sk_buff *skb, 21.890 ++ struct net_device *dev); 21.891 + 21.892 + extern void dev_init(void); 21.893 + 21.894 +@@ -900,11 +915,43 @@ static inline void __netif_rx_complete(s 21.895 + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); 21.896 + } 21.897 + 21.898 ++static inline void netif_tx_lock(struct net_device *dev) 21.899 ++{ 21.900 ++ spin_lock(&dev->_xmit_lock); 21.901 ++ dev->xmit_lock_owner = smp_processor_id(); 21.902 ++} 21.903 ++ 21.904 ++static inline void netif_tx_lock_bh(struct net_device *dev) 21.905 ++{ 21.906 ++ spin_lock_bh(&dev->_xmit_lock); 21.907 ++ dev->xmit_lock_owner = smp_processor_id(); 21.908 ++} 21.909 ++ 21.910 ++static inline int netif_tx_trylock(struct net_device *dev) 21.911 ++{ 21.912 ++ int err = spin_trylock(&dev->_xmit_lock); 21.913 ++ if (!err) 21.914 ++ dev->xmit_lock_owner = smp_processor_id(); 21.915 ++ return err; 21.916 ++} 21.917 ++ 21.918 ++static inline void netif_tx_unlock(struct net_device *dev) 21.919 ++{ 21.920 ++ dev->xmit_lock_owner = -1; 21.921 ++ spin_unlock(&dev->_xmit_lock); 21.922 ++} 21.923 ++ 21.924 ++static inline void netif_tx_unlock_bh(struct net_device *dev) 21.925 ++{ 21.926 ++ dev->xmit_lock_owner = -1; 21.927 ++ spin_unlock_bh(&dev->_xmit_lock); 21.928 ++} 21.929 ++ 21.930 + static inline void netif_tx_disable(struct net_device *dev) 21.931 + { 21.932 +- spin_lock_bh(&dev->xmit_lock); 21.933 ++ netif_tx_lock_bh(dev); 21.934 + netif_stop_queue(dev); 21.935 +- spin_unlock_bh(&dev->xmit_lock); 21.936 ++ netif_tx_unlock_bh(dev); 21.937 + } 21.938 + 21.939 + /* These functions live elsewhere (drivers/net/net_init.c, but related) */ 21.940 +@@ -932,6 +979,7 @@ extern int netdev_max_backlog; 21.941 + extern int weight_p; 21.942 + extern int netdev_set_master(struct net_device *dev, struct net_device *master); 21.943 + extern int skb_checksum_help(struct sk_buff *skb, int inward); 21.944 ++extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features); 21.945 + #ifdef CONFIG_BUG 21.946 + extern void netdev_rx_csum_fault(struct net_device *dev); 21.947 + #else 21.948 +@@ -951,6 +999,18 @@ #endif 21.949 + 21.950 + extern void linkwatch_run_queue(void); 21.951 + 21.952 ++static inline int skb_gso_ok(struct sk_buff *skb, int features) 21.953 ++{ 21.954 ++ int feature = skb_shinfo(skb)->gso_size ? 21.955 ++ skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0; 21.956 ++ return (features & feature) == feature; 21.957 ++} 21.958 ++ 21.959 ++static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) 21.960 ++{ 21.961 ++ return !skb_gso_ok(skb, dev->features); 21.962 ++} 21.963 ++ 21.964 + #endif /* __KERNEL__ */ 21.965 + 21.966 + #endif /* _LINUX_DEV_H */ 21.967 +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h 21.968 +index ad7cc22..b19d45d 100644 21.969 +--- a/include/linux/skbuff.h 21.970 ++++ b/include/linux/skbuff.h 21.971 +@@ -134,9 +134,10 @@ struct skb_frag_struct { 21.972 + struct skb_shared_info { 21.973 + atomic_t dataref; 21.974 + unsigned short nr_frags; 21.975 +- unsigned short tso_size; 21.976 +- unsigned short tso_segs; 21.977 +- unsigned short ufo_size; 21.978 ++ unsigned short gso_size; 21.979 ++ /* Warning: this field is not always filled in (UFO)! */ 21.980 ++ unsigned short gso_segs; 21.981 ++ unsigned short gso_type; 21.982 + unsigned int ip6_frag_id; 21.983 + struct sk_buff *frag_list; 21.984 + skb_frag_t frags[MAX_SKB_FRAGS]; 21.985 +@@ -168,6 +169,14 @@ enum { 21.986 + SKB_FCLONE_CLONE, 21.987 + }; 21.988 + 21.989 ++enum { 21.990 ++ SKB_GSO_TCPV4 = 1 << 0, 21.991 ++ SKB_GSO_UDPV4 = 1 << 1, 21.992 ++ 21.993 ++ /* This indicates the skb is from an untrusted source. */ 21.994 ++ SKB_GSO_DODGY = 1 << 2, 21.995 ++}; 21.996 ++ 21.997 + /** 21.998 + * struct sk_buff - socket buffer 21.999 + * @next: Next buffer in list 21.1000 +@@ -1148,18 +1157,34 @@ static inline int skb_can_coalesce(struc 21.1001 + return 0; 21.1002 + } 21.1003 + 21.1004 ++static inline int __skb_linearize(struct sk_buff *skb) 21.1005 ++{ 21.1006 ++ return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM; 21.1007 ++} 21.1008 ++ 21.1009 + /** 21.1010 + * skb_linearize - convert paged skb to linear one 21.1011 + * @skb: buffer to linarize 21.1012 +- * @gfp: allocation mode 21.1013 + * 21.1014 + * If there is no free memory -ENOMEM is returned, otherwise zero 21.1015 + * is returned and the old skb data released. 21.1016 + */ 21.1017 +-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp); 21.1018 +-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp) 21.1019 ++static inline int skb_linearize(struct sk_buff *skb) 21.1020 ++{ 21.1021 ++ return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0; 21.1022 ++} 21.1023 ++ 21.1024 ++/** 21.1025 ++ * skb_linearize_cow - make sure skb is linear and writable 21.1026 ++ * @skb: buffer to process 21.1027 ++ * 21.1028 ++ * If there is no free memory -ENOMEM is returned, otherwise zero 21.1029 ++ * is returned and the old skb data released. 21.1030 ++ */ 21.1031 ++static inline int skb_linearize_cow(struct sk_buff *skb) 21.1032 + { 21.1033 +- return __skb_linearize(skb, gfp); 21.1034 ++ return skb_is_nonlinear(skb) || skb_cloned(skb) ? 21.1035 ++ __skb_linearize(skb) : 0; 21.1036 + } 21.1037 + 21.1038 + /** 21.1039 +@@ -1254,6 +1279,7 @@ extern void skb_split(struct sk_b 21.1040 + struct sk_buff *skb1, const u32 len); 21.1041 + 21.1042 + extern void skb_release_data(struct sk_buff *skb); 21.1043 ++extern struct sk_buff *skb_segment(struct sk_buff *skb, int features); 21.1044 + 21.1045 + static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, 21.1046 + int len, void *buffer) 21.1047 +diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h 21.1048 +index b94d1ad..75b5b93 100644 21.1049 +--- a/include/net/pkt_sched.h 21.1050 ++++ b/include/net/pkt_sched.h 21.1051 +@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_ge 21.1052 + struct rtattr *tab); 21.1053 + extern void qdisc_put_rtab(struct qdisc_rate_table *tab); 21.1054 + 21.1055 +-extern int qdisc_restart(struct net_device *dev); 21.1056 ++extern void __qdisc_run(struct net_device *dev); 21.1057 + 21.1058 + static inline void qdisc_run(struct net_device *dev) 21.1059 + { 21.1060 +- while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0) 21.1061 +- /* NOTHING */; 21.1062 ++ if (!netif_queue_stopped(dev) && 21.1063 ++ !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) 21.1064 ++ __qdisc_run(dev); 21.1065 + } 21.1066 + 21.1067 + extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, 21.1068 +diff --git a/include/net/protocol.h b/include/net/protocol.h 21.1069 +index 6dc5970..0d2dcdb 100644 21.1070 +--- a/include/net/protocol.h 21.1071 ++++ b/include/net/protocol.h 21.1072 +@@ -37,6 +37,8 @@ #define MAX_INET_PROTOS 256 /* Must be 21.1073 + struct net_protocol { 21.1074 + int (*handler)(struct sk_buff *skb); 21.1075 + void (*err_handler)(struct sk_buff *skb, u32 info); 21.1076 ++ struct sk_buff *(*gso_segment)(struct sk_buff *skb, 21.1077 ++ int features); 21.1078 + int no_policy; 21.1079 + }; 21.1080 + 21.1081 +diff --git a/include/net/sock.h b/include/net/sock.h 21.1082 +index f63d0d5..a8e8d21 100644 21.1083 +--- a/include/net/sock.h 21.1084 ++++ b/include/net/sock.h 21.1085 +@@ -1064,9 +1064,13 @@ static inline void sk_setup_caps(struct 21.1086 + { 21.1087 + __sk_dst_set(sk, dst); 21.1088 + sk->sk_route_caps = dst->dev->features; 21.1089 ++ if (sk->sk_route_caps & NETIF_F_GSO) 21.1090 ++ sk->sk_route_caps |= NETIF_F_TSO; 21.1091 + if (sk->sk_route_caps & NETIF_F_TSO) { 21.1092 + if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len) 21.1093 + sk->sk_route_caps &= ~NETIF_F_TSO; 21.1094 ++ else 21.1095 ++ sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; 21.1096 + } 21.1097 + } 21.1098 + 21.1099 +diff --git a/include/net/tcp.h b/include/net/tcp.h 21.1100 +index 77f21c6..70e1d5f 100644 21.1101 +--- a/include/net/tcp.h 21.1102 ++++ b/include/net/tcp.h 21.1103 +@@ -552,13 +552,13 @@ #include <net/tcp_ecn.h> 21.1104 + */ 21.1105 + static inline int tcp_skb_pcount(const struct sk_buff *skb) 21.1106 + { 21.1107 +- return skb_shinfo(skb)->tso_segs; 21.1108 ++ return skb_shinfo(skb)->gso_segs; 21.1109 + } 21.1110 + 21.1111 + /* This is valid iff tcp_skb_pcount() > 1. */ 21.1112 + static inline int tcp_skb_mss(const struct sk_buff *skb) 21.1113 + { 21.1114 +- return skb_shinfo(skb)->tso_size; 21.1115 ++ return skb_shinfo(skb)->gso_size; 21.1116 + } 21.1117 + 21.1118 + static inline void tcp_dec_pcount_approx(__u32 *count, 21.1119 +@@ -1063,6 +1063,8 @@ extern struct request_sock_ops tcp_reque 21.1120 + 21.1121 + extern int tcp_v4_destroy_sock(struct sock *sk); 21.1122 + 21.1123 ++extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); 21.1124 ++ 21.1125 + #ifdef CONFIG_PROC_FS 21.1126 + extern int tcp4_proc_init(void); 21.1127 + extern void tcp4_proc_exit(void); 21.1128 +diff --git a/net/atm/clip.c b/net/atm/clip.c 21.1129 +index 1842a4e..6dc21a7 100644 21.1130 +--- a/net/atm/clip.c 21.1131 ++++ b/net/atm/clip.c 21.1132 +@@ -101,7 +101,7 @@ static void unlink_clip_vcc(struct clip_ 21.1133 + printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc); 21.1134 + return; 21.1135 + } 21.1136 +- spin_lock_bh(&entry->neigh->dev->xmit_lock); /* block clip_start_xmit() */ 21.1137 ++ netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */ 21.1138 + entry->neigh->used = jiffies; 21.1139 + for (walk = &entry->vccs; *walk; walk = &(*walk)->next) 21.1140 + if (*walk == clip_vcc) { 21.1141 +@@ -125,7 +125,7 @@ static void unlink_clip_vcc(struct clip_ 21.1142 + printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc " 21.1143 + "0x%p)\n",entry,clip_vcc); 21.1144 + out: 21.1145 +- spin_unlock_bh(&entry->neigh->dev->xmit_lock); 21.1146 ++ netif_tx_unlock_bh(entry->neigh->dev); 21.1147 + } 21.1148 + 21.1149 + /* The neighbour entry n->lock is held. */ 21.1150 +diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c 21.1151 +index 0b33a7b..180e79b 100644 21.1152 +--- a/net/bridge/br_device.c 21.1153 ++++ b/net/bridge/br_device.c 21.1154 +@@ -146,9 +146,9 @@ static int br_set_tx_csum(struct net_dev 21.1155 + struct net_bridge *br = netdev_priv(dev); 21.1156 + 21.1157 + if (data) 21.1158 +- br->feature_mask |= NETIF_F_IP_CSUM; 21.1159 ++ br->feature_mask |= NETIF_F_NO_CSUM; 21.1160 + else 21.1161 +- br->feature_mask &= ~NETIF_F_IP_CSUM; 21.1162 ++ br->feature_mask &= ~NETIF_F_ALL_CSUM; 21.1163 + 21.1164 + br_features_recompute(br); 21.1165 + return 0; 21.1166 +@@ -185,6 +185,6 @@ void br_dev_setup(struct net_device *dev 21.1167 + dev->set_mac_address = br_set_mac_address; 21.1168 + dev->priv_flags = IFF_EBRIDGE; 21.1169 + 21.1170 +- dev->features = NETIF_F_SG | NETIF_F_FRAGLIST 21.1171 +- | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM; 21.1172 ++ dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 21.1173 ++ NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST; 21.1174 + } 21.1175 +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c 21.1176 +index 2d24fb4..00b1128 100644 21.1177 +--- a/net/bridge/br_forward.c 21.1178 ++++ b/net/bridge/br_forward.c 21.1179 +@@ -32,7 +32,7 @@ static inline int should_deliver(const s 21.1180 + int br_dev_queue_push_xmit(struct sk_buff *skb) 21.1181 + { 21.1182 + /* drop mtu oversized packets except tso */ 21.1183 +- if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size) 21.1184 ++ if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size) 21.1185 + kfree_skb(skb); 21.1186 + else { 21.1187 + #ifdef CONFIG_BRIDGE_NETFILTER 21.1188 +diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c 21.1189 +index f36b35e..0617146 100644 21.1190 +--- a/net/bridge/br_if.c 21.1191 ++++ b/net/bridge/br_if.c 21.1192 +@@ -385,17 +385,28 @@ void br_features_recompute(struct net_br 21.1193 + struct net_bridge_port *p; 21.1194 + unsigned long features, checksum; 21.1195 + 21.1196 +- features = br->feature_mask &~ NETIF_F_IP_CSUM; 21.1197 +- checksum = br->feature_mask & NETIF_F_IP_CSUM; 21.1198 ++ checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; 21.1199 ++ features = br->feature_mask & ~NETIF_F_ALL_CSUM; 21.1200 + 21.1201 + list_for_each_entry(p, &br->port_list, list) { 21.1202 +- if (!(p->dev->features 21.1203 +- & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM))) 21.1204 ++ unsigned long feature = p->dev->features; 21.1205 ++ 21.1206 ++ if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM)) 21.1207 ++ checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; 21.1208 ++ if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM)) 21.1209 ++ checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM; 21.1210 ++ if (!(feature & NETIF_F_IP_CSUM)) 21.1211 + checksum = 0; 21.1212 +- features &= p->dev->features; 21.1213 ++ 21.1214 ++ if (feature & NETIF_F_GSO) 21.1215 ++ feature |= NETIF_F_TSO; 21.1216 ++ feature |= NETIF_F_GSO; 21.1217 ++ 21.1218 ++ features &= feature; 21.1219 + } 21.1220 + 21.1221 +- br->dev->features = features | checksum | NETIF_F_LLTX; 21.1222 ++ br->dev->features = features | checksum | NETIF_F_LLTX | 21.1223 ++ NETIF_F_GSO_ROBUST; 21.1224 + } 21.1225 + 21.1226 + /* called with RTNL */ 21.1227 +diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c 21.1228 +index 9e27373..588207f 100644 21.1229 +--- a/net/bridge/br_netfilter.c 21.1230 ++++ b/net/bridge/br_netfilter.c 21.1231 +@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s 21.1232 + { 21.1233 + if (skb->protocol == htons(ETH_P_IP) && 21.1234 + skb->len > skb->dev->mtu && 21.1235 +- !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) 21.1236 ++ !skb_shinfo(skb)->gso_size) 21.1237 + return ip_fragment(skb, br_dev_queue_push_xmit); 21.1238 + else 21.1239 + return br_dev_queue_push_xmit(skb); 21.1240 +diff --git a/net/core/dev.c b/net/core/dev.c 21.1241 +index 12a214c..32e1056 100644 21.1242 +--- a/net/core/dev.c 21.1243 ++++ b/net/core/dev.c 21.1244 +@@ -115,6 +115,7 @@ #include <linux/wireless.h> /* Note : w 21.1245 + #include <net/iw_handler.h> 21.1246 + #endif /* CONFIG_NET_RADIO */ 21.1247 + #include <asm/current.h> 21.1248 ++#include <linux/err.h> 21.1249 + 21.1250 + /* 21.1251 + * The list of packet types we will receive (as opposed to discard) 21.1252 +@@ -1032,7 +1033,7 @@ static inline void net_timestamp(struct 21.1253 + * taps currently in use. 21.1254 + */ 21.1255 + 21.1256 +-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) 21.1257 ++static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) 21.1258 + { 21.1259 + struct packet_type *ptype; 21.1260 + 21.1261 +@@ -1106,6 +1107,45 @@ out: 21.1262 + return ret; 21.1263 + } 21.1264 + 21.1265 ++/** 21.1266 ++ * skb_gso_segment - Perform segmentation on skb. 21.1267 ++ * @skb: buffer to segment 21.1268 ++ * @features: features for the output path (see dev->features) 21.1269 ++ * 21.1270 ++ * This function segments the given skb and returns a list of segments. 21.1271 ++ * 21.1272 ++ * It may return NULL if the skb requires no segmentation. This is 21.1273 ++ * only possible when GSO is used for verifying header integrity. 21.1274 ++ */ 21.1275 ++struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) 21.1276 ++{ 21.1277 ++ struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 21.1278 ++ struct packet_type *ptype; 21.1279 ++ int type = skb->protocol; 21.1280 ++ 21.1281 ++ BUG_ON(skb_shinfo(skb)->frag_list); 21.1282 ++ BUG_ON(skb->ip_summed != CHECKSUM_HW); 21.1283 ++ 21.1284 ++ skb->mac.raw = skb->data; 21.1285 ++ skb->mac_len = skb->nh.raw - skb->data; 21.1286 ++ __skb_pull(skb, skb->mac_len); 21.1287 ++ 21.1288 ++ rcu_read_lock(); 21.1289 ++ list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { 21.1290 ++ if (ptype->type == type && !ptype->dev && ptype->gso_segment) { 21.1291 ++ segs = ptype->gso_segment(skb, features); 21.1292 ++ break; 21.1293 ++ } 21.1294 ++ } 21.1295 ++ rcu_read_unlock(); 21.1296 ++ 21.1297 ++ __skb_push(skb, skb->data - skb->mac.raw); 21.1298 ++ 21.1299 ++ return segs; 21.1300 ++} 21.1301 ++ 21.1302 ++EXPORT_SYMBOL(skb_gso_segment); 21.1303 ++ 21.1304 + /* Take action when hardware reception checksum errors are detected. */ 21.1305 + #ifdef CONFIG_BUG 21.1306 + void netdev_rx_csum_fault(struct net_device *dev) 21.1307 +@@ -1142,75 +1182,108 @@ #else 21.1308 + #define illegal_highdma(dev, skb) (0) 21.1309 + #endif 21.1310 + 21.1311 +-/* Keep head the same: replace data */ 21.1312 +-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask) 21.1313 +-{ 21.1314 +- unsigned int size; 21.1315 +- u8 *data; 21.1316 +- long offset; 21.1317 +- struct skb_shared_info *ninfo; 21.1318 +- int headerlen = skb->data - skb->head; 21.1319 +- int expand = (skb->tail + skb->data_len) - skb->end; 21.1320 +- 21.1321 +- if (skb_shared(skb)) 21.1322 +- BUG(); 21.1323 +- 21.1324 +- if (expand <= 0) 21.1325 +- expand = 0; 21.1326 +- 21.1327 +- size = skb->end - skb->head + expand; 21.1328 +- size = SKB_DATA_ALIGN(size); 21.1329 +- data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); 21.1330 +- if (!data) 21.1331 +- return -ENOMEM; 21.1332 +- 21.1333 +- /* Copy entire thing */ 21.1334 +- if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len)) 21.1335 +- BUG(); 21.1336 +- 21.1337 +- /* Set up shinfo */ 21.1338 +- ninfo = (struct skb_shared_info*)(data + size); 21.1339 +- atomic_set(&ninfo->dataref, 1); 21.1340 +- ninfo->tso_size = skb_shinfo(skb)->tso_size; 21.1341 +- ninfo->tso_segs = skb_shinfo(skb)->tso_segs; 21.1342 +- ninfo->nr_frags = 0; 21.1343 +- ninfo->frag_list = NULL; 21.1344 +- 21.1345 +- /* Offset between the two in bytes */ 21.1346 +- offset = data - skb->head; 21.1347 +- 21.1348 +- /* Free old data. */ 21.1349 +- skb_release_data(skb); 21.1350 +- 21.1351 +- skb->head = data; 21.1352 +- skb->end = data + size; 21.1353 +- 21.1354 +- /* Set up new pointers */ 21.1355 +- skb->h.raw += offset; 21.1356 +- skb->nh.raw += offset; 21.1357 +- skb->mac.raw += offset; 21.1358 +- skb->tail += offset; 21.1359 +- skb->data += offset; 21.1360 +- 21.1361 +- /* We are no longer a clone, even if we were. */ 21.1362 +- skb->cloned = 0; 21.1363 +- 21.1364 +- skb->tail += skb->data_len; 21.1365 +- skb->data_len = 0; 21.1366 ++struct dev_gso_cb { 21.1367 ++ void (*destructor)(struct sk_buff *skb); 21.1368 ++}; 21.1369 ++ 21.1370 ++#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb) 21.1371 ++ 21.1372 ++static void dev_gso_skb_destructor(struct sk_buff *skb) 21.1373 ++{ 21.1374 ++ struct dev_gso_cb *cb; 21.1375 ++ 21.1376 ++ do { 21.1377 ++ struct sk_buff *nskb = skb->next; 21.1378 ++ 21.1379 ++ skb->next = nskb->next; 21.1380 ++ nskb->next = NULL; 21.1381 ++ kfree_skb(nskb); 21.1382 ++ } while (skb->next); 21.1383 ++ 21.1384 ++ cb = DEV_GSO_CB(skb); 21.1385 ++ if (cb->destructor) 21.1386 ++ cb->destructor(skb); 21.1387 ++} 21.1388 ++ 21.1389 ++/** 21.1390 ++ * dev_gso_segment - Perform emulated hardware segmentation on skb. 21.1391 ++ * @skb: buffer to segment 21.1392 ++ * 21.1393 ++ * This function segments the given skb and stores the list of segments 21.1394 ++ * in skb->next. 21.1395 ++ */ 21.1396 ++static int dev_gso_segment(struct sk_buff *skb) 21.1397 ++{ 21.1398 ++ struct net_device *dev = skb->dev; 21.1399 ++ struct sk_buff *segs; 21.1400 ++ int features = dev->features & ~(illegal_highdma(dev, skb) ? 21.1401 ++ NETIF_F_SG : 0); 21.1402 ++ 21.1403 ++ segs = skb_gso_segment(skb, features); 21.1404 ++ 21.1405 ++ /* Verifying header integrity only. */ 21.1406 ++ if (!segs) 21.1407 ++ return 0; 21.1408 ++ 21.1409 ++ if (unlikely(IS_ERR(segs))) 21.1410 ++ return PTR_ERR(segs); 21.1411 ++ 21.1412 ++ skb->next = segs; 21.1413 ++ DEV_GSO_CB(skb)->destructor = skb->destructor; 21.1414 ++ skb->destructor = dev_gso_skb_destructor; 21.1415 ++ 21.1416 ++ return 0; 21.1417 ++} 21.1418 ++ 21.1419 ++int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 21.1420 ++{ 21.1421 ++ if (likely(!skb->next)) { 21.1422 ++ if (netdev_nit) 21.1423 ++ dev_queue_xmit_nit(skb, dev); 21.1424 ++ 21.1425 ++ if (netif_needs_gso(dev, skb)) { 21.1426 ++ if (unlikely(dev_gso_segment(skb))) 21.1427 ++ goto out_kfree_skb; 21.1428 ++ if (skb->next) 21.1429 ++ goto gso; 21.1430 ++ } 21.1431 ++ 21.1432 ++ return dev->hard_start_xmit(skb, dev); 21.1433 ++ } 21.1434 ++ 21.1435 ++gso: 21.1436 ++ do { 21.1437 ++ struct sk_buff *nskb = skb->next; 21.1438 ++ int rc; 21.1439 ++ 21.1440 ++ skb->next = nskb->next; 21.1441 ++ nskb->next = NULL; 21.1442 ++ rc = dev->hard_start_xmit(nskb, dev); 21.1443 ++ if (unlikely(rc)) { 21.1444 ++ nskb->next = skb->next; 21.1445 ++ skb->next = nskb; 21.1446 ++ return rc; 21.1447 ++ } 21.1448 ++ if (unlikely(netif_queue_stopped(dev) && skb->next)) 21.1449 ++ return NETDEV_TX_BUSY; 21.1450 ++ } while (skb->next); 21.1451 ++ 21.1452 ++ skb->destructor = DEV_GSO_CB(skb)->destructor; 21.1453 ++ 21.1454 ++out_kfree_skb: 21.1455 ++ kfree_skb(skb); 21.1456 + return 0; 21.1457 + } 21.1458 + 21.1459 + #define HARD_TX_LOCK(dev, cpu) { \ 21.1460 + if ((dev->features & NETIF_F_LLTX) == 0) { \ 21.1461 +- spin_lock(&dev->xmit_lock); \ 21.1462 +- dev->xmit_lock_owner = cpu; \ 21.1463 ++ netif_tx_lock(dev); \ 21.1464 + } \ 21.1465 + } 21.1466 + 21.1467 + #define HARD_TX_UNLOCK(dev) { \ 21.1468 + if ((dev->features & NETIF_F_LLTX) == 0) { \ 21.1469 +- dev->xmit_lock_owner = -1; \ 21.1470 +- spin_unlock(&dev->xmit_lock); \ 21.1471 ++ netif_tx_unlock(dev); \ 21.1472 + } \ 21.1473 + } 21.1474 + 21.1475 +@@ -1246,9 +1319,13 @@ int dev_queue_xmit(struct sk_buff *skb) 21.1476 + struct Qdisc *q; 21.1477 + int rc = -ENOMEM; 21.1478 + 21.1479 ++ /* GSO will handle the following emulations directly. */ 21.1480 ++ if (netif_needs_gso(dev, skb)) 21.1481 ++ goto gso; 21.1482 ++ 21.1483 + if (skb_shinfo(skb)->frag_list && 21.1484 + !(dev->features & NETIF_F_FRAGLIST) && 21.1485 +- __skb_linearize(skb, GFP_ATOMIC)) 21.1486 ++ __skb_linearize(skb)) 21.1487 + goto out_kfree_skb; 21.1488 + 21.1489 + /* Fragmented skb is linearized if device does not support SG, 21.1490 +@@ -1257,25 +1334,26 @@ int dev_queue_xmit(struct sk_buff *skb) 21.1491 + */ 21.1492 + if (skb_shinfo(skb)->nr_frags && 21.1493 + (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && 21.1494 +- __skb_linearize(skb, GFP_ATOMIC)) 21.1495 ++ __skb_linearize(skb)) 21.1496 + goto out_kfree_skb; 21.1497 + 21.1498 + /* If packet is not checksummed and device does not support 21.1499 + * checksumming for this protocol, complete checksumming here. 21.1500 + */ 21.1501 + if (skb->ip_summed == CHECKSUM_HW && 21.1502 +- (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) && 21.1503 ++ (!(dev->features & NETIF_F_GEN_CSUM) && 21.1504 + (!(dev->features & NETIF_F_IP_CSUM) || 21.1505 + skb->protocol != htons(ETH_P_IP)))) 21.1506 + if (skb_checksum_help(skb, 0)) 21.1507 + goto out_kfree_skb; 21.1508 + 21.1509 ++gso: 21.1510 + spin_lock_prefetch(&dev->queue_lock); 21.1511 + 21.1512 + /* Disable soft irqs for various locks below. Also 21.1513 + * stops preemption for RCU. 21.1514 + */ 21.1515 +- local_bh_disable(); 21.1516 ++ rcu_read_lock_bh(); 21.1517 + 21.1518 + /* Updates of qdisc are serialized by queue_lock. 21.1519 + * The struct Qdisc which is pointed to by qdisc is now a 21.1520 +@@ -1309,8 +1387,8 @@ #endif 21.1521 + /* The device has no queue. Common case for software devices: 21.1522 + loopback, all the sorts of tunnels... 21.1523 + 21.1524 +- Really, it is unlikely that xmit_lock protection is necessary here. 21.1525 +- (f.e. loopback and IP tunnels are clean ignoring statistics 21.1526 ++ Really, it is unlikely that netif_tx_lock protection is necessary 21.1527 ++ here. (f.e. loopback and IP tunnels are clean ignoring statistics 21.1528 + counters.) 21.1529 + However, it is possible, that they rely on protection 21.1530 + made by us here. 21.1531 +@@ -1326,11 +1404,8 @@ #endif 21.1532 + HARD_TX_LOCK(dev, cpu); 21.1533 + 21.1534 + if (!netif_queue_stopped(dev)) { 21.1535 +- if (netdev_nit) 21.1536 +- dev_queue_xmit_nit(skb, dev); 21.1537 +- 21.1538 + rc = 0; 21.1539 +- if (!dev->hard_start_xmit(skb, dev)) { 21.1540 ++ if (!dev_hard_start_xmit(skb, dev)) { 21.1541 + HARD_TX_UNLOCK(dev); 21.1542 + goto out; 21.1543 + } 21.1544 +@@ -1349,13 +1424,13 @@ #endif 21.1545 + } 21.1546 + 21.1547 + rc = -ENETDOWN; 21.1548 +- local_bh_enable(); 21.1549 ++ rcu_read_unlock_bh(); 21.1550 + 21.1551 + out_kfree_skb: 21.1552 + kfree_skb(skb); 21.1553 + return rc; 21.1554 + out: 21.1555 +- local_bh_enable(); 21.1556 ++ rcu_read_unlock_bh(); 21.1557 + return rc; 21.1558 + } 21.1559 + 21.1560 +@@ -2670,7 +2745,7 @@ int register_netdevice(struct net_device 21.1561 + BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); 21.1562 + 21.1563 + spin_lock_init(&dev->queue_lock); 21.1564 +- spin_lock_init(&dev->xmit_lock); 21.1565 ++ spin_lock_init(&dev->_xmit_lock); 21.1566 + dev->xmit_lock_owner = -1; 21.1567 + #ifdef CONFIG_NET_CLS_ACT 21.1568 + spin_lock_init(&dev->ingress_lock); 21.1569 +@@ -2714,9 +2789,7 @@ #endif 21.1570 + 21.1571 + /* Fix illegal SG+CSUM combinations. */ 21.1572 + if ((dev->features & NETIF_F_SG) && 21.1573 +- !(dev->features & (NETIF_F_IP_CSUM | 21.1574 +- NETIF_F_NO_CSUM | 21.1575 +- NETIF_F_HW_CSUM))) { 21.1576 ++ !(dev->features & NETIF_F_ALL_CSUM)) { 21.1577 + printk("%s: Dropping NETIF_F_SG since no checksum feature.\n", 21.1578 + dev->name); 21.1579 + dev->features &= ~NETIF_F_SG; 21.1580 +@@ -3268,7 +3341,6 @@ subsys_initcall(net_dev_init); 21.1581 + EXPORT_SYMBOL(__dev_get_by_index); 21.1582 + EXPORT_SYMBOL(__dev_get_by_name); 21.1583 + EXPORT_SYMBOL(__dev_remove_pack); 21.1584 +-EXPORT_SYMBOL(__skb_linearize); 21.1585 + EXPORT_SYMBOL(dev_valid_name); 21.1586 + EXPORT_SYMBOL(dev_add_pack); 21.1587 + EXPORT_SYMBOL(dev_alloc_name); 21.1588 +diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c 21.1589 +index 05d6085..c57d887 100644 21.1590 +--- a/net/core/dev_mcast.c 21.1591 ++++ b/net/core/dev_mcast.c 21.1592 +@@ -62,7 +62,7 @@ #include <net/arp.h> 21.1593 + * Device mc lists are changed by bh at least if IPv6 is enabled, 21.1594 + * so that it must be bh protected. 21.1595 + * 21.1596 +- * We block accesses to device mc filters with dev->xmit_lock. 21.1597 ++ * We block accesses to device mc filters with netif_tx_lock. 21.1598 + */ 21.1599 + 21.1600 + /* 21.1601 +@@ -93,9 +93,9 @@ static void __dev_mc_upload(struct net_d 21.1602 + 21.1603 + void dev_mc_upload(struct net_device *dev) 21.1604 + { 21.1605 +- spin_lock_bh(&dev->xmit_lock); 21.1606 ++ netif_tx_lock_bh(dev); 21.1607 + __dev_mc_upload(dev); 21.1608 +- spin_unlock_bh(&dev->xmit_lock); 21.1609 ++ netif_tx_unlock_bh(dev); 21.1610 + } 21.1611 + 21.1612 + /* 21.1613 +@@ -107,7 +107,7 @@ int dev_mc_delete(struct net_device *dev 21.1614 + int err = 0; 21.1615 + struct dev_mc_list *dmi, **dmip; 21.1616 + 21.1617 +- spin_lock_bh(&dev->xmit_lock); 21.1618 ++ netif_tx_lock_bh(dev); 21.1619 + 21.1620 + for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { 21.1621 + /* 21.1622 +@@ -139,13 +139,13 @@ int dev_mc_delete(struct net_device *dev 21.1623 + */ 21.1624 + __dev_mc_upload(dev); 21.1625 + 21.1626 +- spin_unlock_bh(&dev->xmit_lock); 21.1627 ++ netif_tx_unlock_bh(dev); 21.1628 + return 0; 21.1629 + } 21.1630 + } 21.1631 + err = -ENOENT; 21.1632 + done: 21.1633 +- spin_unlock_bh(&dev->xmit_lock); 21.1634 ++ netif_tx_unlock_bh(dev); 21.1635 + return err; 21.1636 + } 21.1637 + 21.1638 +@@ -160,7 +160,7 @@ int dev_mc_add(struct net_device *dev, v 21.1639 + 21.1640 + dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC); 21.1641 + 21.1642 +- spin_lock_bh(&dev->xmit_lock); 21.1643 ++ netif_tx_lock_bh(dev); 21.1644 + for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { 21.1645 + if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 && 21.1646 + dmi->dmi_addrlen == alen) { 21.1647 +@@ -176,7 +176,7 @@ int dev_mc_add(struct net_device *dev, v 21.1648 + } 21.1649 + 21.1650 + if ((dmi = dmi1) == NULL) { 21.1651 +- spin_unlock_bh(&dev->xmit_lock); 21.1652 ++ netif_tx_unlock_bh(dev); 21.1653 + return -ENOMEM; 21.1654 + } 21.1655 + memcpy(dmi->dmi_addr, addr, alen); 21.1656 +@@ -189,11 +189,11 @@ int dev_mc_add(struct net_device *dev, v 21.1657 + 21.1658 + __dev_mc_upload(dev); 21.1659 + 21.1660 +- spin_unlock_bh(&dev->xmit_lock); 21.1661 ++ netif_tx_unlock_bh(dev); 21.1662 + return 0; 21.1663 + 21.1664 + done: 21.1665 +- spin_unlock_bh(&dev->xmit_lock); 21.1666 ++ netif_tx_unlock_bh(dev); 21.1667 + kfree(dmi1); 21.1668 + return err; 21.1669 + } 21.1670 +@@ -204,7 +204,7 @@ done: 21.1671 + 21.1672 + void dev_mc_discard(struct net_device *dev) 21.1673 + { 21.1674 +- spin_lock_bh(&dev->xmit_lock); 21.1675 ++ netif_tx_lock_bh(dev); 21.1676 + 21.1677 + while (dev->mc_list != NULL) { 21.1678 + struct dev_mc_list *tmp = dev->mc_list; 21.1679 +@@ -215,7 +215,7 @@ void dev_mc_discard(struct net_device *d 21.1680 + } 21.1681 + dev->mc_count = 0; 21.1682 + 21.1683 +- spin_unlock_bh(&dev->xmit_lock); 21.1684 ++ netif_tx_unlock_bh(dev); 21.1685 + } 21.1686 + 21.1687 + #ifdef CONFIG_PROC_FS 21.1688 +@@ -250,7 +250,7 @@ static int dev_mc_seq_show(struct seq_fi 21.1689 + struct dev_mc_list *m; 21.1690 + struct net_device *dev = v; 21.1691 + 21.1692 +- spin_lock_bh(&dev->xmit_lock); 21.1693 ++ netif_tx_lock_bh(dev); 21.1694 + for (m = dev->mc_list; m; m = m->next) { 21.1695 + int i; 21.1696 + 21.1697 +@@ -262,7 +262,7 @@ static int dev_mc_seq_show(struct seq_fi 21.1698 + 21.1699 + seq_putc(seq, '\n'); 21.1700 + } 21.1701 +- spin_unlock_bh(&dev->xmit_lock); 21.1702 ++ netif_tx_unlock_bh(dev); 21.1703 + return 0; 21.1704 + } 21.1705 + 21.1706 +diff --git a/net/core/ethtool.c b/net/core/ethtool.c 21.1707 +index e6f7610..27ce168 100644 21.1708 +--- a/net/core/ethtool.c 21.1709 ++++ b/net/core/ethtool.c 21.1710 +@@ -30,7 +30,7 @@ u32 ethtool_op_get_link(struct net_devic 21.1711 + 21.1712 + u32 ethtool_op_get_tx_csum(struct net_device *dev) 21.1713 + { 21.1714 +- return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0; 21.1715 ++ return (dev->features & NETIF_F_ALL_CSUM) != 0; 21.1716 + } 21.1717 + 21.1718 + int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 21.1719 +@@ -551,9 +551,7 @@ static int ethtool_set_sg(struct net_dev 21.1720 + return -EFAULT; 21.1721 + 21.1722 + if (edata.data && 21.1723 +- !(dev->features & (NETIF_F_IP_CSUM | 21.1724 +- NETIF_F_NO_CSUM | 21.1725 +- NETIF_F_HW_CSUM))) 21.1726 ++ !(dev->features & NETIF_F_ALL_CSUM)) 21.1727 + return -EINVAL; 21.1728 + 21.1729 + return __ethtool_set_sg(dev, edata.data); 21.1730 +@@ -591,7 +589,7 @@ static int ethtool_set_tso(struct net_de 21.1731 + 21.1732 + static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr) 21.1733 + { 21.1734 +- struct ethtool_value edata = { ETHTOOL_GTSO }; 21.1735 ++ struct ethtool_value edata = { ETHTOOL_GUFO }; 21.1736 + 21.1737 + if (!dev->ethtool_ops->get_ufo) 21.1738 + return -EOPNOTSUPP; 21.1739 +@@ -600,6 +598,7 @@ static int ethtool_get_ufo(struct net_de 21.1740 + return -EFAULT; 21.1741 + return 0; 21.1742 + } 21.1743 ++ 21.1744 + static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) 21.1745 + { 21.1746 + struct ethtool_value edata; 21.1747 +@@ -615,6 +614,29 @@ static int ethtool_set_ufo(struct net_de 21.1748 + return dev->ethtool_ops->set_ufo(dev, edata.data); 21.1749 + } 21.1750 + 21.1751 ++static int ethtool_get_gso(struct net_device *dev, char __user *useraddr) 21.1752 ++{ 21.1753 ++ struct ethtool_value edata = { ETHTOOL_GGSO }; 21.1754 ++ 21.1755 ++ edata.data = dev->features & NETIF_F_GSO; 21.1756 ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) 21.1757 ++ return -EFAULT; 21.1758 ++ return 0; 21.1759 ++} 21.1760 ++ 21.1761 ++static int ethtool_set_gso(struct net_device *dev, char __user *useraddr) 21.1762 ++{ 21.1763 ++ struct ethtool_value edata; 21.1764 ++ 21.1765 ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) 21.1766 ++ return -EFAULT; 21.1767 ++ if (edata.data) 21.1768 ++ dev->features |= NETIF_F_GSO; 21.1769 ++ else 21.1770 ++ dev->features &= ~NETIF_F_GSO; 21.1771 ++ return 0; 21.1772 ++} 21.1773 ++ 21.1774 + static int ethtool_self_test(struct net_device *dev, char __user *useraddr) 21.1775 + { 21.1776 + struct ethtool_test test; 21.1777 +@@ -906,6 +928,12 @@ int dev_ethtool(struct ifreq *ifr) 21.1778 + case ETHTOOL_SUFO: 21.1779 + rc = ethtool_set_ufo(dev, useraddr); 21.1780 + break; 21.1781 ++ case ETHTOOL_GGSO: 21.1782 ++ rc = ethtool_get_gso(dev, useraddr); 21.1783 ++ break; 21.1784 ++ case ETHTOOL_SGSO: 21.1785 ++ rc = ethtool_set_gso(dev, useraddr); 21.1786 ++ break; 21.1787 + default: 21.1788 + rc = -EOPNOTSUPP; 21.1789 + } 21.1790 +diff --git a/net/core/netpoll.c b/net/core/netpoll.c 21.1791 +index ea51f8d..ec28d3b 100644 21.1792 +--- a/net/core/netpoll.c 21.1793 ++++ b/net/core/netpoll.c 21.1794 +@@ -273,24 +273,21 @@ static void netpoll_send_skb(struct netp 21.1795 + 21.1796 + do { 21.1797 + npinfo->tries--; 21.1798 +- spin_lock(&np->dev->xmit_lock); 21.1799 +- np->dev->xmit_lock_owner = smp_processor_id(); 21.1800 ++ netif_tx_lock(np->dev); 21.1801 + 21.1802 + /* 21.1803 + * network drivers do not expect to be called if the queue is 21.1804 + * stopped. 21.1805 + */ 21.1806 + if (netif_queue_stopped(np->dev)) { 21.1807 +- np->dev->xmit_lock_owner = -1; 21.1808 +- spin_unlock(&np->dev->xmit_lock); 21.1809 ++ netif_tx_unlock(np->dev); 21.1810 + netpoll_poll(np); 21.1811 + udelay(50); 21.1812 + continue; 21.1813 + } 21.1814 + 21.1815 + status = np->dev->hard_start_xmit(skb, np->dev); 21.1816 +- np->dev->xmit_lock_owner = -1; 21.1817 +- spin_unlock(&np->dev->xmit_lock); 21.1818 ++ netif_tx_unlock(np->dev); 21.1819 + 21.1820 + /* success */ 21.1821 + if(!status) { 21.1822 +diff --git a/net/core/pktgen.c b/net/core/pktgen.c 21.1823 +index da16f8f..2380347 100644 21.1824 +--- a/net/core/pktgen.c 21.1825 ++++ b/net/core/pktgen.c 21.1826 +@@ -2582,7 +2582,7 @@ static __inline__ void pktgen_xmit(struc 21.1827 + } 21.1828 + } 21.1829 + 21.1830 +- spin_lock_bh(&odev->xmit_lock); 21.1831 ++ netif_tx_lock_bh(odev); 21.1832 + if (!netif_queue_stopped(odev)) { 21.1833 + 21.1834 + atomic_inc(&(pkt_dev->skb->users)); 21.1835 +@@ -2627,7 +2627,7 @@ retry_now: 21.1836 + pkt_dev->next_tx_ns = 0; 21.1837 + } 21.1838 + 21.1839 +- spin_unlock_bh(&odev->xmit_lock); 21.1840 ++ netif_tx_unlock_bh(odev); 21.1841 + 21.1842 + /* If pkt_dev->count is zero, then run forever */ 21.1843 + if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) { 21.1844 +diff --git a/net/core/skbuff.c b/net/core/skbuff.c 21.1845 +index 2144952..46f56af 100644 21.1846 +--- a/net/core/skbuff.c 21.1847 ++++ b/net/core/skbuff.c 21.1848 +@@ -164,9 +164,9 @@ struct sk_buff *__alloc_skb(unsigned int 21.1849 + shinfo = skb_shinfo(skb); 21.1850 + atomic_set(&shinfo->dataref, 1); 21.1851 + shinfo->nr_frags = 0; 21.1852 +- shinfo->tso_size = 0; 21.1853 +- shinfo->tso_segs = 0; 21.1854 +- shinfo->ufo_size = 0; 21.1855 ++ shinfo->gso_size = 0; 21.1856 ++ shinfo->gso_segs = 0; 21.1857 ++ shinfo->gso_type = 0; 21.1858 + shinfo->ip6_frag_id = 0; 21.1859 + shinfo->frag_list = NULL; 21.1860 + 21.1861 +@@ -230,8 +230,9 @@ struct sk_buff *alloc_skb_from_cache(kme 21.1862 + 21.1863 + atomic_set(&(skb_shinfo(skb)->dataref), 1); 21.1864 + skb_shinfo(skb)->nr_frags = 0; 21.1865 +- skb_shinfo(skb)->tso_size = 0; 21.1866 +- skb_shinfo(skb)->tso_segs = 0; 21.1867 ++ skb_shinfo(skb)->gso_size = 0; 21.1868 ++ skb_shinfo(skb)->gso_segs = 0; 21.1869 ++ skb_shinfo(skb)->gso_type = 0; 21.1870 + skb_shinfo(skb)->frag_list = NULL; 21.1871 + out: 21.1872 + return skb; 21.1873 +@@ -501,8 +502,9 @@ #endif 21.1874 + new->tc_index = old->tc_index; 21.1875 + #endif 21.1876 + atomic_set(&new->users, 1); 21.1877 +- skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size; 21.1878 +- skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs; 21.1879 ++ skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; 21.1880 ++ skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; 21.1881 ++ skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; 21.1882 + } 21.1883 + 21.1884 + /** 21.1885 +@@ -1777,6 +1779,133 @@ int skb_append_datato_frags(struct sock 21.1886 + return 0; 21.1887 + } 21.1888 + 21.1889 ++/** 21.1890 ++ * skb_segment - Perform protocol segmentation on skb. 21.1891 ++ * @skb: buffer to segment 21.1892 ++ * @features: features for the output path (see dev->features) 21.1893 ++ * 21.1894 ++ * This function performs segmentation on the given skb. It returns 21.1895 ++ * the segment at the given position. It returns NULL if there are 21.1896 ++ * no more segments to generate, or when an error is encountered. 21.1897 ++ */ 21.1898 ++struct sk_buff *skb_segment(struct sk_buff *skb, int features) 21.1899 ++{ 21.1900 ++ struct sk_buff *segs = NULL; 21.1901 ++ struct sk_buff *tail = NULL; 21.1902 ++ unsigned int mss = skb_shinfo(skb)->gso_size; 21.1903 ++ unsigned int doffset = skb->data - skb->mac.raw; 21.1904 ++ unsigned int offset = doffset; 21.1905 ++ unsigned int headroom; 21.1906 ++ unsigned int len; 21.1907 ++ int sg = features & NETIF_F_SG; 21.1908 ++ int nfrags = skb_shinfo(skb)->nr_frags; 21.1909 ++ int err = -ENOMEM; 21.1910 ++ int i = 0; 21.1911 ++ int pos; 21.1912 ++ 21.1913 ++ __skb_push(skb, doffset); 21.1914 ++ headroom = skb_headroom(skb); 21.1915 ++ pos = skb_headlen(skb); 21.1916 ++ 21.1917 ++ do { 21.1918 ++ struct sk_buff *nskb; 21.1919 ++ skb_frag_t *frag; 21.1920 ++ int hsize, nsize; 21.1921 ++ int k; 21.1922 ++ int size; 21.1923 ++ 21.1924 ++ len = skb->len - offset; 21.1925 ++ if (len > mss) 21.1926 ++ len = mss; 21.1927 ++ 21.1928 ++ hsize = skb_headlen(skb) - offset; 21.1929 ++ if (hsize < 0) 21.1930 ++ hsize = 0; 21.1931 ++ nsize = hsize + doffset; 21.1932 ++ if (nsize > len + doffset || !sg) 21.1933 ++ nsize = len + doffset; 21.1934 ++ 21.1935 ++ nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); 21.1936 ++ if (unlikely(!nskb)) 21.1937 ++ goto err; 21.1938 ++ 21.1939 ++ if (segs) 21.1940 ++ tail->next = nskb; 21.1941 ++ else 21.1942 ++ segs = nskb; 21.1943 ++ tail = nskb; 21.1944 ++ 21.1945 ++ nskb->dev = skb->dev; 21.1946 ++ nskb->priority = skb->priority; 21.1947 ++ nskb->protocol = skb->protocol; 21.1948 ++ nskb->dst = dst_clone(skb->dst); 21.1949 ++ memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); 21.1950 ++ nskb->pkt_type = skb->pkt_type; 21.1951 ++ nskb->mac_len = skb->mac_len; 21.1952 ++ 21.1953 ++ skb_reserve(nskb, headroom); 21.1954 ++ nskb->mac.raw = nskb->data; 21.1955 ++ nskb->nh.raw = nskb->data + skb->mac_len; 21.1956 ++ nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw); 21.1957 ++ memcpy(skb_put(nskb, doffset), skb->data, doffset); 21.1958 ++ 21.1959 ++ if (!sg) { 21.1960 ++ nskb->csum = skb_copy_and_csum_bits(skb, offset, 21.1961 ++ skb_put(nskb, len), 21.1962 ++ len, 0); 21.1963 ++ continue; 21.1964 ++ } 21.1965 ++ 21.1966 ++ frag = skb_shinfo(nskb)->frags; 21.1967 ++ k = 0; 21.1968 ++ 21.1969 ++ nskb->ip_summed = CHECKSUM_HW; 21.1970 ++ nskb->csum = skb->csum; 21.1971 ++ memcpy(skb_put(nskb, hsize), skb->data + offset, hsize); 21.1972 ++ 21.1973 ++ while (pos < offset + len) { 21.1974 ++ BUG_ON(i >= nfrags); 21.1975 ++ 21.1976 ++ *frag = skb_shinfo(skb)->frags[i]; 21.1977 ++ get_page(frag->page); 21.1978 ++ size = frag->size; 21.1979 ++ 21.1980 ++ if (pos < offset) { 21.1981 ++ frag->page_offset += offset - pos; 21.1982 ++ frag->size -= offset - pos; 21.1983 ++ } 21.1984 ++ 21.1985 ++ k++; 21.1986 ++ 21.1987 ++ if (pos + size <= offset + len) { 21.1988 ++ i++; 21.1989 ++ pos += size; 21.1990 ++ } else { 21.1991 ++ frag->size -= pos + size - (offset + len); 21.1992 ++ break; 21.1993 ++ } 21.1994 ++ 21.1995 ++ frag++; 21.1996 ++ } 21.1997 ++ 21.1998 ++ skb_shinfo(nskb)->nr_frags = k; 21.1999 ++ nskb->data_len = len - hsize; 21.2000 ++ nskb->len += nskb->data_len; 21.2001 ++ nskb->truesize += nskb->data_len; 21.2002 ++ } while ((offset += len) < skb->len); 21.2003 ++ 21.2004 ++ return segs; 21.2005 ++ 21.2006 ++err: 21.2007 ++ while ((skb = segs)) { 21.2008 ++ segs = skb->next; 21.2009 ++ kfree(skb); 21.2010 ++ } 21.2011 ++ return ERR_PTR(err); 21.2012 ++} 21.2013 ++ 21.2014 ++EXPORT_SYMBOL_GPL(skb_segment); 21.2015 ++ 21.2016 + void __init skb_init(void) 21.2017 + { 21.2018 + skbuff_head_cache = kmem_cache_create("skbuff_head_cache", 21.2019 +diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c 21.2020 +index 44bda85..2e3323a 100644 21.2021 +--- a/net/decnet/dn_nsp_in.c 21.2022 ++++ b/net/decnet/dn_nsp_in.c 21.2023 +@@ -801,8 +801,7 @@ got_it: 21.2024 + * We linearize everything except data segments here. 21.2025 + */ 21.2026 + if (cb->nsp_flags & ~0x60) { 21.2027 +- if (unlikely(skb_is_nonlinear(skb)) && 21.2028 +- skb_linearize(skb, GFP_ATOMIC) != 0) 21.2029 ++ if (unlikely(skb_linearize(skb))) 21.2030 + goto free_out; 21.2031 + } 21.2032 + 21.2033 +diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c 21.2034 +index 3407f19..a0a25e0 100644 21.2035 +--- a/net/decnet/dn_route.c 21.2036 ++++ b/net/decnet/dn_route.c 21.2037 +@@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, st 21.2038 + padlen); 21.2039 + 21.2040 + if (flags & DN_RT_PKT_CNTL) { 21.2041 +- if (unlikely(skb_is_nonlinear(skb)) && 21.2042 +- skb_linearize(skb, GFP_ATOMIC) != 0) 21.2043 ++ if (unlikely(skb_linearize(skb))) 21.2044 + goto dump_it; 21.2045 + 21.2046 + switch(flags & DN_RT_CNTL_MSK) { 21.2047 +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c 21.2048 +index 97c276f..5ba719e 100644 21.2049 +--- a/net/ipv4/af_inet.c 21.2050 ++++ b/net/ipv4/af_inet.c 21.2051 +@@ -68,6 +68,7 @@ 21.2052 + */ 21.2053 + 21.2054 + #include <linux/config.h> 21.2055 ++#include <linux/err.h> 21.2056 + #include <linux/errno.h> 21.2057 + #include <linux/types.h> 21.2058 + #include <linux/socket.h> 21.2059 +@@ -1084,6 +1085,54 @@ int inet_sk_rebuild_header(struct sock * 21.2060 + 21.2061 + EXPORT_SYMBOL(inet_sk_rebuild_header); 21.2062 + 21.2063 ++static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) 21.2064 ++{ 21.2065 ++ struct sk_buff *segs = ERR_PTR(-EINVAL); 21.2066 ++ struct iphdr *iph; 21.2067 ++ struct net_protocol *ops; 21.2068 ++ int proto; 21.2069 ++ int ihl; 21.2070 ++ int id; 21.2071 ++ 21.2072 ++ if (!pskb_may_pull(skb, sizeof(*iph))) 21.2073 ++ goto out; 21.2074 ++ 21.2075 ++ iph = skb->nh.iph; 21.2076 ++ ihl = iph->ihl * 4; 21.2077 ++ if (ihl < sizeof(*iph)) 21.2078 ++ goto out; 21.2079 ++ 21.2080 ++ if (!pskb_may_pull(skb, ihl)) 21.2081 ++ goto out; 21.2082 ++ 21.2083 ++ skb->h.raw = __skb_pull(skb, ihl); 21.2084 ++ iph = skb->nh.iph; 21.2085 ++ id = ntohs(iph->id); 21.2086 ++ proto = iph->protocol & (MAX_INET_PROTOS - 1); 21.2087 ++ segs = ERR_PTR(-EPROTONOSUPPORT); 21.2088 ++ 21.2089 ++ rcu_read_lock(); 21.2090 ++ ops = rcu_dereference(inet_protos[proto]); 21.2091 ++ if (ops && ops->gso_segment) 21.2092 ++ segs = ops->gso_segment(skb, features); 21.2093 ++ rcu_read_unlock(); 21.2094 ++ 21.2095 ++ if (!segs || unlikely(IS_ERR(segs))) 21.2096 ++ goto out; 21.2097 ++ 21.2098 ++ skb = segs; 21.2099 ++ do { 21.2100 ++ iph = skb->nh.iph; 21.2101 ++ iph->id = htons(id++); 21.2102 ++ iph->tot_len = htons(skb->len - skb->mac_len); 21.2103 ++ iph->check = 0; 21.2104 ++ iph->check = ip_fast_csum(skb->nh.raw, iph->ihl); 21.2105 ++ } while ((skb = skb->next)); 21.2106 ++ 21.2107 ++out: 21.2108 ++ return segs; 21.2109 ++} 21.2110 ++ 21.2111 + #ifdef CONFIG_IP_MULTICAST 21.2112 + static struct net_protocol igmp_protocol = { 21.2113 + .handler = igmp_rcv, 21.2114 +@@ -1093,6 +1142,7 @@ #endif 21.2115 + static struct net_protocol tcp_protocol = { 21.2116 + .handler = tcp_v4_rcv, 21.2117 + .err_handler = tcp_v4_err, 21.2118 ++ .gso_segment = tcp_tso_segment, 21.2119 + .no_policy = 1, 21.2120 + }; 21.2121 + 21.2122 +@@ -1138,6 +1188,7 @@ static int ipv4_proc_init(void); 21.2123 + static struct packet_type ip_packet_type = { 21.2124 + .type = __constant_htons(ETH_P_IP), 21.2125 + .func = ip_rcv, 21.2126 ++ .gso_segment = inet_gso_segment, 21.2127 + }; 21.2128 + 21.2129 + static int __init inet_init(void) 21.2130 +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c 21.2131 +index 8dcba38..19c3c73 100644 21.2132 +--- a/net/ipv4/ip_output.c 21.2133 ++++ b/net/ipv4/ip_output.c 21.2134 +@@ -210,8 +210,7 @@ #if defined(CONFIG_NETFILTER) && defined 21.2135 + return dst_output(skb); 21.2136 + } 21.2137 + #endif 21.2138 +- if (skb->len > dst_mtu(skb->dst) && 21.2139 +- !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) 21.2140 ++ if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) 21.2141 + return ip_fragment(skb, ip_finish_output2); 21.2142 + else 21.2143 + return ip_finish_output2(skb); 21.2144 +@@ -362,7 +361,7 @@ packet_routed: 21.2145 + } 21.2146 + 21.2147 + ip_select_ident_more(iph, &rt->u.dst, sk, 21.2148 +- (skb_shinfo(skb)->tso_segs ?: 1) - 1); 21.2149 ++ (skb_shinfo(skb)->gso_segs ?: 1) - 1); 21.2150 + 21.2151 + /* Add an IP checksum. */ 21.2152 + ip_send_check(iph); 21.2153 +@@ -743,7 +742,8 @@ static inline int ip_ufo_append_data(str 21.2154 + (length - transhdrlen)); 21.2155 + if (!err) { 21.2156 + /* specify the length of each IP datagram fragment*/ 21.2157 +- skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); 21.2158 ++ skb_shinfo(skb)->gso_size = mtu - fragheaderlen; 21.2159 ++ skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; 21.2160 + __skb_queue_tail(&sk->sk_write_queue, skb); 21.2161 + 21.2162 + return 0; 21.2163 +@@ -839,7 +839,7 @@ int ip_append_data(struct sock *sk, 21.2164 + */ 21.2165 + if (transhdrlen && 21.2166 + length + fragheaderlen <= mtu && 21.2167 +- rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) && 21.2168 ++ rt->u.dst.dev->features & NETIF_F_ALL_CSUM && 21.2169 + !exthdrlen) 21.2170 + csummode = CHECKSUM_HW; 21.2171 + 21.2172 +@@ -1086,14 +1086,16 @@ ssize_t ip_append_page(struct sock *sk, 21.2173 + 21.2174 + inet->cork.length += size; 21.2175 + if ((sk->sk_protocol == IPPROTO_UDP) && 21.2176 +- (rt->u.dst.dev->features & NETIF_F_UFO)) 21.2177 +- skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); 21.2178 ++ (rt->u.dst.dev->features & NETIF_F_UFO)) { 21.2179 ++ skb_shinfo(skb)->gso_size = mtu - fragheaderlen; 21.2180 ++ skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; 21.2181 ++ } 21.2182 + 21.2183 + 21.2184 + while (size > 0) { 21.2185 + int i; 21.2186 + 21.2187 +- if (skb_shinfo(skb)->ufo_size) 21.2188 ++ if (skb_shinfo(skb)->gso_size) 21.2189 + len = size; 21.2190 + else { 21.2191 + 21.2192 +diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c 21.2193 +index d64e2ec..7494823 100644 21.2194 +--- a/net/ipv4/ipcomp.c 21.2195 ++++ b/net/ipv4/ipcomp.c 21.2196 +@@ -84,7 +84,7 @@ static int ipcomp_input(struct xfrm_stat 21.2197 + struct xfrm_decap_state *decap, struct sk_buff *skb) 21.2198 + { 21.2199 + u8 nexthdr; 21.2200 +- int err = 0; 21.2201 ++ int err = -ENOMEM; 21.2202 + struct iphdr *iph; 21.2203 + union { 21.2204 + struct iphdr iph; 21.2205 +@@ -92,11 +92,8 @@ static int ipcomp_input(struct xfrm_stat 21.2206 + } tmp_iph; 21.2207 + 21.2208 + 21.2209 +- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && 21.2210 +- skb_linearize(skb, GFP_ATOMIC) != 0) { 21.2211 +- err = -ENOMEM; 21.2212 ++ if (skb_linearize_cow(skb)) 21.2213 + goto out; 21.2214 +- } 21.2215 + 21.2216 + skb->ip_summed = CHECKSUM_NONE; 21.2217 + 21.2218 +@@ -171,10 +168,8 @@ static int ipcomp_output(struct xfrm_sta 21.2219 + goto out_ok; 21.2220 + } 21.2221 + 21.2222 +- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && 21.2223 +- skb_linearize(skb, GFP_ATOMIC) != 0) { 21.2224 ++ if (skb_linearize_cow(skb)) 21.2225 + goto out_ok; 21.2226 +- } 21.2227 + 21.2228 + err = ipcomp_compress(x, skb); 21.2229 + iph = skb->nh.iph; 21.2230 +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c 21.2231 +index 00aa80e..84130c9 100644 21.2232 +--- a/net/ipv4/tcp.c 21.2233 ++++ b/net/ipv4/tcp.c 21.2234 +@@ -257,6 +257,7 @@ #include <linux/smp_lock.h> 21.2235 + #include <linux/fs.h> 21.2236 + #include <linux/random.h> 21.2237 + #include <linux/bootmem.h> 21.2238 ++#include <linux/err.h> 21.2239 + 21.2240 + #include <net/icmp.h> 21.2241 + #include <net/tcp.h> 21.2242 +@@ -570,7 +571,7 @@ new_segment: 21.2243 + skb->ip_summed = CHECKSUM_HW; 21.2244 + tp->write_seq += copy; 21.2245 + TCP_SKB_CB(skb)->end_seq += copy; 21.2246 +- skb_shinfo(skb)->tso_segs = 0; 21.2247 ++ skb_shinfo(skb)->gso_segs = 0; 21.2248 + 21.2249 + if (!copied) 21.2250 + TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH; 21.2251 +@@ -621,14 +622,10 @@ ssize_t tcp_sendpage(struct socket *sock 21.2252 + ssize_t res; 21.2253 + struct sock *sk = sock->sk; 21.2254 + 21.2255 +-#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) 21.2256 +- 21.2257 + if (!(sk->sk_route_caps & NETIF_F_SG) || 21.2258 +- !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS)) 21.2259 ++ !(sk->sk_route_caps & NETIF_F_ALL_CSUM)) 21.2260 + return sock_no_sendpage(sock, page, offset, size, flags); 21.2261 + 21.2262 +-#undef TCP_ZC_CSUM_FLAGS 21.2263 +- 21.2264 + lock_sock(sk); 21.2265 + TCP_CHECK_TIMER(sk); 21.2266 + res = do_tcp_sendpages(sk, &page, offset, size, flags); 21.2267 +@@ -725,9 +722,7 @@ new_segment: 21.2268 + /* 21.2269 + * Check whether we can use HW checksum. 21.2270 + */ 21.2271 +- if (sk->sk_route_caps & 21.2272 +- (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | 21.2273 +- NETIF_F_HW_CSUM)) 21.2274 ++ if (sk->sk_route_caps & NETIF_F_ALL_CSUM) 21.2275 + skb->ip_summed = CHECKSUM_HW; 21.2276 + 21.2277 + skb_entail(sk, tp, skb); 21.2278 +@@ -823,7 +818,7 @@ new_segment: 21.2279 + 21.2280 + tp->write_seq += copy; 21.2281 + TCP_SKB_CB(skb)->end_seq += copy; 21.2282 +- skb_shinfo(skb)->tso_segs = 0; 21.2283 ++ skb_shinfo(skb)->gso_segs = 0; 21.2284 + 21.2285 + from += copy; 21.2286 + copied += copy; 21.2287 +@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 21.2288 + } 21.2289 + 21.2290 + 21.2291 ++struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) 21.2292 ++{ 21.2293 ++ struct sk_buff *segs = ERR_PTR(-EINVAL); 21.2294 ++ struct tcphdr *th; 21.2295 ++ unsigned thlen; 21.2296 ++ unsigned int seq; 21.2297 ++ unsigned int delta; 21.2298 ++ unsigned int oldlen; 21.2299 ++ unsigned int len; 21.2300 ++ 21.2301 ++ if (!pskb_may_pull(skb, sizeof(*th))) 21.2302 ++ goto out; 21.2303 ++ 21.2304 ++ th = skb->h.th; 21.2305 ++ thlen = th->doff * 4; 21.2306 ++ if (thlen < sizeof(*th)) 21.2307 ++ goto out; 21.2308 ++ 21.2309 ++ if (!pskb_may_pull(skb, thlen)) 21.2310 ++ goto out; 21.2311 ++ 21.2312 ++ segs = NULL; 21.2313 ++ if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) 21.2314 ++ goto out; 21.2315 ++ 21.2316 ++ oldlen = (u16)~skb->len; 21.2317 ++ __skb_pull(skb, thlen); 21.2318 ++ 21.2319 ++ segs = skb_segment(skb, features); 21.2320 ++ if (IS_ERR(segs)) 21.2321 ++ goto out; 21.2322 ++ 21.2323 ++ len = skb_shinfo(skb)->gso_size; 21.2324 ++ delta = htonl(oldlen + (thlen + len)); 21.2325 ++ 21.2326 ++ skb = segs; 21.2327 ++ th = skb->h.th; 21.2328 ++ seq = ntohl(th->seq); 21.2329 ++ 21.2330 ++ do { 21.2331 ++ th->fin = th->psh = 0; 21.2332 ++ 21.2333 ++ th->check = ~csum_fold(th->check + delta); 21.2334 ++ if (skb->ip_summed != CHECKSUM_HW) 21.2335 ++ th->check = csum_fold(csum_partial(skb->h.raw, thlen, 21.2336 ++ skb->csum)); 21.2337 ++ 21.2338 ++ seq += len; 21.2339 ++ skb = skb->next; 21.2340 ++ th = skb->h.th; 21.2341 ++ 21.2342 ++ th->seq = htonl(seq); 21.2343 ++ th->cwr = 0; 21.2344 ++ } while (skb->next); 21.2345 ++ 21.2346 ++ delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len); 21.2347 ++ th->check = ~csum_fold(th->check + delta); 21.2348 ++ if (skb->ip_summed != CHECKSUM_HW) 21.2349 ++ th->check = csum_fold(csum_partial(skb->h.raw, thlen, 21.2350 ++ skb->csum)); 21.2351 ++ 21.2352 ++out: 21.2353 ++ return segs; 21.2354 ++} 21.2355 ++ 21.2356 + extern void __skb_cb_too_small_for_tcp(int, int); 21.2357 + extern struct tcp_congestion_ops tcp_reno; 21.2358 + 21.2359 +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c 21.2360 +index e9a54ae..defe77a 100644 21.2361 +--- a/net/ipv4/tcp_input.c 21.2362 ++++ b/net/ipv4/tcp_input.c 21.2363 +@@ -1072,7 +1072,7 @@ tcp_sacktag_write_queue(struct sock *sk, 21.2364 + else 21.2365 + pkt_len = (end_seq - 21.2366 + TCP_SKB_CB(skb)->seq); 21.2367 +- if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size)) 21.2368 ++ if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->gso_size)) 21.2369 + break; 21.2370 + pcount = tcp_skb_pcount(skb); 21.2371 + } 21.2372 +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c 21.2373 +index 310f2e6..ee01f69 100644 21.2374 +--- a/net/ipv4/tcp_output.c 21.2375 ++++ b/net/ipv4/tcp_output.c 21.2376 +@@ -497,15 +497,17 @@ static void tcp_set_skb_tso_segs(struct 21.2377 + /* Avoid the costly divide in the normal 21.2378 + * non-TSO case. 21.2379 + */ 21.2380 +- skb_shinfo(skb)->tso_segs = 1; 21.2381 +- skb_shinfo(skb)->tso_size = 0; 21.2382 ++ skb_shinfo(skb)->gso_segs = 1; 21.2383 ++ skb_shinfo(skb)->gso_size = 0; 21.2384 ++ skb_shinfo(skb)->gso_type = 0; 21.2385 + } else { 21.2386 + unsigned int factor; 21.2387 + 21.2388 + factor = skb->len + (mss_now - 1); 21.2389 + factor /= mss_now; 21.2390 +- skb_shinfo(skb)->tso_segs = factor; 21.2391 +- skb_shinfo(skb)->tso_size = mss_now; 21.2392 ++ skb_shinfo(skb)->gso_segs = factor; 21.2393 ++ skb_shinfo(skb)->gso_size = mss_now; 21.2394 ++ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; 21.2395 + } 21.2396 + } 21.2397 + 21.2398 +@@ -850,7 +852,7 @@ static int tcp_init_tso_segs(struct sock 21.2399 + 21.2400 + if (!tso_segs || 21.2401 + (tso_segs > 1 && 21.2402 +- skb_shinfo(skb)->tso_size != mss_now)) { 21.2403 ++ tcp_skb_mss(skb) != mss_now)) { 21.2404 + tcp_set_skb_tso_segs(sk, skb, mss_now); 21.2405 + tso_segs = tcp_skb_pcount(skb); 21.2406 + } 21.2407 +@@ -1510,8 +1512,9 @@ int tcp_retransmit_skb(struct sock *sk, 21.2408 + tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) { 21.2409 + if (!pskb_trim(skb, 0)) { 21.2410 + TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1; 21.2411 +- skb_shinfo(skb)->tso_segs = 1; 21.2412 +- skb_shinfo(skb)->tso_size = 0; 21.2413 ++ skb_shinfo(skb)->gso_segs = 1; 21.2414 ++ skb_shinfo(skb)->gso_size = 0; 21.2415 ++ skb_shinfo(skb)->gso_type = 0; 21.2416 + skb->ip_summed = CHECKSUM_NONE; 21.2417 + skb->csum = 0; 21.2418 + } 21.2419 +@@ -1716,8 +1719,9 @@ void tcp_send_fin(struct sock *sk) 21.2420 + skb->csum = 0; 21.2421 + TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN); 21.2422 + TCP_SKB_CB(skb)->sacked = 0; 21.2423 +- skb_shinfo(skb)->tso_segs = 1; 21.2424 +- skb_shinfo(skb)->tso_size = 0; 21.2425 ++ skb_shinfo(skb)->gso_segs = 1; 21.2426 ++ skb_shinfo(skb)->gso_size = 0; 21.2427 ++ skb_shinfo(skb)->gso_type = 0; 21.2428 + 21.2429 + /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ 21.2430 + TCP_SKB_CB(skb)->seq = tp->write_seq; 21.2431 +@@ -1749,8 +1753,9 @@ void tcp_send_active_reset(struct sock * 21.2432 + skb->csum = 0; 21.2433 + TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST); 21.2434 + TCP_SKB_CB(skb)->sacked = 0; 21.2435 +- skb_shinfo(skb)->tso_segs = 1; 21.2436 +- skb_shinfo(skb)->tso_size = 0; 21.2437 ++ skb_shinfo(skb)->gso_segs = 1; 21.2438 ++ skb_shinfo(skb)->gso_size = 0; 21.2439 ++ skb_shinfo(skb)->gso_type = 0; 21.2440 + 21.2441 + /* Send it off. */ 21.2442 + TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp); 21.2443 +@@ -1833,8 +1838,9 @@ struct sk_buff * tcp_make_synack(struct 21.2444 + TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn; 21.2445 + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; 21.2446 + TCP_SKB_CB(skb)->sacked = 0; 21.2447 +- skb_shinfo(skb)->tso_segs = 1; 21.2448 +- skb_shinfo(skb)->tso_size = 0; 21.2449 ++ skb_shinfo(skb)->gso_segs = 1; 21.2450 ++ skb_shinfo(skb)->gso_size = 0; 21.2451 ++ skb_shinfo(skb)->gso_type = 0; 21.2452 + th->seq = htonl(TCP_SKB_CB(skb)->seq); 21.2453 + th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); 21.2454 + if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ 21.2455 +@@ -1937,8 +1943,9 @@ int tcp_connect(struct sock *sk) 21.2456 + TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN; 21.2457 + TCP_ECN_send_syn(sk, tp, buff); 21.2458 + TCP_SKB_CB(buff)->sacked = 0; 21.2459 +- skb_shinfo(buff)->tso_segs = 1; 21.2460 +- skb_shinfo(buff)->tso_size = 0; 21.2461 ++ skb_shinfo(buff)->gso_segs = 1; 21.2462 ++ skb_shinfo(buff)->gso_size = 0; 21.2463 ++ skb_shinfo(buff)->gso_type = 0; 21.2464 + buff->csum = 0; 21.2465 + TCP_SKB_CB(buff)->seq = tp->write_seq++; 21.2466 + TCP_SKB_CB(buff)->end_seq = tp->write_seq; 21.2467 +@@ -2042,8 +2049,9 @@ void tcp_send_ack(struct sock *sk) 21.2468 + buff->csum = 0; 21.2469 + TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK; 21.2470 + TCP_SKB_CB(buff)->sacked = 0; 21.2471 +- skb_shinfo(buff)->tso_segs = 1; 21.2472 +- skb_shinfo(buff)->tso_size = 0; 21.2473 ++ skb_shinfo(buff)->gso_segs = 1; 21.2474 ++ skb_shinfo(buff)->gso_size = 0; 21.2475 ++ skb_shinfo(buff)->gso_type = 0; 21.2476 + 21.2477 + /* Send it off, this clears delayed acks for us. */ 21.2478 + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp); 21.2479 +@@ -2078,8 +2086,9 @@ static int tcp_xmit_probe_skb(struct soc 21.2480 + skb->csum = 0; 21.2481 + TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; 21.2482 + TCP_SKB_CB(skb)->sacked = urgent; 21.2483 +- skb_shinfo(skb)->tso_segs = 1; 21.2484 +- skb_shinfo(skb)->tso_size = 0; 21.2485 ++ skb_shinfo(skb)->gso_segs = 1; 21.2486 ++ skb_shinfo(skb)->gso_size = 0; 21.2487 ++ skb_shinfo(skb)->gso_type = 0; 21.2488 + 21.2489 + /* Use a previous sequence. This should cause the other 21.2490 + * end to send an ack. Don't queue or clone SKB, just 21.2491 +diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c 21.2492 +index 32ad229..737c1db 100644 21.2493 +--- a/net/ipv4/xfrm4_output.c 21.2494 ++++ b/net/ipv4/xfrm4_output.c 21.2495 +@@ -9,6 +9,8 @@ 21.2496 + */ 21.2497 + 21.2498 + #include <linux/compiler.h> 21.2499 ++#include <linux/if_ether.h> 21.2500 ++#include <linux/kernel.h> 21.2501 + #include <linux/skbuff.h> 21.2502 + #include <linux/spinlock.h> 21.2503 + #include <linux/netfilter_ipv4.h> 21.2504 +@@ -152,16 +154,10 @@ error_nolock: 21.2505 + goto out_exit; 21.2506 + } 21.2507 + 21.2508 +-static int xfrm4_output_finish(struct sk_buff *skb) 21.2509 ++static int xfrm4_output_finish2(struct sk_buff *skb) 21.2510 + { 21.2511 + int err; 21.2512 + 21.2513 +-#ifdef CONFIG_NETFILTER 21.2514 +- if (!skb->dst->xfrm) { 21.2515 +- IPCB(skb)->flags |= IPSKB_REROUTED; 21.2516 +- return dst_output(skb); 21.2517 +- } 21.2518 +-#endif 21.2519 + while (likely((err = xfrm4_output_one(skb)) == 0)) { 21.2520 + nf_reset(skb); 21.2521 + 21.2522 +@@ -174,7 +170,7 @@ #endif 21.2523 + return dst_output(skb); 21.2524 + 21.2525 + err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL, 21.2526 +- skb->dst->dev, xfrm4_output_finish); 21.2527 ++ skb->dst->dev, xfrm4_output_finish2); 21.2528 + if (unlikely(err != 1)) 21.2529 + break; 21.2530 + } 21.2531 +@@ -182,6 +178,48 @@ #endif 21.2532 + return err; 21.2533 + } 21.2534 + 21.2535 ++static int xfrm4_output_finish(struct sk_buff *skb) 21.2536 ++{ 21.2537 ++ struct sk_buff *segs; 21.2538 ++ 21.2539 ++#ifdef CONFIG_NETFILTER 21.2540 ++ if (!skb->dst->xfrm) { 21.2541 ++ IPCB(skb)->flags |= IPSKB_REROUTED; 21.2542 ++ return dst_output(skb); 21.2543 ++ } 21.2544 ++#endif 21.2545 ++ 21.2546 ++ if (!skb_shinfo(skb)->gso_size) 21.2547 ++ return xfrm4_output_finish2(skb); 21.2548 ++ 21.2549 ++ skb->protocol = htons(ETH_P_IP); 21.2550 ++ segs = skb_gso_segment(skb, 0); 21.2551 ++ kfree_skb(skb); 21.2552 ++ if (unlikely(IS_ERR(segs))) 21.2553 ++ return PTR_ERR(segs); 21.2554 ++ 21.2555 ++ do { 21.2556 ++ struct sk_buff *nskb = segs->next; 21.2557 ++ int err; 21.2558 ++ 21.2559 ++ segs->next = NULL; 21.2560 ++ err = xfrm4_output_finish2(segs); 21.2561 ++ 21.2562 ++ if (unlikely(err)) { 21.2563 ++ while ((segs = nskb)) { 21.2564 ++ nskb = segs->next; 21.2565 ++ segs->next = NULL; 21.2566 ++ kfree_skb(segs); 21.2567 ++ } 21.2568 ++ return err; 21.2569 ++ } 21.2570 ++ 21.2571 ++ segs = nskb; 21.2572 ++ } while (segs); 21.2573 ++ 21.2574 ++ return 0; 21.2575 ++} 21.2576 ++ 21.2577 + int xfrm4_output(struct sk_buff *skb) 21.2578 + { 21.2579 + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, 21.2580 +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c 21.2581 +index 5bf70b1..cf5d17e 100644 21.2582 +--- a/net/ipv6/ip6_output.c 21.2583 ++++ b/net/ipv6/ip6_output.c 21.2584 +@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *s 21.2585 + 21.2586 + int ip6_output(struct sk_buff *skb) 21.2587 + { 21.2588 +- if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) || 21.2589 ++ if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) || 21.2590 + dst_allfrag(skb->dst)) 21.2591 + return ip6_fragment(skb, ip6_output2); 21.2592 + else 21.2593 +@@ -829,8 +829,9 @@ static inline int ip6_ufo_append_data(st 21.2594 + struct frag_hdr fhdr; 21.2595 + 21.2596 + /* specify the length of each IP datagram fragment*/ 21.2597 +- skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - 21.2598 +- sizeof(struct frag_hdr); 21.2599 ++ skb_shinfo(skb)->gso_size = mtu - fragheaderlen - 21.2600 ++ sizeof(struct frag_hdr); 21.2601 ++ skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; 21.2602 + ipv6_select_ident(skb, &fhdr); 21.2603 + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; 21.2604 + __skb_queue_tail(&sk->sk_write_queue, skb); 21.2605 +diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c 21.2606 +index d511a88..ef56d5d 100644 21.2607 +--- a/net/ipv6/ipcomp6.c 21.2608 ++++ b/net/ipv6/ipcomp6.c 21.2609 +@@ -64,7 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list); 21.2610 + 21.2611 + static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 21.2612 + { 21.2613 +- int err = 0; 21.2614 ++ int err = -ENOMEM; 21.2615 + u8 nexthdr = 0; 21.2616 + int hdr_len = skb->h.raw - skb->nh.raw; 21.2617 + unsigned char *tmp_hdr = NULL; 21.2618 +@@ -75,11 +75,8 @@ static int ipcomp6_input(struct xfrm_sta 21.2619 + struct crypto_tfm *tfm; 21.2620 + int cpu; 21.2621 + 21.2622 +- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && 21.2623 +- skb_linearize(skb, GFP_ATOMIC) != 0) { 21.2624 +- err = -ENOMEM; 21.2625 ++ if (skb_linearize_cow(skb)) 21.2626 + goto out; 21.2627 +- } 21.2628 + 21.2629 + skb->ip_summed = CHECKSUM_NONE; 21.2630 + 21.2631 +@@ -158,10 +155,8 @@ static int ipcomp6_output(struct xfrm_st 21.2632 + goto out_ok; 21.2633 + } 21.2634 + 21.2635 +- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && 21.2636 +- skb_linearize(skb, GFP_ATOMIC) != 0) { 21.2637 ++ if (skb_linearize_cow(skb)) 21.2638 + goto out_ok; 21.2639 +- } 21.2640 + 21.2641 + /* compression */ 21.2642 + plen = skb->len - hdr_len; 21.2643 +diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c 21.2644 +index 8024217..39bdeec 100644 21.2645 +--- a/net/ipv6/xfrm6_output.c 21.2646 ++++ b/net/ipv6/xfrm6_output.c 21.2647 +@@ -151,7 +151,7 @@ error_nolock: 21.2648 + goto out_exit; 21.2649 + } 21.2650 + 21.2651 +-static int xfrm6_output_finish(struct sk_buff *skb) 21.2652 ++static int xfrm6_output_finish2(struct sk_buff *skb) 21.2653 + { 21.2654 + int err; 21.2655 + 21.2656 +@@ -167,7 +167,7 @@ static int xfrm6_output_finish(struct sk 21.2657 + return dst_output(skb); 21.2658 + 21.2659 + err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL, 21.2660 +- skb->dst->dev, xfrm6_output_finish); 21.2661 ++ skb->dst->dev, xfrm6_output_finish2); 21.2662 + if (unlikely(err != 1)) 21.2663 + break; 21.2664 + } 21.2665 +@@ -175,6 +175,41 @@ static int xfrm6_output_finish(struct sk 21.2666 + return err; 21.2667 + } 21.2668 + 21.2669 ++static int xfrm6_output_finish(struct sk_buff *skb) 21.2670 ++{ 21.2671 ++ struct sk_buff *segs; 21.2672 ++ 21.2673 ++ if (!skb_shinfo(skb)->gso_size) 21.2674 ++ return xfrm6_output_finish2(skb); 21.2675 ++ 21.2676 ++ skb->protocol = htons(ETH_P_IP); 21.2677 ++ segs = skb_gso_segment(skb, 0); 21.2678 ++ kfree_skb(skb); 21.2679 ++ if (unlikely(IS_ERR(segs))) 21.2680 ++ return PTR_ERR(segs); 21.2681 ++ 21.2682 ++ do { 21.2683 ++ struct sk_buff *nskb = segs->next; 21.2684 ++ int err; 21.2685 ++ 21.2686 ++ segs->next = NULL; 21.2687 ++ err = xfrm6_output_finish2(segs); 21.2688 ++ 21.2689 ++ if (unlikely(err)) { 21.2690 ++ while ((segs = nskb)) { 21.2691 ++ nskb = segs->next; 21.2692 ++ segs->next = NULL; 21.2693 ++ kfree_skb(segs); 21.2694 ++ } 21.2695 ++ return err; 21.2696 ++ } 21.2697 ++ 21.2698 ++ segs = nskb; 21.2699 ++ } while (segs); 21.2700 ++ 21.2701 ++ return 0; 21.2702 ++} 21.2703 ++ 21.2704 + int xfrm6_output(struct sk_buff *skb) 21.2705 + { 21.2706 + return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev, 21.2707 +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c 21.2708 +index 99ceb91..28c9efd 100644 21.2709 +--- a/net/sched/sch_generic.c 21.2710 ++++ b/net/sched/sch_generic.c 21.2711 +@@ -72,9 +72,9 @@ void qdisc_unlock_tree(struct net_device 21.2712 + dev->queue_lock serializes queue accesses for this device 21.2713 + AND dev->qdisc pointer itself. 21.2714 + 21.2715 +- dev->xmit_lock serializes accesses to device driver. 21.2716 ++ netif_tx_lock serializes accesses to device driver. 21.2717 + 21.2718 +- dev->queue_lock and dev->xmit_lock are mutually exclusive, 21.2719 ++ dev->queue_lock and netif_tx_lock are mutually exclusive, 21.2720 + if one is grabbed, another must be free. 21.2721 + */ 21.2722 + 21.2723 +@@ -90,14 +90,17 @@ void qdisc_unlock_tree(struct net_device 21.2724 + NOTE: Called under dev->queue_lock with locally disabled BH. 21.2725 + */ 21.2726 + 21.2727 +-int qdisc_restart(struct net_device *dev) 21.2728 ++static inline int qdisc_restart(struct net_device *dev) 21.2729 + { 21.2730 + struct Qdisc *q = dev->qdisc; 21.2731 + struct sk_buff *skb; 21.2732 + 21.2733 + /* Dequeue packet */ 21.2734 +- if ((skb = q->dequeue(q)) != NULL) { 21.2735 ++ if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) { 21.2736 + unsigned nolock = (dev->features & NETIF_F_LLTX); 21.2737 ++ 21.2738 ++ dev->gso_skb = NULL; 21.2739 ++ 21.2740 + /* 21.2741 + * When the driver has LLTX set it does its own locking 21.2742 + * in start_xmit. No need to add additional overhead by 21.2743 +@@ -108,7 +111,7 @@ int qdisc_restart(struct net_device *dev 21.2744 + * will be requeued. 21.2745 + */ 21.2746 + if (!nolock) { 21.2747 +- if (!spin_trylock(&dev->xmit_lock)) { 21.2748 ++ if (!netif_tx_trylock(dev)) { 21.2749 + collision: 21.2750 + /* So, someone grabbed the driver. */ 21.2751 + 21.2752 +@@ -126,8 +129,6 @@ int qdisc_restart(struct net_device *dev 21.2753 + __get_cpu_var(netdev_rx_stat).cpu_collision++; 21.2754 + goto requeue; 21.2755 + } 21.2756 +- /* Remember that the driver is grabbed by us. */ 21.2757 +- dev->xmit_lock_owner = smp_processor_id(); 21.2758 + } 21.2759 + 21.2760 + { 21.2761 +@@ -136,14 +137,11 @@ int qdisc_restart(struct net_device *dev 21.2762 + 21.2763 + if (!netif_queue_stopped(dev)) { 21.2764 + int ret; 21.2765 +- if (netdev_nit) 21.2766 +- dev_queue_xmit_nit(skb, dev); 21.2767 + 21.2768 +- ret = dev->hard_start_xmit(skb, dev); 21.2769 ++ ret = dev_hard_start_xmit(skb, dev); 21.2770 + if (ret == NETDEV_TX_OK) { 21.2771 + if (!nolock) { 21.2772 +- dev->xmit_lock_owner = -1; 21.2773 +- spin_unlock(&dev->xmit_lock); 21.2774 ++ netif_tx_unlock(dev); 21.2775 + } 21.2776 + spin_lock(&dev->queue_lock); 21.2777 + return -1; 21.2778 +@@ -157,8 +155,7 @@ int qdisc_restart(struct net_device *dev 21.2779 + /* NETDEV_TX_BUSY - we need to requeue */ 21.2780 + /* Release the driver */ 21.2781 + if (!nolock) { 21.2782 +- dev->xmit_lock_owner = -1; 21.2783 +- spin_unlock(&dev->xmit_lock); 21.2784 ++ netif_tx_unlock(dev); 21.2785 + } 21.2786 + spin_lock(&dev->queue_lock); 21.2787 + q = dev->qdisc; 21.2788 +@@ -175,7 +172,10 @@ int qdisc_restart(struct net_device *dev 21.2789 + */ 21.2790 + 21.2791 + requeue: 21.2792 +- q->ops->requeue(skb, q); 21.2793 ++ if (skb->next) 21.2794 ++ dev->gso_skb = skb; 21.2795 ++ else 21.2796 ++ q->ops->requeue(skb, q); 21.2797 + netif_schedule(dev); 21.2798 + return 1; 21.2799 + } 21.2800 +@@ -183,11 +183,23 @@ requeue: 21.2801 + return q->q.qlen; 21.2802 + } 21.2803 + 21.2804 ++void __qdisc_run(struct net_device *dev) 21.2805 ++{ 21.2806 ++ if (unlikely(dev->qdisc == &noop_qdisc)) 21.2807 ++ goto out; 21.2808 ++ 21.2809 ++ while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev)) 21.2810 ++ /* NOTHING */; 21.2811 ++ 21.2812 ++out: 21.2813 ++ clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); 21.2814 ++} 21.2815 ++ 21.2816 + static void dev_watchdog(unsigned long arg) 21.2817 + { 21.2818 + struct net_device *dev = (struct net_device *)arg; 21.2819 + 21.2820 +- spin_lock(&dev->xmit_lock); 21.2821 ++ netif_tx_lock(dev); 21.2822 + if (dev->qdisc != &noop_qdisc) { 21.2823 + if (netif_device_present(dev) && 21.2824 + netif_running(dev) && 21.2825 +@@ -201,7 +213,7 @@ static void dev_watchdog(unsigned long a 21.2826 + dev_hold(dev); 21.2827 + } 21.2828 + } 21.2829 +- spin_unlock(&dev->xmit_lock); 21.2830 ++ netif_tx_unlock(dev); 21.2831 + 21.2832 + dev_put(dev); 21.2833 + } 21.2834 +@@ -225,17 +237,17 @@ void __netdev_watchdog_up(struct net_dev 21.2835 + 21.2836 + static void dev_watchdog_up(struct net_device *dev) 21.2837 + { 21.2838 +- spin_lock_bh(&dev->xmit_lock); 21.2839 ++ netif_tx_lock_bh(dev); 21.2840 + __netdev_watchdog_up(dev); 21.2841 +- spin_unlock_bh(&dev->xmit_lock); 21.2842 ++ netif_tx_unlock_bh(dev); 21.2843 + } 21.2844 + 21.2845 + static void dev_watchdog_down(struct net_device *dev) 21.2846 + { 21.2847 +- spin_lock_bh(&dev->xmit_lock); 21.2848 ++ netif_tx_lock_bh(dev); 21.2849 + if (del_timer(&dev->watchdog_timer)) 21.2850 + __dev_put(dev); 21.2851 +- spin_unlock_bh(&dev->xmit_lock); 21.2852 ++ netif_tx_unlock_bh(dev); 21.2853 + } 21.2854 + 21.2855 + void netif_carrier_on(struct net_device *dev) 21.2856 +@@ -577,10 +589,17 @@ void dev_deactivate(struct net_device *d 21.2857 + 21.2858 + dev_watchdog_down(dev); 21.2859 + 21.2860 +- while (test_bit(__LINK_STATE_SCHED, &dev->state)) 21.2861 ++ /* Wait for outstanding dev_queue_xmit calls. */ 21.2862 ++ synchronize_rcu(); 21.2863 ++ 21.2864 ++ /* Wait for outstanding qdisc_run calls. */ 21.2865 ++ while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) 21.2866 + yield(); 21.2867 + 21.2868 +- spin_unlock_wait(&dev->xmit_lock); 21.2869 ++ if (dev->gso_skb) { 21.2870 ++ kfree_skb(dev->gso_skb); 21.2871 ++ dev->gso_skb = NULL; 21.2872 ++ } 21.2873 + } 21.2874 + 21.2875 + void dev_init_scheduler(struct net_device *dev) 21.2876 +@@ -622,6 +641,5 @@ EXPORT_SYMBOL(qdisc_create_dflt); 21.2877 + EXPORT_SYMBOL(qdisc_alloc); 21.2878 + EXPORT_SYMBOL(qdisc_destroy); 21.2879 + EXPORT_SYMBOL(qdisc_reset); 21.2880 +-EXPORT_SYMBOL(qdisc_restart); 21.2881 + EXPORT_SYMBOL(qdisc_lock_tree); 21.2882 + EXPORT_SYMBOL(qdisc_unlock_tree); 21.2883 +diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c 21.2884 +index 79b8ef3..4c16ad5 100644 21.2885 +--- a/net/sched/sch_teql.c 21.2886 ++++ b/net/sched/sch_teql.c 21.2887 +@@ -302,20 +302,17 @@ restart: 21.2888 + 21.2889 + switch (teql_resolve(skb, skb_res, slave)) { 21.2890 + case 0: 21.2891 +- if (spin_trylock(&slave->xmit_lock)) { 21.2892 +- slave->xmit_lock_owner = smp_processor_id(); 21.2893 ++ if (netif_tx_trylock(slave)) { 21.2894 + if (!netif_queue_stopped(slave) && 21.2895 + slave->hard_start_xmit(skb, slave) == 0) { 21.2896 +- slave->xmit_lock_owner = -1; 21.2897 +- spin_unlock(&slave->xmit_lock); 21.2898 ++ netif_tx_unlock(slave); 21.2899 + master->slaves = NEXT_SLAVE(q); 21.2900 + netif_wake_queue(dev); 21.2901 + master->stats.tx_packets++; 21.2902 + master->stats.tx_bytes += len; 21.2903 + return 0; 21.2904 + } 21.2905 +- slave->xmit_lock_owner = -1; 21.2906 +- spin_unlock(&slave->xmit_lock); 21.2907 ++ netif_tx_unlock(slave); 21.2908 + } 21.2909 + if (netif_queue_stopped(dev)) 21.2910 + busy = 1;
22.1 --- a/patches/linux-2.6.16.13/xenoprof-generic.patch Wed Jun 28 07:51:52 2006 -0600 22.2 +++ b/patches/linux-2.6.16.13/xenoprof-generic.patch Wed Jun 28 07:52:21 2006 -0600 22.3 @@ -1,6 +1,6 @@ 22.4 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c 22.5 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02 22:38:44.000000000 +0100 22.6 -+++ ./drivers/oprofile/buffer_sync.c 2006-05-04 17:41:51.000000000 +0100 22.7 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c 22.8 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-03 05:38:44.000000000 +0800 22.9 ++++ ./drivers/oprofile/buffer_sync.c 2006-06-27 12:14:53.000000000 +0800 22.10 @@ -6,6 +6,10 @@ 22.11 * 22.12 * @author John Levon <levon@movementarian.org> 22.13 @@ -12,7 +12,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.14 * This is the core of the buffer management. Each 22.15 * CPU buffer is processed and entered into the 22.16 * global event buffer. Such processing is necessary 22.17 -@@ -275,15 +279,24 @@ static void add_cpu_switch(int i) 22.18 +@@ -275,15 +279,30 @@ static void add_cpu_switch(int i) 22.19 last_cookie = INVALID_COOKIE; 22.20 } 22.21 22.22 @@ -33,7 +33,13 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.23 + break; 22.24 + case CPU_MODE_XEN: 22.25 + add_event_entry(XEN_ENTER_SWITCH_CODE); 22.26 -+ break; 22.27 ++ break; 22.28 ++ case CPU_MODE_PASSIVE_START: 22.29 ++ add_event_entry(PASSIVE_START_CODE); 22.30 ++ break; 22.31 ++ case CPU_MODE_PASSIVE_STOP: 22.32 ++ add_event_entry(PASSIVE_STOP_CODE); 22.33 ++ break; 22.34 + default: 22.35 + break; 22.36 + } 22.37 @@ -43,7 +49,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.38 static void 22.39 add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) 22.40 { 22.41 -@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc 22.42 +@@ -348,9 +367,9 @@ static int add_us_sample(struct mm_struc 22.43 * for later lookup from userspace. 22.44 */ 22.45 static int 22.46 @@ -55,7 +61,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.47 add_sample_entry(s->eip, s->event); 22.48 return 1; 22.49 } else if (mm) { 22.50 -@@ -496,7 +509,7 @@ void sync_buffer(int cpu) 22.51 +@@ -496,10 +515,11 @@ void sync_buffer(int cpu) 22.52 struct mm_struct *mm = NULL; 22.53 struct task_struct * new; 22.54 unsigned long cookie = 0; 22.55 @@ -64,34 +70,62 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.56 unsigned int i; 22.57 sync_buffer_state state = sb_buffer_start; 22.58 unsigned long available; 22.59 -@@ -513,12 +526,12 @@ void sync_buffer(int cpu) 22.60 ++ int domain_switch = NO_DOMAIN_SWITCH; 22.61 + 22.62 + down(&buffer_sem); 22.63 + 22.64 +@@ -513,12 +533,19 @@ void sync_buffer(int cpu) 22.65 struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; 22.66 22.67 if (is_code(s->eip)) { 22.68 - if (s->event <= CPU_IS_KERNEL) { 22.69 -+ if (s->event <= CPU_MODE_XEN) { 22.70 ++ if (s->event < CPU_TRACE_BEGIN) { 22.71 /* kernel/userspace switch */ 22.72 - in_kernel = s->event; 22.73 + cpu_mode = s->event; 22.74 if (state == sb_buffer_start) 22.75 state = sb_sample_start; 22.76 - add_kernel_ctx_switch(s->event); 22.77 -+ add_cpu_mode_switch(s->event); 22.78 ++ 22.79 ++ if (s->event == CPU_MODE_PASSIVE_START) 22.80 ++ domain_switch = DOMAIN_SWITCH_START_EVENT1; 22.81 ++ else if (s->event == CPU_MODE_PASSIVE_STOP) 22.82 ++ domain_switch = DOMAIN_SWITCH_STOP_EVENT1; 22.83 ++ 22.84 ++ if (domain_switch != DOMAIN_SWITCH_START_EVENT2) 22.85 ++ add_cpu_mode_switch(s->event); 22.86 } else if (s->event == CPU_TRACE_BEGIN) { 22.87 state = sb_bt_start; 22.88 add_trace_begin(); 22.89 -@@ -536,7 +549,7 @@ void sync_buffer(int cpu) 22.90 +@@ -535,11 +562,20 @@ void sync_buffer(int cpu) 22.91 + add_user_ctx_switch(new, cookie); 22.92 } 22.93 } else { 22.94 - if (state >= sb_bt_start && 22.95 +- if (state >= sb_bt_start && 22.96 - !add_sample(mm, s, in_kernel)) { 22.97 -+ !add_sample(mm, s, cpu_mode)) { 22.98 - if (state == sb_bt_start) { 22.99 - state = sb_bt_ignore; 22.100 - atomic_inc(&oprofile_stats.bt_lost_no_mapping); 22.101 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c 22.102 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-02 22:38:44.000000000 +0100 22.103 -+++ ./drivers/oprofile/cpu_buffer.c 2006-05-04 17:41:51.000000000 +0100 22.104 +- if (state == sb_bt_start) { 22.105 +- state = sb_bt_ignore; 22.106 +- atomic_inc(&oprofile_stats.bt_lost_no_mapping); 22.107 ++ if (domain_switch == DOMAIN_SWITCH_START_EVENT1) { 22.108 ++ add_event_entry(s->event); 22.109 ++ domain_switch = DOMAIN_SWITCH_START_EVENT2; 22.110 ++ } else if (domain_switch == DOMAIN_SWITCH_START_EVENT1) { 22.111 ++ add_sample_entry(s->eip, s->event); 22.112 ++ } else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) { 22.113 ++ domain_switch = NO_DOMAIN_SWITCH; 22.114 ++ } else { 22.115 ++ if (state >= sb_bt_start && 22.116 ++ !add_sample(mm, s, cpu_mode)) { 22.117 ++ if (state == sb_bt_start) { 22.118 ++ state = sb_bt_ignore; 22.119 ++ atomic_inc(&oprofile_stats.bt_lost_no_mapping); 22.120 ++ } 22.121 + } 22.122 + } 22.123 + } 22.124 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c 22.125 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-03 05:38:44.000000000 +0800 22.126 ++++ ./drivers/oprofile/cpu_buffer.c 2006-06-19 22:43:53.000000000 +0800 22.127 @@ -6,6 +6,10 @@ 22.128 * 22.129 * @author John Levon <levon@movementarian.org> 22.130 @@ -139,13 +173,12 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.131 { 22.132 struct task_struct * task; 22.133 22.134 -@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp 22.135 +@@ -181,16 +185,14 @@ static int log_sample(struct oprofile_cp 22.136 return 0; 22.137 } 22.138 22.139 - is_kernel = !!is_kernel; 22.140 -+ WARN_ON(cpu_mode > CPU_MODE_XEN); 22.141 - 22.142 +- 22.143 task = current; 22.144 22.145 /* notice a switch from user->kernel or vice versa */ 22.146 @@ -161,9 +194,9 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.147 /* notice a task switch */ 22.148 if (cpu_buf->last_task != task) { 22.149 cpu_buf->last_task = task; 22.150 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h 22.151 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-02 22:38:44.000000000 +0100 22.152 -+++ ./drivers/oprofile/cpu_buffer.h 2006-05-04 17:41:51.000000000 +0100 22.153 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h 22.154 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-03 05:38:44.000000000 +0800 22.155 ++++ ./drivers/oprofile/cpu_buffer.h 2006-06-27 10:38:08.000000000 +0800 22.156 @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer { 22.157 volatile unsigned long tail_pos; 22.158 unsigned long buffer_size; 22.159 @@ -173,22 +206,26 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.160 int tracing; 22.161 struct op_sample * buffer; 22.162 unsigned long sample_received; 22.163 -@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu 22.164 +@@ -51,7 +51,13 @@ extern struct oprofile_cpu_buffer cpu_bu 22.165 void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); 22.166 22.167 /* transient events for the CPU buffer -> event buffer */ 22.168 -#define CPU_IS_KERNEL 1 22.169 -#define CPU_TRACE_BEGIN 2 22.170 -+#define CPU_MODE_USER 0 22.171 -+#define CPU_MODE_KERNEL 1 22.172 -+#define CPU_MODE_XEN 2 22.173 -+#define CPU_TRACE_BEGIN 3 22.174 ++#define CPU_MODE_USER 0 22.175 ++#define CPU_MODE_KERNEL 1 22.176 ++#define CPU_MODE_XEN 2 22.177 ++#define CPU_MODE_PASSIVE_START 3 22.178 ++#define CPU_MODE_PASSIVE_STOP 4 22.179 ++#define CPU_TRACE_BEGIN 5 22.180 ++ 22.181 ++#define IGNORED_PC 0 22.182 22.183 #endif /* OPROFILE_CPU_BUFFER_H */ 22.184 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h 22.185 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 2006-05-02 22:38:44.000000000 +0100 22.186 -+++ ./drivers/oprofile/event_buffer.h 2006-05-04 17:41:51.000000000 +0100 22.187 -@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void); 22.188 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h 22.189 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 2006-05-03 05:38:44.000000000 +0800 22.190 ++++ ./drivers/oprofile/event_buffer.h 2006-06-19 22:43:53.000000000 +0800 22.191 +@@ -29,11 +29,14 @@ void wake_up_buffer_waiter(void); 22.192 #define CPU_SWITCH_CODE 2 22.193 #define COOKIE_SWITCH_CODE 3 22.194 #define KERNEL_ENTER_SWITCH_CODE 4 22.195 @@ -199,12 +236,14 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.196 #define TRACE_BEGIN_CODE 8 22.197 #define TRACE_END_CODE 9 22.198 +#define XEN_ENTER_SWITCH_CODE 10 22.199 ++#define PASSIVE_START_CODE 11 22.200 ++#define PASSIVE_STOP_CODE 12 22.201 22.202 #define INVALID_COOKIE ~0UL 22.203 #define NO_COOKIE 0UL 22.204 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c 22.205 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-02 22:38:44.000000000 +0100 22.206 -+++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100 22.207 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c 22.208 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-03 05:38:44.000000000 +0800 22.209 ++++ ./drivers/oprofile/oprof.c 2006-06-19 23:45:17.000000000 +0800 22.210 @@ -5,6 +5,10 @@ 22.211 * @remark Read the file COPYING 22.212 * 22.213 @@ -225,7 +264,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.214 struct oprofile_operations oprofile_ops; 22.215 22.216 unsigned long oprofile_started; 22.217 -@@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem); 22.218 +@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem); 22.219 */ 22.220 static int timer = 0; 22.221 22.222 @@ -242,23 +281,37 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.223 + return err; 22.224 +} 22.225 + 22.226 ++int oprofile_set_passive(int passive_domains[], unsigned int pdomains) 22.227 ++{ 22.228 ++ int err; 22.229 ++ 22.230 ++ if (!oprofile_ops.set_passive) 22.231 ++ return -EINVAL; 22.232 ++ 22.233 ++ down(&start_sem); 22.234 ++ err = oprofile_ops.set_passive(passive_domains, pdomains); 22.235 ++ up(&start_sem); 22.236 ++ return err; 22.237 ++} 22.238 ++ 22.239 int oprofile_setup(void) 22.240 { 22.241 int err; 22.242 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h 22.243 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-02 22:38:44.000000000 +0100 22.244 -+++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100 22.245 -@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_ 22.246 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h 22.247 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-03 05:38:44.000000000 +0800 22.248 ++++ ./drivers/oprofile/oprof.h 2006-06-19 23:42:36.000000000 +0800 22.249 +@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_ 22.250 void oprofile_timer_init(struct oprofile_operations * ops); 22.251 22.252 int oprofile_set_backtrace(unsigned long depth); 22.253 + 22.254 +int oprofile_set_active(int active_domains[], unsigned int adomains); 22.255 ++int oprofile_set_passive(int passive_domains[], unsigned int pdomains); 22.256 22.257 #endif /* OPROF_H */ 22.258 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c 22.259 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 2006-05-02 22:38:44.000000000 +0100 22.260 -+++ ./drivers/oprofile/oprofile_files.c 2006-05-04 17:41:51.000000000 +0100 22.261 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c 22.262 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 2006-05-03 05:38:44.000000000 +0800 22.263 ++++ ./drivers/oprofile/oprofile_files.c 2006-06-19 23:29:07.000000000 +0800 22.264 @@ -5,15 +5,21 @@ 22.265 * @remark Read the file COPYING 22.266 * 22.267 @@ -282,7 +335,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.268 unsigned long fs_buffer_size = 131072; 22.269 unsigned long fs_cpu_buffer_size = 8192; 22.270 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ 22.271 -@@ -117,11 +123,108 @@ static ssize_t dump_write(struct file * 22.272 +@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file * 22.273 static struct file_operations dump_fops = { 22.274 .write = dump_write, 22.275 }; 22.276 @@ -384,17 +437,110 @@ diff -pruN ../pristine-linux-2.6.16.13/d 22.277 + .write = adomain_write, 22.278 +}; 22.279 + 22.280 ++static unsigned int pdomains = 0; 22.281 ++static int passive_domains[MAX_OPROF_DOMAINS]; 22.282 ++static DEFINE_MUTEX(pdom_mutex); 22.283 ++ 22.284 ++static ssize_t pdomain_write(struct file * file, char const __user * buf, 22.285 ++ size_t count, loff_t * offset) 22.286 ++{ 22.287 ++ char *tmpbuf; 22.288 ++ char *startp, *endp; 22.289 ++ int i; 22.290 ++ unsigned long val; 22.291 ++ ssize_t retval = count; 22.292 ++ 22.293 ++ if (*offset) 22.294 ++ return -EINVAL; 22.295 ++ if (count > TMPBUFSIZE - 1) 22.296 ++ return -EINVAL; 22.297 ++ 22.298 ++ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) 22.299 ++ return -ENOMEM; 22.300 ++ 22.301 ++ if (copy_from_user(tmpbuf, buf, count)) { 22.302 ++ kfree(tmpbuf); 22.303 ++ return -EFAULT; 22.304 ++ } 22.305 ++ tmpbuf[count] = 0; 22.306 ++ 22.307 ++ mutex_lock(&pdom_mutex); 22.308 ++ 22.309 ++ startp = tmpbuf; 22.310 ++ /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */ 22.311 ++ for (i = 0; i <= MAX_OPROF_DOMAINS; i++) { 22.312 ++ val = simple_strtoul(startp, &endp, 0); 22.313 ++ if (endp == startp) 22.314 ++ break; 22.315 ++ while (ispunct(*endp) || isspace(*endp)) 22.316 ++ endp++; 22.317 ++ passive_domains[i] = val; 22.318 ++ if (passive_domains[i] != val) 22.319 ++ /* Overflow, force error below */ 22.320 ++ i = MAX_OPROF_DOMAINS + 1; 22.321 ++ startp = endp; 22.322 ++ } 22.323 ++ /* Force error on trailing junk */ 22.324 ++ pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i; 22.325 ++ 22.326 ++ kfree(tmpbuf); 22.327 ++ 22.328 ++ if (pdomains > MAX_OPROF_DOMAINS 22.329 ++ || oprofile_set_passive(passive_domains, pdomains)) { 22.330 ++ pdomains = 0; 22.331 ++ retval = -EINVAL; 22.332 ++ } 22.333 ++ 22.334 ++ mutex_unlock(&pdom_mutex); 22.335 ++ return retval; 22.336 ++} 22.337 ++ 22.338 ++static ssize_t pdomain_read(struct file * file, char __user * buf, 22.339 ++ size_t count, loff_t * offset) 22.340 ++{ 22.341 ++ char * tmpbuf; 22.342 ++ size_t len; 22.343 ++ int i; 22.344 ++ ssize_t retval; 22.345 ++ 22.346 ++ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) 22.347 ++ return -ENOMEM; 22.348 ++ 22.349 ++ mutex_lock(&pdom_mutex); 22.350 ++ 22.351 ++ len = 0; 22.352 ++ for (i = 0; i < pdomains; i++) 22.353 ++ len += snprintf(tmpbuf + len, 22.354 ++ len < TMPBUFSIZE ? TMPBUFSIZE - len : 0, 22.355 ++ "%u ", passive_domains[i]); 22.356 ++ WARN_ON(len > TMPBUFSIZE); 22.357 ++ if (len != 0 && len <= TMPBUFSIZE) 22.358 ++ tmpbuf[len-1] = '\n'; 22.359 ++ 22.360 ++ mutex_unlock(&pdom_mutex); 22.361 ++ 22.362 ++ retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len); 22.363 ++ 22.364 ++ kfree(tmpbuf); 22.365 ++ return retval; 22.366 ++} 22.367 ++ 22.368 ++static struct file_operations passive_domain_ops = { 22.369 ++ .read = pdomain_read, 22.370 ++ .write = pdomain_write, 22.371 ++}; 22.372 ++ 22.373 void oprofile_create_files(struct super_block * sb, struct dentry * root) 22.374 { 22.375 oprofilefs_create_file(sb, root, "enable", &enable_fops); 22.376 oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); 22.377 + oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops); 22.378 ++ oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops); 22.379 oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); 22.380 oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); 22.381 oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); 22.382 -diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h ./include/linux/oprofile.h 22.383 ---- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-02 22:38:44.000000000 +0100 22.384 -+++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100 22.385 +--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-03 05:38:44.000000000 +0800 22.386 ++++ ./include/linux/oprofile.h 2006-06-19 23:52:00.000000000 +0800 22.387 @@ -16,6 +16,8 @@ 22.388 #include <linux/types.h> 22.389 #include <linux/spinlock.h> 22.390 @@ -404,12 +550,15 @@ diff -pruN ../pristine-linux-2.6.16.13/i 22.391 22.392 struct super_block; 22.393 struct dentry; 22.394 -@@ -27,6 +29,8 @@ struct oprofile_operations { 22.395 +@@ -27,6 +29,11 @@ struct oprofile_operations { 22.396 /* create any necessary configuration files in the oprofile fs. 22.397 * Optional. */ 22.398 int (*create_files)(struct super_block * sb, struct dentry * root); 22.399 + /* setup active domains with Xen */ 22.400 + int (*set_active)(int *active_domains, unsigned int adomains); 22.401 ++ /* setup passive domains with Xen */ 22.402 ++ int (*set_passive)(int *passive_domains, unsigned int pdomains); 22.403 ++ 22.404 /* Do any necessary interrupt setup. Optional. */ 22.405 int (*setup)(void); 22.406 /* Do any necessary interrupt shutdown. Optional. */
23.1 --- a/tools/Makefile Wed Jun 28 07:51:52 2006 -0600 23.2 +++ b/tools/Makefile Wed Jun 28 07:52:21 2006 -0600 23.3 @@ -45,6 +45,9 @@ clean: check_clean 23.4 done 23.5 $(MAKE) ioemuclean 23.6 23.7 +.PHONY: distclean 23.8 +distclean: clean 23.9 + 23.10 .PHONY: check 23.11 check: 23.12 $(MAKE) -C check
24.1 --- a/tools/examples/Makefile Wed Jun 28 07:51:52 2006 -0600 24.2 +++ b/tools/examples/Makefile Wed Jun 28 07:52:21 2006 -0600 24.3 @@ -32,7 +32,7 @@ XEN_SCRIPTS += external-device-migrate 24.4 XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh 24.5 XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh 24.6 XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh 24.7 -XEN_SCRIPT_DATA += vtpm-migration.sh 24.8 +XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl 24.9 24.10 XEN_HOTPLUG_DIR = /etc/hotplug 24.11 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
25.1 --- a/tools/examples/vtpm Wed Jun 28 07:51:52 2006 -0600 25.2 +++ b/tools/examples/vtpm Wed Jun 28 07:52:21 2006 -0600 25.3 @@ -9,15 +9,9 @@ case "$command" in 25.4 add) 25.5 vtpm_create_instance 25.6 ;; 25.7 - online) 25.8 - vtpm_create_instance 25.9 - ;; 25.10 remove) 25.11 vtpm_remove_instance 25.12 ;; 25.13 - offline) 25.14 - vtpm_remove_instance 25.15 - ;; 25.16 esac 25.17 25.18 if [ $vtpm_fatal_error -eq 0 ]; then
26.1 --- a/tools/examples/vtpm-common.sh Wed Jun 28 07:51:52 2006 -0600 26.2 +++ b/tools/examples/vtpm-common.sh Wed Jun 28 07:52:21 2006 -0600 26.3 @@ -23,7 +23,7 @@ dir=$(dirname "$0") 26.4 VTPMDB="/etc/xen/vtpm.db" 26.5 26.6 #In the vtpm-impl file some commands should be defined: 26.7 -# vtpm_create, vtpm_setup, vtpm_reset, etc. (see below) 26.8 +# vtpm_create, vtpm_setup, vtpm_start, etc. (see below) 26.9 #This should be indicated by setting VTPM_IMPL_DEFINED. 26.10 if [ -r "$dir/vtpm-impl" ]; then 26.11 . "$dir/vtpm-impl" 26.12 @@ -36,7 +36,7 @@ if [ -z "$VTPM_IMPL_DEFINED" ]; then 26.13 function vtpm_setup() { 26.14 true 26.15 } 26.16 - function vtpm_reset() { 26.17 + function vtpm_start() { 26.18 true 26.19 } 26.20 function vtpm_suspend() { 26.21 @@ -256,22 +256,22 @@ function vtpm_create_instance () { 26.22 else 26.23 instance=$(vtpmdb_get_free_instancenum) 26.24 fi 26.25 - if [ "$reason" == "create" ]; then 26.26 - vtpm_create $instance 26.27 - else 26.28 - vtpm_resume $instance $domname 26.29 - fi 26.30 + 26.31 + vtpm_create $instance 26.32 + 26.33 if [ $vtpm_fatal_error -eq 0 ]; then 26.34 vtpmdb_add_instance $domname $instance 26.35 fi 26.36 + else 26.37 + if [ "$reason" == "resume" ]; then 26.38 + vtpm_resume $instance 26.39 + else 26.40 + vtpm_start $instance 26.41 + fi 26.42 fi 26.43 26.44 release_lock vtpmdb 26.45 26.46 - if [ $vtpm_fatal_error -eq 0 -a \ 26.47 - "$reason" == "create" ]; then 26.48 - vtpm_reset $instance 26.49 - fi 26.50 xenstore_write $XENBUS_PATH/instance $instance 26.51 } 26.52 26.53 @@ -283,19 +283,17 @@ function vtpm_remove_instance () { 26.54 local instance reason domname 26.55 domname=$(xenstore_read "$XENBUS_PATH"/domain) 26.56 26.57 - if [ "$doname" != "" ]; then 26.58 + if [ "$domname" != "" ]; then 26.59 claim_lock vtpmdb 26.60 26.61 instance=$(vtpmdb_find_instance $domname) 26.62 26.63 if [ "$instance" != "0" ]; then 26.64 - if [ "$reason" == "suspend" ]; then 26.65 - vtpm_suspend $instance 26.66 - fi 26.67 + vtpm_suspend $instance 26.68 fi 26.69 + 26.70 + release_lock vtpmdb 26.71 fi 26.72 - 26.73 - release_lock vtpmdb 26.74 } 26.75 26.76
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/tools/examples/vtpm-impl Wed Jun 28 07:52:21 2006 -0600 27.3 @@ -0,0 +1,136 @@ 27.4 +#!/bin/bash 27.5 +# =================================================================== 27.6 +# 27.7 +# Copyright (c) 2005, Intel Corp. 27.8 +# All rights reserved. 27.9 +# 27.10 +# Redistribution and use in source and binary forms, with or without 27.11 +# modification, are permitted provided that the following conditions 27.12 +# are met: 27.13 +# 27.14 +# * Redistributions of source code must retain the above copyright 27.15 +# notice, this list of conditions and the following disclaimer. 27.16 +# * Redistributions in binary form must reproduce the above 27.17 +# copyright notice, this list of conditions and the following 27.18 +# disclaimer in the documentation and/or other materials provided 27.19 +# with the distribution. 27.20 +# * Neither the name of Intel Corporation nor the names of its 27.21 +# contributors may be used to endorse or promote products derived 27.22 +# from this software without specific prior written permission. 27.23 +# 27.24 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27.25 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27.26 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27.27 +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27.28 +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27.29 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27.30 +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27.31 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27.32 +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27.33 +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.34 +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 27.35 +# OF THE POSSIBILITY OF SUCH DAMAGE. 27.36 +# =================================================================== 27.37 + 27.38 +VTPM_IMPL_DEFINED=1 27.39 + 27.40 +# | SRC | TAG | CMD SIZE | ORD | type| mode 27.41 +TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x01 27.42 +TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x02 27.43 +TPM_CMD_CLOS=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x02 27.44 +TPM_CMD_DELE=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x03 27.45 + 27.46 +TPM_SUCCESS=00000000 27.47 + 27.48 +TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo 27.49 +RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo 27.50 + 27.51 +# -------------------- Helpers for binary streams ----------- 27.52 + 27.53 +function str_to_hex32() { 27.54 + printf "%0.8x" $1 27.55 +} 27.56 + 27.57 +function hex32_to_bin() { 27.58 + local inst=$(str_to_hex32 $1); 27.59 + 27.60 + local n1=`echo $inst | sed 's/\(..\)....../\\\\x\1/'` 27.61 + local n2=`echo $inst | sed 's/..\(..\)..../\\\\x\1/'` 27.62 + local n3=`echo $inst | sed 's/....\(..\)../\\\\x\1/'` 27.63 + local n4=`echo $inst | sed 's/......\(..\)/\\\\x\1/'` 27.64 + 27.65 + echo "$n1$n2$n3$n4" 27.66 +} 27.67 + 27.68 +function vtpm_manager_cmd() { 27.69 + local cmd=$1; 27.70 + local inst=$2; 27.71 + local inst_bin=$(hex32_to_bin $inst); 27.72 + 27.73 + #send cmd to vtpm_manager 27.74 + printf "$cmd$inst_bin" > $TX_VTPM_MANAGER 27.75 + 27.76 + #recv response 27.77 + local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null | xxd -ps` 27.78 + 27.79 + #return whether the command was successful 27.80 + if [ $resp_hex != $TPM_SUCCESS ]; then 27.81 + vtpm_fatal_error=1 27.82 + false 27.83 + else 27.84 + true 27.85 + fi 27.86 +} 27.87 + 27.88 +# ------------------ Command handlers ----------------- 27.89 + 27.90 +# Create new vtpm instance & set it up for use 27.91 +function vtpm_create () { 27.92 + # Creation is handled implicitly by the manager on first setup 27.93 + # so just set it up for use 27.94 + $(vtpm_start $1) 27.95 +} 27.96 + 27.97 +# Setup vtpm instance for use. 27.98 +function vtpm_start() { 27.99 + $(vtpm_manager_cmd $TPM_CMD_OPEN $1) 27.100 +} 27.101 + 27.102 +function vtpm_resume() { 27.103 + $(vtpm_manager_cmd $TPM_CMD_RESM $1) 27.104 +} 27.105 + 27.106 +# Reset the vtpm AKA clear PCRs 27.107 +function vtpm_reset() { 27.108 + #not used by current implemenation 27.109 + true 27.110 +} 27.111 + 27.112 +# Shutdown the vtpm while the vm is down 27.113 +# This could be a suspend of shutdown 27.114 +# we cannot distinquish, so save the state 27.115 +# and decide on startup if we should keep is 27.116 +function vtpm_suspend() { 27.117 + $(vtpm_manager_cmd $TPM_CMD_CLOS $1) 27.118 +} 27.119 + 27.120 + 27.121 +function vtpm_delete() { 27.122 + local inst=$1 27.123 + if $(vtpm_manager_cmd $TPM_CMD_DELE $inst); then 27.124 + rm -f /var/vtpm/vtpm_dm_$1.data 27.125 + true 27.126 + else 27.127 + vtpm_fatal_error=1 27.128 + false 27.129 + fi 27.130 +} 27.131 + 27.132 +function vtpm_migrate() { 27.133 + echo "Error: vTPM migration accross machines not implemented." 27.134 +} 27.135 + 27.136 +function vtpm_migrate_recover() { 27.137 + true 27.138 +} 27.139 +
28.1 --- a/tools/libxc/Makefile Wed Jun 28 07:51:52 2006 -0600 28.2 +++ b/tools/libxc/Makefile Wed Jun 28 07:52:21 2006 -0600 28.3 @@ -31,7 +31,6 @@ GUEST_SRCS-y += xc_load_bin.c 28.4 GUEST_SRCS-y += xc_load_elf.c 28.5 GUEST_SRCS-y += xg_private.c 28.6 GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c 28.7 -GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c 28.8 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c 28.9 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c 28.10
29.1 --- a/tools/libxc/xc_aout9.h Wed Jun 28 07:51:52 2006 -0600 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,30 +0,0 @@ 29.4 - 29.5 -typedef struct Exec 29.6 -{ 29.7 - long magic; /* magic number */ 29.8 - long text; /* size of text segment */ 29.9 - long data; /* size of initialized data */ 29.10 - long bss; /* size of uninitialized data */ 29.11 - long syms; /* size of symbol table */ 29.12 - long entry; /* entry point */ 29.13 - long spsz; /* size of pc/sp offset table */ 29.14 - long pcsz; /* size of pc/line number table */ 29.15 -} Exec; 29.16 - 29.17 -#define _MAGIC(b) ((((4*b)+0)*b)+7) 29.18 -#define A_MAGIC _MAGIC(8) /* 68020 */ 29.19 -#define I_MAGIC _MAGIC(11) /* intel 386 */ 29.20 -#define J_MAGIC _MAGIC(12) /* intel 960 (retired) */ 29.21 -#define K_MAGIC _MAGIC(13) /* sparc */ 29.22 -#define V_MAGIC _MAGIC(16) /* mips 3000 BE */ 29.23 -#define X_MAGIC _MAGIC(17) /* att dsp 3210 (retired) */ 29.24 -#define M_MAGIC _MAGIC(18) /* mips 4000 BE */ 29.25 -#define D_MAGIC _MAGIC(19) /* amd 29000 (retired) */ 29.26 -#define E_MAGIC _MAGIC(20) /* arm */ 29.27 -#define Q_MAGIC _MAGIC(21) /* powerpc */ 29.28 -#define N_MAGIC _MAGIC(22) /* mips 4000 LE */ 29.29 -#define L_MAGIC _MAGIC(23) /* dec alpha */ 29.30 -#define P_MAGIC _MAGIC(24) /* mips 3000 LE */ 29.31 -#define U_MAGIC _MAGIC(25) /* sparc64 */ 29.32 -#define S_MAGIC _MAGIC(26) /* amd64 */ 29.33 -
30.1 --- a/tools/libxc/xc_ia64_stubs.c Wed Jun 28 07:51:52 2006 -0600 30.2 +++ b/tools/libxc/xc_ia64_stubs.c Wed Jun 28 07:52:21 2006 -0600 30.3 @@ -38,23 +38,12 @@ int xc_linux_restore(int xc_handle, int 30.4 return -1; 30.5 } 30.6 30.7 -int 30.8 -xc_plan9_build(int xc_handle, 30.9 - uint32_t domid, 30.10 - const char *image_name, 30.11 - const char *cmdline, 30.12 - unsigned int control_evtchn, unsigned long flags) 30.13 -{ 30.14 - PERROR("xc_plan9_build not implemented\n"); 30.15 - return -1; 30.16 -} 30.17 /* 30.18 VMM uses put_user to copy pfn_list to guest buffer, this maybe fail, 30.19 VMM doesn't handle this now. 30.20 This method will touch guest buffer to make sure the buffer's mapping 30.21 is tracked by VMM, 30.22 */ 30.23 - 30.24 int xc_ia64_get_pfn_list(int xc_handle, 30.25 uint32_t domid, 30.26 xen_pfn_t *pfn_buf,
31.1 --- a/tools/libxc/xc_linux_build.c Wed Jun 28 07:51:52 2006 -0600 31.2 +++ b/tools/libxc/xc_linux_build.c Wed Jun 28 07:52:21 2006 -0600 31.3 @@ -7,7 +7,6 @@ 31.4 #include <xenctrl.h> 31.5 31.6 #include "xc_elf.h" 31.7 -#include "xc_aout9.h" 31.8 #include <stdlib.h> 31.9 #include <unistd.h> 31.10 #include <inttypes.h> 31.11 @@ -35,10 +34,6 @@ 31.12 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) 31.13 #define round_pgdown(_p) ((_p)&PAGE_MASK) 31.14 31.15 -#ifdef __ia64__ 31.16 -#define probe_aout9(image,image_size,load_funcs) 1 31.17 -#endif 31.18 - 31.19 struct initrd_info { 31.20 enum { INITRD_none, INITRD_file, INITRD_mem } type; 31.21 unsigned long len; 31.22 @@ -124,8 +119,7 @@ static int probeimageformat(const char * 31.23 struct load_funcs *load_funcs) 31.24 { 31.25 if ( probe_elf(image, image_size, load_funcs) && 31.26 - probe_bin(image, image_size, load_funcs) && 31.27 - probe_aout9(image, image_size, load_funcs) ) 31.28 + probe_bin(image, image_size, load_funcs) ) 31.29 { 31.30 ERROR( "Unrecognized image format" ); 31.31 return -EINVAL;
32.1 --- a/tools/libxc/xc_load_aout9.c Wed Jun 28 07:51:52 2006 -0600 32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3 @@ -1,178 +0,0 @@ 32.4 - 32.5 -#include "xg_private.h" 32.6 -#include "xc_aout9.h" 32.7 - 32.8 -#if defined(__i386__) 32.9 - #define A9_MAGIC I_MAGIC 32.10 -#elif defined(__x86_64__) 32.11 - #define A9_MAGIC S_MAGIC 32.12 -#elif defined(__ia64__) 32.13 - #define A9_MAGIC 0 32.14 -#else 32.15 -#error "Unsupported architecture" 32.16 -#endif 32.17 - 32.18 -#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) 32.19 -#define KZERO 0x80000000 32.20 -#define KOFFSET(_p) ((_p)&~KZERO) 32.21 - 32.22 -static int parseaout9image(const char *, unsigned long, struct domain_setup_info *); 32.23 -static int loadaout9image(const char *, unsigned long, int, uint32_t, xen_pfn_t *, struct domain_setup_info *); 32.24 -static void copyout(int, uint32_t, unsigned long *, unsigned long, const char *, int); 32.25 -struct Exec *get_header(const char *, unsigned long, struct Exec *); 32.26 - 32.27 - 32.28 -int 32.29 -probe_aout9( 32.30 - const char *image, 32.31 - unsigned long image_size, 32.32 - struct load_funcs *load_funcs) 32.33 -{ 32.34 - struct Exec ehdr; 32.35 - 32.36 - if (!get_header(image, image_size, &ehdr)) { 32.37 - ERROR("Kernel image does not have a a.out9 header."); 32.38 - return -EINVAL; 32.39 - } 32.40 - 32.41 - load_funcs->parseimage = parseaout9image; 32.42 - load_funcs->loadimage = loadaout9image; 32.43 - return 0; 32.44 -} 32.45 - 32.46 -static int 32.47 -parseaout9image( 32.48 - const char *image, 32.49 - unsigned long image_size, 32.50 - struct domain_setup_info *dsi) 32.51 -{ 32.52 - struct Exec ehdr; 32.53 - unsigned long start, dstart, end; 32.54 - 32.55 - if (!get_header(image, image_size, &ehdr)) { 32.56 - ERROR("Kernel image does not have a a.out9 header."); 32.57 - return -EINVAL; 32.58 - } 32.59 - 32.60 - if (sizeof ehdr + ehdr.text + ehdr.data > image_size) { 32.61 - ERROR("a.out program extends past end of image."); 32.62 - return -EINVAL; 32.63 - } 32.64 - 32.65 - start = ehdr.entry; 32.66 - dstart = round_pgup(start + ehdr.text); 32.67 - end = dstart + ehdr.data + ehdr.bss; 32.68 - 32.69 - dsi->v_start = KZERO; 32.70 - dsi->v_kernstart = start; 32.71 - dsi->v_kernend = end; 32.72 - dsi->v_kernentry = ehdr.entry; 32.73 - dsi->v_end = end; 32.74 - 32.75 - /* XXX load symbols */ 32.76 - 32.77 - return 0; 32.78 -} 32.79 - 32.80 -static int 32.81 -loadaout9image( 32.82 - const char *image, 32.83 - unsigned long image_size, 32.84 - int xch, uint32_t dom, 32.85 - xen_pfn_t *parray, 32.86 - struct domain_setup_info *dsi) 32.87 -{ 32.88 - struct Exec ehdr; 32.89 - unsigned long start, dstart; 32.90 - 32.91 - if (!get_header(image, image_size, &ehdr)) { 32.92 - ERROR("Kernel image does not have a a.out9 header."); 32.93 - return -EINVAL; 32.94 - } 32.95 - 32.96 - start = ehdr.entry; 32.97 - dstart = round_pgup(start + ehdr.text); 32.98 - copyout(xch, dom, parray, start, image + sizeof ehdr, ehdr.text); 32.99 - copyout(xch, dom, parray, dstart, 32.100 - image + sizeof ehdr + ehdr.text, ehdr.data); 32.101 - 32.102 - /* XXX load symbols */ 32.103 - 32.104 - return 0; 32.105 -} 32.106 - 32.107 -/* 32.108 - * copyout data to the domain given an offset to the start 32.109 - * of its memory region described by parray. 32.110 - */ 32.111 -static void 32.112 -copyout( 32.113 - int xch, uint32_t dom, 32.114 - unsigned long *parray, 32.115 - unsigned long addr, 32.116 - const char *buf, 32.117 - int sz) 32.118 -{ 32.119 - unsigned long pgoff, chunksz, off; 32.120 - void *pg; 32.121 - 32.122 - off = KOFFSET(addr); 32.123 - while (sz > 0) { 32.124 - pgoff = off & (PAGE_SIZE-1); 32.125 - chunksz = sz; 32.126 - if(chunksz > PAGE_SIZE - pgoff) 32.127 - chunksz = PAGE_SIZE - pgoff; 32.128 - 32.129 - pg = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_WRITE, 32.130 - parray[off>>PAGE_SHIFT]); 32.131 - memcpy(pg + pgoff, buf, chunksz); 32.132 - munmap(pg, PAGE_SIZE); 32.133 - 32.134 - off += chunksz; 32.135 - buf += chunksz; 32.136 - sz -= chunksz; 32.137 - } 32.138 -} 32.139 - 32.140 -#define swap16(_v) ((((uint16_t)(_v)>>8)&0xff)|(((uint16_t)(_v)&0xff)<<8)) 32.141 -#define swap32(_v) (((uint32_t)swap16((uint16_t)(_v))<<16)|(uint32_t)swap16((uint32_t)((_v)>>16))) 32.142 - 32.143 -/* 32.144 - * Decode the header from the start of image and return it. 32.145 - */ 32.146 -struct Exec * 32.147 -get_header( 32.148 - const char *image, 32.149 - unsigned long image_size, 32.150 - struct Exec *ehdr) 32.151 -{ 32.152 - uint32_t *v, x; 32.153 - int i; 32.154 - 32.155 - if (A9_MAGIC == 0) 32.156 - return 0; 32.157 - 32.158 - if (image_size < sizeof ehdr) 32.159 - return 0; 32.160 - 32.161 - /* ... all big endian words */ 32.162 - v = (uint32_t *)ehdr; 32.163 - for (i = 0; i < sizeof(*ehdr); i += 4) { 32.164 - x = *(uint32_t *)&image[i]; 32.165 - v[i/4] = swap32(x); 32.166 - } 32.167 - 32.168 - if(ehdr->magic != A9_MAGIC) 32.169 - return 0; 32.170 - return ehdr; 32.171 -} 32.172 - 32.173 -/* 32.174 - * Local variables: 32.175 - * mode: C 32.176 - * c-set-style: "BSD" 32.177 - * c-basic-offset: 4 32.178 - * tab-width: 4 32.179 - * indent-tabs-mode: nil 32.180 - * End: 32.181 - */
33.1 --- a/tools/libxc/xg_private.h Wed Jun 28 07:51:52 2006 -0600 33.2 +++ b/tools/libxc/xg_private.h Wed Jun 28 07:52:21 2006 -0600 33.3 @@ -196,8 +196,5 @@ int probe_elf(const char *image, unsigne 33.4 struct load_funcs *funcs); 33.5 int probe_bin(const char *image, unsigned long image_size, 33.6 struct load_funcs *funcs); 33.7 -int probe_aout9(const char *image, unsigned long image_size, 33.8 - struct load_funcs *funcs); 33.9 33.10 -#endif 33.11 - 33.12 +#endif /* XG_PRIVATE_H */
34.1 --- a/tools/python/xen/lowlevel/xc/xc.c Wed Jun 28 07:51:52 2006 -0600 34.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Wed Jun 28 07:52:21 2006 -0600 34.3 @@ -582,6 +582,12 @@ static PyObject *pyxc_readconsolering(Xc 34.4 } 34.5 34.6 34.7 +static unsigned long pages_to_kib(unsigned long pages) 34.8 +{ 34.9 + return pages * (XC_PAGE_SIZE / 1024); 34.10 +} 34.11 + 34.12 + 34.13 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args) 34.14 { 34.15 unsigned long pages; 34.16 @@ -589,13 +595,7 @@ static PyObject *pyxc_pages_to_kib(XcObj 34.17 if (!PyArg_ParseTuple(args, "l", &pages)) 34.18 return NULL; 34.19 34.20 - return PyLong_FromUnsignedLong(pages * (XC_PAGE_SIZE / 1024)); 34.21 -} 34.22 - 34.23 - 34.24 -static unsigned long pages_to_mb(unsigned long pages) 34.25 -{ 34.26 - return (pages * (XC_PAGE_SIZE / 1024) + 1023) / 1024; 34.27 + return PyLong_FromUnsignedLong(pages_to_kib(pages)); 34.28 } 34.29 34.30 34.31 @@ -618,13 +618,14 @@ static PyObject *pyxc_physinfo(XcObject 34.32 if(q>cpu_cap) 34.33 *(q-1)=0; 34.34 34.35 - return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i,s:s}", 34.36 + return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}", 34.37 "threads_per_core", info.threads_per_core, 34.38 "cores_per_socket", info.cores_per_socket, 34.39 "sockets_per_node", info.sockets_per_node, 34.40 "nr_nodes", info.nr_nodes, 34.41 - "total_memory", pages_to_mb(info.total_pages), 34.42 - "free_memory", pages_to_mb(info.free_pages), 34.43 + "total_memory", pages_to_kib(info.total_pages), 34.44 + "free_memory", pages_to_kib(info.free_pages), 34.45 + "scrub_memory", pages_to_kib(info.scrub_pages), 34.46 "cpu_khz", info.cpu_khz, 34.47 "hw_caps", cpu_cap); 34.48 } 34.49 @@ -637,6 +638,7 @@ static PyObject *pyxc_xeninfo(XcObject * 34.50 xen_capabilities_info_t xen_caps; 34.51 xen_platform_parameters_t p_parms; 34.52 long xen_version; 34.53 + long xen_pagesize; 34.54 char str[128]; 34.55 34.56 xen_version = xc_version(self->xc_handle, XENVER_version, NULL); 34.57 @@ -658,11 +660,16 @@ static PyObject *pyxc_xeninfo(XcObject * 34.58 34.59 sprintf(str, "virt_start=0x%lx", p_parms.virt_start); 34.60 34.61 - return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}", 34.62 + xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL); 34.63 + if (xen_pagesize < 0 ) 34.64 + return PyErr_SetFromErrno(xc_error); 34.65 + 34.66 + return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}", 34.67 "xen_major", xen_version >> 16, 34.68 "xen_minor", (xen_version & 0xffff), 34.69 "xen_extra", xen_extra, 34.70 "xen_caps", xen_caps, 34.71 + "xen_pagesize", xen_pagesize, 34.72 "platform_params", str, 34.73 "xen_changeset", xen_chgset, 34.74 "cc_compiler", xen_cc.compiler,
35.1 --- a/tools/python/xen/xend/XendNode.py Wed Jun 28 07:51:52 2006 -0600 35.2 +++ b/tools/python/xen/xend/XendNode.py Wed Jun 28 07:52:21 2006 -0600 35.3 @@ -64,6 +64,9 @@ class XendNode: 35.4 info['cores_per_socket'] * 35.5 info['threads_per_core']) 35.6 info['cpu_mhz'] = info['cpu_khz'] / 1000 35.7 + # physinfo is in KiB 35.8 + info['total_memory'] = info['total_memory'] / 1024 35.9 + info['free_memory'] = info['free_memory'] / 1024 35.10 35.11 ITEM_ORDER = ['nr_cpus', 35.12 'nr_nodes', 35.13 @@ -86,6 +89,7 @@ class XendNode: 35.14 'xen_minor', 35.15 'xen_extra', 35.16 'xen_caps', 35.17 + 'xen_pagesize', 35.18 'platform_params', 35.19 'xen_changeset', 35.20 'cc_compiler',
36.1 --- a/tools/python/xen/xend/balloon.py Wed Jun 28 07:51:52 2006 -0600 36.2 +++ b/tools/python/xen/xend/balloon.py Wed Jun 28 07:52:21 2006 -0600 36.3 @@ -29,9 +29,7 @@ from XendError import VmError 36.4 36.5 PROC_XEN_BALLOON = '/proc/xen/balloon' 36.6 36.7 -BALLOON_OUT_SLACK = 1 # MiB. We need this because the physinfo details are 36.8 - # rounded. 36.9 -RETRY_LIMIT = 10 36.10 +RETRY_LIMIT = 20 36.11 RETRY_LIMIT_INCR = 5 36.12 ## 36.13 # The time to sleep between retries grows linearly, using this value (in 36.14 @@ -68,22 +66,22 @@ def _get_proc_balloon(label): 36.15 f.close() 36.16 36.17 def get_dom0_current_alloc(): 36.18 - """Returns the current memory allocation (in MiB) of dom0.""" 36.19 + """Returns the current memory allocation (in KiB) of dom0.""" 36.20 36.21 kb = _get_proc_balloon(labels['current']) 36.22 if kb == None: 36.23 raise VmError('Failed to query current memory allocation of dom0.') 36.24 - return kb / 1024 36.25 + return kb 36.26 36.27 def get_dom0_target_alloc(): 36.28 - """Returns the target memory allocation (in MiB) of dom0.""" 36.29 + """Returns the target memory allocation (in KiB) of dom0.""" 36.30 36.31 kb = _get_proc_balloon(labels['target']) 36.32 if kb == None: 36.33 raise VmError('Failed to query target memory allocation of dom0.') 36.34 - return kb / 1024 36.35 + return kb 36.36 36.37 -def free(required): 36.38 +def free(need_mem): 36.39 """Balloon out memory from the privileged domain so that there is the 36.40 specified required amount (in KiB) free. 36.41 """ 36.42 @@ -92,9 +90,10 @@ def free(required): 36.43 # to balloon out to free some up. Memory freed by a destroyed domain may 36.44 # not appear in the free_memory field immediately, because it needs to be 36.45 # scrubbed before it can be released to the free list, which is done 36.46 - # asynchronously by Xen; ballooning is asynchronous also. No matter where 36.47 - # we expect the free memory to come from, therefore, we need to wait for 36.48 - # it to become available. 36.49 + # asynchronously by Xen; ballooning is asynchronous also. Such memory 36.50 + # does, however, need to be accounted for when calculating how much dom0 36.51 + # needs to balloon. No matter where we expect the free memory to come 36.52 + # from, we need to wait for it to become available. 36.53 # 36.54 # We are not allowed to balloon below dom0_min_mem, or if dom0_min_mem 36.55 # is 0, we cannot balloon at all. Memory can still become available 36.56 @@ -108,43 +107,49 @@ def free(required): 36.57 # usage, so we recheck the required alloc each time around the loop, but 36.58 # track the last used value so that we don't trigger too many watches. 36.59 36.60 - need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK 36.61 - 36.62 xroot = XendRoot.instance() 36.63 xc = xen.lowlevel.xc.xc() 36.64 36.65 try: 36.66 - dom0_min_mem = xroot.get_dom0_min_mem() 36.67 + dom0_min_mem = xroot.get_dom0_min_mem() * 1024 36.68 36.69 retries = 0 36.70 sleep_time = SLEEP_TIME_GROWTH 36.71 last_new_alloc = None 36.72 rlimit = RETRY_LIMIT 36.73 while retries < rlimit: 36.74 - free_mem = xc.physinfo()['free_memory'] 36.75 + physinfo = xc.physinfo() 36.76 + free_mem = physinfo['free_memory'] 36.77 + scrub_mem = physinfo['scrub_memory'] 36.78 36.79 if free_mem >= need_mem: 36.80 - log.debug("Balloon: free %d; need %d; done.", free_mem, 36.81 - need_mem) 36.82 + log.debug("Balloon: %d KiB free; need %d; done.", 36.83 + free_mem, need_mem) 36.84 return 36.85 36.86 if retries == 0: 36.87 - rlimit += ((need_mem - free_mem)/1024) * RETRY_LIMIT_INCR 36.88 - log.debug("Balloon: free %d; need %d; retries: %d.", 36.89 - free_mem, need_mem, rlimit) 36.90 + rlimit += ((need_mem - free_mem)/1024/1024) * RETRY_LIMIT_INCR 36.91 + log.debug("Balloon: %d KiB free; %d to scrub; need %d; retries: %d.", 36.92 + free_mem, scrub_mem, need_mem, rlimit) 36.93 36.94 if dom0_min_mem > 0: 36.95 dom0_alloc = get_dom0_current_alloc() 36.96 - new_alloc = dom0_alloc - (need_mem - free_mem) 36.97 + new_alloc = dom0_alloc - (need_mem - free_mem - scrub_mem) 36.98 36.99 - if (new_alloc >= dom0_min_mem and 36.100 - new_alloc != last_new_alloc): 36.101 - log.debug("Balloon: setting dom0 target to %d.", 36.102 - new_alloc) 36.103 - dom0 = XendDomain.instance().privilegedDomain() 36.104 - dom0.setMemoryTarget(new_alloc) 36.105 - last_new_alloc = new_alloc 36.106 - # Continue to retry, waiting for ballooning. 36.107 + if free_mem + scrub_mem >= need_mem: 36.108 + if last_new_alloc == None: 36.109 + log.debug("Balloon: waiting on scrubbing") 36.110 + last_new_alloc = dom0_alloc 36.111 + else: 36.112 + if (new_alloc >= dom0_min_mem and 36.113 + new_alloc != last_new_alloc): 36.114 + new_alloc_mb = new_alloc / 1024 # Round down 36.115 + log.debug("Balloon: setting dom0 target to %d MiB.", 36.116 + new_alloc_mb) 36.117 + dom0 = XendDomain.instance().privilegedDomain() 36.118 + dom0.setMemoryTarget(new_alloc_mb) 36.119 + last_new_alloc = new_alloc 36.120 + # Continue to retry, waiting for ballooning or scrubbing. 36.121 36.122 time.sleep(sleep_time) 36.123 if retries < 2 * RETRY_LIMIT: 36.124 @@ -154,15 +159,15 @@ def free(required): 36.125 # Not enough memory; diagnose the problem. 36.126 if dom0_min_mem == 0: 36.127 raise VmError(('Not enough free memory and dom0_min_mem is 0, so ' 36.128 - 'I cannot release any more. I need %d MiB but ' 36.129 + 'I cannot release any more. I need %d KiB but ' 36.130 'only have %d.') % 36.131 (need_mem, free_mem)) 36.132 elif new_alloc < dom0_min_mem: 36.133 raise VmError( 36.134 - ('I need %d MiB, but dom0_min_mem is %d and shrinking to ' 36.135 - '%d MiB would leave only %d MiB free.') % 36.136 + ('I need %d KiB, but dom0_min_mem is %d and shrinking to ' 36.137 + '%d KiB would leave only %d KiB free.') % 36.138 (need_mem, dom0_min_mem, dom0_min_mem, 36.139 - free_mem + dom0_alloc - dom0_min_mem)) 36.140 + free_mem + scrub_mem + dom0_alloc - dom0_min_mem)) 36.141 else: 36.142 raise VmError('The privileged domain did not balloon!') 36.143
37.1 --- a/tools/python/xen/xm/main.py Wed Jun 28 07:51:52 2006 -0600 37.2 +++ b/tools/python/xen/xm/main.py Wed Jun 28 07:52:21 2006 -0600 37.3 @@ -887,7 +887,7 @@ def parse_dev_info(info): 37.4 'ring-ref' : get_info('ring-ref', int, -1), 37.5 } 37.6 37.7 -def has_long_option(args): 37.8 +def arg_check_for_resource_list(args, name): 37.9 use_long = 0 37.10 try: 37.11 (options, params) = getopt.gnu_getopt(args, 'l', ['long']) 37.12 @@ -898,16 +898,19 @@ def has_long_option(args): 37.13 for (k, v) in options: 37.14 if k in ['-l', '--long']: 37.15 use_long = 1 37.16 + 37.17 + if len(params) == 0: 37.18 + print 'No domain parameter given' 37.19 + usage(name) 37.20 + if len(params) > 1: 37.21 + print 'No multiple domain parameters allowed' 37.22 + usage(name) 37.23 + 37.24 return (use_long, params) 37.25 37.26 def xm_network_list(args): 37.27 - arg_check(args, "network-list", 1, 2) 37.28 - 37.29 - (use_long, params) = has_long_option(args) 37.30 + (use_long, params) = arg_check_for_resource_list(args, "network-list") 37.31 37.32 - if len(params) == 0: 37.33 - print 'No domain parameter given' 37.34 - sys.exit(1) 37.35 dom = params[0] 37.36 if use_long: 37.37 devs = server.xend.domain.getDeviceSxprs(dom, 'vif') 37.38 @@ -931,13 +934,8 @@ def xm_network_list(args): 37.39 % ni) 37.40 37.41 def xm_block_list(args): 37.42 - arg_check(args, "block-list", 1, 2) 37.43 - 37.44 - (use_long, params) = has_long_option(args) 37.45 + (use_long, params) = arg_check_for_resource_list(args, "block-list") 37.46 37.47 - if len(params) == 0: 37.48 - print 'No domain parameter given' 37.49 - sys.exit(1) 37.50 dom = params[0] 37.51 if use_long: 37.52 devs = server.xend.domain.getDeviceSxprs(dom, 'vbd') 37.53 @@ -960,13 +958,8 @@ def xm_block_list(args): 37.54 % ni) 37.55 37.56 def xm_vtpm_list(args): 37.57 - arg_check(args, "vtpm-list", 1, 2) 37.58 - 37.59 - (use_long, params) = has_long_option(args) 37.60 + (use_long, params) = arg_check_for_resource_list(args, "vtpm-list") 37.61 37.62 - if len(params) == 0: 37.63 - print 'No domain parameter given' 37.64 - sys.exit(1) 37.65 dom = params[0] 37.66 if use_long: 37.67 devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
38.1 --- a/tools/vtpm/Rules.mk Wed Jun 28 07:51:52 2006 -0600 38.2 +++ b/tools/vtpm/Rules.mk Wed Jun 28 07:52:21 2006 -0600 38.3 @@ -33,8 +33,7 @@ OBJS = $(patsubst %.c,%.o,$(SRCS)) 38.4 38.5 -include $(DEP_FILES) 38.6 38.7 -# Emulator does not work on 64-bit systems, and may be broken on 32 right now 38.8 -BUILD_EMULATOR = n 38.9 +BUILD_EMULATOR = y 38.10 38.11 # Make sure these are just rules 38.12 .PHONY : all build install clean
39.1 --- a/tools/vtpm/tpm_emulator-0.3-x86_64.patch Wed Jun 28 07:51:52 2006 -0600 39.2 +++ b/tools/vtpm/tpm_emulator-0.3-x86_64.patch Wed Jun 28 07:52:21 2006 -0600 39.3 @@ -1,62 +1,6 @@ 39.4 -diff -uprN tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 39.5 ---- tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 2006-01-10 04:21:45.000000000 -0800 39.6 -+++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-26 11:26:02.000000000 -0700 39.7 -@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne 39.8 - { 39.9 - void *ret = (void*)kmalloc(size, GFP_KERNEL); 39.10 - if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 39.11 -- "GMP: cannot allocate memory (size=%u)\n", size); 39.12 -+ "GMP: cannot allocate memory (size=%Zu)\n", size); 39.13 - return ret; 39.14 - } 39.15 - 39.16 -@@ -88,7 +88,7 @@ void __attribute__ ((regparm(0))) *kerne 39.17 - { 39.18 - void *ret = (void*)kmalloc(new_size, GFP_KERNEL); 39.19 - if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory " 39.20 -- "(old_size=%u new_size=%u)\n", old_size, new_size); 39.21 -+ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size); 39.22 - memcpy(ret, oldptr, old_size); 39.23 - kfree(oldptr); 39.24 - return ret; 39.25 -diff -uprN tpm_emulator-0.3/linux_module.c tpm_emulator-0.3-x86_64/linux_module.c 39.26 ---- tpm_emulator-0.3/linux_module.c 2006-01-10 04:21:45.000000000 -0800 39.27 -+++ tpm_emulator-0.3-x86_64/linux_module.c 2006-05-26 11:26:02.000000000 -0700 39.28 -@@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino 39.29 - 39.30 - static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos) 39.31 - { 39.32 -- debug("%s(%d)", __FUNCTION__, count); 39.33 -+ debug("%s(%Zu)", __FUNCTION__, count); 39.34 - down(&tpm_mutex); 39.35 - if (tpm_response.data != NULL) { 39.36 - count = min(count, (size_t)tpm_response.size - (size_t)*ppos); 39.37 -@@ -91,7 +91,7 @@ static ssize_t tpm_read(struct file *fil 39.38 - 39.39 - static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 39.40 - { 39.41 -- debug("%s(%d)", __FUNCTION__, count); 39.42 -+ debug("%s(%Zu)", __FUNCTION__, count); 39.43 - down(&tpm_mutex); 39.44 - *ppos = 0; 39.45 - if (tpm_response.data != NULL) kfree(tpm_response.data); 39.46 -diff -uprN tpm_emulator-0.3/linux_module.h tpm_emulator-0.3-x86_64/linux_module.h 39.47 ---- tpm_emulator-0.3/linux_module.h 2006-01-10 04:21:45.000000000 -0800 39.48 -+++ tpm_emulator-0.3-x86_64/linux_module.h 2006-05-26 11:26:02.000000000 -0700 39.49 -@@ -28,8 +28,10 @@ 39.50 - 39.51 - /* module settings */ 39.52 - 39.53 -+#ifndef STR 39.54 - #define STR(s) __STR__(s) 39.55 - #define __STR__(s) #s 39.56 -+#endif 39.57 - #include "tpm_version.h" 39.58 - 39.59 - #define TPM_DEVICE_MINOR 224 39.60 -diff -uprN tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile 39.61 ---- tpm_emulator-0.3/Makefile 2006-01-10 04:21:45.000000000 -0800 39.62 -+++ tpm_emulator-0.3-x86_64/Makefile 2006-05-26 11:26:02.000000000 -0700 39.63 +diff -uprN orig/tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile 39.64 +--- orig/tpm_emulator-0.3/Makefile 2006-01-10 04:21:45.000000000 -0800 39.65 ++++ tpm_emulator-0.3-x86_64/Makefile 2006-08-29 15:08:20.532342768 -0700 39.66 @@ -7,6 +7,7 @@ 39.67 KERNEL_RELEASE := $(shell uname -r) 39.68 KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build 39.69 @@ -81,9 +25,9 @@ diff -uprN tpm_emulator-0.3/Makefile tpm 39.70 GMP_HEADER := /usr/include/gmp.h 39.71 39.72 # sources and objects 39.73 -diff -uprN tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README 39.74 ---- tpm_emulator-0.3/README 2006-01-10 04:21:45.000000000 -0800 39.75 -+++ tpm_emulator-0.3-x86_64/README 2006-05-26 11:26:02.000000000 -0700 39.76 +diff -uprN orig/tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README 39.77 +--- orig/tpm_emulator-0.3/README 2006-01-10 04:21:45.000000000 -0800 39.78 ++++ tpm_emulator-0.3-x86_64/README 2006-08-29 15:07:43.530967832 -0700 39.79 @@ -43,6 +43,12 @@ Example: 39.80 GMP_LIB := /usr/lib/libgmp.a 39.81 GMP_HEADER := /usr/include/gmp.h 39.82 @@ -97,9 +41,65 @@ diff -uprN tpm_emulator-0.3/README tpm_e 39.83 Installation 39.84 -------------------------------------------------------------------------- 39.85 The compilation and installation process uses the build environment for 39.86 -diff -uprN tpm_emulator-0.3/tpm/tpm_credentials.c tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 39.87 ---- tpm_emulator-0.3/tpm/tpm_credentials.c 2006-01-10 04:21:45.000000000 -0800 39.88 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 2006-05-26 11:26:02.000000000 -0700 39.89 +diff -uprN orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 39.90 +--- orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 2006-01-10 04:21:45.000000000 -0800 39.91 ++++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-08-29 15:07:43.525968592 -0700 39.92 +@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne 39.93 + { 39.94 + void *ret = (void*)kmalloc(size, GFP_KERNEL); 39.95 + if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 39.96 +- "GMP: cannot allocate memory (size=%u)\n", size); 39.97 ++ "GMP: cannot allocate memory (size=%Zu)\n", size); 39.98 + return ret; 39.99 + } 39.100 + 39.101 +@@ -88,7 +88,7 @@ void __attribute__ ((regparm(0))) *kerne 39.102 + { 39.103 + void *ret = (void*)kmalloc(new_size, GFP_KERNEL); 39.104 + if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory " 39.105 +- "(old_size=%u new_size=%u)\n", old_size, new_size); 39.106 ++ "(old_size=%Zu new_size=%Zu)\n", old_size, new_size); 39.107 + memcpy(ret, oldptr, old_size); 39.108 + kfree(oldptr); 39.109 + return ret; 39.110 +diff -uprN orig/tpm_emulator-0.3/linux_module.c tpm_emulator-0.3-x86_64/linux_module.c 39.111 +--- orig/tpm_emulator-0.3/linux_module.c 2006-01-10 04:21:45.000000000 -0800 39.112 ++++ tpm_emulator-0.3-x86_64/linux_module.c 2006-08-29 15:07:43.526968440 -0700 39.113 +@@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino 39.114 + 39.115 + static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos) 39.116 + { 39.117 +- debug("%s(%d)", __FUNCTION__, count); 39.118 ++ debug("%s(%Zu)", __FUNCTION__, count); 39.119 + down(&tpm_mutex); 39.120 + if (tpm_response.data != NULL) { 39.121 + count = min(count, (size_t)tpm_response.size - (size_t)*ppos); 39.122 +@@ -91,7 +91,7 @@ static ssize_t tpm_read(struct file *fil 39.123 + 39.124 + static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 39.125 + { 39.126 +- debug("%s(%d)", __FUNCTION__, count); 39.127 ++ debug("%s(%Zu)", __FUNCTION__, count); 39.128 + down(&tpm_mutex); 39.129 + *ppos = 0; 39.130 + if (tpm_response.data != NULL) kfree(tpm_response.data); 39.131 +diff -uprN orig/tpm_emulator-0.3/linux_module.h tpm_emulator-0.3-x86_64/linux_module.h 39.132 +--- orig/tpm_emulator-0.3/linux_module.h 2006-01-10 04:21:45.000000000 -0800 39.133 ++++ tpm_emulator-0.3-x86_64/linux_module.h 2006-08-29 15:07:43.527968288 -0700 39.134 +@@ -28,8 +28,10 @@ 39.135 + 39.136 + /* module settings */ 39.137 + 39.138 ++#ifndef STR 39.139 + #define STR(s) __STR__(s) 39.140 + #define __STR__(s) #s 39.141 ++#endif 39.142 + #include "tpm_version.h" 39.143 + 39.144 + #define TPM_DEVICE_MINOR 224 39.145 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_credentials.c tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 39.146 +--- orig/tpm_emulator-0.3/tpm/tpm_credentials.c 2006-01-10 04:21:45.000000000 -0800 39.147 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c 2006-08-29 15:07:43.530967832 -0700 39.148 @@ -47,16 +47,16 @@ int tpm_compute_pubkey_checksum(TPM_NONC 39.149 39.150 TPM_RESULT tpm_get_pubek(TPM_PUBKEY *pubEndorsementKey) 39.151 @@ -140,9 +140,9 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cred 39.152 publicPortion->algorithmParms.algorithmID = TPM_ALG_RSA; 39.153 publicPortion->algorithmParms.encScheme = srk->encScheme; 39.154 publicPortion->algorithmParms.sigScheme = srk->sigScheme; 39.155 -diff -uprN tpm_emulator-0.3/tpm/tpm_crypto.c tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 39.156 ---- tpm_emulator-0.3/tpm/tpm_crypto.c 2006-01-10 04:21:45.000000000 -0800 39.157 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-05-26 11:26:02.000000000 -0700 39.158 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_crypto.c tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 39.159 +--- orig/tpm_emulator-0.3/tpm/tpm_crypto.c 2006-01-10 04:21:45.000000000 -0800 39.160 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-08-29 15:07:43.531967680 -0700 39.161 @@ -182,7 +182,8 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE 39.162 TPM_KEY_DATA *cert, *key; 39.163 sha1_ctx_t sha1_ctx; 39.164 @@ -192,10 +192,10 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cryp 39.165 free_TPM_KEY_PARMS(certifyInfo->algorithmParms); 39.166 return TPM_FAIL; 39.167 } 39.168 -diff -uprN tpm_emulator-0.3/tpm/tpm_data.c tpm_emulator-0.3-x86_64/tpm/tpm_data.c 39.169 ---- tpm_emulator-0.3/tpm/tpm_data.c 2006-01-10 04:21:45.000000000 -0800 39.170 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-05-26 11:26:02.000000000 -0700 39.171 -@@ -214,7 +214,7 @@ static int read_from_file(uint8_t **data 39.172 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_data.c tpm_emulator-0.3-x86_64/tpm/tpm_data.c 39.173 +--- orig/tpm_emulator-0.3/tpm/tpm_data.c 2006-01-10 04:21:45.000000000 -0800 39.174 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-08-29 15:08:20.535342312 -0700 39.175 +@@ -214,23 +214,30 @@ static int read_from_file(uint8_t **data 39.176 int tpm_store_permanent_data(void) 39.177 { 39.178 uint8_t *buf, *ptr; 39.179 @@ -203,8 +203,35 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data 39.180 + UINT32 buf_length, len; 39.181 39.182 /* marshal data */ 39.183 - buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags) 39.184 -@@ -242,13 +242,14 @@ int tpm_store_permanent_data(void) 39.185 +- buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags) 39.186 +- + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) + 2 39.187 +- + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data); 39.188 ++ buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags) 39.189 ++ + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) 39.190 ++ + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2 39.191 ++ + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) 39.192 ++ + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data) 39.193 ++ + sizeof_TPM_STANY_DATA(tpmData.stany.data); 39.194 + buf = ptr = tpm_malloc(buf_length); 39.195 + if (buf == NULL 39.196 + || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version) 39.197 + || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags) 39.198 + || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags) 39.199 ++ || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags) 39.200 + || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.selfTestSucceeded) 39.201 + || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned) 39.202 +- || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)) { 39.203 ++ || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data) 39.204 ++ || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data) 39.205 ++ || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) { 39.206 + tpm_free(buf); 39.207 + return -1; 39.208 + } 39.209 ++ 39.210 + if (write_to_file(buf, buf_length - len)) { 39.211 + tpm_free(buf); 39.212 + return -1; 39.213 +@@ -242,24 +249,29 @@ int tpm_store_permanent_data(void) 39.214 int tpm_restore_permanent_data(void) 39.215 { 39.216 uint8_t *buf, *ptr; 39.217 @@ -221,9 +248,25 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data 39.218 /* unmarshal data */ 39.219 if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver) 39.220 || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION)) 39.221 -diff -uprN tpm_emulator-0.3/tpm/tpm_marshalling.c tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 39.222 ---- tpm_emulator-0.3/tpm/tpm_marshalling.c 2006-01-10 04:21:45.000000000 -0800 39.223 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 2006-05-26 11:26:02.000000000 -0700 39.224 + || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags) 39.225 + || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags) 39.226 ++ || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags) 39.227 + || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.selfTestSucceeded) 39.228 + || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned) 39.229 +- || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)) { 39.230 ++ || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data) 39.231 ++ || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data) 39.232 ++ || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) { 39.233 + tpm_free(buf); 39.234 + return -1; 39.235 + } 39.236 ++ 39.237 + tpm_free(buf); 39.238 + return 0; 39.239 + } 39.240 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.c tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 39.241 +--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.c 2006-01-10 04:21:45.000000000 -0800 39.242 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c 2006-08-29 15:08:20.537342008 -0700 39.243 @@ -1212,7 +1212,7 @@ int tpm_unmarshal_TPM_STANY_FLAGS(BYTE * 39.244 39.245 int tpm_marshal_RSA(BYTE **ptr, UINT32 *length, rsa_private_key_t *v) 39.246 @@ -233,9 +276,92 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_mars 39.247 if (*length < sizeof_RSA((*v))) return -1; 39.248 if (v->size > 0) { 39.249 rsa_export_modulus(v, &(*ptr)[6], &m_len); 39.250 -diff -uprN tpm_emulator-0.3/tpm/tpm_owner.c tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 39.251 ---- tpm_emulator-0.3/tpm/tpm_owner.c 2006-01-10 04:21:45.000000000 -0800 39.252 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 2006-05-26 11:26:02.000000000 -0700 39.253 +@@ -1356,6 +1356,66 @@ int tpm_unmarshal_TPM_PERMANENT_DATA(BYT 39.254 + return 0; 39.255 + } 39.256 + 39.257 ++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v) 39.258 ++{ 39.259 ++ if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag) 39.260 ++ || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceKey) 39.261 ++ || tpm_marshal_TPM_COUNT_ID(ptr, length, v->countID) ) return -1; 39.262 ++ 39.263 ++ return 0; 39.264 ++} 39.265 ++ 39.266 ++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v) 39.267 ++{ 39.268 ++ if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag) 39.269 ++ || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceKey) 39.270 ++ || tpm_unmarshal_TPM_COUNT_ID(ptr, length, &v->countID) ) return -1; 39.271 ++ 39.272 ++ return 0; 39.273 ++} 39.274 ++ 39.275 ++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v) 39.276 ++{ 39.277 ++ UINT32 i; 39.278 ++ if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag) 39.279 ++ || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceSession) 39.280 ++ || tpm_marshal_TPM_DIGEST(ptr, length, &v->auditDigest) 39.281 ++ || tpm_marshal_BOOL(ptr, length, v->auditSession) 39.282 ++ || tpm_marshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks) 39.283 ++ || tpm_marshal_UINT32(ptr, length, v->contextCount) 39.284 ++ || tpm_marshal_UINT32_ARRAY(ptr, length, v->contextList, TPM_MAX_SESSION_LIST)) return -1; 39.285 ++ for (i = 0; i < TPM_MAX_SESSIONS; i++) { 39.286 ++ if (tpm_marshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return -1; 39.287 ++ } 39.288 ++ for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) { 39.289 ++ if (tpm_marshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i])) return -1; 39.290 ++ } 39.291 ++ if (tpm_marshal_TPM_TRANSHANDLE(ptr, length, v->transExclusive)) return -1; 39.292 ++ 39.293 ++ return 0; 39.294 ++} 39.295 ++ 39.296 ++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v) 39.297 ++{ 39.298 ++ UINT32 i; 39.299 ++ if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag) 39.300 ++ || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceSession) 39.301 ++ || tpm_unmarshal_TPM_DIGEST(ptr, length, &v->auditDigest) 39.302 ++ || tpm_unmarshal_BOOL(ptr, length, &v->auditSession) 39.303 ++ || tpm_unmarshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks) 39.304 ++ || tpm_unmarshal_UINT32(ptr, length, &v->contextCount) 39.305 ++ || tpm_unmarshal_UINT32_ARRAY(ptr, length, v->contextList, TPM_MAX_SESSION_LIST)) return -1; 39.306 ++ for (i = 0; i < TPM_MAX_SESSIONS; i++) { 39.307 ++ if (tpm_unmarshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return -1; 39.308 ++ } 39.309 ++ for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) { 39.310 ++ if (tpm_unmarshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i])) return -1; 39.311 ++ } 39.312 ++ if (tpm_unmarshal_TPM_TRANSHANDLE(ptr, length, &v->transExclusive)) return -1; 39.313 ++ 39.314 ++ return 0; 39.315 ++} 39.316 ++ 39.317 + int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA *v) 39.318 + { 39.319 + if (tpm_marshal_BYTE(ptr, length, v->type) 39.320 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.h tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h 39.321 +--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.h 2006-01-10 04:21:45.000000000 -0800 39.322 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h 2006-08-29 15:08:20.538341856 -0700 39.323 +@@ -420,6 +420,12 @@ int tpm_unmarshal_TPM_KEY_DATA(BYTE **pt 39.324 + int tpm_marshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length, TPM_PERMANENT_DATA *); 39.325 + int tpm_unmarshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length, TPM_PERMANENT_DATA *); 39.326 + 39.327 ++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v); 39.328 ++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v); 39.329 ++ 39.330 ++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v); 39.331 ++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v); 39.332 ++ 39.333 + int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA *v); 39.334 + int tpm_unmarshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA *v); 39.335 + 39.336 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_owner.c tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 39.337 +--- orig/tpm_emulator-0.3/tpm/tpm_owner.c 2006-01-10 04:21:45.000000000 -0800 39.338 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c 2006-08-29 15:07:43.535967072 -0700 39.339 @@ -108,7 +108,7 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO 39.340 TPM_RESULT res; 39.341 rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey; 39.342 @@ -255,9 +381,63 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_owne 39.343 /* setup tpmProof and set state to owned */ 39.344 tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce, 39.345 sizeof(tpmData.permanent.data.tpmProof.nonce)); 39.346 -diff -uprN tpm_emulator-0.3/tpm/tpm_storage.c tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 39.347 ---- tpm_emulator-0.3/tpm/tpm_storage.c 2006-01-10 04:21:45.000000000 -0800 39.348 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 2006-05-26 14:33:18.000000000 -0700 39.349 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_startup.c tpm_emulator-0.3-x86_64/tpm/tpm_startup.c 39.350 +--- orig/tpm_emulator-0.3/tpm/tpm_startup.c 2006-01-10 04:21:45.000000000 -0800 39.351 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_startup.c 2006-08-29 15:08:20.538341856 -0700 39.352 +@@ -41,24 +41,29 @@ void TPM_Init(TPM_STARTUP_TYPE startupTy 39.353 + TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE startupType) 39.354 + { 39.355 + int i; 39.356 ++ int restore_fail; 39.357 + info("TPM_Startup(%d)", startupType); 39.358 + if (tpmData.stany.flags.postInitialise == FALSE) return TPM_INVALID_POSTINIT; 39.359 +- /* reset STANY_FLAGS */ 39.360 +- SET_TO_ZERO(&tpmData.stany.flags); 39.361 +- tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS; 39.362 +- /* reset STANY_DATA (invalidates ALL sessions) */ 39.363 +- SET_TO_ZERO(&tpmData.stany.data); 39.364 +- tpmData.stany.data.tag = TPM_TAG_STANY_DATA; 39.365 +- /* init session-context nonce */ 39.366 +- SET_TO_RAND(&tpmData.stany.data.contextNonceSession); 39.367 ++ 39.368 ++ /* try and restore state to get EK, SRK, etc */ 39.369 ++ restore_fail = tpm_restore_permanent_data(); 39.370 ++ 39.371 + /* set data and flags according to the given startup type */ 39.372 + if (startupType == TPM_ST_CLEAR) { 39.373 ++ /* reset STANY_FLAGS */ 39.374 ++ SET_TO_ZERO(&tpmData.stany.flags); 39.375 ++ tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS; 39.376 ++ /* reset STANY_DATA (invalidates ALL sessions) */ 39.377 ++ SET_TO_ZERO(&tpmData.stany.data); 39.378 ++ tpmData.stany.data.tag = TPM_TAG_STANY_DATA; 39.379 ++ /* init session-context nonce */ 39.380 ++ SET_TO_RAND(&tpmData.stany.data.contextNonceSession); 39.381 + /* reset PCR values */ 39.382 + for (i = 0; i < TPM_NUM_PCR; i++) { 39.383 +- if (tpmData.permanent.data.pcrAttrib[i].pcrReset) 39.384 +- SET_TO_ZERO(tpmData.permanent.data.pcrValue[i].digest); 39.385 ++ if (!tpmData.permanent.data.pcrAttrib[i].pcrReset) 39.386 ++ SET_TO_ZERO(&tpmData.permanent.data.pcrValue[i].digest); 39.387 + else 39.388 +- SET_TO_0xFF(tpmData.permanent.data.pcrValue[i].digest); 39.389 ++ SET_TO_0xFF(&tpmData.permanent.data.pcrValue[i].digest); 39.390 + } 39.391 + /* reset STCLEAR_FLAGS */ 39.392 + SET_TO_ZERO(&tpmData.stclear.flags); 39.393 +@@ -77,7 +82,8 @@ TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE 39.394 + /* init key-context nonce */ 39.395 + SET_TO_RAND(&tpmData.stclear.data.contextNonceKey); 39.396 + } else if (startupType == TPM_ST_STATE) { 39.397 +- if (tpm_restore_permanent_data()) { 39.398 ++ /* restore must have been successful for TPM_ST_STATE */ 39.399 ++ if (restore_fail) { 39.400 + error("restoring permanent data failed"); 39.401 + tpmData.permanent.data.testResult = "tpm_restore_permanent_data() failed"; 39.402 + tpmData.permanent.flags.selfTestSucceeded = FALSE; 39.403 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_storage.c tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 39.404 +--- orig/tpm_emulator-0.3/tpm/tpm_storage.c 2006-01-10 04:21:45.000000000 -0800 39.405 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c 2006-08-29 15:07:43.537966768 -0700 39.406 @@ -58,6 +58,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke 39.407 BYTE *enc, UINT32 *enc_size) 39.408 { 39.409 @@ -482,3 +662,76 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_stor 39.410 if (tpm_setup_key_parms(key, &pubKey->algorithmParms) != 0) { 39.411 tpm_free(pubKey->pubKey.key); 39.412 return TPM_FAIL; 39.413 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_structures.h tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 39.414 +--- orig/tpm_emulator-0.3/tpm/tpm_structures.h 2006-01-10 04:21:45.000000000 -0800 39.415 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-08-29 15:08:20.545340792 -0700 39.416 +@@ -1723,6 +1723,7 @@ typedef struct tdTPM_DAA_ISSUER { 39.417 + TPM_DIGEST DAA_digest_gamma; 39.418 + BYTE DAA_generic_q[26]; 39.419 + } TPM_DAA_ISSUER; 39.420 ++#define sizeof_TPM_DAA_ISSUER(s) (2 + (20 * 6) + 26 ) 39.421 + 39.422 + /* 39.423 + * TPM_DAA_TPM ([TPM_Part2], Section 22.8) 39.424 +@@ -1738,6 +1739,7 @@ typedef struct tdTPM_DAA_TPM { 39.425 + TPM_DIGEST DAA_rekey; 39.426 + UINT32 DAA_count; 39.427 + } TPM_DAA_TPM; 39.428 ++#define sizeof_TPM_DAA_TPM(s) (2 + (4 * 20) + 4) 39.429 + 39.430 + /* 39.431 + * TPM_DAA_CONTEXT ([TPM_Part2], Section 22.9) 39.432 +@@ -1752,6 +1754,7 @@ typedef struct tdTPM_DAA_CONTEXT { 39.433 + BYTE DAA_scratch[256]; 39.434 + BYTE DAA_stage; 39.435 + } TPM_DAA_CONTEXT; 39.436 ++#define sizeof_TPM_DAA_CONTEXT(s) (2 + (3 * 20) + 256 + 1) 39.437 + 39.438 + /* 39.439 + * TPM_DAA_JOINDATA ([TPM_Part2], Section 22.10) 39.440 +@@ -1763,6 +1766,7 @@ typedef struct tdTPM_DAA_JOINDATA { 39.441 + BYTE DAA_join_u1[138]; /* WATCH: 138 (v1.2 rev 85) */ 39.442 + TPM_DIGEST DAA_digest_n0; 39.443 + } TPM_DAA_JOINDATA; 39.444 ++#define sizeof_TPM_DAA_JOINDATA(s) (1 + 1 + 20) 39.445 + 39.446 + /* 39.447 + * TPM_DAA_BLOB ([TPM_Part2], Section 22.12) 39.448 +@@ -2033,6 +2037,7 @@ typedef struct tdTPM_STCLEAR_DATA { 39.449 + TPM_COUNT_ID countID; 39.450 + //UINT32 ownerReference; 39.451 + } TPM_STCLEAR_DATA; 39.452 ++#define sizeof_TPM_STCLEAR_DATA(s) (2 + 20 + 4) 39.453 + 39.454 + /* 39.455 + * TPM_SESSION_DATA 39.456 +@@ -2069,6 +2074,11 @@ typedef struct tdTPM_DAA_SESSION_DATA { 39.457 + TPM_DAA_JOINDATA DAA_joinSession; 39.458 + TPM_HANDLE handle; 39.459 + } TPM_DAA_SESSION_DATA; 39.460 ++#define sizeof_TPM_DAA_SESSION_DATA(s) ( 1 \ 39.461 ++ + sizeof_TPM_DAA_ISSUER(s.DAA_issuerSettings) \ 39.462 ++ + sizeof_TPM_DAA_TPM(s.DAA_tpmSpecific) \ 39.463 ++ + sizeof_TPM_DAA_CONTEXT(s.DAA_session) \ 39.464 ++ + sizeof_TPM_DAA_JOINDATA(s.DAA_joinSession) + 4) 39.465 + 39.466 + /* 39.467 + * TPM_STANY_DATA ([TPM_Part2], Section 7.6) 39.468 +@@ -2095,6 +2105,17 @@ typedef struct tdTPM_STANY_DATA { 39.469 + TPM_DAA_SESSION_DATA sessionsDAA[TPM_MAX_SESSIONS_DAA]; 39.470 + TPM_TRANSHANDLE transExclusive; 39.471 + } TPM_STANY_DATA; 39.472 ++#define sizeof_TPM_STANY_DATA(s) (2 + 20 + 20 + 1 \ 39.473 ++ + sizeof_TPM_CURRENT_TICKS(s.currentTicks) \ 39.474 ++ + 4 + (4 * TPM_MAX_SESSION_LIST) \ 39.475 ++ + (sizeof_TPM_SESSION_DATA(s.sessions[0]) * TPM_MAX_SESSION_LIST) \ 39.476 ++ + (sizeof_TPM_DAA_SESSION_DATA(s.sessionsDAA[0]) * TPM_MAX_SESSIONS_DAA) + 4) 39.477 ++ 39.478 ++#define sizeof_TPM_PERMANENT_DATA(s) (2 + 4 + 4*20 \ 39.479 ++ + sizeof_RSA(s.endorsementKey) + TPM_ORD_MAX/8 \ 39.480 ++ + (1+TPM_MAX_KEYS)*sizeof_TPM_KEY_DATA(s.srk) \ 39.481 ++ + TPM_NUM_PCR*(sizeof_TPM_PCR_ATTRIBUTES(x)+20) \ 39.482 ++ + TPM_MAX_COUNTERS*sizeof_TPM_COUNTER_VALUE2(x) + 1 + 4 + 20) 39.483 + 39.484 + /* 39.485 + * TPM_DATA
40.1 --- a/tools/vtpm/tpm_emulator.patch Wed Jun 28 07:51:52 2006 -0600 40.2 +++ b/tools/vtpm/tpm_emulator.patch Wed Jun 28 07:52:21 2006 -0600 40.3 @@ -1,68 +1,63 @@ 40.4 -diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS tpm_emulator/AUTHORS 40.5 ---- orig/tpm_emulator-0.2-x86_64/AUTHORS 2005-08-15 00:58:57.000000000 -0700 40.6 -+++ tpm_emulator/AUTHORS 2005-09-14 20:27:22.000000000 -0700 40.7 -@@ -1 +1,2 @@ 40.8 +diff -uprN tpm_emulator-0.3-x86_64/AUTHORS tpm_emulator/AUTHORS 40.9 +--- tpm_emulator-0.3-x86_64/AUTHORS 2006-08-29 15:07:21.618299064 -0700 40.10 ++++ tpm_emulator/AUTHORS 2006-08-29 15:26:17.099679656 -0700 40.11 +@@ -1,2 +1,3 @@ 40.12 Mario Strasser <mast@gmx.net> 40.13 -+INTEL Corp <> 40.14 -diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog tpm_emulator/ChangeLog 40.15 ---- orig/tpm_emulator-0.2-x86_64/ChangeLog 2005-08-15 00:58:57.000000000 -0700 40.16 -+++ tpm_emulator/ChangeLog 2005-09-14 20:27:22.000000000 -0700 40.17 -@@ -1,3 +1,7 @@ 40.18 -+2005-08-16: INTEL Corp 40.19 -+ * Set default permissions to PCRs 40.20 -+ * Changed device to /dev/tpm0 40.21 + Heiko Stamer <stamer@gaos.org> [DAA] 40.22 ++INTEL Corp <> [Dropped to Ring3] 40.23 +diff -uprN tpm_emulator-0.3-x86_64/ChangeLog tpm_emulator/ChangeLog 40.24 +--- tpm_emulator-0.3-x86_64/ChangeLog 2006-08-29 15:07:21.618299064 -0700 40.25 ++++ tpm_emulator/ChangeLog 2006-08-29 15:26:17.100679504 -0700 40.26 +@@ -1,3 +1,6 @@ 40.27 ++2005-08-16 Intel Corp 40.28 ++ * Moved module out of kernel to run as a ring 3 app 40.29 + 40.30 - 2005-08-15 Mario Strasser <mast@gmx.net> 40.31 - * all: some typos corrected 40.32 - * tpm_integrity.c: bug in TPM_Extend fixed 40.33 -diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h tpm_emulator/linux_module.h 40.34 ---- orig/tpm_emulator-0.2-x86_64/linux_module.h 2005-09-15 19:21:14.844078720 -0700 40.35 -+++ tpm_emulator/linux_module.h 2005-09-14 20:27:22.000000000 -0700 40.36 -@@ -1,5 +1,6 @@ 40.37 - /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.38 - * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.39 -+ * Copyright (C) 2005 INTEL Corp. 40.40 - * 40.41 - * This module is free software; you can redistribute it and/or modify 40.42 - * it under the terms of the GNU General Public License as published 40.43 -@@ -35,7 +36,7 @@ 40.44 - #include "tpm_version.h" 40.45 - 40.46 - #define TPM_DEVICE_MINOR 224 40.47 --#define TPM_DEVICE_NAME "tpm" 40.48 -+#define TPM_DEVICE_NAME "tpm0" 40.49 - #define TPM_MODULE_NAME "tpm_emulator" 40.50 - 40.51 - /* debug and log output functions */ 40.52 -diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile 40.53 ---- orig/tpm_emulator-0.2-x86_64/Makefile 2005-09-15 19:21:14.845078568 -0700 40.54 -+++ tpm_emulator/Makefile 2005-09-14 20:27:22.000000000 -0700 40.55 -@@ -1,16 +1,22 @@ 40.56 + 2005-12-24 Mario Strasser <mast@gmx.net> 40.57 + * tpm_transport.c, tpm_marshalling.c, tpm_structures.h: 40.58 + Transport session functionality added 40.59 +diff -uprN tpm_emulator-0.3-x86_64/Makefile tpm_emulator/Makefile 40.60 +--- tpm_emulator-0.3-x86_64/Makefile 2006-08-29 15:08:20.532342768 -0700 40.61 ++++ tpm_emulator/Makefile 2006-08-29 15:27:39.559143912 -0700 40.62 +@@ -1,22 +1,31 @@ 40.63 # Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.64 # Copyright (C) 2004 Mario Strasser <mast@gmx.net> 40.65 -+# Copyright (C) 2005 INTEL Corp. 40.66 ++# Copyright (C) 2006 INTEL Corp. 40.67 # 40.68 - # $Id: Makefile 10 2005-04-26 20:59:50Z mast $ 40.69 + # $Id: Makefile 69 2005-12-13 12:55:52Z mast $ 40.70 40.71 -+XEN_ROOT := ../../.. 40.72 -+EUID := $(shell id -u) 40.73 -+ 40.74 - # kernel settings 40.75 - KERNEL_RELEASE := $(shell uname -r) 40.76 +-# kernel settings 40.77 +-KERNEL_RELEASE := $(shell uname -r) 40.78 -KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build 40.79 -+CUR_DIR := $(shell pwd) 40.80 -+LINUX_VERSION := $(shell cat $(CUR_DIR)/$(XEN_ROOT)/buildconfigs/mk.linux-2.6-xen | grep "LINUX_VER" | grep "2.6" | gawk '{ print $$3 }' ) 40.81 -+KERNEL_BUILD := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen 40.82 - MOD_SUBDIR := misc 40.83 +-MOD_SUBDIR := misc 40.84 COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) 40.85 40.86 # module settings 40.87 -MODULE_NAME := tpm_emulator 40.88 +BIN := tpm_emulator 40.89 VERSION_MAJOR := 0 40.90 - VERSION_MINOR := 2 40.91 + VERSION_MINOR := 3 40.92 VERSION_BUILD := $(shell date +"%s") 40.93 -@@ -34,11 +38,9 @@ DIRS := . crypto tpm 40.94 + 40.95 +-# enable/disable DEBUG messages 40.96 +-EXTRA_CFLAGS += -Wall -DDEBUG -g 40.97 ++# Installation program and options 40.98 ++INSTALL = install 40.99 ++INSTALL_PROG = $(INSTALL) -m0755 40.100 ++INSTALL_DIR = $(INSTALL) -d -m0755 40.101 ++ 40.102 ++# Xen tools installation directory 40.103 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin 40.104 ++ 40.105 ++CC := gcc 40.106 ++CFLAGS += -g -Wall $(INCLUDE) -DDEBUG 40.107 ++CFLAGS += -I. -Itpm 40.108 ++ 40.109 ++# Is the simulator running in it's own vm? 40.110 ++#CFLAGS += -DVTPM_MULTI_VM 40.111 + 40.112 + ifeq ($(COMPILE_ARCH),x86_64) 40.113 + LIBDIR = lib64 40.114 +@@ -34,38 +43,31 @@ DIRS := . crypto tpm 40.115 SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c)) 40.116 OBJS := $(patsubst %.c, %.o, $(SRCS)) 40.117 SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h)) 40.118 @@ -71,29 +66,37 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ 40.119 40.120 -obj-m := $(MODULE_NAME).o 40.121 -$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a 40.122 -+obj-m := $(BIN).o 40.123 ++obj-m := $(BIN) 40.124 +$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a 40.125 40.126 EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm 40.127 40.128 -@@ -49,23 +51,17 @@ all: $(src)/crypto/gmp.h $(src)/crypto/l 40.129 - @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules 40.130 + # do not print "Entering directory ..." 40.131 + MAKEFLAGS += --no-print-directory 40.132 40.133 - install: 40.134 +-all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version 40.135 +- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules 40.136 ++all: $(BIN) 40.137 ++ 40.138 ++$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS) 40.139 ++ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN) 40.140 ++ 40.141 ++%.o: %.c 40.142 ++ $(CC) $(CFLAGS) -c $< -o $@ 40.143 + 40.144 +-install: 40.145 - @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install 40.146 - test -d /var/tpm || mkdir /var/tpm 40.147 - test -c /dev/tpm || mknod /dev/tpm c 10 224 40.148 - chmod 666 /dev/tpm 40.149 - depmod -a 40.150 -+ @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR) modules_install 40.151 -+ test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm 40.152 -+ test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev 40.153 -+ test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod $(DESTDIR)/dev/tpm0 c 10 224 40.154 -+ [ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0 40.155 ++install: $(BIN) 40.156 ++ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR) 40.157 40.158 clean: 40.159 - @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean 40.160 - rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a 40.161 +- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean 40.162 +- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a 40.163 ++ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS) 40.164 40.165 -dist: $(DISTSRC) 40.166 - rm -rf $(DISTDIR) 40.167 @@ -103,25 +106,591 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ 40.168 - tar -chzf $(DISTDIR).tar.gz $(DISTDIR) 40.169 - rm -rf $(DISTDIR) 40.170 +mrproper: clean 40.171 ++ rm -f $(BIN) tpm_version.h 40.172 40.173 $(src)/crypto/libgmp.a: 40.174 test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a 40.175 -diff -uprN orig/tpm_emulator-0.2-x86_64/README tpm_emulator/README 40.176 ---- orig/tpm_emulator-0.2-x86_64/README 2005-08-15 00:58:57.000000000 -0700 40.177 -+++ tpm_emulator/README 2005-09-14 20:27:22.000000000 -0700 40.178 -@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli 40.179 +diff -uprN tpm_emulator-0.3-x86_64/README tpm_emulator/README 40.180 +--- tpm_emulator-0.3-x86_64/README 2006-08-29 15:07:43.530967832 -0700 40.181 ++++ tpm_emulator/README 2006-08-29 15:26:17.105678744 -0700 40.182 +@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast 40.183 Copyright 40.184 -------------------------------------------------------------------------- 40.185 Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 40.186 -Institute of Technology (ETH) Zurich. 40.187 + Institute of Technology (ETH) Zurich. 40.188 -+Copyright (C) 2005 40.189 ++Copyright (C) 2005 INTEL Corp 40.190 40.191 This program is free software; you can redistribute it and/or modify 40.192 it under the terms of the GNU General Public License as published by 40.193 -diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c 40.194 ---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 2005-09-15 19:21:14.847078264 -0700 40.195 -+++ tpm_emulator/tpm/tpm_data.c 2005-09-14 20:27:22.000000000 -0700 40.196 +diff -uprN tpm_emulator-0.3-x86_64/README.1st tpm_emulator/README.1st 40.197 +--- tpm_emulator-0.3-x86_64/README.1st 1969-12-31 16:00:00.000000000 -0800 40.198 ++++ tpm_emulator/README.1st 2006-08-29 15:26:17.105678744 -0700 40.199 +@@ -0,0 +1 @@ 40.200 ++Note that you must manually create /tmp/tpm_in.fifo and /tmp/tpm_out.fifo for this emulator to work. 40.201 +diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c tpm_emulator/crypto/gmp_kernel_wrapper.c 40.202 +--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-08-29 15:07:43.525968592 -0700 40.203 ++++ tpm_emulator/crypto/gmp_kernel_wrapper.c 2006-08-29 15:26:17.101679352 -0700 40.204 +@@ -1,5 +1,6 @@ 40.205 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.206 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.207 ++ * Copyright (C) 2005 INTEL Corp 40.208 + * 40.209 + * This module is free software; you can redistribute it and/or modify 40.210 + * it under the terms of the GNU General Public License as published 40.211 +@@ -24,15 +25,10 @@ int __gmp_junk; 40.212 + void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename, 40.213 + int linenum, const char *expr) 40.214 + { 40.215 +- panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n", 40.216 ++ error("%s:%d: GNU MP assertion failed: %s\n", 40.217 + filename, linenum, expr); 40.218 + } 40.219 + 40.220 +-void __attribute__ ((regparm(0))) abort(void) 40.221 +-{ 40.222 +- panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n"); 40.223 +-} 40.224 +- 40.225 + /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */ 40.226 + 40.227 + void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate, 40.228 +@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur 40.229 + 40.230 + void __attribute__ ((regparm(0))) *kernel_allocate(size_t size) 40.231 + { 40.232 +- void *ret = (void*)kmalloc(size, GFP_KERNEL); 40.233 +- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 40.234 +- "GMP: cannot allocate memory (size=%Zu)\n", size); 40.235 ++ void *ret = (void*)malloc(size); 40.236 ++ if (!ret) error("GMP: cannot allocate memory (size=%Zu)\n", size); 40.237 + return ret; 40.238 + } 40.239 + 40.240 + void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr, 40.241 + size_t old_size, size_t new_size) 40.242 + { 40.243 +- void *ret = (void*)kmalloc(new_size, GFP_KERNEL); 40.244 +- if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory " 40.245 ++ void *ret = (void*)malloc(new_size); 40.246 ++ if (!ret) error("GMP: Cannot reallocate memory " 40.247 + "(old_size=%Zu new_size=%Zu)\n", old_size, new_size); 40.248 + memcpy(ret, oldptr, old_size); 40.249 +- kfree(oldptr); 40.250 ++ free(oldptr); 40.251 + return ret; 40.252 + } 40.253 + 40.254 +@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel 40.255 + /* overwrite used memory */ 40.256 + if (blk_ptr != NULL) { 40.257 + memset(blk_ptr, 0, blk_size); 40.258 +- kfree(blk_ptr); 40.259 ++ free(blk_ptr); 40.260 + } 40.261 + } 40.262 + 40.263 +diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c tpm_emulator/crypto/rsa.c 40.264 +--- tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-08-29 15:07:21.618299064 -0700 40.265 ++++ tpm_emulator/crypto/rsa.c 2006-08-29 15:26:17.102679200 -0700 40.266 +@@ -1,5 +1,6 @@ 40.267 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.268 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.269 ++ * Copyright (C) 2005 INTEL Corp 40.270 + * 40.271 + * This module is free software; you can redistribute it and/or modify 40.272 + * it under the terms of the GNU General Public License as published 40.273 +@@ -381,7 +382,7 @@ static int encode_message(int type, uint 40.274 + msg[0] = 0x00; 40.275 + get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH); 40.276 + sha1_init(&ctx); 40.277 +- sha1_update(&ctx, "TCPA", 4); 40.278 ++ sha1_update(&ctx, (uint8_t *) "TCPA", 4); 40.279 + sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]); 40.280 + memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 40.281 + msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2); 40.282 +@@ -429,7 +430,7 @@ static int decode_message(int type, uint 40.283 + mask_generation(&msg[1], SHA1_DIGEST_LENGTH, 40.284 + &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1); 40.285 + sha1_init(&ctx); 40.286 +- sha1_update(&ctx, "TCPA", 4); 40.287 ++ sha1_update(&ctx, (uint8_t *) "TCPA", 4); 40.288 + sha1_final(&ctx, &msg[1]); 40.289 + if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 40.290 + SHA1_DIGEST_LENGTH) != 0) return -1; 40.291 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.c tpm_emulator/linux_module.c 40.292 +--- tpm_emulator-0.3-x86_64/linux_module.c 2006-08-29 15:07:43.526968440 -0700 40.293 ++++ tpm_emulator/linux_module.c 1969-12-31 16:00:00.000000000 -0800 40.294 +@@ -1,194 +0,0 @@ 40.295 +-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.296 +- * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.297 +- * 40.298 +- * This module is free software; you can redistribute it and/or modify 40.299 +- * it under the terms of the GNU General Public License as published 40.300 +- * by the Free Software Foundation; either version 2 of the License, 40.301 +- * or (at your option) any later version. 40.302 +- * 40.303 +- * This module is distributed in the hope that it will be useful, 40.304 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of 40.305 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40.306 +- * GNU General Public License for more details. 40.307 +- * 40.308 +- * $Id: linux_module.c 76 2006-01-02 22:17:58Z hstamer $ 40.309 +- */ 40.310 +- 40.311 +-#include <linux/module.h> 40.312 +-#include <linux/kernel.h> 40.313 +-#include <linux/init.h> 40.314 +-#include <linux/miscdevice.h> 40.315 +-#include <linux/poll.h> 40.316 +-#include "linux_module.h" 40.317 +-#include "tpm/tpm_emulator.h" 40.318 +- 40.319 +-MODULE_LICENSE("GPL"); 40.320 +-MODULE_AUTHOR("Mario Strasser <mast@gmx.net>"); 40.321 +-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator"); 40.322 +-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME); 40.323 +- 40.324 +-/* module startup parameters */ 40.325 +-char *startup = "save"; 40.326 +-module_param(startup, charp, 0444); 40.327 +-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. " 40.328 +- "Possible values are 'clear', 'save' (default) and 'deactivated."); 40.329 +-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.2"; 40.330 +-module_param(storage_file, charp, 0644); 40.331 +-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 40.332 +- "file of the TPM."); 40.333 +- 40.334 +-/* TPM lock */ 40.335 +-static struct semaphore tpm_mutex; 40.336 +- 40.337 +-/* TPM command response */ 40.338 +-static struct { 40.339 +- uint8_t *data; 40.340 +- uint32_t size; 40.341 +-} tpm_response; 40.342 +- 40.343 +-/* module state */ 40.344 +-#define STATE_IS_OPEN 0 40.345 +-static uint32_t module_state; 40.346 +- 40.347 +-static int tpm_open(struct inode *inode, struct file *file) 40.348 +-{ 40.349 +- debug("%s()", __FUNCTION__); 40.350 +- if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY; 40.351 +- return 0; 40.352 +-} 40.353 +- 40.354 +-static int tpm_release(struct inode *inode, struct file *file) 40.355 +-{ 40.356 +- debug("%s()", __FUNCTION__); 40.357 +- clear_bit(STATE_IS_OPEN, (void*)&module_state); 40.358 +- down(&tpm_mutex); 40.359 +- if (tpm_response.data != NULL) { 40.360 +- kfree(tpm_response.data); 40.361 +- tpm_response.data = NULL; 40.362 +- } 40.363 +- up(&tpm_mutex); 40.364 +- return 0; 40.365 +-} 40.366 +- 40.367 +-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos) 40.368 +-{ 40.369 +- debug("%s(%Zu)", __FUNCTION__, count); 40.370 +- down(&tpm_mutex); 40.371 +- if (tpm_response.data != NULL) { 40.372 +- count = min(count, (size_t)tpm_response.size - (size_t)*ppos); 40.373 +- count -= copy_to_user(buf, &tpm_response.data[*ppos], count); 40.374 +- *ppos += count; 40.375 +- if ((size_t)tpm_response.size == (size_t)*ppos) { 40.376 +- kfree(tpm_response.data); 40.377 +- tpm_response.data = NULL; 40.378 +- } 40.379 +- } else { 40.380 +- count = 0; 40.381 +- } 40.382 +- up(&tpm_mutex); 40.383 +- return count; 40.384 +-} 40.385 +- 40.386 +-static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 40.387 +-{ 40.388 +- debug("%s(%Zu)", __FUNCTION__, count); 40.389 +- down(&tpm_mutex); 40.390 +- *ppos = 0; 40.391 +- if (tpm_response.data != NULL) kfree(tpm_response.data); 40.392 +- if (tpm_handle_command(buf, count, &tpm_response.data, 40.393 +- &tpm_response.size) != 0) { 40.394 +- count = -EILSEQ; 40.395 +- tpm_response.data = NULL; 40.396 +- } 40.397 +- up(&tpm_mutex); 40.398 +- return count; 40.399 +-} 40.400 +- 40.401 +-#define TPMIOC_CANCEL _IO('T', 0x00) 40.402 +-#define TPMIOC_TRANSMIT _IO('T', 0x01) 40.403 +- 40.404 +-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 40.405 +-{ 40.406 +- debug("%s(%d, %p)", __FUNCTION__, cmd, (char*)arg); 40.407 +- if (cmd == TPMIOC_TRANSMIT) { 40.408 +- uint32_t count = ntohl(*(uint32_t*)(arg + 2)); 40.409 +- down(&tpm_mutex); 40.410 +- if (tpm_response.data != NULL) kfree(tpm_response.data); 40.411 +- if (tpm_handle_command((char*)arg, count, &tpm_response.data, 40.412 +- &tpm_response.size) == 0) { 40.413 +- tpm_response.size -= copy_to_user((char*)arg, tpm_response.data, 40.414 +- tpm_response.size); 40.415 +- kfree(tpm_response.data); 40.416 +- tpm_response.data = NULL; 40.417 +- } else { 40.418 +- tpm_response.size = 0; 40.419 +- tpm_response.data = NULL; 40.420 +- } 40.421 +- up(&tpm_mutex); 40.422 +- return tpm_response.size; 40.423 +- } 40.424 +- return -1; 40.425 +-} 40.426 +- 40.427 +-struct file_operations fops = { 40.428 +- .owner = THIS_MODULE, 40.429 +- .open = tpm_open, 40.430 +- .release = tpm_release, 40.431 +- .read = tpm_read, 40.432 +- .write = tpm_write, 40.433 +- .ioctl = tpm_ioctl, 40.434 +-}; 40.435 +- 40.436 +-static struct miscdevice tpm_dev = { 40.437 +- .minor = TPM_DEVICE_MINOR, 40.438 +- .name = TPM_DEVICE_NAME, 40.439 +- .fops = &fops, 40.440 +-}; 40.441 +- 40.442 +-int __init init_tpm_module(void) 40.443 +-{ 40.444 +- int res = misc_register(&tpm_dev); 40.445 +- if (res != 0) { 40.446 +- error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR); 40.447 +- return res; 40.448 +- } 40.449 +- /* initialize variables */ 40.450 +- sema_init(&tpm_mutex, 1); 40.451 +- module_state = 0; 40.452 +- tpm_response.data = NULL; 40.453 +- /* initialize TPM emulator */ 40.454 +- if (!strcmp(startup, "clear")) { 40.455 +- tpm_emulator_init(1); 40.456 +- } else if (!strcmp(startup, "save")) { 40.457 +- tpm_emulator_init(2); 40.458 +- } else if (!strcmp(startup, "deactivated")) { 40.459 +- tpm_emulator_init(3); 40.460 +- } else { 40.461 +- error("invalid startup mode '%s'; must be 'clear', " 40.462 +- "'save' (default) or 'deactivated", startup); 40.463 +- misc_deregister(&tpm_dev); 40.464 +- return -EINVAL; 40.465 +- } 40.466 +- return 0; 40.467 +-} 40.468 +- 40.469 +-void __exit cleanup_tpm_module(void) 40.470 +-{ 40.471 +- tpm_emulator_shutdown(); 40.472 +- misc_deregister(&tpm_dev); 40.473 +- if (tpm_response.data != NULL) kfree(tpm_response.data); 40.474 +-} 40.475 +- 40.476 +-module_init(init_tpm_module); 40.477 +-module_exit(cleanup_tpm_module); 40.478 +- 40.479 +-uint64_t tpm_get_ticks(void) 40.480 +-{ 40.481 +- static struct timespec old_time = {0, 0}; 40.482 +- struct timespec new_time = current_kernel_time(); 40.483 +- uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000 40.484 +- + (old_time.tv_nsec - new_time.tv_nsec) / 1000; 40.485 +- old_time = new_time; 40.486 +- return (ticks > 0) ? ticks : 1; 40.487 +-} 40.488 +- 40.489 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.h tpm_emulator/linux_module.h 40.490 +--- tpm_emulator-0.3-x86_64/linux_module.h 2006-08-29 15:07:43.527968288 -0700 40.491 ++++ tpm_emulator/linux_module.h 2006-08-29 15:26:17.103679048 -0700 40.492 +@@ -1,5 +1,6 @@ 40.493 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.494 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.495 ++ * Copyright (C) 2005 INTEL Corp 40.496 + * 40.497 + * This module is free software; you can redistribute it and/or modify 40.498 + * it under the terms of the GNU General Public License as published 40.499 +@@ -17,17 +18,22 @@ 40.500 + #ifndef _LINUX_MODULE_H_ 40.501 + #define _LINUX_MODULE_H_ 40.502 + 40.503 +-#include <linux/version.h> 40.504 +-#include <linux/kernel.h> 40.505 +-#include <linux/slab.h> 40.506 ++#include <malloc.h> 40.507 ++#include <stdint.h> 40.508 ++#include <stdio.h> 40.509 ++#include <string.h> 40.510 + #include <linux/types.h> 40.511 +-#include <linux/string.h> 40.512 +-#include <linux/random.h> 40.513 +-#include <linux/time.h> 40.514 +-#include <asm/byteorder.h> 40.515 + 40.516 +-/* module settings */ 40.517 ++#include <endian.h> 40.518 ++#define __BYTEORDER_HAS_U64__ 40.519 ++#ifdef LITTLE_ENDIAN 40.520 ++ #include <linux/byteorder/little_endian.h> 40.521 ++#else 40.522 ++ #include <linux/byteorder/big_endian.h> 40.523 ++#endif 40.524 + 40.525 ++/* module settings */ 40.526 ++#define min(A,B) ((A)<(B)?(A):(B)) 40.527 + #ifndef STR 40.528 + #define STR(s) __STR__(s) 40.529 + #define __STR__(s) #s 40.530 +@@ -38,35 +44,36 @@ 40.531 + #define TPM_DEVICE_NAME "tpm" 40.532 + #define TPM_MODULE_NAME "tpm_emulator" 40.533 + 40.534 +-/* debug and log output functions */ 40.535 +- 40.536 + #ifdef DEBUG 40.537 +-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \ 40.538 +- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__) 40.539 ++#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \ 40.540 ++ __FILE__, __LINE__, ## __VA_ARGS__) 40.541 + #else 40.542 + #define debug(fmt, ...) 40.543 + #endif 40.544 +-#define info(fmt, ...) printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \ 40.545 +- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__) 40.546 +-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \ 40.547 +- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__) 40.548 +-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \ 40.549 +- TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__) 40.550 ++#define info(fmt, ...) printf("TPMD: %s:%d: Info: " fmt "\n", \ 40.551 ++ __FILE__, __LINE__, ## __VA_ARGS__) 40.552 ++#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \ 40.553 ++ __FILE__, __LINE__, ## __VA_ARGS__) 40.554 ++#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \ 40.555 ++ __FILE__, __LINE__, ## __VA_ARGS__) 40.556 + 40.557 + /* memory allocation */ 40.558 + 40.559 + static inline void *tpm_malloc(size_t size) 40.560 + { 40.561 +- return kmalloc(size, GFP_KERNEL); 40.562 ++ return malloc(size); 40.563 + } 40.564 + 40.565 + static inline void tpm_free(const void *ptr) 40.566 + { 40.567 +- if (ptr != NULL) kfree(ptr); 40.568 ++ if (ptr != NULL) free( (void *) ptr); 40.569 + } 40.570 + 40.571 + /* random numbers */ 40.572 + 40.573 ++//FIXME; 40.574 ++void get_random_bytes(void *buf, int nbytes); 40.575 ++ 40.576 + static inline void tpm_get_random_bytes(void *buf, int nbytes) 40.577 + { 40.578 + get_random_bytes(buf, nbytes); 40.579 +@@ -86,9 +93,9 @@ uint64_t tpm_get_ticks(void); 40.580 + #define CPU_TO_LE16(x) __cpu_to_le16(x) 40.581 + 40.582 + #define BE64_TO_CPU(x) __be64_to_cpu(x) 40.583 +-#define LE64_TO_CPU(x) __be64_to_cpu(x) 40.584 ++#define LE64_TO_CPU(x) __le64_to_cpu(x) 40.585 + #define BE32_TO_CPU(x) __be32_to_cpu(x) 40.586 +-#define LE32_TO_CPU(x) __be32_to_cpu(x) 40.587 ++#define LE32_TO_CPU(x) __le32_to_cpu(x) 40.588 + #define BE16_TO_CPU(x) __be16_to_cpu(x) 40.589 + #define LE16_TO_CPU(x) __le16_to_cpu(x) 40.590 + 40.591 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c tpm_emulator/tpm/tpm_audit.c 40.592 +--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-08-29 15:07:21.620298760 -0700 40.593 ++++ tpm_emulator/tpm/tpm_audit.c 2006-08-29 15:26:17.107678440 -0700 40.594 +@@ -1,6 +1,7 @@ 40.595 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.596 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.597 + * Swiss Federal Institute of Technology (ETH) Zurich 40.598 ++ * Copyright (C) 2005 INTEL Corp 40.599 + * 40.600 + * This module is free software; you can redistribute it and/or modify 40.601 + * it under the terms of the GNU General Public License as published 40.602 +@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE 40.603 + tpmData.permanent.data.auditMonotonicCounter++; 40.604 + } 40.605 + /* update audit digest */ 40.606 +- *((UINT16*)&buf[0]) = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN); 40.607 +- *((UINT32*)&buf[2]) = cpu_to_be32(ordinal); 40.608 ++ *((UINT16*)&buf[0]) = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN); 40.609 ++ *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal); 40.610 + sha1_init(&sha1_ctx); 40.611 + sha1_update(&sha1_ctx, req->param, req->paramSize); 40.612 + sha1_final(&sha1_ctx, &buf[6]); 40.613 +- *((UINT16*)&buf[26]) = cpu_to_be16(TPM_TAG_COUNTER_VALUE); 40.614 ++ *((UINT16*)&buf[26]) = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE); 40.615 + memset(&buf[30], 0, 4); 40.616 +- *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter); 40.617 ++ *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter); 40.618 + sha1_init(&sha1_ctx); 40.619 + sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 40.620 + sizeof(TPM_DIGEST)); 40.621 +@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE 40.622 + && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) { 40.623 + info("tpm_audit_response()"); 40.624 + /* update audit digest */ 40.625 +- *((UINT16*)&buf[0]) = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT); 40.626 +- *((UINT32*)&buf[2]) = cpu_to_be32(ordinal); 40.627 ++ *((UINT16*)&buf[0]) = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT); 40.628 ++ *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal); 40.629 + sha1_init(&sha1_ctx); 40.630 + sha1_update(&sha1_ctx, rsp->param, rsp->paramSize); 40.631 + sha1_final(&sha1_ctx, &buf[6]); 40.632 +- *((UINT16*)&buf[26]) = cpu_to_be16(TPM_TAG_COUNTER_VALUE); 40.633 ++ *((UINT16*)&buf[26]) = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE); 40.634 + memset(&buf[30], 0, 4); 40.635 +- *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter); 40.636 +- *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result); 40.637 ++ *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter); 40.638 ++ *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result); 40.639 + sha1_init(&sha1_ctx); 40.640 + sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 40.641 + sizeof(TPM_DIGEST)); 40.642 +@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_ 40.643 + } 40.644 + memcpy(&buf[0], "\x05\x00ADIG", 6); 40.645 + memcpy(&buf[6], antiReplay->nonce, 20); 40.646 +- *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30); 40.647 ++ *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30); 40.648 + memcpy(&buf[30], auditDigest->digest, 20); 40.649 + ptr = &buf[50]; 40.650 + len = buf_size - 50; 40.651 +@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM 40.652 + } 40.653 + return TPM_SUCCESS; 40.654 + } 40.655 +- 40.656 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c tpm_emulator/tpm/tpm_authorization.c 40.657 +--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-08-29 15:07:21.620298760 -0700 40.658 ++++ tpm_emulator/tpm/tpm_authorization.c 2006-08-29 15:26:17.108678288 -0700 40.659 +@@ -1,6 +1,7 @@ 40.660 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.661 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.662 + * Swiss Federal Institute of Technology (ETH) Zurich 40.663 ++ * Copyright (C) 2005 INTEL Corp 40.664 + * 40.665 + * This module is free software; you can redistribute it and/or modify 40.666 + * it under the terms of the GNU General Public License as published 40.667 +@@ -279,7 +280,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut 40.668 + { 40.669 + hmac_ctx_t ctx; 40.670 + TPM_SESSION_DATA *session; 40.671 +- UINT32 auth_handle = cpu_to_be32(auth->authHandle); 40.672 ++ UINT32 auth_handle = CPU_TO_BE32(auth->authHandle); 40.673 + 40.674 + info("tpm_verify_auth(%08x)", auth->authHandle); 40.675 + /* get dedicated authorization or transport session */ 40.676 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c tpm_emulator/tpm/tpm_capability.c 40.677 +--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-08-29 15:07:21.620298760 -0700 40.678 ++++ tpm_emulator/tpm/tpm_capability.c 2006-08-29 15:26:17.109678136 -0700 40.679 +@@ -1,6 +1,7 @@ 40.680 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.681 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.682 + * Swiss Federal Institute of Technology (ETH) Zurich 40.683 ++ * Copyright (C) 2005 INTEL Corp 40.684 + * 40.685 + * This module is free software; you can redistribute it and/or modify 40.686 + * it under the terms of the GNU General Public License as published 40.687 +@@ -406,7 +407,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL 40.688 + 40.689 + case TPM_CAP_KEY_HANDLE: 40.690 + debug("[TPM_CAP_KEY_HANDLE]"); 40.691 +- subCapSize = cpu_to_be32(TPM_RT_KEY); 40.692 ++ subCapSize = CPU_TO_BE32(TPM_RT_KEY); 40.693 + return cap_handle(4, (BYTE*)&subCapSize, respSize, resp); 40.694 + 40.695 + case TPM_CAP_CHECK_LOADED: 40.696 +@@ -480,4 +481,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL 40.697 + return TPM_BAD_MODE; 40.698 + } 40.699 + } 40.700 +- 40.701 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c tpm_emulator/tpm/tpm_cmd_handler.c 40.702 +--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-08-29 15:07:21.621298608 -0700 40.703 ++++ tpm_emulator/tpm/tpm_cmd_handler.c 2006-08-29 15:26:17.113677528 -0700 40.704 +@@ -1,6 +1,7 @@ 40.705 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.706 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.707 + * Swiss Federal Institute of Technology (ETH) Zurich 40.708 ++ * Copyright (C) 2005 INTEL Corp 40.709 + * 40.710 + * This module is free software; you can redistribute it and/or modify 40.711 + * it under the terms of the GNU General Public License as published 40.712 +@@ -73,7 +74,7 @@ void tpm_compute_in_param_digest(TPM_REQ 40.713 + { 40.714 + sha1_ctx_t sha1; 40.715 + UINT32 offset = tpm_get_param_offset(req->ordinal); 40.716 +- UINT32 ord = cpu_to_be32(req->ordinal); 40.717 ++ UINT32 ord = CPU_TO_BE32(req->ordinal); 40.718 + 40.719 + /* compute SHA1 hash */ 40.720 + if (offset <= req->paramSize) { 40.721 +@@ -89,8 +90,8 @@ void tpm_compute_in_param_digest(TPM_REQ 40.722 + void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp) 40.723 + { 40.724 + sha1_ctx_t sha1; 40.725 +- UINT32 res = cpu_to_be32(rsp->result); 40.726 +- UINT32 ord = cpu_to_be32(ordinal); 40.727 ++ UINT32 res = CPU_TO_BE32(rsp->result); 40.728 ++ UINT32 ord = CPU_TO_BE32(ordinal); 40.729 + 40.730 + /* compute SHA1 hash */ 40.731 + sha1_init(&sha1); 40.732 +@@ -3123,7 +3124,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA 40.733 + hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest)); 40.734 + #if 0 40.735 + if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) { 40.736 +- UINT32 handle = cpu_to_be32(rsp->auth2->authHandle); 40.737 ++ UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle); 40.738 + hmac_update(&hmac, (BYTE*)&handle, 4); 40.739 + } 40.740 + #endif 40.741 +@@ -3138,7 +3139,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA 40.742 + hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest)); 40.743 + #if 0 40.744 + if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) { 40.745 +- UINT32 handle = cpu_to_be32(rsp->auth1->authHandle); 40.746 ++ UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle); 40.747 + hmac_update(&hmac, (BYTE*)&handle, 4); 40.748 + } 40.749 + #endif 40.750 +@@ -3221,7 +3222,9 @@ extern const char *tpm_error_to_string(T 40.751 + void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp) 40.752 + { 40.753 + TPM_RESULT res; 40.754 +- 40.755 ++ 40.756 ++ req->tag = (BYTE) req->tag; // FIXME: Why is this here 40.757 ++ 40.758 + /* setup authorisation as well as response tag and size */ 40.759 + memset(rsp, 0, sizeof(*rsp)); 40.760 + switch (req->tag) { 40.761 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c tpm_emulator/tpm/tpm_crypto.c 40.762 +--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-08-29 15:07:43.531967680 -0700 40.763 ++++ tpm_emulator/tpm/tpm_crypto.c 2006-08-29 15:26:17.114677376 -0700 40.764 @@ -1,6 +1,7 @@ 40.765 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.766 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.767 @@ -130,15 +699,1043 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/ 40.768 * 40.769 * This module is free software; you can redistribute it and/or modify 40.770 * it under the terms of the GNU General Public License as published 40.771 -@@ -85,6 +86,11 @@ void tpm_init_data(void) 40.772 - tpmData.permanent.data.version.revMinor = VERSION_MINOR; 40.773 - /* setup PCR attributes */ 40.774 - for (i = 0; i < TPM_NUM_PCR; i++) { 40.775 -+ int j; 40.776 -+ for (j=0; j < TPM_NUM_LOCALITY; j++) { 40.777 -+ tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE; 40.778 +@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T 40.779 + /* setup TPM_SIGN_INFO structure */ 40.780 + memcpy(&buf[0], "\x05\x00SIGN", 6); 40.781 + memcpy(&buf[6], auth->nonceOdd.nonce, 20); 40.782 +- *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize); 40.783 ++ *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize); 40.784 + memcpy(&buf[30], areaToSign, areaToSignSize); 40.785 + if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 40.786 + buf, areaToSignSize + 30, *sig)) { 40.787 +@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL 40.788 + } 40.789 + return TPM_SUCCESS; 40.790 + } 40.791 +- 40.792 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c tpm_emulator/tpm/tpm_daa.c 40.793 +--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-08-29 15:07:21.622298456 -0700 40.794 ++++ tpm_emulator/tpm/tpm_daa.c 2006-08-29 15:26:17.119676616 -0700 40.795 +@@ -700,14 +700,14 @@ info("tested until here"); 40.796 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.797 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.798 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.799 +- sha1_update(&sha1, "\x00", 1); 40.800 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.801 + sha1_final(&sha1, scratch); 40.802 + sha1_init(&sha1); 40.803 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.804 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.805 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.806 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.807 +- sha1_update(&sha1, "\x01", 1); 40.808 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.809 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.810 + mpz_init(f), mpz_init(q); 40.811 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.812 +@@ -787,14 +787,14 @@ info("tested until here"); 40.813 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.814 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.815 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.816 +- sha1_update(&sha1, "\x00", 1); 40.817 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.818 + sha1_final(&sha1, scratch); 40.819 + sha1_init(&sha1); 40.820 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.821 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.822 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.823 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.824 +- sha1_update(&sha1, "\x01", 1); 40.825 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.826 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.827 + mpz_init(f), mpz_init(q); 40.828 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.829 +@@ -1440,14 +1440,14 @@ info("tested until here"); 40.830 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.831 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.832 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.833 +- sha1_update(&sha1, "\x00", 1); 40.834 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.835 + sha1_final(&sha1, scratch); 40.836 + sha1_init(&sha1); 40.837 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.838 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.839 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.840 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.841 +- sha1_update(&sha1, "\x01", 1); 40.842 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.843 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.844 + mpz_init(f), mpz_init(q); 40.845 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.846 +@@ -1660,14 +1660,14 @@ info("tested until here"); 40.847 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.848 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.849 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.850 +- sha1_update(&sha1, "\x00", 1); 40.851 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.852 + sha1_final(&sha1, scratch); 40.853 + sha1_init(&sha1); 40.854 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.855 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.856 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.857 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.858 +- sha1_update(&sha1, "\x01", 1); 40.859 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.860 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.861 + mpz_init(f), mpz_init(q); 40.862 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.863 +@@ -1740,14 +1740,14 @@ info("tested until here"); 40.864 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.865 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.866 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.867 +- sha1_update(&sha1, "\x00", 1); 40.868 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.869 + sha1_final(&sha1, scratch); 40.870 + sha1_init(&sha1); 40.871 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.872 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.873 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.874 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.875 +- sha1_update(&sha1, "\x01", 1); 40.876 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.877 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.878 + mpz_init(f), mpz_init(q); 40.879 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.880 +@@ -2828,14 +2828,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl 40.881 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.882 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.883 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.884 +- sha1_update(&sha1, "\x00", 1); 40.885 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.886 + sha1_final(&sha1, scratch); 40.887 + sha1_init(&sha1); 40.888 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.889 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.890 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.891 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.892 +- sha1_update(&sha1, "\x01", 1); 40.893 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.894 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.895 + mpz_init(f), mpz_init(q); 40.896 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.897 +@@ -3050,7 +3050,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl 40.898 + sha1_init(&sha1); 40.899 + sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 40.900 + sizeof(session->DAA_session.DAA_digest)); 40.901 +- sha1_update(&sha1, "\x01", 1); 40.902 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.903 + sha1_update(&sha1, inputData1, inputSize1); 40.904 + sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest); 40.905 + } 40.906 +@@ -3078,7 +3078,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl 40.907 + sha1_init(&sha1); 40.908 + sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 40.909 + sizeof(session->DAA_session.DAA_digest)); 40.910 +- sha1_update(&sha1, "\x01", 1); 40.911 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.912 + rsa_export_modulus(&aikData->key, scratch, &size); 40.913 + sha1_update(&sha1, scratch, size); 40.914 + sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest); 40.915 +@@ -3134,14 +3134,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl 40.916 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.917 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.918 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.919 +- sha1_update(&sha1, "\x00", 1); 40.920 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.921 + sha1_final(&sha1, scratch); 40.922 + sha1_init(&sha1); 40.923 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.924 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.925 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.926 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.927 +- sha1_update(&sha1, "\x01", 1); 40.928 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.929 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.930 + mpz_init(f), mpz_init(q); 40.931 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.932 +@@ -3213,14 +3213,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl 40.933 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.934 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.935 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.936 +- sha1_update(&sha1, "\x00", 1); 40.937 ++ sha1_update(&sha1, (BYTE *) "\x00", 1); 40.938 + sha1_final(&sha1, scratch); 40.939 + sha1_init(&sha1); 40.940 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 40.941 + sizeof(session->DAA_tpmSpecific.DAA_rekey)); 40.942 + sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 40.943 + sizeof(session->DAA_tpmSpecific.DAA_count)); 40.944 +- sha1_update(&sha1, "\x01", 1); 40.945 ++ sha1_update(&sha1, (BYTE *) "\x01", 1); 40.946 + sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 40.947 + mpz_init(f), mpz_init(q); 40.948 + mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 40.949 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c 40.950 +--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-08-29 15:08:20.535342312 -0700 40.951 ++++ tpm_emulator/tpm/tpm_data.c 2006-08-29 15:26:17.121676312 -0700 40.952 +@@ -150,44 +150,43 @@ void tpm_release_data(void) 40.953 + 40.954 + #ifdef TPM_STORE_TO_FILE 40.955 + 40.956 +-#include <linux/fs.h> 40.957 +-#include <linux/unistd.h> 40.958 +-#include <asm/uaccess.h> 40.959 ++#include <sys/types.h> 40.960 ++#include <sys/stat.h> 40.961 ++#include <fcntl.h> 40.962 ++#include <unistd.h> 40.963 + 40.964 + #define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) 40.965 + 40.966 + static int write_to_file(uint8_t *data, size_t data_length) 40.967 + { 40.968 + int res; 40.969 +- struct file *fp; 40.970 +- mm_segment_t old_fs = get_fs(); 40.971 +- fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); 40.972 +- if (IS_ERR(fp)) return -1; 40.973 +- set_fs(get_ds()); 40.974 +- res = fp->f_op->write(fp, data, data_length, &fp->f_pos); 40.975 +- set_fs(old_fs); 40.976 +- filp_close(fp, NULL); 40.977 ++ int fp; 40.978 ++ fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); 40.979 ++ res = write(fp, data, data_length); 40.980 ++ close(fp); 40.981 + return (res == data_length) ? 0 : -1; 40.982 + } 40.983 + 40.984 + static int read_from_file(uint8_t **data, size_t *data_length) 40.985 + { 40.986 + int res; 40.987 +- struct file *fp; 40.988 +- mm_segment_t old_fs = get_fs(); 40.989 +- fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0); 40.990 +- if (IS_ERR(fp)) return -1; 40.991 +- *data_length = (size_t)fp->f_dentry->d_inode->i_size; 40.992 +- /* *data_length = i_size_read(fp->f_dentry->d_inode); */ 40.993 ++ int fp, file_status; 40.994 ++ struct stat file_info; 40.995 ++ fp = open(TPM_STORAGE_FILE, O_RDONLY, 0); 40.996 ++ file_status = fstat(fp, &file_info); 40.997 ++ if (file_status < 0) { 40.998 ++ close(fp); 40.999 ++ return -1; 40.1000 ++ } 40.1001 ++ 40.1002 ++ *data_length = file_info.st_size; 40.1003 + *data = tpm_malloc(*data_length); 40.1004 + if (*data == NULL) { 40.1005 +- filp_close(fp, NULL); 40.1006 ++ close(fp); 40.1007 + return -1; 40.1008 + } 40.1009 +- set_fs(get_ds()); 40.1010 +- res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos); 40.1011 +- set_fs(old_fs); 40.1012 +- filp_close(fp, NULL); 40.1013 ++ res = read(fp, *data, *data_length); 40.1014 ++ close(fp); 40.1015 + if (res != *data_length) { 40.1016 + tpm_free(*data); 40.1017 + return -1; 40.1018 +@@ -278,7 +277,7 @@ int tpm_restore_permanent_data(void) 40.1019 + 40.1020 + int tpm_erase_permanent_data(void) 40.1021 + { 40.1022 +- int res = write_to_file("", 0); 40.1023 ++ int res = write_to_file((uint8_t *) "", 0); 40.1024 + return res; 40.1025 + } 40.1026 + 40.1027 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig tpm_emulator/tpm/tpm_data.c.orig 40.1028 +--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig 1969-12-31 16:00:00.000000000 -0800 40.1029 ++++ tpm_emulator/tpm/tpm_data.c.orig 2006-08-29 15:26:08.469991568 -0700 40.1030 +@@ -0,0 +1,284 @@ 40.1031 ++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1032 ++ * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1033 ++ * Swiss Federal Institute of Technology (ETH) Zurich 40.1034 ++ * 40.1035 ++ * This module is free software; you can redistribute it and/or modify 40.1036 ++ * it under the terms of the GNU General Public License as published 40.1037 ++ * by the Free Software Foundation; either version 2 of the License, 40.1038 ++ * or (at your option) any later version. 40.1039 ++ * 40.1040 ++ * This module is distributed in the hope that it will be useful, 40.1041 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 40.1042 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40.1043 ++ * GNU General Public License for more details. 40.1044 ++ * 40.1045 ++ * $Id: tpm_data.c 36 2005-10-26 20:31:19Z hstamer $ 40.1046 ++ */ 40.1047 ++ 40.1048 ++#include "tpm_emulator.h" 40.1049 ++#include "tpm_structures.h" 40.1050 ++#include "tpm_marshalling.h" 40.1051 ++#include "linux_module.h" 40.1052 ++ 40.1053 ++TPM_DATA tpmData; 40.1054 ++ 40.1055 ++BOOL tpm_get_physical_presence(void) 40.1056 ++{ 40.1057 ++ return (tpmData.stclear.flags.physicalPresence || TRUE); 40.1058 ++} 40.1059 ++ 40.1060 ++static inline void init_pcr_attr(int pcr, BOOL reset, BYTE rl, BYTE el) 40.1061 ++{ 40.1062 ++ int i; 40.1063 ++ tpmData.permanent.data.pcrAttrib[pcr].pcrReset = reset; 40.1064 ++ for (i = 0; i < TPM_NUM_LOCALITY; i++) { 40.1065 ++ tpmData.permanent.data.pcrAttrib[pcr].pcrResetLocal[i] = (rl & (1 << i)); 40.1066 ++ tpmData.permanent.data.pcrAttrib[pcr].pcrExtendLocal[i] = (el & (1 << i)); 40.1067 ++ } 40.1068 ++} 40.1069 ++ 40.1070 ++void tpm_init_data(void) 40.1071 ++{ 40.1072 ++ /* endorsement key */ 40.1073 ++ uint8_t ek_n[] = "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7" 40.1074 ++ "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93" 40.1075 ++ "\x92\xeb\xd1\x96\x2b\x72\x18\x81\x79\x12\x9d\x9c\x40\xd7\x1a" 40.1076 ++ "\x21\xda\x5f\x56\xe0\xc9\x48\x31\xdd\x96\xdc\xbb\x45\xc6\x8e" 40.1077 ++ "\xad\x58\x23\xcb\xbe\xbb\x13\x2d\x6b\x86\xc5\x57\xf5\xdd\x48" 40.1078 ++ "\xc1\x3d\xcd\x4d\xda\x81\xc4\x43\x17\xaa\x05\x40\x33\x62\x0a" 40.1079 ++ "\x59\xdb\x28\xcd\xb5\x08\x31\xbb\x06\xf5\xf7\x71\xae\x21\xa8" 40.1080 ++ "\xf2\x2f\x0e\x17\x80\x5d\x9c\xdf\xaa\xe9\x89\x09\x54\x65\x2b" 40.1081 ++ "\x46\xfb\x9d\xb2\x00\x70\x63\x0d\x9a\x6d\x3d\x5e\x11\x78\x65" 40.1082 ++ "\x90\xe6\x26\xee\x77\xbe\x08\xff\x07\x60\x5a\xcc\xf1\x0a\xbd" 40.1083 ++ "\x44\x92\x6b\xca\xb6\xce\x66\xf9\x93\x40\xae\xf3\x3e\x53\x02" 40.1084 ++ "\x3c\xa6\x81\xb3\xbe\xad\x6e\x6c\xa6\xf0\xeb\xdf\xe9\xa2\x83" 40.1085 ++ "\x36\x0e\x52\x0d\x64\x17\xd9\xff\xa1\x74\x7c\x2b\xbc\x6a\xcc" 40.1086 ++ "\xe5\x4e\xb4\x52\xd9\xec\x43\xbd\x26\x6a\x2b\x19\x19\x6e\x97" 40.1087 ++ "\xb8\x1d\x9f\x7b\xe7\x32\x2d\xdd\x7c\x51\xc8\xe4\xf3\x02\xd4" 40.1088 ++ "\x7c\x90\x44\xa0\x33\x72\x81\x75\xa9\x16\x27\x5c\x00\x1d\x07" 40.1089 ++ "\x81\xd4\xf7\xac\xcb\xfe\xd6\x60\x03\x6f\x7a\xcc\x00\xd1\xc4" 40.1090 ++ "\x85\x37"; 40.1091 ++ uint8_t ek_e[] = "\x01\x00\x01"; 40.1092 ++ uint8_t ek_p[] = "\xd7\xea\x61\x15\x8b\xa3\x71\xdf\xa8\x74\x77\xca\x88\x95" 40.1093 ++ "\xd0\x76\x17\x43\x2c\xf6\x23\x27\x44\xb9\x0e\x18\x35\x7e\xe4" 40.1094 ++ "\xc3\xcb\x13\x6e\xfc\x38\x02\x1e\x77\x26\x40\x9d\x17\xb2\x39" 40.1095 ++ "\x9c\x7f\x5f\x98\xe6\xf2\x55\x0c\x12\x05\x4c\xb3\x51\xae\x29" 40.1096 ++ "\xe7\xcd\xce\x41\x0b\x28\x4d\x97\x13\x4b\x60\xc8\xd8\x70\x81" 40.1097 ++ "\xf9\x1c\x12\x44\xdf\x53\x0a\x87\x9d\x33\x92\x4a\x34\x69\xf0" 40.1098 ++ "\x70\x5e\x1b\x5d\x65\xc7\x84\x90\xa2\x62\xdf\x83\x14\x10\x69" 40.1099 ++ "\xe2\xa7\x18\x43\xd7\x1f\x60\xc9\x03\x8f\xd6\xa4\xce\xb2\x9d" 40.1100 ++ "\x40\x37\x70\x17\x4c\xe3\x69\xd4\x59"; 40.1101 ++ uint8_t ek_q[] = "\xc8\x34\xd2\xd0\x7c\xfa\xdc\x68\xe2\x72\xd7\x92\xe2\x50" 40.1102 ++ "\x93\xfc\xbb\x72\x55\x4d\x6b\x7a\x0c\x0b\xcf\x87\x66\x1f\x81" 40.1103 ++ "\x71\xf3\x50\xcb\xaa\xe6\x43\x7e\xbe\x11\xc4\xec\x00\x53\xf4" 40.1104 ++ "\x78\x13\x2b\x59\x26\x4a\x9f\x91\x61\x8f\xa7\x07\x64\x11\x5a" 40.1105 ++ "\xf4\xaf\x9c\x9b\x5a\x5d\x69\x20\x17\x55\x74\xba\xd8\xe4\x59" 40.1106 ++ "\x39\x1a\x0a\x7b\x4a\x30\xf0\xc8\x7f\xd9\xaf\x72\xc5\xb6\x71" 40.1107 ++ "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b" 40.1108 ++ "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47" 40.1109 ++ "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f"; 40.1110 ++ int i; 40.1111 ++ /* reset all data to NULL, FALSE or 0 */ 40.1112 ++ memset(&tpmData, 0, sizeof(tpmData)); 40.1113 ++ tpmData.permanent.data.tag = TPM_TAG_PERMANENT_DATA; 40.1114 ++ /* set permanent flags */ 40.1115 ++ tpmData.permanent.flags.tag = TPM_TAG_PERMANENT_FLAGS; 40.1116 ++ tpmData.permanent.flags.disable = FALSE; 40.1117 ++ tpmData.permanent.flags.deactivated = FALSE; 40.1118 ++ tpmData.permanent.flags.ownership = TRUE; 40.1119 ++ tpmData.permanent.flags.readPubek = TRUE; 40.1120 ++ tpmData.permanent.flags.allowMaintenance = TRUE; 40.1121 ++ tpmData.permanent.flags.enableRevokeEK = TRUE; 40.1122 ++ /* set TPM vision */ 40.1123 ++ tpmData.permanent.data.version.major = 1; 40.1124 ++ tpmData.permanent.data.version.minor = 2; 40.1125 ++ tpmData.permanent.data.version.revMajor = VERSION_MAJOR; 40.1126 ++ tpmData.permanent.data.version.revMinor = VERSION_MINOR; 40.1127 ++ /* setup PCR attributes */ 40.1128 ++ for (i = 0; i < min(16, TPM_NUM_PCR); i++) { 40.1129 ++ init_pcr_attr(i, FALSE, 0x00, 0x1f); 40.1130 ++ } 40.1131 ++ if (TPM_NUM_PCR >= 24) { 40.1132 ++ init_pcr_attr(16, TRUE, 0x1f, 0x1f); 40.1133 ++ init_pcr_attr(17, TRUE, 0x10, 0x1c); 40.1134 ++ init_pcr_attr(18, TRUE, 0x10, 0x1c); 40.1135 ++ init_pcr_attr(19, TRUE, 0x10, 0x0c); 40.1136 ++ init_pcr_attr(20, TRUE, 0x14, 0x0e); 40.1137 ++ init_pcr_attr(21, TRUE, 0x04, 0x04); 40.1138 ++ init_pcr_attr(22, TRUE, 0x04, 0x04); 40.1139 ++ init_pcr_attr(23, TRUE, 0x1f, 0x1f); 40.1140 ++ } 40.1141 ++ for (i = 24; i < TPM_NUM_PCR; i++) { 40.1142 ++ init_pcr_attr(i, TRUE, 0x00, 0x00); 40.1143 ++ } 40.1144 ++ /* set tick type */ 40.1145 ++ tpmData.permanent.data.tickType = TICK_INC; 40.1146 ++#ifdef TPM_GENERATE_EK 40.1147 ++ /* generate a new endorsement key */ 40.1148 ++ rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048); 40.1149 ++#else 40.1150 ++ /* setup endorsement key */ 40.1151 ++ rsa_import_key(&tpmData.permanent.data.endorsementKey, 40.1152 ++ RSA_MSB_FIRST, ek_n, 256, ek_e, 3, ek_p, ek_q); 40.1153 ++#endif 40.1154 ++#ifdef TPM_GENERATE_SEED_DAA 40.1155 ++ /* generate the DAA seed (cf. [TPM_Part2], v1.2 rev 85, Section 7.4) */ 40.1156 ++ tpm_get_random_bytes(tpmData.permanent.data.tpmDAASeed.digest, 40.1157 ++ sizeof(tpmData.permanent.data.tpmDAASeed.digest)); 40.1158 ++#else 40.1159 ++ /* FIXME: setup DAA seed */ 40.1160 ++ memcpy(tpmData.permanent.data.tpmDAASeed.digest, 40.1161 ++ "\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 40.1162 ++ "\x00\x00\x00\x77", 20); 40.1163 ++#endif 40.1164 ++ 40.1165 ++ memcpy(tpmData.permanent.data.ekReset.nonce, "\xde\xad\xbe\xef", 4); 40.1166 ++} 40.1167 ++ 40.1168 ++void tpm_release_data(void) 40.1169 ++{ 40.1170 ++ int i; 40.1171 ++ /* release the EK, SRK as well as all other rsa keys */ 40.1172 ++ if (tpmData.permanent.data.endorsementKey.size > 0) 40.1173 ++ rsa_release_private_key(&tpmData.permanent.data.endorsementKey); 40.1174 ++ if (tpmData.permanent.data.srk.valid) 40.1175 ++ rsa_release_private_key(&tpmData.permanent.data.srk.key); 40.1176 ++ for (i = 0; i < TPM_MAX_KEYS; i++) 40.1177 ++ if (tpmData.permanent.data.keys[i].valid) 40.1178 ++ rsa_release_private_key(&tpmData.permanent.data.keys[i].key); 40.1179 ++} 40.1180 ++ 40.1181 ++#ifdef TPM_STORE_TO_FILE 40.1182 ++ 40.1183 ++#include <linux/fs.h> 40.1184 ++#include <linux/unistd.h> 40.1185 ++#include <asm/uaccess.h> 40.1186 ++ 40.1187 ++#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) 40.1188 ++ 40.1189 ++static int write_to_file(uint8_t *data, size_t data_length) 40.1190 ++{ 40.1191 ++ int res; 40.1192 ++ struct file *fp; 40.1193 ++ mm_segment_t old_fs = get_fs(); 40.1194 ++ fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); 40.1195 ++ if (IS_ERR(fp)) return -1; 40.1196 ++ set_fs(get_ds()); 40.1197 ++ res = fp->f_op->write(fp, data, data_length, &fp->f_pos); 40.1198 ++ set_fs(old_fs); 40.1199 ++ filp_close(fp, NULL); 40.1200 ++ return (res == data_length) ? 0 : -1; 40.1201 ++} 40.1202 ++ 40.1203 ++static int read_from_file(uint8_t **data, size_t *data_length) 40.1204 ++{ 40.1205 ++ int res; 40.1206 ++ struct file *fp; 40.1207 ++ mm_segment_t old_fs = get_fs(); 40.1208 ++ fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0); 40.1209 ++ if (IS_ERR(fp)) return -1; 40.1210 ++ *data_length = (size_t)fp->f_dentry->d_inode->i_size; 40.1211 ++ /* *data_length = i_size_read(fp->f_dentry->d_inode); */ 40.1212 ++ *data = tpm_malloc(*data_length); 40.1213 ++ if (*data == NULL) { 40.1214 ++ filp_close(fp, NULL); 40.1215 ++ return -1; 40.1216 ++ } 40.1217 ++ set_fs(get_ds()); 40.1218 ++ res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos); 40.1219 ++ set_fs(old_fs); 40.1220 ++ filp_close(fp, NULL); 40.1221 ++ if (res != *data_length) { 40.1222 ++ tpm_free(*data); 40.1223 ++ return -1; 40.1224 ++ } 40.1225 ++ return 0; 40.1226 ++} 40.1227 ++ 40.1228 ++#else 40.1229 ++ 40.1230 ++static int write_to_file(uint8_t *data, size_t data_length) 40.1231 ++{ 40.1232 ++ info("TPM_STORE_TO_FILE disabled, no data written"); 40.1233 ++ return 0; 40.1234 ++} 40.1235 ++ 40.1236 ++static int read_from_file(uint8_t **data, size_t *data_length) 40.1237 ++{ 40.1238 ++ info("TPM_STORE_TO_FILE disabled, no data read"); 40.1239 ++ return 0; 40.1240 ++} 40.1241 ++ 40.1242 ++#endif /* TPM_STORE_TO_FILE */ 40.1243 ++ 40.1244 ++int tpm_store_permanent_data(void) 40.1245 ++{ 40.1246 ++ uint8_t *buf, *ptr; 40.1247 ++ UINT32 buf_length, len; 40.1248 ++ 40.1249 ++ /* marshal data */ 40.1250 ++ buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags) 40.1251 ++ + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) 40.1252 ++ + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2 40.1253 ++ + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) 40.1254 ++ + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data) 40.1255 ++ + sizeof_TPM_STANY_DATA(tpmData.stany.data); 40.1256 ++ buf = ptr = tpm_malloc(buf_length); 40.1257 ++ if (buf == NULL 40.1258 ++ || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version) 40.1259 ++ || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags) 40.1260 ++ || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags) 40.1261 ++ || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags) 40.1262 ++ || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.selfTestSucceeded) 40.1263 ++ || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned) 40.1264 ++ || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data) 40.1265 ++ || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data) 40.1266 ++ || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) { 40.1267 ++ tpm_free(buf); 40.1268 ++ return -1; 40.1269 ++ } 40.1270 ++ 40.1271 ++ if (write_to_file(buf, buf_length - len)) { 40.1272 ++ tpm_free(buf); 40.1273 ++ return -1; 40.1274 ++ } 40.1275 ++ tpm_free(buf); 40.1276 ++ return 0; 40.1277 ++} 40.1278 ++ 40.1279 ++int tpm_restore_permanent_data(void) 40.1280 ++{ 40.1281 ++ uint8_t *buf, *ptr; 40.1282 ++ size_t buf_length; 40.1283 ++ UINT32 len; 40.1284 ++ TPM_VERSION ver; 40.1285 ++ 40.1286 ++ /* read data */ 40.1287 ++ if (read_from_file(&buf, &buf_length)) return -1; 40.1288 ++ ptr = buf; 40.1289 ++ len = (uint32_t) buf_length; 40.1290 ++ /* unmarshal data */ 40.1291 ++ if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver) 40.1292 ++ || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION)) 40.1293 ++ || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags) 40.1294 ++ || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags) 40.1295 ++ || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags) 40.1296 ++ || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.selfTestSucceeded) 40.1297 ++ || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned) 40.1298 ++ || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data) 40.1299 ++ || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data) 40.1300 ++ || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) { 40.1301 ++ tpm_free(buf); 40.1302 ++ return -1; 40.1303 ++ } 40.1304 ++ 40.1305 ++ tpm_free(buf); 40.1306 ++ return 0; 40.1307 ++} 40.1308 ++ 40.1309 ++int tpm_erase_permanent_data(void) 40.1310 ++{ 40.1311 ++ int res = write_to_file("", 0); 40.1312 ++ return res; 40.1313 ++} 40.1314 ++ 40.1315 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c tpm_emulator/tpm/tpm_deprecated.c 40.1316 +--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-08-29 15:07:21.622298456 -0700 40.1317 ++++ tpm_emulator/tpm/tpm_deprecated.c 2006-08-29 15:26:17.122676160 -0700 40.1318 +@@ -1,6 +1,7 @@ 40.1319 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1320 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1321 + * Swiss Federal Institute of Technology (ETH) Zurich 40.1322 ++ * Copyright (C) 2005 INTEL Corp 40.1323 + * 40.1324 + * This module is free software; you can redistribute it and/or modify 40.1325 + * it under the terms of the GNU General Public License as published 40.1326 +@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA 40.1327 + BYTE *ptr; 40.1328 + UINT32 len; 40.1329 + info("TPM_SaveKeyContext()"); 40.1330 +- res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..", 40.1331 ++ res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..", 40.1332 + keyContextSize, &contextBlob); 40.1333 + if (res != TPM_SUCCESS) return res; 40.1334 + len = *keyContextSize; 40.1335 +@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH 40.1336 + BYTE *ptr; 40.1337 + UINT32 len; 40.1338 + info("TPM_SaveAuthContext()"); 40.1339 +- res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.", 40.1340 ++ res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.", 40.1341 + authContextSize, &contextBlob); 40.1342 + if (res != TPM_SUCCESS) return res; 40.1343 + len = *authContextSize; 40.1344 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h tpm_emulator/tpm/tpm_emulator.h 40.1345 +--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-08-29 15:07:21.648294504 -0700 40.1346 ++++ tpm_emulator/tpm/tpm_emulator.h 2006-08-29 15:26:17.122676160 -0700 40.1347 +@@ -1,5 +1,6 @@ 40.1348 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1349 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1350 ++ * Copyright (C) 2005 INTEL Corp 40.1351 + * 40.1352 + * This module is free software; you can redistribute it and/or modify 40.1353 + * it under the terms of the GNU General Public License as published 40.1354 +@@ -22,7 +23,8 @@ 40.1355 + /* TPM configuration */ 40.1356 + #define TPM_STORE_TO_FILE 1 40.1357 + #undef TPM_STRONG_PERSISTENCE 40.1358 +-#undef TPM_GENERATE_EK 40.1359 ++//#undef TPM_GENERATE_EK 40.1360 ++#define TPM_GENERATE_EK 40.1361 + #undef TPM_GENERATE_SEED_DAA 40.1362 + 40.1363 + #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */ 40.1364 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c tpm_emulator/tpm/tpm_integrity.c 40.1365 +--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-08-29 15:07:21.645294960 -0700 40.1366 ++++ tpm_emulator/tpm/tpm_integrity.c 2006-08-29 15:26:17.123676008 -0700 40.1367 +@@ -1,6 +1,7 @@ 40.1368 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1369 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1370 + * Swiss Federal Institute of Technology (ETH) Zurich 40.1371 ++ * Copyright (C) 2005 INTEL Corp 40.1372 + * 40.1373 + * This module is free software; you can redistribute it and/or modify 40.1374 + * it under the terms of the GNU General Public License as published 40.1375 +@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA * 40.1376 + } 40.1377 + return TPM_SUCCESS; 40.1378 + } 40.1379 +- 40.1380 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h tpm_emulator/tpm/tpm_structures.h 40.1381 +--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-08-29 15:08:20.545340792 -0700 40.1382 ++++ tpm_emulator/tpm/tpm_structures.h 2006-08-29 15:26:17.125675704 -0700 40.1383 +@@ -1,6 +1,7 @@ 40.1384 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1385 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1386 + * Swiss Federal Institute of Technology (ETH) Zurich 40.1387 ++ * Copyright (C) 2005 INTEL Corp 40.1388 + * 40.1389 + * This module is free software; you can redistribute it and/or modify 40.1390 + * it under the terms of the GNU General Public License as published 40.1391 +@@ -18,7 +19,7 @@ 40.1392 + #ifndef _TPM_STRUCTURES_H_ 40.1393 + #define _TPM_STRUCTURES_H_ 40.1394 + 40.1395 +-#include <linux/types.h> 40.1396 ++//#include <linux/types.h> 40.1397 + #include "crypto/rsa.h" 40.1398 + 40.1399 + /* 40.1400 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c tpm_emulator/tpm/tpm_testing.c 40.1401 +--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-08-29 15:07:21.646294808 -0700 40.1402 ++++ tpm_emulator/tpm/tpm_testing.c 2006-08-29 15:26:17.127675400 -0700 40.1403 +@@ -1,6 +1,7 @@ 40.1404 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1405 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1406 + * Swiss Federal Institute of Technology (ETH) Zurich 40.1407 ++ * Copyright (C) 2005 INTEL Corp 40.1408 + * 40.1409 + * This module is free software; you can redistribute it and/or modify 40.1410 + * it under the terms of the GNU General Public License as published 40.1411 +@@ -95,24 +96,24 @@ static int tpm_test_sha1(void) 40.1412 + struct { 40.1413 + uint8_t *data; uint32_t repetitions; uint8_t *digest; 40.1414 + } test_cases[] = {{ 40.1415 +- "abc", 1, 40.1416 +- "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" 40.1417 ++ (uint8_t*)"abc", 1, 40.1418 ++ (uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" 40.1419 + }, { 40.1420 +- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1, 40.1421 +- "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" 40.1422 ++ (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1, 40.1423 ++ (uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" 40.1424 + }, { 40.1425 +- "a", 1000000, 40.1426 +- "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" 40.1427 ++ (uint8_t*)"a", 1000000, 40.1428 ++ (uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" 40.1429 + }, { 40.1430 +- "0123456701234567012345670123456701234567012345670123456701234567", 10, 40.1431 +- "\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52" 40.1432 ++ (uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567", 10, 40.1433 ++ (uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52" 40.1434 + }}; 40.1435 + 40.1436 + debug("tpm_test_sha1()"); 40.1437 + for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) { 40.1438 + sha1_init(&ctx); 40.1439 + for (j = 0; j < test_cases[i].repetitions; j++) 40.1440 +- sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data)); 40.1441 ++ sha1_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data)); 40.1442 + sha1_final(&ctx, digest); 40.1443 + if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1; 40.1444 + } 40.1445 +@@ -128,41 +129,41 @@ static int tpm_test_hmac(void) 40.1446 + struct { 40.1447 + uint8_t *key, key_len, *data, data_len, *digest; 40.1448 + } test_cases[] = {{ 40.1449 +- "\x0b", 20, "Hi There", 8, 40.1450 +- "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00" 40.1451 ++ (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8, 40.1452 ++ (uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00" 40.1453 + }, { 40.1454 +- "Jefe", 4, "what do ya want for nothing?", 28, 40.1455 +- "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79" 40.1456 ++ (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28, 40.1457 ++ (uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79" 40.1458 + }, { 40.1459 +- "\xaa", 20, "\xdd", 50, 40.1460 +- "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3" 40.1461 ++ (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50, 40.1462 ++ (uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3" 40.1463 + }, { 40.1464 +- "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" 40.1465 +- "\x15\x16\x17\x18\x19", 25, "\xcd", 50, 40.1466 +- "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda" 40.1467 ++ (uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" 40.1468 ++ "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50, 40.1469 ++ (uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda" 40.1470 + }, { 40.1471 +- "\x0c", 20, "Test With Truncation", 20, 40.1472 +- "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04" 40.1473 ++ (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20, 40.1474 ++ (uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04" 40.1475 + }, { 40.1476 +- "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54, 40.1477 +- "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12" 40.1478 ++ (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key - Hash Key First", 54, 40.1479 ++ (uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12" 40.1480 + }, { 40.1481 +- "\xaa", 80, 40.1482 +- "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, 40.1483 +- "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91" 40.1484 ++ (uint8_t*)"\xaa", 80, 40.1485 ++ (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, 40.1486 ++ (uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91" 40.1487 + }}; 40.1488 + 40.1489 + debug("tpm_test_hmac()"); 40.1490 + for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) { 40.1491 +- if (strlen(test_cases[i].key) < test_cases[i].key_len) { 40.1492 ++ if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) { 40.1493 + uint8_t key[test_cases[i].key_len]; 40.1494 + memset(key, test_cases[i].key[0], test_cases[i].key_len); 40.1495 + hmac_init(&ctx, key, test_cases[i].key_len); 40.1496 + } else { 40.1497 + hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len); 40.1498 + } 40.1499 +- for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) { 40.1500 +- hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data)); 40.1501 ++ for (j = 0; j < test_cases[i].data_len; j += strlen((char*)test_cases[i].data)) { 40.1502 ++ hmac_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data)); 40.1503 + } 40.1504 + hmac_final(&ctx, digest); 40.1505 + if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1; 40.1506 +@@ -173,9 +174,9 @@ static int tpm_test_hmac(void) 40.1507 + static int tpm_test_rsa_EK(void) 40.1508 + { 40.1509 + int res = 0; 40.1510 +- char *data = "RSA PKCS #1 v1.5 Test-String"; 40.1511 ++ uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String"; 40.1512 + uint8_t buf[256]; 40.1513 +- size_t buf_len, data_len = strlen(data); 40.1514 ++ size_t buf_len, data_len = strlen((char*)data); 40.1515 + rsa_private_key_t priv_key; 40.1516 + rsa_public_key_t pub_key; 40.1517 + 40.1518 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c tpm_emulator/tpm/tpm_ticks.c 40.1519 +--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-08-29 15:07:21.646294808 -0700 40.1520 ++++ tpm_emulator/tpm/tpm_ticks.c 2006-08-29 15:26:17.128675248 -0700 40.1521 +@@ -1,6 +1,7 @@ 40.1522 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1523 + * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 40.1524 + * Swiss Federal Institute of Technology (ETH) Zurich 40.1525 ++ * Copyright (C) 2005 INTEL Corp 40.1526 + * 40.1527 + * This module is free software; you can redistribute it and/or modify 40.1528 + * it under the terms of the GNU General Public License as published 40.1529 +@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE 40.1530 + TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime) 40.1531 + { 40.1532 + info("TPM_GetTicks()"); 40.1533 +- memcpy(currentTime, &tpmData.stany.data.currentTicks, 40.1534 +- sizeof(TPM_CURRENT_TICKS)); 40.1535 +- return TPM_SUCCESS; 40.1536 ++ return TPM_DISABLED_CMD; 40.1537 + } 40.1538 + 40.1539 + TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay, 40.1540 +@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN 40.1541 + TPM_CURRENT_TICKS *currentTicks, 40.1542 + UINT32 *sigSize, BYTE **sig) 40.1543 + { 40.1544 +- TPM_RESULT res; 40.1545 +- TPM_KEY_DATA *key; 40.1546 +- BYTE *info, *p; 40.1547 +- UINT32 info_length, length; 40.1548 + info("TPM_TickStampBlob()"); 40.1549 +- /* get key */ 40.1550 +- key = tpm_get_key(keyHandle); 40.1551 +- if (key == NULL) return TPM_INVALID_KEYHANDLE; 40.1552 +- /* verify authorization */ 40.1553 +- res = tpm_verify_auth(auth1, key->usageAuth, keyHandle); 40.1554 +- if (res != TPM_SUCCESS) return res; 40.1555 +- if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY 40.1556 +- && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE; 40.1557 +- /* get current ticks */ 40.1558 +- TPM_GetTicks(currentTicks); 40.1559 +- /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container */ 40.1560 +- *sigSize = key->key.size >> 3; 40.1561 +- *sig = tpm_malloc(*sigSize); 40.1562 +- if (*sig == NULL) return TPM_FAIL; 40.1563 +- /* setup TPM_SIGN_INFO structure */ 40.1564 +- info_length = 30 + sizeof(TPM_DIGEST) + sizeof_TPM_CURRENT_TICKS(currentTicks); 40.1565 +- info = tpm_malloc(info_length); 40.1566 +- if (info == NULL) { 40.1567 +- tpm_free(*sig); 40.1568 +- return TPM_FAIL; 40.1569 +- } 40.1570 +- memcpy(&info[0], "\x05\x00TSTP", 6); 40.1571 +- memcpy(&info[6], antiReplay->nonce, 20); 40.1572 +- *(UINT32*)&info[26] = cpu_to_be32(20 40.1573 +- + sizeof_TPM_CURRENT_TICKS(currentTicks)); 40.1574 +- memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST)); 40.1575 +- p = &info[30 + sizeof(TPM_DIGEST)]; 40.1576 +- length = sizeof_TPM_CURRENT_TICKS(currentTicks); 40.1577 +- if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks) 40.1578 +- || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) { 40.1579 +- tpm_free(*sig); 40.1580 +- tpm_free(info); 40.1581 +- return TPM_FAIL; 40.1582 +- } 40.1583 +- return TPM_SUCCESS; 40.1584 ++ return TPM_DISABLED_CMD; 40.1585 + } 40.1586 + 40.1587 + void tpm_update_ticks(void) 40.1588 + { 40.1589 +- if (tpmData.stany.data.currentTicks.tag == 0) { 40.1590 +- tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS; 40.1591 +- tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks(); 40.1592 +- tpmData.stany.data.currentTicks.tickType = tpmData.permanent.data.tickType; 40.1593 +- tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce, 40.1594 +- sizeof(TPM_NONCE)); 40.1595 +- tpmData.stany.data.currentTicks.tickRate = 1; 40.1596 +- tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK; 40.1597 +- } else { 40.1598 +- tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks(); 40.1599 +- } 40.1600 + } 40.1601 + 40.1602 + 40.1603 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c tpm_emulator/tpm/tpm_transport.c 40.1604 +--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-08-29 15:07:21.647294656 -0700 40.1605 ++++ tpm_emulator/tpm/tpm_transport.c 2006-08-29 15:26:17.129675096 -0700 40.1606 +@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE 40.1607 + static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20], 40.1608 + BYTE pubKeyHash[20], TPM_DIGEST *transDigest) 40.1609 + { 40.1610 +- UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_IN); 40.1611 ++ UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_IN); 40.1612 + BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)]; 40.1613 + UINT32 len = sizeof(buf); 40.1614 + sha1_ctx_t sha1; 40.1615 +@@ -76,7 +76,7 @@ static void transport_log_in(TPM_COMMAND 40.1616 + static void transport_log_out(TPM_CURRENT_TICKS *currentTicks, BYTE parameters[20], 40.1617 + TPM_MODIFIER_INDICATOR locality, TPM_DIGEST *transDigest) 40.1618 + { 40.1619 +- UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_OUT); 40.1620 ++ UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_OUT); 40.1621 + BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)]; 40.1622 + UINT32 len = sizeof(buf); 40.1623 + sha1_ctx_t sha1; 40.1624 +@@ -191,7 +191,7 @@ static void decrypt_wrapped_command(BYTE 40.1625 + sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce)); 40.1626 + sha1_update(&sha1, "in", 2); 40.1627 + sha1_update(&sha1, secret, sizeof(TPM_SECRET)); 40.1628 +- j = cpu_to_be32(i); 40.1629 ++ j = CPU_TO_BE32(i); 40.1630 + sha1_update(&sha1, (BYTE*)&j, 4); 40.1631 + sha1_final(&sha1, mask); 40.1632 + for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 40.1633 +@@ -213,7 +213,7 @@ static void encrypt_wrapped_command(BYTE 40.1634 + sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce)); 40.1635 + sha1_update(&sha1, "out", 3); 40.1636 + sha1_update(&sha1, secret, sizeof(TPM_SECRET)); 40.1637 +- j = cpu_to_be32(i); 40.1638 ++ j = CPU_TO_BE32(i); 40.1639 + sha1_update(&sha1, (BYTE*)&j, 4); 40.1640 + sha1_final(&sha1, mask); 40.1641 + for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 40.1642 +@@ -253,9 +253,9 @@ TPM_RESULT TPM_ExecuteTransport(UINT32 i 40.1643 + /* verify authorization */ 40.1644 + tpm_compute_in_param_digest(&req); 40.1645 + sha1_init(&sha1); 40.1646 +- res = cpu_to_be32(TPM_ORD_ExecuteTransport); 40.1647 ++ res = CPU_TO_BE32(TPM_ORD_ExecuteTransport); 40.1648 + sha1_update(&sha1, (BYTE*)&res, 4); 40.1649 +- res = cpu_to_be32(inWrappedCmdSize); 40.1650 ++ res = CPU_TO_BE32(inWrappedCmdSize); 40.1651 + sha1_update(&sha1, (BYTE*)&res, 4); 40.1652 + sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest)); 40.1653 + sha1_final(&sha1, auth1->digest); 40.1654 +@@ -357,7 +357,7 @@ TPM_RESULT TPM_ReleaseTransportSigned(TP 40.1655 + /* setup a TPM_SIGN_INFO structure */ 40.1656 + memcpy(&buf[0], "\x05\x00TRAN", 6); 40.1657 + memcpy(&buf[6], antiReplay->nonce, 20); 40.1658 +- *(UINT32*)&buf[26] = cpu_to_be32(20); 40.1659 ++ *(UINT32*)&buf[26] = CPU_TO_BE32(20); 40.1660 + memcpy(&buf[30], session->transInternal.transDigest.digest, 20); 40.1661 + /* sign info structure */ 40.1662 + res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize); 40.1663 +diff -uprN tpm_emulator-0.3-x86_64/tpm_version.h tpm_emulator/tpm_version.h 40.1664 +--- tpm_emulator-0.3-x86_64/tpm_version.h 2006-08-29 15:07:21.649294352 -0700 40.1665 ++++ tpm_emulator/tpm_version.h 1969-12-31 16:00:00.000000000 -0800 40.1666 +@@ -1,6 +0,0 @@ 40.1667 +-#ifndef _TPM_VERSION_H_ 40.1668 +-#define _TPM_VERSION_H_ 40.1669 +-#define VERSION_MAJOR 0 40.1670 +-#define VERSION_MINOR 3 40.1671 +-#define VERSION_BUILD 1136893683 40.1672 +-#endif /* _TPM_VERSION_H_ */ 40.1673 +diff -uprN tpm_emulator-0.3-x86_64/tpmd.c tpm_emulator/tpmd.c 40.1674 +--- tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800 40.1675 ++++ tpm_emulator/tpmd.c 2006-08-29 15:26:17.130674944 -0700 40.1676 +@@ -0,0 +1,141 @@ 40.1677 ++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 40.1678 ++ * Copyright (C) 2005 INTEL Corp 40.1679 ++ * 40.1680 ++ * This module is free software; you can redistribute it and/or modify 40.1681 ++ * it under the terms of the GNU General Public License as published 40.1682 ++ * by the Free Software Foundation; either version 2 of the License, 40.1683 ++ * or (at your option) any later version. 40.1684 ++ * 40.1685 ++ * This module is distributed in the hope that it will be useful, 40.1686 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 40.1687 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40.1688 ++ * GNU General Public License for more details. 40.1689 ++ * 40.1690 ++ */ 40.1691 ++ 40.1692 ++#include <stdio.h> 40.1693 ++#include <stdlib.h> 40.1694 ++#include <unistd.h> 40.1695 ++#include <string.h> 40.1696 ++#include <sys/types.h> 40.1697 ++#include <sys/stat.h> 40.1698 ++#include <fcntl.h> 40.1699 ++#include <sys/time.h> 40.1700 ++ 40.1701 ++#include "tpm_emulator.h" 40.1702 ++ 40.1703 ++#define TPM_RX_FNAME "/tmp/tpm_in.fifo" 40.1704 ++#define TPM_TX_FNAME "/tmp/tpm_out.fifo" 40.1705 ++ 40.1706 ++#define BUFFER_SIZE 2048 40.1707 ++ 40.1708 ++static int devurandom=0; 40.1709 ++ 40.1710 ++void get_random_bytes(void *buf, int nbytes) { 40.1711 ++ 40.1712 ++ if (devurandom == 0) { 40.1713 ++ devurandom = open("/dev/urandom", O_RDONLY); 40.1714 ++ } 40.1715 ++ 40.1716 ++ if (read(devurandom, buf, nbytes) != nbytes) { 40.1717 ++ printf("Can't get random number.\n"); 40.1718 ++ exit(-1); 40.1719 ++ } 40.1720 ++} 40.1721 ++ 40.1722 ++uint64_t tpm_get_ticks(void) 40.1723 ++{ 40.1724 ++ //struct timeval tv; 40.1725 ++ //int gettimeofday(&tv, struct timezone *tz); 40.1726 ++ return 0; 40.1727 ++} 40.1728 ++ 40.1729 ++int main(int argc, char **argv) 40.1730 ++{ 40.1731 ++ uint8_t in[BUFFER_SIZE], *out; 40.1732 ++ uint32_t out_size; 40.1733 ++ int in_size, written; 40.1734 ++ int i; 40.1735 ++ 40.1736 ++ int tpm_tx_fh=-1, tpm_rx_fh=-1; 40.1737 ++ if (argc < 2) { 40.1738 ++ printf("Usage: tpmd clear|save|deactivated\n" ); 40.1739 ++ return -1; 40.1740 ++ } 40.1741 ++ 40.1742 ++ /* initialize TPM emulator */ 40.1743 ++ if (!strcmp(argv[1], "clear")) { 40.1744 ++ printf("Initializing tpm: %s\n", argv[1]); 40.1745 ++ tpm_emulator_init(1); 40.1746 ++ } else if (!strcmp(argv[1], "save")) { 40.1747 ++ printf("Initializing tpm: %s\n", argv[1]); 40.1748 ++ tpm_emulator_init(2); 40.1749 ++ } else if (!strcmp(argv[1], "deactivated")) { 40.1750 ++ printf("Initializing tpm: %s\n", argv[1]); 40.1751 ++ tpm_emulator_init(3); 40.1752 ++ } else { 40.1753 ++ printf("invalid startup mode '%s'; must be 'clear', " 40.1754 ++ "'save' (default) or 'deactivated", argv[1]); 40.1755 ++ return -1; 40.1756 ++ } 40.1757 ++ 40.1758 ++ while (1) { 40.1759 ++abort_command: 40.1760 ++ if (tpm_rx_fh < 0) { 40.1761 ++ tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY); 40.1762 ++ } 40.1763 ++ 40.1764 ++ if (tpm_rx_fh < 0) { 40.1765 ++ printf("ERROR: failed to open devices to listen to guest.\n"); 40.1766 ++ return -1; 40.1767 ++ } 40.1768 ++ 40.1769 ++ if (tpm_tx_fh < 0) { 40.1770 ++ tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY); 40.1771 + } 40.1772 + 40.1773 - tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE; 40.1774 - } 40.1775 - /* set tick type */ 40.1776 ++ if (tpm_tx_fh < 0) { 40.1777 ++ printf("ERROR: failed to open devices to respond to guest.\n"); 40.1778 ++ return -1; 40.1779 ++ } 40.1780 ++ 40.1781 ++ in_size = read(tpm_rx_fh, in, BUFFER_SIZE); 40.1782 ++ if (in_size < 6) { // Magic size of minium TPM command 40.1783 ++ printf("Recv[%d] to small: 0x", in_size); 40.1784 ++ if (in_size <= 0) { 40.1785 ++ close(tpm_rx_fh); 40.1786 ++ tpm_rx_fh = -1; 40.1787 ++ goto abort_command; 40.1788 ++ } 40.1789 ++ } else { 40.1790 ++ printf("Recv[%d]: 0x", in_size); 40.1791 ++ for (i=0; i< in_size; i++) 40.1792 ++ printf("%x ", in[i]); 40.1793 ++ printf("\n"); 40.1794 ++ } 40.1795 ++ 40.1796 ++ 40.1797 ++ if (tpm_handle_command(in, in_size, &out, &out_size) != 0) { 40.1798 ++ printf("ERROR: Handler Failed.\n"); 40.1799 ++ } 40.1800 ++ 40.1801 ++ written = write(tpm_tx_fh, out, out_size); 40.1802 ++ 40.1803 ++ if (written != out_size ) { 40.1804 ++ printf("ERROR: Part of response not written %d/%d.\nAttempt: ", written, out_size); 40.1805 ++ } else { 40.1806 ++ printf("Sent[%Zu]: ", out_size); 40.1807 ++ } 40.1808 ++ for (i=0; i< out_size; i++) 40.1809 ++ printf("%x ", out[i]); 40.1810 ++ printf("\n"); 40.1811 ++ tpm_free(out); 40.1812 ++ 40.1813 ++ } // loop 40.1814 ++ 40.1815 ++ tpm_emulator_shutdown(); 40.1816 ++ 40.1817 ++ close(tpm_tx_fh); 40.1818 ++ close(tpm_rx_fh); 40.1819 ++ 40.1820 ++}
41.1 --- a/tools/vtpm/vtpm.patch Wed Jun 28 07:51:52 2006 -0600 41.2 +++ b/tools/vtpm/vtpm.patch Wed Jun 28 07:52:21 2006 -0600 41.3 @@ -1,13 +1,13 @@ 41.4 -diff -uprN orig/tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS 41.5 ---- orig/tpm_emulator-0.3-x86_64/AUTHORS 2006-01-10 04:21:45.000000000 -0800 41.6 -+++ vtpm/AUTHORS 2006-05-30 12:23:26.000000000 -0700 41.7 +diff -uprN tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS 41.8 +--- tpm_emulator-0.3-x86_64/AUTHORS 2006-08-29 15:07:21.618299064 -0700 41.9 ++++ vtpm/AUTHORS 2006-08-29 15:12:07.184886344 -0700 41.10 @@ -1,2 +1,3 @@ 41.11 Mario Strasser <mast@gmx.net> 41.12 Heiko Stamer <stamer@gaos.org> [DAA] 41.13 +INTEL Corp <> [VTPM Extensions] 41.14 -diff -uprN orig/tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog 41.15 ---- orig/tpm_emulator-0.3-x86_64/ChangeLog 2006-01-10 04:21:45.000000000 -0800 41.16 -+++ vtpm/ChangeLog 2006-05-30 12:23:26.000000000 -0700 41.17 +diff -uprN tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog 41.18 +--- tpm_emulator-0.3-x86_64/ChangeLog 2006-08-29 15:07:21.618299064 -0700 41.19 ++++ vtpm/ChangeLog 2006-08-29 15:12:07.185886192 -0700 41.20 @@ -1,3 +1,7 @@ 41.21 +2005-08-16 Intel Corp 41.22 + * Moved module out of kernel to run as a ring 3 app 41.23 @@ -16,9 +16,117 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.24 2005-12-24 Mario Strasser <mast@gmx.net> 41.25 * tpm_transport.c, tpm_marshalling.c, tpm_structures.h: 41.26 Transport session functionality added 41.27 -diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c 41.28 ---- orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-05-30 12:28:02.000000000 -0700 41.29 -+++ vtpm/crypto/gmp_kernel_wrapper.c 2006-05-30 12:23:26.000000000 -0700 41.30 +diff -uprN tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile 41.31 +--- tpm_emulator-0.3-x86_64/Makefile 2006-08-29 15:08:20.532342768 -0700 41.32 ++++ vtpm/Makefile 2006-08-29 15:13:53.023796384 -0700 41.33 +@@ -1,22 +1,31 @@ 41.34 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.35 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net> 41.36 ++# Copyright (C) 2006 INTEL Corp. 41.37 + # 41.38 + # $Id: Makefile 69 2005-12-13 12:55:52Z mast $ 41.39 + 41.40 +-# kernel settings 41.41 +-KERNEL_RELEASE := $(shell uname -r) 41.42 +-KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build 41.43 +-MOD_SUBDIR := misc 41.44 + COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) 41.45 + 41.46 + # module settings 41.47 +-MODULE_NAME := tpm_emulator 41.48 ++BIN := vtpmd 41.49 + VERSION_MAJOR := 0 41.50 + VERSION_MINOR := 3 41.51 + VERSION_BUILD := $(shell date +"%s") 41.52 + 41.53 +-# enable/disable DEBUG messages 41.54 +-EXTRA_CFLAGS += -Wall -DDEBUG -g 41.55 ++# Installation program and options 41.56 ++INSTALL = install 41.57 ++INSTALL_PROG = $(INSTALL) -m0755 41.58 ++INSTALL_DIR = $(INSTALL) -d -m0755 41.59 ++ 41.60 ++# Xen tools installation directory 41.61 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin 41.62 ++ 41.63 ++CC := gcc 41.64 ++CFLAGS += -g -Wall $(INCLUDE) -DDEBUG 41.65 ++CFLAGS += -I. -Itpm -I../../vtpm_manager/manager 41.66 ++ 41.67 ++# Is the simulator running in it's own vm? 41.68 ++#CFLAGS += -DVTPM_MULTI_VM 41.69 + 41.70 + ifeq ($(COMPILE_ARCH),x86_64) 41.71 + LIBDIR = lib64 41.72 +@@ -34,38 +43,31 @@ DIRS := . crypto tpm 41.73 + SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c)) 41.74 + OBJS := $(patsubst %.c, %.o, $(SRCS)) 41.75 + SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h)) 41.76 +-DISTSRC := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS) 41.77 +-DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR) 41.78 + 41.79 +-obj-m := $(MODULE_NAME).o 41.80 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a 41.81 ++obj-m := $(BIN) 41.82 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a 41.83 + 41.84 + EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm 41.85 + 41.86 + # do not print "Entering directory ..." 41.87 + MAKEFLAGS += --no-print-directory 41.88 + 41.89 +-all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version 41.90 +- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules 41.91 ++all: $(BIN) 41.92 ++ 41.93 ++$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS) 41.94 ++ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN) 41.95 ++ 41.96 ++%.o: %.c 41.97 ++ $(CC) $(CFLAGS) -c $< -o $@ 41.98 + 41.99 +-install: 41.100 +- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install 41.101 +- test -d /var/tpm || mkdir /var/tpm 41.102 +- test -c /dev/tpm || mknod /dev/tpm c 10 224 41.103 +- chmod 666 /dev/tpm 41.104 +- depmod -a 41.105 ++install: $(BIN) 41.106 ++ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR) 41.107 + 41.108 + clean: 41.109 +- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean 41.110 +- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a 41.111 ++ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS) 41.112 + 41.113 +-dist: $(DISTSRC) 41.114 +- rm -rf $(DISTDIR) 41.115 +- mkdir $(DISTDIR) 41.116 +- cp --parents $(DISTSRC) $(DISTDIR)/ 41.117 +- rm -f $(DISTDIR)/crypto/gmp.h 41.118 +- tar -chzf $(DISTDIR).tar.gz $(DISTDIR) 41.119 +- rm -rf $(DISTDIR) 41.120 ++mrproper: clean 41.121 ++ rm -f $(BIN) tpm_version.h 41.122 + 41.123 + $(src)/crypto/libgmp.a: 41.124 + test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a 41.125 +diff -uprN tpm_emulator-0.3-x86_64/README vtpm/README 41.126 +--- tpm_emulator-0.3-x86_64/README 2006-08-29 15:07:43.530967832 -0700 41.127 ++++ vtpm/README 2006-08-29 15:12:07.190885432 -0700 41.128 +@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast 41.129 + Copyright 41.130 + -------------------------------------------------------------------------- 41.131 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 41.132 +-Institute of Technology (ETH) Zurich. 41.133 ++ Institute of Technology (ETH) Zurich. 41.134 ++Copyright (C) 2005 INTEL Corp 41.135 + 41.136 + This program is free software; you can redistribute it and/or modify 41.137 + it under the terms of the GNU General Public License as published by 41.138 +diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c 41.139 +--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 2006-08-29 15:07:43.525968592 -0700 41.140 ++++ vtpm/crypto/gmp_kernel_wrapper.c 2006-08-29 15:12:07.186886040 -0700 41.141 @@ -1,5 +1,6 @@ 41.142 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.143 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.144 @@ -78,9 +186,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.145 } 41.146 } 41.147 41.148 -diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c 41.149 ---- orig/tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-01-10 04:21:45.000000000 -0800 41.150 -+++ vtpm/crypto/rsa.c 2006-05-30 12:23:26.000000000 -0700 41.151 +diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c 41.152 +--- tpm_emulator-0.3-x86_64/crypto/rsa.c 2006-08-29 15:07:21.618299064 -0700 41.153 ++++ vtpm/crypto/rsa.c 2006-08-29 15:12:07.187885888 -0700 41.154 @@ -1,5 +1,6 @@ 41.155 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.156 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.157 @@ -106,8 +214,8 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.158 sha1_final(&ctx, &msg[1]); 41.159 if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 41.160 SHA1_DIGEST_LENGTH) != 0) return -1; 41.161 -diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c 41.162 ---- orig/tpm_emulator-0.3-x86_64/linux_module.c 2006-05-30 12:28:02.000000000 -0700 41.163 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c 41.164 +--- tpm_emulator-0.3-x86_64/linux_module.c 2006-08-29 15:07:43.526968440 -0700 41.165 +++ vtpm/linux_module.c 1969-12-31 16:00:00.000000000 -0800 41.166 @@ -1,194 +0,0 @@ 41.167 -/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.168 @@ -304,9 +412,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.169 - return (ticks > 0) ? ticks : 1; 41.170 -} 41.171 - 41.172 -diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h 41.173 ---- orig/tpm_emulator-0.3-x86_64/linux_module.h 2006-05-30 12:28:02.000000000 -0700 41.174 -+++ vtpm/linux_module.h 2006-05-30 12:23:26.000000000 -0700 41.175 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h 41.176 +--- tpm_emulator-0.3-x86_64/linux_module.h 2006-08-29 15:07:43.527968288 -0700 41.177 ++++ vtpm/linux_module.h 2006-08-29 15:12:07.189885584 -0700 41.178 @@ -1,5 +1,6 @@ 41.179 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.180 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.181 @@ -406,116 +514,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.182 #define BE16_TO_CPU(x) __be16_to_cpu(x) 41.183 #define LE16_TO_CPU(x) __le16_to_cpu(x) 41.184 41.185 -diff -uprN orig/tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile 41.186 ---- orig/tpm_emulator-0.3-x86_64/Makefile 2006-05-30 12:28:02.000000000 -0700 41.187 -+++ vtpm/Makefile 2006-05-30 12:23:26.000000000 -0700 41.188 -@@ -1,22 +1,31 @@ 41.189 - # Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.190 - # Copyright (C) 2004 Mario Strasser <mast@gmx.net> 41.191 -+# Copyright (C) 2006 INTEL Corp. 41.192 - # 41.193 - # $Id: Makefile 69 2005-12-13 12:55:52Z mast $ 41.194 - 41.195 --# kernel settings 41.196 --KERNEL_RELEASE := $(shell uname -r) 41.197 --KERNEL_BUILD := /lib/modules/$(KERNEL_RELEASE)/build 41.198 --MOD_SUBDIR := misc 41.199 - COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) 41.200 - 41.201 - # module settings 41.202 --MODULE_NAME := tpm_emulator 41.203 -+BIN := vtpmd 41.204 - VERSION_MAJOR := 0 41.205 - VERSION_MINOR := 3 41.206 - VERSION_BUILD := $(shell date +"%s") 41.207 - 41.208 --# enable/disable DEBUG messages 41.209 --EXTRA_CFLAGS += -Wall -DDEBUG -g 41.210 -+# Installation program and options 41.211 -+INSTALL = install 41.212 -+INSTALL_PROG = $(INSTALL) -m0755 41.213 -+INSTALL_DIR = $(INSTALL) -d -m0755 41.214 -+ 41.215 -+# Xen tools installation directory 41.216 -+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin 41.217 -+ 41.218 -+CC := gcc 41.219 -+CFLAGS += -g -Wall $(INCLUDE) -DDEBUG 41.220 -+CFLAGS += -I. -Itpm -I../../vtpm_manager/manager 41.221 -+ 41.222 -+# Is the simulator running in it's own vm? 41.223 -+#CFLAGS += -DVTPM_MULTI_VM 41.224 - 41.225 - ifeq ($(COMPILE_ARCH),x86_64) 41.226 - LIBDIR = lib64 41.227 -@@ -34,38 +43,31 @@ DIRS := . crypto tpm 41.228 - SRCS := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c)) 41.229 - OBJS := $(patsubst %.c, %.o, $(SRCS)) 41.230 - SRCS += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h)) 41.231 --DISTSRC := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS) 41.232 --DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR) 41.233 - 41.234 --obj-m := $(MODULE_NAME).o 41.235 --$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a 41.236 -+obj-m := $(BIN) 41.237 -+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a 41.238 - 41.239 - EXTRA_CFLAGS += -I$(src) -I$(src)/crypto -I$(src)/tpm 41.240 - 41.241 - # do not print "Entering directory ..." 41.242 - MAKEFLAGS += --no-print-directory 41.243 - 41.244 --all: $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version 41.245 -- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules 41.246 -+all: $(BIN) 41.247 -+ 41.248 -+$(BIN): $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS) 41.249 -+ $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN) 41.250 -+ 41.251 -+%.o: %.c 41.252 -+ $(CC) $(CFLAGS) -c $< -o $@ 41.253 - 41.254 - install: 41.255 -- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install 41.256 -- test -d /var/tpm || mkdir /var/tpm 41.257 -- test -c /dev/tpm || mknod /dev/tpm c 10 224 41.258 -- chmod 666 /dev/tpm 41.259 -- depmod -a 41.260 -+ $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR) 41.261 - 41.262 - clean: 41.263 -- @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean 41.264 -- rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a 41.265 -+ rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS) 41.266 - 41.267 --dist: $(DISTSRC) 41.268 -- rm -rf $(DISTDIR) 41.269 -- mkdir $(DISTDIR) 41.270 -- cp --parents $(DISTSRC) $(DISTDIR)/ 41.271 -- rm -f $(DISTDIR)/crypto/gmp.h 41.272 -- tar -chzf $(DISTDIR).tar.gz $(DISTDIR) 41.273 -- rm -rf $(DISTDIR) 41.274 -+mrproper: clean 41.275 -+ rm -f $(BIN) tpm_version.h 41.276 - 41.277 - $(src)/crypto/libgmp.a: 41.278 - test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a 41.279 -diff -uprN orig/tpm_emulator-0.3-x86_64/README vtpm/README 41.280 ---- orig/tpm_emulator-0.3-x86_64/README 2006-05-30 12:28:02.000000000 -0700 41.281 -+++ vtpm/README 2006-05-30 12:23:26.000000000 -0700 41.282 -@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast 41.283 - Copyright 41.284 - -------------------------------------------------------------------------- 41.285 - Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 41.286 --Institute of Technology (ETH) Zurich. 41.287 -+ Institute of Technology (ETH) Zurich. 41.288 -+Copyright (C) 2005 INTEL Corp 41.289 - 41.290 - This program is free software; you can redistribute it and/or modify 41.291 - it under the terms of the GNU General Public License as published by 41.292 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c 41.293 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-01-10 04:21:45.000000000 -0800 41.294 -+++ vtpm/tpm/tpm_audit.c 2006-05-30 12:23:26.000000000 -0700 41.295 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c 41.296 +--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c 2006-08-29 15:07:21.620298760 -0700 41.297 ++++ vtpm/tpm/tpm_audit.c 2006-08-29 15:12:07.191885280 -0700 41.298 @@ -1,6 +1,7 @@ 41.299 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.300 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.301 @@ -578,9 +579,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.302 return TPM_SUCCESS; 41.303 } 41.304 - 41.305 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c 41.306 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-01-10 04:21:45.000000000 -0800 41.307 -+++ vtpm/tpm/tpm_authorization.c 2006-05-30 12:23:26.000000000 -0700 41.308 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c 41.309 +--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 2006-08-29 15:07:21.620298760 -0700 41.310 ++++ vtpm/tpm/tpm_authorization.c 2006-08-29 15:12:07.192885128 -0700 41.311 @@ -1,6 +1,7 @@ 41.312 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.313 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.314 @@ -598,9 +599,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.315 41.316 info("tpm_verify_auth(%08x)", auth->authHandle); 41.317 /* get dedicated authorization or transport session */ 41.318 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c 41.319 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-01-10 04:21:45.000000000 -0800 41.320 -+++ vtpm/tpm/tpm_capability.c 2006-05-30 12:23:26.000000000 -0700 41.321 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c 41.322 +--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 2006-08-29 15:07:21.620298760 -0700 41.323 ++++ vtpm/tpm/tpm_capability.c 2006-08-29 15:12:07.193884976 -0700 41.324 @@ -1,6 +1,7 @@ 41.325 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.326 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.327 @@ -623,9 +624,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.328 } 41.329 } 41.330 - 41.331 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c 41.332 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-01-10 04:21:45.000000000 -0800 41.333 -+++ vtpm/tpm/tpm_cmd_handler.c 2006-05-30 12:23:26.000000000 -0700 41.334 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c 41.335 +--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-08-29 15:07:21.621298608 -0700 41.336 ++++ vtpm/tpm/tpm_cmd_handler.c 2006-08-29 15:12:07.197884368 -0700 41.337 @@ -1,6 +1,7 @@ 41.338 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.339 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.340 @@ -683,9 +684,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.341 /* setup authorisation as well as response tag and size */ 41.342 memset(rsp, 0, sizeof(*rsp)); 41.343 switch (req->tag) { 41.344 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c 41.345 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-05-30 12:28:02.000000000 -0700 41.346 -+++ vtpm/tpm/tpm_crypto.c 2006-05-30 12:23:26.000000000 -0700 41.347 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c 41.348 +--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 2006-08-29 15:07:43.531967680 -0700 41.349 ++++ vtpm/tpm/tpm_crypto.c 2006-08-29 15:12:07.198884216 -0700 41.350 @@ -1,6 +1,7 @@ 41.351 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.352 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.353 @@ -708,9 +709,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.354 return TPM_SUCCESS; 41.355 } 41.356 - 41.357 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c 41.358 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-01-10 04:21:45.000000000 -0800 41.359 -+++ vtpm/tpm/tpm_daa.c 2006-05-30 12:23:26.000000000 -0700 41.360 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c 41.361 +--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-08-29 15:07:21.622298456 -0700 41.362 ++++ vtpm/tpm/tpm_daa.c 2006-08-29 15:12:07.203883456 -0700 41.363 @@ -700,14 +700,14 @@ info("tested until here"); 41.364 sizeof(session->DAA_tpmSpecific.DAA_rekey)); 41.365 sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 41.366 @@ -865,9 +866,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.367 sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH); 41.368 mpz_init(f), mpz_init(q); 41.369 mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch); 41.370 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c 41.371 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-05-30 12:28:02.000000000 -0700 41.372 -+++ vtpm/tpm/tpm_data.c 2006-05-30 12:23:26.000000000 -0700 41.373 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c 41.374 +--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c 2006-08-29 15:08:20.535342312 -0700 41.375 ++++ vtpm/tpm/tpm_data.c 2006-08-29 15:12:07.206883000 -0700 41.376 @@ -1,6 +1,7 @@ 41.377 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.378 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.379 @@ -1177,7 +1178,7 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.380 } 41.381 41.382 #else 41.383 -@@ -267,7 +462,6 @@ int tpm_restore_permanent_data(void) 41.384 +@@ -278,7 +473,6 @@ int tpm_restore_permanent_data(void) 41.385 41.386 int tpm_erase_permanent_data(void) 41.387 { 41.388 @@ -1186,9 +1187,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.389 return res; 41.390 } 41.391 - 41.392 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c 41.393 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-01-10 04:21:45.000000000 -0800 41.394 -+++ vtpm/tpm/tpm_deprecated.c 2006-05-30 12:23:26.000000000 -0700 41.395 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c 41.396 +--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 2006-08-29 15:07:21.622298456 -0700 41.397 ++++ vtpm/tpm/tpm_deprecated.c 2006-08-29 15:12:07.207882848 -0700 41.398 @@ -1,6 +1,7 @@ 41.399 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.400 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.401 @@ -1215,9 +1216,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.402 authContextSize, &contextBlob); 41.403 if (res != TPM_SUCCESS) return res; 41.404 len = *authContextSize; 41.405 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h 41.406 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-01-10 04:21:45.000000000 -0800 41.407 -+++ vtpm/tpm/tpm_emulator.h 2006-05-30 12:23:26.000000000 -0700 41.408 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h 41.409 +--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-08-29 15:07:21.648294504 -0700 41.410 ++++ vtpm/tpm/tpm_emulator.h 2006-08-29 15:12:07.208882696 -0700 41.411 @@ -1,5 +1,6 @@ 41.412 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.413 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.414 @@ -1235,9 +1236,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.415 #undef TPM_GENERATE_SEED_DAA 41.416 41.417 #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */ 41.418 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c 41.419 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-01-10 04:21:45.000000000 -0800 41.420 -+++ vtpm/tpm/tpm_integrity.c 2006-05-30 12:23:26.000000000 -0700 41.421 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c 41.422 +--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 2006-08-29 15:07:21.645294960 -0700 41.423 ++++ vtpm/tpm/tpm_integrity.c 2006-08-29 15:12:07.208882696 -0700 41.424 @@ -1,6 +1,7 @@ 41.425 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.426 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.427 @@ -1251,9 +1252,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.428 return TPM_SUCCESS; 41.429 } 41.430 - 41.431 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h 41.432 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-01-10 04:21:45.000000000 -0800 41.433 -+++ vtpm/tpm/tpm_structures.h 2006-05-30 12:23:26.000000000 -0700 41.434 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h 41.435 +--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 2006-08-29 15:08:20.545340792 -0700 41.436 ++++ vtpm/tpm/tpm_structures.h 2006-08-29 15:12:07.211882240 -0700 41.437 @@ -1,6 +1,7 @@ 41.438 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.439 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.440 @@ -1271,9 +1272,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.441 #include "crypto/rsa.h" 41.442 41.443 /* 41.444 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c 41.445 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-01-10 04:21:45.000000000 -0800 41.446 -+++ vtpm/tpm/tpm_testing.c 2006-05-30 12:23:26.000000000 -0700 41.447 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c 41.448 +--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 2006-08-29 15:07:21.646294808 -0700 41.449 ++++ vtpm/tpm/tpm_testing.c 2006-08-29 15:12:07.213881936 -0700 41.450 @@ -1,6 +1,7 @@ 41.451 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.452 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.453 @@ -1389,9 +1390,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.454 rsa_private_key_t priv_key; 41.455 rsa_public_key_t pub_key; 41.456 41.457 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c 41.458 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-01-10 04:21:45.000000000 -0800 41.459 -+++ vtpm/tpm/tpm_ticks.c 2006-05-30 12:23:26.000000000 -0700 41.460 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c 41.461 +--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c 2006-08-29 15:07:21.646294808 -0700 41.462 ++++ vtpm/tpm/tpm_ticks.c 2006-08-29 15:12:07.235878592 -0700 41.463 @@ -1,6 +1,7 @@ 41.464 /* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.465 * Copyright (C) 2004 Mario Strasser <mast@gmx.net>, 41.466 @@ -1474,9 +1475,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.467 } 41.468 41.469 41.470 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c 41.471 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-01-10 04:21:45.000000000 -0800 41.472 -+++ vtpm/tpm/tpm_transport.c 2006-05-30 12:23:26.000000000 -0700 41.473 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c 41.474 +--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 2006-08-29 15:07:21.647294656 -0700 41.475 ++++ vtpm/tpm/tpm_transport.c 2006-08-29 15:12:07.239877984 -0700 41.476 @@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE 41.477 static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20], 41.478 BYTE pubKeyHash[20], TPM_DIGEST *transDigest) 41.479 @@ -1534,9 +1535,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/ 41.480 memcpy(&buf[30], session->transInternal.transDigest.digest, 20); 41.481 /* sign info structure */ 41.482 res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize); 41.483 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c 41.484 ---- orig/tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800 41.485 -+++ vtpm/tpmd.c 2006-05-30 12:23:26.000000000 -0700 41.486 +diff -uprN tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c 41.487 +--- tpm_emulator-0.3-x86_64/tpmd.c 1969-12-31 16:00:00.000000000 -0800 41.488 ++++ vtpm/tpmd.c 2006-08-29 15:12:07.240877832 -0700 41.489 @@ -0,0 +1,207 @@ 41.490 +/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 41.491 + * Copyright (C) 2005 INTEL Corp
42.1 --- a/tools/vtpm_manager/Rules.mk Wed Jun 28 07:51:52 2006 -0600 42.2 +++ b/tools/vtpm_manager/Rules.mk Wed Jun 28 07:52:21 2006 -0600 42.3 @@ -56,6 +56,9 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT 42.4 # vtpm_manager listens on fifo's rather than backend 42.5 #CFLAGS += -DDUMMY_BACKEND 42.6 42.7 +# TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos 42.8 +#CFLAGS += -DDUMMY_TPM 42.9 + 42.10 # Do not have manager launch DMs. 42.11 #CFLAGS += -DMANUAL_DM_LAUNCH 42.12
43.1 --- a/tools/vtpm_manager/manager/dmictl.c Wed Jun 28 07:51:52 2006 -0600 43.2 +++ b/tools/vtpm_manager/manager/dmictl.c Wed Jun 28 07:52:21 2006 -0600 43.3 @@ -76,14 +76,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf 43.4 43.5 VTPM_DMI_RESOURCE *new_dmi=NULL; 43.6 TPM_RESULT status=TPM_FAIL; 43.7 - BYTE type; 43.8 - UINT32 dmi_id, domain_id, *dmi_id_key; 43.9 + BYTE type, startup_mode; 43.10 + UINT32 dmi_id, *dmi_id_key=NULL; 43.11 43.12 if (param_buf == NULL) { // Assume creation of Dom 0 control 43.13 - type = 0; 43.14 - domain_id = VTPM_CTL_DM; 43.15 + type = VTPM_TYPE_NON_MIGRATABLE; 43.16 dmi_id = VTPM_CTL_DM; 43.17 - } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) { 43.18 + } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(BYTE) + sizeof(UINT32)) { 43.19 vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", buffer_len(param_buf)); 43.20 status = TPM_BAD_PARAMETER; 43.21 goto abort_egress; 43.22 @@ -91,13 +90,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf 43.23 vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0 43.24 BSG_UnpackList( param_buf->bytes, 3, 43.25 BSG_TYPE_BYTE, &type, 43.26 - BSG_TYPE_UINT32, &domain_id, 43.27 + BSG_TYPE_BYTE, &startup_mode, 43.28 BSG_TYPE_UINT32, &dmi_id); 43.29 } 43.30 - 43.31 + 43.32 new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id); 43.33 if (new_dmi == NULL) { 43.34 - vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on domain %d.\n", dmi_id, domain_id); 43.35 + vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n", dmi_id ); 43.36 // Brand New DMI. Initialize the persistent pieces 43.37 if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) == NULL) { 43.38 status = TPM_RESOURCES; 43.39 @@ -106,32 +105,44 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf 43.40 memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE)); 43.41 new_dmi->dmi_id = dmi_id; 43.42 new_dmi->connected = FALSE; 43.43 + 43.44 + if (type != VTPM_TYPE_MIGRATED) { 43.45 + new_dmi->dmi_type = type; 43.46 + } else { 43.47 + vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n"); 43.48 + status = TPM_BAD_PARAMETER; 43.49 + goto free_egress; 43.50 + } 43.51 43.52 if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) { 43.53 status = TPM_RESOURCES; 43.54 - goto abort_egress; 43.55 + goto free_egress; 43.56 } 43.57 *dmi_id_key = new_dmi->dmi_id; 43.58 43.59 // install into map 43.60 if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){ 43.61 - free(new_dmi); 43.62 - free(dmi_id_key); 43.63 + vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance into table. Aborting.\n", dmi_id); 43.64 status = TPM_FAIL; 43.65 - goto egress; 43.66 + goto free_egress; 43.67 } 43.68 43.69 } else 43.70 - vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d .\n", dmi_id, domain_id); 43.71 + vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id); 43.72 43.73 if (new_dmi->connected) { 43.74 vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached instance %d. Ignoring\n", dmi_id); 43.75 status = TPM_BAD_PARAMETER; 43.76 - goto egress; 43.77 + goto abort_egress; 43.78 } 43.79 43.80 + if (type == VTPM_TYPE_MIGRATED) { 43.81 + vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach previously migrated instance %d without recovering first. Ignoring\n", dmi_id); 43.82 + status = TPM_BAD_PARAMETER; 43.83 + goto abort_egress; 43.84 + } 43.85 + 43.86 // Initialize the Non-persistent pieces 43.87 - new_dmi->dmi_domain_id = domain_id; 43.88 new_dmi->NVMLocation = NULL; 43.89 43.90 new_dmi->TCSContext = 0; 43.91 @@ -144,9 +155,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf 43.92 43.93 // Design specific new DMI code. 43.94 // Includes: create IPCs, Measuring DMI, and maybe launching DMI 43.95 - status = VTPM_New_DMI_Extra(new_dmi); 43.96 + status = VTPM_New_DMI_Extra(new_dmi, startup_mode); 43.97 goto egress; 43.98 43.99 + free_egress: // Error that requires freeing of newly allocated dmi 43.100 + free(new_dmi); 43.101 + free(dmi_id_key); 43.102 + 43.103 abort_egress: 43.104 vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. Cleaning.\n", dmi_id, tpm_get_error_name(status)); 43.105 close_dmi(new_dmi ); 43.106 @@ -221,7 +236,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const 43.107 goto abort_egress; 43.108 } 43.109 43.110 - //TODO: Automatically delete file dmi_res->NVMLocation 43.111 + //vtpm scripts delete file dmi_res->NVMLocation for us 43.112 43.113 // Close DMI first 43.114 TPMTRYRETURN(close_dmi( dmi_res ));
44.1 --- a/tools/vtpm_manager/manager/securestorage.c Wed Jun 28 07:51:52 2006 -0600 44.2 +++ b/tools/vtpm_manager/manager/securestorage.c Wed Jun 28 07:52:21 2006 -0600 44.3 @@ -190,8 +190,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI 44.4 long bytes_written; 44.5 buffer_t sealed_NVM; 44.6 44.7 - 44.8 - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf)); 44.9 + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf)); 44.10 44.11 TPMTRYRETURN( envelope_encrypt(inbuf, 44.12 &vtpm_globals->storageKey, 44.13 @@ -310,6 +309,7 @@ TPM_RESULT VTPM_SaveManagerData(void) { 44.14 UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap); 44.15 struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes}; 44.16 struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes}; 44.17 + BYTE vtpm_manager_gen = VTPM_MANAGER_GEN; 44.18 44.19 struct hashtable_itr *dmi_itr; 44.20 VTPM_DMI_RESOURCE *dmi_res; 44.21 @@ -321,7 +321,8 @@ TPM_RESULT VTPM_SaveManagerData(void) { 44.22 boot_key_size = sizeof(UINT32) + // bootkeysize 44.23 bootKeySize; // boot key 44.24 44.25 - TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths 44.26 + TPMTRYRETURN(buffer_init(&clear_flat_global,sizeof(BYTE) + // manager version 44.27 + 3*sizeof(TPM_DIGEST) + // Auths 44.28 sizeof(UINT32) +// storagekeysize 44.29 storageKeySize, NULL) ); // storage key 44.30 44.31 @@ -332,7 +333,8 @@ TPM_RESULT VTPM_SaveManagerData(void) { 44.32 boot_key_size = BSG_PackList(flat_boot_key, 1, 44.33 BSG_TPM_SIZE32_DATA, &boot_key_pack); 44.34 44.35 - BSG_PackList(clear_flat_global.bytes, 3, 44.36 + BSG_PackList(clear_flat_global.bytes, 4, 44.37 + BSG_TYPE_BYTE, &vtpm_manager_gen, 44.38 BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth, 44.39 BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, 44.40 BSG_TPM_SIZE32_DATA, &storage_key_pack); 44.41 @@ -348,7 +350,7 @@ TPM_RESULT VTPM_SaveManagerData(void) { 44.42 44.43 flat_dmis = (BYTE *) malloc( 44.44 (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0) 44.45 - (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info 44.46 + (sizeof(UINT32) +sizeof(BYTE) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info 44.47 44.48 dmi_itr = hashtable_iterator(vtpm_globals->dmi_map); 44.49 do { 44.50 @@ -360,8 +362,9 @@ TPM_RESULT VTPM_SaveManagerData(void) { 44.51 continue; 44.52 44.53 44.54 - flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3, 44.55 + flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 4, 44.56 BSG_TYPE_UINT32, &dmi_res->dmi_id, 44.57 + BSG_TYPE_BYTE, &dmi_res->dmi_type, 44.58 BSG_TPM_DIGEST, &dmi_res->NVM_measurement, 44.59 BSG_TPM_DIGEST, &dmi_res->DMI_measurement); 44.60 44.61 @@ -408,6 +411,7 @@ TPM_RESULT VTPM_LoadManagerData(void) { 44.62 buffer_t unsealed_data; 44.63 struct pack_buf_t storage_key_pack, boot_key_pack; 44.64 UINT32 *dmi_id_key, enc_size; 44.65 + BYTE vtpm_manager_gen; 44.66 44.67 VTPM_DMI_RESOURCE *dmi_res; 44.68 struct stat file_stat; 44.69 @@ -458,8 +462,14 @@ TPM_RESULT VTPM_LoadManagerData(void) { 44.70 &unsealed_data) ); 44.71 step_size += enc_size; 44.72 44.73 + if (*unsealed_data.bytes != VTPM_MANAGER_GEN) { 44.74 + // Once there is more than one gen, this will include some compatability stuff 44.75 + vtpmlogerror(VTPM_LOG_VTPM, "Warning: Manager Data file is gen %d, which this manager is gen %d.\n", vtpm_manager_gen, VTPM_MANAGER_GEN); 44.76 + } 44.77 + 44.78 // Global Values needing to be saved 44.79 - BSG_UnpackList( unsealed_data.bytes, 3, 44.80 + BSG_UnpackList( unsealed_data.bytes, 4, 44.81 + BSG_TYPE_BYTE, &vtpm_manager_gen, 44.82 BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth, 44.83 BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, 44.84 BSG_TPM_SIZE32_DATA, &storage_key_pack); 44.85 @@ -469,7 +479,7 @@ TPM_RESULT VTPM_LoadManagerData(void) { 44.86 44.87 // Per DMI values to be saved 44.88 while ( step_size < fh_size ){ 44.89 - if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) { 44.90 + if (fh_size - step_size < (long) (sizeof(UINT32) + sizeof(BYTE) + 2*sizeof(TPM_DIGEST))) { 44.91 vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of manager state.\n", fh_size-step_size); 44.92 step_size = fh_size; 44.93 } else { 44.94 @@ -478,8 +488,9 @@ TPM_RESULT VTPM_LoadManagerData(void) { 44.95 44.96 dmi_res->connected = FALSE; 44.97 44.98 - step_size += BSG_UnpackList(flat_table + step_size, 3, 44.99 + step_size += BSG_UnpackList(flat_table + step_size, 4, 44.100 BSG_TYPE_UINT32, &dmi_res->dmi_id, 44.101 + BSG_TYPE_BYTE, &dmi_res->dmi_type, 44.102 BSG_TPM_DIGEST, &dmi_res->NVM_measurement, 44.103 BSG_TPM_DIGEST, &dmi_res->DMI_measurement); 44.104
45.1 --- a/tools/vtpm_manager/manager/vtpm_manager.c Wed Jun 28 07:51:52 2006 -0600 45.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.c Wed Jun 28 07:52:21 2006 -0600 45.3 @@ -92,8 +92,9 @@ TPM_RESULT VTPM_Create_Manager(){ 45.4 status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo); 45.5 45.6 // If we can read PubEK then there is no owner and we should take it. 45.7 + // We use the abilty to read the pubEK to flag that the TPM is owned. 45.8 + // FIXME: Change to just trying to take ownership and react to the status 45.9 if (status == TPM_SUCCESS) { 45.10 - vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n"); 45.11 TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle, 45.12 (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 45.13 &SRK_AUTH, 45.14 @@ -103,6 +104,8 @@ TPM_RESULT VTPM_Create_Manager(){ 45.15 TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle, 45.16 (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 45.17 &vtpm_globals->keyAuth)); 45.18 + } else { 45.19 + vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n"); 45.20 } 45.21 45.22 // Generate storage key's auth 45.23 @@ -165,7 +168,7 @@ TPM_RESULT VTPM_Create_Manager(){ 45.24 &vtpm_globals->bootKey, 45.25 TRUE ) ); 45.26 45.27 - printf("***************************** FIXME: SAVE NEW STATE *******\n"); 45.28 + TPMTRYRETURN( VTSP_SaveState(vtpm_globals->manager_tcs_handle) ); 45.29 goto egress; 45.30 45.31 abort_egress: 45.32 @@ -181,7 +184,7 @@ TPM_RESULT VTPM_Create_Manager(){ 45.33 TPM_RESULT VTPM_Init_Manager() { 45.34 TPM_RESULT status = TPM_FAIL, serviceStatus; 45.35 BYTE *randomsead; 45.36 - UINT32 randomsize; 45.37 + UINT32 randomsize=256; 45.38 45.39 if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){ 45.40 status = TPM_FAIL; 45.41 @@ -216,7 +219,7 @@ TPM_RESULT VTPM_Init_Manager() { 45.42 &vtpm_globals->keyAuth) ); 45.43 vtpm_globals->keyAuth.fContinueAuthSession = TRUE; 45.44 45.45 - // If failed, create new Manager. 45.46 + // If failed, create new Manager. 45.47 serviceStatus = VTPM_LoadManagerData(); 45.48 if (serviceStatus == TPM_IOERROR) { 45.49 vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
46.1 --- a/tools/vtpm_manager/manager/vtpm_manager.h Wed Jun 28 07:51:52 2006 -0600 46.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.h Wed Jun 28 07:52:21 2006 -0600 46.3 @@ -73,6 +73,12 @@ 46.4 #define VTPM_RESTORE_CONTEXT_FAILED 4 46.5 #define VTPM_INVALID_REQUEST 5 46.6 46.7 +//*********************** Parameter Values ************************* 46.8 +#define VTPM_TYPE_NON_MIGRATABLE 0x00 46.9 +#define VTPM_TYPE_MIGRATABLE 0x01 46.10 +#define VTPM_TYPE_MIGRATED 0xFF // VTPM has been migrated. 46.11 + // VTPM can be recovered or deleted only 46.12 + 46.13 /******************* Command Parameter API ************************* 46.14 46.15 VTPM Command Format 46.16 @@ -94,8 +100,8 @@ VTPM Response Format 46.17 46.18 VTPM_Open: 46.19 Input Parameters: 46.20 - Domain_type: 1 byte 46.21 - domain_id: 4 bytes 46.22 + Domain_type: 1 byte 46.23 + startup_mode: 1 byte // Cold Boot = 1, resume = 2, deactive = 3 46.24 instance_id: 4 bytes 46.25 Output Parameters: 46.26 None
47.1 --- a/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed Jun 28 07:51:52 2006 -0600 47.2 +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed Jun 28 07:52:21 2006 -0600 47.3 @@ -78,13 +78,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.4 BOOL is_priv, 47.5 char *thread_name) { 47.6 TPM_RESULT status = TPM_FAIL; // Should never return 47.7 - UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full; 47.8 - BYTE *cmd_header, *in_param, *out_message; 47.9 + UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size; 47.10 + BYTE *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply; 47.11 buffer_t *command_buf=NULL, *result_buf=NULL; 47.12 TPM_TAG tag; 47.13 TPM_COMMAND_CODE ord; 47.14 VTPM_DMI_RESOURCE *dmi_res; 47.15 int size_read, size_write, i; 47.16 + BOOL add_header=TRUE; // This indicates to prepend a header on result_buf before sending 47.17 47.18 cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV); 47.19 command_buf = (buffer_t *) malloc(sizeof(buffer_t)); 47.20 @@ -100,7 +101,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.21 // Read command header 47.22 size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); 47.23 if (size_read > 0) { 47.24 - vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read); 47.25 + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d]: 0x", size_read); 47.26 for (i=0; i<size_read; i++) 47.27 vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); 47.28 } else { 47.29 @@ -165,6 +166,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.30 (!dmi_res->connected) ) { 47.31 vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or disconnected DMI %d. Aborting...\n", dmi); 47.32 status = TPM_BAD_PARAMETER; 47.33 + goto abort_with_error; 47.34 } 47.35 47.36 if (tag == VTPM_TAG_REQ) { 47.37 @@ -176,9 +178,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.38 status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name); 47.39 47.40 // This means calling the DMI failed, not that the cmd failed in the DMI 47.41 + // Since the return will be interpretted by a TPM app, all errors are IO_ERRORs to the app 47.42 if (status != TPM_SUCCESS) { 47.43 + status = TPM_IOERROR; 47.44 goto abort_with_error; 47.45 } 47.46 + // Unlike all other commands, forwarded commands yield a result_buf that includes the DMI's status. This 47.47 + // should be forwarded to the caller VM 47.48 + add_header = FALSE; 47.49 } else { 47.50 // We are not supposed to forward TPM commands at all. 47.51 int i; 47.52 @@ -205,38 +212,43 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.53 #ifndef VTPM_MULTI_VM 47.54 abort_with_error: 47.55 #endif 47.56 - 47.57 - // Prepend VTPM header with destination DM stamped 47.58 - out_param_size = buffer_len(result_buf); 47.59 - out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; 47.60 - out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; 47.61 - out_message = (BYTE *) malloc (out_message_size_full); 47.62 + 47.63 + if (add_header) { 47.64 + // Prepend VTPM header with destination DM stamped 47.65 + out_param_size = buffer_len(result_buf); 47.66 + out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size; 47.67 + reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size; 47.68 + out_message = (BYTE *) malloc (reply_size); 47.69 + reply = out_message; 47.70 47.71 - BSG_PackList(out_message, 4, 47.72 - BSG_TYPE_UINT32, (BYTE *) &dmi, 47.73 - BSG_TPM_TAG, (BYTE *) &tag, 47.74 - BSG_TYPE_UINT32, (BYTE *) &out_message_size, 47.75 - BSG_TPM_RESULT, (BYTE *) &status); 47.76 + BSG_PackList(out_message, 4, 47.77 + BSG_TYPE_UINT32, (BYTE *) &dmi, 47.78 + BSG_TPM_TAG, (BYTE *) &tag, 47.79 + BSG_TYPE_UINT32, (BYTE *) &out_message_size, 47.80 + BSG_TPM_RESULT, (BYTE *) &status); 47.81 47.82 - if (buffer_len(result_buf) > 0) 47.83 - memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); 47.84 - 47.85 - //Note: Send message + dmi_id 47.86 - size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_vtpm_ipc_h, out_message, out_message_size_full ); 47.87 + if (buffer_len(result_buf) > 0) 47.88 + memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size); 47.89 + //Note: Send message + dmi_id 47.90 + } else { 47.91 + reply = result_buf->bytes; 47.92 + reply_size = buffer_len(result_buf); 47.93 + } 47.94 + size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size ); 47.95 if (size_write > 0) { 47.96 vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x"); 47.97 - for (i=0; i < out_message_size_full; i++) 47.98 - vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]); 47.99 + for (i=0; i < reply_size; i++) 47.100 + vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", reply[i]); 47.101 47.102 vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); 47.103 } else { 47.104 vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name); 47.105 goto abort_command; 47.106 } 47.107 - free(out_message); 47.108 + free(out_message); out_message=NULL; 47.109 47.110 - if (size_write < (int)out_message_size_full) { 47.111 - vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, out_message_size_full); 47.112 + if (size_write < (int)reply_size) { 47.113 + vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, reply_size); 47.114 goto abort_command; 47.115 } 47.116 47.117 @@ -246,9 +258,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.118 //free buffers 47.119 bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV); 47.120 //free(in_param); // This was converted to command_buf. No need to free 47.121 - if (command_buf != result_buf) 47.122 - buffer_free(result_buf); 47.123 - 47.124 + buffer_free(result_buf); 47.125 buffer_free(command_buf); 47.126 47.127 // If we have a write lock, save the manager table 47.128 @@ -258,6 +268,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip 47.129 } 47.130 47.131 vtpm_lock_unlock(); 47.132 + add_header = TRUE; // Reset to the default 47.133 } // End while(1) 47.134 47.135 } 47.136 @@ -369,6 +380,7 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v 47.137 dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV; 47.138 size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV ); 47.139 if (size_write > 0) { 47.140 + vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x"); 47.141 for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) 47.142 vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]); 47.143 47.144 @@ -438,7 +450,8 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v 47.145 vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n"); 47.146 } 47.147 47.148 - if (buffer_init_convert(result_buf, adj_param_size, in_param) != TPM_SUCCESS) { 47.149 + if ( (buffer_init(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, cmd_header) != TPM_SUCCESS) || 47.150 + (buffer_append_raw(result_buf, adj_param_size, in_param) != TPM_SUCCESS) ) { 47.151 vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n"); 47.152 status = TPM_FAIL; 47.153 goto abort_with_error;
48.1 --- a/tools/vtpm_manager/manager/vtpmd.c Wed Jun 28 07:51:52 2006 -0600 48.2 +++ b/tools/vtpm_manager/manager/vtpmd.c Wed Jun 28 07:52:21 2006 -0600 48.3 @@ -64,14 +64,6 @@ 48.4 #define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo" 48.5 #define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo" 48.6 48.7 - 48.8 -#define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo" 48.9 -#define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo" 48.10 - 48.11 -#define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm-to-%d.fifo" 48.12 -#define VTPM_RX_FIFO "/var/vtpm/fifos/vtpm-from-all.fifo" 48.13 - 48.14 - 48.15 struct vtpm_thread_params_s { 48.16 vtpm_ipc_handle_t *tx_ipc_h; 48.17 vtpm_ipc_handle_t *rx_ipc_h; 48.18 @@ -113,7 +105,7 @@ void signal_handler(int reason) { 48.19 48.20 struct sigaction ctl_c_handler; 48.21 48.22 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) { 48.23 +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode) { 48.24 48.25 TPM_RESULT status = TPM_SUCCESS; 48.26 int fh; 48.27 @@ -150,14 +142,14 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R 48.28 48.29 // Measure DMI 48.30 // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value 48.31 - // Also, this mechanism is specific to 1 VM. 48.32 + // Also, this mechanism is specific to 1 VM architecture. 48.33 /* 48.34 fh = open(TPM_EMULATOR_PATH, O_RDONLY); 48.35 stat_ret = fstat(fh, &file_stat); 48.36 if (stat_ret == 0) 48.37 dmi_size = file_stat.st_size; 48.38 else { 48.39 - vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n"); 48.40 + vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n"); 48.41 status = TPM_IOERROR; 48.42 goto abort_egress; 48.43 } 48.44 @@ -179,10 +171,20 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R 48.45 status = TPM_RESOURCES; 48.46 goto abort_egress; 48.47 } else if (pid == 0) { 48.48 - if ( stat(dmi_res->NVMLocation, &file_info) == -1) 48.49 + switch (startup_mode) { 48.50 + case TPM_ST_CLEAR: 48.51 execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL); 48.52 - else 48.53 + break; 48.54 + case TPM_ST_STATE: 48.55 execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL); 48.56 + break; 48.57 + case TPM_ST_DEACTIVATED: 48.58 + execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", dmi_id_str, NULL); 48.59 + break; 48.60 + default: 48.61 + status = TPM_BAD_PARAMETER; 48.62 + goto abort_egress; 48.63 + } 48.64 48.65 // Returning from these at all is an error. 48.66 vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n"); 48.67 @@ -309,7 +311,7 @@ int main(int argc, char **argv) { 48.68 be_thread_params.fw_tpm = TRUE; 48.69 be_thread_params.fw_tx_ipc_h = NULL; 48.70 be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h; 48.71 - be_thread_params.is_priv = TRUE; //FIXME: Change when HP is up 48.72 + be_thread_params.is_priv = FALSE; 48.73 be_thread_params.thread_name = "Backend Listener"; 48.74 48.75 dmi_thread_params.tx_ipc_h = NULL; 48.76 @@ -318,7 +320,7 @@ int main(int argc, char **argv) { 48.77 dmi_thread_params.fw_tx_ipc_h = NULL; 48.78 dmi_thread_params.fw_rx_ipc_h = NULL; 48.79 dmi_thread_params.is_priv = FALSE; 48.80 - dmi_thread_params.thread_name = "VTPM Listeners"; 48.81 + dmi_thread_params.thread_name = "VTPM Listener"; 48.82 48.83 hp_thread_params.tx_ipc_h = &tx_hp_ipc_h; 48.84 hp_thread_params.rx_ipc_h = &rx_hp_ipc_h; 48.85 @@ -345,10 +347,10 @@ int main(int argc, char **argv) { 48.86 } 48.87 48.88 48.89 -// if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) { 48.90 -// vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n"); 48.91 -// exit(-1); 48.92 -// } 48.93 + if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) { 48.94 + vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n"); 48.95 + exit(-1); 48.96 + } 48.97 48.98 //Join the other threads until exit time. 48.99 pthread_join(be_thread, NULL);
49.1 --- a/tools/vtpm_manager/manager/vtpmpriv.h Wed Jun 28 07:51:52 2006 -0600 49.2 +++ b/tools/vtpm_manager/manager/vtpmpriv.h Wed Jun 28 07:52:21 2006 -0600 49.3 @@ -40,15 +40,19 @@ 49.4 #ifndef __VTPMPRIV_H__ 49.5 #define __VTPMPRIV_H__ 49.6 49.7 +#include "vtpm_manager.h" 49.8 #include "tcg.h" 49.9 #include "tcs.h" 49.10 #include "buffer.h" 49.11 #include "crypto.h" 49.12 #include "vtpm_ipc.h" 49.13 49.14 -#define STATE_FILE "/var/vtpm/VTPM" 49.15 -#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data" 49.16 -#define VTPM_CTL_DM 0 49.17 +#define VTPM_MANAGER_GEN 2 // This is incremented when the manager's table 49.18 + // is changed. It's used for backwards compatability 49.19 + 49.20 +#define STATE_FILE "/var/vtpm/VTPM" 49.21 +#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data" 49.22 +#define VTPM_CTL_DM 0 49.23 49.24 // ------------------------ Private Structures ----------------------- 49.25 typedef struct VTPM_DMI_RESOURCE_T { 49.26 @@ -70,6 +74,7 @@ typedef struct VTPM_DMI_RESOURCE_T { 49.27 // of NVM. 49.28 // Persistent Information about DMI 49.29 UINT32 dmi_id; 49.30 + BYTE dmi_type; 49.31 TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the blob 49.32 TPM_DIGEST DMI_measurement; // Correct measurement of the owning DMI 49.33 } VTPM_DMI_RESOURCE; 49.34 @@ -138,7 +143,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI(const 49.35 TPM_RESULT VTPM_SaveManagerData(void); 49.36 TPM_RESULT VTPM_LoadManagerData(void); 49.37 49.38 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res); 49.39 +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode); 49.40 49.41 TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res); 49.42
50.1 --- a/tools/vtpm_manager/manager/vtsp.c Wed Jun 28 07:51:52 2006 -0600 50.2 +++ b/tools/vtpm_manager/manager/vtsp.c Wed Jun 28 07:52:21 2006 -0600 50.3 @@ -971,6 +971,17 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT 50.4 return status; 50.5 } 50.6 50.7 +TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext) { 50.8 + 50.9 + vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n"); 50.10 + 50.11 + TPM_RESULT status = TPM_SUCCESS; 50.12 + 50.13 + // Call TCS 50.14 + return ( TCSP_SaveState ( hContext ) ); 50.15 + 50.16 +} 50.17 + 50.18 50.19 // Function Reaches into unsupported TCS command, beware. 50.20 TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext,
51.1 --- a/tools/vtpm_manager/manager/vtsp.h Wed Jun 28 07:51:52 2006 -0600 51.2 +++ b/tools/vtpm_manager/manager/vtsp.h Wed Jun 28 07:52:21 2006 -0600 51.3 @@ -118,4 +118,6 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT 51.4 TCS_AUTH *auth, 51.5 TCS_AUTH *dataAuth); 51.6 51.7 +TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext); 51.8 + 51.9 #endif //_VTSP_H_
52.1 --- a/tools/vtpm_manager/tcs/tcs.c Wed Jun 28 07:51:52 2006 -0600 52.2 +++ b/tools/vtpm_manager/tcs/tcs.c Wed Jun 28 07:52:21 2006 -0600 52.3 @@ -1126,6 +1126,49 @@ TPM_RESULT TCSP_ReadPubek(TCS_CONTEXT_HA 52.4 return(returnCode); 52.5 } 52.6 52.7 + 52.8 +TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE hContext) // in 52.9 +{ 52.10 + // setup input/output parameters block 52.11 + TPM_TAG tag = TPM_TAG_RQU_COMMAND; 52.12 + UINT32 paramSize = 0; 52.13 + TPM_COMMAND_CODE ordinal = TPM_ORD_SaveState; 52.14 + TPM_RESULT returnCode = TPM_SUCCESS; 52.15 + 52.16 + // setup the TPM driver input and output buffers 52.17 + TDDL_RESULT hRes = TDDL_E_FAIL; 52.18 + TDDL_UINT32 InLength = TCPA_MAX_BUFFER_LENGTH; 52.19 + TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH; 52.20 + 52.21 + // Convert Byte Input parameter in the input byte stream InBuf 52.22 + InLength = BSG_PackList(InBuf, 3, 52.23 + BSG_TPM_TAG, &tag, 52.24 + BSG_TYPE_UINT32, ¶mSize, 52.25 + BSG_TPM_COMMAND_CODE, &ordinal); 52.26 + // fill paramSize again as we now have the correct size 52.27 + BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2); 52.28 + 52.29 + vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength); 52.30 + 52.31 + // call the TPM driver 52.32 + if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == TDDL_SUCCESS) { 52.33 + // unpack OutBuf to get the tag, paramSize, & returnCode 52.34 + BSG_UnpackList(OutBuf, 3, 52.35 + BSG_TPM_TAG, &tag, 52.36 + BSG_TYPE_UINT32, ¶mSize, 52.37 + BSG_TPM_COMMAND_CODE, &returnCode); 52.38 + 52.39 + if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) { 52.40 + vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize); 52.41 + } else { 52.42 + vtpmlogerror(VTPM_LOG_TCS, "TCSP_SaveState Failed with return code %s\n", tpm_get_error_name(returnCode)); 52.43 + } 52.44 + } 52.45 + 52.46 + return(returnCode); 52.47 +} 52.48 + 52.49 + 52.50 TPM_RESULT TCSP_RawTransmitData( UINT32 inDataSize, // in 52.51 BYTE *inData, // in 52.52 UINT32 *outDataSize,// in/out
53.1 --- a/tools/vtpm_manager/tcs/tcs.h Wed Jun 28 07:51:52 2006 -0600 53.2 +++ b/tools/vtpm_manager/tcs/tcs.h Wed Jun 28 07:52:21 2006 -0600 53.3 @@ -229,7 +229,10 @@ TPM_RESULT TCSP_ReadPubek ( TCS_CONTEXT 53.4 ); 53.5 53.6 53.7 -// Non-Standard TCSP call to give direct access to TransmitData. 53.8 +// Non-Standard TCSP calls 53.9 +TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE hContext); // in 53.10 + 53.11 +//Give direct access to TransmitData. 53.12 // Key and Auth Management is done before transfering command to TDDL. 53.13 TPM_RESULT TCSP_RawTransmitData(UINT32 inDataSize, // in 53.14 BYTE *inData, // in
54.1 --- a/tools/vtpm_manager/tcs/transmit.c Wed Jun 28 07:51:52 2006 -0600 54.2 +++ b/tools/vtpm_manager/tcs/transmit.c Wed Jun 28 07:52:21 2006 -0600 54.3 @@ -43,7 +43,17 @@ 54.4 54.5 // flag to track whether TDDL has been opened 54.6 static int g_TDDL_open = 0; 54.7 -static int g_fd = -1; // the fd to the TPM 54.8 +static int g_tx_fd = -1; // the fd to the TPM 54.9 + 54.10 +#ifndef DUMMY_TPM 54.11 + #define TPM_TX_FNAME "/dev/tpm0" 54.12 + static int *g_rx_fdp = &g_tx_fd; 54.13 +#else 54.14 + #define TPM_TX_FNAME "/tmp/tpm_in.fifo" 54.15 + #define TPM_RX_FNAME "/tmp/tpm_out.fifo" 54.16 + static int g_rx_fd = -1; 54.17 + static int *g_rx_fdp = &g_rx_fd; // the fd to the TPM 54.18 +#endif 54.19 54.20 TPM_RESULT 54.21 TDDL_TransmitData( TDDL_BYTE* in, 54.22 @@ -60,10 +70,9 @@ TDDL_TransmitData( TDDL_BYTE* in, 54.23 vtpmloginfomore(VTPM_LOG_TXDATA, "\n"); 54.24 54.25 ssize_t size = 0; 54.26 - int fd = g_fd; 54.27 54.28 // send the request 54.29 - size = write (fd, in, insize); 54.30 + size = write (g_tx_fd, in, insize); 54.31 if (size < 0) { 54.32 vtpmlogerror(VTPM_LOG_TXDATA, "write() failed"); 54.33 ERRORDIE (TPM_IOERROR); 54.34 @@ -74,7 +83,7 @@ TDDL_TransmitData( TDDL_BYTE* in, 54.35 } 54.36 54.37 // read the response 54.38 - size = read (fd, out, TCPA_MAX_BUFFER_LENGTH); 54.39 + size = read (*g_rx_fdp, out, TCPA_MAX_BUFFER_LENGTH); 54.40 if (size < 0) { 54.41 vtpmlogerror(VTPM_LOG_TXDATA, "read() failed"); 54.42 ERRORDIE (TPM_IOERROR); 54.43 @@ -98,18 +107,20 @@ TDDL_TransmitData( TDDL_BYTE* in, 54.44 TPM_RESULT TDDL_Open() { 54.45 54.46 TDDL_RESULT status = TDDL_SUCCESS; 54.47 - int fd = -1; 54.48 54.49 if (g_TDDL_open) 54.50 return TPM_FAIL; 54.51 - 54.52 - fd = open ("/dev/tpm0", O_RDWR); 54.53 - if (fd < 0) { 54.54 + 54.55 +#ifdef DUMMY_TPM 54.56 + *g_rx_fdp = open (TPM_RX_FNAME, O_RDWR); 54.57 +#endif 54.58 + 54.59 + g_tx_fd = open (TPM_TX_FNAME, O_RDWR); 54.60 + if (g_tx_fd < 0) { 54.61 vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed"); 54.62 return TPM_IOERROR; 54.63 } 54.64 54.65 - g_fd = fd; 54.66 g_TDDL_open = 1; 54.67 54.68 return status; 54.69 @@ -119,13 +130,18 @@ void TDDL_Close() { 54.70 if (! g_TDDL_open) 54.71 return; 54.72 54.73 - if (g_fd>= 0) { 54.74 - if (close(g_fd) < 0) 54.75 + if (g_tx_fd>= 0) { 54.76 + if (close(g_tx_fd) < 0) 54.77 vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed"); 54.78 - 54.79 - g_fd = -1; 54.80 + g_tx_fd = -1; 54.81 } 54.82 54.83 + if (*g_rx_fdp>= 0) { 54.84 + if (close(*g_rx_fdp) < 0) 54.85 + vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed"); 54.86 + *g_rx_fdp = -1; 54.87 + } 54.88 + 54.89 g_TDDL_open = 0; 54.90 54.91 }
55.1 --- a/tools/vtpm_manager/util/tcg.h Wed Jun 28 07:51:52 2006 -0600 55.2 +++ b/tools/vtpm_manager/util/tcg.h Wed Jun 28 07:52:21 2006 -0600 55.3 @@ -389,6 +389,11 @@ typedef struct pack_constbuf_t { 55.4 #define TPM_DELEGATE_ADMIN TPM_BASE + 77 // Delegation table management not enabled 55.5 #define TPM_TRANSPORT_EXCLUSIVE TPM_BASE + 78 // There was a command executed outside of an exclusive transport session 55.6 55.7 +// TPM_STARTUP_TYPE values 55.8 +#define TPM_ST_CLEAR 0x0001 55.9 +#define TPM_ST_STATE 0x0002 55.10 +#define TPM_ST_DEACTIVATED 0x003 55.11 + 55.12 // TPM_TAG values 55.13 #define TPM_TAG_RQU_COMMAND 0x00c1 55.14 #define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
56.1 --- a/tools/xenstat/xentop/xentop.1 Wed Jun 28 07:51:52 2006 -0600 56.2 +++ b/tools/xenstat/xentop/xentop.1 Wed Jun 28 07:52:21 2006 -0600 56.3 @@ -25,6 +25,8 @@ 56.4 [\fB\-n\fR] 56.5 [\fB\-r\fR] 56.6 [\fB\-v\fR] 56.7 +[\fB\-b\fR] 56.8 +[\fB\-i\fRITERATIONS] 56.9 56.10 .SH DESCRIPTION 56.11 \fBxentop\fR displays information about the Xen system and domains, in a 56.12 @@ -50,6 +52,13 @@ repeat table header before each domain 56.13 .TP 56.14 \fB\-v\fR, \fB\-\-vcpus\fR 56.15 output VCPU data 56.16 +.TP 56.17 +\fB\-b\fR, \fB\-\-batch\fR 56.18 +output data in batch mode (to stdout) 56.19 +.TP 56.20 +\fB\-i\fR, \fB\-\-iterations\fR=\fIITERATIONS\fR 56.21 +maximum number of iterations xentop should produce before ending 56.22 + 56.23 56.24 .SH "INTERACTIVE COMMANDS" 56.25 All interactive commands are case-insensitive.
57.1 --- a/tools/xenstat/xentop/xentop.c Wed Jun 28 07:51:52 2006 -0600 57.2 +++ b/tools/xenstat/xentop/xentop.c Wed Jun 28 07:52:21 2006 -0600 57.3 @@ -153,6 +153,9 @@ xenstat_node *cur_node = NULL; 57.4 field_id sort_field = FIELD_DOMID; 57.5 unsigned int first_domain_index = 0; 57.6 unsigned int delay = 3; 57.7 +unsigned int batch = 0; 57.8 +unsigned int loop = 1; 57.9 +unsigned int iterations = 0; 57.10 int show_vcpus = 0; 57.11 int show_networks = 0; 57.12 int repeat_header = 0; 57.13 @@ -179,6 +182,8 @@ static void usage(const char *program) 57.14 "-n, --networks output vif network data\n" 57.15 "-r, --repeat-header repeat table header before each domain\n" 57.16 "-v, --vcpus output vcpu data\n" 57.17 + "-b, --batch output in batch mode, no user input accepted\n" 57.18 + "-i, --iterations number of iterations before exiting\n" 57.19 "\n" XENTOP_BUGSTO, 57.20 program); 57.21 return; 57.22 @@ -236,9 +241,15 @@ static void print(const char *fmt, ...) 57.23 { 57.24 va_list args; 57.25 57.26 - if(current_row() < lines()-1) { 57.27 + if (!batch) { 57.28 + if((current_row() < lines()-1)) { 57.29 + va_start(args, fmt); 57.30 + vw_printw(stdscr, fmt, args); 57.31 + va_end(args); 57.32 + } 57.33 + } else { 57.34 va_start(args, fmt); 57.35 - vw_printw(stdscr, fmt, args); 57.36 + vprintf(fmt, args); 57.37 va_end(args); 57.38 } 57.39 } 57.40 @@ -803,6 +814,7 @@ static void top(void) 57.41 do_network(domains[i]); 57.42 } 57.43 57.44 + if(!batch) 57.45 do_bottom_line(); 57.46 } 57.47 57.48 @@ -818,9 +830,11 @@ int main(int argc, char **argv) 57.49 { "repeat-header", no_argument, NULL, 'r' }, 57.50 { "vcpus", no_argument, NULL, 'v' }, 57.51 { "delay", required_argument, NULL, 'd' }, 57.52 + { "batch", no_argument, NULL, 'b' }, 57.53 + { "iterations", required_argument, NULL, 'i' }, 57.54 { 0, 0, 0, 0 }, 57.55 }; 57.56 - const char *sopts = "hVbnvd:"; 57.57 + const char *sopts = "hVbnvd:bi:"; 57.58 57.59 if (atexit(cleanup) != 0) 57.60 fail("Failed to install cleanup handler.\n"); 57.61 @@ -847,6 +861,13 @@ int main(int argc, char **argv) 57.62 case 'd': 57.63 delay = atoi(optarg); 57.64 break; 57.65 + case 'b': 57.66 + batch = 1; 57.67 + break; 57.68 + case 'i': 57.69 + iterations = atoi(optarg); 57.70 + loop = 0; 57.71 + break; 57.72 } 57.73 } 57.74 57.75 @@ -855,28 +876,41 @@ int main(int argc, char **argv) 57.76 if (xhandle == NULL) 57.77 fail("Failed to initialize xenstat library\n"); 57.78 57.79 - /* Begin curses stuff */ 57.80 - initscr(); 57.81 - start_color(); 57.82 - cbreak(); 57.83 - noecho(); 57.84 - nonl(); 57.85 - keypad(stdscr, TRUE); 57.86 - halfdelay(5); 57.87 - use_default_colors(); 57.88 - init_pair(1, -1, COLOR_YELLOW); 57.89 + if (!batch) { 57.90 + /* Begin curses stuff */ 57.91 + initscr(); 57.92 + start_color(); 57.93 + cbreak(); 57.94 + noecho(); 57.95 + nonl(); 57.96 + keypad(stdscr, TRUE); 57.97 + halfdelay(5); 57.98 + use_default_colors(); 57.99 + init_pair(1, -1, COLOR_YELLOW); 57.100 57.101 - do { 57.102 - gettimeofday(&curtime, NULL); 57.103 - if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) { 57.104 - clear(); 57.105 - top(); 57.106 - oldtime = curtime; 57.107 - refresh(); 57.108 - } 57.109 - ch = getch(); 57.110 - } while (handle_key(ch)); 57.111 - 57.112 + do { 57.113 + gettimeofday(&curtime, NULL); 57.114 + if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) { 57.115 + clear(); 57.116 + top(); 57.117 + oldtime = curtime; 57.118 + refresh(); 57.119 + if ((!loop) && !(--iterations)) 57.120 + break; 57.121 + } 57.122 + ch = getch(); 57.123 + } while (handle_key(ch)); 57.124 + } else { 57.125 + do { 57.126 + gettimeofday(&curtime, NULL); 57.127 + top(); 57.128 + oldtime = curtime; 57.129 + sleep(delay); 57.130 + if ((!loop) && !(--iterations)) 57.131 + break; 57.132 + } while (1); 57.133 + } 57.134 + 57.135 /* Cleanup occurs in cleanup(), so no work to do here. */ 57.136 57.137 return 0;
58.1 --- a/tools/xm-test/tests/info/02_info_compiledata_pos.py Wed Jun 28 07:51:52 2006 -0600 58.2 +++ b/tools/xm-test/tests/info/02_info_compiledata_pos.py Wed Jun 28 07:52:21 2006 -0600 58.3 @@ -24,7 +24,8 @@ for line in lines: 58.4 map[pieces[0]] = pieces[1] 58.5 58.6 for field in ["cores_per_socket", "threads_per_core", "cpu_mhz", 58.7 - "total_memory", "free_memory", "xen_major", "xen_minor"]: 58.8 + "total_memory", "free_memory", "xen_major", "xen_minor", 58.9 + "xen_pagesize"]: 58.10 val = map[field] 58.11 if not val.isdigit(): 58.12 FAIL("Numeric field %s not all-numbers: %s" % (field, val))
59.1 --- a/xen/Makefile Wed Jun 28 07:51:52 2006 -0600 59.2 +++ b/xen/Makefile Wed Jun 28 07:52:21 2006 -0600 59.3 @@ -14,8 +14,8 @@ default: build 59.4 .PHONY: dist 59.5 dist: install 59.6 59.7 -.PHONY: build install clean cscope TAGS tags 59.8 -build install debug clean cscope TAGS tags:: 59.9 +.PHONY: build install clean distclean cscope TAGS tags 59.10 +build install debug clean distclean cscope TAGS tags:: 59.11 make -f Rules.mk _$@ 59.12 59.13 .PHONY: _build 59.14 @@ -50,6 +50,10 @@ build install debug clean cscope TAGS ta 59.15 rm -f include/asm-*/asm-offsets.h 59.16 rm -f include/xen/acm_policy.h 59.17 59.18 +.PHONY: _distclean 59.19 +_distclean: clean 59.20 + rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out 59.21 + 59.22 $(TARGET).gz: $(TARGET) 59.23 gzip -f -9 < $< > $@.new 59.24 mv $@.new $@ 59.25 @@ -132,11 +136,11 @@ endef 59.26 59.27 .PHONY: _TAGS 59.28 _TAGS: 59.29 - $(all_sources) | etags - 59.30 + rm -f TAGS && $(all_sources) | xargs etags -a 59.31 59.32 .PHONY: _tags 59.33 _tags: 59.34 - $(all_sources) | xargs ctags 59.35 + rm -f TAGS && $(all_sources) | xargs ctags -a 59.36 59.37 .PHONY: _cscope 59.38 _cscope:
60.1 --- a/xen/arch/x86/dom0_ops.c Wed Jun 28 07:51:52 2006 -0600 60.2 +++ b/xen/arch/x86/dom0_ops.c Wed Jun 28 07:52:21 2006 -0600 60.3 @@ -194,6 +194,7 @@ long arch_do_dom0_op(struct dom0_op *op, 60.4 pi->nr_nodes = 1; 60.5 pi->total_pages = total_pages; 60.6 pi->free_pages = avail_domheap_pages(); 60.7 + pi->scrub_pages = avail_scrub_pages(); 60.8 pi->cpu_khz = cpu_khz; 60.9 memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); 60.10 memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
61.1 --- a/xen/arch/x86/hvm/svm/svm.c Wed Jun 28 07:51:52 2006 -0600 61.2 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Jun 28 07:52:21 2006 -0600 61.3 @@ -47,7 +47,6 @@ 61.4 #include <asm/shadow_64.h> 61.5 #endif 61.6 #include <public/sched.h> 61.7 -#include <public/hvm/ioreq.h> 61.8 61.9 #define SVM_EXTRA_DEBUG 61.10 61.11 @@ -66,8 +65,6 @@ extern void send_pio_req(struct cpu_user 61.12 extern int svm_instrlen(struct cpu_user_regs *regs, int mode); 61.13 extern void svm_dump_inst(unsigned long eip); 61.14 extern int svm_dbg_on; 61.15 -void svm_manual_event_injection32(st